diff --git a/.hgignore b/.hgignore
index b180d9200349eb5cb3f63baa0126d399860bf30a..c845758e7ce33da2c381bae3eb96459cffaa4cc7 100644
--- a/.hgignore
+++ b/.hgignore
@@ -10,7 +10,7 @@ syntax: glob
 .*.swp
 #OSX image cache file
 *.DS_Store
-*.orig
+#*.orig
 LICENSES
 indra/.distcc
 build-linux-*
@@ -50,6 +50,11 @@ indra/web/doc/asset-upload/plugins/verify-texture
 installed.xml
 libraries
 tarfile_tmp
+debian/secondlife-viewer*
+debian/secondlife-appearance-utility*
+debian/files
+build-stamp
+configure-stamp
 ^indra/lib/python/mulib.*
 ^web/locale.*
 ^web/secondlife.com.*
@@ -69,4 +74,4 @@ glob:indra/newview/filters.xml
 glob:indra/newview/avatar_icons_cache.txt
 glob:indra/newview/avatar_lad.log
 glob:*.diff
-*.rej
+#*.rej
diff --git a/.hgtags b/.hgtags
index 3d09a1e8437ca009722a6d0eba18ac882b380588..53693c2cdfff8f171d98c04d79a5229dd1b7de9d 100644
--- a/.hgtags
+++ b/.hgtags
@@ -72,35 +72,35 @@ b53a0576eec80614d7767ed72b40ed67aeff27c9 DRTVWR-38_2.5.2-release
 461c8c65b5c799ddfe365422f9be9c0095d91e7d 2.6.0-beta1-tip
 9e4641f4a7870c0f565a25a2971368d5a29516a1 2.6.0-beta2
 9e4641f4a7870c0f565a25a2971368d5a29516a1 DRTVWR-41_2.6.0-beta2
-42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
-42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-beta1
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 2.6.1-start
 c5bdef3aaa2744626aef3c217ce29e1900d357b3 DRTVWR-43_2.6.1-beta1
-c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
-c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
 56b2778c743c2a964d82e1caf11084d76a87de2c 2.6.2-start
 d1203046bb653b763f835b04d184646949d8dd5c 2.6.2-beta1
 d1203046bb653b763f835b04d184646949d8dd5c DRTVWR-45_2.6.2-beta1
-214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
-214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
+42f32494bac475d0737799346f6831558ae8bf5d 2.6.0-release
+42f32494bac475d0737799346f6831558ae8bf5d DRTVWR-39_2.6.0-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa 2.6.1-release
+c9182ed77d427c759cfacf49a7b71a2e20d522aa DRTVWR-42_2.6.1-release
 52b2263ab28f0976c689fd0b76c55a9eb027cdbf end-of-develop.py
 ec32f1045e7c2644015245df3a9933620aa194b8 2.6.3-start
 d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc 2.6.3-beta1
 d7fcefabdf32bb61a9ea6d6037c1bb26190a85bc DRTVWR-47_2.6.3-beta1
 0630e977504af5ea320c58d33cae4e1ddee793e9 2.6.3-beta2
 0630e977504af5ea320c58d33cae4e1ddee793e9 DRTVWR-48_2.6.3-beta2
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
-8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
 3178e311da3a8739a85363665006ea3c4610cad4 dons-headless-hackathon-work
+214180ad5714ce8392b82bbebcc92f4babd98300 2.6.2-release
+214180ad5714ce8392b82bbebcc92f4babd98300 DRTVWR-44_2.6.2-release
 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd 2.6.5-beta1
 7db558aaa7c176f2022b3e9cfe38ac72f6d1fccd DRTVWR-50_2.6.5-beta1
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 2.6.3-release
+8f2da1701c81a62352df2b8d413d27fb2cade9a6 DRTVWR-46_2.6.3-release
 800cefce8d364ffdd2f383cbecb91294da3ea424 2.6.6-start
 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 2.6.6-beta1
 bb1075286b3b147b1dae2e3d6b2d56f04ff03f35 DRTVWR-52_2.6.6-beta1
+5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
 dac76a711da5f1489a01c1fa62ec97d99c25736d 2.6.6-release
 dac76a711da5f1489a01c1fa62ec97d99c25736d DRTVWR-51_2.6.6-release
-5e349dbe9cc84ea5795af8aeb6d473a0af9d4953 2.6.8-start
 beafa8a9bd1d1b670b7523d865204dc4a4b38eef 2.6.8-beta1
 beafa8a9bd1d1b670b7523d865204dc4a4b38eef DRTVWR-55_2.6.8-beta1
 be2000b946f8cb3de5f44b2d419287d4c48ec4eb 2.6.8-release
@@ -119,50 +119,50 @@ e67da2c6e3125966dd49eef98b36317afac1fcfe 2.6.9-start
 9f79a6ed8fdcd2f3dac33ea6b3236eeb278dccfe 2.7.2-start
 e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb 2.7.2-beta1
 e0dc8b741eaa27dcdfbc9e956bb2579b954d15eb DRTVWR-63_2.7.2-beta1
+6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
 fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.1-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb 2.7.2-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-60_2.7.1-release
 fe3a8e7973072ea62043c08b19b66626c1a720eb DRTVWR-62_2.7.2-release
-6a3e7e403bd19e45fdfc2fcc716867af3ab80861 2.7.3-start
 6af10678de4736222b2c3f7e010e984fb5b327de 2.7.4-start
 be963a4eef635542f9617d7f5fd22ba48fb71958 2.7.4-beta1
 be963a4eef635542f9617d7f5fd22ba48fb71958 DRTVWR-67_2.7.4-beta1
-057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
-057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
 19a498fa62570f352d7d246f17e3c81cc1d82d8b 2.7.5-start
 09984bfa6cae17e0f72d02b75c1b7393c65eecfc 2.7.5-beta1
 09984bfa6cae17e0f72d02b75c1b7393c65eecfc DRTVWR-69_2.7.5-beta1
-6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
-6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-beta1
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c 2.8.0-start
 e1ed60913230dd64269a7f7fc52cbc6004f6d52c DRTVWR-71_2.8.0-beta1
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
-493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
+057f319dd8eccdf63a54d99686c68cdcb31b6abc 2.7.4-release
+057f319dd8eccdf63a54d99686c68cdcb31b6abc DRTVWR-66_2.7.4-release
+6866d9df6efbd441c66451debd376d21211de39c 2.7.5-release
+6866d9df6efbd441c66451debd376d21211de39c DRTVWR-68_2.7.5-release
 502f6a5deca9365ddae57db4f1e30172668e171e 2.8.1-start
 2c7e459e0c883f8e406b932e41e60097e9ee077e 2.8.1-beta1
 2c7e459e0c883f8e406b932e41e60097e9ee077e DRTVWR-73_2.8.1-beta1
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 2.8.0-release
+493d9127ee50e84ba08a736a65a23ca86f7a5b01 DRTVWR-70_2.8.0-release
+54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
+ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
 29e93d7e19991011bd12b5748142b11a5dcb4370 2.8.1-release
 29e93d7e19991011bd12b5748142b11a5dcb4370 DRTVWR-72_2.8.1-release
 4780e3bd2b3042f91be3426151f28c30d199bb3b 2.8.1-hotfix
 4780e3bd2b3042f91be3426151f28c30d199bb3b DRTVWR-76_2.8.1-hotfix
-54bc7823ad4e3a436fef79710f685a7372bbf795 2.8.2-start
-ac0f1a132d35c02a58861d37cca75b0429ac9137 2.8.3-start
 599677276b227357140dda35bea4a2c18e2e67b5 2.8.3-beta1
 599677276b227357140dda35bea4a2c18e2e67b5 DRTVWR-75_2.8.3-beta1
-fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
-fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
 6b678ea52f90d5c14181661dcd2546e25bde483e 3.0.0-start
 b0be6ce3adfef3a014a2389d360539f8a86c5439 3.0.0-beta1
 b0be6ce3adfef3a014a2389d360539f8a86c5439 DRTVWR-78_3.0.0-beta1
-1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
-1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
+fb85792b84bf28428889c4cc966469d92e5dac4c 2.8.3-release
+fb85792b84bf28428889c4cc966469d92e5dac4c DRTVWR-74_2.8.3-release
 82a2079ffcb57ecb1b3849cb41376b443e1eb912 3.0.1-start
 364fd63517fbacbbcb9129d096187171ba8c9e48 3.0.1-beta1
 364fd63517fbacbbcb9129d096187171ba8c9e48 DRTVWR-81_3.0.1-beta1
 f2412ecd6740803ea9452f1d17fd872e263a0df7 3.0.2-start
 42784bf50fa01974bada2a1af3892ee09c93fcda 3.0.2-beta1
 42784bf50fa01974bada2a1af3892ee09c93fcda DRTVWR-83_3.0.2-beta1
+1778f26b6d0ae762dec3ca37140f66620f2485d9 3.0.0-release
+1778f26b6d0ae762dec3ca37140f66620f2485d9 DRTVWR-77_3.0.0-release
 e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e 3.0.2-beta2
 e5c9af2d7980a99a71650be3a0cf7b2b3c3b897e DRTVWR-86_3.0.2-beta2
 b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
@@ -170,9 +170,9 @@ b95ddac176ac944efdc85cbee94ac2e1eab44c79 3.0.3-start
 6694f3f062aa45f64ab391d25a3eb3d5eb1b0871 DRTVWR-85_3.0.3-beta1
 61aa7974df089e8621fe9a4c69bcdefdb3cc208a 3.0.3-beta2
 61aa7974df089e8621fe9a4c69bcdefdb3cc208a DRTVWR-89_3.0.3-beta2
+586907287be581817b2422b5137971b22d54ea48 3.0.4-start
 0496d2f74043cf4e6058e76ac3db03d44cff42ce 3.0.3-release
 0496d2f74043cf4e6058e76ac3db03d44cff42ce DRTVWR-84_3.0.3-release
-586907287be581817b2422b5137971b22d54ea48 3.0.4-start
 92a3aa04775438226399b19deee12ac3b5a62838 3.0.5-start
 c7282e59f374ee904bd793c3c444455e3399b0c5 3.1.0-start
 2657fa785bbfac115852c41bd0adaff74c2ad5da 3.1.0-beta1
@@ -193,11 +193,11 @@ e440cd1dfbd128d7d5467019e497f7f803640ad6 DRTVWR-95_3.2.0-beta1
 c4911ec8cd81e676dfd2af438b3e065407a94a7a 3.2.1-start
 9e390d76807fa70d356b8716fb83b8ce42a629ef 3.2.1-beta1
 9e390d76807fa70d356b8716fb83b8ce42a629ef DRTVWR-100_3.2.1-beta1
-a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
-a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
 40b46edba007d15d0059c80864b708b99c1da368 3.2.2-start
 523df3e67378541498d516d52af4402176a26bac 3.2.2-beta1
 523df3e67378541498d516d52af4402176a26bac DRTVWR-102_3.2.2-beta1
+a8c7030d6845186fac7c188be4323a0e887b4184 3.2.1-release
+a8c7030d6845186fac7c188be4323a0e887b4184 DRTVWR-99_3.2.1-release
 80f3e30d8aa4d8f674a48bd742aaa6d8e9eae0b5 3.2.3-start
 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-beta1
 3fe994349fae64fc40874bb59db387131eb35a41 3.2.4-start
@@ -248,67 +248,57 @@ 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
 9cd174d3a54d93d409a7c346a15b8bfb40fc58f4 DRTVWR-184
 ab2ffc547c8a8950ff187c4f6c95e5334fab597b 3.3.4-beta5
 28e100d0379a2b0710c57647a28fc5239d3d7b99 3.3.4-release
+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
 6dfb0fba782c9233dd95f24ec48146db0d3f210b DRTVWR-199
 7c9102fb998885621919f2474a002c35b583539b 3.3.4-release2
 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
 8c9085066c78ed5f6c9379dc054c82a6fcdb1851 DRTVWR-207
 351eea5f9dc192fc5ddea3b02958de97677a0a12 3.3.4-release3
 af7b28e75bd5a629cd9e0dc46fb3f1757626f493 DRTVWR-212
@@ -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
@@ -419,3 +417,24 @@ b23419a2748483c98f3b84b630468a21c88feba5 DRTVWR-292
 0a5d409161ef2a89b28c9a741051dd2dedc707d6 DRTVWR-297
 852b69ef0b5fe6b13b69cc2217282cc64de6afab 3.4.5-beta5
 a49c715243a36a8a380504d14cb7416b3039c956 3.4.5-release
+37947e4f771f001b551581bf7cd0051c3153beed DRTVWR-282
+6482cceb91cda68b799f3e6cdc66d33bf123547a DRTVWR-284
+092a9effbedd1a0276fa5ced520992ce00f96fbf CHUI-PV-0
+279ef1dfc9b749a6cc499cf190fec0c090b6d682 DRTVWR-288
+9b19edaf1d8ddf435f60fbbb444dd25db8f63953 3.5.0-beta1
+c6b3561c7d7ad365eeba669db54eb57b5149ce75 3.5.0-beta2
+6d91ffd77bf2a20f18a2175eb7579da880ae12ac DRTVWR-302
+f6ca5bb75bca975ff0bc77e71e615f6478c4559c 3.5.0-beta3
+910b5fad950e343b58229f5a0aefa7729b9308b3 DRTVWR-303
+53cffdde0b3cc367ba9bb6abd5c83ae14df5e882 3.5.0-beta4
+4d5f6234dc59a0fb6ead5e02c7d343a0610e0488 DRTVWR-304
+dd058a6093c493120d67c8e02c812c0f7b2d3db0 3.5.0-beta5
+fd6b510e83f56830e45670c428653134899d3e25 DRTVWR-305
+55339537d99afc394d1bb7fdb7d074bf321ca62f 3.5.0-beta6
+902caf2b9fdbdbc5c399c4d5ebcecaf9cb97bab8 DRTVWR-306
+5c6098fd17d40ee3a38ca6b64f6be9db7f61f0a8 3.5.0-beta7
+adc360e6bf21390d2665380951d85937cd29a604 3.5.0-release
+0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
+1ada73295ed0eaa4a772ef079c29f57069342c32 DRTVWR-310
+0ca3910763cec967703e45bc6208a325dccb9f95 3.5.1-beta1
+20cdf370f5c8be6193bef6fb3a81cc3f81275191 3.5.1-beta1
diff --git a/BuildParams b/BuildParams
index c8edfeaa2fad6a9fa16e9319921b914d9e5ccc09..c929c2d90d1a9ea1db0adfef985e8a5e627a13ba 100644
--- a/BuildParams
+++ b/BuildParams
@@ -21,6 +21,11 @@ email_status_this_is_os = true
 # Limit extent of codeticket updates to revisions after...
 codeticket_since = 3.3.0-release
 
+# Override build system default toolchain
+# Note that this will only affect automated builds.
+Linux.gcc_version = /usr/bin/gcc-4.6
+Linux.cxx_version = /usr/bin/g++-4.6
+
 # ========================================
 # Viewer Development
 # ========================================
@@ -127,6 +132,18 @@ viewer-pathfinding.build_debug_release_separately = true
 viewer-pathfinding.build_CYGWIN_Debug = false
 viewer-pathfinding.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/autobuild.xml b/autobuild.xml
index 9c878fd730746a2b58e8fb85d2b04325e5b12610..ba6b76e7b21baa30284948608e67f211aefcdec3 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -18,9 +18,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b2fe1c860613a68e74d4384be418ffee</string>
+              <string>e6071abd822c0688390382a26f8a782c</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Darwin/installer/glod-1.0pre4-darwin-20110610.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/267984/arch/Darwin/installer/glod-1.0pre4-darwin-20121211.tar.bz2</string>
             </map>
             <key>name</key>
             <string>darwin</string>
@@ -30,9 +30,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>c0c64dae149d0892343e2ff300fd06b9</string>
+              <string>176736c52b3cde6ca8e7d9e173d91731</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/232684/arch/Linux/installer/glod-1.0pre4-linux-20110611.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glod/rev/268002/arch/Linux/installer/glod-1.0pre4-linux-20121212.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -606,9 +606,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>9f8a9dc39fd7c3da0fb3533782d1fddf</string>
+              <string>ca95bbdabd2bed612af79a3704fdbe79</string>
               <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-freetype/rev/226814/arch/Linux/installer/freetype-2.3.9-linux-20110418.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-freetype/rev/265843/arch/Linux/installer/freetype-2.3.9-linux-20121013.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -690,9 +690,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>26f2df1f0b0fa01e94e0253e322f3583</string>
+              <string>1b1f1e9975e3a671c9faf32fcf4b6d43</string>
               <key>url</key>
-              <string>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/glh_linear-linux-20101001.tar.bz2</string>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-glh_linear/rev/263308/arch/Linux/installer/glh_linear-0.0.0-linux-20120810.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -843,6 +843,42 @@
           </map>
         </map>
       </map>
+      <key>gperftools</key>
+      <map>
+        <key>license</key>
+        <string>bsd</string>
+        <key>license_file</key>
+        <string>LICENSES/gperftools.txt</string>
+        <key>name</key>
+        <string>gperftools</string>
+        <key>platforms</key>
+        <map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>8aedfdcf670348c18a9991ae1b384a61</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+          <key>windows</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>f62841804acb91e1309603a84f3f0ce8</string>
+              <key>url</key>
+              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>windows</string>
+          </map>
+        </map>
+      </map>
       <key>gstreamer</key>
       <map>
         <key>license</key>
@@ -1239,6 +1275,32 @@
           </map>
         </map>
       </map>
+      <key>llappearanceutility-source</key>
+      <map>
+        <key>license</key>
+        <string>TEMPORARY</string>
+        <key>license_file</key>
+        <string>LICENSES/llappearanceutility.txt</string>
+        <key>name</key>
+        <string>llappearanceutility-source</string>
+        <key>platforms</key>
+        <map>
+          <key>linux</key>
+          <map>
+            <key>archive</key>
+            <map>
+              <key>hash</key>
+              <string>5bc44db15eb3cca021382e40e04a9a38</string>
+              <key>url</key>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/271972/arch/Linux/installer/llappearanceutility_source-0.1-linux-20130315.tar.bz2</string>
+            </map>
+            <key>name</key>
+            <string>linux</string>
+          </map>
+        </map>
+        <key>version</key>
+        <string>0.1</string>
+      </map>
       <key>llphysicsextensions_source</key>
       <map>
         <key>license</key>
@@ -1268,9 +1330,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>b706fdeed4ce2182d434043dc33d9d1d</string>
+              <string>a6856b4d58a3b71321acad7e1fa9c8d4</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/263415/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20120814.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llphysicsextensions-source/rev/265749/arch/Linux/installer/llphysicsextensions_source-0.3-linux-20121011.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
@@ -1779,42 +1841,6 @@
           </map>
         </map>
       </map>
-      <key>tcmalloc</key>
-      <map>
-        <key>license</key>
-        <string>bsd</string>
-        <key>license_file</key>
-        <string>LICENSES/google-perftools.txt</string>
-        <key>name</key>
-        <string>tcmalloc</string>
-        <key>platforms</key>
-        <map>
-          <key>linux</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>8aedfdcf670348c18a9991ae1b384a61</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/Linux/installer/gperftools-2.0-linux-20120727.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>linux</string>
-          </map>
-          <key>windows</key>
-          <map>
-            <key>archive</key>
-            <map>
-              <key>hash</key>
-              <string>f62841804acb91e1309603a84f3f0ce8</string>
-              <key>url</key>
-              <string>http://automated-builds-secondlife-com.s3.amazonaws.com/hg/repo/3p-google-perftools/rev/262672/arch/CYGWIN/installer/gperftools-2.0-windows-20120727.tar.bz2</string>
-            </map>
-            <key>name</key>
-            <string>windows</string>
-          </map>
-        </map>
-      </map>
       <key>tut</key>
       <map>
         <key>license</key>
diff --git a/build.sh b/build.sh
index 15f0463aff43eb5d526d8e94bc9a6647b7aba9d6..964f9ef0a60a5de2b8bfe95630ba4b23ceeb1073 100755
--- a/build.sh
+++ b/build.sh
@@ -113,11 +113,23 @@ build()
     check_for "Before 'autobuild build'" ${build_dir}/packages/dictionaries
 
     "$AUTOBUILD" build --no-configure -c $variant
-    viewer_build_ok=$?
+    build_ok=$?
     end_section "Viewer$variant"
+
+    # Run build extensions
+    if [ $build_ok -eq 0 -a -d ${build_dir}/packages/build-extensions ]; then
+        for extension in ${build_dir}/packages/build-extensions/*.sh; do
+            . $extension
+            if [ $build_ok -ne 0 ]; then
+                break
+            fi
+        done
+    fi
+
+    # *TODO: Make this a build extension.
     package_llphysicsextensions_tpv
     tpvlib_build_ok=$?
-    if [ $viewer_build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
+    if [ $build_ok -eq 0 -a $tpvlib_build_ok -eq 0 ]
     then
       echo true >"$build_dir"/build_ok
     else
@@ -292,12 +304,86 @@ then
   end_section WaitParallel
 fi
 
+# build debian package
+if [ "$arch" == "Linux" ]
+then
+  if $succeeded
+  then
+    if $build_viewer_deb && [ "$last_built_variant" == "Release" ]
+    then
+      begin_section "Build Viewer Debian Package"
+      local have_private_repo=false
+      # mangle the changelog
+      dch --force-bad-version \
+          --distribution unstable \
+          --newversion "${VIEWER_VERSION}" \
+          "Automated build #$build_id, repository $branch revision $revision." \
+          >> "$build_log" 2>&1
+
+      # build the debian package
+      $pkg_default_debuild_command  >>"$build_log" 2>&1 || record_failure "\"$pkg_default_debuild_command\" failed."
+
+      # Unmangle the changelog file
+      hg revert debian/changelog
+
+      end_section "Build Viewer Debian Package"
+
+      # Run debian extensions
+      if [ -d ${build_dir}/packages/debian-extensions ]; then
+          for extension in ${build_dir}/packages/debian-extensions/*.sh; do
+              . $extension
+          done
+      fi
+      # Move any .deb results.
+      mkdir -p ../packages_public
+      mkdir -p ../packages_private
+      mv ${build_dir}/packages/*.deb ../packages_public 2>/dev/null || true
+      mv ${build_dir}/packages/packages_private/*.deb ../packages_private 2>/dev/null || true
+
+      # upload debian package and create repository
+      begin_section "Upload Debian Repository"
+      for deb_file in `/bin/ls ../packages_public/*.deb ../*.deb 2>/dev/null`; do
+        upload_item debian $deb_file binary/octet-stream
+      done
+      for deb_file in `/bin/ls ../packages_private/*.deb 2>/dev/null`; do
+        upload_item debian_private $deb_file binary/octet-stream
+        have_private_repo=true
+      done
+
+      create_deb_repo
+
+      # Rename the local debian_repo* directories so that the master buildscript
+      # doesn't make a remote repo again.
+      for debian_repo_type in debian_repo debian_repo_private; do
+        if [ -d "$build_log_dir/$debian_repo_type" ]; then
+          mv $build_log_dir/$debian_repo_type $build_log_dir/${debian_repo_type}_pushed
+        fi
+      done
+
+      if [ $have_private_repo = true ]; then
+        eval "$python_command \"$redirect\" '\${private_S3PROXY_URL}${S3PREFIX}repo/$repo/rev/$revision/index.html'"\
+            >"$build_log_dir/private.html" || fatal generating redirect
+        upload_item global_redirect "$build_log_dir/private.html" text/html
+        
+      fi
+
+      end_section "Upload Debian Repository"
+      
+    else
+      echo skipping debian build
+    fi
+  else
+    echo skipping debian build due to failed build.
+  fi
+fi
+
+
 # check status and upload results to S3
 if $succeeded
 then
   if $build_viewer
   then
-    begin_section Upload
+    begin_section Upload Installer
     # Upload installer - note that ONLY THE FIRST ITEM uploaded as "installer"
     # will appear in the version manager.
     package=$(installer_$arch)
@@ -317,8 +403,9 @@ then
         do
           upload_item symbolfile "$build_dir/$symbolfile" binary/octet-stream
         done
-        
+
         # Upload the llphysicsextensions_tpv package, if one was produced
+        # *TODO: Make this an upload-extension
         if [ -r "$build_dir/llphysicsextensions_package" ]
         then
             llphysicsextensions_package=$(cat $build_dir/llphysicsextensions_package)
@@ -332,15 +419,22 @@ then
         ;;
       esac
 
+      # Run upload extensions
+      if [ -d ${build_dir}/packages/upload-extensions ]; then
+          for extension in ${build_dir}/packages/upload-extensions/*.sh; do
+              . $extension
+          done
+      fi
+
       # Upload stub installers
       upload_stub_installers "$build_dir_stubs"
     fi
-    end_section Upload
+    end_section Upload Installer
   else
-    echo skipping viewer
+    echo skipping upload of installer
   fi
 else
-  echo skipping upload of build results due to failed build.
+  echo skipping upload of installer due to failed build.
 fi
 
 # The branch independent build.sh script invoking this script will finish processing
diff --git a/debian/changelog b/debian/changelog
new file mode 100644
index 0000000000000000000000000000000000000000..ce54b54c6f107de19d88453456b9a243b6559ed4
--- /dev/null
+++ b/debian/changelog
@@ -0,0 +1,18 @@
+secondlife-viewer (0.3) unstable; urgency=low
+
+  * Initial debian configuration
+
+ -- Don Kjer <don@lindenlab.com>  Wed, 04 Jul 2012 00:43:03 +0000
+
+secondlife-viewer (0.2) unstable; urgency=low
+
+  * Adding default LSB headers for squeeze
+
+ -- Tyler Kohler <tyler@lindenlab.com>  Thu, 24 Mar 2011 09:43:36 -0700
+
+secondlife-viewer (0.1) unstable; urgency=low
+
+  * Cloned from debian package skeleton.
+
+ -- Lex Linden <lex@lindenlab.com>  Mon, 20 Sep 2010 08:01:59 -0700
+
diff --git a/debian/compat b/debian/compat
new file mode 100644
index 0000000000000000000000000000000000000000..7ed6ff82de6bcc2a78243fc9c54d3ef5ac14da69
--- /dev/null
+++ b/debian/compat
@@ -0,0 +1 @@
+5
diff --git a/debian/control b/debian/control
new file mode 100644
index 0000000000000000000000000000000000000000..50b9ed9a264abf7dbf48dc789484056635f36753
--- /dev/null
+++ b/debian/control
@@ -0,0 +1,16 @@
+Source: secondlife-viewer
+Section: unknown
+Priority: extra
+Maintainer: Don Linden <don@lindenlab.com>
+Build-Depends: debhelper (>= 5)
+Homepage: http://secondlife.com
+Standards-Version: 3.7.2
+
+Package: secondlife-viewer
+Architecture: any
+Depends: ${shlibs:Depends}, ${misc:Depends},
+ ia32-libs,
+ ia32-libs-gtk
+Description: Second Life Viewer
+ Second Life is an online virtual world developed by Linden Lab.
+ 
diff --git a/debian/copyright b/debian/copyright
new file mode 100644
index 0000000000000000000000000000000000000000..106fa3802f1b7d6b7550167cb8d928ef098ee197
--- /dev/null
+++ b/debian/copyright
@@ -0,0 +1,32 @@
+Second Life Viewer Copyright: 2000-2012 Linden Research, Inc.
+
+License:
+
+3Dconnexion SDK Copyright (C) 1992-2009 3Dconnexion
+APR Copyright (C) 2011 The Apache Software Foundation
+Collada DOM Copyright 2006 Sony Computer Entertainment Inc.
+cURL Copyright (C) 1996-2010, Daniel Stenberg, (daniel@haxx.se)
+DBus/dbus-glib Copyright (C) 2002, 2003  CodeFactory AB / Copyright (C) 2003, 2004 Red Hat, Inc.
+expat Copyright (C) 1998, 1999, 2000 Thai Open Source Software Center Ltd.
+FreeType Copyright (C) 1996-2002, 2006 David Turner, Robert Wilhelm, and Werner Lemberg.
+GL Copyright (C) 1999-2004 Brian Paul.
+GLOD Copyright (C) 2003-04 Jonathan Cohen, Nat Duca, Chris Niski, Johns Hopkins University and David Luebke, Brenden Schubert, University of Virginia.
+google-perftools Copyright (c) 2005, Google Inc.
+Havok.com(TM) Copyright (C) 1999-2001, Telekinesys Research Limited.
+jpeg2000 Copyright (C) 2001, David Taubman, The University of New South Wales (UNSW)
+jpeglib Copyright (C) 1991-1998, Thomas G. Lane.
+ogg/vorbis Copyright (C) 2002, Xiphophorus
+OpenSSL Copyright (C) 1998-2008 The OpenSSL Project.
+PCRE Copyright (c) 1997-2012 University of Cambridge
+SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga
+SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+xmlrpc-epi Copyright (C) 2000 Epinions, Inc.
+zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler.
+
+Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details.
+
+This software contains source code provided by NVIDIA Corporation.
+
+All rights reserved.  See licenses.txt for details.
+
+Voice chat Audio coding: Polycom(R) Siren14(TM) (ITU-T Rec. G.722.1 Annex C)
diff --git a/debian/postinst b/debian/postinst
new file mode 100644
index 0000000000000000000000000000000000000000..2c4f8ea8588b62b63d5ba8106d8e18964903307e
--- /dev/null
+++ b/debian/postinst
@@ -0,0 +1,43 @@
+#!/bin/sh
+# postinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postinst> `configure' <most-recently-configured-version>
+#        * <old-postinst> `abort-upgrade' <new version>
+#        * <conflictor's-postinst> `abort-remove' `in-favour' <package>
+#          <new-version>
+#        * <postinst> `abort-remove'
+#        * <deconfigured's-postinst> `abort-deconfigure' `in-favour'
+#          <failed-install-package> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    configure)
+    ;;
+
+    abort-upgrade|abort-remove|abort-deconfigure)
+    ;;
+
+    *)
+        echo "postinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/postrm b/debian/postrm
new file mode 100644
index 0000000000000000000000000000000000000000..a575936ab04060765153060adf711ba28bb02890
--- /dev/null
+++ b/debian/postrm
@@ -0,0 +1,41 @@
+#!/bin/sh
+# postrm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <postrm> `remove'
+#        * <postrm> `purge'
+#        * <old-postrm> `upgrade' <new-version>
+#        * <new-postrm> `failed-upgrade' <old-version>
+#        * <new-postrm> `abort-install'
+#        * <new-postrm> `abort-install' <old-version>
+#        * <new-postrm> `abort-upgrade' <old-version>
+#        * <disappearer's-postrm> `disappear' <overwriter>
+#          <overwriter-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    purge|remove|upgrade|failed-upgrade|abort-install|abort-upgrade|disappear)
+    ;;
+
+    *)
+        echo "postrm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/preinst b/debian/preinst
new file mode 100644
index 0000000000000000000000000000000000000000..f62243440f6cf253026d0926576fa0c99535e524
--- /dev/null
+++ b/debian/preinst
@@ -0,0 +1,39 @@
+#!/bin/sh
+# preinst script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <new-preinst> `install'
+#        * <new-preinst> `install' <old-version>
+#        * <new-preinst> `upgrade' <old-version>
+#        * <old-preinst> `abort-upgrade' <new-version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    install|upgrade)
+    ;;
+
+    abort-upgrade)
+    ;;
+
+    *)
+        echo "preinst called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/prerm b/debian/prerm
new file mode 100644
index 0000000000000000000000000000000000000000..405b8f9c87bcfe6e3bcca23b7eb192a9dd6ee0e2
--- /dev/null
+++ b/debian/prerm
@@ -0,0 +1,42 @@
+#!/bin/sh
+# prerm script for secondlife-viewer
+#
+# Delete this file if you don't need it.
+#
+# see: dh_installdeb(1)
+
+set -e
+
+# summary of how this script can be called:
+#        * <prerm> `remove'
+#        * <old-prerm> `upgrade' <new-version>
+#        * <new-prerm> `failed-upgrade' <old-version>
+#        * <conflictor's-prerm> `remove' `in-favour' <package> <new-version>
+#        * <deconfigured's-prerm> `deconfigure' `in-favour'
+#          <package-being-installed> <version> `removing'
+#          <conflicting-package> <version>
+# for details, see http://www.debian.org/doc/debian-policy/ or
+# the debian-policy package
+
+
+case "$1" in
+    remove|upgrade|deconfigure)
+    ;;
+
+    failed-upgrade)
+    ;;
+
+    *)
+        echo "prerm called with unknown argument \`$1'" >&2
+        exit 1
+    ;;
+esac
+
+# dh_installdeb will replace this with shell code automatically
+# generated by other debhelper scripts.  Don't delete this!
+
+#DEBHELPER#
+
+exit 0
+
+
diff --git a/debian/rules b/debian/rules
new file mode 100644
index 0000000000000000000000000000000000000000..305fc58bb401b7ca74dbcabb111b80ea4f925530
--- /dev/null
+++ b/debian/rules
@@ -0,0 +1,118 @@
+#!/usr/bin/make -f
+# -*- makefile -*-
+# Sample debian/rules that uses debhelper.
+# This file was originally written by Joey Hess and Craig Small.
+# As a special exception, when this file is copied by dh-make into a
+# dh-make output file, you may use that output file without restriction.
+# This special exception was added by Craig Small in version 0.37 of dh-make.
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+BASEDIR=opt/linden
+
+VIEWER_PKG=secondlife-viewer
+VIEWER_PACKAGEDIR=build-linux-i686/newview/packaged
+VIEWER_DESTDIR=$(CURDIR)/debian/$(VIEWER_PKG)
+VIEWER_VERSION:=$(shell dpkg-parsechangelog | grep ^Version | sed 's/^Version: //')
+VIEWER_INSTALLDIR:=$(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION)
+
+configure: configure-stamp
+configure-stamp:
+	dh_testdir
+	# Add here commands to configure the package.
+
+	touch configure-stamp
+
+build: build-stamp
+
+build-stamp: configure-stamp 
+	dh_testdir
+
+	# Add here commands to compile the package.
+	#$(MAKE)
+	#docbook-to-man debian/secondlife-viewer.sgml > secondlife-viewer.1
+
+	touch $@
+
+clean:
+	dh_testdir
+	dh_testroot
+	rm -f build-stamp configure-stamp
+
+	# Add here commands to clean up after the build process.
+	#-$(MAKE) clean
+
+	dh_clean 
+
+install: build
+	dh_testdir
+	dh_testroot
+	dh_clean -k 
+	dh_installdirs
+
+	# Add here commands to install the package into debian/secondlife-viewer.
+	for file in $$(find $(VIEWER_PACKAGEDIR) -type f -o -type l | sed 's~$(VIEWER_PACKAGEDIR)/~~'); do \
+		# create containing directory \
+		install -v -m 755 -o root -g root -d "$$(dirname "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file")"; \
+		PERM=644; \
+		if [ -x "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
+			PERM=755; \
+		fi; \
+		if [ -L "$(VIEWER_PACKAGEDIR)/$$file" ]; then \
+			REAL="$$( readlink -f $(VIEWER_PACKAGEDIR)/$$file )"; \
+			RELATIVE="$$( echo $$REAL | sed 's~$(CURDIR)/$(VIEWER_PACKAGEDIR)/~~' )"; \
+			echo dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
+			dh_link -p $(VIEWER_PKG) "$(VIEWER_INSTALLDIR)/$$RELATIVE" "$(VIEWER_INSTALLDIR)/$$file" ; \
+		else \
+			install -v -m $$PERM -o root -g root "$(VIEWER_PACKAGEDIR)/$$file" "$(VIEWER_DESTDIR)/$(VIEWER_INSTALLDIR)/$$file"; \
+		fi; \
+	done
+	dh_link -p $(VIEWER_PKG) /$(VIEWER_INSTALLDIR)/secondlife /usr/bin/secondlife
+	dh_link -p $(VIEWER_PKG) $(BASEDIR)/viewer/SecondLife-i686-$(VIEWER_VERSION) $(BASEDIR)/viewer/SecondLife
+
+
+# Build architecture-independent files here.
+binary-indep: build install
+# We have nothing to do by default.
+
+# Build architecture-dependent files here.
+binary-arch: build install
+	dh_testdir
+	dh_testroot
+	dh_installchangelogs 
+	dh_installdocs
+	dh_installexamples
+#	dh_install
+#	dh_installmenu
+#	dh_installdebconf	
+#	dh_installlogrotate
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+#	dh_python
+
+# To add an init script, uncomment this line and edit debian/init.d and 
+# customize debian/secondlife-viewer.default to suit your needs.
+#	dh_installinit
+
+# To add cron jobs, uncomment this line and make a crontab file named 
+# debian/cron.d, and it will be installed in /etc/cron.d/
+#	dh_installcron
+
+#	dh_installinfo
+	dh_installman
+	dh_link
+#	dh_strip
+	dh_compress
+#	dh_fixperms
+#	dh_perl
+#	dh_makeshlibs
+	dh_installdeb
+#	dh_shlibdeps
+	dh_gencontrol
+	dh_md5sums
+	dh_builddeb
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
diff --git a/doc/contributions.txt b/doc/contributions.txt
index 49fc6efe0d0e9c47a14e639d2ef6ae55a1bc0d6e..98713a8e8521550759dad9ee4d696b3ae1513d77 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -744,10 +744,12 @@ Marc Claridge
 Marc2 Sands
 Marianne McCann
 Marine Kelley
+    CHUIBUG-134
     STORM-281
 MartinRJ Fayray
     STORM-1844
     STORM-1845
+    STORM-1934
 Matthew Anthony
 Matthew Dowd
 	VWR-1344
diff --git a/indra/CMakeLists.txt b/indra/CMakeLists.txt
index 001bb4b9359aa6e930c9b9158e0cf27a1da1d758..0a54163644cc09fdf8d43060fafa940e91992d67 100644
--- a/indra/CMakeLists.txt
+++ b/indra/CMakeLists.txt
@@ -41,6 +41,7 @@ endif ("${CMAKE_SOURCE_DIR}/../autobuild.xml" IS_NEWER_THAN "${CMAKE_BINARY_DIR}
 add_subdirectory(cmake)
 
 add_subdirectory(${LIBS_OPEN_PREFIX}llaudio)
+add_subdirectory(${LIBS_OPEN_PREFIX}llappearance)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcharacter)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcommon)
 add_subdirectory(${LIBS_OPEN_PREFIX}llcorehttp)
@@ -63,71 +64,53 @@ if (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 endif (WINDOWS AND EXISTS ${LIBS_CLOSED_DIR}copy_win_scripts)
 
 add_custom_target(viewer)
-if (VIEWER)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
-  add_subdirectory(${LIBS_OPEN_PREFIX}llui)
-  add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
-
-  # Legacy C++ tests. Build always, run if LL_TESTS is true.
-  add_subdirectory(${VIEWER_PREFIX}test)
-
-  # viewer media plugins
-  add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
-
-  # llplugin testbed code (is this the right way to include it?)
-  if (LL_TESTS AND NOT LINUX)
-    add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
-  endif (LL_TESTS AND NOT LINUX)
-
-  if (LINUX)
-    add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
-    add_dependencies(viewer linux-crash-logger-strip-target)
-  elseif (DARWIN)
-    add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
-    add_subdirectory(${VIEWER_PREFIX}mac_updater)
-    add_dependencies(viewer mac-updater mac-crash-logger)
-  elseif (WINDOWS)
-    add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
-    # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
-    if (EXISTS ${VIEWER_DIR}win_setup)
-      add_subdirectory(${VIEWER_DIR}win_setup)
-    endif (EXISTS ${VIEWER_DIR}win_setup)
-    add_subdirectory(${VIEWER_PREFIX}win_updater)
-    # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
-    add_dependencies(viewer windows-updater windows-crash-logger)
-  elseif (SOLARIS)
-    add_subdirectory(solaris_crash_logger)
-    add_dependencies(viewer solaris-crash-logger)
-  endif (LINUX)
-
-  add_subdirectory(${VIEWER_PREFIX}newview)
-  add_dependencies(viewer secondlife-bin)
-endif (VIEWER)
-
-# Linux builds the viewer and server in 2 separate projects
-# In order for build server to work on linux, 
-# the viewer project needs a server target.
-# This is not true for mac and windows.
-if (LINUX) 
-  add_custom_target(server)
+add_subdirectory(${LIBS_OPEN_PREFIX}llcrashlogger)
+add_subdirectory(${LIBS_OPEN_PREFIX}llplugin)
+add_subdirectory(${LIBS_OPEN_PREFIX}llui)
+add_subdirectory(${LIBS_OPEN_PREFIX}viewer_components)
+
+# Legacy C++ tests. Build always, run if LL_TESTS is true.
+add_subdirectory(${VIEWER_PREFIX}test)
+
+# viewer media plugins
+add_subdirectory(${LIBS_OPEN_PREFIX}media_plugins)
+
+# llplugin testbed code (is this the right way to include it?)
+if (LL_TESTS AND NOT LINUX)
+  add_subdirectory(${VIEWER_PREFIX}test_apps/llplugintest)
+endif (LL_TESTS AND NOT LINUX)
+
+if (LINUX)
+  add_subdirectory(${VIEWER_PREFIX}linux_crash_logger)
+  add_subdirectory(${VIEWER_PREFIX}linux_updater)
+  if (INSTALL_PROPRIETARY)
+      include(LLAppearanceUtility)
+      add_subdirectory(${LLAPPEARANCEUTILITY_SRC_DIR} ${LLAPPEARANCEUTILITY_BIN_DIR})
+  endif (INSTALL_PROPRIETARY)
+  add_dependencies(viewer linux-crash-logger-strip-target linux-updater)
+elseif (DARWIN)
+  add_subdirectory(${VIEWER_PREFIX}mac_crash_logger)
+  add_subdirectory(${VIEWER_PREFIX}mac_updater)
+  add_dependencies(viewer mac-updater mac-crash-logger)
+elseif (WINDOWS)
+  add_subdirectory(${VIEWER_PREFIX}win_crash_logger)
+  # cmake EXISTS requires an absolute path, see indra/cmake/Variables.cmake
+  if (EXISTS ${VIEWER_DIR}win_setup)
+    add_subdirectory(${VIEWER_DIR}win_setup)
+  endif (EXISTS ${VIEWER_DIR}win_setup)
+  add_subdirectory(${VIEWER_PREFIX}win_updater)
+  # add_dependencies(viewer windows-updater windows-setup windows-crash-logger)
+  add_dependencies(viewer windows-updater windows-crash-logger)
+elseif (SOLARIS)
+  add_subdirectory(solaris_crash_logger)
+  add_dependencies(viewer solaris-crash-logger)
 endif (LINUX)
-if (SERVER)
-  if (NOT LINUX)
-    add_custom_target(server)
-  endif (NOT LINUX)
-  include(${SERVER_PREFIX}Server.cmake)
-endif (SERVER)
-
-# Windows builds include tools like VFS tool
-if (SERVER)
-  if (WINDOWS)
-    add_subdirectory(${SERVER_PREFIX}tools)
-  endif (WINDOWS)
-endif (SERVER)
+
+add_subdirectory(${VIEWER_PREFIX}newview)
+add_dependencies(viewer secondlife-bin)
 
 if (LL_TESTS)
-  # Define after the custom viewer and server targets are created so
+  # Define after the custom targets are created so
   # individual apps can add themselves as dependencies
   add_subdirectory(${INTEGRATION_TESTS_PREFIX}integration_tests)
 endif (LL_TESTS)
diff --git a/indra/cmake/00-Common.cmake b/indra/cmake/00-Common.cmake
index 452fd5f35602e259915acab77a068d1bd6e16be4..fb5c759493672cfd968cb3a0535c01f59df91d80 100644
--- a/indra/cmake/00-Common.cmake
+++ b/indra/cmake/00-Common.cmake
@@ -2,6 +2,9 @@
 #
 # Compilation options shared by all Second Life components.
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(Variables)
 
 # Portable compilation flags.
@@ -150,41 +153,21 @@ if (LINUX)
       -pthread
       )
 
-  if (SERVER)
-    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ftemplate-depth-60")
-    if (EXISTS /etc/debian_version)
-      FILE(READ /etc/debian_version DEBIAN_VERSION)
-    else (EXISTS /etc/debian_version)
-      set(DEBIAN_VERSION "")
-    endif (EXISTS /etc/debian_version)
-
-    if (NOT DEBIAN_VERSION STREQUAL "3.1")
-      add_definitions(-DCTYPE_WORKAROUND)
-    endif (NOT DEBIAN_VERSION STREQUAL "3.1")
-
-    if (EXISTS /usr/lib/mysql4/mysql)
-      link_directories(/usr/lib/mysql4/mysql)
-    endif (EXISTS /usr/lib/mysql4/mysql)
-
-  endif (SERVER)
-
-  if (VIEWER)
-    add_definitions(-DAPPID=secondlife)
-    add_definitions(-fvisibility=hidden)
-    # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway.
-    add_definitions(-DLL_IGNORE_SIGCHLD)
-    if (WORD_SIZE EQUAL 32)
-      add_definitions(-march=pentium4)
-    endif (WORD_SIZE EQUAL 32)
-    add_definitions(-mfpmath=sse)
-    #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
-    if (NOT STANDALONE)
-      # this stops us requiring a really recent glibc at runtime
-      add_definitions(-fno-stack-protector)
-      # linking can be very memory-hungry, especially the final viewer link
-      set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
-    endif (NOT STANDALONE)
-  endif (VIEWER)
+  add_definitions(-DAPPID=secondlife)
+  add_definitions(-fvisibility=hidden)
+  # don't catch SIGCHLD in our base application class for the viewer - some of our 3rd party libs may need their *own* SIGCHLD handler to work.  Sigh!  The viewer doesn't need to catch SIGCHLD anyway.
+  add_definitions(-DLL_IGNORE_SIGCHLD)
+  if (WORD_SIZE EQUAL 32)
+    add_definitions(-march=pentium4)
+  endif (WORD_SIZE EQUAL 32)
+  add_definitions(-mfpmath=sse)
+  #add_definitions(-ftree-vectorize) # THIS CRASHES GCC 3.1-3.2
+  if (NOT STANDALONE)
+    # this stops us requiring a really recent glibc at runtime
+    add_definitions(-fno-stack-protector)
+    # linking can be very memory-hungry, especially the final viewer link
+    set(CMAKE_CXX_LINK_FLAGS "-Wl,--no-keep-memory")
+  endif (NOT STANDALONE)
 
   set(CMAKE_CXX_FLAGS_DEBUG "-fno-inline ${CMAKE_CXX_FLAGS_DEBUG}")
   set(CMAKE_CXX_FLAGS_RELEASE "-O2 ${CMAKE_CXX_FLAGS_RELEASE}")
@@ -198,7 +181,7 @@ if (DARWIN)
   # ucontext_t struct when _XOPEN_SOURCE is not defined (rdar://problem/5578699 ).
   # As a workaround, define _XOPEN_SOURCE before including ucontext.h.
   add_definitions(-DLL_DARWIN=1 -D_XOPEN_SOURCE)
-  set(CMAKE_CXX_LINK_FLAGS "-Wl,-headerpad_max_install_names,-search_paths_first")
+  set(CMAKE_CXX_LINK_FLAGS "-Wl,-no_compact_unwind -Wl,-headerpad_max_install_names,-search_paths_first")
   set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_CXX_LINK_FLAGS}")
   set(DARWIN_extra_cstar_flags "-mlong-branch -g")
   set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${DARWIN_extra_cstar_flags}")
@@ -254,6 +237,4 @@ else (STANDALONE)
       )
 endif (STANDALONE)
 
-if(SERVER)
-  include_directories(${LIBS_PREBUILT_DIR}/include/havok)
-endif(SERVER)
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/APR.cmake b/indra/cmake/APR.cmake
index daafa00fe27ef5e8d7093a4661683bf915e597fe..492ba2adea1249606fe704ad404f42b791e5a80e 100644
--- a/indra/cmake/APR.cmake
+++ b/indra/cmake/APR.cmake
@@ -49,9 +49,7 @@ else (STANDALONE)
   set(APR_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/apr-1)
 
   if (LINUX)
-    if (VIEWER)
-      list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
-    endif (VIEWER)
+    list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} uuid)
     list(APPEND APRUTIL_LIBRARIES ${DB_LIBRARIES} rt)
   endif (LINUX)
 endif (STANDALONE)
diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt
index acff0621d11e16e230a9836cd66e3a61194b7887..88e1f4a686d65dbd0611655538d93572b3ff63d6 100644
--- a/indra/cmake/CMakeLists.txt
+++ b/indra/cmake/CMakeLists.txt
@@ -14,48 +14,68 @@ set(cmake_SOURCE_FILES
     Boost.cmake
     BuildVersion.cmake
     CARes.cmake
-    CURL.cmake
     CMakeCopyIfDifferent.cmake
+    ConfigurePkgConfig.cmake
+    CURL.cmake
     Copy3rdPartyLibs.cmake
-    CSharpMacros.cmake
     DBusGlib.cmake
+    DeploySharedLibs.cmake
     DirectX.cmake
+    DragDrop.cmake
     EXPAT.cmake
+    ExamplePlugin.cmake
+    FMOD.cmake
     FindAPR.cmake
+    FindAutobuild.cmake
     FindBerkeleyDB.cmake
     FindCARes.cmake
     FindELFIO.cmake
     FindFMODEX.cmake
+    FindGLH.cmake
+    FindGoogleBreakpad.cmake
     FindGooglePerfTools.cmake
-    FindMono.cmake
-    FindMySQL.cmake
+    FindHUNSPELL.cmake
+    FindJsonCpp.cmake
+    FindNDOF.cmake
     FindOpenJPEG.cmake
+    FindSCP.cmake
     FindXmlRpcEpi.cmake
     FindZLIB.cmake
     FMODEX.cmake
     FreeType.cmake
+    GLEXT.cmake
+    GLH.cmake
     GLOD.cmake
     GStreamer010Plugin.cmake
+    GetPrerequisites_2_8.cmake
+    Glui.cmake
+    Glut.cmake
+    GoogleBreakpad.cmake
+    GoogleMock.cmake
     GooglePerfTools.cmake
+    Havok.cmake
     Hunspell.cmake
     JPEG.cmake
+    JsonCpp.cmake
     LLAddBuildTest.cmake
+    LLAppearance.cmake
+    LLAppearanceUtility.cmake
     LLAudio.cmake
     LLCharacter.cmake
     LLCommon.cmake
     LLCrashLogger.cmake
-    LLDatabase.cmake
     LLImage.cmake
     LLImageJ2COJ.cmake
     LLInventory.cmake
     LLKDU.cmake
+    LLLogin.cmake
     LLMath.cmake
     LLMessage.cmake
+    LLPhysicsExtensions.cmake
     LLPlugin.cmake
     LLPrimitive.cmake
-    LLPhysicsExtensions.cmake
     LLRender.cmake
-    LLScene.cmake
+    LLSharedLibs.cmake
     LLTestCommand.cmake
     LLUI.cmake
     LLVFS.cmake
@@ -63,21 +83,26 @@ set(cmake_SOURCE_FILES
     LLXML.cmake
     LScript.cmake
     Linking.cmake
-    MonoEmbed.cmake
-    MySQL.cmake
+    MediaPluginBase.cmake
     NDOF.cmake
     OPENAL.cmake
     OpenGL.cmake
     OpenJPEG.cmake
     OpenSSL.cmake
     PNG.cmake
-    Python.cmake
+    PluginAPI.cmake
     Prebuilt.cmake
+    PulseAudio.cmake
+    Python.cmake
+    QuickTimePlugin.cmake
     TemplateCheck.cmake
     Tut.cmake
     UI.cmake
     UnixInstall.cmake
     Variables.cmake
+    ViewerMiscLibs.cmake
+    VisualLeakDetector.cmake
+    WebKitLibPlugin.cmake
     XmlRpcEpi.cmake
     ZLIB.cmake
     )
@@ -88,10 +113,6 @@ set(master_SOURCE_FILES
     ../CMakeLists.txt
     )
 
-if (SERVER)
-  list(APPEND master_SOURCE_FILES ../Server.cmake)
-endif (SERVER)
-
 source_group("Master Rules" FILES ${master_SOURCE_FILES})
 
 set_source_files_properties(${cmake_SOURCE_FILES} ${master_SOURCE_FILES}
diff --git a/indra/cmake/CSharpMacros.cmake b/indra/cmake/CSharpMacros.cmake
deleted file mode 100644
index a4dd81504304db576763d0660552073da88fca3e..0000000000000000000000000000000000000000
--- a/indra/cmake/CSharpMacros.cmake
+++ /dev/null
@@ -1,142 +0,0 @@
-# - This is a support module for easy Mono/C# handling with CMake
-# It defines the following macros:
-#
-# ADD_CS_LIBRARY (<target> <source>)
-# ADD_CS_EXECUTABLE (<target> <source>)
-# INSTALL_GAC (<target>)
-#
-# Note that the order of the arguments is important.
-#
-# You can optionally set the variable CS_FLAGS to tell the macros whether
-# to pass additional flags to the compiler. This is particularly useful to
-# set assembly references, unsafe code, etc... These flags are always reset
-# after the target was added so you don't have to care about that.
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-
-
-# ----- support macros -----
-MACRO(GET_CS_LIBRARY_TARGET_DIR)
-        IF (NOT LIBRARY_OUTPUT_PATH)
-                SET(CS_LIBRARY_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
-        ELSE (NOT LIBRARY_OUTPUT_PATH)
-                SET(CS_LIBRARY_TARGET_DIR ${LIBRARY_OUTPUT_PATH})
-        ENDIF (NOT LIBRARY_OUTPUT_PATH)
-ENDMACRO(GET_CS_LIBRARY_TARGET_DIR)
-
-MACRO(GET_CS_EXECUTABLE_TARGET_DIR)
-        IF (NOT EXECUTABLE_OUTPUT_PATH)
-                SET(CS_EXECUTABLE_TARGET_DIR ${CMAKE_CURRENT_BINARY_DIR})
-        ELSE (NOT EXECUTABLE_OUTPUT_PATH)
-                SET(CS_EXECUTABLE_TARGET_DIR ${EXECUTABLE_OUTPUT_PATH})
-        ENDIF (NOT EXECUTABLE_OUTPUT_PATH)
-ENDMACRO(GET_CS_EXECUTABLE_TARGET_DIR)
-
-MACRO(MAKE_PROPER_FILE_LIST)
-        FOREACH(file ${ARGN})
-                # first assume it's a relative path
-                FILE(GLOB globbed ${CMAKE_CURRENT_SOURCE_DIR}/${file})
-                IF(globbed)
-                        FILE(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/${file} native)
-                ELSE(globbed)
-                        FILE(TO_NATIVE_PATH ${file} native)
-                ENDIF(globbed)
-                SET(proper_file_list ${proper_file_list} ${native})
-                SET(native "")
-        ENDFOREACH(file)
-ENDMACRO(MAKE_PROPER_FILE_LIST)
-# ----- end support macros -----
-
-MACRO(ADD_CS_LIBRARY target)
-        GET_CS_LIBRARY_TARGET_DIR()
-        
-        SET(target_DLL "${CS_LIBRARY_TARGET_DIR}/${target}.dll")
-        MAKE_PROPER_FILE_LIST(${ARGN})
-        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_DLL})
-        
-        SET(target_KEY "${CMAKE_CURRENT_SOURCE_DIR}/${target}.key")
-        SET(target_CS_FLAGS "${CS_FLAGS}")
-        IF(${target}_CS_FLAGS)
-                LIST(APPEND target_CS_FLAGS ${${target}_CS_FLAGS})
-        ENDIF(${target}_CS_FLAGS)
-        IF(EXISTS ${target_KEY})
-                LIST(APPEND target_CS_FLAGS -keyfile:${target_KEY})
-        ENDIF(EXISTS ${target_KEY})
-
-        FOREACH(ref ${${target}_REFS})
-                SET(ref_DLL ${CMAKE_CURRENT_BINARY_DIR}/${ref}.dll)
-                IF(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
-                ELSE(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref})
-                ENDIF(EXISTS ${ref_DLL})
-        ENDFOREACH(ref ${${target}_REFS})
-
-        ADD_CUSTOM_COMMAND (OUTPUT ${target_DLL}
-                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_DLL} -target:library ${proper_file_list}
-                MAIN_DEPENDENCY ${proper_file_list}
-                DEPENDS ${ARGN}
-                COMMENT "Building ${relative_path}")
-        ADD_CUSTOM_TARGET (${target} ALL DEPENDS ${target_DLL})
-
-        FOREACH(ref ${${target}_REFS})
-                GET_TARGET_PROPERTY(is_target ${ref} TYPE)
-                IF(is_target)
-                        ADD_DEPENDENCIES(${target} ${ref})
-                ENDIF(is_target)
-        ENDFOREACH(ref ${${target}_REFS})
-
-        SET(relative_path "")
-        SET(proper_file_list "")
-ENDMACRO(ADD_CS_LIBRARY)
-
-MACRO(ADD_CS_EXECUTABLE target)
-        GET_CS_EXECUTABLE_TARGET_DIR()
-        
-        # Seems like cmake doesn't like the ".exe" ending for custom commands.
-        # If we call it ${target}.exe, 'make' will later complain about a missing rule.
-        # Create a fake target instead.
-        SET(target_EXE "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe")
-        SET(target_TOUCH "${CS_EXECUTABLE_TARGET_DIR}/${target}.exe-built")
-        GET_DIRECTORY_PROPERTY(clean ADDITIONAL_MAKE_CLEAN_FILES)
-        LIST(APPEND clean ${target}.exe)
-        SET_DIRECTORY_PROPERTIES(PROPERTIES ADDITIONAL_MAKE_CLEAN_FILES "${clean}")
-        MAKE_PROPER_FILE_LIST(${ARGN})
-        FILE(RELATIVE_PATH relative_path ${CMAKE_BINARY_DIR} ${target_EXE})
-        SET(target_CS_FLAGS "${CS_FLAGS}")
-        
-        FOREACH(ref ${${target}_REFS})
-                SET(ref_DLL ${CMAKE_CURRENT_SOURCE_DIR}/${ref}.dll)
-                IF(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref_DLL})
-                ELSE(EXISTS ${ref_DLL})
-                        LIST(APPEND target_CS_FLAGS -r:${ref})
-                ENDIF(EXISTS ${ref_DLL})
-        ENDFOREACH(ref ${${target}_REFS})
-
-        ADD_CUSTOM_COMMAND (OUTPUT "${target_TOUCH}"
-                COMMAND ${MCS_EXECUTABLE} ${target_CS_FLAGS} -out:${target_EXE} ${proper_file_list}
-                COMMAND ${CMAKE_COMMAND} -E touch ${target_TOUCH}
-                MAIN_DEPENDENCY ${ARGN}
-                DEPENDS ${ARGN}
-                COMMENT "Building ${relative_path}")
-        ADD_CUSTOM_TARGET ("${target}" ALL DEPENDS "${target_TOUCH}")
-
-        FOREACH(ref ${${target}_REFS})
-                GET_TARGET_PROPERTY(is_target ${ref} TYPE)
-                IF(is_target)
-                        ADD_DEPENDENCIES(${target} ${ref})
-                ENDIF(is_target)
-        ENDFOREACH(ref ${${target}_REFS})
-
-        SET(relative_path "")
-        SET(proper_file_list "")
-ENDMACRO(ADD_CS_EXECUTABLE)
-
-MACRO(INSTALL_GAC target)
-        GET_CS_LIBRARY_TARGET_DIR()
-        
-        INSTALL(CODE "EXECUTE_PROCESS(COMMAND ${GACUTIL_EXECUTABLE} -i ${CS_LIBRARY_TARGET_DIR}/${target}.dll -package 2.0)")
-ENDMACRO(INSTALL_GAC target)
diff --git a/indra/cmake/ConfigurePkgConfig.cmake b/indra/cmake/ConfigurePkgConfig.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..82ee3e7a5b54d107e852ea17bab037c76c3d9c16
--- /dev/null
+++ b/indra/cmake/ConfigurePkgConfig.cmake
@@ -0,0 +1,74 @@
+# -*- cmake -*-
+
+SET(DEBUG_PKG_CONFIG "YES")
+
+# Don't change this if manually set by user.
+IF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+  # Guess at architecture-specific system library paths.
+  if (WORD_SIZE EQUAL 32)
+    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib32 /usr/lib)
+    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib32 /usr/local/lib)
+    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/i386-linux-gnu)
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/i386-linux-gnu)
+  else (WORD_SIZE EQUAL 32)
+    SET(PKG_CONFIG_NO_MULTI_GUESS /usr/lib64 /usr/lib)
+    SET(PKG_CONFIG_NO_MULTI_LOCAL_GUESS /usr/local/lib64 /usr/local/lib)
+    SET(PKG_CONFIG_MULTI_GUESS /usr/local/lib/x86_64-linux-gnu)
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usr/local/lib/x86_64-linux-gnu)
+  endif (WORD_SIZE EQUAL 32)
+  
+  # Use DPKG architecture, if available.
+  IF (${DPKG_ARCH})
+    SET(PKG_CONFIG_MULTI_GUESS /usr/lib/${DPKG_ARCH})
+    SET(PKG_CONFIG_MULTI_LOCAL_GUESS /usrlocal/lib/${DPKG_ARCH})
+  ENDIF (${DPKG_ARCH})
+  
+  # Explicitly include anything listed in PKG_CONFIG_PATH
+  string(REPLACE ":" ";" PKG_CONFIG_PATH_LIST "$ENV{PKG_CONFIG_PATH}")
+  FOREACH(PKG_CONFIG_DIR ${PKG_CONFIG_PATH_LIST})
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_DIR}/pkgconfig")
+  ENDFOREACH(PKG_CONFIG_DIR)
+
+  # Look for valid pkgconfig directories.
+  FIND_PATH(PKG_CONFIG_ENV pkgconfig ENV LD_LIBRARY_PATH)
+  FIND_PATH(PKG_CONFIG_MULTI pkgconfig HINT ${PKG_CONFIG_MULTI_GUESS})
+  FIND_PATH(PKG_CONFIG_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_MULTI_LOCAL_GUESS})
+  FIND_PATH(PKG_CONFIG_NO_MULTI pkgconfig HINT ${PKG_CONFIG_NO_MULTI_GUESS})
+  FIND_PATH(PKG_CONFIG_NO_MULTI_LOCAL pkgconfig HINT ${PKG_CONFIG_NO_MULTI_LOCAL_GUESS})
+
+  # Add anything we found to our list.
+  IF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_ENV}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_ENV STREQUAL PKG_CONFIG_ENV-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_MULTI STREQUAL PKG_CONFIG_MULTI-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_MULTI_LOCAL}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_MULTI_LOCAL STREQUAL PKG_CONFIG_MULTI_LOCAL-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_NO_MULTI STREQUAL PKG_CONFIG_NO_MULTI-NOTFOUND) 
+
+  IF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) 
+    SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:${PKG_CONFIG_NO_MULTI_LOCAL}/pkgconfig")
+  ENDIF(NOT PKG_CONFIG_NO_MULTI_LOCAL STREQUAL PKG_CONFIG_NO_MULTI_LOCAL-NOTFOUND) 
+
+  # Also add some non-architecture specific package locations.
+  SET(VALID_PKG_LIBDIRS "${VALID_PKG_LIBDIRS}:/usr/share/pkgconfig:/usr/local/share/pkgconfig")
+
+  # Remove first unwanted ':'
+  string(SUBSTRING ${VALID_PKG_LIBDIRS} 1 -1 VALID_PKG_LIBDIRS)
+
+  # Set PKG_CONFIG_LIBDIR environment.
+  SET(ENV{PKG_CONFIG_LIBDIR} ${VALID_PKG_LIBDIRS})
+ENDIF("$ENV{PKG_CONFIG_LIBDIR}" STREQUAL "")
+
+IF(DEBUG_PKG_CONFIG)
+  MESSAGE(STATUS "Using PKG_CONFIG_LIBDIR=$ENV{PKG_CONFIG_LIBDIR}")
+ENDIF(DEBUG_PKG_CONFIG)
+
diff --git a/indra/cmake/Copy3rdPartyLibs.cmake b/indra/cmake/Copy3rdPartyLibs.cmake
index b9101dbf537ed5a8ba57546bf421f5d94f3abde8..ef529c32d329a42239439eb29990220d9b26bb8f 100644
--- a/indra/cmake/Copy3rdPartyLibs.cmake
+++ b/indra/cmake/Copy3rdPartyLibs.cmake
@@ -267,7 +267,7 @@ elseif(LINUX)
         libdb-5.1.so
         libexpat.so
         libexpat.so.1
-        libglod.so
+        libGLOD.so
         libgmock_main.so
         libgmock.so.0
         libgmodule-2.0.so
diff --git a/indra/cmake/CopyBackToSource.cmake b/indra/cmake/CopyBackToSource.cmake
deleted file mode 100644
index d217df9aecf1f05284525cbad1d3132af94a1b88..0000000000000000000000000000000000000000
--- a/indra/cmake/CopyBackToSource.cmake
+++ /dev/null
@@ -1,16 +0,0 @@
-# -*- cmake -*-
-# Copies a binary back to the source directory
-
-MACRO(COPY_BACK_TO_SOURCE target)
-   GET_TARGET_PROPERTY(FROM ${target} LOCATION)
-   SET(TO ${CMAKE_CURRENT_SOURCE_DIR})
-   #MESSAGE("TARGET ${target} POST_BUILD COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}")
-   ADD_CUSTOM_COMMAND(
-        TARGET ${target} POST_BUILD
-        COMMAND ${CMAKE_COMMAND} -E copy ${FROM} ${TO}
-        DEPENDS ${FROM}
-        COMMENT "Copying ${target} to ${CMAKE_CURRENT_BINARY_DIR}"
-        )
-ENDMACRO(COPY_BACK_TO_SOURCE)
-
-
diff --git a/indra/cmake/DirectX.cmake b/indra/cmake/DirectX.cmake
index b2a18805d478fc5cd12633a1464999d7900cda72..25163d03226dbdfba43492d921635cb82e814549 100644
--- a/indra/cmake/DirectX.cmake
+++ b/indra/cmake/DirectX.cmake
@@ -1,8 +1,9 @@
 # -*- cmake -*-
 
-if (VIEWER AND WINDOWS)
+if (WINDOWS)
   find_path(DIRECTX_INCLUDE_DIR dxdiag.h
             "$ENV{DXSDK_DIR}/Include"
+            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Include"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Include"
@@ -25,6 +26,7 @@ if (VIEWER AND WINDOWS)
 
   find_path(DIRECTX_LIBRARY_DIR dxguid.lib
             "$ENV{DXSDK_DIR}/Lib/x86"
+            "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (June 2010)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2009)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (March 2009)/Lib/x86"
             "$ENV{PROGRAMFILES}/Microsoft DirectX SDK (August 2008)/Lib/x86"
@@ -43,4 +45,4 @@ if (VIEWER AND WINDOWS)
     message(FATAL_ERROR "Could not find DirectX SDK Libraries")
   endif (DIRECTX_LIBRARY_DIR)
 
-endif (VIEWER AND WINDOWS)
+endif (WINDOWS)
diff --git a/indra/cmake/DragDrop.cmake b/indra/cmake/DragDrop.cmake
index c0424396e5f83109aa29b45457b03bad91289388..b70aa6b6ee8c28c3b3887ac961cbafd0227a4160 100644
--- a/indra/cmake/DragDrop.cmake
+++ b/indra/cmake/DragDrop.cmake
@@ -1,23 +1,20 @@
 # -*- cmake -*-
 
-if (VIEWER)
+set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
 
-  set(OS_DRAG_DROP ON CACHE BOOL "Build the viewer with OS level drag and drop turned on or off")
+if (OS_DRAG_DROP)
 
-  if (OS_DRAG_DROP)
+  if (WINDOWS)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+  endif (WINDOWS)
 
-    if (WINDOWS)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
-    endif (WINDOWS)
+  if (DARWIN)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
+  endif (DARWIN)
 
-    if (DARWIN)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=1)
-    endif (DARWIN)
+  if (LINUX)
+    add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
+  endif (LINUX)
 
-    if (LINUX)
-      add_definitions(-DLL_OS_DRAGDROP_ENABLED=0)
-    endif (LINUX)
+endif (OS_DRAG_DROP)
 
-  endif (OS_DRAG_DROP)
-
-endif (VIEWER)
diff --git a/indra/cmake/Externals.cmake b/indra/cmake/Externals.cmake
deleted file mode 100644
index 26f3b5604937a781490838532276b2e67717e8d1..0000000000000000000000000000000000000000
--- a/indra/cmake/Externals.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-
-include(Python)
-include(FindSVN)
-
-macro (use_svn_external _binary _path _url _rev)
-  if (NOT STANDALONE)
-    if(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-      if(SVN_FOUND)
-        if(DEBUG_EXTERNALS)
-          message("cd ${_path} && ${SVN_EXECUTABLE} checkout -r ${_rev} ${_url} ${_binary}")
-        endif(DEBUG_EXTERNALS)
-        execute_process(COMMAND ${SVN_EXECUTABLE}
-          checkout
-          -r ${_rev}
-          ${_url}
-          ${_binary}
-          WORKING_DIRECTORY ${_path}
-          RESULT_VARIABLE ${_binary}_installed
-          )
-      else(SVN_FOUND)
-        message(FATAL_ERROR "Failed to find SVN_EXECUTABLE")
-      endif(SVN_FOUND)
-      file(WRITE ${CMAKE_BINARY_DIR}/temp/${_binary}_installed "${${_binary}_installed}")
-    else(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-      set(${_binary}_installed 0)
-    endif(${CMAKE_BINARY_DIR}/temp/sentinel_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/${_binary}_installed)
-    if(NOT ${_binary}_installed EQUAL 0)
-      message(FATAL_ERROR
-              "Failed to download or unpack prebuilt '${_binary}'."
-              " Process returned ${${_binary}_installed}.")
-    endif (NOT ${_binary}_installed EQUAL 0)
-  endif (NOT STANDALONE)
-endmacro (use_svn_external _binary _path _url _rev)
diff --git a/indra/cmake/FindELFIO.cmake b/indra/cmake/FindELFIO.cmake
deleted file mode 100644
index 8a5421ab9c8e636cc16abc9c826ddf6efb42d223..0000000000000000000000000000000000000000
--- a/indra/cmake/FindELFIO.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find ELFIO
-# Find the ELFIO includes and library
-# This module defines
-#  ELFIO_INCLUDE_DIR, where to find elfio.h, etc.
-#  ELFIO_LIBRARIES, the libraries needed to use ELFIO.
-#  ELFIO_FOUND, If false, do not try to use ELFIO.
-# also defined, but not for general use are
-#  ELFIO_LIBRARY, where to find the ELFIO library.
-
-FIND_PATH(ELFIO_INCLUDE_DIR ELFIO/ELFIO.h
-/usr/local/include
-/usr/include
-)
-
-SET(ELFIO_NAMES ${ELFIO_NAMES} ELFIO)
-FIND_LIBRARY(ELFIO_LIBRARY
-  NAMES ${ELFIO_NAMES}
-  PATHS /usr/lib /usr/local/lib
-  )
-
-IF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-    SET(ELFIO_LIBRARIES ${ELFIO_LIBRARY})
-    SET(ELFIO_FOUND "YES")
-ELSE (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-  SET(ELFIO_FOUND "NO")
-ENDIF (ELFIO_LIBRARY AND ELFIO_INCLUDE_DIR)
-
-
-IF (ELFIO_FOUND)
-   IF (NOT ELFIO_FIND_QUIETLY)
-      MESSAGE(STATUS "Found ELFIO: ${ELFIO_LIBRARIES}")
-   ENDIF (NOT ELFIO_FIND_QUIETLY)
-ELSE (ELFIO_FOUND)
-   IF (ELFIO_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find ELFIO library")
-   ENDIF (ELFIO_FIND_REQUIRED)
-ENDIF (ELFIO_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_ELFIO_INCLUDE_PATH ${ELFIO_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_ELFIO_LIB_PATH ${ELFIO_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  ELFIO_LIBRARY
-  ELFIO_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindLLQtWebkit.cmake b/indra/cmake/FindLLQtWebkit.cmake
deleted file mode 100644
index 2f666d3bf01e42587c340f7bbfbe94e7b54bb04b..0000000000000000000000000000000000000000
--- a/indra/cmake/FindLLQtWebkit.cmake
+++ /dev/null
@@ -1,62 +0,0 @@
-# -*- cmake -*-
-
-# - Find llqtwebkit
-# Find the llqtwebkit includes and library
-# This module defines
-#  LLQTWEBKIT_INCLUDE_DIR, where to find llqtwebkit.h, etc.
-#  LLQTWEBKIT_LIBRARY, the llqtwebkit library with full path.
-#  LLQTWEBKIT_FOUND, If false, do not try to use llqtwebkit.
-# also defined, but not for general use are
-#  LLQTWEBKIT_LIBRARIES, the libraries needed to use llqtwebkit.
-#  LLQTWEBKIT_LIBRARY_DIRS, where to find the llqtwebkit library.
-#  LLQTWEBKIT_DEFINITIONS - You should add_definitions(${LLQTWEBKIT_DEFINITIONS})
-#      before compiling code that includes llqtwebkit library files.
-
-# Try to use pkg-config first.
-# This allows to have two different libllqtwebkit packages installed:
-# one for viewer 2.x and one for viewer 1.x.
-include(FindPkgConfig)
-if (PKG_CONFIG_FOUND)
-    if (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-        set(_PACKAGE_ARGS libllqtwebkit>=${LLQtWebkit_FIND_VERSION} REQUIRED)
-    else (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-        set(_PACKAGE_ARGS libllqtwebkit)
-    endif (LLQtWebkit_FIND_REQUIRED AND LLQtWebkit_FIND_VERSION)
-    if (NOT "${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION}.${CMAKE_PATCH_VERSION}" VERSION_LESS "2.8.2")
-      # As virtually nobody will have a pkg-config file for this, do this check always quiet.
-      # Unfortunately cmake 2.8.2 or higher is required for pkg_check_modules to have a 'QUIET'.
-      set(_PACKAGE_ARGS ${_PACKAGE_ARGS} QUIET)
-    endif ()
-    pkg_check_modules(LLQTWEBKIT ${_PACKAGE_ARGS})
-endif (PKG_CONFIG_FOUND)
-set(LLQTWEBKIT_DEFINITIONS ${LLQTWEBKIT_CFLAGS_OTHER})
-
-find_path(LLQTWEBKIT_INCLUDE_DIR llqtwebkit.h NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_INCLUDE_DIRS})
-
-find_library(LLQTWEBKIT_LIBRARY NAMES llqtwebkit NO_SYSTEM_ENVIRONMENT_PATH HINTS ${LLQTWEBKIT_LIBRARY_DIRS})
-
-if (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)   # If pkg-config couldn't find it, pretend we don't have pkg-config.
-   set(LLQTWEBKIT_LIBRARIES llqtwebkit)
-   get_filename_component(LLQTWEBKIT_LIBRARY_DIRS ${LLQTWEBKIT_LIBRARY} PATH)
-endif (NOT PKG_CONFIG_FOUND OR NOT LLQTWEBKIT_FOUND)
-
-# Handle the QUIETLY and REQUIRED arguments and set LLQTWEBKIT_FOUND
-# to TRUE if all listed variables are TRUE.
-include(FindPackageHandleStandardArgs)
-find_package_handle_standard_args(
-  LLQTWEBKIT
-  DEFAULT_MSG
-  LLQTWEBKIT_LIBRARY
-  LLQTWEBKIT_INCLUDE_DIR
-  LLQTWEBKIT_LIBRARIES
-  LLQTWEBKIT_LIBRARY_DIRS
-  )
-
-mark_as_advanced(
-  LLQTWEBKIT_LIBRARY
-  LLQTWEBKIT_INCLUDE_DIR
-  LLQTWEBKIT_LIBRARIES
-  LLQTWEBKIT_LIBRARY_DIRS
-  LLQTWEBKIT_DEFINITIONS
-  )
-
diff --git a/indra/cmake/FindMT.cmake b/indra/cmake/FindMT.cmake
deleted file mode 100644
index 5239a4c2f5a549c5c2e4ecd143640904618d6da2..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMT.cmake
+++ /dev/null
@@ -1,15 +0,0 @@
-#Find the windows manifest tool.
-
-FIND_PROGRAM(HAVE_MANIFEST_TOOL NAMES mt
-                 PATHS
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/VC/bin"
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/Common7/Tools/Bin"
-                 "$ENV{PROGRAMFILES}/Microsoft Visual Studio 8/SDK/v2.0/Bin")
-IF(HAVE_MANIFEST_TOOL)
-    MESSAGE(STATUS "Found Mainfest Tool. Embedding custom manifests.")
-ELSE(HAVE_MANIFEST_TOOL)
-    MESSAGE(FATAL_ERROR "Manifest tool, mt.exe, can't be found.")
-ENDIF(HAVE_MANIFEST_TOOL)
-
-STRING(REPLACE "/MANIFEST" "/MANIFEST:NO" CMAKE_EXE_LINKER_FLAGS 
-      ${CMAKE_EXE_LINKER_FLAGS})
diff --git a/indra/cmake/FindMono.cmake b/indra/cmake/FindMono.cmake
deleted file mode 100644
index d956c48656a51db6a691688e6fcafff91f432560..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMono.cmake
+++ /dev/null
@@ -1,68 +0,0 @@
-# - Try to find the mono, mcs, gmcs and gacutil
-#
-# defines
-#
-# MONO_FOUND - system has mono, mcs, gmcs and gacutil
-# MONO_PATH - where to find 'mono'
-# MCS_PATH - where to find 'mcs'
-# GMCS_PATH - where to find 'gmcs'
-# GACUTIL_PATH - where to find 'gacutil'
-#
-# copyright (c) 2007 Arno Rehn arno@arnorehn.de
-#
-# Redistribution and use is allowed according to the terms of the GPL license.
-# Removed the check for gmcs
-
-FIND_PROGRAM (MONO_EXECUTABLE mono
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (MCS_EXECUTABLE mcs
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (GMCS_EXECUTABLE gmcs
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (GACUTIL_EXECUTABLE gacutil
-             "$ENV{PROGRAMFILES}/Mono-1.9.1/bin"
-             "$ENV{PROGRAMFILES}/Mono-1.2.6/bin"
-             /bin
-             /usr/bin
-             /usr/local/bin
-)
-FIND_PROGRAM (ILASM_EXECUTABLE
-             NAMES ilasm.bat ilasm
-             NO_DEFAULT_PATH
-             PATHS "$ENV{PROGRAMFILES}/Mono-1.9.1/bin" "$ENV{PROGRAMFILES}/Mono-1.2.6/bin" /bin /usr/bin /usr/local/bin
-)
-
-SET (MONO_FOUND FALSE)
-
-IF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
-        SET (MONO_FOUND TRUE)
-ENDIF (MONO_EXECUTABLE AND MCS_EXECUTABLE AND GACUTIL_EXECUTABLE)
-
-IF (MONO_FOUND)
-        IF (NOT Mono_FIND_QUIETLY)
-                MESSAGE(STATUS "Found mono: ${MONO_EXECUTABLE}")
-                MESSAGE(STATUS "Found mcs: ${MCS_EXECUTABLE}")
-                MESSAGE(STATUS "Found gacutil: ${GACUTIL_EXECUTABLE}")
-        ENDIF (NOT Mono_FIND_QUIETLY)
-ELSE (MONO_FOUND)
-        IF (Mono_FIND_REQUIRED)
-                MESSAGE(FATAL_ERROR "Could not find one or more of the following programs: mono, mcs, gacutil")
-        ENDIF (Mono_FIND_REQUIRED)
-ENDIF (MONO_FOUND)
-
-MARK_AS_ADVANCED(MONO_EXECUTABLE MCS_EXECUTABLE GACUTIL_EXECUTABLE)
diff --git a/indra/cmake/FindMySQL.cmake b/indra/cmake/FindMySQL.cmake
deleted file mode 100644
index 431940328f97ddcc81c0cb802fd094782cbb49d5..0000000000000000000000000000000000000000
--- a/indra/cmake/FindMySQL.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-# - Find MySQL
-# Find the MySQL includes and library
-# This module defines
-#  MYSQL_INCLUDE_DIR, where to find mysql.h, etc.
-#  MYSQL_LIBRARIES, the libraries needed to use Mysql.
-#  MYSQL_FOUND, If false, do not try to use Mysql.
-# also defined, but not for general use are
-#  MYSQL_LIBRARY, where to find the Mysql library.
-
-FIND_PATH(MYSQL_INCLUDE_DIR mysql/mysql.h
-/usr/local/include
-/usr/include
-)
-
-SET(MYSQL_NAMES ${MYSQL_NAMES} mysqlclient)
-FIND_LIBRARY(MYSQL_LIBRARY
-  NAMES ${MYSQL_NAMES}
-  PATHS /usr/lib/mysql /usr/lib /usr/local/lib/mysql /usr/local/lib
-  )
-
-IF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-    SET(MYSQL_LIBRARIES ${MYSQL_LIBRARY})
-    SET(MYSQL_FOUND "YES")
-ELSE (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-  SET(MYSQL_FOUND "NO")
-ENDIF (MYSQL_LIBRARY AND MYSQL_INCLUDE_DIR)
-
-
-IF (MYSQL_FOUND)
-   IF (NOT MYSQL_FIND_QUIETLY)
-      MESSAGE(STATUS "Found MySQL: ${MYSQL_LIBRARIES}")
-   ENDIF (NOT MYSQL_FIND_QUIETLY)
-ELSE (MYSQL_FOUND)
-   IF (MYSQL_FIND_REQUIRED)
-      MESSAGE(FATAL_ERROR "Could not find MySQL library")
-   ENDIF (MYSQL_FIND_REQUIRED)
-ENDIF (MYSQL_FOUND)
-
-# Deprecated declarations.
-SET (NATIVE_MYSQL_INCLUDE_PATH ${MYSQL_INCLUDE_DIR} )
-GET_FILENAME_COMPONENT (NATIVE_MYSQL_LIB_PATH ${MYSQL_LIBRARY} PATH)
-
-MARK_AS_ADVANCED(
-  MYSQL_LIBRARY
-  MYSQL_INCLUDE_DIR
-  )
diff --git a/indra/cmake/FindSVN.cmake b/indra/cmake/FindSVN.cmake
deleted file mode 100644
index 3322be4ca9213bffcae36da3922d4ef8e539ecd1..0000000000000000000000000000000000000000
--- a/indra/cmake/FindSVN.cmake
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- cmake -*-
-#
-# Find the svn executable for exporting old svn:externals.
-#
-# Input variables:
-#   SVN_FIND_REQUIRED - set this if configuration should fail without scp
-#
-# Output variables:
-#
-#   SVN_FOUND - set if svn was found
-#   SVN_EXECUTABLE - path to svn executable
-#   SVN_BATCH_FLAG - how to put svn into batch mode
-
-
-SET(SVN_EXECUTABLE)
-FIND_PROGRAM(SVN_EXECUTABLE NAMES svn svn.exe)
-
-IF (SVN_EXECUTABLE)
-  SET(SVN_FOUND ON)
-ELSE (SVN_EXECUTABLE)
-  SET(SVN_FOUND OFF)
-ENDIF (SVN_EXECUTABLE)
-
-IF (SVN_FOUND)
-  GET_FILENAME_COMPONENT(_svn_name ${SVN_EXECUTABLE} NAME_WE)
-  SET(SVN_BATCH_FLAG --non-interactive)
-ELSE (SVN_FOUND)
-  IF (SVN_FIND_REQUIRED)
-    MESSAGE(FATAL_ERROR "Could not find svn executable")
-  ENDIF (SVN_FIND_REQUIRED)
-ENDIF (SVN_FOUND)
-
-MARK_AS_ADVANCED(SVN_EXECUTABLE SVN_FOUND SVN_BATCH_FLAG)
-
diff --git a/indra/cmake/GLEXT.cmake b/indra/cmake/GLEXT.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..0a3dd976b43354adf1d5d2768356e95b004fc10e
--- /dev/null
+++ b/indra/cmake/GLEXT.cmake
@@ -0,0 +1,8 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+if (NOT STANDALONE)
+  use_prebuilt_binary(glext)
+  use_prebuilt_binary(glh_linear)
+  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
+endif (NOT STANDALONE)
diff --git a/indra/cmake/GLOD.cmake b/indra/cmake/GLOD.cmake
index 77221d55ede01056ed6b2e83228173907b064a03..6bdbaf621edf12e714299791c2cba7f675a11fbd 100644
--- a/indra/cmake/GLOD.cmake
+++ b/indra/cmake/GLOD.cmake
@@ -6,4 +6,4 @@ if (NOT STANDALONE)
 endif (NOT STANDALONE)
 
 set(GLOD_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-set(GLOD_LIBRARIES glod)
+set(GLOD_LIBRARIES GLOD)
diff --git a/indra/cmake/GooglePerfTools.cmake b/indra/cmake/GooglePerfTools.cmake
index 73b3642ae646c3e5ff493157e92d32b9fcb7c9fb..f3fd008e492cb99183507e4acfc980f69ef301a2 100644
--- a/indra/cmake/GooglePerfTools.cmake
+++ b/indra/cmake/GooglePerfTools.cmake
@@ -10,7 +10,7 @@ if (STANDALONE)
 else (STANDALONE)
   if (WINDOWS)
     if (USE_TCMALLOC)
-       use_prebuilt_binary(tcmalloc)
+       use_prebuilt_binary(gperftools)
        set(TCMALLOC_LIBRARIES 
          debug libtcmalloc_minimal-debug
          optimized libtcmalloc_minimal)
@@ -23,7 +23,7 @@ else (STANDALONE)
   endif (WINDOWS)
   if (LINUX)
     if (USE_TCMALLOC)
-      use_prebuilt_binary(tcmalloc)
+      use_prebuilt_binary(gperftools)
       set(TCMALLOC_LIBRARIES 
         tcmalloc)
     else (USE_TCMALLOC)
diff --git a/indra/cmake/Havok.cmake b/indra/cmake/Havok.cmake
index 5c0768abfa91c50ed25b72ce219fd890c5c651ac..44f81ce332a92a6b77b786d2e88773bb70ed7aca 100644
--- a/indra/cmake/Havok.cmake
+++ b/indra/cmake/Havok.cmake
@@ -1,6 +1,10 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 use_prebuilt_binary(havok-source)
+
 set(Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Source)
 list(APPEND Havok_INCLUDE_DIRS ${LIBS_PREBUILT_DIR}/include/havok/Demo)
 
@@ -8,14 +12,14 @@ set(HAVOK_DEBUG_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
 set(HAVOK_RELEASE_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
 
 if (LL_DEBUG_HAVOK)
-   if (WIN32)
-      # Always link relwithdebinfo to havok-hybrid on windows.
-      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
-   else (WIN32)
-      set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
-   endif (WIN32)
+  if (WIN32)
+    # Always link relwithdebinfo to havok-hybrid on windows.
+    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-hybrid)
+  else (WIN32)
+    set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/debug/havok-fulldebug)
+  endif (WIN32)
 else (LL_DEBUG_HAVOK)
-   set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
+  set(HAVOK_RELWITHDEBINFO_LIBRARY_PATH ${LIBS_PREBUILT_DIR}/lib/release/havok)
 endif (LL_DEBUG_HAVOK)
 
 set(HAVOK_LIBS
@@ -45,39 +49,89 @@ unset(HK_DEBUG_LIBRARIES)
 unset(HK_RELEASE_LIBRARIES)
 unset(HK_RELWITHDEBINFO_LIBRARIES)
 
+# *TODO: Figure out why we need to extract like this...
 foreach(HAVOK_LIB ${HAVOK_LIBS})
-        find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
-        find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
-        find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
-        
-        if(LINUX)
-            set(cmd "mkdir")
-            set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
-            set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
-
-            exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
-
-            set(cmd "ar")
-            set(arg " -xv")
-            set(arg "${arg} ../lib${HAVOK_LIB}.a")
-            exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-            exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
-
-            file(GLOB extracted_debug "${debug_dir}/*.o")
-            file(GLOB extracted_release "${release_dir}/*.o")
-            file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
-            list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
-            list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
-        else(LINUX)
-        # Win32
-            list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
-            list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
-        endif (LINUX)
+  find_library(HAVOK_DEBUG_LIB_${HAVOK_LIB}   ${HAVOK_LIB} PATHS ${HAVOK_DEBUG_LIBRARY_PATH})
+  find_library(HAVOK_RELEASE_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELEASE_LIBRARY_PATH})
+  find_library(HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB} ${HAVOK_LIB} PATHS ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH})
+  
+  if(LINUX)
+    set(debug_dir "${HAVOK_DEBUG_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(release_dir "${HAVOK_RELEASE_LIBRARY_PATH}/${HAVOK_LIB}")
+    set(relwithdebinfo_dir "${HAVOK_RELWITHDEBINFO_LIBRARY_PATH}/${HAVOK_LIB}")
+
+    # Try to avoid extracting havok library each time we run cmake.
+    if("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+      file(READ ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "havok_${HAVOK_LIB}_extracted")
+      if(DEBUG_PREBUILT)
+        message(STATUS "havok_${HAVOK_LIB}_extracted: \"${havok_${HAVOK_LIB}_extracted}\"")
+      endif(DEBUG_PREBUILT)
+    endif("${havok_${HAVOK_LIB}_extracted}" STREQUAL "" AND EXISTS "${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted")
+
+    if(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "Extracting ${HAVOK_LIB}...")
+      endif(DEBUG_PREBUILT)
+      set(cmd "mkdir")
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${debug_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_DEBUG_LIBRARY_PATH} ARGS ${debug_dir} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${release_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_RELEASE_LIBRARY_PATH} ARGS ${release_dir} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "${cmd} ${relwithdebinfo_dir}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${HAVOK_RELWITHDEBINFO_LIBRARY_PATH} ARGS ${relwithdebinfo_dir} OUTPUT_VARIABLE rv)
+
+      set(cmd "ar")
+      set(arg " -xv")
+      set(arg "${arg} ../lib${HAVOK_LIB}.a")
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${debug_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${debug_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${release_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${release_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      if(DEBUG_PREBUILT)
+        MESSAGE(STATUS "cd ${relwithdebinfo_dir} && ${cmd} ${arg}")
+      endif(DEBUG_PREBUILT)
+      exec_program( ${cmd} ${relwithdebinfo_dir} ARGS ${arg} OUTPUT_VARIABLE rv)
+
+      # Just assume success for now.
+      set(havok_${HAVOK_LIB}_extracted 0)
+      file(WRITE ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted "${havok_${HAVOK_LIB}_extracted}")
+
+    endif(${CMAKE_BINARY_DIR}/temp/havok-source_installed IS_NEWER_THAN ${CMAKE_BINARY_DIR}/temp/havok_${HAVOK_LIB}_extracted OR NOT ${havok_${HAVOK_LIB}_extracted} EQUAL 0)
+
+    file(GLOB extracted_debug "${debug_dir}/*.o")
+    file(GLOB extracted_release "${release_dir}/*.o")
+    file(GLOB extracted_relwithdebinfo "${relwithdebinfo_dir}/*.o")
+
+    if(DEBUG_PREBUILT)
+      MESSAGE(STATUS "extracted_debug ${debug_dir}/*.o")
+      MESSAGE(STATUS "extracted_release ${release_dir}/*.o")
+      MESSAGE(STATUS "extracted_relwithdebinfo ${relwithdebinfo_dir}/*.o")
+    endif(DEBUG_PREBUILT)
+
+    list(APPEND HK_DEBUG_LIBRARIES ${extracted_debug})
+    list(APPEND HK_RELEASE_LIBRARIES ${extracted_release})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${extracted_relwithdebinfo})
+  else(LINUX)
+  # Win32
+    list(APPEND HK_DEBUG_LIBRARIES   ${HAVOK_DEBUG_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELEASE_LIBRARIES ${HAVOK_RELEASE_LIB_${HAVOK_LIB}})
+    list(APPEND HK_RELWITHDEBINFO_LIBRARIES ${HAVOK_RELWITHDEBINFO_LIB_${HAVOK_LIB}})
+  endif (LINUX)
 endforeach(HAVOK_LIB)
 
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/LLAppearance.cmake b/indra/cmake/LLAppearance.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bd3795a5262b0dcbca26779ba7353e382ad38c77
--- /dev/null
+++ b/indra/cmake/LLAppearance.cmake
@@ -0,0 +1,17 @@
+# -*- cmake -*-
+
+include(Variables)
+
+set(LLAPPEARANCE_INCLUDE_DIRS
+    ${LIBS_OPEN_DIR}/llappearance
+    )
+
+if (BUILD_HEADLESS)
+  set(LLAPPEARANCE_HEADLESS_LIBRARIES
+    llappearanceheadless
+    )
+endif (BUILD_HEADLESS)
+
+set(LLAPPEARANCE_LIBRARIES llappearance)
+
+
diff --git a/indra/cmake/LLAppearanceUtility.cmake b/indra/cmake/LLAppearanceUtility.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..bea45543dea2fbe0e37381f4d6f0b162660f478f
--- /dev/null
+++ b/indra/cmake/LLAppearanceUtility.cmake
@@ -0,0 +1,12 @@
+# -*- cmake -*-
+include(Prebuilt)
+
+# Linux proprietary build only
+if (INSTALL_PROPRIETARY)
+    if(LINUX)
+        use_prebuilt_binary(llappearanceutility-source)
+        set(LLAPPEARANCEUTILITY_SRC_DIR ${LIBS_PREBUILT_DIR}/llappearanceutility/src)
+        set(LLAPPEARANCEUTILITY_BIN_DIR ${CMAKE_BINARY_DIR}/llappearanceutility)
+    endif (LINUX)
+endif (INSTALL_PROPRIETARY)
+
diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake
index c254bf6f053b337ac6637f8a6b96e4f6cf9b2afc..b52556a73e4fead0f075cf631f8203de6e8a3203 100644
--- a/indra/cmake/LLCommon.cmake
+++ b/indra/cmake/LLCommon.cmake
@@ -10,6 +10,8 @@ set(LLCOMMON_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llcommon
     ${APRUTIL_INCLUDE_DIR}
     ${APR_INCLUDE_DIR}
+    )
+set(LLCOMMON_SYSTEM_INCLUDE_DIRS
     ${Boost_INCLUDE_DIRS}
     )
 
diff --git a/indra/cmake/LLDatabase.cmake b/indra/cmake/LLDatabase.cmake
deleted file mode 100644
index 65261013861f5844a99cd4d43594507961da7da4..0000000000000000000000000000000000000000
--- a/indra/cmake/LLDatabase.cmake
+++ /dev/null
@@ -1,10 +0,0 @@
-# -*- cmake -*-
-
-include(MySQL)
-
-set(LLDATABASE_INCLUDE_DIRS
-    ${LIBS_SERVER_DIR}/lldatabase
-    ${MYSQL_INCLUDE_DIR}
-    )
-
-set(LLDATABASE_LIBRARIES lldatabase)
diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake
index 8427928151dfe48cf65c71e769e660e979982c43..ae71ee4c0d611e09cd9e8d98f16bb21ececc4c1d 100644
--- a/indra/cmake/LLRender.cmake
+++ b/indra/cmake/LLRender.cmake
@@ -1,5 +1,6 @@
 # -*- cmake -*-
 
+include(Variables)
 include(FreeType)
 include(GLH)
 
@@ -8,27 +9,12 @@ set(LLRENDER_INCLUDE_DIRS
     ${GLH_INCLUDE_DIR}
     )
 
-if (SERVER AND LINUX)
-  set(LLRENDER_LIBRARIES
-      llrenderheadless
-      )
-else (SERVER AND LINUX)
+if (BUILD_HEADLESS)
+  set(LLRENDER_HEADLESS_LIBRARIES
+    llrenderheadless
+    )
+endif (BUILD_HEADLESS)
 set(LLRENDER_LIBRARIES
     llrender
     )
-endif (SERVER AND LINUX)
 
-# mapserver requires certain files to be copied so LL_MESA_HEADLESS can be set
-# differently for different object files.
-macro (copy_server_sources )
-  foreach (PREFIX ${ARGV})
-    add_custom_command(
-        OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
-        COMMAND ${CMAKE_COMMAND}
-        ARGS -E copy ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
-             ${CMAKE_CURRENT_BINARY_DIR}/${PREFIX}_server.cpp
-        DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/${PREFIX}.cpp
-        )
-    list(APPEND server_SOURCE_FILES ${PREFIX}_server.cpp)
-  endforeach (PREFIX ${_copied_SOURCES})
-endmacro (copy_server_sources _copied_SOURCES)
diff --git a/indra/cmake/LLScene.cmake b/indra/cmake/LLScene.cmake
deleted file mode 100644
index 96ad5085a24aa45642ef60d8bf829447e899bedc..0000000000000000000000000000000000000000
--- a/indra/cmake/LLScene.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLSCENE_INCLUDE_DIRS
-    ${LIBS_SERVER_DIR}/llscene
-    )
-
-set(LLSCENE_LIBRARIES llscene)
diff --git a/indra/cmake/LLWindow.cmake b/indra/cmake/LLWindow.cmake
index b4bb9a078a9c8dbac63312638d2839842ac54aaa..0def507e659aca39bd2cc67a3f496f55c79e71d2 100644
--- a/indra/cmake/LLWindow.cmake
+++ b/indra/cmake/LLWindow.cmake
@@ -1,6 +1,7 @@
 # -*- cmake -*-
 
-include(OpenGL)
+include(Variables)
+include(GLEXT)
 include(Prebuilt)
 
 if (STANDALONE)
@@ -13,17 +14,15 @@ if (STANDALONE)
       SDL_LIBRARY
       )
 else (STANDALONE)
-  use_prebuilt_binary(mesa)
-  if (LINUX AND VIEWER)
+  if (LINUX)
     use_prebuilt_binary(SDL)
     set (SDL_FOUND TRUE)
     set (SDL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/i686-linux)
     set (SDL_LIBRARY SDL directfb fusion direct)
-  endif (LINUX AND VIEWER)
+  endif (LINUX)
 endif (STANDALONE)
 
 if (SDL_FOUND)
-  add_definitions(-DLL_SDL=1)
   include_directories(${SDL_INCLUDE_DIR})
 endif (SDL_FOUND)
 
@@ -32,12 +31,12 @@ set(LLWINDOW_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llwindow
     )
 
-if (SERVER AND LINUX)
-  set(LLWINDOW_LIBRARIES
-      llwindowheadless
-      )
-else (SERVER AND LINUX)
-  set(LLWINDOW_LIBRARIES
-      llwindow
-      )
-endif (SERVER AND LINUX)
+if (BUILD_HEADLESS)
+  set(LLWINDOW_HEADLESS_LIBRARIES
+    llwindowheadless
+    )
+endif (BUILD_HEADLESS)
+
+set(LLWINDOW_LIBRARIES
+    llwindow
+    )
diff --git a/indra/cmake/LLXML.cmake b/indra/cmake/LLXML.cmake
index 64dfdb604f1cf71922e175020deef1ea160e66cf..b093c762975efc4771464bc6e6efcadf28faff7f 100644
--- a/indra/cmake/LLXML.cmake
+++ b/indra/cmake/LLXML.cmake
@@ -5,8 +5,10 @@ include(EXPAT)
 
 set(LLXML_INCLUDE_DIRS
     ${LIBS_OPEN_DIR}/llxml
-    ${Boost_INCLUDE_DIRS}
     ${EXPAT_INCLUDE_DIRS}
     )
+set(LLXML_SYSTEM_INCLUDE_DIRS
+    ${Boost_INCLUDE_DIRS}
+    )
 
 set(LLXML_LIBRARIES llxml)
diff --git a/indra/cmake/LLXUIXML.cmake b/indra/cmake/LLXUIXML.cmake
deleted file mode 100644
index b8bfe48c77660cb81495e23314795dfa48a8afc4..0000000000000000000000000000000000000000
--- a/indra/cmake/LLXUIXML.cmake
+++ /dev/null
@@ -1,7 +0,0 @@
-# -*- cmake -*-
-
-set(LLXUIXML_INCLUDE_DIRS
-    ${LIBS_OPEN_DIR}/llxuixml
-    )
-
-set(LLXUIXML_LIBRARIES llxuixml)
diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake
index c3e3a80fd0d06cf20d8d1af12e3952ff7864d78b..b9c9e531fce292acc672e6ef9643626d4b6b41b5 100644
--- a/indra/cmake/Linking.cmake
+++ b/indra/cmake/Linking.cmake
@@ -1,5 +1,8 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(Variables)
 
 set(ARCH_PREBUILT_DIRS ${AUTOBUILD_INSTALL_DIR}/lib)
@@ -69,3 +72,5 @@ else (WINDOWS)
 endif (WINDOWS)
     
 mark_as_advanced(DL_LIBRARY PTHREAD_LIBRARY WINDOWS_LIBRARIES)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/MonoDeps.cmake b/indra/cmake/MonoDeps.cmake
deleted file mode 100644
index 52d5491563607396342669cdbefbd40fa40fba3d..0000000000000000000000000000000000000000
--- a/indra/cmake/MonoDeps.cmake
+++ /dev/null
@@ -1,48 +0,0 @@
-# -*- cmake -*-
-
-set(MONO_PREBUILT_LIBRARIES_DIR ${LIBS_PREBUILT_DIR}/mono/1.0)
-
-set(MONO_PREBUILT_LIBRARIES
-     Iesi.Collections.dll
-     Iesi.Collections.pdb
-     Mono.CompilerServices.SymbolWriter.dll
-     Mono.PEToolkit.dll
-     Mono.PEToolkit.pdb
-     Mono.Security.dll
-     PEAPI.dll
-     RAIL.dll
-     RAIL.pdb
-  )
-  
-  set(MONO_CORE_LIBRARIES
-    System.dll
-    System.Xml.dll
-    mscorlib.dll)
-    
-if(WINDOWS)
-    set(MONO_DEPENDENCIES
-        DomainCreator
-        DomainRegister
-        LslLibrary
-        LslUserScript
-        Script
-        ScriptTypes
-        TestFormat
-        UserScript
-        UThread
-        UThreadInjector
-        )
-else(WINDOWS)
-    set(MONO_DEPENDENCIES
-        DomainCreator_POST_BUILD
-        DomainRegister_POST_BUILD
-        LslLibrary_POST_BUILD
-        LslUserScript_POST_BUILD
-        Script_POST_BUILD
-        ScriptTypes_POST_BUILD
-        TestFormat_POST_BUILD
-        UserScript_POST_BUILD
-        UThread_POST_BUILD
-        UThreadInjector_POST_BUILD
-        )
-endif(WINDOWS)
diff --git a/indra/cmake/MonoEmbed.cmake b/indra/cmake/MonoEmbed.cmake
deleted file mode 100644
index 30890aed217ad31b262fe4803ba716fae1617df5..0000000000000000000000000000000000000000
--- a/indra/cmake/MonoEmbed.cmake
+++ /dev/null
@@ -1,57 +0,0 @@
-# -*- cmake -*-
-
-include(Prebuilt)
-use_prebuilt_binary(libmono)
-
-SET(GLIB_2_0 glib-2.0)
-
-if (WINDOWS)
-    SET(MONO_LIB mono) 
-else (WINDOWS)
-    SET(MONO_LIB mono)
-    SET(M_LIBRARIES m)
-    SET(GTHREAD_2_0 gthread-2.0)
-endif(WINDOWS)
-
-
-IF (DARWIN)
-
-  FIND_LIBRARY(MONO_LIBRARY NAMES Mono)
-  # Find_file doesnt work as expected. Hardcode relative to Mono.framework. 
-  #FIND_FILE(GLIB_CONFIG glibconfig.h ${MONO_LIBRARY})
-  #FIND_FILE(MONO_GLIB_LIBRARY glib.h ${MONO_LIBRARY})
-  SET(MONO_GLIB_LIBRARY ${MONO_LIBRARY}/Headers/glib-2.0/)
-  SET(GLIB_CONFIG ${MONO_LIBRARY}/Libraries/glib-2.0/include/)
-  SET(MONO_LIB_DIRECTORY ${MONO_LIBRARY}/Libraries)
-
-  IF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-    MESSAGE(STATUS "Found Mono for embedding")
-    INCLUDE_DIRECTORIES(${MONO_GLIB_LIBRARY} ${GLIB_CONFIG})
-    LINK_DIRECTORIES(${MONO_LIB_DIRECTORY})
-  ELSE (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-    MESSAGE(FATAL_ERROR "Mono not found for embedding")   
-    MESSAGE(${MONO_LIBRARY})
-    MESSAGE(${MONO_GLIB_LIBRARY})
-    MESSAGE(${GLIB_CONFIG})
-  ENDIF (MONO_LIBRARY AND MONO_GLIB_LIBRARY AND GLIB_CONFIG)
-
-ELSE (DARWIN)
-
-  SET(MONO_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)  
-  SET(GLIB_2_0_PLATFORM_INCLUDE_DIR
-    ${LIBS_PREBUILT_DIR}/include/glib-2.0)
-  SET(GLIB_2_0_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/glib-2.0)
-
-  INCLUDE_DIRECTORIES(
-    ${MONO_INCLUDE_DIR} 
-    ${GLIB_2_0_PLATFORM_INCLUDE_DIR} 
-    ${GLIB_2_0_INCLUDE_DIR})
-    
-ENDIF (DARWIN) 
-
-SET(MONO_LIBRARIES 
-    ${MONO_LIB} 
-    ${M_LIBRARIES} 
-    ${GLIB_2_0}
-    ${GTHREAD_2_0} 
-)
diff --git a/indra/cmake/MySQL.cmake b/indra/cmake/MySQL.cmake
deleted file mode 100644
index 218482449dc0daa6a02596ebf4de274cbb7d2114..0000000000000000000000000000000000000000
--- a/indra/cmake/MySQL.cmake
+++ /dev/null
@@ -1,26 +0,0 @@
-# -*- cmake -*-
-include(Linking)
-include(Prebuilt)
-
-use_prebuilt_binary(mysql)
-
-if (LINUX)
-  if (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-    set(MYSQL_LIBRARIES mysqlclient)
-    set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-  else (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-    # Use the native MySQL library on a 64-bit system.
-    set(MYSQL_FIND_QUIETLY ON)
-    set(MYSQL_FIND_REQUIRED ON)
-    include(FindMySQL)
-  endif (WORD_SIZE EQUAL 32 OR DEBIAN_VERSION STREQUAL "3.1")
-elseif (WINDOWS)
-  set(MYSQL_LIBRARIES mysqlclient)
-  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-elseif (DARWIN)
-  set(MYSQL_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-  set(MYSQL_LIBRARIES
-    optimized ${ARCH_PREBUILT_DIRS_RELEASE}/libmysqlclient.a
-    debug ${ARCH_PREBUILT_DIRS_DEBUG}/libmysqlclient.a
-    )
-endif (LINUX)
diff --git a/indra/cmake/OpenGL.cmake b/indra/cmake/OpenGL.cmake
index 0a3dd976b43354adf1d5d2768356e95b004fc10e..2259c992935ff42dbbf46eb4105467a7ec7584d8 100644
--- a/indra/cmake/OpenGL.cmake
+++ b/indra/cmake/OpenGL.cmake
@@ -1,8 +1,12 @@
 # -*- cmake -*-
+
+include(Variables)
 include(Prebuilt)
 
-if (NOT STANDALONE)
-  use_prebuilt_binary(glext)
-  use_prebuilt_binary(glh_linear)
-  set(GLEXT_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include)
-endif (NOT STANDALONE)
+if (BUILD_HEADLESS)
+  SET(OPENGL_glu_LIBRARY GLU)
+  SET(OPENGL_HEADLESS_LIBRARIES OSMesa16 dl GLU)
+endif (BUILD_HEADLESS)
+
+include(FindOpenGL)
+
diff --git a/indra/cmake/Prebuilt.cmake b/indra/cmake/Prebuilt.cmake
index dbb4dfc46c7f034c792224ac52a33269be1e8028..ac0cbde25322fa81a1b7a27197fb874a51f1abc1 100644
--- a/indra/cmake/Prebuilt.cmake
+++ b/indra/cmake/Prebuilt.cmake
@@ -1,5 +1,8 @@
 # -*- cmake -*-
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 include(FindAutobuild)
 if(INSTALL_PROPRIETARY)
   include(FindSCP)
@@ -51,3 +54,5 @@ macro (use_prebuilt_binary _binary)
     endif (NOT ${_binary}_installed EQUAL 0)
   endif (NOT STANDALONE_${_binary})
 endmacro (use_prebuilt_binary _binary)
+
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/Python.cmake b/indra/cmake/Python.cmake
index 748c8c2bec1b80b3680c2b7e410fbf3de1830df5..a81c9307fc062c8ba18e168ad8779b0e47ab93ac 100644
--- a/indra/cmake/Python.cmake
+++ b/indra/cmake/Python.cmake
@@ -23,7 +23,7 @@ if (WINDOWS)
 elseif (EXISTS /etc/debian_version)
   # On Debian and Ubuntu, avoid Python 2.4 if possible.
 
-  find_program(PYTHON_EXECUTABLE python2.5 python2.3 python PATHS /usr/bin)
+  find_program(PYTHON_EXECUTABLE python PATHS /usr/bin)
 
   if (PYTHON_EXECUTABLE)
     set(PYTHONINTERP_FOUND ON)
diff --git a/indra/cmake/UI.cmake b/indra/cmake/UI.cmake
index 91e5258fb704ed7169e4d5e7bba61b7ca652f53b..d0fd4df03a225550b84f72ad650ade3a6bfda6b3 100644
--- a/indra/cmake/UI.cmake
+++ b/indra/cmake/UI.cmake
@@ -1,5 +1,6 @@
 # -*- cmake -*-
 include(Prebuilt)
+include(FreeType)
 
 if (STANDALONE)
   include(FindPkgConfig)
@@ -47,6 +48,7 @@ else (STANDALONE)
         pangoft2-1.0
         pangox-1.0
         pangoxft-1.0
+        ${FREETYPE_LIBRARIES}
         )
   endif (LINUX)
 
diff --git a/indra/cmake/Variables.cmake b/indra/cmake/Variables.cmake
index 4b459f1a486195758e3caf1a4f9917c7ef66e276..6ec621632b8356213e145e33bd04a0a73d7b134e 100644
--- a/indra/cmake/Variables.cmake
+++ b/indra/cmake/Variables.cmake
@@ -8,24 +8,20 @@
 #   DARWIN  - Mac OS X
 #   LINUX   - Linux
 #   WINDOWS - Windows
-#
-# What to build:
-#
-#   VIEWER - viewer and other viewer-side components
-#   SERVER - simulator and other server-side bits
 
 
 # Relative and absolute paths to subtrees.
 
+if(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
+set(${CMAKE_CURRENT_LIST_FILE}_INCLUDED "YES")
+
 if(NOT DEFINED COMMON_CMAKE_DIR)
     set(COMMON_CMAKE_DIR "${CMAKE_SOURCE_DIR}/cmake")
 endif(NOT DEFINED COMMON_CMAKE_DIR)
 
 set(LIBS_CLOSED_PREFIX)
 set(LIBS_OPEN_PREFIX)
-set(LIBS_SERVER_PREFIX)
 set(SCRIPTS_PREFIX ../scripts)
-set(SERVER_PREFIX)
 set(VIEWER_PREFIX)
 set(INTEGRATION_TESTS_PREFIX)
 set(LL_TESTS ON CACHE BOOL "Build and run unit and integration tests (disable for build timing runs to reduce variation")
@@ -43,9 +39,7 @@ else(LIBS_COMMON_DIR)
 endif(LIBS_COMMON_DIR)
 set(LIBS_OPEN_DIR ${LIBS_COMMON_DIR})
 
-set(LIBS_SERVER_DIR ${CMAKE_SOURCE_DIR}/${LIBS_SERVER_PREFIX})
 set(SCRIPTS_DIR ${CMAKE_SOURCE_DIR}/${SCRIPTS_PREFIX})
-set(SERVER_DIR ${CMAKE_SOURCE_DIR}/${SERVER_PREFIX})
 set(VIEWER_DIR ${CMAKE_SOURCE_DIR}/${VIEWER_PREFIX})
 
 set(AUTOBUILD_INSTALL_DIR ${CMAKE_BINARY_DIR}/packages)
@@ -79,21 +73,57 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
   # If someone has specified a word size, use that to determine the
   # architecture.  Otherwise, let the architecture specify the word size.
   if (WORD_SIZE EQUAL 32)
+    #message(STATUS "WORD_SIZE is 32")
     set(ARCH i686)
   elseif (WORD_SIZE EQUAL 64)
+    #message(STATUS "WORD_SIZE is 64")
     set(ARCH x86_64)
   else (WORD_SIZE EQUAL 32)
+    #message(STATUS "WORD_SIZE is UNDEFINED")
     execute_process(COMMAND uname -m COMMAND sed s/i.86/i686/
                     OUTPUT_VARIABLE ARCH OUTPUT_STRIP_TRAILING_WHITESPACE)
     if (ARCH STREQUAL x86_64)
+      #message(STATUS "ARCH is detected as 64; ARCH is ${ARCH}")
       set(WORD_SIZE 64)
     else (ARCH STREQUAL x86_64)
+      #message(STATUS "ARCH is detected as 32; ARCH is ${ARCH}")
       set(WORD_SIZE 32)
     endif (ARCH STREQUAL x86_64)
   endif (WORD_SIZE EQUAL 32)
 
+  if (WORD_SIZE EQUAL 32)
+    set(DEB_ARCHITECTURE i386)
+    set(FIND_LIBRARY_USE_LIB64_PATHS OFF)
+    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib32 ${CMAKE_SYSTEM_LIBRARY_PATH})
+  else (WORD_SIZE EQUAL 32)
+    set(DEB_ARCHITECTURE amd64)
+    set(FIND_LIBRARY_USE_LIB64_PATHS ON)
+  endif (WORD_SIZE EQUAL 32)
+
+  execute_process(COMMAND dpkg-architecture -a${DEB_ARCHITECTURE} -qDEB_HOST_MULTIARCH 
+      RESULT_VARIABLE DPKG_RESULT
+      OUTPUT_VARIABLE DPKG_ARCH
+      OUTPUT_STRIP_TRAILING_WHITESPACE ERROR_QUIET)
+  #message (STATUS "DPKG_RESULT ${DPKG_RESULT}, DPKG_ARCH ${DPKG_ARCH}")
+  if (DPKG_RESULT EQUAL 0)
+    set(CMAKE_LIBRARY_ARCHITECTURE ${DPKG_ARCH})
+    set(CMAKE_SYSTEM_LIBRARY_PATH /usr/lib/${DPKG_ARCH} /usr/local/lib/${DPKG_ARCH} ${CMAKE_SYSTEM_LIBRARY_PATH})
+  endif (DPKG_RESULT EQUAL 0)
+
+  include(ConfigurePkgConfig)
+
   set(LL_ARCH ${ARCH}_linux)
   set(LL_ARCH_DIR ${ARCH}-linux)
+
+  if (INSTALL_PROPRIETARY)
+    # Only turn on headless if we can find osmesa libraries.
+    include(FindPkgConfig)
+    #pkg_check_modules(OSMESA osmesa)
+    #if (OSMESA_FOUND)
+    #  set(BUILD_HEADLESS ON CACHE BOOL "Build headless libraries.")
+    #endif (OSMESA_FOUND)
+  endif (INSTALL_PROPRIETARY)
+
 endif (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
 
 if (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
@@ -140,7 +170,6 @@ endif (${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
 # Default deploy grid
 set(GRID agni CACHE STRING "Target Grid")
 
-set(VIEWER ON CACHE BOOL "Build Second Life viewer.")
 set(VIEWER_CHANNEL "LindenDeveloper" CACHE STRING "Viewer Channel Name")
 set(VIEWER_LOGIN_CHANNEL ${VIEWER_CHANNEL} CACHE STRING "Fake login channel for A/B Testing")
 
@@ -153,21 +182,8 @@ set(VERSION_BUILD "0" CACHE STRING "Revision number passed in from the outside")
 set(STANDALONE OFF CACHE BOOL "Do not use Linden-supplied prebuilt libraries.")
 set(UNATTENDED OFF CACHE BOOL "Should be set to ON for building with VC Express editions.")
 
-if (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-    set(SERVER ON CACHE BOOL "Build Second Life server software.")
-endif (NOT STANDALONE AND EXISTS ${CMAKE_SOURCE_DIR}/llphysics)
-
-if (LINUX AND SERVER AND VIEWER)
-  MESSAGE(FATAL_ERROR "
-The indra source does not currently support building SERVER and VIEWER at the same time.
-Please set one of these values to OFF in your CMake cache file.
-(either by running ccmake or by editing CMakeCache.txt by hand)
-For more information, please see JIRA DEV-14943 - Cmake Linux cannot build both VIEWER and SERVER in one build environment
-  ")
-endif (LINUX AND SERVER AND VIEWER)
-
-
 set(USE_PRECOMPILED_HEADERS ON CACHE BOOL "Enable use of precompiled header directives where supported.")
 
 source_group("CMake Rules" FILES CMakeLists.txt)
 
+endif(NOT DEFINED ${CMAKE_CURRENT_LIST_FILE}_INCLUDED)
diff --git a/indra/cmake/VisualLeakDetector.cmake b/indra/cmake/VisualLeakDetector.cmake
index d3ba554e462621cbc6bff6d0d670f0a89055f01e..27e93e28bb483f85fd9980beb5404f7339babca5 100644
--- a/indra/cmake/VisualLeakDetector.cmake
+++ b/indra/cmake/VisualLeakDetector.cmake
@@ -1,15 +1,12 @@
 # -*- cmake -*-
 
-if (VIEWER)
+set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
 
-  set(INCLUDE_VLD_CMAKE OFF CACHE BOOL "Build the Windows viewer with Visual Leak Detector turned on or off")
+if (INCLUDE_VLD_CMAKE)
 
-  if (INCLUDE_VLD_CMAKE)
+  if (WINDOWS)
+    add_definitions(-DINCLUDE_VLD=1)
+  endif (WINDOWS)
 
-    if (WINDOWS)
-      add_definitions(-DINCLUDE_VLD=1)
-    endif (WINDOWS)
+endif (INCLUDE_VLD_CMAKE)
 
-  endif (INCLUDE_VLD_CMAKE)
-
-endif (VIEWER)
diff --git a/indra/integration_tests/llimage_libtest/CMakeLists.txt b/indra/integration_tests/llimage_libtest/CMakeLists.txt
index af5c9fb2e75dfbb1b9a6af401b115f6380139ad9..36a7d38bb71609d836222a2f60248a20b65b3b26 100644
--- a/indra/integration_tests/llimage_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llimage_libtest/CMakeLists.txt
@@ -16,6 +16,9 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLIMAGE_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llimage_libtest_SOURCE_FILES
     llimage_libtest.cpp
diff --git a/indra/integration_tests/llui_libtest/CMakeLists.txt b/indra/integration_tests/llui_libtest/CMakeLists.txt
index 91c9f20c107f51f4e6c54a29d7a4fdb3db4765d6..e83b4e8cd7210dc6d4907da4f63451c382089da9 100644
--- a/indra/integration_tests/llui_libtest/CMakeLists.txt
+++ b/indra/integration_tests/llui_libtest/CMakeLists.txt
@@ -34,6 +34,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LIBS_PREBUILD_DIR}/include/hunspell
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llui_libtest_SOURCE_FILES
     llui_libtest.cpp
diff --git a/indra/linux_crash_logger/CMakeLists.txt b/indra/linux_crash_logger/CMakeLists.txt
index 98ebdc748739f0ffcba0265e138a5293d8d08a83..e0d0c9fc6974639f7bd9d3f3735c1d01194448e3 100644
--- a/indra/linux_crash_logger/CMakeLists.txt
+++ b/indra/linux_crash_logger/CMakeLists.txt
@@ -20,6 +20,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(linux_crash_logger_SOURCE_FILES
     linux_crash_logger.cpp
diff --git a/indra/linux_updater/CMakeLists.txt b/indra/linux_updater/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..4a9e82f9b620b3a0202e974d60c73c868f25bccb
--- /dev/null
+++ b/indra/linux_updater/CMakeLists.txt
@@ -0,0 +1,57 @@
+# -*- cmake -*-
+
+project(linux_updater)
+
+include(00-Common)
+include(CURL)
+include(CARes)
+include(OpenSSL)
+include(UI)
+include(LLCommon)
+include(LLMessage)
+include(LLVFS)
+include(LLXML)
+include(LLUI)
+include(Linking)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLVFS_INCLUDE_DIRS}
+    ${LLXML_INCLUDE_DIRS}
+    ${LLUI_INCLUDE_DIRS}
+    ${CURL_INCLUDE_DIRS}
+    ${CARES_INCLUDE_DIRS}
+    ${OPENSSL_INCLUDE_DIRS}
+    ${UI_INCLUDE_DIRS}
+    )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
+
+set(linux_updater_SOURCE_FILES linux_updater.cpp)
+
+set(linux_updater_HEADER_FILES CMakeLists.txt)
+
+set_source_files_properties(${linux_updater_HEADER_FILES}
+                            PROPERTIES HEADER_FILES_ONLY TRUE)
+
+list(APPEND linux_updater_SOURCE_FILES ${linux_updater_HEADER_FILES})
+
+add_executable(linux-updater ${linux_updater_SOURCE_FILES})
+
+target_link_libraries(linux-updater
+    ${CURL_LIBRARIES}
+    ${CARES_LIBRARIES}
+    ${OPENSSL_LIBRARIES}
+    ${CRYPTO_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${UI_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLUI_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
+    )
+
+add_custom_target(linux-updater-target ALL
+                  DEPENDS linux-updater)
diff --git a/indra/linux_updater/linux_updater.cpp b/indra/linux_updater/linux_updater.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..86fa596aef6d98d0eb982aed22a796e64376c88f
--- /dev/null
+++ b/indra/linux_updater/linux_updater.cpp
@@ -0,0 +1,924 @@
+/**
+ * @file linux_updater.cpp
+ * @author Kyle Ambroff <ambroff@lindenlab.com>, Tofu Linden
+ * @brief Viewer update program for unix platforms that support GTK+
+ *
+ * $LicenseInfo:firstyear=2008&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include <unistd.h>
+#include <signal.h>
+#include <errno.h>
+
+#include "linden_common.h"
+#include "llerrorcontrol.h"
+#include "llfile.h"
+#include "lldir.h"
+#include "lldiriterator.h"
+
+/*==========================================================================*|
+// IQA-490: Use of LLTrans -- by this program at least -- appears to be buggy.
+// With it, the 3.3.2 beta 1 linux-updater.bin crashes; without it seems stable.
+#include "llxmlnode.h"
+#include "lltrans.h"
+|*==========================================================================*/
+
+static class LLTrans
+{
+public:
+	LLTrans();
+	static std::string getString(const std::string& key);
+
+private:
+	std::string _getString(const std::string& key) const;
+
+	typedef std::map<std::string, std::string> MessageMap;
+	MessageMap mMessages;
+} sLLTransInstance;
+
+#include <curl/curl.h>
+#include <map>
+#include <boost/foreach.hpp>
+
+extern "C" {
+#include <gtk/gtk.h>
+}
+
+const guint UPDATE_PROGRESS_TIMEOUT = 100;
+const guint UPDATE_PROGRESS_TEXT_TIMEOUT = 1000;
+const guint ROTATE_IMAGE_TIMEOUT = 8000;
+
+typedef struct _updater_app_state {
+	std::string app_name;
+	std::string url;
+	std::string file;
+	std::string image_dir;
+	std::string dest_dir;
+	std::string strings_dirs;
+	std::string strings_file;
+
+	LLDirIterator *image_dir_iter;
+
+	GtkWidget *window;
+	GtkWidget *progress_bar;
+	GtkWidget *image;
+
+	double progress_value;
+	bool activity_mode;
+
+	guint image_rotation_timeout_id;
+	guint progress_update_timeout_id;
+	guint update_progress_text_timeout_id;
+
+	bool failure;
+} UpdaterAppState;
+
+// List of entries from strings.xml to always replace
+static std::set<std::string> default_trans_args;
+void init_default_trans_args()
+{
+        default_trans_args.insert("SECOND_LIFE"); // World
+        default_trans_args.insert("APP_NAME");
+        default_trans_args.insert("SECOND_LIFE_GRID");
+        default_trans_args.insert("SUPPORT_SITE");
+}
+
+bool translate_init(std::string comma_delim_path_list,
+		    std::string base_xml_name)
+{
+	return true;
+/*==========================================================================*|
+	init_default_trans_args();
+
+	// extract paths string vector from comma-delimited flat string
+	std::vector<std::string> paths;
+	LLStringUtil::getTokens(comma_delim_path_list, paths, ","); // split over ','
+
+	for(std::vector<std::string>::iterator it = paths.begin(), end_it = paths.end();
+		it != end_it;
+		++it)
+	{
+		(*it) = gDirUtilp->findSkinnedFilename(*it, base_xml_name);
+	}
+
+	// suck the translation xml files into memory
+	LLXMLNodePtr root;
+	bool success = LLXMLNode::getLayeredXMLNode(root, paths);
+	if (!success)
+	{
+		// couldn't load string table XML
+		return false;
+	}
+	else
+	{
+		// get those strings out of the XML
+		LLTrans::parseStrings(root, default_trans_args);
+		return true;
+	}
+|*==========================================================================*/
+}
+
+
+void updater_app_ui_init(void);
+void updater_app_quit(UpdaterAppState *app_state);
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state);
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter);
+void display_error(GtkWidget *parent, std::string title, std::string message);
+BOOL install_package(std::string package_file, std::string destination);
+BOOL spawn_viewer(UpdaterAppState *app_state);
+
+extern "C" {
+	void on_window_closed(GtkWidget *sender, GdkEvent *event, gpointer state);
+	gpointer worker_thread_cb(gpointer *data);
+	int download_progress_cb(gpointer data, double t, double d, double utotal, double ulnow);
+	gboolean rotate_image_cb(gpointer data);
+	gboolean progress_update_timeout(gpointer data);
+	gboolean update_progress_text_timeout(gpointer data);
+}
+
+void updater_app_ui_init(UpdaterAppState *app_state)
+{
+	GtkWidget *vbox;
+	GtkWidget *summary_label;
+	GtkWidget *description_label;
+	GtkWidget *frame;
+
+	llassert(app_state != NULL);
+
+	// set up window and main container
+	std::string window_title = LLTrans::getString("UpdaterWindowTitle");
+	app_state->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+	gtk_window_set_title(GTK_WINDOW(app_state->window),
+			     window_title.c_str());
+	gtk_window_set_resizable(GTK_WINDOW(app_state->window), FALSE);
+	gtk_window_set_position(GTK_WINDOW(app_state->window),
+				GTK_WIN_POS_CENTER_ALWAYS);
+
+	gtk_container_set_border_width(GTK_CONTAINER(app_state->window), 12);
+	g_signal_connect(G_OBJECT(app_state->window), "delete-event",
+			 G_CALLBACK(on_window_closed), app_state);
+
+	vbox = gtk_vbox_new(FALSE, 6);
+	gtk_container_add(GTK_CONTAINER(app_state->window), vbox);
+
+	// set top label
+	std::ostringstream label_ostr;
+	label_ostr << "<big><b>"
+		   << LLTrans::getString("UpdaterNowUpdating")
+		   << "</b></big>";
+
+	summary_label = gtk_label_new(NULL);
+	gtk_label_set_use_markup(GTK_LABEL(summary_label), TRUE);
+	gtk_label_set_markup(GTK_LABEL(summary_label),
+			     label_ostr.str().c_str());
+	gtk_misc_set_alignment(GTK_MISC(summary_label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(vbox), summary_label, FALSE, FALSE, 0);
+
+	// create the description label
+	description_label = gtk_label_new(LLTrans::getString("UpdaterUpdatingDescriptive").c_str());
+	gtk_label_set_line_wrap(GTK_LABEL(description_label), TRUE);
+	gtk_misc_set_alignment(GTK_MISC(description_label), 0, 0.5);
+	gtk_box_pack_start(GTK_BOX(vbox), description_label, FALSE, FALSE, 0);
+
+	// If an image path has been set, load the background images
+	if (!app_state->image_dir.empty()) {
+		frame = gtk_frame_new(NULL);
+		gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
+		gtk_box_pack_start(GTK_BOX(vbox), frame, TRUE, TRUE, 0);
+
+		// load the first image
+		app_state->image = gtk_image_new_from_file
+			(next_image_filename(app_state->image_dir, *app_state->image_dir_iter).c_str());
+		gtk_widget_set_size_request(app_state->image, 340, 310);
+		gtk_container_add(GTK_CONTAINER(frame), app_state->image);
+
+		// rotate the images every 5 seconds
+		app_state->image_rotation_timeout_id = g_timeout_add
+			(ROTATE_IMAGE_TIMEOUT, rotate_image_cb, app_state);
+	}
+
+	// set up progress bar, and update it roughly every 1/10 of a second
+	app_state->progress_bar = gtk_progress_bar_new();
+	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+				  LLTrans::getString("UpdaterProgressBarTextWithEllipses").c_str());
+	gtk_box_pack_start(GTK_BOX(vbox),
+			   app_state->progress_bar, FALSE, TRUE, 0);
+	app_state->progress_update_timeout_id = g_timeout_add
+		(UPDATE_PROGRESS_TIMEOUT, progress_update_timeout, app_state);
+	app_state->update_progress_text_timeout_id = g_timeout_add
+		(UPDATE_PROGRESS_TEXT_TIMEOUT, update_progress_text_timeout, app_state);
+
+	gtk_widget_show_all(app_state->window);
+}
+
+gboolean rotate_image_cb(gpointer data)
+{
+	UpdaterAppState *app_state;
+	std::string filename;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	filename = next_image_filename(app_state->image_dir, *app_state->image_dir_iter);
+
+	gdk_threads_enter();
+	gtk_image_set_from_file(GTK_IMAGE(app_state->image), filename.c_str());
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+std::string next_image_filename(std::string& image_path, LLDirIterator& iter)
+{
+	std::string image_filename;
+	iter.next(image_filename);
+	return gDirUtilp->add(image_path, image_filename);
+}
+
+void on_window_closed(GtkWidget *sender, GdkEvent* event, gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	updater_app_quit(app_state);
+}
+
+void updater_app_quit(UpdaterAppState *app_state)
+{
+	if (app_state != NULL)
+	{
+		g_source_remove(app_state->progress_update_timeout_id);
+
+		if (!app_state->image_dir.empty())
+		{
+			g_source_remove(app_state->image_rotation_timeout_id);
+		}
+	}
+
+	gtk_main_quit();
+}
+
+void display_error(GtkWidget *parent, std::string title, std::string message)
+{
+	GtkWidget *dialog;
+
+	dialog = gtk_message_dialog_new(GTK_WINDOW(parent),
+					GTK_DIALOG_DESTROY_WITH_PARENT,
+					GTK_MESSAGE_ERROR,
+					GTK_BUTTONS_OK,
+					"%s", message.c_str());
+	gtk_window_set_title(GTK_WINDOW(dialog), title.c_str());
+	gtk_dialog_run(GTK_DIALOG(dialog));
+	gtk_widget_destroy(dialog);
+}
+
+gpointer worker_thread_cb(gpointer data)
+{
+	UpdaterAppState *app_state;
+	CURL *curl;
+	CURLcode result;
+	FILE *package_file;
+	GError *error = NULL;
+	int fd;
+
+	//g_return_val_if_fail (data != NULL, NULL);
+	app_state = (UpdaterAppState *) data;
+
+	try {
+
+		if(!app_state->url.empty())
+		{
+			char* tmp_local_filename = NULL;
+			// create temporary file to store the package.
+			fd = g_file_open_tmp
+				("secondlife-update-XXXXXX", &tmp_local_filename, &error);
+			if (error != NULL)
+			{
+				llerrs << "Unable to create temporary file: "
+					   << error->message
+					   << llendl;
+
+				g_error_free(error);
+				throw 0;
+			}
+
+			if(tmp_local_filename != NULL)
+			{
+				app_state->file = tmp_local_filename;
+				g_free(tmp_local_filename);
+			}
+
+			package_file = fdopen(fd, "wb");
+			if (package_file == NULL)
+			{
+				llerrs << "Failed to create temporary file: "
+					   << app_state->file.c_str()
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
+
+			// initialize curl and start downloading the package
+			llinfos << "Downloading package: " << app_state->url << llendl;
+
+			curl = curl_easy_init();
+			if (curl == NULL)
+			{
+				llerrs << "Failed to initialize libcurl" << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+				throw 0;
+			}
+
+			curl_easy_setopt(curl, CURLOPT_URL, app_state->url.c_str());
+			curl_easy_setopt(curl, CURLOPT_NOSIGNAL, TRUE);
+			curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, TRUE);
+			curl_easy_setopt(curl, CURLOPT_WRITEDATA, package_file);
+			curl_easy_setopt(curl, CURLOPT_NOPROGRESS, FALSE);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSFUNCTION,
+							 &download_progress_cb);
+			curl_easy_setopt(curl, CURLOPT_PROGRESSDATA, app_state);
+
+			result = curl_easy_perform(curl);
+			fclose(package_file);
+			curl_easy_cleanup(curl);
+
+			if (result)
+			{
+				llerrs << "Failed to download update: "
+					   << app_state->url
+					   << llendl;
+
+				gdk_threads_enter();
+				display_error(app_state->window,
+							  LLTrans::getString("UpdaterFailDownloadTitle"),
+							  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+				gdk_threads_leave();
+
+				throw 0;
+			}
+		}
+
+		// now pulse the progres bar back and forth while the package is
+		// being unpacked
+		gdk_threads_enter();
+		std::string installing_msg = LLTrans::getString("UpdaterNowInstalling");
+		gtk_progress_bar_set_text(
+			GTK_PROGRESS_BAR(app_state->progress_bar),
+			installing_msg.c_str());
+		app_state->activity_mode = TRUE;
+		gdk_threads_leave();
+
+		// *TODO: if the destination is not writable, terminate this
+		// thread and show file chooser?
+		if (!install_package(app_state->file.c_str(), app_state->dest_dir))
+		{
+			llwarns << "Failed to install package to destination: "
+				<< app_state->dest_dir
+				<< llendl;
+
+			gdk_threads_enter();
+			display_error(app_state->window,
+						  LLTrans::getString("UpdaterFailInstallTitle"),
+						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+			//"Failed to update " + app_state->app_name,
+			gdk_threads_leave();
+			throw 0;
+		}
+
+		// try to spawn the new viewer
+		if (!spawn_viewer(app_state))
+		{
+			llwarns << "Viewer was not installed properly in : "
+				<< app_state->dest_dir
+				<< llendl;
+
+			gdk_threads_enter();
+			display_error(app_state->window,
+						  LLTrans::getString("UpdaterFailStartTitle"),
+						  LLTrans::getString("UpdaterFailUpdateDescriptive"));
+			gdk_threads_leave();
+			throw 0;
+		}
+	}
+	catch (...)
+	{
+		app_state->failure = TRUE;
+	}
+
+	gdk_threads_enter();
+	updater_app_quit(app_state);
+	gdk_threads_leave();
+
+	return NULL;
+}
+
+
+gboolean less_anal_gspawnsync(gchar **argv,
+			      gchar **stderr_output,
+			      gint *child_exit_status,
+			      GError **spawn_error)
+{
+	// store current SIGCHLD handler if there is one, replace with default
+	// handler to make glib happy
+	struct sigaction sigchld_backup;
+	struct sigaction sigchld_appease_glib;
+	sigchld_appease_glib.sa_handler = SIG_DFL;
+	sigemptyset(&sigchld_appease_glib.sa_mask);
+	sigchld_appease_glib.sa_flags = 0;
+	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+	gboolean rtn = g_spawn_sync(NULL,
+				    argv,
+				    NULL,
+				    (GSpawnFlags) (G_SPAWN_STDOUT_TO_DEV_NULL),
+				    NULL,
+				    NULL,
+				    NULL,
+				    stderr_output,
+				    child_exit_status,
+				    spawn_error);
+
+	// restore SIGCHLD handler
+	sigaction(SIGCHLD, &sigchld_backup, NULL);
+
+	return rtn;
+}
+
+
+// perform a rename, or perform a (prompted) root rename if that fails
+int
+rename_with_sudo_fallback(const std::string& filename, const std::string& newname)
+{
+	int rtncode = ::rename(filename.c_str(), newname.c_str());
+	lldebugs << "rename result is: " << rtncode << " / " << errno << llendl;
+	if (rtncode && (EACCES == errno || EPERM == errno || EXDEV == errno))
+	{
+		llinfos << "Permission problem in rename, or moving between different mount points.  Retrying as a mv under a sudo." << llendl;
+		// failed due to permissions, try again as a gksudo or kdesu mv wrapper hack
+		char *sudo_cmd = NULL;
+		sudo_cmd = g_find_program_in_path("gksudo");
+		if (!sudo_cmd)
+		{
+			sudo_cmd = g_find_program_in_path("kdesu");
+		}
+		if (sudo_cmd)
+		{
+			char *mv_cmd = NULL;
+			mv_cmd = g_find_program_in_path("mv");
+			if (mv_cmd)
+			{
+				char *src_string_copy = g_strdup(filename.c_str());
+				char *dst_string_copy = g_strdup(newname.c_str());
+				char* argv[] =
+					{
+						sudo_cmd,
+						mv_cmd,
+						src_string_copy,
+						dst_string_copy,
+						NULL
+					};
+
+				gchar *stderr_output = NULL;
+				gint child_exit_status = 0;
+				GError *spawn_error = NULL;
+				if (!less_anal_gspawnsync(argv, &stderr_output,
+							  &child_exit_status, &spawn_error))
+				{
+					llwarns << "Failed to spawn child process: "
+						<< spawn_error->message
+						<< llendl;
+				}
+				else if (child_exit_status)
+				{
+					llwarns << "mv command failed: "
+						<< (stderr_output ? stderr_output : "(no reason given)")
+						<< llendl;
+				}
+				else
+				{
+					// everything looks good, clear the error code
+					rtncode = 0;
+				}
+
+				g_free(src_string_copy);
+				g_free(dst_string_copy);
+				if (spawn_error) g_error_free(spawn_error);
+			}
+		}
+	}
+	return rtncode;
+}
+
+gboolean install_package(std::string package_file, std::string destination)
+{
+	char *tar_cmd = NULL;
+	std::ostringstream command;
+
+	// Find the absolute path to the 'tar' command.
+	tar_cmd = g_find_program_in_path("tar");
+	if (!tar_cmd)
+	{
+		llerrs << "`tar' was not found in $PATH" << llendl;
+		return FALSE;
+	}
+	llinfos << "Found tar command: " << tar_cmd << llendl;
+
+	// Unpack the tarball in a temporary place first, then move it to
+	// its final destination
+	std::string tmp_dest_dir = gDirUtilp->getTempFilename();
+	if (LLFile::mkdir(tmp_dest_dir, 0744))
+	{
+		llerrs << "Failed to create directory: "
+		       << destination
+		       << llendl;
+
+		return FALSE;
+	}
+
+	char *package_file_string_copy = g_strdup(package_file.c_str());
+	char *tmp_dest_dir_string_copy = g_strdup(tmp_dest_dir.c_str());
+	gchar *argv[8] = {
+		tar_cmd,
+		const_cast<gchar*>("--strip"), const_cast<gchar*>("1"),
+		const_cast<gchar*>("-xjf"),
+		package_file_string_copy,
+		const_cast<gchar*>("-C"), tmp_dest_dir_string_copy,
+		NULL,
+	};
+
+	llinfos << "Untarring package: " << package_file << llendl;
+
+	// store current SIGCHLD handler if there is one, replace with default
+	// handler to make glib happy
+	struct sigaction sigchld_backup;
+	struct sigaction sigchld_appease_glib;
+	sigchld_appease_glib.sa_handler = SIG_DFL;
+	sigemptyset(&sigchld_appease_glib.sa_mask);
+	sigchld_appease_glib.sa_flags = 0;
+	sigaction(SIGCHLD, &sigchld_appease_glib, &sigchld_backup);
+
+	gchar *stderr_output = NULL;
+	gint child_exit_status = 0;
+	GError *untar_error = NULL;
+	if (!less_anal_gspawnsync(argv, &stderr_output,
+				  &child_exit_status, &untar_error))
+	{
+		llwarns << "Failed to spawn child process: "
+			<< untar_error->message
+			<< llendl;
+		return FALSE;
+	}
+
+	if (child_exit_status)
+	{
+	 	llwarns << "Untar command failed: "
+			<< (stderr_output ? stderr_output : "(no reason given)")
+			<< llendl;
+		return FALSE;
+	}
+
+	g_free(tar_cmd);
+	g_free(package_file_string_copy);
+	g_free(tmp_dest_dir_string_copy);
+	g_free(stderr_output);
+	if (untar_error) g_error_free(untar_error);
+
+	// move the existing package out of the way if it exists
+	if (gDirUtilp->fileExists(destination))
+	{
+		std::string backup_dir = destination + ".backup";
+		int oldcounter = 1;
+		while (gDirUtilp->fileExists(backup_dir))
+		{
+			// find a foo.backup.N folder name that isn't taken yet
+			backup_dir = destination + ".backup." + llformat("%d", oldcounter);
+			++oldcounter;
+		}
+
+		if (rename_with_sudo_fallback(destination, backup_dir))
+		{
+			llwarns << "Failed to move directory: '"
+				<< destination << "' -> '" << backup_dir
+				<< llendl;
+			return FALSE;
+		}
+	}
+
+	// The package has been unpacked in a staging directory, now we just
+	// need to move it to its destination.
+	if (rename_with_sudo_fallback(tmp_dest_dir, destination))
+	{
+		llwarns << "Failed to move installation to the destination: "
+			<< destination
+			<< llendl;
+		return FALSE;
+	}
+
+	// \0/ Success!
+	return TRUE;
+}
+
+gboolean progress_update_timeout(gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+
+	app_state = (UpdaterAppState *) data;
+
+	gdk_threads_enter();
+	if (app_state->activity_mode)
+	{
+		gtk_progress_bar_pulse
+			(GTK_PROGRESS_BAR(app_state->progress_bar));
+	}
+	else
+	{
+		gtk_progress_set_value(GTK_PROGRESS(app_state->progress_bar),
+				       app_state->progress_value);
+	}
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+gboolean update_progress_text_timeout(gpointer data)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	if (app_state->activity_mode == TRUE)
+	{
+		// We no longer need this timeout, it will be removed.
+		return FALSE;
+	}
+
+	if (!app_state->progress_value)
+	{
+		return TRUE;
+	}
+
+	std::string progress_text = llformat((LLTrans::getString("UpdaterProgressBarText")+" (%.0f%%)").c_str(), app_state->progress_value);
+
+	gdk_threads_enter();
+	gtk_progress_bar_set_text(GTK_PROGRESS_BAR(app_state->progress_bar),
+				  progress_text.c_str());
+	gdk_threads_leave();
+
+	return TRUE;
+}
+
+int download_progress_cb(gpointer data,
+			 double t,
+			 double d,
+			 double utotal,
+			 double ulnow)
+{
+	UpdaterAppState *app_state;
+
+	llassert(data != NULL);
+	app_state = (UpdaterAppState *) data;
+
+	if (t <= 0.0)
+	{
+		app_state->progress_value = 0;
+	}
+	else
+	{
+		app_state->progress_value = d * 100.0 / t;
+	}
+	return 0;
+}
+
+BOOL spawn_viewer(UpdaterAppState *app_state)
+{
+	llassert(app_state != NULL);
+
+	std::string cmd = app_state->dest_dir + "/secondlife";
+	GError *error = NULL;
+
+	// We want to spawn the Viewer on the same display as the updater app
+	gboolean success = gdk_spawn_command_line_on_screen
+		(gtk_widget_get_screen(app_state->window), cmd.c_str(), &error);
+
+	if (!success)
+	{
+		llwarns << "Failed to launch viewer: " << error->message
+			<< llendl;
+	}
+
+	if (error) g_error_free(error);
+
+	return success;
+}
+
+void show_usage_and_exit()
+{
+	std::cout << "Usage: linux-updater <--url URL | --file FILE> --name NAME --dest PATH --stringsdir PATH1,PATH2 --stringsfile FILE"
+		  << "[--image-dir PATH]"
+		  << std::endl;
+	exit(1);
+}
+
+void parse_args_and_init(int argc, char **argv, UpdaterAppState *app_state)
+{
+	int i;
+
+	for (i = 1; i < argc; i++)
+	{
+		if ((!strcmp(argv[i], "--url")) && (++i < argc))
+		{
+			app_state->url = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--file")) && (++i < argc))
+		{
+			app_state->file = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--name")) && (++i < argc))
+		{
+			app_state->app_name = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--image-dir")) && (++i < argc))
+		{
+			app_state->image_dir = argv[i];
+			app_state->image_dir_iter = new LLDirIterator(argv[i], "*.jpg");
+		}
+		else if ((!strcmp(argv[i], "--dest")) && (++i < argc))
+		{
+			app_state->dest_dir = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--stringsdir")) && (++i < argc))
+		{
+			app_state->strings_dirs = argv[i];
+		}
+		else if ((!strcmp(argv[i], "--stringsfile")) && (++i < argc))
+		{
+			app_state->strings_file = argv[i];
+		}
+		else
+		{
+			// show usage, an invalid option was given.
+			show_usage_and_exit();
+		}
+	}
+
+	if (app_state->app_name.empty()
+	    || (app_state->url.empty() && app_state->file.empty())
+	    || app_state->dest_dir.empty())
+	{
+		show_usage_and_exit();
+	}
+
+	app_state->progress_value = 0.0;
+	app_state->activity_mode = FALSE;
+	app_state->failure = FALSE;
+
+	translate_init(app_state->strings_dirs, app_state->strings_file);
+}
+
+int main(int argc, char **argv)
+{
+	UpdaterAppState* app_state = new UpdaterAppState;
+
+	parse_args_and_init(argc, argv, app_state);
+
+	// Initialize logger, and rename old log file
+	gDirUtilp->initAppDirs("SecondLife");
+	LLError::initForApplication
+		(gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, ""));
+	std::string old_log_file = gDirUtilp->getExpandedFilename
+		(LL_PATH_LOGS, "updater.log.old");
+	std::string log_file =
+		gDirUtilp->getExpandedFilename(LL_PATH_LOGS, "updater.log");
+	LLFile::rename(log_file, old_log_file);
+	LLError::logToFile(log_file);
+
+	// initialize gthreads and gtk+
+	if (!g_thread_supported())
+	{
+		g_thread_init(NULL);
+		gdk_threads_init();
+	}
+
+	gtk_init(&argc, &argv);
+
+	// create UI
+	updater_app_ui_init(app_state);
+
+	//llinfos << "SAMPLE TRANSLATION IS: " << LLTrans::getString("LoginInProgress") << llendl;
+
+	// create download thread
+	g_thread_create(GThreadFunc(worker_thread_cb), app_state, FALSE, NULL);
+
+	gdk_threads_enter();
+	gtk_main();
+	gdk_threads_leave();
+
+	// Delete the file only if created from url download.
+	if(!app_state->url.empty() && !app_state->file.empty())
+	{
+		if (gDirUtilp->fileExists(app_state->file))
+		{
+			LLFile::remove(app_state->file);
+		}
+	}
+
+	bool success = !app_state->failure;
+	delete app_state->image_dir_iter;
+	delete app_state;
+	return success ? 0 : 1;
+}
+
+/*****************************************************************************
+*   Dummy LLTrans implementation (IQA-490)
+*****************************************************************************/
+static LLTrans sStaticStrings;
+
+// lookup
+std::string LLTrans::_getString(const std::string& key) const
+{
+	MessageMap::const_iterator found = mMessages.find(key);
+	if (found != mMessages.end())
+	{
+		return found->second;
+	}
+	LL_WARNS("linux_updater") << "No message for key '" << key
+							  << "' -- add to LLTrans::LLTrans() in linux_updater.cpp"
+							  << LL_ENDL;
+	return key;
+}
+
+// static lookup
+std::string LLTrans::getString(const std::string& key)
+{
+    return sLLTransInstance._getString(key);
+}
+
+// initialization
+LLTrans::LLTrans()
+{
+	typedef std::pair<const char*, const char*> Pair;
+	static const Pair data[] =
+	{
+		Pair("UpdaterFailDownloadTitle",
+			 "Failed to download update"),
+		Pair("UpdaterFailInstallTitle",
+			 "Failed to install update"),
+		Pair("UpdaterFailStartTitle",
+			 "Failed to start viewer"),
+		Pair("UpdaterFailUpdateDescriptive",
+			 "An error occurred while updating Second Life. "
+			 "Please download the latest version from www.secondlife.com."),
+		Pair("UpdaterNowInstalling",
+			 "Installing Second Life..."),
+		Pair("UpdaterNowUpdating",
+			 "Now updating Second Life..."),
+		Pair("UpdaterProgressBarText",
+			 "Downloading update"),
+		Pair("UpdaterProgressBarTextWithEllipses",
+			 "Downloading update..."),
+		Pair("UpdaterUpdatingDescriptive",
+			 "Your Second Life Viewer is being updated to the latest release. "
+			 "This may take some time, so please be patient."),
+		Pair("UpdaterWindowTitle",
+			 "Second Life Update")
+	};
+
+	BOOST_FOREACH(Pair pair, data)
+	{
+		mMessages[pair.first] = pair.second;
+	}
+}
diff --git a/indra/llappearance/CMakeLists.txt b/indra/llappearance/CMakeLists.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0dbd58b7cd7e6a22aa6a7e630923e9636ac9b764
--- /dev/null
+++ b/indra/llappearance/CMakeLists.txt
@@ -0,0 +1,118 @@
+# -*- cmake -*-
+
+project(llappearance)
+
+include(00-Common)
+include(LLCommon)
+include(LLCharacter)
+include(LLImage)
+include(LLInventory)
+include(LLMath)
+include(LLMessage)
+include(LLRender)
+include(LLVFS)
+include(LLWindow)
+include(LLXML)
+include(Linking)
+
+include_directories(
+    ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCHARACTER_INCLUDE_DIRS}
+    ${LLIMAGE_INCLUDE_DIRS}
+    ${LLINVENTORY_INCLUDE_DIRS}
+    ${LLMATH_INCLUDE_DIRS}
+    ${LLRENDER_INCLUDE_DIRS}
+    ${LLVFS_INCLUDE_DIRS}
+    ${LLWINDOW_INCLUDE_DIRS}
+    ${LLXML_INCLUDE_DIRS}
+    )
+
+set(llappearance_SOURCE_FILES
+    llavatarappearance.cpp
+    llavatarjoint.cpp
+    llavatarjointmesh.cpp
+    lldriverparam.cpp
+    lllocaltextureobject.cpp
+    llpolyskeletaldistortion.cpp
+    llpolymesh.cpp
+    llpolymorph.cpp
+    lltexglobalcolor.cpp
+    lltexlayer.cpp
+    lltexlayerparams.cpp
+    lltexturemanagerbridge.cpp
+    llwearable.cpp
+    llwearabledata.cpp
+    llwearabletype.cpp
+    llviewervisualparam.cpp
+    llavatarappearancedefines.cpp
+    )
+    
+set(llappearance_HEADER_FILES
+    CMakeLists.txt
+
+    llavatarappearance.h
+    llavatarjoint.h
+    llavatarjointmesh.h
+    lldriverparam.h
+    lljointpickname.h
+    lllocaltextureobject.h
+    llpolyskeletaldistortion.h
+    llpolymesh.h
+    llpolymorph.h
+    lltexglobalcolor.h
+    lltexlayer.h
+    lltexlayerparams.h
+    lltexturemanagerbridge.h
+    llwearable.h
+    llwearabledata.h
+    llwearabletype.h
+    llviewervisualparam.h
+    llavatarappearancedefines.h
+    )
+
+set_source_files_properties(${llappearance_HEADER_FILES}
+                            PROPERTIES HEADER_FILE_ONLY TRUE)
+
+list(APPEND llappearance_SOURCE_FILES ${llappearance_HEADER_FILES})
+
+add_library (llappearance ${llappearance_SOURCE_FILES})
+
+target_link_libraries(llappearance
+    ${LLCHARACTER_LIBRARIES}
+    ${LLINVENTORY_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLRENDER_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
+    )
+
+if (BUILD_HEADLESS)
+  add_library (llappearanceheadless ${llappearance_SOURCE_FILES})
+  
+  target_link_libraries(llappearanceheadless
+      ${LLCHARACTER_LIBRARIES}
+      ${LLINVENTORY_LIBRARIES}
+      ${LLIMAGE_LIBRARIES}
+      ${LLRENDERHEADLESS_LIBRARIES}
+      ${LLVFS_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLXML_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLCOMMON_LIBRARIES}
+      )
+endif (BUILD_HEADLESS)
+
+#add unit tests
+#if (LL_TESTS)
+#    INCLUDE(LLAddBuildTest)
+#    SET(llappearance_TEST_SOURCE_FILES
+#      # no real unit tests yet!
+#      )
+#    LL_ADD_PROJECT_UNIT_TESTS(llappearance "${llappearance_TEST_SOURCE_FILES}")
+
+    #set(TEST_DEBUG on)
+#    set(test_libs llappearance ${LLCOMMON_LIBRARIES})
+#endif (LL_TESTS)
diff --git a/indra/llappearance/llavatarappearance.cpp b/indra/llappearance/llavatarappearance.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3bb759d45879890b3e81b78be9b9db48971d7a0b
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.cpp
@@ -0,0 +1,1953 @@
+/** 
+ * @File llavatarappearance.cpp
+ * @brief Implementation of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#if LL_MSVC
+// disable warning about boost::lexical_cast returning uninitialized data
+// when it fails to parse the string
+#pragma warning (disable:4701)
+#endif
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "imageids.h"
+#include "lldir.h"
+#include "lldeleteutils.h"
+#include "llpolymorph.h"
+#include "llpolymesh.h"
+#include "llpolyskeletaldistortion.h"
+#include "llstl.h"
+#include "lltexglobalcolor.h"
+#include "llwearabledata.h"
+
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
+
+#include <boost/lexical_cast.hpp>
+
+using namespace LLAvatarAppearanceDefines;
+
+//-----------------------------------------------------------------------------
+// Constants
+//-----------------------------------------------------------------------------
+
+const std::string AVATAR_DEFAULT_CHAR = "avatar";
+const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+
+/*********************************************************************************
+ **                                                                             **
+ ** Begin private LLAvatarAppearance Support classes
+ **
+ **/
+
+//------------------------------------------------------------------------
+// LLAvatarBoneInfo
+// Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.
+//------------------------------------------------------------------------
+class LLAvatarBoneInfo
+{
+	friend class LLAvatarAppearance;
+	friend class LLAvatarSkeletonInfo;
+public:
+	LLAvatarBoneInfo() : mIsJoint(FALSE) {}
+	~LLAvatarBoneInfo()
+	{
+		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
+	}
+	BOOL parseXml(LLXmlTreeNode* node);
+	
+private:
+	std::string mName;
+	BOOL mIsJoint;
+	LLVector3 mPos;
+	LLVector3 mRot;
+	LLVector3 mScale;
+	LLVector3 mPivot;
+	typedef std::vector<LLAvatarBoneInfo*> child_list_t;
+	child_list_t mChildList;
+};
+
+//------------------------------------------------------------------------
+// LLAvatarSkeletonInfo
+// Overall avatar skeleton
+//------------------------------------------------------------------------
+class LLAvatarSkeletonInfo
+{
+	friend class LLAvatarAppearance;
+public:
+	LLAvatarSkeletonInfo() :
+		mNumBones(0), mNumCollisionVolumes(0) {}
+	~LLAvatarSkeletonInfo()
+	{
+		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
+	}
+	BOOL parseXml(LLXmlTreeNode* node);
+	S32 getNumBones() const { return mNumBones; }
+	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+	
+private:
+	S32 mNumBones;
+	S32 mNumCollisionVolumes;
+	typedef std::vector<LLAvatarBoneInfo*> bone_info_list_t;
+	bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLAvatarXmlInfo
+//-----------------------------------------------------------------------------
+
+LLAvatarAppearance::LLAvatarXmlInfo::LLAvatarXmlInfo()
+	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
+{
+}
+
+LLAvatarAppearance::LLAvatarXmlInfo::~LLAvatarXmlInfo()
+{
+	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
+	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		
+	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
+	deleteAndClear(mTexSkinColorInfo);
+	deleteAndClear(mTexHairColorInfo);
+	deleteAndClear(mTexEyeColorInfo);
+	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		
+	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
+	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
+}
+
+
+/**
+ **
+ ** End LLAvatarAppearance Support classes
+ **                                                                             **
+ *********************************************************************************/
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+LLXmlTree LLAvatarAppearance::sXMLTree;
+LLXmlTree LLAvatarAppearance::sSkeletonXMLTree;
+LLAvatarSkeletonInfo* LLAvatarAppearance::sAvatarSkeletonInfo = NULL;
+LLAvatarAppearance::LLAvatarXmlInfo* LLAvatarAppearance::sAvatarXmlInfo = NULL;
+
+
+LLAvatarAppearance::LLAvatarAppearance(LLWearableData* wearable_data) :
+	LLCharacter(),
+	mIsDummy(FALSE),
+	mTexSkinColor( NULL ),
+	mTexHairColor( NULL ),
+	mTexEyeColor( NULL ),
+	mPelvisToFoot(0.f),
+	mHeadOffset(),
+	mRoot(NULL),
+	mWearableData(wearable_data)
+{
+	llassert_always(mWearableData);
+	mBakedTextureDatas.resize(LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
+	{
+		mBakedTextureDatas[i].mLastTextureID = IMG_DEFAULT_AVATAR;
+		mBakedTextureDatas[i].mTexLayerSet = NULL;
+		mBakedTextureDatas[i].mIsLoaded = false;
+		mBakedTextureDatas[i].mIsUsed = false;
+		mBakedTextureDatas[i].mMaskTexName = 0;
+		mBakedTextureDatas[i].mTextureIndex = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((LLAvatarAppearanceDefines::EBakedTextureIndex)i);
+	}
+
+	mIsBuilt = FALSE;
+
+	mNumCollisionVolumes = 0;
+	mCollisionVolumes = NULL;
+}
+
+// virtual
+void LLAvatarAppearance::initInstance()
+{
+	//-------------------------------------------------------------------------
+	// initialize joint, mesh and shape members
+	//-------------------------------------------------------------------------
+	mRoot = createAvatarJoint();
+	mRoot->setName( "mRoot" );
+
+	for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+		 ++iter)
+	{
+		const EMeshIndex mesh_index = iter->first;
+		const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+		LLAvatarJoint* joint = createAvatarJoint();
+		joint->setName(mesh_dict->mName);
+		joint->setMeshID(mesh_index);
+		mMeshLOD.push_back(joint);
+		
+		/* mHairLOD.setName("mHairLOD");
+		   mHairMesh0.setName("mHairMesh0");
+		   mHairMesh0.setMeshID(MESH_ID_HAIR);
+		   mHairMesh1.setName("mHairMesh1"); */
+		for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
+		{
+			LLAvatarJointMesh* mesh = createAvatarJointMesh();
+			std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
+			// We pre-pended an m - need to capitalize first character for camelCase
+			mesh_name[1] = toupper(mesh_name[1]);
+			mesh->setName(mesh_name);
+			mesh->setMeshID(mesh_index);
+			mesh->setPickName(mesh_dict->mPickName);
+			mesh->setIsTransparent(FALSE);
+			switch((int)mesh_index)
+			{
+				case MESH_ID_HAIR:
+					mesh->setIsTransparent(TRUE);
+					break;
+				case MESH_ID_SKIRT:
+					mesh->setIsTransparent(TRUE);
+					break;
+				case MESH_ID_EYEBALL_LEFT:
+				case MESH_ID_EYEBALL_RIGHT:
+					mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
+					break;
+			}
+			
+			joint->mMeshParts.push_back(mesh);
+		}
+	}
+
+	//-------------------------------------------------------------------------
+	// associate baked textures with meshes
+	//-------------------------------------------------------------------------
+	for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+		 ++iter)
+	{
+		const EMeshIndex mesh_index = iter->first;
+		const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = iter->second;
+		const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
+		// Skip it if there's no associated baked texture.
+		if (baked_texture_index == BAKED_NUM_INDICES) continue;
+		
+		for (avatar_joint_mesh_list_t::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
+			 iter != mMeshLOD[mesh_index]->mMeshParts.end(); 
+			 ++iter)
+		{
+			LLAvatarJointMesh* mesh = (*iter);
+			mBakedTextureDatas[(int)baked_texture_index].mJointMeshes.push_back(mesh);
+		}
+	}
+
+	buildCharacter();
+
+}
+
+// virtual
+LLAvatarAppearance::~LLAvatarAppearance()
+{
+	deleteAndClear(mTexSkinColor);
+	deleteAndClear(mTexHairColor);
+	deleteAndClear(mTexEyeColor);
+
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+	{
+		deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
+		mBakedTextureDatas[i].mJointMeshes.clear();
+
+		for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
+			 iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
+		{
+			LLMaskedMorph* masked_morph = (*iter2);
+			delete masked_morph;
+		}
+	}
+
+	if (mRoot) mRoot->removeAllChildren();
+	mJointMap.clear();
+
+	clearSkeleton();
+	deleteAndClearArray(mCollisionVolumes);
+
+	deleteAndClear(mTexSkinColor);
+	deleteAndClear(mTexHairColor);
+	deleteAndClear(mTexEyeColor);
+
+	std::for_each(mPolyMeshes.begin(), mPolyMeshes.end(), DeletePairedPointer());
+	mPolyMeshes.clear();
+
+	for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+		 jointIter != mMeshLOD.end(); 
+		 ++jointIter)
+	{
+		LLAvatarJoint* joint = *jointIter;
+		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
+		joint->mMeshParts.clear();
+	}
+	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
+	mMeshLOD.clear();
+}
+
+//static
+void LLAvatarAppearance::initClass()
+{
+	std::string xmlFile;
+
+	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
+	BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
+	if (!success)
+	{
+		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
+	}
+
+	// now sanity check xml file
+	LLXmlTreeNode* root = sXMLTree.getRoot();
+	if (!root) 
+	{
+		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// <linden_avatar version="1.0"> (root)
+	//-------------------------------------------------------------------------
+	if( !root->hasName( "linden_avatar" ) )
+	{
+		llerrs << "Invalid avatar file header: " << xmlFile << llendl;
+	}
+	
+	std::string version;
+	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	{
+		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
+	}
+
+	S32 wearable_def_version = 1;
+	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
+	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
+	LLWearable::setCurrentDefinitionVersion( wearable_def_version );
+
+	std::string mesh_file_name;
+
+	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
+	if (!skeleton_node)
+	{
+		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
+		return;
+	}
+	
+	std::string skeleton_file_name;
+	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
+	{
+		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
+	}
+	
+	std::string skeleton_path;
+	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
+	if (!parseSkeletonFile(skeleton_path))
+	{
+		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
+	}
+
+	// Process XML data
+
+	// avatar_skeleton.xml
+	if (sAvatarSkeletonInfo)
+	{ //this can happen if a login attempt failed
+		delete sAvatarSkeletonInfo;
+	}
+	sAvatarSkeletonInfo = new LLAvatarSkeletonInfo;
+	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
+	{
+		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
+	}
+	// parse avatar_lad.xml
+	if (sAvatarXmlInfo)
+	{ //this can happen if a login attempt failed
+		deleteAndClear(sAvatarXmlInfo);
+	}
+	sAvatarXmlInfo = new LLAvatarXmlInfo;
+	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlColorNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+	if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
+	{
+		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
+	}
+}
+
+void LLAvatarAppearance::cleanupClass()
+{
+	deleteAndClear(sAvatarXmlInfo);
+	// *TODO: What about sAvatarSkeletonInfo ???
+	sSkeletonXMLTree.cleanup();
+	sXMLTree.cleanup();
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+//------------------------------------------------------------------------
+// The viewer can only suggest a good size for the agent,
+// the simulator will keep it inside a reasonable range.
+void LLAvatarAppearance::computeBodySize() 
+{
+	LLVector3 pelvis_scale = mPelvisp->getScale();
+
+	// some of the joints have not been cached
+	LLVector3 skull = mSkullp->getPosition();
+	//LLVector3 skull_scale = mSkullp->getScale();
+
+	LLVector3 neck = mNeckp->getPosition();
+	LLVector3 neck_scale = mNeckp->getScale();
+
+	LLVector3 chest = mChestp->getPosition();
+	LLVector3 chest_scale = mChestp->getScale();
+
+	// the rest of the joints have been cached
+	LLVector3 head = mHeadp->getPosition();
+	LLVector3 head_scale = mHeadp->getScale();
+
+	LLVector3 torso = mTorsop->getPosition();
+	LLVector3 torso_scale = mTorsop->getScale();
+
+	LLVector3 hip = mHipLeftp->getPosition();
+	LLVector3 hip_scale = mHipLeftp->getScale();
+
+	LLVector3 knee = mKneeLeftp->getPosition();
+	LLVector3 knee_scale = mKneeLeftp->getScale();
+
+	LLVector3 ankle = mAnkleLeftp->getPosition();
+	LLVector3 ankle_scale = mAnkleLeftp->getScale();
+
+	LLVector3 foot  = mFootLeftp->getPosition();
+
+	F32 old_offset = mAvatarOffset.mV[VZ];
+
+	mAvatarOffset.mV[VZ] = getVisualParamWeight(AVATAR_HOVER);
+
+	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
+				 	knee.mV[VZ] * hip_scale.mV[VZ] -
+				 	ankle.mV[VZ] * knee_scale.mV[VZ] -
+				 	foot.mV[VZ] * ankle_scale.mV[VZ];
+
+	LLVector3 new_body_size;
+	new_body_size.mV[VZ] = mPelvisToFoot +
+					   // the sqrt(2) correction below is an approximate
+					   // correction to get to the top of the head
+					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + 
+					   head.mV[VZ] * neck_scale.mV[VZ] + 
+					   neck.mV[VZ] * chest_scale.mV[VZ] + 
+					   chest.mV[VZ] * torso_scale.mV[VZ] + 
+					   torso.mV[VZ] * pelvis_scale.mV[VZ]; 
+
+	// TODO -- measure the real depth and width
+	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
+	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
+
+	mAvatarOffset.mV[VX] = 0.0f;
+	mAvatarOffset.mV[VY] = 0.0f;
+
+	// Certain configurations of avatars can force the overall height (with offset) to go negative.
+	// Enforce a constraint to make sure we don't go below 0.1 meters.
+	// Camera positioning and other things start to break down when your avatar is "walking" while being fully underground
+	if (new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] < 0.1f) 
+	{
+		mAvatarOffset.mV[VZ] = -(new_body_size.mV[VZ] - 0.11f); // avoid floating point rounding making the above check continue to fail.
+
+		llassert(new_body_size.mV[VZ] + mAvatarOffset.mV[VZ] >= 0.1f);
+
+		if (mWearableData && isSelf()) 
+		{
+			LLWearable* shape = mWearableData->getWearable(LLWearableType::WT_SHAPE, 0);
+			if (shape) 
+			{
+				shape->setVisualParamWeight(AVATAR_HOVER, mAvatarOffset.mV[VZ], false);
+			}
+		}
+	}
+
+	if (new_body_size != mBodySize || old_offset != mAvatarOffset.mV[VZ])
+	{
+		mBodySize = new_body_size;
+		bodySizeChanged();
+	}
+}
+
+//-----------------------------------------------------------------------------
+// parseSkeletonFile()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::parseSkeletonFile(const std::string& filename)
+{
+	//-------------------------------------------------------------------------
+	// parse the file
+	//-------------------------------------------------------------------------
+	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
+
+	if (!parsesuccess)
+	{
+		llerrs << "Can't parse skeleton file: " << filename << llendl;
+		return FALSE;
+	}
+
+	// now sanity check xml file
+	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
+	if (!root) 
+	{
+		llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
+		return FALSE;
+	}
+
+	if( !root->hasName( "linden_skeleton" ) )
+	{
+		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
+		return FALSE;
+	}
+
+	std::string version;
+	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
+	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
+	{
+		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
+		return FALSE;
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// setupBone()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &volume_num, S32 &joint_num)
+{
+	LLJoint* joint = NULL;
+
+	if (info->mIsJoint)
+	{
+		joint = getCharacterJoint(joint_num);
+		if (!joint)
+		{
+			llwarns << "Too many bones" << llendl;
+			return FALSE;
+		}
+		joint->setName( info->mName );
+	}
+	else // collision volume
+	{
+		if (volume_num >= (S32)mNumCollisionVolumes)
+		{
+			llwarns << "Too many bones" << llendl;
+			return FALSE;
+		}
+		joint = (&mCollisionVolumes[volume_num]);
+		joint->setName( info->mName );
+	}
+
+	// add to parent
+	if (parent)
+	{
+		parent->addChild( joint );
+	}
+
+	joint->setPosition(info->mPos);
+	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
+							 info->mRot.mV[VZ], LLQuaternion::XYZ));
+	joint->setScale(info->mScale);
+
+	joint->setDefaultFromCurrentXform();
+	
+	if (info->mIsJoint)
+	{
+		joint->setSkinOffset( info->mPivot );
+		joint_num++;
+	}
+	else // collision volume
+	{
+		volume_num++;
+	}
+
+	// setup children
+	LLAvatarBoneInfo::child_list_t::const_iterator iter;
+	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
+	{
+		LLAvatarBoneInfo *child_info = *iter;
+		if (!setupBone(child_info, joint, volume_num, joint_num))
+		{
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCharacterJoints()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCharacterJoints( U32 num )
+{
+	clearSkeleton();
+
+	for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+	{
+		mSkeleton.push_back(createAvatarJoint(joint_num));
+	}
+
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// buildSkeleton()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::buildSkeleton(const LLAvatarSkeletonInfo *info)
+{
+	//-------------------------------------------------------------------------
+	// allocate joints
+	//-------------------------------------------------------------------------
+	if (!allocateCharacterJoints(info->mNumBones))
+	{
+		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
+		return FALSE;
+	}
+	
+	//-------------------------------------------------------------------------
+	// allocate volumes
+	//-------------------------------------------------------------------------
+	if (info->mNumCollisionVolumes)
+	{
+		if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
+		{
+			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
+			return FALSE;
+		}
+	}
+
+	S32 current_joint_num = 0;
+	S32 current_volume_num = 0;
+	LLAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
+	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
+	{
+		LLAvatarBoneInfo *info = *iter;
+		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
+		{
+			llerrs << "Error parsing bone in skeleton file" << llendl;
+			return FALSE;
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// clearSkeleton()
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::clearSkeleton()
+{
+	std::for_each(mSkeleton.begin(), mSkeleton.end(), DeletePointer());
+	mSkeleton.clear();
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::buildCharacter()
+// Deferred initialization and rebuild of the avatar.
+//-----------------------------------------------------------------------------
+void LLAvatarAppearance::buildCharacter()
+{
+	//-------------------------------------------------------------------------
+	// remove all references to our existing skeleton
+	// so we can rebuild it
+	//-------------------------------------------------------------------------
+	flushAllMotions();
+
+	//-------------------------------------------------------------------------
+	// remove all of mRoot's children
+	//-------------------------------------------------------------------------
+	mRoot->removeAllChildren();
+	mJointMap.clear();
+	mIsBuilt = FALSE;
+
+	//-------------------------------------------------------------------------
+	// clear mesh data
+	//-------------------------------------------------------------------------
+	for (avatar_joint_list_t::iterator jointIter = mMeshLOD.begin();
+		 jointIter != mMeshLOD.end(); ++jointIter)
+	{
+		LLAvatarJoint* joint = *jointIter;
+		for (avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
+			 meshIter != joint->mMeshParts.end(); ++meshIter)
+		{
+			LLAvatarJointMesh * mesh = *meshIter;
+			mesh->setMesh(NULL);
+		}
+	}
+
+	//-------------------------------------------------------------------------
+	// (re)load our skeleton and meshes
+	//-------------------------------------------------------------------------
+	LLTimer timer;
+
+	BOOL status = loadAvatar();
+	stop_glerror();
+
+// 	gPrintMessagesThisFrame = TRUE;
+	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
+
+	if (!status)
+	{
+		if (isSelf())
+		{
+			llerrs << "Unable to load user's avatar" << llendl;
+		}
+		else
+		{
+			llwarns << "Unable to load other's avatar" << llendl;
+		}
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// initialize "well known" joint pointers
+	//-------------------------------------------------------------------------
+	mPelvisp		= mRoot->findJoint("mPelvis");
+	mTorsop			= mRoot->findJoint("mTorso");
+	mChestp			= mRoot->findJoint("mChest");
+	mNeckp			= mRoot->findJoint("mNeck");
+	mHeadp			= mRoot->findJoint("mHead");
+	mSkullp			= mRoot->findJoint("mSkull");
+	mHipLeftp		= mRoot->findJoint("mHipLeft");
+	mHipRightp		= mRoot->findJoint("mHipRight");
+	mKneeLeftp		= mRoot->findJoint("mKneeLeft");
+	mKneeRightp		= mRoot->findJoint("mKneeRight");
+	mAnkleLeftp		= mRoot->findJoint("mAnkleLeft");
+	mAnkleRightp	= mRoot->findJoint("mAnkleRight");
+	mFootLeftp		= mRoot->findJoint("mFootLeft");
+	mFootRightp		= mRoot->findJoint("mFootRight");
+	mWristLeftp		= mRoot->findJoint("mWristLeft");
+	mWristRightp	= mRoot->findJoint("mWristRight");
+	mEyeLeftp		= mRoot->findJoint("mEyeLeft");
+	mEyeRightp		= mRoot->findJoint("mEyeRight");
+
+	//-------------------------------------------------------------------------
+	// Make sure "well known" pointers exist
+	//-------------------------------------------------------------------------
+	if (!(mPelvisp && 
+		  mTorsop &&
+		  mChestp &&
+		  mNeckp &&
+		  mHeadp &&
+		  mSkullp &&
+		  mHipLeftp &&
+		  mHipRightp &&
+		  mKneeLeftp &&
+		  mKneeRightp &&
+		  mAnkleLeftp &&
+		  mAnkleRightp &&
+		  mFootLeftp &&
+		  mFootRightp &&
+		  mWristLeftp &&
+		  mWristRightp &&
+		  mEyeLeftp &&
+		  mEyeRightp))
+	{
+		llerrs << "Failed to create avatar." << llendl;
+		return;
+	}
+
+	//-------------------------------------------------------------------------
+	// initialize the pelvis
+	//-------------------------------------------------------------------------
+	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
+
+	mIsBuilt = TRUE;
+	stop_glerror();
+
+}
+
+BOOL LLAvatarAppearance::loadAvatar()
+{
+// 	LLFastTimer t(FTM_LOAD_AVATAR);
+	
+	// avatar_skeleton.xml
+	if( !buildSkeleton(sAvatarSkeletonInfo) )
+	{
+		llwarns << "avatar file: buildSkeleton() failed" << llendl;
+		return FALSE;
+	}
+
+	// avatar_lad.xml : <skeleton>
+	if( !loadSkeletonNode() )
+	{
+		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <mesh>
+	if( !loadMeshNodes() )
+	{
+		llwarns << "avatar file: loadNodeMesh() failed" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <global_color>
+	if( sAvatarXmlInfo->mTexSkinColorInfo )
+	{
+		mTexSkinColor = new LLTexGlobalColor( this );
+		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
+		{
+			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
+		return FALSE;
+	}
+	if( sAvatarXmlInfo->mTexHairColorInfo )
+	{
+		mTexHairColor = new LLTexGlobalColor( this );
+		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
+		{
+			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
+		return FALSE;
+	}
+	if( sAvatarXmlInfo->mTexEyeColorInfo )
+	{
+		mTexEyeColor = new LLTexGlobalColor( this );
+		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
+		{
+			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
+			return FALSE;
+		}
+	}
+	else
+	{
+		llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
+		return FALSE;
+	}
+	
+	// avatar_lad.xml : <layer_set>
+	if (sAvatarXmlInfo->mLayerInfoList.empty())
+	{
+		llwarns << "avatar file: missing <layer_set> node" << llendl;
+		return FALSE;
+	}
+
+	if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
+	{
+		llwarns << "avatar file: missing <morph_masks> node" << llendl;
+		return FALSE;
+	}
+
+	// avatar_lad.xml : <morph_masks>
+	for (LLAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
+		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
+		 ++iter)
+	{
+		LLAvatarXmlInfo::LLAvatarMorphInfo *info = *iter;
+
+		EBakedTextureIndex baked = LLAvatarAppearanceDictionary::findBakedByRegionName(info->mRegion); 
+		if (baked != BAKED_NUM_INDICES)
+		{
+			LLVisualParam* morph_param;
+			const std::string *name = &info->mName;
+			morph_param = getVisualParam(name->c_str());
+			if (morph_param)
+			{
+				BOOL invert = info->mInvert;
+				addMaskedMorph(baked, morph_param, invert, info->mLayer);
+			}
+		}
+
+	}
+
+	loadLayersets();
+	
+	// avatar_lad.xml : <driver_parameters>
+	for (LLAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
+		 iter != sAvatarXmlInfo->mDriverInfoList.end(); 
+		 ++iter)
+	{
+		LLDriverParamInfo *info = *iter;
+		LLDriverParam* driver_param = new LLDriverParam( this );
+		if (driver_param->setInfo(info))
+		{
+			addVisualParam( driver_param );
+			driver_param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+			LLVisualParam*(LLAvatarAppearance::*avatar_function)(S32)const = &LLAvatarAppearance::getVisualParam; 
+			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLAvatarAppearance*)this,_1 ), false))
+			{
+				llwarns << "could not link driven params for avatar " << getID().asString() << " param id: " << driver_param->getID() << llendl;
+				continue;
+			}
+		}
+		else
+		{
+			delete driver_param;
+			llwarns << "avatar file: driver_param->parseData() failed" << llendl;
+			return FALSE;
+		}
+	}
+
+	
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadSkeletonNode(): loads <skeleton> node from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadSkeletonNode ()
+{
+	mRoot->addChild( mSkeleton[0] );
+
+	// make meshes children before calling parent version of the function
+	for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
+		 iter != mMeshLOD.end(); 
+		 ++iter)
+	{
+		LLAvatarJoint *joint = *iter;
+		joint->mUpdateXform = FALSE;
+		joint->setMeshesToChildren();
+	}
+
+	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+	mRoot->addChild(mMeshLOD[MESH_ID_EYELASH]);
+	mRoot->addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
+	mRoot->addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
+	mRoot->addChild(mMeshLOD[MESH_ID_SKIRT]);
+	mRoot->addChild(mMeshLOD[MESH_ID_HEAD]);
+
+	LLAvatarJoint *skull = (LLAvatarJoint*)mRoot->findJoint("mSkull");
+	if (skull)
+	{
+		skull->addChild(mMeshLOD[MESH_ID_HAIR] );
+	}
+
+	LLAvatarJoint *eyeL = (LLAvatarJoint*)mRoot->findJoint("mEyeLeft");
+	if (eyeL)
+	{
+		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
+	}
+
+	LLAvatarJoint *eyeR = (LLAvatarJoint*)mRoot->findJoint("mEyeRight");
+	if (eyeR)
+	{
+		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
+	}
+
+	// SKELETAL DISTORTIONS
+	{
+		LLAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
+		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
+			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); 
+			 ++iter)
+		{
+			LLPolySkeletalDistortionInfo *info = (LLPolySkeletalDistortionInfo*)*iter;
+			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
+			if (!param->setInfo(info))
+			{
+				delete param;
+				return FALSE;
+			}
+			else
+			{
+				addVisualParam(param);
+				param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+			}				
+		}
+	}
+
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadMeshNodes(): loads <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadMeshNodes()
+{
+	for (LLAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
+		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); 
+		 ++meshinfo_iter)
+	{
+		const LLAvatarXmlInfo::LLAvatarMeshInfo *info = *meshinfo_iter;
+		const std::string &type = info->mType;
+		S32 lod = info->mLOD;
+
+		LLAvatarJointMesh* mesh = NULL;
+		U8 mesh_id = 0;
+		BOOL found_mesh_id = FALSE;
+
+		/* if (type == "hairMesh")
+			switch(lod)
+			  case 0:
+				mesh = &mHairMesh0; */
+		for (LLAvatarAppearanceDictionary::MeshEntries::const_iterator mesh_iter = LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().begin();
+			 mesh_iter != LLAvatarAppearanceDictionary::getInstance()->getMeshEntries().end();
+			 ++mesh_iter)
+		{
+			const EMeshIndex mesh_index = mesh_iter->first;
+			const LLAvatarAppearanceDictionary::MeshEntry *mesh_dict = mesh_iter->second;
+			if (type.compare(mesh_dict->mName) == 0)
+			{
+				mesh_id = mesh_index;
+				found_mesh_id = TRUE;
+				break;
+			}
+		}
+
+		if (found_mesh_id)
+		{
+			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
+			{
+				mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
+			}
+			else
+			{
+				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
+				return FALSE;
+			}
+		}
+		else 
+		{
+			llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
+			return FALSE;
+		}
+
+		//	llinfos << "Parsing mesh data for " << type << "..." << llendl;
+
+		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
+		// Do not touch!!!
+		mesh->setColor( LLColor4::white );
+
+		LLPolyMesh *poly_mesh = NULL;
+
+		if (!info->mReferenceMeshName.empty())
+		{
+			polymesh_map_t::const_iterator polymesh_iter = mPolyMeshes.find(info->mReferenceMeshName);
+			if (polymesh_iter != mPolyMeshes.end())
+			{
+				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
+				poly_mesh->setAvatar(this);
+			}
+			else
+			{
+				// This should never happen
+				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
+			}
+		}
+		else
+		{
+			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
+			poly_mesh->setAvatar(this);
+		}
+
+		if( !poly_mesh )
+		{
+			llwarns << "Failed to load mesh of type " << type << llendl;
+			return FALSE;
+		}
+
+		// Multimap insert
+		mPolyMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
+	
+		mesh->setMesh( poly_mesh );
+		mesh->setLOD( info->mMinPixelArea );
+
+		for (LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
+			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); 
+			 ++xmlinfo_iter)
+		{
+			const LLAvatarXmlInfo::LLAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
+			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
+			if (!param->setInfo((LLPolyMorphTargetInfo*)info_pair->first))
+			{
+				delete param;
+				return FALSE;
+			}
+			else
+			{
+				if (info_pair->second)
+				{
+					addSharedVisualParam(param);
+					param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+				}
+				else
+				{
+					addVisualParam(param);
+					param->setParamLocation(isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
+				}
+			}				
+		}
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// loadLayerSets()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::loadLayersets()
+{
+	BOOL success = TRUE;
+	for (LLAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
+		 layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); 
+		 ++layerset_iter)
+	{
+		LLTexLayerSetInfo *layerset_info = *layerset_iter;
+		if (isSelf())
+		{
+			// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+			LLTexLayerSet* layer_set = createTexLayerSet();
+			
+			if (!layer_set->setInfo(layerset_info))
+			{
+				stop_glerror();
+				delete layer_set;
+				llwarns << "avatar file: layer_set->setInfo() failed" << llendl;
+				return FALSE;
+			}
+
+			// scan baked textures and associate the layerset with the appropriate one
+			EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
+			for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+				 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+				 ++baked_iter)
+			{
+				const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+				if (layer_set->isBodyRegion(baked_dict->mName))
+				{
+					baked_index = baked_iter->first;
+					// ensure both structures are aware of each other
+					mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
+					layer_set->setBakedTexIndex(baked_index);
+					break;
+				}
+			}
+			// if no baked texture was found, warn and cleanup
+			if (baked_index == BAKED_NUM_INDICES)
+			{
+				llwarns << "<layer_set> has invalid body_region attribute" << llendl;
+				delete layer_set;
+				return FALSE;
+			}
+
+			// scan morph masks and let any affected layers know they have an associated morph
+			for (LLAvatarAppearance::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
+				morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
+				 ++morph_iter)
+			{
+				LLMaskedMorph *morph = *morph_iter;
+				LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
+				if (layer)
+				{
+					layer->setHasMorph(TRUE);
+				}
+				else
+				{
+					llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
+					success = FALSE;
+				}
+			}
+		}
+		else // !isSelf()
+		{
+			// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
+			LLTexLayerSetInfo *layerset_info = *layerset_iter;
+			layerset_info->createVisualParams(this);
+		}
+	}
+	return success;
+}
+
+//-----------------------------------------------------------------------------
+// getCharacterJoint()
+//-----------------------------------------------------------------------------
+LLJoint *LLAvatarAppearance::getCharacterJoint( U32 num )
+{
+	if ((S32)num >= mSkeleton.size()
+	    || (S32)num < 0)
+	{
+		return NULL;
+	}
+	return mSkeleton[num];
+}
+
+
+//-----------------------------------------------------------------------------
+// getVolumePos()
+//-----------------------------------------------------------------------------
+LLVector3 LLAvatarAppearance::getVolumePos(S32 joint_index, LLVector3& volume_offset)
+{
+	if (joint_index > mNumCollisionVolumes)
+	{
+		return LLVector3::zero;
+	}
+
+	return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+LLJoint* LLAvatarAppearance::findCollisionVolume(U32 volume_id)
+{
+	if ((S32)volume_id > mNumCollisionVolumes)
+	{
+		return NULL;
+	}
+	
+	return &mCollisionVolumes[volume_id];
+}
+
+//-----------------------------------------------------------------------------
+// findCollisionVolume()
+//-----------------------------------------------------------------------------
+S32 LLAvatarAppearance::getCollisionVolumeID(std::string &name)
+{
+	for (S32 i = 0; i < mNumCollisionVolumes; i++)
+	{
+		if (mCollisionVolumes[i].getName() == name)
+		{
+			return i;
+		}
+	}
+
+	return -1;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getHeadMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh*	LLAvatarAppearance::getHeadMesh()
+{
+	return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarAppearance::getUpperBodyMesh()
+//-----------------------------------------------------------------------------
+LLPolyMesh*	LLAvatarAppearance::getUpperBodyMesh()
+{
+	return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
+}
+
+
+
+// virtual
+BOOL LLAvatarAppearance::isValid() const
+{
+	// This should only be called on ourself.
+	if (!isSelf())
+	{
+		llerrs << "Called LLAvatarAppearance::isValid() on when isSelf() == false" << llendl;
+	}
+	return TRUE;
+}
+
+
+// adds a morph mask to the appropriate baked texture structure
+void LLAvatarAppearance::addMaskedMorph(EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer)
+{
+	if (index < BAKED_NUM_INDICES)
+	{
+		LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
+		mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+	}
+}
+
+
+//static
+BOOL LLAvatarAppearance::teToColorParams( ETextureIndex te, U32 *param_name )
+{
+	switch( te )
+	{
+		case TEX_UPPER_SHIRT:
+			param_name[0] = 803; //"shirt_red";
+			param_name[1] = 804; //"shirt_green";
+			param_name[2] = 805; //"shirt_blue";
+			break;
+
+		case TEX_LOWER_PANTS:
+			param_name[0] = 806; //"pants_red";
+			param_name[1] = 807; //"pants_green";
+			param_name[2] = 808; //"pants_blue";
+			break;
+
+		case TEX_LOWER_SHOES:
+			param_name[0] = 812; //"shoes_red";
+			param_name[1] = 813; //"shoes_green";
+			param_name[2] = 817; //"shoes_blue";
+			break;
+
+		case TEX_LOWER_SOCKS:
+			param_name[0] = 818; //"socks_red";
+			param_name[1] = 819; //"socks_green";
+			param_name[2] = 820; //"socks_blue";
+			break;
+
+		case TEX_UPPER_JACKET:
+		case TEX_LOWER_JACKET:
+			param_name[0] = 834; //"jacket_red";
+			param_name[1] = 835; //"jacket_green";
+			param_name[2] = 836; //"jacket_blue";
+			break;
+
+		case TEX_UPPER_GLOVES:
+			param_name[0] = 827; //"gloves_red";
+			param_name[1] = 829; //"gloves_green";
+			param_name[2] = 830; //"gloves_blue";
+			break;
+
+		case TEX_UPPER_UNDERSHIRT:
+			param_name[0] = 821; //"undershirt_red";
+			param_name[1] = 822; //"undershirt_green";
+			param_name[2] = 823; //"undershirt_blue";
+			break;
+	
+		case TEX_LOWER_UNDERPANTS:
+			param_name[0] = 824; //"underpants_red";
+			param_name[1] = 825; //"underpants_green";
+			param_name[2] = 826; //"underpants_blue";
+			break;
+
+		case TEX_SKIRT:
+			param_name[0] = 921; //"skirt_red";
+			param_name[1] = 922; //"skirt_green";
+			param_name[2] = 923; //"skirt_blue";
+			break;
+
+		case TEX_HEAD_TATTOO:
+		case TEX_LOWER_TATTOO:
+		case TEX_UPPER_TATTOO:
+			param_name[0] = 1071; //"tattoo_red";
+			param_name[1] = 1072; //"tattoo_green";
+			param_name[2] = 1073; //"tattoo_blue";
+			break;	
+
+		default:
+			llassert(0);
+			return FALSE;
+	}
+
+	return TRUE;
+}
+
+void LLAvatarAppearance::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
+{
+	U32 param_name[3];
+	if( teToColorParams( te, param_name ) )
+	{
+		setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
+		setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
+		setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
+	}
+}
+
+LLColor4 LLAvatarAppearance::getClothesColor( ETextureIndex te )
+{
+	LLColor4 color;
+	U32 param_name[3];
+	if( teToColorParams( te, param_name ) )
+	{
+		color.mV[VX] = getVisualParamWeight( param_name[0] );
+		color.mV[VY] = getVisualParamWeight( param_name[1] );
+		color.mV[VZ] = getVisualParamWeight( param_name[2] );
+	}
+	return color;
+}
+
+// static
+LLColor4 LLAvatarAppearance::getDummyColor()
+{
+	return DUMMY_COLOR;
+}
+
+LLColor4 LLAvatarAppearance::getGlobalColor( const std::string& color_name ) const
+{
+	if (color_name=="skin_color" && mTexSkinColor)
+	{
+		return mTexSkinColor->getColor();
+	}
+	else if(color_name=="hair_color" && mTexHairColor)
+	{
+		return mTexHairColor->getColor();
+	}
+	if(color_name=="eye_color" && mTexEyeColor)
+	{
+		return mTexEyeColor->getColor();
+	}
+	else
+	{
+//		return LLColor4( .5f, .5f, .5f, .5f );
+		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+	}
+}
+
+// Unlike most wearable functions, this works for both self and other.
+// virtual
+BOOL LLAvatarAppearance::isWearingWearableType(LLWearableType::EType type) const
+{
+	return mWearableData->getWearableCount(type) > 0;
+}
+
+LLTexLayerSet* LLAvatarAppearance::getAvatarLayerSet(EBakedTextureIndex baked_index) const
+{
+	/* switch(index)
+		case TEX_HEAD_BAKED:
+		case TEX_HEAD_BODYPAINT:
+			return mHeadLayerSet; */
+	return mBakedTextureDatas[baked_index].mTexLayerSet;
+}
+
+//-----------------------------------------------------------------------------
+// allocateCollisionVolumes()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::allocateCollisionVolumes( U32 num )
+{
+	deleteAndClearArray(mCollisionVolumes);
+	mNumCollisionVolumes = 0;
+
+	mCollisionVolumes = new LLAvatarJointCollisionVolume[num];
+	if (!mCollisionVolumes)
+	{
+		return FALSE;
+	}
+
+	mNumCollisionVolumes = num;
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarBoneInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
+{
+	if (node->hasName("bone"))
+	{
+		mIsJoint = TRUE;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!node->getFastAttributeString(name_string, mName))
+		{
+			llwarns << "Bone without name" << llendl;
+			return FALSE;
+		}
+	}
+	else if (node->hasName("collision_volume"))
+	{
+		mIsJoint = FALSE;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!node->getFastAttributeString(name_string, mName))
+		{
+			mName = "Collision Volume";
+		}
+	}
+	else
+	{
+		llwarns << "Invalid node " << node->getName() << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
+	if (!node->getFastAttributeVector3(pos_string, mPos))
+	{
+		llwarns << "Bone without position" << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
+	if (!node->getFastAttributeVector3(rot_string, mRot))
+	{
+		llwarns << "Bone without rotation" << llendl;
+		return FALSE;
+	}
+	
+	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+	if (!node->getFastAttributeVector3(scale_string, mScale))
+	{
+		llwarns << "Bone without scale" << llendl;
+		return FALSE;
+	}
+
+	if (mIsJoint)
+	{
+		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
+		if (!node->getFastAttributeVector3(pivot_string, mPivot))
+		{
+			llwarns << "Bone without pivot" << llendl;
+			return FALSE;
+		}
+	}
+
+	// parse children
+	LLXmlTreeNode* child;
+	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+	{
+		LLAvatarBoneInfo *child_info = new LLAvatarBoneInfo;
+		if (!child_info->parseXml(child))
+		{
+			delete child_info;
+			return FALSE;
+		}
+		mChildList.push_back(child_info);
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarSkeletonInfo::parseXml()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
+{
+	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
+	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
+	{
+		llwarns << "Couldn't find number of bones." << llendl;
+		return FALSE;
+	}
+
+	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
+	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
+
+	LLXmlTreeNode* child;
+	for( child = node->getFirstChild(); child; child = node->getNextChild() )
+	{
+		LLAvatarBoneInfo *info = new LLAvatarBoneInfo;
+		if (!info->parseXml(child))
+		{
+			delete info;
+			llwarns << "Error parsing bone in skeleton file" << llendl;
+			return FALSE;
+		}
+		mBoneInfoList.push_back(info);
+	}
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* node = root->getChildByName( "skeleton" );
+	if( !node )
+	{
+		llwarns << "avatar file: missing <skeleton>" << llendl;
+		return FALSE;
+	}
+
+	LLXmlTreeNode* child;
+
+	// SKELETON DISTORTIONS
+	for (child = node->getChildByName( "param" );
+		 child;
+		 child = node->getNextNamedChild())
+	{
+		if (!child->getChildByName("param_skeleton"))
+		{
+			if (child->getChildByName("param_morph"))
+			{
+				llwarns << "Can't specify morph param in skeleton definition." << llendl;
+			}
+			else
+			{
+				llwarns << "Unknown param type." << llendl;
+			}
+			continue;
+		}
+		
+		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
+		if (!info->parseXml(child))
+		{
+			delete info;
+			return FALSE;
+		}
+
+		mSkeletalDistortionInfoList.push_back(info);
+	}
+
+	// ATTACHMENT POINTS
+	for (child = node->getChildByName( "attachment_point" );
+		 child;
+		 child = node->getNextNamedChild())
+	{
+		LLAvatarAttachmentInfo* info = new LLAvatarAttachmentInfo();
+
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (!child->getFastAttributeString(name_string, info->mName))
+		{
+			llwarns << "No name supplied for attachment point." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
+		if (!child->getFastAttributeString(joint_string, info->mJointName))
+		{
+			llwarns << "No bone declared in attachment point " << info->mName << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
+		if (child->getFastAttributeVector3(position_string, info->mPosition))
+		{
+			info->mHasPosition = TRUE;
+		}
+
+		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
+		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
+		{
+			info->mHasRotation = TRUE;
+		}
+		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
+		if (child->getFastAttributeS32(group_string, info->mGroup))
+		{
+			if (info->mGroup == -1)
+				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
+		}
+
+		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
+		if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
+		{
+			llwarns << "No id supplied for attachment point " << info->mName << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
+		child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
+			
+		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
+		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
+
+		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
+		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
+
+		mAttachmentInfoList.push_back(info);
+	}
+
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
+		 node;
+		 node = root->getNextNamedChild())
+	{
+		LLAvatarMeshInfo *info = new LLAvatarMeshInfo;
+
+		// attribute: type
+		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
+		if( !node->getFastAttributeString( type_string, info->mType ) )
+		{
+			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+		
+		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
+		if (!node->getFastAttributeS32( lod_string, info->mLOD ))
+		{
+			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+
+		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
+		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
+		{
+			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl;
+			delete info;
+			return FALSE;  // Ignore this element
+		}
+
+		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
+		node->getFastAttributeString( reference_string, info->mReferenceMeshName );
+		
+		// attribute: min_pixel_area
+		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
+		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
+		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
+		{
+			F32 min_pixel_area = 0.1f;
+			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
+			{
+				// this is square root of pixel area (sensible to use linear space in defining lods)
+				min_pixel_area = min_pixel_area * min_pixel_area;
+			}
+			info->mMinPixelArea = min_pixel_area;
+		}
+		
+		// Parse visual params for this node only if we haven't already
+		for (LLXmlTreeNode* child = node->getChildByName( "param" );
+			 child;
+			 child = node->getNextNamedChild())
+		{
+			if (!child->getChildByName("param_morph"))
+			{
+				if (child->getChildByName("param_skeleton"))
+				{
+					llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
+				}
+				else
+				{
+					llwarns << "Unknown param type." << llendl;
+				}
+				continue;
+			}
+
+			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
+			if (!morphinfo->parseXml(child))
+			{
+				delete morphinfo;
+				delete info;
+				return -1;
+			}
+			BOOL shared = FALSE;
+			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
+			child->getFastAttributeBOOL(shared_string, shared);
+
+			info->mPolyMorphTargetInfoList.push_back(LLAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
+		}
+
+		mMeshInfoList.push_back(info);
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlColorNodes(): parses <global_color> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
+		 color_node;
+		 color_node = root->getNextNamedChild())
+	{
+		std::string global_color_name;
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+		if (color_node->getFastAttributeString( name_string, global_color_name ) )
+		{
+			if( global_color_name == "skin_color" )
+			{
+				if (mTexSkinColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of skin_color" << llendl;
+					return FALSE;
+				}
+				mTexSkinColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexSkinColorInfo->parseXml( color_node ) )
+				{
+					deleteAndClear(mTexSkinColorInfo);
+					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+			else if( global_color_name == "hair_color" )
+			{
+				if (mTexHairColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of hair_color" << llendl;
+					return FALSE;
+				}
+				mTexHairColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexHairColorInfo->parseXml( color_node ) )
+				{
+					deleteAndClear(mTexHairColorInfo);
+					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+			else if( global_color_name == "eye_color" )
+			{
+				if (mTexEyeColorInfo)
+				{
+					llwarns << "avatar file: multiple instances of eye_color" << llendl;
+					return FALSE;
+				}
+				mTexEyeColorInfo = new LLTexGlobalColorInfo;
+				if( !mTexEyeColorInfo->parseXml( color_node ) )
+				{
+					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
+{
+	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
+		 layer_node;
+		 layer_node = root->getNextNamedChild())
+	{
+		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
+		if( layer_info->parseXml( layer_node ) )
+		{
+			mLayerInfoList.push_back(layer_info);
+		}
+		else
+		{
+			delete layer_info;
+			llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
+	if( driver )
+	{
+		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
+			 grand_child;
+			 grand_child = driver->getNextNamedChild())
+		{
+			if( grand_child->getChildByName( "param_driver" ) )
+			{
+				LLDriverParamInfo* driver_info = new LLDriverParamInfo();
+				if( driver_info->parseXml( grand_child ) )
+				{
+					mDriverInfoList.push_back(driver_info);
+				}
+				else
+				{
+					delete driver_info;
+					llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
+					return FALSE;
+				}
+			}
+		}
+	}
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
+//-----------------------------------------------------------------------------
+BOOL LLAvatarAppearance::LLAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
+{
+	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
+	if( !masks )
+	{
+		return FALSE;
+	}
+
+	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
+		 grand_child;
+		 grand_child = masks->getNextNamedChild())
+	{
+		LLAvatarMorphInfo* info = new LLAvatarMorphInfo();
+
+		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
+		if (!grand_child->getFastAttributeString(name_string, info->mName))
+		{
+			llwarns << "No name supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
+		if (!grand_child->getFastAttributeString(region_string, info->mRegion))
+		{
+			llwarns << "No region supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
+		if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
+		{
+			llwarns << "No layer supplied for morph mask." << llendl;
+			delete info;
+			continue;
+		}
+
+		// optional parameter. don't throw a warning if not present.
+		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
+		grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
+
+		mMorphMaskInfoList.push_back(info);
+	}
+
+	return TRUE;
+}
+
+//virtual 
+LLAvatarAppearance::LLMaskedMorph::LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer) :
+			mMorphTarget(morph_target), 
+			mInvert(invert),
+			mLayer(layer)
+{
+	LLPolyMorphTarget *target = dynamic_cast<LLPolyMorphTarget*>(morph_target);
+	if (target)
+	{
+		target->addPendingMorphMask();
+	}
+}
+
+
+
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
new file mode 100644
index 0000000000000000000000000000000000000000..bce25402581032514c6cce838ddc26e69c0d951a
--- /dev/null
+++ b/indra/llappearance/llavatarappearance.h
@@ -0,0 +1,448 @@
+/**
+ * @file llavatarappearance.h
+ * @brief Declaration of LLAvatarAppearance class
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_AVATAR_APPEARANCE_H
+#define LL_AVATAR_APPEARANCE_H
+
+#include "llcharacter.h"
+#include "llavatarappearancedefines.h"
+#include "llavatarjointmesh.h"
+#include "lldriverparam.h"
+#include "lltexlayer.h"
+#include "llviewervisualparam.h"
+#include "llxmltree.h"
+
+class LLTexLayerSet;
+class LLTexGlobalColor;
+class LLTexGlobalColorInfo;
+class LLWearableData;
+class LLAvatarBoneInfo;
+class LLAvatarSkeletonInfo;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLAvatarAppearance
+// 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+class LLAvatarAppearance : public LLCharacter
+{
+	LOG_CLASS(LLAvatarAppearance);
+
+protected:
+	struct LLAvatarXmlInfo;
+
+/********************************************************************************
+ **                                                                            **
+ **                    INITIALIZATION
+ **/
+private:
+	// Hide default constructor.
+	LLAvatarAppearance() {}
+
+public:
+	LLAvatarAppearance(LLWearableData* wearable_data);
+	virtual ~LLAvatarAppearance();
+
+	static void			initClass(); // initializes static members
+	static void			cleanupClass();	// Cleanup data that's only init'd once per class.
+	virtual void 		initInstance(); // Called after construction to initialize the instance.
+	virtual BOOL		loadSkeletonNode();
+	BOOL				loadMeshNodes();
+	BOOL				loadLayersets();
+
+
+/**                    Initialization
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    INHERITED
+ **/
+
+	//--------------------------------------------------------------------
+	// LLCharacter interface and related
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/ LLJoint*		getCharacterJoint(U32 num);
+
+	/*virtual*/ const char*		getAnimationPrefix() { return "avatar"; }
+	/*virtual*/ LLVector3		getVolumePos(S32 joint_index, LLVector3& volume_offset);
+	/*virtual*/ LLJoint*		findCollisionVolume(U32 volume_id);
+	/*virtual*/ S32				getCollisionVolumeID(std::string &name);
+	/*virtual*/ LLPolyMesh*		getHeadMesh();
+	/*virtual*/ LLPolyMesh*		getUpperBodyMesh();
+
+/**                    Inherited
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    STATE
+ **/
+public:
+	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent
+	virtual BOOL	isValid() const;
+	virtual BOOL	isUsingServerBakes() const = 0;
+	virtual BOOL	isUsingLocalAppearance() const = 0;
+	virtual BOOL	isEditingAppearance() const = 0;
+
+	bool isBuilt() const { return mIsBuilt; }
+
+	
+/**                    State
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    SKELETON
+ **/
+
+protected:
+	virtual LLAvatarJoint*	createAvatarJoint() = 0;
+	virtual LLAvatarJoint*	createAvatarJoint(S32 joint_num) = 0;
+	virtual LLAvatarJointMesh*	createAvatarJointMesh() = 0;
+public:
+	F32					getPelvisToFoot() const { return mPelvisToFoot; }
+	/*virtual*/ LLJoint*	getRootJoint() { return mRoot; }
+
+	LLVector3			mHeadOffset; // current head position
+	LLAvatarJoint		*mRoot;
+
+	typedef std::map<std::string, LLJoint*> joint_map_t;
+	joint_map_t			mJointMap;
+	
+	void				computeBodySize();
+
+
+protected:
+	static BOOL			parseSkeletonFile(const std::string& filename);
+	virtual void		buildCharacter();
+	virtual BOOL		loadAvatar();
+	virtual void		bodySizeChanged() = 0;
+
+	BOOL				setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
+	BOOL				allocateCharacterJoints(U32 num);
+	BOOL				buildSkeleton(const LLAvatarSkeletonInfo *info);
+protected:
+	void				clearSkeleton();
+	BOOL				mIsBuilt; // state of deferred character building
+	typedef std::vector<LLAvatarJoint*> avatar_joint_list_t;
+	avatar_joint_list_t	mSkeleton;
+	
+	//--------------------------------------------------------------------
+	// Pelvis height adjustment members.
+	//--------------------------------------------------------------------
+public:
+	LLVector3			mBodySize;
+	LLVector3			mAvatarOffset;
+protected:
+	F32					mPelvisToFoot;
+
+	//--------------------------------------------------------------------
+	// Cached pointers to well known joints
+	//--------------------------------------------------------------------
+public:
+	LLJoint* 		mPelvisp;
+	LLJoint* 		mTorsop;
+	LLJoint* 		mChestp;
+	LLJoint* 		mNeckp;
+	LLJoint* 		mHeadp;
+	LLJoint* 		mSkullp;
+	LLJoint* 		mEyeLeftp;
+	LLJoint* 		mEyeRightp;
+	LLJoint* 		mHipLeftp;
+	LLJoint* 		mHipRightp;
+	LLJoint* 		mKneeLeftp;
+	LLJoint* 		mKneeRightp;
+	LLJoint* 		mAnkleLeftp;
+	LLJoint* 		mAnkleRightp;
+	LLJoint* 		mFootLeftp;
+	LLJoint* 		mFootRightp;
+	LLJoint* 		mWristLeftp;
+	LLJoint* 		mWristRightp;
+
+	//--------------------------------------------------------------------
+	// XML parse tree
+	//--------------------------------------------------------------------
+protected:
+	static LLXmlTree 	sXMLTree; // avatar config file
+	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
+
+	static LLAvatarSkeletonInfo* 					sAvatarSkeletonInfo;
+	static LLAvatarXmlInfo* 						sAvatarXmlInfo;
+
+
+/**                    Skeleton
+ **                                                                            **
+ *******************************************************************************/
+
+
+/********************************************************************************
+ **                                                                            **
+ **                    RENDERING
+ **/
+public:
+	BOOL		mIsDummy; // for special views
+
+	//--------------------------------------------------------------------
+	// Morph masks
+	//--------------------------------------------------------------------
+public:
+	void 	addMaskedMorph(LLAvatarAppearanceDefines::EBakedTextureIndex index, LLVisualParam* morph_target, BOOL invert, std::string layer);
+	virtual void	applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES) = 0;
+
+/**                    Rendering
+ **                                                                            **
+ *******************************************************************************/
+
+	//--------------------------------------------------------------------
+	// Composites
+	//--------------------------------------------------------------------
+public:
+	virtual void	invalidateComposite(LLTexLayerSet* layerset, BOOL upload_result) = 0;
+
+/********************************************************************************
+ **                                                                            **
+ **                    MESHES
+ **/
+
+public:
+	virtual void	updateMeshTextures() = 0;
+	virtual void	dirtyMesh() = 0; // Dirty the avatar mesh
+protected:
+	virtual void	dirtyMesh(S32 priority) = 0; // Dirty the avatar mesh, with priority
+
+protected:
+	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
+	polymesh_map_t 									mPolyMeshes;
+	avatar_joint_list_t								mMeshLOD;
+
+/**                    Meshes
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    APPEARANCE
+ **/
+
+	//--------------------------------------------------------------------
+	// Clothing colors (convenience functions to access visual parameters)
+	//--------------------------------------------------------------------
+public:
+	void			setClothesColor(LLAvatarAppearanceDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
+	LLColor4		getClothesColor(LLAvatarAppearanceDefines::ETextureIndex te);
+	static BOOL		teToColorParams(LLAvatarAppearanceDefines::ETextureIndex te, U32 *param_name);
+
+	//--------------------------------------------------------------------
+	// Global colors
+	//--------------------------------------------------------------------
+public:
+	LLColor4		getGlobalColor(const std::string& color_name ) const;
+	virtual void	onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake) = 0;
+protected:
+	LLTexGlobalColor* mTexSkinColor;
+	LLTexGlobalColor* mTexHairColor;
+	LLTexGlobalColor* mTexEyeColor;
+
+	//--------------------------------------------------------------------
+	// Visibility
+	//--------------------------------------------------------------------
+public:
+	static LLColor4 getDummyColor();
+/**                    Appearance
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    WEARABLES
+ **/
+
+public:
+	LLWearableData*			getWearableData() { return mWearableData; }
+	const LLWearableData*	getWearableData() const { return mWearableData; }
+	virtual BOOL isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index = 0 ) const = 0;
+	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const;
+
+private:
+	LLWearableData* mWearableData;
+
+/********************************************************************************
+ **                                                                            **
+ **                    BAKED TEXTURES
+ **/
+public:
+	LLTexLayerSet*		getAvatarLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+
+protected:
+	virtual LLTexLayerSet*	createTexLayerSet() = 0;
+
+protected:
+	class LLMaskedMorph;
+	typedef std::deque<LLMaskedMorph *> 	morph_list_t;
+	struct BakedTextureData
+	{
+		LLUUID								mLastTextureID;
+		LLTexLayerSet*		 				mTexLayerSet; // Only exists for self
+		bool								mIsLoaded;
+		bool								mIsUsed;
+		LLAvatarAppearanceDefines::ETextureIndex 	mTextureIndex;
+		U32									mMaskTexName;
+		// Stores pointers to the joint meshes that this baked texture deals with
+		avatar_joint_mesh_list_t			mJointMeshes;
+		morph_list_t						mMaskedMorphs;
+	};
+	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;
+	bakedtexturedata_vec_t 					mBakedTextureDatas;
+
+/********************************************************************************
+ **                                                                            **
+ **                    PHYSICS
+ **/
+
+	//--------------------------------------------------------------------
+	// Collision volumes
+	//--------------------------------------------------------------------
+public:
+  	S32			mNumCollisionVolumes;
+	LLAvatarJointCollisionVolume* mCollisionVolumes;
+protected:
+	BOOL		allocateCollisionVolumes(U32 num);
+
+/**                    Physics
+ **                                                                            **
+ *******************************************************************************/
+
+/********************************************************************************
+ **                                                                            **
+ **                    SUPPORT CLASSES
+ **/
+
+	struct LLAvatarXmlInfo
+	{
+		LLAvatarXmlInfo();
+		~LLAvatarXmlInfo();
+
+		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root);
+		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root);
+		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root);
+		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root);
+
+		struct LLAvatarMeshInfo
+		{
+			typedef std::pair<LLViewerVisualParamInfo*,BOOL> morph_info_pair_t; // LLPolyMorphTargetInfo stored here
+			typedef std::vector<morph_info_pair_t> morph_info_list_t;
+
+			LLAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
+			~LLAvatarMeshInfo()
+			{
+				morph_info_list_t::iterator iter;
+				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
+				{
+					delete iter->first;
+				}
+				mPolyMorphTargetInfoList.clear();
+			}
+
+			std::string mType;
+			S32			mLOD;
+			std::string	mMeshFileName;
+			std::string	mReferenceMeshName;
+			F32			mMinPixelArea;
+			morph_info_list_t mPolyMorphTargetInfoList;
+		};
+		typedef std::vector<LLAvatarMeshInfo*> mesh_info_list_t;
+		mesh_info_list_t mMeshInfoList;
+
+		typedef std::vector<LLViewerVisualParamInfo*> skeletal_distortion_info_list_t; // LLPolySkeletalDistortionInfo stored here
+		skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
+
+		struct LLAvatarAttachmentInfo
+		{
+			LLAvatarAttachmentInfo()
+				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
+				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
+			std::string mName;
+			std::string mJointName;
+			LLVector3 mPosition;
+			LLVector3 mRotationEuler;
+			S32 mGroup;
+			S32 mAttachmentID;
+			S32 mPieMenuSlice;
+			BOOL mVisibleFirstPerson;
+			BOOL mIsHUDAttachment;
+			BOOL mHasPosition;
+			BOOL mHasRotation;
+		};
+		typedef std::vector<LLAvatarAttachmentInfo*> attachment_info_list_t;
+		attachment_info_list_t mAttachmentInfoList;
+
+		LLTexGlobalColorInfo *mTexSkinColorInfo;
+		LLTexGlobalColorInfo *mTexHairColorInfo;
+		LLTexGlobalColorInfo *mTexEyeColorInfo;
+
+		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
+		layer_info_list_t mLayerInfoList;
+
+		typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
+		driver_info_list_t mDriverInfoList;
+
+		struct LLAvatarMorphInfo
+		{
+			LLAvatarMorphInfo()
+				: mInvert(FALSE) {}
+			std::string mName;
+			std::string mRegion;
+			std::string mLayer;
+			BOOL mInvert;
+		};
+
+		typedef std::vector<LLAvatarMorphInfo*> morph_info_list_t;
+		morph_info_list_t	mMorphMaskInfoList;
+	};
+
+
+	class LLMaskedMorph
+	{
+	public:
+		LLMaskedMorph(LLVisualParam *morph_target, BOOL invert, std::string layer);
+
+		LLVisualParam	*mMorphTarget;
+		BOOL				mInvert;
+		std::string			mLayer;
+	};
+/**                    Support Classes
+ **                                                                            **
+ *******************************************************************************/
+};
+
+#endif // LL_AVATAR_APPEARANCE_H
diff --git a/indra/newview/llvoavatardefines.cpp b/indra/llappearance/llavatarappearancedefines.cpp
similarity index 79%
rename from indra/newview/llvoavatardefines.cpp
rename to indra/llappearance/llavatarappearancedefines.cpp
index 1ed4e3b61c34f6e61c9fb4931784a696874d7bf3..f1c78946a11e95db72686ab1add4ccd04a788cd4 100644
--- a/indra/newview/llvoavatardefines.cpp
+++ b/indra/llappearance/llavatarappearancedefines.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file llvoavatar.cpp
- * @brief Implementation of LLVOAvatar class which is a derivation fo LLViewerObject
+ * @file llavatarappearancedefines.cpp
+ * @brief Implementation of LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary 
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,21 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
-#include "llvoavatardefines.h"
-#include "llviewercontrol.h" // gSavedSettings
+#include "linden_common.h"
+#include "llavatarappearancedefines.h"
 
-const S32 LLVOAvatarDefines::SCRATCH_TEX_WIDTH = 512;
-const S32 LLVOAvatarDefines::SCRATCH_TEX_HEIGHT = 512;
-const S32 LLVOAvatarDefines::IMPOSTOR_PERIOD = 2;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_WIDTH = 512;
+const S32 LLAvatarAppearanceDefines::SCRATCH_TEX_HEIGHT = 512;
+const S32 LLAvatarAppearanceDefines::IMPOSTOR_PERIOD = 2;
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 /*********************************************************************************
  * Edit this function to add/remove/change textures and mesh definitions for avatars.
  */
 
-LLVOAvatarDictionary::Textures::Textures()
+LLAvatarAppearanceDictionary::Textures::Textures()
 {
 	addEntry(TEX_HEAD_BODYPAINT,              new TextureEntry("head_bodypaint",   TRUE,  BAKED_NUM_INDICES, "",                          LLWearableType::WT_SKIN));
 	addEntry(TEX_UPPER_SHIRT,                 new TextureEntry("upper_shirt",      TRUE,  BAKED_NUM_INDICES, "UIImgDefaultShirtUUID",     LLWearableType::WT_SHIRT));
@@ -66,15 +65,15 @@ LLVOAvatarDictionary::Textures::Textures()
 	addEntry(TEX_UPPER_TATTOO,                new TextureEntry("upper_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO));
 	addEntry(TEX_LOWER_TATTOO,                new TextureEntry("lower_tattoo",     TRUE,  BAKED_NUM_INDICES, "",     LLWearableType::WT_TATTOO));
 
-	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD));
-	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER));
-	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER));
-	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES));
-	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR));
-	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT));
+	addEntry(TEX_HEAD_BAKED,                  new TextureEntry("head-baked",       FALSE, BAKED_HEAD, "head"));
+	addEntry(TEX_UPPER_BAKED,                 new TextureEntry("upper-baked",      FALSE, BAKED_UPPER, "upper"));
+	addEntry(TEX_LOWER_BAKED,                 new TextureEntry("lower-baked",      FALSE, BAKED_LOWER, "lower"));
+	addEntry(TEX_EYES_BAKED,                  new TextureEntry("eyes-baked",       FALSE, BAKED_EYES, "eyes"));
+	addEntry(TEX_HAIR_BAKED,                  new TextureEntry("hair-baked",       FALSE, BAKED_HAIR, "hair"));
+	addEntry(TEX_SKIRT_BAKED,                 new TextureEntry("skirt-baked",      FALSE, BAKED_SKIRT, "skirt"));
 }
 
-LLVOAvatarDictionary::BakedTextures::BakedTextures()
+LLAvatarAppearanceDictionary::BakedTextures::BakedTextures()
 {
 	// Baked textures
 	addEntry(BAKED_HEAD,       new BakedEntry(TEX_HEAD_BAKED,  
@@ -110,36 +109,36 @@ LLVOAvatarDictionary::BakedTextures::BakedTextures()
 											  2, LLWearableType::WT_HAIR, LLWearableType::WT_ALPHA));
 }
 
-LLVOAvatarDictionary::Meshes::Meshes()
+LLAvatarAppearanceDictionary::MeshEntries::MeshEntries()
 {
-	// Meshes
-	addEntry(MESH_ID_HAIR,             new MeshEntry(BAKED_HAIR,  "hairMesh",         6, LLViewerJoint::PN_4));
-	addEntry(MESH_ID_HEAD,             new MeshEntry(BAKED_HEAD,  "headMesh",         5, LLViewerJoint::PN_5));
-	addEntry(MESH_ID_EYELASH,          new MeshEntry(BAKED_HEAD,  "eyelashMesh",      1, LLViewerJoint::PN_0)); // no baked mesh associated currently
-	addEntry(MESH_ID_UPPER_BODY,       new MeshEntry(BAKED_UPPER, "upperBodyMesh",    5, LLViewerJoint::PN_1));
-	addEntry(MESH_ID_LOWER_BODY,       new MeshEntry(BAKED_LOWER, "lowerBodyMesh",    5, LLViewerJoint::PN_2));
-	addEntry(MESH_ID_EYEBALL_LEFT,     new MeshEntry(BAKED_EYES,  "eyeBallLeftMesh",  2, LLViewerJoint::PN_3));
-	addEntry(MESH_ID_EYEBALL_RIGHT,    new MeshEntry(BAKED_EYES,  "eyeBallRightMesh", 2, LLViewerJoint::PN_3));
-	addEntry(MESH_ID_SKIRT,            new MeshEntry(BAKED_SKIRT, "skirtMesh",        5, LLViewerJoint::PN_5));
+	// MeshEntries
+	addEntry(MESH_ID_HAIR,             new MeshEntry(BAKED_HAIR,  "hairMesh",         6, PN_4));
+	addEntry(MESH_ID_HEAD,             new MeshEntry(BAKED_HEAD,  "headMesh",         5, PN_5));
+	addEntry(MESH_ID_EYELASH,          new MeshEntry(BAKED_HEAD,  "eyelashMesh",      1, PN_0)); // no baked mesh associated currently
+	addEntry(MESH_ID_UPPER_BODY,       new MeshEntry(BAKED_UPPER, "upperBodyMesh",    5, PN_1));
+	addEntry(MESH_ID_LOWER_BODY,       new MeshEntry(BAKED_LOWER, "lowerBodyMesh",    5, PN_2));
+	addEntry(MESH_ID_EYEBALL_LEFT,     new MeshEntry(BAKED_EYES,  "eyeBallLeftMesh",  2, PN_3));
+	addEntry(MESH_ID_EYEBALL_RIGHT,    new MeshEntry(BAKED_EYES,  "eyeBallRightMesh", 2, PN_3));
+	addEntry(MESH_ID_SKIRT,            new MeshEntry(BAKED_SKIRT, "skirtMesh",        5, PN_5));
 }
 
 /*
  *
  *********************************************************************************/
 
-LLVOAvatarDictionary::LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::LLAvatarAppearanceDictionary()
 {
 	createAssociations();
 }
 
 //virtual 
-LLVOAvatarDictionary::~LLVOAvatarDictionary()
+LLAvatarAppearanceDictionary::~LLAvatarAppearanceDictionary()
 {
 }
 
 // Baked textures are composites of textures; for each such composited texture,
 // map it to the baked texture.
-void LLVOAvatarDictionary::createAssociations()
+void LLAvatarAppearanceDictionary::createAssociations()
 {
 	for (BakedTextures::const_iterator iter = mBakedTextures.begin(); iter != mBakedTextures.end(); iter++)
 	{
@@ -160,7 +159,7 @@ void LLVOAvatarDictionary::createAssociations()
 		
 }
 
-LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
+LLAvatarAppearanceDictionary::TextureEntry::TextureEntry(const std::string &name,
 												 bool is_local_texture, 
 												 EBakedTextureIndex baked_texture_index,
 												 const std::string &default_image_name,
@@ -175,17 +174,17 @@ LLVOAvatarDictionary::TextureEntry::TextureEntry(const std::string &name,
 {
 }
 
-LLVOAvatarDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, 
+LLAvatarAppearanceDictionary::MeshEntry::MeshEntry(EBakedTextureIndex baked_index, 
 										   const std::string &name, 
 										   U8 level,
-										   LLViewerJoint::PickName pick) :
+										   LLJointPickName pick) :
 	LLDictionaryEntry(name),
 	mBakedID(baked_index),
 	mLOD(level),
 	mPickName(pick)
 {
 }
-LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, 
+LLAvatarAppearanceDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index, 
 											 const std::string &name, 
 											 const std::string &hash_name,
 											 U32 num_local_textures,
@@ -216,18 +215,18 @@ LLVOAvatarDictionary::BakedEntry::BakedEntry(ETextureIndex tex_index,
 }
 
 // static
-ETextureIndex LLVOAvatarDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
+ETextureIndex LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(EBakedTextureIndex index)
 {
-	return LLVOAvatarDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
+	return LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(index)->mTextureIndex;
 }
 
-//static 
-EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
+// static
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByRegionName(std::string name)
 {
 	U8 index = 0;
 	while (index < BAKED_NUM_INDICES)
 	{
-		const BakedEntry *be = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+		const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
 		if (be && be->mName.compare(name) == 0)
 		{
 			// baked texture found
@@ -239,23 +238,30 @@ EBakedTextureIndex LLVOAvatarDictionary::findBakedByRegionName(std::string name)
 	return BAKED_NUM_INDICES;
 }
 
-//static
-const LLUUID LLVOAvatarDictionary::getDefaultTextureImageID(ETextureIndex index)
+// static 
+EBakedTextureIndex LLAvatarAppearanceDictionary::findBakedByImageName(std::string name)
 {
-	const TextureEntry *texture_dict = getInstance()->getTexture(index);
-	const std::string &default_image_name = texture_dict->mDefaultImageName;
-	if (default_image_name == "")
-	{
-		return IMG_DEFAULT_AVATAR;
-	}
-	else
+	U8 index = 0;
+	while (index < BAKED_NUM_INDICES)
 	{
-		return LLUUID(gSavedSettings.getString(default_image_name));
+		const BakedEntry *be = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex) index);
+		if (be)
+		{
+			const TextureEntry *te = LLAvatarAppearanceDictionary::getInstance()->getTexture(be->mTextureIndex);
+			if (te && te->mDefaultImageName.compare(name) == 0)
+			{
+				// baked texture found
+				return (EBakedTextureIndex) index;
+			}
+		}
+		index++;
 	}
+	// baked texture could not be found
+	return BAKED_NUM_INDICES;
 }
 
 // static
-LLWearableType::EType LLVOAvatarDictionary::getTEWearableType(ETextureIndex index )
+LLWearableType::EType LLAvatarAppearanceDictionary::getTEWearableType(ETextureIndex index )
 {
 	return getInstance()->getTexture(index)->mWearableType;
 }
diff --git a/indra/newview/llvoavatardefines.h b/indra/llappearance/llavatarappearancedefines.h
similarity index 86%
rename from indra/newview/llvoavatardefines.h
rename to indra/llappearance/llavatarappearancedefines.h
index 35bb37463ae3f69be96d2b1536a119d12f3435e0..8a1d2c4707e735823e94e17018240c4e8ad2fe9b 100644
--- a/indra/newview/llvoavatardefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -1,6 +1,6 @@
 /** 
- * @file llvoavatar.h
- * @brief Declaration of LLVOAvatar class which is a derivation fo
+ * @file llavatarappearancedefines.h
+ * @brief Various LLAvatarAppearance related definitions
  * LLViewerObject
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
@@ -25,26 +25,30 @@
  * $/LicenseInfo$
  */
 
-#ifndef LLVOAVATAR_DEFINES_H
-#define LLVOAVATAR_DEFINES_H
+#ifndef LL_AVATARAPPEARANCE_DEFINES_H
+#define LL_AVATARAPPEARANCE_DEFINES_H
 
 #include <vector>
-#include "llwearable.h"
-#include "llviewerjoint.h"
+#include "lljointpickname.h"
 #include "lldictionary.h"
+#include "llwearabletype.h"
+#include "lluuid.h"
 
-namespace LLVOAvatarDefines
+namespace LLAvatarAppearanceDefines
 {
 
 extern const S32 SCRATCH_TEX_WIDTH;
 extern const S32 SCRATCH_TEX_HEIGHT;
 extern const S32 IMPOSTOR_PERIOD;
 
+static const U32 AVATAR_HOVER = 11001;
+
 //--------------------------------------------------------------------
 // Enums
 //--------------------------------------------------------------------
 enum ETextureIndex
 {
+	TEX_INVALID = -1,
 	TEX_HEAD_BODYPAINT = 0,
 	TEX_UPPER_SHIRT,
 	TEX_LOWER_PANTS,
@@ -111,21 +115,21 @@ typedef std::vector<EMeshIndex> mesh_vec_t;
 typedef std::vector<LLWearableType::EType> wearables_vec_t;
 
 //------------------------------------------------------------------------
-// LLVOAvatarDictionary
+// LLAvatarAppearanceDictionary
 // 
 // Holds dictionary static entries for textures, baked textures, meshes, etc.; i.e.
 // information that is common to all avatars.
 // 
 // This holds const data - it is initialized once and the contents never change after that.
 //------------------------------------------------------------------------
-class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
+class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictionary>
 {
 	//--------------------------------------------------------------------
 	// Constructors and Destructors
 	//--------------------------------------------------------------------
 public:
-	LLVOAvatarDictionary();
-	virtual ~LLVOAvatarDictionary();
+	LLAvatarAppearanceDictionary();
+	virtual ~LLAvatarAppearanceDictionary();
 private:
 	void createAssociations();
 	
@@ -166,20 +170,20 @@ class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
 		MeshEntry(EBakedTextureIndex baked_index, 
 				  const std::string &name, // names of mesh types as they are used in avatar_lad.xml
 				  U8 level,
-				  LLViewerJoint::PickName pick);
+				  LLJointPickName pick);
 		// Levels of Detail for each mesh.  Must match levels of detail present in avatar_lad.xml
         // Otherwise meshes will be unable to be found, or levels of detail will be ignored
 		const U8 						mLOD;
 		const EBakedTextureIndex 		mBakedID;
-		const LLViewerJoint::PickName 	mPickName;
+		const LLJointPickName 	mPickName;
 	};
 
-	struct Meshes : public LLDictionary<EMeshIndex, MeshEntry>
+	struct MeshEntries : public LLDictionary<EMeshIndex, MeshEntry>
 	{
-		Meshes();
-	} mMeshes;
-	const MeshEntry*		getMesh(EMeshIndex index) const { return mMeshes.lookup(index); }
-	const Meshes&			getMeshes() const { return mMeshes; }
+		MeshEntries();
+	} mMeshEntries;
+	const MeshEntry*		getMeshEntry(EMeshIndex index) const { return mMeshEntries.lookup(index); }
+	const MeshEntries&		getMeshEntries() const { return mMeshEntries; }
 
 	//--------------------------------------------------------------------
 	// Baked Textures
@@ -215,14 +219,13 @@ class LLVOAvatarDictionary : public LLSingleton<LLVOAvatarDictionary>
 
 	// find a baked texture index based on its name
 	static EBakedTextureIndex 	findBakedByRegionName(std::string name);
-
-	static const LLUUID			getDefaultTextureImageID(ETextureIndex index);
+	static EBakedTextureIndex 	findBakedByImageName(std::string name);
 
 	// Given a texture entry, determine which wearable type owns it.
 	static LLWearableType::EType 		getTEWearableType(ETextureIndex index);
 
-}; // End LLVOAvatarDictionary
+}; // End LLAvatarAppearanceDictionary
 
-} // End namespace LLVOAvatarDefines
+} // End namespace LLAvatarAppearanceDefines
 
-#endif //LL_VO_AVATARDEFINES_H
+#endif //LL_AVATARAPPEARANCE_DEFINES_H
diff --git a/indra/llappearance/llavatarjoint.cpp b/indra/llappearance/llavatarjoint.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6ab341af64ee270f0475f3ad43912e5959041dbe
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.cpp
@@ -0,0 +1,326 @@
+/** 
+ * @file llavatarjoint.cpp
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llavatarjoint.h"
+
+#include "llgl.h"
+#include "llrender.h"
+#include "llmath.h"
+#include "llglheaders.h"
+#include "llavatarappearance.h"
+
+const F32 DEFAULT_AVATAR_JOINT_LOD = 0.0f;
+
+//-----------------------------------------------------------------------------
+// Static Data
+//-----------------------------------------------------------------------------
+BOOL					LLAvatarJoint::sDisableLOD = FALSE;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJoint()
+// Class Constructors
+//-----------------------------------------------------------------------------
+LLAvatarJoint::LLAvatarJoint() :
+	LLJoint()
+{
+	init();
+}
+
+LLAvatarJoint::LLAvatarJoint(const std::string &name, LLJoint *parent) :
+	LLJoint(name, parent)
+{
+	init();
+}
+
+LLAvatarJoint::LLAvatarJoint(S32 joint_num) :
+	LLJoint(joint_num)
+{
+	init();
+}
+
+
+void LLAvatarJoint::init()
+{
+	mValid = FALSE;
+	mComponents = SC_JOINT | SC_BONE | SC_AXES;
+	mMinPixelArea = DEFAULT_AVATAR_JOINT_LOD;
+	mPickName = PN_DEFAULT;
+	mVisible = TRUE;
+	mMeshID = 0;
+	mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJoint()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJoint::~LLAvatarJoint()
+{
+}
+
+
+//--------------------------------------------------------------------
+// setValid()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setValid( BOOL valid, BOOL recursive )
+{
+	//----------------------------------------------------------------
+	// set visibility for this joint
+	//----------------------------------------------------------------
+	mValid = valid;
+	
+	//----------------------------------------------------------------
+	// set visibility for children
+	//----------------------------------------------------------------
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			joint->setValid(valid, TRUE);
+		}
+	}
+
+}
+
+//--------------------------------------------------------------------
+// setSkeletonComponents()
+//--------------------------------------------------------------------
+void LLAvatarJoint::setSkeletonComponents( U32 comp, BOOL recursive )
+{
+	mComponents = comp;
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+			joint->setSkeletonComponents(comp, recursive);
+		}
+	}
+}
+
+void LLAvatarJoint::setVisible(BOOL visible, BOOL recursive)
+{
+	mVisible = visible;
+
+	if (recursive)
+	{
+		for (child_list_t::iterator iter = mChildren.begin();
+			 iter != mChildren.end(); ++iter)
+		{
+			LLAvatarJoint* joint = (LLAvatarJoint*)(*iter);
+			joint->setVisible(visible, recursive);
+		}
+	}
+}
+
+void LLAvatarJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
+	}
+}
+
+void LLAvatarJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
+	}
+}
+
+void LLAvatarJoint::updateJointGeometry()
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->updateJointGeometry();
+	}
+}
+
+
+BOOL LLAvatarJoint::updateLOD(F32 pixel_area, BOOL activate)
+{
+	BOOL lod_changed = FALSE;
+	BOOL found_lod = FALSE;
+
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		F32 jointLOD = joint->getLOD();
+		
+		if (found_lod || jointLOD == DEFAULT_AVATAR_JOINT_LOD)
+		{
+			// we've already found a joint to enable, so enable the rest as alternatives
+			lod_changed |= joint->updateLOD(pixel_area, TRUE);
+		}
+		else
+		{
+			if (pixel_area >= jointLOD || sDisableLOD)
+			{
+				lod_changed |= joint->updateLOD(pixel_area, TRUE);
+				found_lod = TRUE;
+			}
+			else
+			{
+				lod_changed |= joint->updateLOD(pixel_area, FALSE);
+			}
+		}
+	}
+	return lod_changed;
+}
+
+void LLAvatarJoint::dump()
+{
+	for (child_list_t::iterator iter = mChildren.begin();
+		 iter != mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
+		joint->dump();
+	}
+}
+
+
+void LLAvatarJoint::setMeshesToChildren()
+{
+	removeAllChildren();
+	for (avatar_joint_mesh_list_t::iterator iter = mMeshParts.begin();
+		iter != mMeshParts.end(); iter++)
+	{
+		addChild((*iter));
+	}
+}
+//-----------------------------------------------------------------------------
+// LLAvatarJointCollisionVolume()
+//-----------------------------------------------------------------------------
+
+LLAvatarJointCollisionVolume::LLAvatarJointCollisionVolume()
+{
+	mUpdateXform = FALSE;
+}
+
+/*virtual*/
+U32 LLAvatarJointCollisionVolume::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
+{
+	llerrs << "Cannot call render() on LLAvatarJointCollisionVolume" << llendl;
+	return 0;
+}
+
+LLVector3 LLAvatarJointCollisionVolume::getVolumePos(LLVector3 &offset)
+{
+	mUpdateXform = TRUE;
+	
+	LLVector3 result = offset;
+	result.scaleVec(getScale());
+	result.rotVec(getWorldRotation());
+	result += getWorldPosition();
+
+	return result;
+}
+
+void LLAvatarJointCollisionVolume::renderCollision()
+{
+	updateWorldMatrix();
+	
+	gGL.pushMatrix();
+	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
+
+	gGL.diffuseColor3f( 0.f, 0.f, 1.f );
+	
+	gGL.begin(LLRender::LINES);
+	
+	LLVector3 v[] = 
+	{
+		LLVector3(1,0,0),
+		LLVector3(-1,0,0),
+		LLVector3(0,1,0),
+		LLVector3(0,-1,0),
+
+		LLVector3(0,0,-1),
+		LLVector3(0,0,1),
+	};
+
+	//sides
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[2].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[3].mV);
+
+
+	//top
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[4].mV);
+
+
+	//bottom
+	gGL.vertex3fv(v[0].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[1].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[2].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.vertex3fv(v[3].mV); 
+	gGL.vertex3fv(v[5].mV);
+
+	gGL.end();
+
+	gGL.popMatrix();
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjoint.h b/indra/llappearance/llavatarjoint.h
new file mode 100644
index 0000000000000000000000000000000000000000..fec91503c787b863ca0a7223561649ce9a257dd4
--- /dev/null
+++ b/indra/llappearance/llavatarjoint.h
@@ -0,0 +1,140 @@
+/** 
+ * @file llavatarjoint.h
+ * @brief Implementation of LLAvatarJoint class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINT_H
+#define LL_LLAVATARJOINT_H
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "lljoint.h"
+#include "lljointpickname.h"
+
+class LLFace;
+class LLAvatarJointMesh;
+
+extern const F32 DEFAULT_AVATAR_JOINT_LOD;
+
+//-----------------------------------------------------------------------------
+// class LLViewerJoint
+//-----------------------------------------------------------------------------
+class LLAvatarJoint :
+	public LLJoint
+{
+public:
+	LLAvatarJoint();
+	LLAvatarJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
+	LLAvatarJoint(const std::string &name, LLJoint *parent = NULL);
+	virtual ~LLAvatarJoint();
+
+	// Gets the validity of this joint
+	BOOL getValid() { return mValid; }
+
+	// Sets the validity of this joint
+	virtual void setValid( BOOL valid, BOOL recursive=FALSE );
+
+	// Returns true if this object is transparent.
+	// This is used to determine in which order to draw objects.
+	virtual BOOL isTransparent() { return mIsTransparent; }
+
+	// Returns true if this object should inherit scale modifiers from its immediate parent
+	virtual BOOL inheritScale() { return FALSE; }
+
+	enum Components
+	{
+		SC_BONE		= 1,
+		SC_JOINT	= 2,
+		SC_AXES		= 4
+	};
+
+	// Selects which skeleton components to draw
+	void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
+
+	// Returns which skeleton components are enables for drawing
+	U32 getSkeletonComponents() { return mComponents; }
+
+	// Sets the level of detail for this node as a minimum
+	// pixel area threshold.  If the current pixel area for this
+	// object is less than the specified threshold, the node is
+	// not traversed.  In addition, if a value is specified (not
+	// default of 0.0), and the pixel area is larger than the
+	// specified minimum, the node is rendered, but no other siblings
+	// of this node under the same parent will be.
+	F32 getLOD() { return mMinPixelArea; }
+	void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
+
+	void setPickName(LLJointPickName name) { mPickName = name; }
+	LLJointPickName getPickName() { return mPickName; }
+
+	void setVisible( BOOL visible, BOOL recursive );
+
+	// Takes meshes in mMeshParts and sets each one as a child joint
+	void setMeshesToChildren();
+
+	// LLViewerJoint interface
+	virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) = 0;
+	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
+	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
+	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
+	virtual void updateJointGeometry();
+	virtual void dump();
+	
+
+public:
+	static BOOL	sDisableLOD;
+	avatar_joint_mesh_list_t mMeshParts; //LLViewerJointMesh*
+	void setMeshID( S32 id ) {mMeshID = id;}
+
+protected:
+	void init();
+
+	BOOL		mValid;
+	BOOL		mIsTransparent;
+	U32			mComponents;
+	F32			mMinPixelArea;
+	LLJointPickName	mPickName;
+	BOOL		mVisible;
+	S32			mMeshID;
+};
+
+class LLAvatarJointCollisionVolume : public LLAvatarJoint
+{
+public:
+	LLAvatarJointCollisionVolume();
+	virtual ~LLAvatarJointCollisionVolume() {};
+
+	/*virtual*/ BOOL inheritScale() { return TRUE; }
+	/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
+
+	void renderCollision();
+
+	LLVector3 getVolumePos(LLVector3 &offset);
+};
+
+#endif // LL_LLAVATARJOINT_H
+
+
diff --git a/indra/llappearance/llavatarjointmesh.cpp b/indra/llappearance/llavatarjointmesh.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4a5cff1dc36a8805f7c1e309daeccc517acc1e28
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.cpp
@@ -0,0 +1,375 @@
+/** 
+ * @file LLAvatarJointMesh.cpp
+ * @brief Implementation of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "linden_common.h"
+#include "imageids.h"
+#include "llfasttimer.h"
+#include "llrender.h"
+
+#include "llavatarjointmesh.h"
+#include "llavatarappearance.h"
+//#include "llapr.h"
+//#include "llbox.h"
+//#include "lldrawable.h"
+//#include "lldrawpoolavatar.h"
+//#include "lldrawpoolbump.h"
+//#include "lldynamictexture.h"
+//#include "llface.h"
+//#include "llgldbg.h"
+//#include "llglheaders.h"
+#include "lltexlayer.h"
+//#include "llviewercamera.h"
+//#include "llviewercontrol.h"
+//#include "llviewertexturelist.h"
+//#include "llsky.h"
+//#include "pipeline.h"
+//#include "llviewershadermgr.h"
+#include "llmath.h"
+#include "v4math.h"
+#include "m3math.h"
+#include "m4math.h"
+#include "llmatrix4a.h"
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::LLSkinJoint
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::LLSkinJoint()
+{
+	mJoint       = NULL;
+}
+
+//-----------------------------------------------------------------------------
+// ~LLSkinJoint
+//-----------------------------------------------------------------------------
+LLSkinJoint::~LLSkinJoint()
+{
+	mJoint = NULL;
+}
+
+
+//-----------------------------------------------------------------------------
+// LLSkinJoint::setupSkinJoint()
+//-----------------------------------------------------------------------------
+BOOL LLSkinJoint::setupSkinJoint( LLAvatarJoint *joint)
+{
+	// find the named joint
+	mJoint = joint;
+	if ( !mJoint )
+	{
+		llinfos << "Can't find joint" << llendl;
+	}
+
+	// compute the inverse root skin matrix
+	mRootToJointSkinOffset.clearVec();
+
+	LLVector3 rootSkinOffset;
+	while (joint)
+	{
+		rootSkinOffset += joint->getSkinOffset();
+		joint = (LLAvatarJoint*)joint->getParent();
+	}
+
+	mRootToJointSkinOffset = -rootSkinOffset;
+	mRootToParentJointSkinOffset = mRootToJointSkinOffset;
+	mRootToParentJointSkinOffset += mJoint->getSkinOffset();
+
+	return TRUE;
+}
+
+
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
+BOOL LLAvatarJointMesh::sPipelineRender = FALSE;
+EAvatarRenderPass LLAvatarJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
+U32 LLAvatarJointMesh::sClothingMaskImageName = 0;
+LLColor4 LLAvatarJointMesh::sClothingInnerColor;
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh()
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::LLAvatarJointMesh()
+	:
+	mTexture( NULL ),
+	mLayerSet( NULL ),
+	mTestImageName( 0 ),
+	mFaceIndexCount(0)
+{
+
+	mColor[0] = 1.0f;
+	mColor[1] = 1.0f;
+	mColor[2] = 1.0f;
+	mColor[3] = 1.0f;
+	mShiny = 0.0f;
+	mCullBackFaces = TRUE;
+
+	mMesh = NULL;
+
+	mNumSkinJoints = 0;
+	mSkinJoints = NULL;
+
+	mFace = NULL;
+
+	mMeshID = 0;
+	mUpdateXform = FALSE;
+
+	mValid = FALSE;
+
+	mIsTransparent = FALSE;
+}
+
+
+//-----------------------------------------------------------------------------
+// ~LLAvatarJointMesh()
+// Class Destructor
+//-----------------------------------------------------------------------------
+LLAvatarJointMesh::~LLAvatarJointMesh()
+{
+	mMesh = NULL;
+	mTexture = NULL;
+	freeSkinData();
+}
+
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::allocateSkinData()
+//-----------------------------------------------------------------------------
+BOOL LLAvatarJointMesh::allocateSkinData( U32 numSkinJoints )
+{
+	mSkinJoints = new LLSkinJoint[ numSkinJoints ];
+	mNumSkinJoints = numSkinJoints;
+	return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::freeSkinData()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::freeSkinData()
+{
+	mNumSkinJoints = 0;
+	delete [] mSkinJoints;
+	mSkinJoints = NULL;
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
+{
+	*red   = mColor[0];
+	*green = mColor[1];
+	*blue  = mColor[2];
+	*alpha = mColor[3];
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setColor()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
+{
+	mColor[0] = red;
+	mColor[1] = green;
+	mColor[2] = blue;
+	mColor[3] = alpha;
+}
+
+void LLAvatarJointMesh::setColor( const LLColor4& color )
+{
+	mColor = color;
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getTexture()
+//--------------------------------------------------------------------
+//LLViewerTexture *LLAvatarJointMesh::getTexture()
+//{
+//	return mTexture;
+//}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setTexture()
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setTexture( LLGLTexture *texture )
+{
+	mTexture = texture;
+
+	// texture and dynamic_texture are mutually exclusive
+	if( texture )
+	{
+		mLayerSet = NULL;
+		//texture->bindTexture(0);
+		//texture->setClamp(TRUE, TRUE);
+	}
+}
+
+
+BOOL LLAvatarJointMesh::hasGLTexture() const
+{
+	return mTexture.notNull() && mTexture->hasGLTexture();
+}
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::setLayerSet()
+// Sets the shape texture (takes precedence over normal texture)
+//--------------------------------------------------------------------
+void LLAvatarJointMesh::setLayerSet( LLTexLayerSet* layer_set )
+{
+	mLayerSet = layer_set;
+	
+	// texture and dynamic_texture are mutually exclusive
+	if( layer_set )
+	{
+		mTexture = NULL;
+	}
+}
+
+BOOL LLAvatarJointMesh::hasComposite() const
+{
+	return (mLayerSet && mLayerSet->hasComposite());
+}
+
+
+//--------------------------------------------------------------------
+// LLAvatarJointMesh::getMesh()
+//--------------------------------------------------------------------
+LLPolyMesh *LLAvatarJointMesh::getMesh()
+{
+	return mMesh;
+}
+
+//-----------------------------------------------------------------------------
+// LLAvatarJointMesh::setMesh()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setMesh( LLPolyMesh *mesh )
+{
+	// set the mesh pointer
+	mMesh = mesh;
+
+	// release any existing skin joints
+	freeSkinData();
+
+	if ( mMesh == NULL )
+	{
+		return;
+	}
+
+	// acquire the transform from the mesh object
+	setPosition( mMesh->getPosition() );
+	setRotation( mMesh->getRotation() );
+	setScale( mMesh->getScale() );
+
+	// create skin joints if necessary
+	if ( mMesh->hasWeights() && !mMesh->isLOD())
+	{
+		U32 numJointNames = mMesh->getNumJointNames();
+		
+		allocateSkinData( numJointNames );
+		std::string *jointNames = mMesh->getJointNames();
+
+		U32 jn;
+		for (jn = 0; jn < numJointNames; jn++)
+		{
+			//llinfos << "Setting up joint " << jointNames[jn] << llendl;
+			LLAvatarJoint* joint = (LLAvatarJoint*)(getRoot()->findJoint(jointNames[jn]) );
+			mSkinJoints[jn].setupSkinJoint( joint );
+		}
+	}
+
+	// setup joint array
+	if (!mMesh->isLOD())
+	{
+		setupJoint((LLAvatarJoint*)getRoot());
+	}
+
+//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
+}
+
+//-----------------------------------------------------------------------------
+// setupJoint()
+//-----------------------------------------------------------------------------
+void LLAvatarJointMesh::setupJoint(LLAvatarJoint* current_joint)
+{
+//	llinfos << "Mesh: " << getName() << llendl;
+
+//	S32 joint_count = 0;
+	U32 sj;
+	for (sj=0; sj<mNumSkinJoints; sj++)
+	{
+		LLSkinJoint &js = mSkinJoints[sj];
+
+		if (js.mJoint != current_joint)
+		{
+			continue;
+		}
+
+		// we've found a skinjoint for this joint..
+
+		// is the last joint in the array our parent?
+		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
+		{
+			// ...then just add ourselves
+			LLAvatarJoint* jointp = js.mJoint;
+			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
+//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
+//			joint_count++;
+		}
+		// otherwise add our parent and ourselves
+		else
+		{
+			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
+//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
+//			joint_count++;
+			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
+//			llinfos << "joint " << joint_count << current_joint->getName() << llendl;
+//			joint_count++;
+		}
+	}
+
+	// depth-first traversal
+	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
+		 iter != current_joint->mChildren.end(); ++iter)
+	{
+		LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+		setupJoint(child_joint);
+	}
+}
+
+
+// End
diff --git a/indra/llappearance/llavatarjointmesh.h b/indra/llappearance/llavatarjointmesh.h
new file mode 100644
index 0000000000000000000000000000000000000000..6486932cdfcd38ea5e7441da037cfabaa50c3603
--- /dev/null
+++ b/indra/llappearance/llavatarjointmesh.h
@@ -0,0 +1,145 @@
+/** 
+ * @file llavatarjointmesh.h
+ * @brief Declaration of LLAvatarJointMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLAVATARJOINTMESH_H
+#define LL_LLAVATARJOINTMESH_H
+
+#include "llavatarjoint.h"
+#include "llgltexture.h"
+#include "llpolymesh.h"
+#include "v4color.h"
+
+class LLDrawable;
+class LLFace;
+class LLCharacter;
+class LLTexLayerSet;
+
+typedef enum e_avatar_render_pass
+{
+	AVATAR_RENDER_PASS_SINGLE,
+	AVATAR_RENDER_PASS_CLOTHING_INNER,
+	AVATAR_RENDER_PASS_CLOTHING_OUTER
+} EAvatarRenderPass;
+
+class LLSkinJoint
+{
+public:
+	LLSkinJoint();
+	~LLSkinJoint();
+	BOOL setupSkinJoint( LLAvatarJoint *joint);
+
+	LLAvatarJoint	*mJoint;
+	LLVector3		mRootToJointSkinOffset;
+	LLVector3		mRootToParentJointSkinOffset;
+};
+
+//-----------------------------------------------------------------------------
+// class LLViewerJointMesh
+//-----------------------------------------------------------------------------
+class LLAvatarJointMesh : public virtual LLAvatarJoint
+{
+protected:
+	LLColor4					mColor;			// color value
+// 	LLColor4					mSpecular;		// specular color (always white for now)
+	F32							mShiny;			// shiny value
+	LLPointer<LLGLTexture>		mTexture;		// ptr to a global texture
+	LLTexLayerSet*				mLayerSet;		// ptr to a layer set owned by the avatar
+	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads
+	LLPolyMesh*					mMesh;			// ptr to a global polymesh
+	BOOL						mCullBackFaces;	// true by default
+	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh
+
+	U32							mFaceIndexCount;
+
+	U32							mNumSkinJoints;
+	LLSkinJoint*				mSkinJoints;
+	S32							mMeshID;
+
+public:
+	static BOOL					sPipelineRender;
+	//RN: this is here for testing purposes
+	static U32					sClothingMaskImageName;
+	static EAvatarRenderPass	sRenderPass;
+	static LLColor4				sClothingInnerColor;
+
+public:
+	// Constructor
+	LLAvatarJointMesh();
+
+	// Destructor
+	virtual ~LLAvatarJointMesh();
+
+	// Gets the shape color
+	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
+
+	// Sets the shape color
+	void setColor( F32 red, F32 green, F32 blue, F32 alpha );
+	void setColor( const LLColor4& color );
+
+	// Sets the shininess
+	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
+
+	// Sets the shape texture
+	void setTexture( LLGLTexture *texture );
+
+	BOOL hasGLTexture() const;
+
+	void setTestTexture( U32 name ) { mTestImageName = name; }
+
+	// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
+	void setLayerSet( LLTexLayerSet* layer_set );
+
+	BOOL hasComposite() const;
+
+	// Gets the poly mesh
+	LLPolyMesh *getMesh();
+
+	// Sets the poly mesh
+	void setMesh( LLPolyMesh *mesh );
+
+	// Sets up joint matrix data for rendering
+	void setupJoint(LLAvatarJoint* current_joint);
+
+	// Render time method to upload batches of joint matrices
+	void uploadJointMatrices();
+
+	// Sets ID for picking
+	void setMeshID( S32 id ) {mMeshID = id;}
+
+	// Gets ID for picking
+	S32 getMeshID() { return mMeshID; }	
+
+	void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
+
+private:
+	// Allocate skin data
+	BOOL allocateSkinData( U32 numSkinJoints );
+
+	// Free skin data
+	void freeSkinData();
+};
+
+#endif // LL_LLAVATARJOINTMESH_H
diff --git a/indra/newview/lldriverparam.cpp b/indra/llappearance/lldriverparam.cpp
similarity index 88%
rename from indra/newview/lldriverparam.cpp
rename to indra/llappearance/lldriverparam.cpp
index 885cae1737003f2f489139ca583b2c0251f405fc..1f7e8b86524a667bd8a46f5a2ac080acaab53ff1 100644
--- a/indra/newview/lldriverparam.cpp
+++ b/indra/llappearance/lldriverparam.cpp
@@ -24,22 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lldriverparam.h"
 
-#include "llfasttimer.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llagent.h"
+#include "llavatarappearance.h"
 #include "llwearable.h"
-#include "llagentwearables.h"
+#include "llwearabledata.h"
 
 //-----------------------------------------------------------------------------
 // LLDriverParamInfo
 //-----------------------------------------------------------------------------
 
-LLDriverParamInfo::LLDriverParamInfo()
+LLDriverParamInfo::LLDriverParamInfo() :
+	mDriverParam(NULL)
 {
 }
 
@@ -112,12 +110,14 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 
 	out << std::endl;
 
-	if(isAgentAvatarValid())
+	if(mDriverParam && mDriverParam->getAvatarAppearance()->isSelf() &&
+		mDriverParam->getAvatarAppearance()->isValid())
 	{
 		for (entry_info_list_t::iterator iter = mDrivenInfoList.begin(); iter != mDrivenInfoList.end(); iter++)
 		{
 			LLDrivenEntryInfo driven = *iter;
-			LLViewerVisualParam *param = (LLViewerVisualParam*)gAgentAvatarp->getVisualParam(driven.mDrivenID);
+			LLViewerVisualParam *param = 
+				(LLViewerVisualParam*)mDriverParam->getAvatarAppearance()->getVisualParam(driven.mDrivenID);
 			if (param)
 			{
 				param->getInfo()->toStream(out);
@@ -139,7 +139,9 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 			}
 			else
 			{
-				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " << gAgentAvatarp.get() << " for driver parameter " << getID() << llendl;
+				llwarns << "could not get parameter " << driven.mDrivenID << " from avatar " 
+						<< mDriverParam->getAvatarAppearance() 
+						<< " for driver parameter " << getID() << llendl;
 			}
 			out << std::endl;
 		}
@@ -150,19 +152,16 @@ void LLDriverParamInfo::toStream(std::ostream &out)
 // LLDriverParam
 //-----------------------------------------------------------------------------
 
-LLDriverParam::LLDriverParam(LLVOAvatar *avatarp) : 
+LLDriverParam::LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable /* = NULL */) :
 	mCurrentDistortionParam( NULL ), 
-	mAvatarp(avatarp), 
-	mWearablep(NULL)
-{
-	mDefaultVec.clear();
-}
-
-LLDriverParam::LLDriverParam(LLWearable *wearablep) : 
-	mCurrentDistortionParam( NULL ), 
-	mAvatarp(NULL), 
-	mWearablep(wearablep)
+	mAvatarAppearance(appearance), 
+	mWearablep(wearable)
 {
+	llassert(mAvatarAppearance);
+	if (mWearablep)
+	{
+		llassert(mAvatarAppearance->isSelf());
+	}
 	mDefaultVec.clear();
 }
 
@@ -177,67 +176,25 @@ BOOL LLDriverParam::setInfo(LLDriverParamInfo *info)
 		return FALSE;
 	mInfo = info;
 	mID = info->mID;
+	info->mDriverParam = this;
 
 	setWeight(getDefaultWeight(), FALSE );
 
 	return TRUE;
 }
 
-void LLDriverParam::setWearable(LLWearable *wearablep)
-{
-	if (wearablep)
-	{
-		mWearablep = wearablep;
-		mAvatarp = NULL;
-	}
-}
-
-void LLDriverParam::setAvatar(LLVOAvatar *avatarp)
-{
-	if (avatarp)
-	{
-		mWearablep = NULL;
-		mAvatarp = avatarp;
-	}
-}
-
 /*virtual*/ LLViewerVisualParam* LLDriverParam::cloneParam(LLWearable* wearable) const
 {
-	LLDriverParam *new_param;
-	if (wearable)
-	{
-		new_param = new LLDriverParam(wearable);
-	}
-	else
-	{
-		if (mWearablep)
-		{
-			new_param = new LLDriverParam(mWearablep);
-		}
-		else
-		{
-			new_param = new LLDriverParam(mAvatarp);
-		}
-	}
+	llassert(wearable);
+	LLDriverParam *new_param = new LLDriverParam(mAvatarAppearance, wearable);
+	// FIXME DRANO this clobbers mWearablep, which means any code
+	// currently using mWearablep is wrong, or at least untested.
 	*new_param = *this;
+	//new_param->mWearablep = wearable;
+//	new_param->mDriven.clear(); // clear driven list to avoid overwriting avatar driven params from wearables. 
 	return new_param;
 }
 
-#if 0 // obsolete
-BOOL LLDriverParam::parseData(LLXmlTreeNode* node)
-{
-	LLDriverParamInfo* info = new LLDriverParamInfo;
-
-	info->parseXml(node);
-	if (!setInfo(info))
-	{
-		delete info;
-		return FALSE;
-	}
-	return TRUE;
-}
-#endif
-
 void LLDriverParam::setWeight(F32 weight, BOOL upload_bake)
 {
 	F32 min_weight = getMinWeight();
@@ -456,6 +413,20 @@ const LLVector4a*	LLDriverParam::getNextDistortion(U32 *index, LLPolyMesh **poly
 	return v;
 };
 
+S32 LLDriverParam::getDrivenParamsCount() const
+{
+	return mDriven.size();
+}
+
+const LLViewerVisualParam* LLDriverParam::getDrivenParam(S32 index) const
+{
+	if (0 > index || index >= mDriven.size())
+	{
+		return NULL;
+	}
+	return mDriven[index].mParam;
+}
+
 //-----------------------------------------------------------------------------
 // setAnimationTarget()
 //-----------------------------------------------------------------------------
@@ -511,6 +482,7 @@ BOOL LLDriverParam::linkDrivenParams(visual_param_mapper mapper, BOOL only_cross
 		if (!found)
 		{
 			LLViewerVisualParam* param = (LLViewerVisualParam*)mapper(driven_id);
+			if (param) param->setParamLocation(this->getParamLocation());
 			bool push = param && (!only_cross_params || param->getCrossWearable());
 			if (push)
 			{
@@ -555,7 +527,7 @@ void LLDriverParam::updateCrossDrivenParams(LLWearableType::EType driven_type)
 		// Thus this wearable needs to get updates from the driver wearable.
 		// The call to setVisualParamWeight seems redundant, but is necessary
 		// as the number of driven wearables has changed since the last update. -Nyx
-		LLWearable *wearable = gAgentWearables.getTopWearable(driver_type);
+		LLWearable *wearable = mAvatarAppearance->getWearableData()->getTopWearable(driver_type);
 		if (wearable)
 		{
 			wearable->setVisualParamWeight(mID, wearable->getVisualParamWeight(mID), false);
@@ -623,13 +595,22 @@ F32 LLDriverParam::getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight
 
 void LLDriverParam::setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake)
 {
-	if(isAgentAvatarValid() &&
-	   mWearablep && 
-	   driven->mParam->getCrossWearable() &&
-	   mWearablep->isOnTop())
+	bool use_self = false;
+	if(mWearablep &&
+		mAvatarAppearance->isValid() &&
+		driven->mParam->getCrossWearable())
+	{
+		LLWearable* wearable = dynamic_cast<LLWearable*> (mWearablep);
+		if (mAvatarAppearance->getWearableData()->isOnTop(wearable))
+		{
+			use_self = true;
+		}
+	}
+
+	if (use_self)
 	{
 		// call setWeight through LLVOAvatarSelf so other wearables can be updated with the correct values
-		gAgentAvatarp->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
+		mAvatarAppearance->setVisualParamWeight( (LLVisualParam*)driven->mParam, driven_weight, upload_bake );
 	}
 	else
 	{
diff --git a/indra/newview/lldriverparam.h b/indra/llappearance/lldriverparam.h
similarity index 87%
rename from indra/newview/lldriverparam.h
rename to indra/llappearance/lldriverparam.h
index 216cf003e1105a2efb69920ab60947d4a168afa2..040c9cf5be1dce89df81b2b31b49b27f3be3fb92 100644
--- a/indra/newview/lldriverparam.h
+++ b/indra/llappearance/lldriverparam.h
@@ -30,8 +30,8 @@
 #include "llviewervisualparam.h"
 #include "llwearabletype.h"
 
-class LLPhysicsMotion;
-class LLVOAvatar;
+class LLAvatarAppearance;
+class LLDriverParam;
 class LLWearable;
 
 //-----------------------------------------------------------------------------
@@ -71,6 +71,7 @@ class LLDriverParamInfo : public LLViewerVisualParamInfo
 protected:
 	typedef std::deque<LLDrivenEntryInfo> entry_info_list_t;
 	entry_info_list_t mDrivenInfoList;
+	LLDriverParam* mDriverParam; // backpointer
 };
 
 //-----------------------------------------------------------------------------
@@ -78,10 +79,11 @@ class LLDriverParamInfo : public LLViewerVisualParamInfo
 LL_ALIGN_PREFIX(16)
 class LLDriverParam : public LLViewerVisualParam
 {
-	friend class LLPhysicsMotion; // physics motion needs to access driven params directly.
+private:
+	// Hide the default constructor.  Force construction with LLAvatarAppearance.
+	LLDriverParam() {}
 public:
-	LLDriverParam(LLVOAvatar *avatarp);
-	LLDriverParam(LLWearable *wearablep);
+	LLDriverParam(LLAvatarAppearance *appearance, LLWearable* wearable = NULL);
 	~LLDriverParam();
 
 	void* operator new(size_t size)
@@ -99,14 +101,14 @@ class LLDriverParam : public LLViewerVisualParam
 	//   This sets mInfo and calls initialization functions
 	BOOL					setInfo(LLDriverParamInfo *info);
 
-	void					setWearable(LLWearable *wearablep);
-	void					setAvatar(LLVOAvatar *avatarp);
+	LLAvatarAppearance* getAvatarAppearance() { return mAvatarAppearance; }
+	const LLAvatarAppearance* getAvatarAppearance() const { return mAvatarAppearance; }
+
 	void					updateCrossDrivenParams(LLWearableType::EType driven_type);
 
 	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
 
 	// LLVisualParam Virtual functions
-	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
 	/*virtual*/ void				apply( ESex sex ) {} // apply is called separately for each driven param.
 	/*virtual*/ void				setWeight(F32 weight, BOOL upload_bake);
 	/*virtual*/ void				setAnimationTarget( F32 target_value, BOOL upload_bake );
@@ -122,6 +124,9 @@ class LLDriverParam : public LLViewerVisualParam
 	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh);
 	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh);
 
+	S32								getDrivenParamsCount() const;
+	const LLViewerVisualParam*		getDrivenParam(S32 index) const;
+
 protected:
 	F32 getDrivenWeight(const LLDrivenEntry* driven, F32 input_weight);
 	void setDrivenWeight(LLDrivenEntry *driven, F32 driven_weight, bool upload_bake);
@@ -132,7 +137,7 @@ class LLDriverParam : public LLViewerVisualParam
 	entry_list_t mDriven;
 	LLViewerVisualParam* mCurrentDistortionParam;
 	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar* mAvatarp;
+	LLAvatarAppearance* mAvatarAppearance;
 	LLWearable* mWearablep;
 } LL_ALIGN_POSTFIX(16);
 
diff --git a/indra/llappearance/lljointpickname.h b/indra/llappearance/lljointpickname.h
new file mode 100644
index 0000000000000000000000000000000000000000..1d41a761fc3970057ba2f3867567db366341f8e5
--- /dev/null
+++ b/indra/llappearance/lljointpickname.h
@@ -0,0 +1,49 @@
+/** 
+ * @file lljointpickname.h
+ * @brief Defines OpenGL seleciton stack names
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_LLJOINTPICKNAME_H
+#define LL_LLJOINTPICKNAME_H
+
+class LLAvatarJointMesh;
+
+// Sets the OpenGL selection stack name that is pushed and popped
+// with this joint state.  The default value indicates that no name
+// should be pushed/popped.
+enum LLJointPickName
+{
+	PN_DEFAULT = -1,
+	PN_0 = 0,
+	PN_1 = 1,
+	PN_2 = 2,
+	PN_3 = 3,
+	PN_4 = 4,
+	PN_5 = 5
+};
+
+typedef std::vector<LLAvatarJointMesh*> avatar_joint_mesh_list_t;
+
+#endif // LL_LLJOINTPICKNAME_H
diff --git a/indra/newview/lllocaltextureobject.cpp b/indra/llappearance/lllocaltextureobject.cpp
similarity index 92%
rename from indra/newview/lllocaltextureobject.cpp
rename to indra/llappearance/lllocaltextureobject.cpp
index 07ec0fab95c7c87f92bc62fd4163d12798555ef7..7e36a06797456fbb12be34d171524a5d126e1aab 100644
--- a/indra/newview/lllocaltextureobject.cpp
+++ b/indra/llappearance/lllocaltextureobject.cpp
@@ -23,13 +23,14 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lllocaltextureobject.h"
 
+#include "llimage.h"
+#include "llrender.h"
 #include "lltexlayer.h"
-#include "llviewertexture.h"
-#include "lltextureentry.h"
+#include "llgltexture.h"
 #include "lluuid.h"
 #include "llwearable.h"
 
@@ -41,7 +42,7 @@ LLLocalTextureObject::LLLocalTextureObject() :
 	mImage = NULL;
 }
 
-LLLocalTextureObject::LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id) :
+LLLocalTextureObject::LLLocalTextureObject(LLGLTexture* image, const LLUUID& id) :
 	mIsBakedReady(FALSE),
 	mDiscard(MAX_DISCARD_LEVEL+1)
 {
@@ -77,7 +78,7 @@ LLLocalTextureObject::~LLLocalTextureObject()
 {
 }
 
-LLViewerFetchedTexture* LLLocalTextureObject::getImage() const
+LLGLTexture* LLLocalTextureObject::getImage() const
 {
 	return mImage;
 }
@@ -126,7 +127,7 @@ BOOL LLLocalTextureObject::getBakedReady() const
 	return mIsBakedReady;
 }
 
-void LLLocalTextureObject::setImage(LLViewerFetchedTexture* new_image)
+void LLLocalTextureObject::setImage(LLGLTexture* new_image)
 {
 	mImage = new_image;
 }
diff --git a/indra/newview/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h
similarity index 89%
rename from indra/newview/lllocaltextureobject.h
rename to indra/llappearance/lllocaltextureobject.h
index b9bfc5472fa4e7aca81e9e2f4ecb5db8aa1b6e00..9b9f41fd1961e0ca30b149a8a0a647734ad36f12 100644
--- a/indra/newview/lllocaltextureobject.h
+++ b/indra/llappearance/lllocaltextureobject.h
@@ -29,11 +29,10 @@
 
 #include <boost/shared_ptr.hpp>
 
-#include "llviewertexture.h"
+#include "llpointer.h"
+#include "llgltexture.h"
 
-class LLUUID;
 class LLTexLayer;
-class LLTextureEntry;
 class LLTexLayerTemplate;
 class LLWearable;
 
@@ -44,11 +43,11 @@ class LLLocalTextureObject
 {
 public:
 	LLLocalTextureObject();
-	LLLocalTextureObject(LLViewerFetchedTexture* image, const LLUUID& id);
+	LLLocalTextureObject(LLGLTexture* image, const LLUUID& id);
 	LLLocalTextureObject(const LLLocalTextureObject& lto);
 	~LLLocalTextureObject();
 
-	LLViewerFetchedTexture* getImage() const;
+	LLGLTexture* getImage() const;
 	LLTexLayer* getTexLayer(U32 index) const;
 	LLTexLayer* getTexLayer(const std::string &name);
 	U32 		getNumTexLayers() const;
@@ -56,7 +55,7 @@ class LLLocalTextureObject
 	S32			getDiscard() const;
 	BOOL		getBakedReady() const;
 
-	void setImage(LLViewerFetchedTexture* new_image);
+	void setImage(LLGLTexture* new_image);
 	BOOL setTexLayer(LLTexLayer *new_tex_layer, U32 index);
 	BOOL addTexLayer(LLTexLayer *new_tex_layer, LLWearable *wearable);
 	BOOL addTexLayer(LLTexLayerTemplate *new_tex_layer, LLWearable *wearable);
@@ -70,7 +69,7 @@ class LLLocalTextureObject
 
 private:
 
-	LLPointer<LLViewerFetchedTexture>  			mImage;
+	LLPointer<LLGLTexture>			mImage;
 	// NOTE: LLLocalTextureObject should be the exclusive owner of mTexEntry and mTexLayer
 	// using shared pointers here only for smart assignment & cleanup
 	// do NOT create new shared pointers to these objects, or keep pointers to them around
diff --git a/indra/newview/llpolymesh.cpp b/indra/llappearance/llpolymesh.cpp
similarity index 81%
rename from indra/newview/llpolymesh.cpp
rename to indra/llappearance/llpolymesh.cpp
index 5f5258bbceb05bb120259f1ba25dcefe75f4130b..a01457246e19de1ff115e9e16bfa08d4f6ed6d27 100644
--- a/indra/newview/llpolymesh.cpp
+++ b/indra/llappearance/llpolymesh.cpp
@@ -27,25 +27,24 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
-
+#include "linden_common.h"
+#include "llpolymesh.h"
 #include "llfasttimer.h"
 #include "llmemory.h"
 
-#include "llviewercontrol.h"
+//#include "llviewercontrol.h"
 #include "llxmltree.h"
-#include "llvoavatar.h"
+#include "llavatarappearance.h"
 #include "llwearable.h"
 #include "lldir.h"
 #include "llvolume.h"
 #include "llendianswizzle.h"
 
-#include "llpolymesh.h"
 
 #define HEADER_ASCII "Linden Mesh 1.0"
 #define HEADER_BINARY "Linden Binary Mesh 1.0"
 
-extern LLControlGroup gSavedSettings;                           // read only
+//extern LLControlGroup gSavedSettings;                           // read only
 
 LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
 					     const std::string &name);
@@ -241,7 +240,7 @@ BOOL LLPolyMeshSharedData::allocateVertexData( U32 numVertices )
 			mBaseNormals[i].clear();
 			mBaseBinormals[i].clear();
 			mTexCoords[i].clear();
-			mWeights[i] = 0.f;
+            mWeights[i] = 0.f;
         }
         mNumVertices = numVertices;
         return TRUE;
@@ -1046,250 +1045,4 @@ F32*    LLPolyMesh::getWritableWeights() const
         return mSharedData->mWeights;
 }
 
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortionInfo()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
-{
-}
-
-BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
-{
-        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
-        
-        if (!LLViewerVisualParamInfo::parseXml(node))
-                return FALSE;
-
-        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
-
-        if (NULL == skeletalParam)
-        {
-                llwarns << "Failed to getChildByName(\"param_skeleton\")"
-                        << llendl;
-                return FALSE;
-        }
-
-        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
-        {
-                if (bone->hasName("bone"))
-                {
-                        std::string name;
-                        LLVector3 scale;
-                        LLVector3 pos;
-                        BOOL haspos = FALSE;
-                        
-                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-                        if (!bone->getFastAttributeString(name_string, name))
-                        {
-                                llwarns << "No bone name specified for skeletal param." << llendl;
-                                continue;
-                        }
-
-                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-                        if (!bone->getFastAttributeVector3(scale_string, scale))
-                        {
-                                llwarns << "No scale specified for bone " << name << "." << llendl;
-                                continue;
-                        }
-
-                        // optional offset deformation (translation)
-                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
-                        if (bone->getFastAttributeVector3(offset_string, pos))
-                        {
-                                haspos = TRUE;
-                        }
-                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
-                }
-                else
-                {
-                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
-                        continue;
-                }
-        }
-        return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLVOAvatar *avatarp)
-{
-        mAvatar = avatarp;
-        mDefaultVec.splat(0.001f);
-}
-
-//-----------------------------------------------------------------------------
-// ~LLPolySkeletalDistortion()
-//-----------------------------------------------------------------------------
-LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
-{
-}
-
-BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
-{
-        llassert(mInfo == NULL);
-        if (info->mID < 0)
-                return FALSE;
-        mInfo = info;
-        mID = info->mID;
-        setWeight(getDefaultWeight(), FALSE );
-
-        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
-        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
-        {
-                LLPolySkeletalBoneInfo *bone_info = &(*iter);
-                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
-                if (!joint)
-                {
-                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
-                        continue;
-                }
-
-                if (mJointScales.find(joint) != mJointScales.end())
-                {
-                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
-                }
-
-                // store it
-                mJointScales[joint] = bone_info->mScaleDeformation;
-
-                // apply to children that need to inherit it
-                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
-                     iter != joint->mChildren.end(); ++iter)
-                {
-                        LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
-                        if (child_joint->inheritScale())
-                        {
-                                LLVector3 childDeformation = LLVector3(child_joint->getScale());
-                                childDeformation.scaleVec(bone_info->mScaleDeformation);
-                                mJointScales[child_joint] = childDeformation;
-                        }
-                }
-
-                if (bone_info->mHasPositionDeformation)
-                {
-                        if (mJointOffsets.find(joint) != mJointOffsets.end())
-                        {
-                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
-                        }
-                        mJointOffsets[joint] = bone_info->mPositionDeformation;
-                }
-        }
-        return TRUE;
-}
-
-/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
-{
-        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
-        *new_param = *this;
-        return new_param;
-}
-
-//-----------------------------------------------------------------------------
-// apply()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
-
-void LLPolySkeletalDistortion::apply( ESex avatar_sex )
-{
-	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
-
-        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
-
-        LLJoint* joint;
-        joint_vec_map_t::iterator iter;
-
-        for (iter = mJointScales.begin();
-             iter != mJointScales.end();
-             iter++)
-        {
-                joint = iter->first;
-                LLVector3 newScale = joint->getScale();
-                LLVector3 scaleDelta = iter->second;
-                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
-                joint->setScale(newScale);
-        }
-
-        for (iter = mJointOffsets.begin();
-             iter != mJointOffsets.end();
-             iter++)
-        {
-                joint = iter->first;
-                LLVector3 newPosition = joint->getPosition();
-                LLVector3 positionDelta = iter->second;
-                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
-                joint->setPosition(newPosition);
-        }
-
-        if (mLastWeight != mCurWeight && !mIsAnimating)
-        {
-                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
-        }
-        mLastWeight = mCurWeight;
-}
-
-
-LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
-					     const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-                cloned_morph_data->mCoords[v] = src_data->mCoords[v];
-                cloned_morph_data->mNormals[v] = src_data->mNormals[v];
-                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
-        }
-        return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
-					     const LLVector3 &direction,
-					     const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-		LLVector4a dir;
-		dir.load3(direction.mV);
-
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-                cloned_morph_data->mCoords[v] = dir;
-                cloned_morph_data->mNormals[v].clear();
-                cloned_morph_data->mBinormals[v].clear();
-        }
-        return cloned_morph_data;
-}
-
-LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
-                                            F32 scale,
-                                            const std::string &name)
-{
-        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
-        cloned_morph_data->mName = name;
-
-		LLVector4a sc;
-		sc.splat(scale);
-
-		LLVector4a nsc;
-		nsc.set(scale, -scale, scale, scale);
-
-        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
-        {
-            if (cloned_morph_data->mCoords[v][1] < 0)
-            {
-                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
-				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
-				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
-			}
-			else
-			{
-				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
-				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
-				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
-			}
-        }
-        return cloned_morph_data;
-}
-
 // End
diff --git a/indra/newview/llpolymesh.h b/indra/llappearance/llpolymesh.h
similarity index 75%
rename from indra/newview/llpolymesh.h
rename to indra/llappearance/llpolymesh.h
index 28da230541a0a422881fccb26790616faab7204c..ef1dfb1adb25feb94f105bde280589ae588a0511 100644
--- a/indra/newview/llpolymesh.h
+++ b/indra/llappearance/llpolymesh.h
@@ -24,8 +24,8 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLPOLYMESH_H
-#define LL_LLPOLYMESH_H
+#ifndef LL_LLPOLYMESHINTERFACE_H
+#define LL_LLPOLYMESHINTERFACE_H
 
 #include <string>
 #include <map>
@@ -39,7 +39,7 @@
 //#include "lldarray.h"
 
 class LLSkinJoint;
-class LLVOAvatar;
+class LLAvatarAppearance;
 class LLWearable;
 
 //#define USE_STRIPS	// Use tri-strips for rendering.
@@ -319,8 +319,8 @@ class LLPolyMesh
 
 	BOOL	isLOD() { return mSharedData && mSharedData->isLOD(); }
 
-	void setAvatar(LLVOAvatar* avatarp) { mAvatarp = avatarp; }
-	LLVOAvatar* getAvatar() { return mAvatarp; }
+	void setAvatar(LLAvatarAppearance* avatarp) { mAvatarp = avatarp; }
+	LLAvatarAppearance* getAvatar() { return mAvatarp; }
 
 	LLDynamicArray<LLJointRenderData*>	mJointRenderData;
 
@@ -362,90 +362,8 @@ class LLPolyMesh
 	static LLPolyMeshSharedDataTable sGlobalSharedMeshList;
 
 	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar* mAvatarp;
+	LLAvatarAppearance* mAvatarp;
 };
 
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformationInfo
-// Shared information for LLPolySkeletalDeformations
-//-----------------------------------------------------------------------------
-struct LLPolySkeletalBoneInfo
-{
-	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
-		: mBoneName(name),
-		  mScaleDeformation(scale),
-		  mPositionDeformation(pos),
-		  mHasPositionDeformation(haspos) {}
-	std::string mBoneName;
-	LLVector3 mScaleDeformation;
-	LLVector3 mPositionDeformation;
-	BOOL mHasPositionDeformation;
-};
-
-class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
-{
-	friend class LLPolySkeletalDistortion;
-public:
-	LLPolySkeletalDistortionInfo();
-	/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
-	
-	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
-
-protected:
-	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
-	bone_info_list_t mBoneInfoList;
-};
-
-//-----------------------------------------------------------------------------
-// LLPolySkeletalDeformation
-// A set of joint scale data for deforming the avatar mesh
-//-----------------------------------------------------------------------------
-
-LL_ALIGN_PREFIX(16)
-class LLPolySkeletalDistortion : public LLViewerVisualParam
-{
-public:
-	LLPolySkeletalDistortion(LLVOAvatar *avatarp);
-	~LLPolySkeletalDistortion();
-
-	void* operator new(size_t size)
-	{
-		return ll_aligned_malloc_16(size);
-	}
-
-	void operator delete(void* ptr)
-	{
-		ll_aligned_free_16(ptr);
-	}
-
-	// Special: These functions are overridden by child classes
-	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
-	//   This sets mInfo and calls initialization functions
-	BOOL							setInfo(LLPolySkeletalDistortionInfo *info);
-
-	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
-
-	// LLVisualParam Virtual functions
-	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
-	/*virtual*/ void				apply( ESex sex );
-	
-	// LLViewerVisualParam Virtual functions
-	/*virtual*/ F32					getTotalDistortion() { return 0.1f; }
-	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; }
-	/*virtual*/ F32					getMaxDistortion() { return 0.1f; }
-	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
-	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
-	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
-
-protected:
-	LL_ALIGN_16(LLVector4a	mDefaultVec);
-
-	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
-	joint_vec_map_t mJointScales;
-	joint_vec_map_t mJointOffsets;
-	// Backlink only; don't make this an LLPointer.
-	LLVOAvatar *mAvatar;
-} LL_ALIGN_POSTFIX(16);
-
-#endif // LL_LLPOLYMESH_H
+#endif // LL_LLPOLYMESHINTERFACE_H
 
diff --git a/indra/newview/llpolymorph.cpp b/indra/llappearance/llpolymorph.cpp
similarity index 99%
rename from indra/newview/llpolymorph.cpp
rename to indra/llappearance/llpolymorph.cpp
index 495fdc348c043f9da78394d2e1da58887f9ad097..8a178190833ca463c15499e9722cb4e7300ca8af 100644
--- a/indra/newview/llpolymorph.cpp
+++ b/indra/llappearance/llpolymorph.cpp
@@ -27,13 +27,14 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
 
 #include "llpolymorph.h"
-#include "llvoavatar.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
 #include "llwearable.h"
 #include "llxmltree.h"
 #include "llendianswizzle.h"
+#include "llpolymesh.h"
 
 //#include "../tools/imdebug/imdebug.h"
 
@@ -343,7 +344,7 @@ BOOL LLPolyMorphTarget::setInfo(LLPolyMorphTargetInfo* info)
 	mID = info->mID;
 	setWeight(getDefaultWeight(), FALSE );
 
-	LLVOAvatar* avatarp = mMesh->getAvatar();
+	LLAvatarAppearance* avatarp = mMesh->getAvatar();
 	LLPolyMorphTargetInfo::volume_info_list_t::iterator iter;
 	for (iter = getInfo()->mVolumeInfoList.begin(); iter != getInfo()->mVolumeInfoList.end(); iter++)
 	{
diff --git a/indra/newview/llpolymorph.h b/indra/llappearance/llpolymorph.h
similarity index 97%
rename from indra/newview/llpolymorph.h
rename to indra/llappearance/llpolymorph.h
index 24940c52e0fa390cb529822cea09cda021a7480b..ee380ae7c3792bf2b85217deadd8b19d282ddd27 100644
--- a/indra/newview/llpolymorph.h
+++ b/indra/llappearance/llpolymorph.h
@@ -32,10 +32,10 @@
 
 #include "llviewervisualparam.h"
 
+class LLAvatarJointCollisionVolume;
 class LLPolyMeshSharedData;
-class LLVOAvatar;
 class LLVector2;
-class LLViewerJointCollisionVolume;
+class LLAvatarJointCollisionVolume;
 class LLWearable;
 
 //-----------------------------------------------------------------------------
@@ -119,10 +119,10 @@ struct LLPolyVolumeMorphInfo
 
 struct LLPolyVolumeMorph
 {
-	LLPolyVolumeMorph(LLViewerJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
+	LLPolyVolumeMorph(LLAvatarJointCollisionVolume* volume, LLVector3 scale, LLVector3 pos)
 		: mVolume(volume), mScale(scale), mPos(pos) {};
 
-	LLViewerJointCollisionVolume*	mVolume;
+	LLAvatarJointCollisionVolume*	mVolume;
 	LLVector3						mScale;
 	LLVector3						mPos;
 };
diff --git a/indra/llappearance/llpolyskeletaldistortion.cpp b/indra/llappearance/llpolyskeletaldistortion.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4ba16691c28b48ec0318be80537cf76f898cc965
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.cpp
@@ -0,0 +1,293 @@
+/** 
+ * @file llpolyskeletaldistortion.cpp
+ * @brief Implementation of LLPolySkeletalDistortion classes
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+//-----------------------------------------------------------------------------
+// Header Files
+//-----------------------------------------------------------------------------
+#include "llpreprocessor.h"
+#include "llerrorlegacy.h"
+//#include "llcommon.h"
+//#include "llmemory.h"
+#include "llavatarappearance.h"
+#include "llavatarjoint.h"
+#include "llpolymorph.h"
+//#include "llviewercontrol.h"
+//#include "llxmltree.h"
+//#include "llvoavatar.h"
+#include "llwearable.h"
+//#include "lldir.h"
+//#include "llvolume.h"
+//#include "llendianswizzle.h"
+
+#include "llpolyskeletaldistortion.h"
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortionInfo()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortionInfo::LLPolySkeletalDistortionInfo()
+{
+}
+
+BOOL LLPolySkeletalDistortionInfo::parseXml(LLXmlTreeNode* node)
+{
+        llassert( node->hasName( "param" ) && node->getChildByName( "param_skeleton" ) );
+        
+        if (!LLViewerVisualParamInfo::parseXml(node))
+                return FALSE;
+
+        LLXmlTreeNode* skeletalParam = node->getChildByName("param_skeleton");
+
+        if (NULL == skeletalParam)
+        {
+                llwarns << "Failed to getChildByName(\"param_skeleton\")"
+                        << llendl;
+                return FALSE;
+        }
+
+        for( LLXmlTreeNode* bone = skeletalParam->getFirstChild(); bone; bone = skeletalParam->getNextChild() )
+        {
+                if (bone->hasName("bone"))
+                {
+                        std::string name;
+                        LLVector3 scale;
+                        LLVector3 pos;
+                        BOOL haspos = FALSE;
+                        
+                        static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
+                        if (!bone->getFastAttributeString(name_string, name))
+                        {
+                                llwarns << "No bone name specified for skeletal param." << llendl;
+                                continue;
+                        }
+
+                        static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
+                        if (!bone->getFastAttributeVector3(scale_string, scale))
+                        {
+                                llwarns << "No scale specified for bone " << name << "." << llendl;
+                                continue;
+                        }
+
+                        // optional offset deformation (translation)
+                        static LLStdStringHandle offset_string = LLXmlTree::addAttributeString("offset");
+                        if (bone->getFastAttributeVector3(offset_string, pos))
+                        {
+                                haspos = TRUE;
+                        }
+                        mBoneInfoList.push_back(LLPolySkeletalBoneInfo(name, scale, pos, haspos));
+                }
+                else
+                {
+                        llwarns << "Unrecognized element " << bone->getName() << " in skeletal distortion" << llendl;
+                        continue;
+                }
+        }
+        return TRUE;
+}
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::LLPolySkeletalDistortion(LLAvatarAppearance *avatarp)
+{
+        mAvatar = avatarp;
+        mDefaultVec.splat(0.001f);
+}
+
+//-----------------------------------------------------------------------------
+// ~LLPolySkeletalDistortion()
+//-----------------------------------------------------------------------------
+LLPolySkeletalDistortion::~LLPolySkeletalDistortion()
+{
+}
+
+BOOL LLPolySkeletalDistortion::setInfo(LLPolySkeletalDistortionInfo *info)
+{
+        llassert(mInfo == NULL);
+        if (info->mID < 0)
+                return FALSE;
+        mInfo = info;
+        mID = info->mID;
+        setWeight(getDefaultWeight(), FALSE );
+
+        LLPolySkeletalDistortionInfo::bone_info_list_t::iterator iter;
+        for (iter = getInfo()->mBoneInfoList.begin(); iter != getInfo()->mBoneInfoList.end(); iter++)
+        {
+                LLPolySkeletalBoneInfo *bone_info = &(*iter);
+                LLJoint* joint = mAvatar->getJoint(bone_info->mBoneName);
+                if (!joint)
+                {
+                        llwarns << "Joint " << bone_info->mBoneName << " not found." << llendl;
+                        continue;
+                }
+
+                if (mJointScales.find(joint) != mJointScales.end())
+                {
+                        llwarns << "Scale deformation already supplied for joint " << joint->getName() << "." << llendl;
+                }
+
+                // store it
+                mJointScales[joint] = bone_info->mScaleDeformation;
+
+                // apply to children that need to inherit it
+                for (LLJoint::child_list_t::iterator iter = joint->mChildren.begin();
+                     iter != joint->mChildren.end(); ++iter)
+                {
+                        LLAvatarJoint* child_joint = (LLAvatarJoint*)(*iter);
+                        if (child_joint->inheritScale())
+                        {
+                                LLVector3 childDeformation = LLVector3(child_joint->getScale());
+                                childDeformation.scaleVec(bone_info->mScaleDeformation);
+                                mJointScales[child_joint] = childDeformation;
+                        }
+                }
+
+                if (bone_info->mHasPositionDeformation)
+                {
+                        if (mJointOffsets.find(joint) != mJointOffsets.end())
+                        {
+                                llwarns << "Offset deformation already supplied for joint " << joint->getName() << "." << llendl;
+                        }
+                        mJointOffsets[joint] = bone_info->mPositionDeformation;
+                }
+        }
+        return TRUE;
+}
+
+/*virtual*/ LLViewerVisualParam* LLPolySkeletalDistortion::cloneParam(LLWearable* wearable) const
+{
+        LLPolySkeletalDistortion *new_param = new LLPolySkeletalDistortion(mAvatar);
+        *new_param = *this;
+        return new_param;
+}
+
+//-----------------------------------------------------------------------------
+// apply()
+//-----------------------------------------------------------------------------
+static LLFastTimer::DeclareTimer FTM_POLYSKELETAL_DISTORTION_APPLY("Skeletal Distortion");
+
+void LLPolySkeletalDistortion::apply( ESex avatar_sex )
+{
+	LLFastTimer t(FTM_POLYSKELETAL_DISTORTION_APPLY);
+
+        F32 effective_weight = ( getSex() & avatar_sex ) ? mCurWeight : getDefaultWeight();
+
+        LLJoint* joint;
+        joint_vec_map_t::iterator iter;
+
+        for (iter = mJointScales.begin();
+             iter != mJointScales.end();
+             iter++)
+        {
+                joint = iter->first;
+                LLVector3 newScale = joint->getScale();
+                LLVector3 scaleDelta = iter->second;
+                newScale = newScale + (effective_weight * scaleDelta) - (mLastWeight * scaleDelta);
+                joint->setScale(newScale);
+        }
+
+        for (iter = mJointOffsets.begin();
+             iter != mJointOffsets.end();
+             iter++)
+        {
+                joint = iter->first;
+                LLVector3 newPosition = joint->getPosition();
+                LLVector3 positionDelta = iter->second;
+                newPosition = newPosition + (effective_weight * positionDelta) - (mLastWeight * positionDelta);
+                joint->setPosition(newPosition);
+        }
+
+        if (mLastWeight != mCurWeight && !mIsAnimating)
+        {
+                mAvatar->setSkeletonSerialNum(mAvatar->getSkeletonSerialNum() + 1);
+        }
+        mLastWeight = mCurWeight;
+}
+
+
+LLPolyMorphData *clone_morph_param_duplicate(const LLPolyMorphData *src_data,
+					     const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+                cloned_morph_data->mCoords[v] = src_data->mCoords[v];
+                cloned_morph_data->mNormals[v] = src_data->mNormals[v];
+                cloned_morph_data->mBinormals[v] = src_data->mBinormals[v];
+        }
+        return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_direction(const LLPolyMorphData *src_data,
+					     const LLVector3 &direction,
+					     const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+		LLVector4a dir;
+		dir.load3(direction.mV);
+
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+                cloned_morph_data->mCoords[v] = dir;
+                cloned_morph_data->mNormals[v].clear();
+                cloned_morph_data->mBinormals[v].clear();
+        }
+        return cloned_morph_data;
+}
+
+LLPolyMorphData *clone_morph_param_cleavage(const LLPolyMorphData *src_data,
+                                            F32 scale,
+                                            const std::string &name)
+{
+        LLPolyMorphData* cloned_morph_data = new LLPolyMorphData(*src_data);
+        cloned_morph_data->mName = name;
+
+		LLVector4a sc;
+		sc.splat(scale);
+
+		LLVector4a nsc;
+		nsc.set(scale, -scale, scale, scale);
+
+        for (U32 v=0; v < cloned_morph_data->mNumIndices; v++)
+        {
+            if (cloned_morph_data->mCoords[v][1] < 0)
+            {
+                cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],nsc);
+				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v],nsc);
+				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],nsc);
+			}
+			else
+			{
+				cloned_morph_data->mCoords[v].setMul(src_data->mCoords[v],sc);
+				cloned_morph_data->mNormals[v].setMul(src_data->mNormals[v], sc);
+				cloned_morph_data->mBinormals[v].setMul(src_data->mBinormals[v],sc);
+			}
+        }
+        return cloned_morph_data;
+}
+
+// End
diff --git a/indra/llappearance/llpolyskeletaldistortion.h b/indra/llappearance/llpolyskeletaldistortion.h
new file mode 100644
index 0000000000000000000000000000000000000000..774bc7dfa2a8071ad89ae8c680e4326a17f0c033
--- /dev/null
+++ b/indra/llappearance/llpolyskeletaldistortion.h
@@ -0,0 +1,131 @@
+/** 
+ * @file llpolyskeletaldistortion.h
+ * @brief Implementation of LLPolyMesh class
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPOLYSKELETALDISTORTION_H
+#define LL_LLPOLYSKELETALDISTORTION_H
+
+#include "llcommon.h"
+
+#include <string>
+#include <map>
+#include "llstl.h"
+
+#include "v3math.h"
+#include "v2math.h"
+#include "llquaternion.h"
+//#include "llpolymorph.h"
+#include "lljoint.h"
+#include "llviewervisualparam.h"
+//#include "lldarray.h"
+
+//class LLSkinJoint;
+class LLAvatarAppearance;
+
+//#define USE_STRIPS	// Use tri-strips for rendering.
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformationInfo
+// Shared information for LLPolySkeletalDeformations
+//-----------------------------------------------------------------------------
+struct LLPolySkeletalBoneInfo
+{
+	LLPolySkeletalBoneInfo(std::string &name, LLVector3 &scale, LLVector3 &pos, BOOL haspos)
+		: mBoneName(name),
+		  mScaleDeformation(scale),
+		  mPositionDeformation(pos),
+		  mHasPositionDeformation(haspos) {}
+	std::string mBoneName;
+	LLVector3 mScaleDeformation;
+	LLVector3 mPositionDeformation;
+	BOOL mHasPositionDeformation;
+};
+
+LL_ALIGN_PREFIX(16)
+class LLPolySkeletalDistortionInfo : public LLViewerVisualParamInfo
+{
+	friend class LLPolySkeletalDistortion;
+public:
+	
+	LLPolySkeletalDistortionInfo();
+	/*virtual*/ ~LLPolySkeletalDistortionInfo() {};
+	
+	/*virtual*/ BOOL parseXml(LLXmlTreeNode* node);
+
+protected:
+	typedef std::vector<LLPolySkeletalBoneInfo> bone_info_list_t;
+	bone_info_list_t mBoneInfoList;
+};
+
+//-----------------------------------------------------------------------------
+// LLPolySkeletalDeformation
+// A set of joint scale data for deforming the avatar mesh
+//-----------------------------------------------------------------------------
+class LLPolySkeletalDistortion : public LLViewerVisualParam
+{
+public:
+	void* operator new(size_t size)
+	{
+		return ll_aligned_malloc_16(size);
+	}
+
+	void operator delete(void* ptr)
+	{
+		ll_aligned_free_16(ptr);
+	}
+
+	LLPolySkeletalDistortion(LLAvatarAppearance *avatarp);
+	~LLPolySkeletalDistortion();
+
+	// Special: These functions are overridden by child classes
+	LLPolySkeletalDistortionInfo*	getInfo() const { return (LLPolySkeletalDistortionInfo*)mInfo; }
+	//   This sets mInfo and calls initialization functions
+	BOOL							setInfo(LLPolySkeletalDistortionInfo *info);
+
+	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const;
+
+	// LLVisualParam Virtual functions
+	///*virtual*/ BOOL				parseData(LLXmlTreeNode* node);
+	/*virtual*/ void				apply( ESex sex );
+	
+	// LLViewerVisualParam Virtual functions
+	/*virtual*/ F32					getTotalDistortion() { return 0.1f; }
+	/*virtual*/ const LLVector4a&	getAvgDistortion()	{ return mDefaultVec; }
+	/*virtual*/ F32					getMaxDistortion() { return 0.1f; }
+	/*virtual*/ LLVector4a			getVertexDistortion(S32 index, LLPolyMesh *poly_mesh){return LLVector4a(0.001f, 0.001f, 0.001f);}
+	/*virtual*/ const LLVector4a*	getFirstDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return &mDefaultVec;};
+	/*virtual*/ const LLVector4a*	getNextDistortion(U32 *index, LLPolyMesh **poly_mesh){index = 0; poly_mesh = NULL; return NULL;};
+
+protected:
+	LL_ALIGN_16(LLVector4a mDefaultVec);
+	typedef std::map<LLJoint*, LLVector3> joint_vec_map_t;
+	joint_vec_map_t mJointScales;
+	joint_vec_map_t mJointOffsets;
+	// Backlink only; don't make this an LLPointer.
+	LLAvatarAppearance *mAvatar;
+} LL_ALIGN_POSTFIX(16);
+
+#endif // LL_LLPOLYSKELETALDISTORTION_H
+
diff --git a/indra/newview/lltexglobalcolor.cpp b/indra/llappearance/lltexglobalcolor.cpp
similarity index 92%
rename from indra/newview/lltexglobalcolor.cpp
rename to indra/llappearance/lltexglobalcolor.cpp
index ebe5ccd6c05149d2099b866a9c7af666f749236a..f38b98210422667fcf93b373670e2bfe2ecebdd4 100644
--- a/indra/newview/lltexglobalcolor.cpp
+++ b/indra/llappearance/lltexglobalcolor.cpp
@@ -24,20 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
-#include "llagent.h"
+#include "linden_common.h"
+#include "llavatarappearance.h"
 #include "lltexlayer.h"
-#include "llvoavatar.h"
-#include "llwearable.h"
 #include "lltexglobalcolor.h"
 
+class LLWearable;
+
 //-----------------------------------------------------------------------------
 // LLTexGlobalColor
 //-----------------------------------------------------------------------------
 
-LLTexGlobalColor::LLTexGlobalColor(LLVOAvatar* avatar) 
+LLTexGlobalColor::LLTexGlobalColor(LLAvatarAppearance* appearance)
 	:
-	mAvatar(avatar),
+	mAvatarAppearance(appearance),
 	mInfo(NULL)
 {
 }
@@ -91,7 +91,7 @@ const std::string& LLTexGlobalColor::getName() const
 // LLTexParamGlobalColor
 //-----------------------------------------------------------------------------
 LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color) :
-	LLTexLayerParamColor(tex_global_color->getAvatar()),
+	LLTexLayerParamColor(tex_global_color->getAvatarAppearance()),
 	mTexGlobalColor(tex_global_color)
 {
 }
@@ -105,7 +105,7 @@ LLTexParamGlobalColor::LLTexParamGlobalColor(LLTexGlobalColor* tex_global_color)
 
 void LLTexParamGlobalColor::onGlobalColorChanged(bool upload_bake)
 {
-	mAvatar->onGlobalColorChanged(mTexGlobalColor, upload_bake);
+	mAvatarAppearance->onGlobalColorChanged(mTexGlobalColor, upload_bake);
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/lltexglobalcolor.h b/indra/llappearance/lltexglobalcolor.h
similarity index 84%
rename from indra/newview/lltexglobalcolor.h
rename to indra/llappearance/lltexglobalcolor.h
index ae0479844528ec46dc8ef74804df8494de737a7b..2867479876d72f9c434132bca2821bd1a3b3429a 100644
--- a/indra/newview/lltexglobalcolor.h
+++ b/indra/llappearance/lltexglobalcolor.h
@@ -1,6 +1,6 @@
 /** 
  * @file lltexglobalcolor.h
- * @brief This is global texture color info used by llvoavatar.
+ * @brief This is global texture color info used by llavatarappearance.
  *
  * $LicenseInfo:firstyear=2008&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -30,31 +30,31 @@
 #include "lltexlayer.h"
 #include "lltexlayerparams.h"
 
-class LLVOAvatar;
+class LLAvatarAppearance;
 class LLWearable;
 class LLTexGlobalColorInfo;
 
 class LLTexGlobalColor
 {
 public:
-	LLTexGlobalColor( LLVOAvatar* avatar );
+	LLTexGlobalColor( LLAvatarAppearance* appearance );
 	~LLTexGlobalColor();
 
 	LLTexGlobalColorInfo*	getInfo() const { return mInfo; }
 	//   This sets mInfo and calls initialization functions
 	BOOL					setInfo(LLTexGlobalColorInfo *info);
 	
-	LLVOAvatar*				getAvatar()	const			   	{ return mAvatar; }
+	LLAvatarAppearance*		getAvatarAppearance()	const	   	{ return mAvatarAppearance; }
 	LLColor4				getColor() const;
 	const std::string&		getName() const;
 
 private:
 	param_color_list_t		mParamGlobalColorList;
-	LLVOAvatar*				mAvatar;  // just backlink, don't LLPointer 
+	LLAvatarAppearance*		mAvatarAppearance;  // just backlink, don't LLPointer 
 	LLTexGlobalColorInfo	*mInfo;
 };
 
-// Used by llvoavatar to determine skin/eye/hair color.
+// Used by llavatarappearance to determine skin/eye/hair color.
 class LLTexGlobalColorInfo
 {
 	friend class LLTexGlobalColor;
diff --git a/indra/newview/lltexlayer.cpp b/indra/llappearance/lltexlayer.cpp
similarity index 64%
rename from indra/newview/lltexlayer.cpp
rename to indra/llappearance/lltexlayer.cpp
index ad09af6594e7a7fdefa92f353197e921c4729d89..f951a982e5b5c5ec190e3f0651eb4ab74eb37249 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/llappearance/lltexlayer.cpp
@@ -24,36 +24,29 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lltexlayer.h"
 
-#include "llagent.h"
+#include "llavatarappearance.h"
+#include "llcrc.h"
+#include "imageids.h"
 #include "llimagej2c.h"
 #include "llimagetga.h"
-#include "llnotificationsutil.h"
+#include "lldir.h"
 #include "llvfile.h"
 #include "llvfs.h"
-#include "llviewerstats.h"
-#include "llviewerregion.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "pipeline.h"
-#include "llassetuploadresponders.h"
 #include "lltexlayerparams.h"
-#include "llui.h"
-#include "llagentwearables.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
 #include "llwearable.h"
-#include "llviewercontrol.h"
-#include "llviewershadermgr.h"
+#include "llwearabledata.h"
+#include "llvertexbuffer.h"
 #include "llviewervisualparam.h"
 
 //#include "../tools/imdebug/imdebug.h"
 
-using namespace LLVOAvatarDefines;
-
-static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
-static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
+using namespace LLAvatarAppearanceDefines;
 
 // runway consolidate
 extern std::string self_av_string();
@@ -68,7 +61,7 @@ class LLTexLayerInfo
 	~LLTexLayerInfo();
 
 	BOOL parseXml(LLXmlTreeNode* node);
-	BOOL createVisualParams(LLVOAvatar *avatar);
+	BOOL createVisualParams(LLAvatarAppearance *appearance);
 	BOOL isUserSettable() { return mLocalTexture != -1;	}
 	S32  getLocalTexture() const { return mLocalTexture; }
 	BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
@@ -95,126 +88,18 @@ class LLTexLayerInfo
 	param_alpha_info_list_t		mParamAlphaInfoList;
 };
 
-//-----------------------------------------------------------------------------
-// LLBakedUploadData()
-//-----------------------------------------------------------------------------
-LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
-									 LLTexLayerSet* layerset,
-									 const LLUUID& id,
-									 bool highest_res) :
-	mAvatar(avatar),
-	mTexLayerSet(layerset),
-	mID(id),
-	mStartTime(LLFrameTimer::getTotalTime()),		// Record starting time
-	mIsHighestRes(highest_res)
-{ 
-}
-
 //-----------------------------------------------------------------------------
 // LLTexLayerSetBuffer
-// The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
 //-----------------------------------------------------------------------------
 
-// static
-S32 LLTexLayerSetBuffer::sGLByteCount = 0;
-
-LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner, 
-										 S32 width, S32 height) :
-	// ORDER_LAST => must render these after the hints are created.
-	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
-	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
-	mNeedsUpload(FALSE),
-	mNumLowresUploads(0),
-	mUploadFailCount(0),
-	mNeedsUpdate(TRUE),
-	mNumLowresUpdates(0),
+LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner) :
 	mTexLayerSet(owner)
 {
-	LLTexLayerSetBuffer::sGLByteCount += getSize();
-	mNeedsUploadTimer.start();
-	mNeedsUpdateTimer.start();
 }
 
 LLTexLayerSetBuffer::~LLTexLayerSetBuffer()
 {
-	LLTexLayerSetBuffer::sGLByteCount -= getSize();
-	destroyGLTexture();
-	for( S32 order = 0; order < ORDER_COUNT; order++ )
-	{
-		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
-	}
-}
-
-//virtual 
-S8 LLTexLayerSetBuffer::getType() const 
-{
-	return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
-}
-
-//virtual 
-void LLTexLayerSetBuffer::restoreGLTexture() 
-{	
-	LLViewerDynamicTexture::restoreGLTexture() ;
-}
-
-//virtual 
-void LLTexLayerSetBuffer::destroyGLTexture() 
-{
-	LLViewerDynamicTexture::destroyGLTexture() ;
-}
-
-// static
-void LLTexLayerSetBuffer::dumpTotalByteCount()
-{
-	llinfos << "Composite System GL Buffers: " << (LLTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
-}
-
-void LLTexLayerSetBuffer::requestUpdate()
-{
-	restartUpdateTimer();
-	mNeedsUpdate = TRUE;
-	mNumLowresUpdates = 0;
-	// If we're in the middle of uploading a baked texture, we don't care about it any more.
-	// When it's downloaded, ignore it.
-	mUploadID.setNull();
-}
-
-void LLTexLayerSetBuffer::requestUpload()
-{
-	conditionalRestartUploadTimer();
-	mNeedsUpload = TRUE;
-	mNumLowresUploads = 0;
-	mUploadPending = TRUE;
-}
-
-void LLTexLayerSetBuffer::conditionalRestartUploadTimer()
-{
-	// If we requested a new upload but haven't even uploaded
-	// a low res version of our last upload request, then
-	// keep the timer ticking instead of resetting it.
-	if (mNeedsUpload && (mNumLowresUploads == 0))
-	{
-		mNeedsUploadTimer.unpause();
-	}
-	else
-	{
-		mNeedsUploadTimer.reset();
-		mNeedsUploadTimer.start();
-	}
-}
-
-void LLTexLayerSetBuffer::restartUpdateTimer()
-{
-	mNeedsUpdateTimer.reset();
-	mNeedsUpdateTimer.start();
-}
-
-void LLTexLayerSetBuffer::cancelUpload()
-{
-	mNeedsUpload = FALSE;
-	mUploadPending = FALSE;
-	mNeedsUploadTimer.pause();
-	mUploadRetryTimer.reset();
 }
 
 void LLTexLayerSetBuffer::pushProjection() const
@@ -222,7 +107,7 @@ void LLTexLayerSetBuffer::pushProjection() const
 	gGL.matrixMode(LLRender::MM_PROJECTION);
 	gGL.pushMatrix();
 	gGL.loadIdentity();
-	gGL.ortho(0.0f, mFullWidth, 0.0f, mFullHeight, -1.0f, 1.0f);
+	gGL.ortho(0.0f, getCompositeWidth(), 0.0f, getCompositeHeight(), -1.0f, 1.0f);
 
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
@@ -238,64 +123,24 @@ void LLTexLayerSetBuffer::popProjection() const
 	gGL.popMatrix();
 }
 
-BOOL LLTexLayerSetBuffer::needsRender()
-{
-	llassert(mTexLayerSet->getAvatar() == gAgentAvatarp);
-	if (!isAgentAvatarValid()) return FALSE;
-
-	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
-	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-
-	// Don't render if we don't want to (or aren't ready to) upload or update.
-	if (!(update_now || upload_now))
-	{
-		return FALSE;
-	}
-
-	// Don't render if we're animating our appearance.
-	if (gAgentAvatarp->getIsAppearanceAnimating())
-	{
-		return FALSE;
-	}
-
-	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
-	if (gAgentAvatarp->getBakedTE(mTexLayerSet) == LLVOAvatarDefines::TEX_SKIRT_BAKED && 
-		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
-	{
-		cancelUpload();
-		return FALSE;
-	}
-
-	// Render if we have at least minimal level of detail for each local texture.
-	return mTexLayerSet->isLocalTextureDataAvailable();
-}
-
-void LLTexLayerSetBuffer::preRender(BOOL clear_depth)
+// virtual
+void LLTexLayerSetBuffer::preRenderTexLayerSet()
 {
 	// Set up an ortho projection
 	pushProjection();
-	
-	// keep depth buffer, we don't need to clear it
-	LLViewerDynamicTexture::preRender(FALSE);
 }
 
-void LLTexLayerSetBuffer::postRender(BOOL success)
+// virtual
+void LLTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
 {
 	popProjection();
-
-	LLViewerDynamicTexture::postRender(success);
 }
 
-BOOL LLTexLayerSetBuffer::render()
+BOOL LLTexLayerSetBuffer::renderTexLayerSet()
 {
 	// Default color mask for tex layer render
 	gGL.setColorMask(true, true);
 
-	// do we need to upload, and do we have sufficient data to create an uploadable composite?
-	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
-	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
-	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
-	
 	BOOL success = TRUE;
 	
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
@@ -305,42 +150,20 @@ BOOL LLTexLayerSetBuffer::render()
 		gAlphaMaskProgram.bind();
 		gAlphaMaskProgram.setMinimumAlpha(0.004f);
 	}
+	else
+	{
+		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.00f);
+	}
 
 	LLVertexBuffer::unbind();
 
 	// Composite the color data
 	LLGLSUIDefault gls_ui;
-	success &= mTexLayerSet->render( mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight );
+	success &= mTexLayerSet->render( getCompositeOriginX(), getCompositeOriginY(), 
+									 getCompositeWidth(), getCompositeHeight() );
 	gGL.flush();
 
-	if(upload_now)
-	{
-		if (!success)
-		{
-			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
-			mUploadPending = FALSE;
-		}
-		else
-		{
-			if (mTexLayerSet->isVisible())
-			{
-				mTexLayerSet->getAvatar()->debugBakedTextureUpload(mTexLayerSet->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
-				doUpload();
-			}
-			else
-			{
-				mUploadPending = FALSE;
-				mNeedsUpload = FALSE;
-				mNeedsUploadTimer.pause();
-				mTexLayerSet->getAvatar()->setNewBakedTexture(mTexLayerSet->getBakedTexIndex(),IMG_INVISIBLE);
-			}
-		}
-	}
-	
-	if (update_now)
-	{
-		doUpdate();
-	}
+	midRenderTexLayerSet(success);
 
 	if (use_shaders)
 	{
@@ -353,374 +176,11 @@ BOOL LLTexLayerSetBuffer::render()
 	gGL.setColorMask(true, true);
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
-	// we have valid texture data now
-	mGLTexturep->setGLTextureCreated(true);
-
 	return success;
 }
 
-BOOL LLTexLayerSetBuffer::isInitialized(void) const
-{
-	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
-}
-
-BOOL LLTexLayerSetBuffer::uploadPending() const
-{
-	return mUploadPending;
-}
-
-BOOL LLTexLayerSetBuffer::uploadNeeded() const
-{
-	return mNeedsUpload;
-}
-
-BOOL LLTexLayerSetBuffer::uploadInProgress() const
-{
-	return !mUploadID.isNull();
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpload() const
-{
-	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
-	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures()) return FALSE; // Don't upload if avatar is using composites.
-
-	BOOL ready = FALSE;
-	if (mTexLayerSet->isLocalTextureDataFinal())
-	{
-		// If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
-		if (mUploadFailCount == 0)
-		{
-			ready = TRUE;
-		}
-		else
-		{
-			ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
-		}
-	}
-	else
-	{
-		// Upload if we've hit a timeout.  Upload is a pretty expensive process so we need to make sure
-		// we aren't doing uploads too frequently.
-		const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
-		if (texture_timeout != 0)
-		{
-			// The timeout period increases exponentially between every lowres upload in order to prevent
-			// spamming the server with frequent uploads.
-			const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
-
-			// If we hit our timeout and have textures available at even lower resolution, then upload.
-			const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
-			const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
-			ready = has_lower_lod && is_upload_textures_timeout;
-		}
-	}
-
-	return ready;
-}
-
-BOOL LLTexLayerSetBuffer::isReadyToUpdate() const
-{
-	// If we requested an update and have the final LOD ready, then update.
-	if (mTexLayerSet->isLocalTextureDataFinal()) return TRUE;
-
-	// If we haven't done an update yet, then just do one now regardless of state of textures.
-	if (mNumLowresUpdates == 0) return TRUE;
-
-	// Update if we've hit a timeout.  Unlike for uploads, we can make this timeout fairly small
-	// since render unnecessarily doesn't cost much.
-	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
-	if (texture_timeout != 0)
-	{
-		// If we hit our timeout and have textures available at even lower resolution, then update.
-		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
-		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
-		if (has_lower_lod && is_update_textures_timeout) return TRUE; 
-	}
-
-	return FALSE;
-}
-
-BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
-{
-	mNeedsUpdate = TRUE;
-	BOOL result = FALSE;
-
-	if (needsRender())
-	{
-		preRender(FALSE);
-		result = render();
-		postRender(result);
-	}
-
-	return result;
-}
-
-// Create the baked texture, send it out to the server, then wait for it to come
-// back so we can switch to using it.
-void LLTexLayerSetBuffer::doUpload()
-{
-	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
-
-	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
-	// until this image is sent to the server and the Avatar Appearance message is received.)
-	mTexLayerSet->deleteCaches();
-
-	// Get the COLOR information from our texture
-	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
-	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
-	stop_glerror();
-
-	// Get the MASK information from our texture
-	LLGLSUIDefault gls_ui;
-	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
-	U8* baked_mask_data = baked_mask_image->getData(); 
-	mTexLayerSet->gatherMorphMaskAlpha(baked_mask_data, mFullWidth, mFullHeight);
-
-
-	// Create the baked image from our color and mask information
-	const S32 baked_image_components = 5; // red green blue [bump] clothing
-	LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
-	U8* baked_image_data = baked_image->getData();
-	S32 i = 0;
-	for (S32 u=0; u < mFullWidth; u++)
-	{
-		for (S32 v=0; v < mFullHeight; v++)
-		{
-			baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
-			baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
-			baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
-			baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
-			baked_image_data[5*i + 4] = baked_mask_data[i];
-			i++;
-		}
-	}
-	
-	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
-	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
-	if (compressedImage->encode(baked_image, comment_text))
-	{
-		LLTransactionID tid;
-		tid.generate();
-		const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-		if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
-							   gVFS, asset_id, LLAssetType::AT_TEXTURE))
-		{
-			// Read back the file and validate.
-			BOOL valid = FALSE;
-			LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
-			S32 file_size = 0;
-			
-			//data buffer MUST be allocated using LLImageBase
-			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE);
-			file_size = file.getSize();
-			U8* data = integrity_test->allocateData(file_size);
-			file.read(data, file_size);
-			
-			if (data)
-			{
-				valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
-			}
-			else
-			{
-				integrity_test->setLastError("Unable to read entire file");
-			}
-			
-			if (valid)
-			{
-				const bool highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-				// Baked_upload_data is owned by the responder and deleted after the request completes.
-				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
-																			 this->mTexLayerSet, 
-																			 asset_id,
-																			 highest_lod);
-				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
-				mUploadID = asset_id;
-
-				// Upload the image
-				const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
-				if(!url.empty()
-					&& !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
-					&& (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
-				{
-					LLSD body = LLSD::emptyMap();
-					// The responder will call LLTexLayerSetBuffer::onTextureUploadComplete()
-					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
-					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
-				} 
-				else
-				{
-					gAssetStorage->storeAssetData(tid,
-												  LLAssetType::AT_TEXTURE,
-												  LLTexLayerSetBuffer::onTextureUploadComplete,
-												  baked_upload_data,
-												  TRUE,		// temp_file
-												  TRUE,		// is_priority
-												  TRUE);	// store_local
-					llinfos << "Baked texture upload via Asset Store." <<  llendl;
-				}
-
-				if (highest_lod)
-				{
-					// Sending the final LOD for the baked texture.  All done, pause 
-					// the upload timer so we know how long it took.
-					mNeedsUpload = FALSE;
-					mNeedsUploadTimer.pause();
-				}
-				else
-				{
-					// Sending a lower level LOD for the baked texture.  Restart the upload timer.
-					mNumLowresUploads++;
-					mNeedsUploadTimer.unpause();
-					mNeedsUploadTimer.reset();
-				}
-
-				// Print out notification that we uploaded this texture.
-				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-				{
-					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
-					LLSD args;
-					args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
-					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
-					args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
-					args["RESOLUTION"] = lod_str;
-					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
-					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
-				}
-			}
-			else
-			{
-				// The read back and validate operation failed.  Remove the uploaded file.
-				mUploadPending = FALSE;
-				LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
-				file.remove();
-				llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
-			}
-		}
-	}
-	else
-	{
-		// The VFS write file operation failed.
-		mUploadPending = FALSE;
-		llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
-	}
-
-	delete [] baked_color_data;
-}
-
-// Mostly bookkeeping; don't need to actually "do" anything since
-// render() will actually do the update.
-void LLTexLayerSetBuffer::doUpdate()
-{
-	const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-	if (highest_lod)
-	{
-		mNeedsUpdate = FALSE;
-	}
-	else
-	{
-		mNumLowresUpdates++;
-	}
-
-	restartUpdateTimer();
-
-	// need to swtich to using this layerset if this is the first update
-	// after getting the lowest LOD
-	mTexLayerSet->getAvatar()->updateMeshTextures();
-	
-	// Print out notification that we uploaded this texture.
-	if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
-	{
-		const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
-		const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
-		LLSD args;
-		args["EXISTENCE"] = llformat("%d",(U32)mTexLayerSet->getAvatar()->debugGetExistenceTimeElapsedF32());
-		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
-		args["BODYREGION"] = mTexLayerSet->getBodyRegionName();
-		args["RESOLUTION"] = lod_str;
-		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
-		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
-	}
-}
-
-// static
-void LLTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
-												  void* userdata,
-												  S32 result,
-												  LLExtStat ext_status) // StoreAssetData callback (not fixed)
-{
-	LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
-
-	if (isAgentAvatarValid() &&
-		!gAgentAvatarp->isDead() &&
-		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
-		(baked_upload_data->mTexLayerSet->hasComposite()))
-	{
-		LLTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getComposite();
-		S32 failures = layerset_buffer->mUploadFailCount;
-		layerset_buffer->mUploadFailCount = 0;
-
-		if (layerset_buffer->mUploadID.isNull())
-		{
-			// The upload got canceled, we should be in the
-			// process of baking a new texture so request an
-			// upload with the new data
-
-			// BAP: does this really belong in this callback, as
-			// opposed to where the cancellation takes place?
-			// suspect this does nothing.
-			layerset_buffer->requestUpload();
-		}
-		else if (baked_upload_data->mID == layerset_buffer->mUploadID)
-		{
-			// This is the upload we're currently waiting for.
-			layerset_buffer->mUploadID.setNull();
-			const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
-			const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
-			if (result >= 0)
-			{
-				layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
-				LLVOAvatarDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->mTexLayerSet);
-				// Update baked texture info with the new UUID
-				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
-				llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
-				gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
-			}
-			else
-			{	
-				++failures;
-				S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
-				llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
-				if (failures < max_attempts)
-				{
-					layerset_buffer->mUploadFailCount = failures;
-					layerset_buffer->mUploadRetryTimer.start();
-					layerset_buffer->requestUpload();
-				}
-			}
-		}
-		else
-		{
-			llinfos << "Received baked texture out of date, ignored." << llendl;
-		}
-
-		gAgentAvatarp->dirtyMesh();
-	}
-	else
-	{
-		// Baked texture failed to upload (in which case since we
-		// didn't set the new baked texture, it means that they'll try
-		// and rebake it at some point in the future (after login?)),
-		// or this response to upload is out of date, in which case a
-		// current response should be on the way or already processed.
-		llwarns << "Baked upload failed" << llendl;
-	}
-
-	delete baked_upload_data;
-}
-
 //-----------------------------------------------------------------------------
-// LLTexLayerSet
+// LLTexLayerSetInfo
 // An ordered set of texture layers that get composited into a single texture.
 //-----------------------------------------------------------------------------
 
@@ -790,7 +250,7 @@ BOOL LLTexLayerSetInfo::parseXml(LLXmlTreeNode* node)
 }
 
 // creates visual params without generating layersets or layers
-void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
+void LLTexLayerSetInfo::createVisualParams(LLAvatarAppearance *appearance)
 {
 	//layer_info_list_t		mLayerInfoList;
 	for (layer_info_list_t::iterator layer_iter = mLayerInfoList.begin();
@@ -798,7 +258,7 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
 		 layer_iter++)
 	{
 		LLTexLayerInfo *layer_info = *layer_iter;
-		layer_info->createVisualParams(avatar);
+		layer_info->createVisualParams(appearance);
 	}
 }
 
@@ -809,16 +269,15 @@ void LLTexLayerSetInfo::createVisualParams(LLVOAvatar *avatar)
 
 BOOL LLTexLayerSet::sHasCaches = FALSE;
 
-LLTexLayerSet::LLTexLayerSet(LLVOAvatarSelf* const avatar) :
-	mComposite( NULL ),
-	mAvatar( avatar ),
-	mUpdatesEnabled( FALSE ),
+LLTexLayerSet::LLTexLayerSet(LLAvatarAppearance* const appearance) :
+	mAvatarAppearance( appearance ),
 	mIsVisible( TRUE ),
-	mBakedTexIndex(LLVOAvatarDefines::BAKED_HEAD),
+	mBakedTexIndex(LLAvatarAppearanceDefines::BAKED_HEAD),
 	mInfo( NULL )
 {
 }
 
+// virtual
 LLTexLayerSet::~LLTexLayerSet()
 {
 	deleteCaches();
@@ -844,13 +303,13 @@ BOOL LLTexLayerSet::setInfo(const LLTexLayerSetInfo *info)
 		LLTexLayerInterface *layer = NULL;
 		if ( (*iter)->isUserSettable() )
 		{
-			layer = new LLTexLayerTemplate( this );
+			layer = new LLTexLayerTemplate( this, getAvatarAppearance() );
 		}
 		else
 		{
 			layer = new LLTexLayer(this);
 		}
-		// this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar
+		// this is the first time this layer (of either type) is being created - make sure you add the parameters to the avatar appearance
 		if (!layer->setInfo(*iter, NULL))
 		{
 			mInfo = NULL;
@@ -910,21 +369,6 @@ void LLTexLayerSet::deleteCaches()
 	}
 }
 
-// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
-BOOL LLTexLayerSet::isLocalTextureDataAvailable() const
-{
-	if (!mAvatar->isSelf()) return FALSE;
-	return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataAvailable(this);
-}
-
-
-// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
-BOOL LLTexLayerSet::isLocalTextureDataFinal() const
-{
-	if (!mAvatar->isSelf()) return FALSE;
-	return ((LLVOAvatarSelf *)mAvatar)->isLocalTextureDataFinal(this);
-}
-
 
 BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 {
@@ -1025,43 +469,31 @@ const std::string LLTexLayerSet::getBodyRegionName() const
 	return mInfo->mBodyRegion; 
 }
 
-void LLTexLayerSet::requestUpdate()
-{
-	if( mUpdatesEnabled )
-	{
-		createComposite();
-		mComposite->requestUpdate(); 
-	}
-}
-
-void LLTexLayerSet::requestUpload()
-{
-	createComposite();
-	mComposite->requestUpload();
-}
 
-void LLTexLayerSet::cancelUpload()
+// virtual
+void LLTexLayerSet::asLLSD(LLSD& sd) const
 {
-	if(mComposite)
+	sd["visible"] = LLSD::Boolean(isVisible());
+	LLSD layer_list_sd;
+	layer_list_t::const_iterator layer_iter = mLayerList.begin();
+	layer_list_t::const_iterator layer_end  = mLayerList.end();
+	for(; layer_iter != layer_end; ++layer_iter);
 	{
-		mComposite->cancelUpload();
+		LLSD layer_sd;
+		//LLTexLayerInterface* layer = (*layer_iter);
+		//if (layer)
+		//{
+		//	layer->asLLSD(layer_sd);
+		//}
+		layer_list_sd.append(layer_sd);
 	}
+	LLSD mask_list_sd;
+	LLSD info_sd;
+	sd["layers"] = layer_list_sd;
+	sd["masks"] = mask_list_sd;
+	sd["info"] = info_sd;
 }
 
-void LLTexLayerSet::createComposite()
-{
-	if(!mComposite)
-	{
-		S32 width = mInfo->mWidth;
-		S32 height = mInfo->mHeight;
-		// Composite other avatars at reduced resolution
-		if( !mAvatar->isSelf() )
-		{
-			llerrs << "composites should not be created for non-self avatars!" << llendl;
-		}
-		mComposite = new LLTexLayerSetBuffer( this, width, height );
-	}
-}
 
 void LLTexLayerSet::destroyComposite()
 {
@@ -1071,18 +503,6 @@ void LLTexLayerSet::destroyComposite()
 	}
 }
 
-void LLTexLayerSet::setUpdatesEnabled( BOOL b )
-{
-	mUpdatesEnabled = b; 
-}
-
-
-void LLTexLayerSet::updateComposite()
-{
-	createComposite();
-	mComposite->requestUpdateImmediate();
-}
-
 LLTexLayerSetBuffer* LLTexLayerSet::getComposite()
 {
 	if (!mComposite)
@@ -1097,22 +517,26 @@ const LLTexLayerSetBuffer* LLTexLayerSet::getComposite() const
 	return mComposite;
 }
 
-void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
+static LLFastTimer::DeclareTimer FTM_GATHER_MORPH_MASK_ALPHA("gatherMorphMaskAlpha");
+void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_GATHER_MORPH_MASK_ALPHA);
 	memset(data, 255, width * height);
 
 	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-		layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height);
+		layer->gatherAlphaMasks(data, origin_x, origin_y, width, height);
 	}
 	
 	// Set alpha back to that of our alpha masks.
-	renderAlphaMaskTextures(mComposite->getOriginX(), mComposite->getOriginY(), width, height, true);
+	renderAlphaMaskTextures(origin_x, origin_y, width, height, true);
 }
 
+static LLFastTimer::DeclareTimer FTM_RENDER_ALPHA_MASK_TEXTURES("renderAlphaMaskTextures");
 void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear)
 {
+	LLFastTimer t(FTM_RENDER_ALPHA_MASK_TEXTURES);
 	const LLTexLayerSetInfo *info = getInfo();
 	
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
@@ -1125,7 +549,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 	{
 		gGL.flush();
 		{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(info->mStaticAlphaFileName, TRUE);
 			if( tex )
 			{
 				LLGLSUIDefault gls_ui;
@@ -1182,7 +606,7 @@ void LLTexLayerSet::renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height,
 
 void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components)
 {
-	mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
+	mAvatarAppearance->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
 }
 
 BOOL LLTexLayerSet::isMorphValid() const
@@ -1297,11 +721,11 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
 			/* if ("upper_shirt" == local_texture_name)
 				mLocalTexture = TEX_UPPER_SHIRT; */
 			mLocalTexture = TEX_NUM_INDICES;
-			for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+			for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 				 iter++)
 			{
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 				if (local_texture_name == texture_dict->mName)
 			{
 					mLocalTexture = iter->first;
@@ -1368,7 +792,7 @@ BOOL LLTexLayerInfo::parseXml(LLXmlTreeNode* node)
 	return TRUE;
 }
 
-BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
+BOOL LLTexLayerInfo::createVisualParams(LLAvatarAppearance *appearance)
 {
 	BOOL success = TRUE;
 	for (param_color_info_list_t::iterator color_info_iter = mParamColorInfoList.begin();
@@ -1376,7 +800,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
 		 color_info_iter++)
 	{
 		LLTexLayerParamColorInfo * color_info = *color_info_iter;
-		LLTexLayerParamColor* param_color = new LLTexLayerParamColor(avatar);
+		LLTexLayerParamColor* param_color = new LLTexLayerParamColor(appearance);
 		if (!param_color->setInfo(color_info, TRUE))
 		{
 			llwarns << "NULL TexLayer Color Param could not be added to visual param list. Deleting." << llendl;
@@ -1390,7 +814,7 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
 		 alpha_info_iter++)
 	{
 		LLTexLayerParamAlphaInfo * alpha_info = *alpha_info_iter;
-		LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(avatar);
+		LLTexLayerParamAlpha* param_alpha = new LLTexLayerParamAlpha(appearance);
 		if (!param_alpha->setInfo(alpha_info, TRUE))
 		{
 			llwarns << "NULL TexLayer Alpha Param could not be added to visual param list. Deleting." << llendl;
@@ -1498,6 +922,59 @@ const std::string& LLTexLayerInterface::getName() const
 	return mInfo->mName; 
 }
 
+ETextureIndex LLTexLayerInterface::getLocalTextureIndex() const
+{
+	return (ETextureIndex) mInfo->mLocalTexture;
+}
+
+LLWearableType::EType LLTexLayerInterface::getWearableType() const
+{
+	ETextureIndex te = getLocalTextureIndex();
+	if (TEX_INVALID == te)
+	{
+		LLWearableType::EType type = LLWearableType::WT_INVALID;
+		param_color_list_t::const_iterator color_iter = mParamColorList.begin();
+		param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin();
+
+		for (; color_iter != mParamColorList.end(); color_iter++)
+		{
+			LLTexLayerParamColor* param = *color_iter;
+			if (param) 
+			{
+				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+				if (new_type != LLWearableType::WT_INVALID && new_type != type) 
+				{
+					if (type != LLWearableType::WT_INVALID) 
+					{
+						return LLWearableType::WT_INVALID;
+					}
+					type = new_type;
+				}
+			}
+		}
+
+		for (; alpha_iter != mParamAlphaList.end(); alpha_iter++)
+		{
+			LLTexLayerParamAlpha* param = *alpha_iter;
+			if (param) 
+			{
+				LLWearableType::EType new_type = (LLWearableType::EType)param->getWearableType();
+				if (new_type != LLWearableType::WT_INVALID && new_type != type) 
+				{
+					if (type != LLWearableType::WT_INVALID) 
+					{
+						return LLWearableType::WT_INVALID;
+					}
+					type = new_type;
+				}
+			}
+		}
+
+		return type;
+	}
+	return LLAvatarAppearanceDictionary::getTEWearableType(te);
+}
+
 LLTexLayerInterface::ERenderPass LLTexLayerInterface::getRenderPass() const
 {
 	return mInfo->mRenderPass; 
@@ -1586,6 +1063,12 @@ LLTexLayer::~LLTexLayer()
 
 }
 
+void LLTexLayer::asLLSD(LLSD& sd) const
+{
+	// *TODO: Finish
+	sd["id"] = getUUID();
+}
+
 //-----------------------------------------------------------------------------
 // setInfo
 //-----------------------------------------------------------------------------
@@ -1637,17 +1120,21 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LL
 BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 {
 	LLGLEnable color_mat(GL_COLOR_MATERIAL);
-	gPipeline.disableLights();
+	// *TODO: Is this correct?
+	//gPipeline.disableLights();
+	stop_glerror();
+	glDisable(GL_LIGHTING);
+	stop_glerror();
 
 	bool use_shaders = LLGLSLShader::sNoFixedFunction;
 
 	LLColor4 net_color;
 	BOOL color_specified = findNetColor(&net_color);
 	
-	if (mTexLayerSet->getAvatar()->mIsDummy)
+	if (mTexLayerSet->getAvatarAppearance()->mIsDummy)
 	{
 		color_specified = true;
-		net_color = LLVOAvatar::getDummyColor();
+		net_color = LLAvatarAppearance::getDummyColor();
 	}
 
 	BOOL success = TRUE;
@@ -1687,7 +1174,8 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 			}
 		}//*/
 
-		renderMorphMasks(x, y, width, height, net_color);
+		const bool force_render = true;
+		renderMorphMasks(x, y, width, height, net_color, force_render);
 		alpha_mask_specified = TRUE;
 		gGL.flush();
 		gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
@@ -1704,7 +1192,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	if( (getInfo()->mLocalTexture != -1) && !getInfo()->mUseLocalTextureAlphaOnly )
 	{
 		{
-			LLViewerTexture* tex = NULL;
+			LLGLTexture* tex = NULL;
 			if (mLocalTextureObject && mLocalTextureObject->getImage())
 			{
 				tex = mLocalTextureObject->getImage();
@@ -1717,15 +1205,18 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 			{
 				llinfos << "lto not defined or image not defined: " << getInfo()->getLocalTexture() << " lto: " << mLocalTextureObject << llendl;
 			}
-//			if( mTexLayerSet->getAvatar()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
+//			if( mTexLayerSet->getAvatarAppearance()->getLocalTextureGL((ETextureIndex)getInfo()->mLocalTexture, &image_gl ) )
 			{
 				if( tex )
 				{
 					bool no_alpha_test = getInfo()->mWriteAllChannels;
 					LLGLDisable alpha_test(no_alpha_test ? GL_ALPHA_TEST : 0);
-					if (use_shaders && no_alpha_test)
+					if (no_alpha_test)
 					{
-						gAlphaMaskProgram.setMinimumAlpha(0.f);
+						if (use_shaders)
+						{
+							gAlphaMaskProgram.setMinimumAlpha(0.f);
+						}
 					}
 					
 					LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
@@ -1737,11 +1228,13 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 
 					gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
 					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-					if (use_shaders && no_alpha_test)
+					if (no_alpha_test)
 					{
-						gAlphaMaskProgram.setMinimumAlpha(0.004f);
+						if (use_shaders)
+						{
+							gAlphaMaskProgram.setMinimumAlpha(0.004f);
+						}
 					}
-					
 				}
 			}
 //			else
@@ -1754,7 +1247,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
 		{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 			if( tex )
 			{
 				gGL.getTexUnit(0)->bind(tex, TRUE);
@@ -1776,8 +1269,9 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
 		if (use_shaders)
 		{
-			gAlphaMaskProgram.setMinimumAlpha(0.f);
+			gAlphaMaskProgram.setMinimumAlpha(0.000f);
 		}
+
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		gGL.color4fv( net_color.mV );
 		gl_rect_2d_simple( width, height );
@@ -1834,7 +1328,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
 	{
 		if( !getGlobalColor().empty() )
 		{
-			net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getInfo()->mGlobalColor ) );
+			net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getInfo()->mGlobalColor ) );
 		}
 		else if (getInfo()->mFixedColor.mV[VW])
 		{
@@ -1851,7 +1345,7 @@ BOOL LLTexLayer::findNetColor(LLColor4* net_color) const
 
 	if( !getGlobalColor().empty() )
 	{
-		net_color->setVec( mTexLayerSet->getAvatar()->getGlobalColor( getGlobalColor() ) );
+		net_color->setVec( mTexLayerSet->getAvatarAppearance()->getGlobalColor( getGlobalColor() ) );
 		return TRUE;
 	}
 
@@ -1876,7 +1370,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
-		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
+		LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture( getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask );
 		if( tex )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1901,7 +1395,7 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 	{
 		if (getInfo()->mLocalTexture >=0 && getInfo()->mLocalTexture < TEX_NUM_INDICES)
 		{
-			LLViewerTexture* tex = mLocalTextureObject->getImage();
+			LLGLTexture* tex = mLocalTextureObject->getImage();
 			if (tex)
 			{
 				LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1929,8 +1423,15 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 	addAlphaMask(data, originX, originY, width, height);
 }
 
-BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color)
+static LLFastTimer::DeclareTimer FTM_RENDER_MORPH_MASKS("renderMorphMasks");
+void LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render)
 {
+	if (!force_render && !hasMorph())
+	{
+		lldebugs << "skipping renderMorphMasks for " << getUUID() << llendl;
+		return;
+	}
+	LLFastTimer t(FTM_RENDER_MORPH_MASKS);
 	BOOL success = TRUE;
 
 	llassert( !mParamAlphaList.empty() );
@@ -1966,6 +1467,11 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	{
 		LLTexLayerParamAlpha* param = *iter;
 		success &= param->render( x, y, width, height );
+		if (!success && !force_render)
+		{
+			lldebugs << "Failed to render param " << param->getID() << " ; skipping morph mask." << llendl;
+			return;
+		}
 	}
 
 	// Approximates a min() function
@@ -1975,7 +1481,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	// Accumulate the alpha component of the texture
 	if( getInfo()->mLocalTexture != -1 )
 	{
-		LLViewerTexture* tex = mLocalTextureObject->getImage();
+		LLGLTexture* tex = mLocalTextureObject->getImage();
 		if( tex && (tex->getComponents() == 4) )
 		{
 			LLGLSNoAlphaTest gls_no_alpha_test;
@@ -1991,25 +1497,29 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		}
 	}
 
-	if( !getInfo()->mStaticImageFileName.empty() )
+	if( !getInfo()->mStaticImageFileName.empty() && getInfo()->mStaticImageIsMask )
 	{
-		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+		LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 		if( tex )
 		{
-			if(	(tex->getComponents() == 4) ||
-				( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
+			if(	(tex->getComponents() == 4) || (tex->getComponents() == 1) )
 			{
 				LLGLSNoAlphaTest gls_no_alpha_test;
 				gGL.getTexUnit(0)->bind(tex, TRUE);
 				gl_rect_2d_simple_tex( width, height );
 				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			}
+			else
+			{
+				llwarns << "Skipping rendering of " << getInfo()->mStaticImageFileName 
+						<< "; expected 1 or 4 components." << llendl;
+			}
 		}
 	}
 
 	// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
 	// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
-	if (layer_color.mV[VW] != 1.f)
+	if ( !is_approx_equal(layer_color.mV[VW], 1.f) )
 	{
 		LLGLDisable no_alpha(GL_ALPHA_TEST);
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
@@ -2044,7 +1554,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 		if (!alpha_data)
 		{
 			// clear out a slot if we have filled our cache
-			S32 max_cache_entries = getTexLayerSet()->getAvatar()->isSelf() ? 4 : 1;
+			S32 max_cache_entries = getTexLayerSet()->getAvatarAppearance()->isSelf() ? 4 : 1;
 			while ((S32)mAlphaCache.size() >= max_cache_entries)
 			{
 				alpha_cache_t::iterator iter2 = mAlphaCache.begin(); // arbitrarily grab the first entry
@@ -2057,17 +1567,17 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 			glReadPixels(x, y, width, height, GL_ALPHA, GL_UNSIGNED_BYTE, alpha_data);
 		}
 		
-		getTexLayerSet()->getAvatar()->dirtyMesh();
+		getTexLayerSet()->getAvatarAppearance()->dirtyMesh();
 
 		mMorphMasksValid = TRUE;
 		getTexLayerSet()->applyMorphMask(alpha_data, width, height, 1);
 	}
-
-	return success;
 }
 
+static LLFastTimer::DeclareTimer FTM_ADD_ALPHA_MASK("addAlphaMask");
 void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_ADD_ALPHA_MASK);
 	S32 size = width * height;
 	const U8* alphaData = getAlphaData();
 	if (!alphaData && hasAlphaParams())
@@ -2076,7 +1586,8 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 		findNetColor( &net_color );
 		// TODO: eliminate need for layer morph mask valid flag
 		invalidateMorphMasks();
-		renderMorphMasks(originX, originY, width, height, net_color);
+		const bool force_render = false;
+		renderMorphMasks(originX, originY, width, height, net_color, force_render);
 		alphaData = getAlphaData();
 	}
 	if (alphaData)
@@ -2085,7 +1596,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 		{
 			U8 curAlpha = data[i];
 			U16 resultAlpha = curAlpha;
-			resultAlpha *= (alphaData[i] + 1);
+			resultAlpha *= ( ((U16)alphaData[i]) + 1);
 			resultAlpha = resultAlpha >> 8;
 			data[i] = (U8)resultAlpha;
 		}
@@ -2110,7 +1621,7 @@ LLUUID LLTexLayer::getUUID() const
 	LLUUID uuid;
 	if( getInfo()->mLocalTexture != -1 )
 	{
-			LLViewerTexture* tex = mLocalTextureObject->getImage();
+			LLGLTexture* tex = mLocalTextureObject->getImage();
 			if (tex)
 			{
 				uuid = mLocalTextureObject->getID();
@@ -2118,7 +1629,7 @@ LLUUID LLTexLayer::getUUID() const
 	}
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+			LLGLTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
 			if( tex )
 			{
 				uuid = tex->getID();
@@ -2141,13 +1652,15 @@ LLUUID LLTexLayer::getUUID() const
 //			* a texture entry index (TE)
 //		* (optional) one or more alpha parameters (weighted alpha textures)
 //-----------------------------------------------------------------------------
-LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set) :
-	LLTexLayerInterface(layer_set)
+LLTexLayerTemplate::LLTexLayerTemplate(LLTexLayerSet* layer_set, LLAvatarAppearance* const appearance) :
+	LLTexLayerInterface(layer_set),
+	mAvatarAppearance( appearance )
 {
 }
 
 LLTexLayerTemplate::LLTexLayerTemplate(const LLTexLayerTemplate &layer) :
-	LLTexLayerInterface(layer)
+	LLTexLayerInterface(layer),
+	mAvatarAppearance(layer.getAvatarAppearance())
 {
 }
 
@@ -2168,18 +1681,17 @@ U32 LLTexLayerTemplate::updateWearableCache() const
 {
 	mWearableCache.clear();
 
-	S32 te = mInfo->mLocalTexture;
-	if (te == -1)
+	LLWearableType::EType wearable_type = getWearableType();
+	if (LLWearableType::WT_INVALID == wearable_type)
 	{
 		//this isn't a cloneable layer 
 		return 0;
 	}
-	LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te);
-	U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+	U32 num_wearables = getAvatarAppearance()->getWearableData()->getWearableCount(wearable_type);
 	U32 added = 0;
 	for (U32 i = 0; i < num_wearables; i++)
 	{
-		LLWearable*  wearable = gAgentWearables.getWearable(wearable_type, i);
+		LLWearable*  wearable = getAvatarAppearance()->getWearableData()->getWearable(wearable_type, i);
 		if (!wearable)
 		{
 			continue;
@@ -2234,7 +1746,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
 		}
 		if (layer)
 		{
-			wearable->writeToAvatar();
+			wearable->writeToAvatar(mAvatarAppearance);
 			layer->setLTO(lto);
 			success &= layer->render(x,y,width,height);
 		}
@@ -2341,7 +1853,7 @@ LLTexLayerInterface*  LLTexLayerSet::findLayerByName(const std::string& name)
 	return NULL;
 }
 
-void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable *wearable)
+void LLTexLayerSet::cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable *wearable)
 {
 	// initialize all texlayers with this texture type for this LTO
 	for( LLTexLayerSet::layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
@@ -2408,8 +1920,10 @@ void LLTexLayerStaticImageList::deleteCachedImages()
 
 // Returns an LLImageTGA that contains the encoded data from a tga file named file_name.
 // Caches the result to speed identical subsequent requests.
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TGA("getImageTGA");
 LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
 {
+	LLFastTimer t(FTM_LOAD_STATIC_TGA);
 	const char *namekey = mImageNames.addString(file_name);
 	image_tga_map_t::const_iterator iter = mStaticImageListTGA.find(namekey);
 	if( iter != mStaticImageListTGA.end() )
@@ -2436,9 +1950,11 @@ LLImageTGA* LLTexLayerStaticImageList::getImageTGA(const std::string& file_name)
 
 // Returns a GL Image (without a backing ImageRaw) that contains the decoded data from a tga file named file_name.
 // Caches the result to speed identical subsequent requests.
-LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
+static LLFastTimer::DeclareTimer FTM_LOAD_STATIC_TEXTURE("getTexture");
+LLGLTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_name, BOOL is_mask)
 {
-	LLPointer<LLViewerTexture> tex;
+	LLFastTimer t(FTM_LOAD_STATIC_TEXTURE);
+	LLPointer<LLGLTexture> tex;
 	const char *namekey = mImageNames.addString(file_name);
 
 	texture_map_t::const_iterator iter = mStaticImageList.find(namekey);
@@ -2448,17 +1964,24 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n
 	}
 	else
 	{
-		tex = LLViewerTextureManager::getLocalTexture( FALSE );
+		llassert(gTextureManagerBridgep);
+		tex = gTextureManagerBridgep->getLocalTexture( FALSE );
 		LLPointer<LLImageRaw> image_raw = new LLImageRaw;
 		if( loadImageRaw( file_name, image_raw ) )
 		{
 			if( (image_raw->getComponents() == 1) && is_mask )
 			{
-				// Note: these are static, unchanging images so it's ok to assume
-				// that once an image is a mask it's always a mask.
-				tex->setExplicitFormat( GL_ALPHA8, GL_ALPHA );
+				// Convert grayscale alpha masks from single channel into RGBA.
+				// Fill RGB with black to allow fixed function gl calls
+				// to match shader implementation.
+				LLPointer<LLImageRaw> alpha_image_raw = image_raw;
+				image_raw = new LLImageRaw(image_raw->getWidth(),
+										   image_raw->getHeight(),
+										   4);
+
+				image_raw->copyUnscaledAlphaMask(alpha_image_raw, LLColor4U::black);
 			}
-			tex->createGLTexture(0, image_raw, 0, TRUE, LLViewerTexture::LOCAL);
+			tex->createGLTexture(0, image_raw, 0, TRUE, LLGLTexture::LOCAL);
 
 			gGL.getTexUnit(0)->bind(tex);
 			tex->setAddressMode(LLTexUnit::TAM_CLAMP);
@@ -2477,8 +2000,10 @@ LLViewerTexture* LLTexLayerStaticImageList::getTexture(const std::string& file_n
 
 // Reads a .tga file, decodes it, and puts the decoded data in image_raw.
 // Returns TRUE if successful.
+static LLFastTimer::DeclareTimer FTM_LOAD_IMAGE_RAW("loadImageRaw");
 BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLImageRaw* image_raw)
 {
+	LLFastTimer t(FTM_LOAD_IMAGE_RAW);
 	BOOL success = FALSE;
 	std::string path;
 	path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,file_name);
@@ -2492,23 +2017,3 @@ BOOL LLTexLayerStaticImageList::loadImageRaw(const std::string& file_name, LLIma
 	return success;
 }
 
-const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
-{
-	if (!isAgentAvatarValid()) return "";
-
-	const BOOL is_high_res = !mNeedsUpload;
-	const U32 num_low_res = mNumLowresUploads;
-	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
-	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
-
-	std::string status 				= "CREATING ";
-	if (!uploadNeeded()) status 	= "DONE     ";
-	if (uploadInProgress()) status 	= "UPLOADING";
-
-	std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
-								status.c_str(),
-								is_high_res, num_low_res,
-								upload_time, 
-								local_texture_info.c_str());
-	return text;
-}
diff --git a/indra/newview/lltexlayer.h b/indra/llappearance/lltexlayer.h
similarity index 65%
rename from indra/newview/lltexlayer.h
rename to indra/llappearance/lltexlayer.h
index 4f43547dae5034117610fe9bd6274de7b1cc9a67..959d6e499abfb348bf8709e2b4c6b618871a9e3c 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -28,14 +28,15 @@
 #define LL_LLTEXLAYER_H
 
 #include <deque>
-#include "lldynamictexture.h"
-#include "llvoavatardefines.h"
+#include "llglslshader.h"
+#include "llgltexture.h"
+#include "llavatarappearancedefines.h"
 #include "lltexlayerparams.h"
 
-class LLVOAvatar;
-class LLVOAvatarSelf;
+class LLAvatarAppearance;
 class LLImageTGA;
 class LLImageRaw;
+class LLLocalTextureObject;
 class LLXmlTreeNode;
 class LLTexLayerSet;
 class LLTexLayerSetInfo;
@@ -71,6 +72,8 @@ class LLTexLayerInterface
 
 	const LLTexLayerInfo* 	getInfo() const 			{ return mInfo; }
 	virtual BOOL			setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
+	LLWearableType::EType	getWearableType() const;
+	LLAvatarAppearanceDefines::ETextureIndex	getLocalTextureIndex() const;
 
 	const std::string&		getName() const;
 	const LLTexLayerSet* const getTexLayerSet() const 	{ return mTexLayerSet; }
@@ -88,6 +91,8 @@ class LLTexLayerInterface
 	ERenderPass				getRenderPass() const;
 	BOOL					isVisibilityMask() const;
 
+	virtual void			asLLSD(LLSD& sd) const {}
+
 protected:
 	const std::string&		getGlobalColor() const;
 	LLViewerVisualParam*	getVisualParamPtr(S32 index) const;
@@ -113,7 +118,7 @@ class LLTexLayerInterface
 class LLTexLayerTemplate : public LLTexLayerInterface
 {
 public:
-	LLTexLayerTemplate(LLTexLayerSet* const layer_set);
+	LLTexLayerTemplate(LLTexLayerSet* const layer_set, LLAvatarAppearance* const appearance);
 	LLTexLayerTemplate(const LLTexLayerTemplate &layer);
 	/*virtual*/ ~LLTexLayerTemplate();
 	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height);
@@ -126,7 +131,9 @@ class LLTexLayerTemplate : public LLTexLayerInterface
 protected:
 	U32 					updateWearableCache() const;
 	LLTexLayer* 			getLayer(U32 i) const;
+	LLAvatarAppearance*		getAvatarAppearance()	const		{ return mAvatarAppearance; }
 private:
+	LLAvatarAppearance*	const	mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
 	typedef std::vector<LLWearable*> wearable_cache_t;
 	mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
 };
@@ -153,17 +160,18 @@ class LLTexLayer : public LLTexLayerInterface
 	BOOL					findNetColor(LLColor4* color) const;
 	/*virtual*/ BOOL		blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
 	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
-	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
+	void					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, bool force_render);
 	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
 	/*virtual*/ BOOL		isInvisibleAlphaMask() const;
 
 	void					setLTO(LLLocalTextureObject *lto) 	{ mLocalTextureObject = lto; }
 	LLLocalTextureObject* 	getLTO() 							{ return mLocalTextureObject; }
 
+	/*virtual*/ void		asLLSD(LLSD& sd) const;
+
 	static void 			calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
 protected:
 	LLUUID					getUUID() const;
-private:
 	typedef std::map<U32, U8*> alpha_cache_t;
 	alpha_cache_t			mAlphaCache;
 	LLLocalTextureObject* 	mLocalTextureObject;
@@ -179,8 +187,14 @@ class LLTexLayerSet
 {
 	friend class LLTexLayerSetBuffer;
 public:
-	LLTexLayerSet(LLVOAvatarSelf* const avatar);
-	~LLTexLayerSet();
+	LLTexLayerSet(LLAvatarAppearance* const appearance);
+	virtual ~LLTexLayerSet();
+
+	LLTexLayerSetBuffer*		getComposite();
+	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
+	virtual void				createComposite() = 0;
+	void						destroyComposite();
+	void						gatherMorphMaskAlpha(U8 *data, S32 origin_x, S32 origin_y, S32 width, S32 height);
 
 	const LLTexLayerSetInfo* 	getInfo() const 			{ return mInfo; }
 	BOOL						setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
@@ -189,45 +203,34 @@ class LLTexLayerSet
 	void						renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
 
 	BOOL						isBodyRegion(const std::string& region) const;
-	LLTexLayerSetBuffer*		getComposite();
-	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
-	void						requestUpdate();
-	void						requestUpload();
-	void						cancelUpload();
-	void						updateComposite();
-	BOOL						isLocalTextureDataAvailable() const;
-	BOOL						isLocalTextureDataFinal() const;
-	void						createComposite();
-	void						destroyComposite();
-	void						setUpdatesEnabled(BOOL b);
-	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
-	void						deleteCaches();
-	void						gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
 	void						applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
 	BOOL						isMorphValid() const;
+	virtual void				requestUpdate() = 0;
 	void						invalidateMorphMasks();
+	void						deleteCaches();
 	LLTexLayerInterface*		findLayerByName(const std::string& name);
-	void						cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
+	void						cloneTemplates(LLLocalTextureObject *lto, LLAvatarAppearanceDefines::ETextureIndex tex_index, LLWearable* wearable);
 	
-	LLVOAvatarSelf*		    	getAvatar()	const 			{ return mAvatar; }
+	LLAvatarAppearance*			getAvatarAppearance()	const		{ return mAvatarAppearance; }
 	const std::string			getBodyRegionName() const;
 	BOOL						hasComposite() const 		{ return (mComposite.notNull()); }
-	LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
-	void						setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
+	LLAvatarAppearanceDefines::EBakedTextureIndex getBakedTexIndex() const { return mBakedTexIndex; }
+	void						setBakedTexIndex(LLAvatarAppearanceDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
 	BOOL						isVisible() const 			{ return mIsVisible; }
 
 	static BOOL					sHasCaches;
 
-private:
+	virtual void				asLLSD(LLSD& sd) const;
+
+protected:
 	typedef std::vector<LLTexLayerInterface *> layer_list_t;
 	layer_list_t				mLayerList;
 	layer_list_t				mMaskLayerList;
 	LLPointer<LLTexLayerSetBuffer>	mComposite;
-	LLVOAvatarSelf*	const		mAvatar; // note: backlink only; don't make this an LLPointer.
-	BOOL						mUpdatesEnabled;
+	LLAvatarAppearance*	const	mAvatarAppearance; // note: backlink only; don't make this an LLPointer.
 	BOOL						mIsVisible;
 
-	LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
+	LLAvatarAppearanceDefines::EBakedTextureIndex mBakedTexIndex;
 	const LLTexLayerSetInfo* 	mInfo;
 };
 
@@ -243,8 +246,10 @@ class LLTexLayerSetInfo
 	LLTexLayerSetInfo();
 	~LLTexLayerSetInfo();
 	BOOL parseXml(LLXmlTreeNode* node);
-	void createVisualParams(LLVOAvatar *avatar);
-private:
+	void createVisualParams(LLAvatarAppearance *appearance);
+	S32 getWidth() const { return mWidth; }
+	S32 getHeight() const { return mHeight; }
+protected:
 	std::string				mBodyRegion;
 	S32						mWidth;
 	S32						mHeight;
@@ -259,78 +264,27 @@ class LLTexLayerSetInfo
 //
 // The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLTexLayerSetBuffer : public LLViewerDynamicTexture
+class LLTexLayerSetBuffer : public virtual LLRefCount
 {
 	LOG_CLASS(LLTexLayerSetBuffer);
 
 public:
-	LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+	LLTexLayerSetBuffer(LLTexLayerSet* const owner);
 	virtual ~LLTexLayerSetBuffer();
 
-public:
-	/*virtual*/ S8          getType() const;
-	BOOL					isInitialized(void) const;
-	static void				dumpTotalByteCount();
-	const std::string		dumpTextureInfo() const;
-	virtual void 			restoreGLTexture();
-	virtual void 			destroyGLTexture();
 protected:
 	void					pushProjection() const;
 	void					popProjection() const;
-private:
-	LLTexLayerSet* const    mTexLayerSet;
-	static S32				sGLByteCount;
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success) {}
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const = 0;
+	virtual S32				getCompositeOriginY() const = 0;
+	virtual S32				getCompositeWidth() const = 0;
+	virtual S32				getCompositeHeight() const = 0;
+	BOOL					renderTexLayerSet();
 
-	//--------------------------------------------------------------------
-	// Render
-	//--------------------------------------------------------------------
-public:
-	/*virtual*/ BOOL		needsRender();
-protected:
-	BOOL					render(S32 x, S32 y, S32 width, S32 height);
-	virtual void			preRender(BOOL clear_depth);
-	virtual void			postRender(BOOL success);
-	virtual BOOL			render();	
-	
-	//--------------------------------------------------------------------
-	// Uploads
-	//--------------------------------------------------------------------
-public:
-	void					requestUpload();
-	void					cancelUpload();
-	BOOL					uploadNeeded() const; 			// We need to upload a new texture
-	BOOL					uploadInProgress() const; 		// We have started uploading a new texture and are awaiting the result
-	BOOL					uploadPending() const; 			// We are expecting a new texture to be uploaded at some point
-	static void				onTextureUploadComplete(const LLUUID& uuid,
-													void* userdata,
-													S32 result, LLExtStat ext_status);
-protected:
-	BOOL					isReadyToUpload() const;
-	void					doUpload(); 					// Does a read back and upload.
-	void					conditionalRestartUploadTimer();
-private:
-	BOOL					mNeedsUpload; 					// Whether we need to send our baked textures to the server
-	U32						mNumLowresUploads; 				// Number of times we've sent a lowres version of our baked textures to the server
-	BOOL					mUploadPending; 				// Whether we have received back the new baked textures
-	LLUUID					mUploadID; 						// The current upload process (null if none).
-	LLFrameTimer    		mNeedsUploadTimer; 				// Tracks time since upload was requested and performed.
-	S32						mUploadFailCount;				// Number of consecutive upload failures
-	LLFrameTimer    		mUploadRetryTimer; 				// Tracks time since last upload failure.
-
-	//--------------------------------------------------------------------
-	// Updates
-	//--------------------------------------------------------------------
-public:
-	void					requestUpdate();
-	BOOL					requestUpdateImmediate();
-protected:
-	BOOL					isReadyToUpdate() const;
-	void					doUpdate();
-	void					restartUpdateTimer();
-private:
-	BOOL					mNeedsUpdate; 					// Whether we need to locally update our baked textures
-	U32						mNumLowresUpdates; 				// Number of times we've locally updated with lowres version of our baked textures
-	LLFrameTimer    		mNeedsUpdateTimer; 				// Tracks time since update was requested and performed.
+	LLTexLayerSet* const	mTexLayerSet;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -342,7 +296,7 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 public:
 	LLTexLayerStaticImageList();
 	~LLTexLayerStaticImageList();
-	LLViewerTexture*	getTexture(const std::string& file_name, BOOL is_mask);
+	LLGLTexture*		getTexture(const std::string& file_name, BOOL is_mask);
 	LLImageTGA*			getImageTGA(const std::string& file_name);
 	void				deleteCachedImages();
 	void				dumpByteCount() const;
@@ -350,7 +304,7 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 	BOOL				loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
 private:
 	LLStringTable 		mImageNames;
-	typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
+	typedef std::map<const char*, LLPointer<LLGLTexture> > texture_map_t;
 	texture_map_t 		mStaticImageList;
 	typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
 	image_tga_map_t 	mStaticImageListTGA;
@@ -358,23 +312,4 @@ class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 	S32 				mTGABytes;
 };
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// LLBakedUploadData
-//
-// Used by LLTexLayerSetBuffer for a callback.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-struct LLBakedUploadData
-{
-	LLBakedUploadData(const LLVOAvatarSelf* avatar, 
-					  LLTexLayerSet* layerset, 
-					  const LLUUID& id,
-					  bool highest_res);
-	~LLBakedUploadData() {}
-	const LLUUID				mID;
-	const LLVOAvatarSelf*		mAvatar; // note: backlink only; don't LLPointer 
-	LLTexLayerSet*				mTexLayerSet;
-   	const U64					mStartTime;	// for measuring baked texture upload time
-   	const bool					mIsHighestRes; // whether this is a "final" bake, or intermediate low res
-};
-
 #endif  // LL_LLTEXLAYER_H
diff --git a/indra/newview/lltexlayerparams.cpp b/indra/llappearance/lltexlayerparams.cpp
similarity index 85%
rename from indra/newview/lltexlayerparams.cpp
rename to indra/llappearance/lltexlayerparams.cpp
index 8972827effb513b90dbd7a951f1776266d88cd9c..6aae9a8cc11ce032266c3bbcfec8027f810d1b03 100644
--- a/indra/newview/lltexlayerparams.cpp
+++ b/indra/llappearance/lltexlayerparams.cpp
@@ -24,27 +24,28 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "lltexlayerparams.h"
 
-#include "llagentcamera.h"
+#include "llavatarappearance.h"
 #include "llimagetga.h"
+#include "llquantize.h"
 #include "lltexlayer.h"
-#include "llvoavatarself.h"
+#include "lltexturemanagerbridge.h"
+#include "../llui/llui.h"
 #include "llwearable.h"
-#include "llui.h"
 
 //-----------------------------------------------------------------------------
 // LLTexLayerParam
 //-----------------------------------------------------------------------------
 LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
 	mTexLayer(layer),
-	mAvatar(NULL)
+	mAvatarAppearance(NULL)
 {
 	if (mTexLayer != NULL)
 	{
-		mAvatar = mTexLayer->getTexLayerSet()->getAvatar();
+		mAvatarAppearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
 	}
 	else
 	{
@@ -52,20 +53,21 @@ LLTexLayerParam::LLTexLayerParam(LLTexLayerInterface *layer) :
 	}
 }
 
-LLTexLayerParam::LLTexLayerParam(LLVOAvatar *avatar) :
-	mTexLayer(NULL)
+LLTexLayerParam::LLTexLayerParam(LLAvatarAppearance *appearance) :
+	mTexLayer(NULL),
+	mAvatarAppearance(appearance)
 {
-	mAvatar = avatar;
 }
 
 
-BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar  )
-{	
+BOOL LLTexLayerParam::setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance)
+{
 	LLViewerVisualParam::setInfo(info);
 
-	if (add_to_avatar)
+	if (add_to_appearance)
 	{
-		mAvatar->addVisualParam( this);
+		mAvatarAppearance->addVisualParam( this);
+		this->setParamLocation(mAvatarAppearance->isSelf() ? LOC_AV_SELF : LOC_AV_OTHER);
 	}
 
 	return TRUE;
@@ -96,7 +98,7 @@ void LLTexLayerParamAlpha::getCacheByteCount(S32* gl_bytes)
 		 iter != sInstances.end(); iter++)
 	{
 		LLTexLayerParamAlpha* instance = *iter;
-		LLViewerTexture* tex = instance->mCachedProcessedTexture;
+		LLGLTexture* tex = instance->mCachedProcessedTexture;
 		if (tex)
 		{
 			S32 bytes = (S32)tex->getWidth() * tex->getHeight() * tex->getComponents();
@@ -120,8 +122,8 @@ LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLTexLayerInterface* layer) :
 	sInstances.push_front(this);
 }
 
-LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLVOAvatar* avatar) :
-	LLTexLayerParam(avatar),
+LLTexLayerParamAlpha::LLTexLayerParamAlpha(LLAvatarAppearance* appearance) :
+	LLTexLayerParam(appearance),
 	mCachedProcessedTexture(NULL),
 	mNeedsCreateTexture(FALSE),
 	mStaticImageInvalid(FALSE),
@@ -173,13 +175,10 @@ void LLTexLayerParamAlpha::setWeight(F32 weight, BOOL upload_bake)
 	{
 		mCurWeight = new_weight;
 
-		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+		if ((mAvatarAppearance->getSex() & getSex()) &&
+			(mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
 		{
-			if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
-			{
-				upload_bake = FALSE;
-			}
-			mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+			mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
 			mTexLayer->invalidateMorphMasks();
 		}
 	}
@@ -218,11 +217,11 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 		return TRUE;
 	}
 
-	const LLVOAvatar *avatar = mTexLayer->getTexLayerSet()->getAvatar();
+	const LLAvatarAppearance *appearance = mTexLayer->getTexLayerSet()->getAvatarAppearance();
 
 	if (((LLTexLayerParamAlphaInfo *)getInfo())->mSkipIfZeroWeight)
 	{
-		F32 effective_weight = (avatar->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+		F32 effective_weight = (appearance->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
 		if (is_approx_zero(effective_weight)) 
 		{
 			return TRUE;
@@ -230,7 +229,7 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 	}
 
 	LLWearableType::EType type = (LLWearableType::EType)getWearableType();
-	if ((type != LLWearableType::WT_INVALID) && !avatar->isWearingWearableType(type))
+	if ((type != LLWearableType::WT_INVALID) && !appearance->isWearingWearableType(type))
 	{
 		return TRUE;
 	}
@@ -239,8 +238,10 @@ BOOL LLTexLayerParamAlpha::getSkip() const
 }
 
 
+static LLFastTimer::DeclareTimer FTM_TEX_LAYER_PARAM_ALPHA("alpha render");
 BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 {
+	LLFastTimer t(FTM_TEX_LAYER_PARAM_ALPHA);
 	BOOL success = TRUE;
 
 	if (!mTexLayer)
@@ -248,7 +249,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 		return success;
 	}
 
-	F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatar()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
+	F32 effective_weight = (mTexLayer->getTexLayerSet()->getAvatarAppearance()->getSex() & getSex()) ? mCurWeight : getDefaultWeight();
 	BOOL weight_changed = effective_weight != mCachedEffectiveWeight;
 	if (getSkip())
 	{
@@ -290,12 +291,12 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 			(mCachedProcessedTexture->getHeight() != image_tga_height) ||
 			(weight_changed))
 		{
-//			llinfos << "Building Cached Alpha: " << mName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << effective_weight << llendl;
 			mCachedEffectiveWeight = effective_weight;
 
 			if (!mCachedProcessedTexture)
 			{
-				mCachedProcessedTexture = LLViewerTextureManager::getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
+				llassert(gTextureManagerBridgep);
+				mCachedProcessedTexture = gTextureManagerBridgep->getLocalTexture(image_tga_width, image_tga_height, 1, FALSE);
 
 				// We now have something in one of our caches
 				LLTexLayerSet::sHasCaches |= mCachedProcessedTexture ? TRUE : FALSE;
@@ -308,6 +309,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 			mStaticImageRaw = new LLImageRaw;
 			mStaticImageTGA->decodeAndProcess(mStaticImageRaw, info->mDomain, effective_weight);
 			mNeedsCreateTexture = TRUE;			
+			lldebugs << "Built Cached Alpha: " << info->mStaticImageFileName << ": (" << mStaticImageRaw->getWidth() << ", " << mStaticImageRaw->getHeight() << ") " << "Domain: " << info->mDomain << " Weight: " << effective_weight << llendl;
 		}
 
 		if (mCachedProcessedTexture)
@@ -332,7 +334,7 @@ BOOL LLTexLayerParamAlpha::render(S32 x, S32 y, S32 width, S32 height)
 
 		// Don't keep the cache for other people's avatars
 		// (It's not really a "cache" in that case, but the logic is the same)
-		if (!mAvatar->isSelf())
+		if (!mAvatarAppearance->isSelf())
 		{
 			mCachedProcessedTexture = NULL;
 		}
@@ -402,8 +404,8 @@ LLTexLayerParamColor::LLTexLayerParamColor(LLTexLayerInterface* layer) :
 {
 }
 
-LLTexLayerParamColor::LLTexLayerParamColor(LLVOAvatar *avatar) :
-	LLTexLayerParam(avatar),
+LLTexLayerParamColor::LLTexLayerParamColor(LLAvatarAppearance *appearance) :
+	LLTexLayerParam(appearance),
 	mAvgDistortionVec(1.f, 1.f, 1.f)
 {
 }
@@ -425,7 +427,7 @@ LLColor4 LLTexLayerParamColor::getNetColor() const
 	
 	llassert(info->mNumColors >= 1);
 
-	F32 effective_weight = (mAvatar && (mAvatar->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
+	F32 effective_weight = (mAvatarAppearance && (mAvatarAppearance->getSex() & getSex())) ? mCurWeight : getDefaultWeight();
 
 	S32 index_last = info->mNumColors - 1;
 	F32 scaled_weight = effective_weight * index_last;
@@ -470,12 +472,12 @@ void LLTexLayerParamColor::setWeight(F32 weight, BOOL upload_bake)
 			return;
 		}
 
-		if ((mAvatar->getSex() & getSex()) && (mAvatar->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
+		if ((mAvatarAppearance->getSex() & getSex()) && (mAvatarAppearance->isSelf() && !mIsDummy)) // only trigger a baked texture update if we're changing a wearable's visual param.
 		{
 			onGlobalColorChanged(upload_bake);
 			if (mTexLayer)
 			{
-				mAvatar->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
+				mAvatarAppearance->invalidateComposite(mTexLayer->getTexLayerSet(), upload_bake);
 			}
 		}
 
diff --git a/indra/newview/lltexlayerparams.h b/indra/llappearance/lltexlayerparams.h
similarity index 95%
rename from indra/newview/lltexlayerparams.h
rename to indra/llappearance/lltexlayerparams.h
index c812199796f91a839a1c3e575248fbc5506a99c6..b38d28d3ebb4d666265747e5696c263fc6c7f715 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/llappearance/lltexlayerparams.h
@@ -27,14 +27,16 @@
 #ifndef LL_LLTEXLAYERPARAMS_H
 #define LL_LLTEXLAYERPARAMS_H
 
+#include "llpointer.h"
+#include "v4color.h"
 #include "llviewervisualparam.h"
 
+class LLAvatarAppearance;
 class LLImageRaw;
 class LLImageTGA;
 class LLTexLayer;
 class LLTexLayerInterface;
-class LLViewerTexture;
-class LLVOAvatar;
+class LLGLTexture;
 class LLWearable;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -45,13 +47,13 @@ class LLTexLayerParam : public LLViewerVisualParam
 {
 public: 
 	LLTexLayerParam(LLTexLayerInterface *layer);
-	LLTexLayerParam(LLVOAvatar *avatar);
-	/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_avatar  );
+	LLTexLayerParam(LLAvatarAppearance *appearance);
+	/*virtual*/ BOOL setInfo(LLViewerVisualParamInfo *info, BOOL add_to_appearance);
 	/*virtual*/ LLViewerVisualParam* cloneParam(LLWearable* wearable) const = 0;
 
 protected:
 	LLTexLayerInterface*	mTexLayer;
-	LLVOAvatar*             mAvatar;
+	LLAvatarAppearance*		mAvatarAppearance;
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -63,7 +65,7 @@ class LLTexLayerParamAlpha : public LLTexLayerParam
 {
 public:
 	LLTexLayerParamAlpha( LLTexLayerInterface* layer );
-	LLTexLayerParamAlpha( LLVOAvatar* avatar );
+	LLTexLayerParamAlpha( LLAvatarAppearance* appearance );
 	/*virtual*/ ~LLTexLayerParamAlpha();
 
 	void* operator new(size_t size)
@@ -100,7 +102,7 @@ class LLTexLayerParamAlpha : public LLTexLayerParam
 	BOOL					getMultiplyBlend() const;
 
 private:
-	LLPointer<LLViewerTexture>	mCachedProcessedTexture;
+	LLPointer<LLGLTexture>	mCachedProcessedTexture;
 	LLPointer<LLImageTGA>	mStaticImageTGA;
 	LLPointer<LLImageRaw>	mStaticImageRaw;
 	BOOL					mNeedsCreateTexture;
@@ -153,7 +155,7 @@ class LLTexLayerParamColor : public LLTexLayerParam
 	};
 
 	LLTexLayerParamColor( LLTexLayerInterface* layer );
-	LLTexLayerParamColor( LLVOAvatar* avatar );
+	LLTexLayerParamColor( LLAvatarAppearance* appearance );
 
 	void* operator new(size_t size)
 	{
diff --git a/indra/llappearance/lltexturemanagerbridge.cpp b/indra/llappearance/lltexturemanagerbridge.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..33f2185e4fad5cb942661dd5421e7722b63a6a4e
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.cpp
@@ -0,0 +1,32 @@
+ /** 
+ * @file lltexturemanagerbridge.cpp
+ * @brief Defined a null texture manager bridge.  Applications must provide their own bridge implementaton.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "lltexturemanagerbridge.h"
+
+// Define a null texture manager bridge.  Applications must provide their own bridge implementaton.
+LLTextureManagerBridge* gTextureManagerBridgep = NULL;
+
+
diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h
new file mode 100644
index 0000000000000000000000000000000000000000..4b814b522dd49ff23dff72fc6da4ab36f7c26e75
--- /dev/null
+++ b/indra/llappearance/lltexturemanagerbridge.h
@@ -0,0 +1,46 @@
+/** 
+ * @file lltexturemanagerbridge.h
+ * @brief Bridge to an application-specific texture manager.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_TEXTUREMANAGERBRIDGE_H
+#define LL_TEXTUREMANAGERBRIDGE_H
+
+#include "llavatarappearancedefines.h"
+#include "llpointer.h"
+#include "llgltexture.h"
+
+// Abstract bridge interface
+class LLTextureManagerBridge
+{
+public:
+	virtual LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE) = 0;
+	virtual LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) = 0;
+	virtual LLGLTexture* getFetchedTexture(const LLUUID &image_id) = 0;
+};
+
+extern LLTextureManagerBridge* gTextureManagerBridgep;
+
+#endif // LL_TEXTUREMANAGERBRIDGE_H
+
diff --git a/indra/newview/llviewervisualparam.cpp b/indra/llappearance/llviewervisualparam.cpp
similarity index 98%
rename from indra/newview/llviewervisualparam.cpp
rename to indra/llappearance/llviewervisualparam.cpp
index f0cf9b7692ef9e492d13c5dc65168f46863dd10a..cc81bcf118a2a964d9a40feb556c400eed2cdf99 100644
--- a/indra/newview/llviewervisualparam.cpp
+++ b/indra/llappearance/llviewervisualparam.cpp
@@ -27,11 +27,10 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "llviewervisualparam.h"
 #include "llxmltree.h"
-#include "llui.h"
 #include "llwearable.h"
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llviewervisualparam.h b/indra/llappearance/llviewervisualparam.h
similarity index 100%
rename from indra/newview/llviewervisualparam.h
rename to indra/llappearance/llviewervisualparam.h
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d86a460511fba4cb052b8d40029dae735488e08b
--- /dev/null
+++ b/indra/llappearance/llwearable.cpp
@@ -0,0 +1,781 @@
+/** 
+ * @file llwearable.cpp
+ * @brief LLWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llavatarappearance.h"
+#include "lllocaltextureobject.h"
+#include "lltexlayer.h"
+#include "lltexturemanagerbridge.h"
+#include "llvisualparam.h"
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// static
+S32 LLWearable::sCurrentDefinitionVersion = 1;
+
+// Private local functions
+static std::string terse_F32_to_string(F32 f);
+
+// virtual
+LLWearable::~LLWearable()
+{
+}
+
+const std::string& LLWearable::getTypeLabel() const
+{
+	return LLWearableType::getTypeLabel(mType);
+}
+
+const std::string& LLWearable::getTypeName() const
+{
+	return LLWearableType::getTypeName(mType);
+}
+
+LLAssetType::EType LLWearable::getAssetType() const
+{
+	return LLWearableType::getAssetType(mType);
+}
+
+BOOL LLWearable::exportFile(LLFILE* fp) const
+{
+	llofstream ofs(fp);
+	return exportStream(ofs);
+}
+
+// virtual
+BOOL LLWearable::exportStream( std::ostream& output_stream ) const
+{
+	if (!output_stream.good()) return FALSE;
+
+	// header and version
+	output_stream << "LLWearable version " << mDefinitionVersion  << "\n";
+	// name
+	output_stream << mName << "\n";
+	// description
+	output_stream << mDescription << "\n";
+
+	// permissions
+	if( !mPermissions.exportLegacyStream( output_stream ) )
+	{
+		return FALSE;
+	}
+
+	// sale info
+	if( !mSaleInfo.exportLegacyStream( output_stream ) )
+	{
+		return FALSE;
+	}
+
+	// wearable type
+	output_stream << "type " << (S32) getType() << "\n";
+
+	// parameters
+	output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
+
+	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
+		 iter != mVisualParamIndexMap.end(); 
+		 ++iter)
+	{
+		S32 param_id = iter->first;
+		const LLVisualParam* param = iter->second;
+		F32 param_weight = param->getWeight();
+		output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";
+	}
+
+	// texture entries
+	output_stream << "textures " << mTEMap.size() << "\n";
+
+	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
+	{
+			S32 te = iter->first;
+			const LLUUID& image_id = iter->second->getID();
+			output_stream << te << " " << image_id << "\n";
+	}
+	return TRUE;
+}
+
+void LLWearable::createVisualParams(LLAvatarAppearance *avatarp)
+{
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) avatarp->getFirstVisualParam(); 
+		 param;
+		 param = (LLViewerVisualParam*) avatarp->getNextVisualParam())
+	{
+		if (param->getWearableType() == mType)
+		{
+			LLVisualParam *clone_param = param->cloneParam(this);
+			clone_param->setParamLocation(LOC_UNKNOWN);
+			clone_param->setParamLocation(LOC_WEARABLE);
+			addVisualParam(clone_param);
+		}
+	}
+
+	// resync driver parameters to point to the newly cloned driven parameters
+	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); 
+		 param_iter != mVisualParamIndexMap.end(); 
+		 ++param_iter)
+	{
+		LLVisualParam* param = param_iter->second;
+		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; 
+		// need this line to disambiguate between versions of LLCharacter::getVisualParam()
+		LLVisualParam*(LLAvatarAppearance::*param_function)(S32)const = &LLAvatarAppearance::getVisualParam; 
+		param->resetDrivenParams();
+		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
+		{
+			if( !param->linkDrivenParams(boost::bind(param_function,avatarp,_1 ), true))
+			{
+				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
+				continue;
+			}
+		}
+	}
+}
+
+void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
+{
+	LLTexLayerSet *layer_set = NULL;
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+	if (texture_dict->mIsUsedByBakedTexture)
+	{
+		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+		
+		 layer_set = avatarp->getAvatarLayerSet(baked_index);
+	}
+
+	if (layer_set)
+	{
+		   layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
+	}
+	else
+	{
+		   llerrs << "could not find layerset for LTO in wearable!" << llendl;
+	}
+}
+
+LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
+{
+	llifstream ifs(fp);
+	return importStream(ifs, avatarp);
+}
+
+// virtual
+LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+	// *NOTE: changing the type or size of this buffer will require
+	// changes in the fscanf() code below.
+	// We are using a local max buffer size here to avoid issues
+	// if MAX_STRING size changes.
+	const U32 PARSE_BUFFER_SIZE = 2048;
+	char buffer[PARSE_BUFFER_SIZE];		/* Flawfinder: ignore */
+	char uuid_buffer[37];	/* Flawfinder: ignore */
+
+	// This data is being generated on the viewer.
+	// Impose some sane limits on parameter and texture counts.
+	const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
+	const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
+
+	if(!avatarp)
+	{
+		return LLWearable::FAILURE;
+	}
+
+	// read header and version 
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Failed to read wearable asset input stream." << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( 1 != sscanf( /* Flawfinder: ignore */
+				buffer,
+				"LLWearable version %d\n",
+				&mDefinitionVersion ) )
+	{
+		return LLWearable::BAD_HEADER;
+	}
+
+	// Hack to allow wearables with definition version 24 to still load.
+	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
+	// the extra check for version == 24 can be removed before release, once internal testers
+	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
+	// these wearables get re-saved with version definition 22.
+	if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
+	{
+		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// name may be empty
+    if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading name" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mName = buffer;
+
+	// description may be empty
+	if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading description" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mDescription = buffer;
+
+	// permissions may have extra empty lines before the correct line
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading permissions" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 perm_version = -1;
+	if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
+		 perm_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( !mPermissions.importLegacyStream( input_stream ) )
+	{
+		return LLWearable::FAILURE;
+	}
+
+	// sale info
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading sale info" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 sale_info_version = -1;
+	if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
+		sale_info_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
+		return LLWearable::FAILURE;
+	}
+	// Sale info used to contain next owner perm. It is now in the
+	// permissions. Thus, we read that out, and fix legacy
+	// objects. It's possible this op would fail, but it should pick
+	// up the vast majority of the tasks.
+	BOOL has_perm_mask = FALSE;
+	U32 perm_mask = 0;
+	if( !mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask) )
+	{
+		return LLWearable::FAILURE;
+	}
+	if(has_perm_mask)
+	{
+		// fair use fix.
+		if(!(perm_mask & PERM_COPY))
+		{
+			perm_mask |= PERM_TRANSFER;
+		}
+		mPermissions.setMaskNext(perm_mask);
+	}
+
+	// wearable type
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading type" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 type = -1;
+	if ( 1 != sscanf( buffer, "type %d\n", &type ) )
+	{
+		llwarns << "Bad Wearable asset: bad type" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( 0 <= type && type < LLWearableType::WT_COUNT )
+	{
+		setType((LLWearableType::EType)type, avatarp);
+	}
+	else
+	{
+		mType = LLWearableType::WT_COUNT;
+		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// parameters header
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading parameters header" << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 num_parameters = -1;
+	if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
+	{
+		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
+	{
+		llwarns << "Bad Wearable asset: too many parameters, "
+				<< num_parameters << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( num_parameters != mVisualParamIndexMap.size() )
+	{
+		llwarns << "Wearable parameter mismatch. Reading in " 
+				<< num_parameters << " from file, but created " 
+				<< mVisualParamIndexMap.size() 
+				<< " from avatar parameters. type: " 
+				<<  getType() << llendl;
+	}
+
+	// parameters
+	S32 i;
+	for( i = 0; i < num_parameters; i++ )
+	{
+		if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading parameter #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		S32 param_id = 0;
+		F32 param_weight = 0.f;
+		if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
+		{
+			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		mSavedVisualParamMap[param_id] = param_weight;
+	}
+
+	// textures header
+	if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading textures header" << i << llendl;
+		return LLWearable::FAILURE;
+	}
+	S32 num_textures = -1;
+	if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
+	{
+		llwarns << "Bad Wearable asset: missing textures block" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
+	{
+		llwarns << "Bad Wearable asset: too many textures, "
+				<< num_textures << llendl;
+		return LLWearable::FAILURE;
+	}
+
+	// textures
+	for( i = 0; i < num_textures; i++ )
+	{
+		if (!getNextPopulatedLine(input_stream, buffer, PARSE_BUFFER_SIZE))
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading textures #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		S32 te = 0;
+		if ( 2 != sscanf(   /* Flawfinder: ignore */
+				buffer,
+				"%d %36s\n",
+				&te, uuid_buffer) )
+		{
+				llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
+				return LLWearable::FAILURE;
+		}
+	
+		if( !LLUUID::validate( uuid_buffer ) )
+		{
+				llwarns << "Bad Wearable asset: bad texture uuid: " 
+						<< uuid_buffer << llendl;
+				return LLWearable::FAILURE;
+		}
+		LLUUID id = LLUUID(uuid_buffer);
+		LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );
+		if( mTEMap.find(te) != mTEMap.end() )
+		{
+				delete mTEMap[te];
+		}
+		if( mSavedTEMap.find(te) != mSavedTEMap.end() )
+		{
+				delete mSavedTEMap[te];
+		}
+	
+		LLUUID textureid(uuid_buffer);
+		mTEMap[te] = new LLLocalTextureObject(image, textureid);
+		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
+		createLayers(te, avatarp);
+	}
+
+	// copy all saved param values to working params
+	revertValues();
+
+	return LLWearable::SUCCESS;
+}
+
+BOOL LLWearable::getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size)
+{
+	if (!input_stream.good())
+	{
+		return FALSE;
+	}
+
+	do 
+	{
+		input_stream.getline(buffer, buffer_size);
+	}
+	while (input_stream.good() && buffer[0]=='\0');
+
+	return (buffer[0] != '\0'); 
+}
+
+
+void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp) 
+{ 
+	mType = type; 
+	createVisualParams(avatarp);
+}
+
+
+LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
+{
+	te_map_t::iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
+{
+	te_map_t::const_iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		const LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
+{
+	std::vector<LLLocalTextureObject*> result;
+
+	for(te_map_t::const_iterator iter = mTEMap.begin();
+		iter != mTEMap.end(); iter++)
+	{
+		LLLocalTextureObject* lto = iter->second;
+		result.push_back(lto);
+	}
+
+	return result;
+}
+
+void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
+{
+	if( mTEMap.find(index) != mTEMap.end() )
+	{
+		mTEMap.erase(index);
+	}
+	mTEMap[index] = new LLLocalTextureObject(lto);
+}
+
+void LLWearable::revertValues()
+{
+	// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
+
+	//update saved settings so wearable is no longer dirty
+	// non-driver params first
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	//then driver params
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	// make sure that saved values are sane
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		LLVisualParam *param = getVisualParam(id);
+		if( param )
+		{
+			mSavedVisualParamMap[id] = param->getWeight();
+		}
+	}
+
+	syncImages(mSavedTEMap, mTEMap);
+}
+
+void LLWearable::saveValues()
+{
+	//update saved settings so wearable is no longer dirty
+	mSavedVisualParamMap.clear();
+	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
+	{
+		S32 id = iter->first;
+		LLVisualParam *wearable_param = iter->second;
+		F32 value = wearable_param->getWeight();
+		mSavedVisualParamMap[id] = value;
+	}
+
+	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+	syncImages(mTEMap, mSavedTEMap);
+}
+
+void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
+{
+	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = src.find(te);
+			LLUUID image_id;
+			LLGLTexture *image = NULL;
+			LLLocalTextureObject *lto = NULL;
+			if(iter != src.end())
+			{
+				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
+				lto = iter->second;
+				image = lto->getImage();
+				image_id = lto->getID();
+			}
+			else
+			{
+				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+				image = gTextureManagerBridgep->getFetchedTexture( image_id );
+			}
+
+			if( dst.find(te) != dst.end() )
+			{
+				// there's already an entry in the destination map for the texture. Just update its values.
+				dst[te]->setImage(image);
+				dst[te]->setID(image_id);
+			}
+			else
+			{
+				// no entry found in the destination map, we need to create a new Local Texture Object
+				dst[te] = new LLLocalTextureObject(image, image_id);
+			}
+
+			if( lto )
+			{
+				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
+				dst[te]->setBakedReady(lto->getBakedReady());
+				dst[te]->setDiscard(lto->getDiscard());
+			}
+		}
+	}
+}
+
+void LLWearable::destroyTextures()
+{
+	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mTEMap.clear();
+	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mSavedTEMap.clear();
+}
+
+void LLWearable::addVisualParam(LLVisualParam *param)
+{
+	if( mVisualParamIndexMap[param->getID()] )
+	{
+		delete mVisualParamIndexMap[param->getID()];
+	}
+	param->setIsDummy(FALSE);
+	param->setParamLocation(LOC_WEARABLE);
+	mVisualParamIndexMap[param->getID()] = param;
+	mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
+}
+
+
+void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
+{
+	if( is_in_map(mVisualParamIndexMap, param_index ) )
+	{
+		LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
+		wearable_param->setWeight(value, upload_bake);
+	}
+	else
+	{
+		llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
+	}
+}
+
+F32 LLWearable::getVisualParamWeight(S32 param_index) const
+{
+	if( is_in_map(mVisualParamIndexMap, param_index ) )
+	{
+		const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
+		return wearable_param->getWeight();
+	}
+	else
+	{
+		llwarns << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << llendl;
+	}
+	return (F32)-1.0;
+}
+
+LLVisualParam* LLWearable::getVisualParam(S32 index) const
+{
+	visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
+	return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
+}
+
+
+void LLWearable::getVisualParams(visual_param_vec_t &list)
+{
+	visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+	visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
+
+	// add all visual params to the passed-in vector
+	for( ; iter != end; ++iter )
+	{
+		list.push_back(iter->second);
+	}
+}
+
+void LLWearable::animateParams(F32 delta, BOOL upload_bake)
+{
+	for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
+		 iter != mVisualParamIndexMap.end();
+		 ++iter)
+	{
+		LLVisualParam *param = (LLVisualParam*) iter->second;
+		param->animate(delta, upload_bake);
+	}
+}
+
+LLColor4 LLWearable::getClothesColor(S32 te) const
+{
+	LLColor4 color;
+	U32 param_name[3];
+	if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+	{
+		for( U8 index = 0; index < 3; index++ )
+		{
+			color.mV[index] = getVisualParamWeight(param_name[index]);
+		}
+	}
+	return color;
+}
+
+void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
+{
+	U32 param_name[3];
+	if( LLAvatarAppearance::teToColorParams( (LLAvatarAppearanceDefines::ETextureIndex)te, param_name ) )
+	{
+		for( U8 index = 0; index < 3; index++ )
+		{
+			setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
+		}
+	}
+}
+
+void LLWearable::writeToAvatar(LLAvatarAppearance* avatarp)
+{
+	if (!avatarp) return;
+
+	// Pull params
+	for( LLVisualParam* param = avatarp->getFirstVisualParam(); param; param = avatarp->getNextVisualParam() )
+	{
+		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
+		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
+		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
+		{
+			S32 param_id = param->getID();
+			F32 weight = getVisualParamWeight(param_id);
+
+			avatarp->setVisualParamWeight( param_id, weight, FALSE );
+		}
+	}
+}
+
+
+std::string terse_F32_to_string(F32 f)
+{
+	std::string r = llformat("%.2f", f);
+	S32 len = r.length();
+
+    // "1.20"  -> "1.2"
+    // "24.00" -> "24."
+	while (len > 0 && ('0' == r[len - 1]))
+	{
+		r.erase(len-1, 1);
+		len--;
+	}
+	if ('.' == r[len - 1])
+	{
+		// "24." -> "24"
+		r.erase(len-1, 1);
+	}
+	else if (('-' == r[0]) && ('0' == r[1]))
+	{
+		// "-0.59" -> "-.59"
+		r.erase(1, 1);
+	}
+	else if ('0' == r[0])
+	{
+		// "0.59" -> ".59"
+		r.erase(0, 1);
+	}
+	return r;
+}
+
diff --git a/indra/newview/llwearable.h b/indra/llappearance/llwearable.h
similarity index 68%
rename from indra/newview/llwearable.h
rename to indra/llappearance/llwearable.h
index 3d8c53a755c3a17efe810d10d272b224f0d750f8..6f5a1e14e8ab82ae5e3dec1c1e8b6e24448477a7 100644
--- a/indra/newview/llwearable.h
+++ b/indra/llappearance/llwearable.h
@@ -27,31 +27,25 @@
 #ifndef LL_LLWEARABLE_H
 #define LL_LLWEARABLE_H
 
-#include "lluuid.h"
-#include "llstring.h"
+#include "llavatarappearancedefines.h"
+#include "llextendedstatus.h"
 #include "llpermissions.h"
 #include "llsaleinfo.h"
-#include "llassetstorage.h"
 #include "llwearabletype.h"
-#include "llfile.h"
 #include "lllocaltextureobject.h"
 
-class LLViewerInventoryItem;
+class LLMD5;
 class LLVisualParam;
 class LLTexGlobalColorInfo;
 class LLTexGlobalColor;
+class LLAvatarAppearance;
 
+// Abstract class.
 class LLWearable
 {
-	friend class LLWearableList;
-
 	//--------------------------------------------------------------------
 	// Constructors and destructors
 	//--------------------------------------------------------------------
-private:
-	// Private constructors used by LLWearableList
-	LLWearable(const LLTransactionID& transactionID);
-	LLWearable(const LLAssetID& assetID);
 public:
 	virtual ~LLWearable();
 
@@ -59,11 +53,8 @@ class LLWearable
 	// Accessors
 	//--------------------------------------------------------------------
 public:
-	const LLUUID&				getItemID() const;
-	const LLAssetID&			getAssetID() const { return mAssetID; }
-	const LLTransactionID&		getTransactionID() const { return mTransactionID; }
-	LLWearableType::EType				getType() const	{ return mType; }
-	void						setType(LLWearableType::EType type);
+	LLWearableType::EType		getType() const	{ return mType; }
+	void						setType(LLWearableType::EType type, LLAvatarAppearance *avatarp);
 	const std::string&			getName() const	{ return mName; }
 	void						setName(const std::string& name) { mName = name; }
 	const std::string&			getDescription() const { return mDescription; }
@@ -77,32 +68,26 @@ class LLWearable
 	LLAssetType::EType			getAssetType() const;
 	S32							getDefinitionVersion() const { return mDefinitionVersion; }
 	void						setDefinitionVersion( S32 new_version ) { mDefinitionVersion = new_version; }
+	static S32					getCurrentDefinitionVersion() { return LLWearable::sCurrentDefinitionVersion; }
 
 public:
 	typedef std::vector<LLVisualParam*> visual_param_vec_t;
 
-	BOOL				isDirty() const;
-	BOOL				isOldVersion() const;
-
-	void				writeToAvatar();
-	void				removeFromAvatar( BOOL upload_bake )	{ LLWearable::removeFromAvatar( mType, upload_bake ); }
-	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); 
+	virtual void	writeToAvatar(LLAvatarAppearance* avatarp);
 
+	enum EImportResult
+	{
+		FAILURE = 0,
+		SUCCESS,
+		BAD_HEADER
+	};
 	BOOL				exportFile(LLFILE* file) const;
-	BOOL				importFile(LLFILE* file);
-	
-	void				setParamsToDefaults();
-	void				setTexturesToDefaults();
-
-	void				saveNewAsset() const;
-	static void			onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
-
-	void				copyDataFrom(const LLWearable* src);
+	EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp );
+	virtual BOOL				exportStream( std::ostream& output_stream ) const;
+	virtual EImportResult		importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
 
 	static void			setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
-
-	friend std::ostream& operator<<(std::ostream &s, const LLWearable &w);
-	void				setItemID(const LLUUID& item_id);
+	virtual LLUUID		getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
 
 	LLLocalTextureObject* getLocalTextureObject(S32 index);
 	const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
@@ -110,7 +95,6 @@ class LLWearable
 
 	void				setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
 	void				addVisualParam(LLVisualParam *param);
-	void				setVisualParams();
 	void 				setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
 	F32					getVisualParamWeight(S32 index) const;
 	LLVisualParam*		getVisualParam(S32 index) const;
@@ -120,27 +104,22 @@ class LLWearable
 	LLColor4			getClothesColor(S32 te) const;
 	void 				setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
 
-	void				revertValues();
-	void				saveValues();
-	void				pullCrossWearableValues();		
+	virtual void		revertValues();
+	virtual void		saveValues();
 
-	BOOL				isOnTop() const;
+	// Something happened that requires the wearable to be updated (e.g. worn/unworn).
+	virtual void		setUpdated() const = 0;
 
-	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
-	void				setLabelUpdated() const;
+	// Update the baked texture hash.
+	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0;
 
-	// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
-	// not the wearable asset itself.
-	void				refreshName();
-
-private:
+protected:
 	typedef std::map<S32, LLLocalTextureObject*> te_map_t;
-	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;
-
-	void 				createLayers(S32 te);
-	void 				createVisualParams();
 	void				syncImages(te_map_t &src, te_map_t &dst);
-	void				destroyTextures();	
+	void				destroyTextures();
+	void			 	createVisualParams(LLAvatarAppearance *avatarp);
+	void 				createLayers(S32 te, LLAvatarAppearance *avatarp);
+	BOOL				getNextPopulatedLine(std::istream& input_stream, char* buffer, U32 buffer_size);
 
 	static S32			sCurrentDefinitionVersion;	// Depends on the current state of the avatar_lad.xml.
 	S32					mDefinitionVersion;			// Depends on the state of the avatar_lad.xml when this asset was created.
@@ -148,18 +127,16 @@ class LLWearable
 	std::string			mDescription;
 	LLPermissions		mPermissions;
 	LLSaleInfo			mSaleInfo;
-	LLAssetID mAssetID;
-	LLTransactionID		mTransactionID;
 	LLWearableType::EType		mType;
 
 	typedef std::map<S32, F32> param_map_t;
 	param_map_t mSavedVisualParamMap; // last saved version of visual params
 
+	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;
 	visual_param_index_map_t mVisualParamIndexMap;
 
 	te_map_t mTEMap;				// maps TE to LocalTextureObject
 	te_map_t mSavedTEMap;			// last saved version of TEMap
-	LLUUID				mItemID;  // ID of the inventory item in the agent's inventory	
 };
 
 #endif  // LL_LLWEARABLE_H
diff --git a/indra/llappearance/llwearabledata.cpp b/indra/llappearance/llwearabledata.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..68fdcca78214dc7030de849e35e9280838cbd1c2
--- /dev/null
+++ b/indra/llappearance/llwearabledata.cpp
@@ -0,0 +1,360 @@
+/** 
+ * @file llwearabledata.cpp
+ * @brief LLWearableData class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llwearabledata.h"
+
+#include "llavatarappearance.h"
+#include "llavatarappearancedefines.h"
+#include "lldriverparam.h"
+#include "llmd5.h"
+
+LLWearableData::LLWearableData() :
+	mAvatarAppearance(NULL)
+{
+}
+
+// virtual
+LLWearableData::~LLWearableData()
+{
+}
+
+using namespace LLAvatarAppearanceDefines;
+
+LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return NULL;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		return NULL;
+	}
+	else
+	{
+		return wearable_vec[index];
+	}
+}
+
+void LLWearableData::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+{
+	LLWearable *old_wearable = getWearable(type,index);
+	if (!old_wearable)
+	{
+		pushWearable(type,wearable);
+		return;
+	}
+	
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		llwarns << "invalid type, type " << type << " index " << index << llendl; 
+		return;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		llwarns << "invalid index, type " << type << " index " << index << llendl; 
+	}
+	else
+	{
+		wearable_vec[index] = wearable;
+		old_wearable->setUpdated();
+		const BOOL removed = FALSE;
+		wearableUpdated(wearable, removed);
+	}
+}
+
+U32 LLWearableData::pushWearable(const LLWearableType::EType type, 
+								   LLWearable *wearable,
+								   bool trigger_updated /* = true */)
+{
+	if (wearable == NULL)
+	{
+		// no null wearables please!
+		llwarns << "Null wearable sent for type " << type << llendl;
+		return MAX_CLOTHING_PER_TYPE;
+	}
+	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
+	{
+		mWearableDatas[type].push_back(wearable);
+		if (trigger_updated)
+		{
+			const BOOL removed = FALSE;
+			wearableUpdated(wearable, removed);
+		}
+		return mWearableDatas[type].size()-1;
+	}
+	return MAX_CLOTHING_PER_TYPE;
+}
+
+// virtual
+void LLWearableData::wearableUpdated(LLWearable *wearable, BOOL removed)
+{
+	wearable->setUpdated();
+	// FIXME DRANO avoid updating params via wearables when rendering server-baked appearance.
+#if 0
+	if (mAvatarAppearance->isUsingServerBakes() && !mAvatarAppearance->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+	if (!removed)
+	{
+		pullCrossWearableValues(wearable->getType());
+	}
+}
+
+void LLWearableData::popWearable(LLWearable *wearable)
+{
+	if (wearable == NULL)
+	{
+		// nothing to do here. move along.
+		return;
+	}
+
+	U32 index = getWearableIndex(wearable);
+	const LLWearableType::EType type = wearable->getType();
+
+	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+	{
+		popWearable(type, index);
+	}
+}
+
+void LLWearableData::popWearable(const LLWearableType::EType type, U32 index)
+{
+	LLWearable *wearable = getWearable(type, index);
+	if (wearable)
+	{
+		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
+		const BOOL removed = TRUE;
+		wearableUpdated(wearable, removed);
+	}
+}
+
+void LLWearableData::clearWearableType(const LLWearableType::EType type)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return;
+	}
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	wearable_vec.clear();
+}
+
+bool LLWearableData::swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b)
+{
+	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return false;
+	}
+
+	wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (0 > index_a || index_a >= wearable_vec.size()) return false;
+	if (0 > index_b || index_b >= wearable_vec.size()) return false;
+
+	LLWearable* wearable = wearable_vec[index_a];
+	wearable_vec[index_a] = wearable_vec[index_b];
+	wearable_vec[index_b] = wearable;
+	return true;
+}
+
+void LLWearableData::pullCrossWearableValues(const LLWearableType::EType type)
+{
+	llassert(mAvatarAppearance);
+	// scan through all of the avatar's visual parameters
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) mAvatarAppearance->getFirstVisualParam(); 
+		 param;
+		 param = (LLViewerVisualParam*) mAvatarAppearance->getNextVisualParam())
+	{
+		if( param )
+		{
+			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
+			if(driver_param)
+			{
+				// parameter is a driver parameter, have it update its cross-driven params
+				driver_param->updateCrossDrivenParams(type);
+			}
+		}
+	}
+}
+
+
+U32	LLWearableData::getWearableIndex(const LLWearable *wearable) const
+{
+	if (wearable == NULL)
+	{
+		return MAX_CLOTHING_PER_TYPE;
+	}
+
+	const LLWearableType::EType type = wearable->getType();
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		llwarns << "tried to get wearable index with an invalid type!" << llendl;
+		return MAX_CLOTHING_PER_TYPE;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	for(U32 index = 0; index < wearable_vec.size(); index++)
+	{
+		if (wearable_vec[index] == wearable)
+		{
+			return index;
+		}
+	}
+
+	return MAX_CLOTHING_PER_TYPE;
+}
+
+BOOL LLWearableData::isOnTop(LLWearable* wearable) const
+{
+	if (!wearable) return FALSE;
+	const LLWearableType::EType type = wearable->getType();
+	return ( getTopWearable(type) == wearable );
+}
+
+const LLWearable* LLWearableData::getWearable(const LLWearableType::EType type, U32 index) const
+{
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return NULL;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	if (index>=wearable_vec.size())
+	{
+		return NULL;
+	}
+	else
+	{
+		return wearable_vec[index];
+	}
+}
+
+LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type)
+{
+	U32 count = getWearableCount(type);
+	if ( count == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, count-1);
+}
+
+const LLWearable* LLWearableData::getTopWearable(const LLWearableType::EType type) const
+{
+	U32 count = getWearableCount(type);
+	if ( count == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, count-1);
+}
+
+LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type)
+{
+	if (getWearableCount(type) == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, 0);
+}
+
+const LLWearable* LLWearableData::getBottomWearable(const LLWearableType::EType type) const
+{
+	if (getWearableCount(type) == 0)
+	{
+		return NULL;
+	}
+
+	return getWearable(type, 0);
+}
+
+U32 LLWearableData::getWearableCount(const LLWearableType::EType type) const
+{
+	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
+	if (wearable_iter == mWearableDatas.end())
+	{
+		return 0;
+	}
+	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
+	return wearable_vec.size();
+}
+
+U32 LLWearableData::getWearableCount(const U32 tex_index) const
+{
+	const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((LLAvatarAppearanceDefines::ETextureIndex)tex_index);
+	return getWearableCount(wearable_type);
+}
+
+LLUUID LLWearableData::computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+{
+	LLUUID hash_id;
+	bool hash_computed = false;
+	LLMD5 hash;
+	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
+
+	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
+	{
+		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
+		const U32 num_wearables = getWearableCount(baked_type);
+		for (U32 index = 0; index < num_wearables; ++index)
+		{
+			const LLWearable* wearable = getWearable(baked_type,index);
+			if (wearable)
+			{
+				wearable->addToBakedTextureHash(hash);
+				hash_computed = true;
+			}
+		}
+	}
+	if (hash_computed)
+	{
+		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
+
+		if (!generate_valid_hash)
+		{
+			invalidateBakedTextureHash(hash);
+		}
+		hash.finalize();
+		hash.raw_digest(hash_id.mData);
+	}
+
+	return hash_id;
+}
+
+
diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h
new file mode 100644
index 0000000000000000000000000000000000000000..03bd179f258812a1fdac747fd5404f41f7d2cd2a
--- /dev/null
+++ b/indra/llappearance/llwearabledata.h
@@ -0,0 +1,109 @@
+/** 
+ * @file llwearabledata.h
+ * @brief LLWearableData class header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_WEARABLEDATA_H
+#define LL_WEARABLEDATA_H
+
+#include "llavatarappearancedefines.h"
+#include "llwearable.h"
+#include "llerror.h"
+
+class LLAvatarAppearance;
+
+class LLWearableData
+{
+	// *TODO: Figure out why this is causing compile error.
+	//LOG_CLASS(LLWearableData);
+
+	//--------------------------------------------------------------------
+	// Constructors / destructors / Initializers
+	//--------------------------------------------------------------------
+public:
+	LLWearableData();
+	virtual ~LLWearableData();
+
+	void setAvatarAppearance(LLAvatarAppearance* appearance) { mAvatarAppearance = appearance; }
+
+protected:
+	//--------------------------------------------------------------------
+	// Accessors
+	//--------------------------------------------------------------------
+public:
+	LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
+	const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
+	LLWearable*			getTopWearable(const LLWearableType::EType type);
+	const LLWearable*	getTopWearable(const LLWearableType::EType type) const;
+	LLWearable*			getBottomWearable(const LLWearableType::EType type);
+	const LLWearable*	getBottomWearable(const LLWearableType::EType type) const;
+	U32				getWearableCount(const LLWearableType::EType type) const;
+	U32				getWearableCount(const U32 tex_index) const;
+	U32				getWearableIndex(const LLWearable *wearable) const;
+
+	BOOL			isOnTop(LLWearable* wearable) const;
+
+	static const U32 MAX_CLOTHING_PER_TYPE = 5; 
+
+	//--------------------------------------------------------------------
+	// Setters
+	//--------------------------------------------------------------------
+protected:
+	// Low-level data structure setter - public access is via setWearableItem, etc.
+	void 			setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
+	U32 			pushWearable(const LLWearableType::EType type, LLWearable *wearable, 
+								 bool trigger_updated = true);
+	virtual void	wearableUpdated(LLWearable *wearable, BOOL removed);
+	void 			popWearable(LLWearable *wearable);
+	void			popWearable(const LLWearableType::EType type, U32 index);
+	void			clearWearableType(const LLWearableType::EType type);
+	bool			swapWearables(const LLWearableType::EType type, U32 index_a, U32 index_b);
+
+private:
+	void			pullCrossWearableValues(const LLWearableType::EType type);
+
+	//--------------------------------------------------------------------
+	// Server Communication
+	//--------------------------------------------------------------------
+public:
+	LLUUID			computeBakedTextureHash(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index,
+											BOOL generate_valid_hash = TRUE);
+protected:
+	virtual void	invalidateBakedTextureHash(LLMD5& hash) const {}
+
+	//--------------------------------------------------------------------
+	// Member variables
+	//--------------------------------------------------------------------
+protected:
+	LLAvatarAppearance* mAvatarAppearance;
+	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
+	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type
+	wearableentry_map_t mWearableDatas;
+
+};
+
+
+
+#endif // LL_WEARABLEDATA_H
+
diff --git a/indra/newview/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
similarity index 83%
rename from indra/newview/llwearabletype.cpp
rename to indra/llappearance/llwearabletype.cpp
index c090ab5c3dedeef17ec052b3c85eb810a54204f6..618e2a1941bc8768765a0d91c61159bf87fd0e02 100644
--- a/indra/newview/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -24,23 +24,35 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 #include "llwearabletype.h"
-#include "llinventoryfunctions.h"
-#include "lltrans.h"
+#include "llinventorytype.h"
+
+static LLTranslationBridge* sTrans = NULL;
+
+// static
+void LLWearableType::initClass(LLTranslationBridge* trans)
+{
+	sTrans = trans;
+}
+
+void LLWearableType::cleanupClass()
+{
+	delete sTrans;
+}
 
 struct WearableEntry : public LLDictionaryEntry
 {
 	WearableEntry(const std::string &name,
 				  const std::string& default_new_name,
 				  LLAssetType::EType assetType,
-				  LLInventoryIcon::EIconName iconName,
+				  LLInventoryType::EIconName iconName,
 				  BOOL disable_camera_switch = FALSE,
 				  BOOL allow_multiwear = TRUE) :
 		LLDictionaryEntry(name),
 		mAssetType(assetType),
 		mDefaultNewName(default_new_name),
-		mLabel(LLTrans::getString(name)),
+		mLabel(sTrans->getString(name)),
 		mIconName(iconName),
 		mDisableCameraSwitch(disable_camera_switch),
 		mAllowMultiwear(allow_multiwear)
@@ -50,7 +62,7 @@ struct WearableEntry : public LLDictionaryEntry
 	const LLAssetType::EType mAssetType;
 	const std::string mLabel;
 	const std::string mDefaultNewName; //keep mLabel for backward compatibility
-	LLInventoryIcon::EIconName mIconName;
+	LLInventoryType::EIconName mIconName;
 	BOOL mDisableCameraSwitch;
 	BOOL mAllowMultiwear;
 };
@@ -64,26 +76,26 @@ class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
 
 LLWearableDictionary::LLWearableDictionary()
 {
-	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
-	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
-	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryIcon::ICONNAME_BODYPART_EYES, FALSE, FALSE));
-	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
-	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
-	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
-	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
-	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
-
-	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
-
-	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
-	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryIcon::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SHAPE,        new WearableEntry("shape",       "New Shape",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SHAPE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SKIN,         new WearableEntry("skin",        "New Skin",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_SKIN, FALSE, FALSE));
+	addEntry(LLWearableType::WT_HAIR,         new WearableEntry("hair",        "New Hair",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_HAIR, FALSE, FALSE));
+	addEntry(LLWearableType::WT_EYES,         new WearableEntry("eyes",        "New Eyes",			LLAssetType::AT_BODYPART, 	LLInventoryType::ICONNAME_BODYPART_EYES, FALSE, FALSE));
+	addEntry(LLWearableType::WT_SHIRT,        new WearableEntry("shirt",       "New Shirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_PANTS,        new WearableEntry("pants",       "New Pants",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SHOES,        new WearableEntry("shoes",       "New Shoes",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SHOES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SOCKS,        new WearableEntry("socks",       "New Socks",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SOCKS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_JACKET,       new WearableEntry("jacket",      "New Jacket",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_JACKET, FALSE, TRUE));
+	addEntry(LLWearableType::WT_GLOVES,       new WearableEntry("gloves",      "New Gloves",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_GLOVES, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERSHIRT,   new WearableEntry("undershirt",  "New Undershirt",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_UNDERPANTS,   new WearableEntry("underpants",  "New Underpants",	LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, FALSE, TRUE));
+	addEntry(LLWearableType::WT_SKIRT,        new WearableEntry("skirt",       "New Skirt",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_SKIRT, FALSE, TRUE));
+	addEntry(LLWearableType::WT_ALPHA,        new WearableEntry("alpha",       "New Alpha",			LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_ALPHA, FALSE, TRUE));
+	addEntry(LLWearableType::WT_TATTOO,       new WearableEntry("tattoo",      "New Tattoo",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_TATTOO, FALSE, TRUE));
+
+	addEntry(LLWearableType::WT_PHYSICS,      new WearableEntry("physics",     "New Physics",		LLAssetType::AT_CLOTHING, 	LLInventoryType::ICONNAME_CLOTHING_PHYSICS, TRUE, TRUE));
+
+	addEntry(LLWearableType::WT_INVALID,      new WearableEntry("invalid",     "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
+	addEntry(LLWearableType::WT_NONE,      	  new WearableEntry("none",        "Invalid Wearable", 	LLAssetType::AT_NONE, 		LLInventoryType::ICONNAME_NONE, FALSE, FALSE));
 }
 
 // static
@@ -131,7 +143,7 @@ LLAssetType::EType LLWearableType::getAssetType(LLWearableType::EType type)
 }
 
 // static 
-LLInventoryIcon::EIconName LLWearableType::getIconName(LLWearableType::EType type)
+LLInventoryType::EIconName LLWearableType::getIconName(LLWearableType::EType type)
 {
 	const LLWearableDictionary *dict = LLWearableDictionary::getInstance();
 	const WearableEntry *entry = dict->lookup(type);
diff --git a/indra/newview/llwearabletype.h b/indra/llappearance/llwearabletype.h
similarity index 85%
rename from indra/newview/llwearabletype.h
rename to indra/llappearance/llwearabletype.h
index d633b4807ece113c630fca0250318a5d86a338fe..e51e6731d38880e82896fd9b4d8c3da4f3650e37 100644
--- a/indra/newview/llwearabletype.h
+++ b/indra/llappearance/llwearabletype.h
@@ -29,9 +29,16 @@
 
 #include "llassettype.h"
 #include "lldictionary.h"
-#include "llinventoryicon.h"
+#include "llinventorytype.h"
 #include "llsingleton.h"
 
+class LLTranslationBridge
+{
+public:
+	virtual std::string getString(const std::string &xml_desc) = 0;
+};
+
+
 class LLWearableType
 {
 public: 
@@ -59,12 +66,15 @@ class LLWearableType
 		WT_NONE		  = -1,
 	};
 
+	static void			initClass(LLTranslationBridge* trans); // initializes static members
+	static void			cleanupClass(); // initializes static members
+
 	static const std::string& 			getTypeName(EType type);
 	static const std::string& 			getTypeDefaultNewName(EType type);
 	static const std::string& 			getTypeLabel(EType type);
 	static LLAssetType::EType 			getAssetType(EType type);
 	static EType 						typeNameToType(const std::string& type_name);
-	static LLInventoryIcon::EIconName 	getIconName(EType type);
+	static LLInventoryType::EIconName 	getIconName(EType type);
 	static BOOL 						getDisableCameraSwitch(EType type);
 	static BOOL 						getAllowMultiwear(EType type);
 
diff --git a/indra/llaudio/CMakeLists.txt b/indra/llaudio/CMakeLists.txt
index f27bcb27d1cafbe2a139557d63d0435854455319..1b2bdb9888c7005beb56ef4f220c049cf2b892dc 100644
--- a/indra/llaudio/CMakeLists.txt
+++ b/indra/llaudio/CMakeLists.txt
@@ -80,6 +80,10 @@ list(APPEND llaudio_SOURCE_FILES ${llaudio_HEADER_FILES})
 add_library (llaudio ${llaudio_SOURCE_FILES})
 target_link_libraries(
     llaudio
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLVFS_LIBRARIES}
     ${VORBISENC_LIBRARIES}
     ${VORBISFILE_LIBRARIES}
     ${VORBIS_LIBRARIES}
diff --git a/indra/llaudio/llaudioengine.cpp b/indra/llaudio/llaudioengine.cpp
index ef560cd7fcaf2198027417efc4e21ba06f1a90c2..06e752cf340494ad5c490b5b9ce61bbf5c6edc2b 100644
--- a/indra/llaudio/llaudioengine.cpp
+++ b/indra/llaudio/llaudioengine.cpp
@@ -839,6 +839,10 @@ void LLAudioEngine::triggerSound(const LLUUID &audio_uuid, const LLUUID& owner_i
 	asp->play(audio_uuid);
 }
 
+void LLAudioEngine::triggerSound(SoundData& soundData)
+{
+	triggerSound(soundData.audio_uuid, soundData.owner_id, soundData.gain, soundData.type, soundData.pos_global);
+}
 
 void LLAudioEngine::setListenerPos(LLVector3 aVec)
 {
diff --git a/indra/llaudio/llaudioengine.h b/indra/llaudio/llaudioengine.h
index dbaba0fb91acb15a510efc21f284b87680ec514b..da1629a1db57a7c1fda86305a06e6ced52e90898 100644
--- a/indra/llaudio/llaudioengine.h
+++ b/indra/llaudio/llaudioengine.h
@@ -65,6 +65,7 @@ class LLAudioChannel;
 class LLAudioChannelOpenAL;
 class LLAudioBuffer;
 class LLStreamingAudioInterface;
+struct SoundData;
 
 
 //
@@ -143,6 +144,8 @@ class LLAudioEngine
 	void triggerSound(const LLUUID &sound_id, const LLUUID& owner_id, const F32 gain,
 					  const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
 					  const LLVector3d &pos_global = LLVector3d::zero);
+	void triggerSound(SoundData& soundData);
+
 	bool preloadSound(const LLUUID &id);
 
 	void addAudioSource(LLAudioSource *asp);
@@ -455,6 +458,27 @@ class LLAudioBuffer
 	LLFrameTimer mLastUseTimer;
 };
 
+struct SoundData
+{
+	LLUUID audio_uuid;
+	LLUUID owner_id;
+	F32 gain;
+	S32 type;
+	LLVector3d pos_global;
+
+	SoundData(const LLUUID &audio_uuid, 
+		const LLUUID& owner_id, 
+		const F32 gain, 					  
+		const S32 type = LLAudioEngine::AUDIO_TYPE_NONE,
+		const LLVector3d &pos_global = LLVector3d::zero)
+	{
+		this->audio_uuid = audio_uuid;
+		this->owner_id = owner_id;
+		this->gain = gain;
+		this->type = type;
+		this->pos_global = pos_global;
+	}
+};
 
 
 extern LLAudioEngine* gAudiop;
diff --git a/indra/llcharacter/CMakeLists.txt b/indra/llcharacter/CMakeLists.txt
index a1712699eb25266c863aeb6234336bbb983b58d5..2573417b260536371d7a93c87e459514b597db37 100644
--- a/indra/llcharacter/CMakeLists.txt
+++ b/indra/llcharacter/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llcharacter_SOURCE_FILES
     llanimationstates.cpp
@@ -76,6 +80,15 @@ list(APPEND llcharacter_SOURCE_FILES ${llcharacter_HEADER_FILES})
 
 add_library (llcharacter ${llcharacter_SOURCE_FILES})
 
+target_link_libraries(
+    llcharacter
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    )
+
 
 # Add tests
 if (LL_TESTS)
diff --git a/indra/llcharacter/llanimationstates.cpp b/indra/llcharacter/llanimationstates.cpp
index 155226cf17955705b0d838f23c489f33b4cf4806..c16cae1bbc7237eec62fcf9aaa1fded4489e71ba 100644
--- a/indra/llcharacter/llanimationstates.cpp
+++ b/indra/llcharacter/llanimationstates.cpp
@@ -46,7 +46,7 @@ LLUUID const ANIM_AGENT_BLOW_KISS             ("db84829b-462c-ee83-1e27-9bbee66b
 LLUUID const ANIM_AGENT_BORED                 ("b906c4ba-703b-1940-32a3-0c7f7d791510");
 LLUUID const ANIM_AGENT_BOW                   ("82e99230-c906-1403-4d9c-3889dd98daba");
 LLUUID const ANIM_AGENT_BRUSH                 ("349a3801-54f9-bf2c-3bd0-1ac89772af01");
-LLUUID const ANIM_AGENT_BUSY                  ("efcf670c-2d18-8128-973a-034ebc806b67");
+LLUUID const ANIM_AGENT_DO_NOT_DISTURB        ("efcf670c-2d18-8128-973a-034ebc806b67");
 LLUUID const ANIM_AGENT_CLAP                  ("9b0c1c4e-8ac7-7969-1494-28c874c4f668");
 LLUUID const ANIM_AGENT_COURTBOW              ("9ba1c942-08be-e43a-fb29-16ad440efc50");
 LLUUID const ANIM_AGENT_CROUCH                ("201f3fdf-cb1f-dbec-201f-7333e328ae7c");
@@ -211,7 +211,7 @@ LLAnimationLibrary::LLAnimationLibrary() :
 	mAnimMap[ANIM_AGENT_BORED]=				mAnimStringTable.addString("express_bored");
 	mAnimMap[ANIM_AGENT_BOW]=				mAnimStringTable.addString("bow");
 	mAnimMap[ANIM_AGENT_BRUSH]=				mAnimStringTable.addString("brush");
-	mAnimMap[ANIM_AGENT_BUSY]=				mAnimStringTable.addString("busy");
+	mAnimMap[ANIM_AGENT_DO_NOT_DISTURB]=	mAnimStringTable.addString("busy");
 	mAnimMap[ANIM_AGENT_CLAP]=				mAnimStringTable.addString("clap");
 	mAnimMap[ANIM_AGENT_COURTBOW]=			mAnimStringTable.addString("courtbow");
 	mAnimMap[ANIM_AGENT_CROUCH]=			mAnimStringTable.addString("crouch");
diff --git a/indra/llcharacter/llanimationstates.h b/indra/llcharacter/llanimationstates.h
index aa6579ac8e17e6c3b683ee31f4bd7861ef342b1c..84185c3f92c8b27a17ac411afb18a874b3050b2f 100644
--- a/indra/llcharacter/llanimationstates.h
+++ b/indra/llcharacter/llanimationstates.h
@@ -56,7 +56,7 @@ extern const LLUUID ANIM_AGENT_BLOW_KISS;
 extern const LLUUID ANIM_AGENT_BORED;
 extern const LLUUID ANIM_AGENT_BOW;
 extern const LLUUID ANIM_AGENT_BRUSH;
-extern const LLUUID ANIM_AGENT_BUSY;
+extern const LLUUID ANIM_AGENT_DO_NOT_DISTURB;
 extern const LLUUID ANIM_AGENT_CLAP;
 extern const LLUUID ANIM_AGENT_COURTBOW;
 extern const LLUUID ANIM_AGENT_CROUCH;
diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 0a6a8f9fa6b4a095d404085ed4900264c0aa32d1..85cf1cd3f5eac08db7e89efd7d25d90fe313a227 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -286,7 +286,7 @@ void LLCharacter::removeAnimationData(std::string name)
 //-----------------------------------------------------------------------------
 // setVisualParamWeight()
 //-----------------------------------------------------------------------------
-BOOL LLCharacter::setVisualParamWeight(LLVisualParam* which_param, F32 weight, BOOL upload_bake)
+BOOL LLCharacter::setVisualParamWeight(const LLVisualParam* which_param, F32 weight, BOOL upload_bake)
 {
 	S32 index = which_param->getID();
 	visual_param_index_map_t::iterator index_iter = mVisualParamIndexMap.find(index);
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 3ebb2bffb04ec47b8b5a44d856fbd03f0b2452a4..5740dbce77274089b2a4a0d60ea9c6b8c57c50bd 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -93,13 +93,6 @@ class LLCharacter
 	// get the height & normal of the ground under a point
 	virtual void getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm) = 0;
 
-	// allocate an array of joints for the character skeleton
-	// this must be overloaded to support joint subclasses,
-	// and is called implicitly from buildSkeleton().
-	// Note this must handle reallocation as it will be called
-	// each time buildSkeleton() is called.
-	virtual BOOL allocateCharacterJoints( U32 num ) = 0;
-
 	// skeleton joint accessor to support joint subclasses
 	virtual LLJoint *getCharacterJoint( U32 i ) = 0;
 
@@ -197,7 +190,7 @@ class LLCharacter
 	void addVisualParam(LLVisualParam *param);
 	void addSharedVisualParam(LLVisualParam *param);
 
-	virtual BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+	virtual BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
 	virtual BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
 	virtual BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
 
diff --git a/indra/llcharacter/lljoint.cpp b/indra/llcharacter/lljoint.cpp
index 19907933cb4c5cab89f20eb329be4f262351182e..09a7c11a22d972a007c22407aac3a2802463a3eb 100644
--- a/indra/llcharacter/lljoint.cpp
+++ b/indra/llcharacter/lljoint.cpp
@@ -40,7 +40,9 @@ S32 LLJoint::sNumTouches = 0;
 // LLJoint()
 // Class Constructor
 //-----------------------------------------------------------------------------
-LLJoint::LLJoint()
+
+
+void LLJoint::init()
 {
 	mName = "unnamed";
 	mParent = NULL;
@@ -48,7 +50,20 @@ LLJoint::LLJoint()
 	mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
 	mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
 	mUpdateXform = TRUE;
-	mJointNum = -1;
+}
+
+LLJoint::LLJoint() :
+	mJointNum(-1)
+{
+	init();
+	touch();
+	mResetAfterRestoreOldXform = false;
+}
+
+LLJoint::LLJoint(S32 joint_num) :
+	mJointNum(joint_num)
+{
+	init();
 	touch();
 	mResetAfterRestoreOldXform = false;
 }
@@ -58,15 +73,12 @@ LLJoint::LLJoint()
 // LLJoint()
 // Class Constructor
 //-----------------------------------------------------------------------------
-LLJoint::LLJoint(const std::string &name, LLJoint *parent)
+LLJoint::LLJoint(const std::string &name, LLJoint *parent) :
+	mJointNum(0)
 {
-	mName = "unnamed";
-	mParent = NULL;
-	mXform.setScaleChildOffset(TRUE);
-	mXform.setScale(LLVector3(1.0f, 1.0f, 1.0f));
-	mDirtyFlags = MATRIX_DIRTY | ROTATION_DIRTY | POSITION_DIRTY;
+	init();
 	mUpdateXform = FALSE;
-	mJointNum = 0;
+	// *TODO: mResetAfterRestoreOldXform is not initialized!!!
 
 	setName(name);
 	if (parent)
diff --git a/indra/llcharacter/lljoint.h b/indra/llcharacter/lljoint.h
index dc3c58cf645204c6667dfe62d403ba41e4a0c8b3..2b1e2005c62022910497ea8bbd8dbbd6ce7f8c31 100644
--- a/indra/llcharacter/lljoint.h
+++ b/indra/llcharacter/lljoint.h
@@ -105,10 +105,15 @@ class LLJoint
 
 public:
 	LLJoint();
+	LLJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
 	LLJoint( const std::string &name, LLJoint *parent=NULL );
-
 	virtual ~LLJoint();
 
+private:
+	void init();
+
+public:
 	// set name and parent
 	void setup( const std::string &name, LLJoint *parent=NULL );
 
@@ -178,7 +183,6 @@ class LLJoint
 	virtual BOOL isAnimatable() const { return TRUE; }
 
 	S32 getJointNum() const { return mJointNum; }
-	void setJointNum(S32 joint_num) { mJointNum = joint_num; }
 	
 	void restoreOldXform( void );
 	void restoreToDefaultXform( void );
diff --git a/indra/llcharacter/llvisualparam.cpp b/indra/llcharacter/llvisualparam.cpp
index 809b312abe29241a0c7b1153a57792f8d234d5c2..f7cb0f76b717f9a83b42d91d96b64219b527a9ff 100644
--- a/indra/llcharacter/llvisualparam.cpp
+++ b/indra/llcharacter/llvisualparam.cpp
@@ -168,7 +168,8 @@ LLVisualParam::LLVisualParam()
 	mIsAnimating( FALSE ),
 	mID( -1 ),
 	mInfo( 0 ),
-	mIsDummy(FALSE)
+	mIsDummy(FALSE),
+	mParamLocation(LOC_UNKNOWN)
 {
 }
 
@@ -250,6 +251,7 @@ void LLVisualParam::setAnimationTarget(F32 target_value, BOOL upload_bake)
 	if (mIsDummy)
 	{
 		setWeight(target_value, upload_bake);
+		mTargetWeight = mCurWeight;
 		return;
 	}
 
@@ -319,3 +321,32 @@ void LLVisualParam::resetDrivenParams()
 	// nothing to do for non-driver parameters
 	return;
 }
+
+const std::string param_location_name(const EParamLocation& loc)
+{
+	switch (loc)
+	{
+		case LOC_UNKNOWN: return "unknown";
+		case LOC_AV_SELF: return "self";
+		case LOC_AV_OTHER: return "other";
+		case LOC_WEARABLE: return "wearable";
+		default: return "error";
+	}
+}
+
+void LLVisualParam::setParamLocation(EParamLocation loc)
+{
+	if (mParamLocation == LOC_UNKNOWN || loc == LOC_UNKNOWN)
+	{
+		mParamLocation = loc;
+	}
+	else if (mParamLocation == loc)
+	{
+		// no action
+	}
+	else
+	{
+		lldebugs << "param location is already " << mParamLocation << ", not slamming to " << loc << llendl;
+	}
+}
+
diff --git a/indra/llcharacter/llvisualparam.h b/indra/llcharacter/llvisualparam.h
index 281fb147810203bcb09f412bc5c3d23501c3056e..60ea7a369a8aecfc6c0a1c96a9d8b32c33b7eec7 100644
--- a/indra/llcharacter/llvisualparam.h
+++ b/indra/llcharacter/llvisualparam.h
@@ -50,6 +50,16 @@ enum EVisualParamGroup
 	NUM_VISUAL_PARAM_GROUPS
 };
 
+enum EParamLocation
+{
+	LOC_UNKNOWN,
+	LOC_AV_SELF,
+	LOC_AV_OTHER,
+	LOC_WEARABLE
+};
+
+const std::string param_location_name(const EParamLocation& loc);
+
 const S32 MAX_TRANSMITTED_VISUAL_PARAMS = 255;
 
 //-----------------------------------------------------------------------------
@@ -150,6 +160,9 @@ class LLVisualParam
 
 	void					setIsDummy(BOOL is_dummy) { mIsDummy = is_dummy; }
 
+	void					setParamLocation(EParamLocation loc);
+	EParamLocation			getParamLocation() const { return mParamLocation; }
+
 protected:
 	F32					mCurWeight;			// current weight
 	F32					mLastWeight;		// last weight
@@ -161,6 +174,7 @@ class LLVisualParam
 
 	S32					mID;				// id for storing weight/morphtarget compares compactly
 	LLVisualParamInfo	*mInfo;
+	EParamLocation		mParamLocation;		// where does this visual param live?
 } LL_ALIGN_POSTFIX(16);
 
 #endif // LL_LLVisualParam_H
diff --git a/indra/llcharacter/tests/lljoint_test.cpp b/indra/llcharacter/tests/lljoint_test.cpp
index e92aa832d66f820c46524920d3b1db27b6919432..da151808f21c660f6e57c922d848af356f4889c8 100644
--- a/indra/llcharacter/tests/lljoint_test.cpp
+++ b/indra/llcharacter/tests/lljoint_test.cpp
@@ -150,11 +150,11 @@ namespace tut
 	template<> template<>
 	void lljoint_object::test<11>()
 	{
-		LLJoint lljoint("parent");
 		S32 joint_num = 12;
-		lljoint.setJointNum(joint_num);
+		LLJoint lljoint(joint_num);
+		lljoint.setName("parent");
 		S32 jointNum = 	lljoint.getJointNum();
-		ensure("setJointNum()/getJointNum failed ", (jointNum == joint_num));
+		ensure("getJointNum failed ", (jointNum == joint_num));
 	}
 
 	template<> template<>
diff --git a/indra/llcommon/imageids.cpp b/indra/llcommon/imageids.cpp
index fe11465221075cd82ee66ae9cee50a46f1944665..7d647e5c364f4dae5a76bc817c50e2f1c48d699c 100644
--- a/indra/llcommon/imageids.cpp
+++ b/indra/llcommon/imageids.cpp
@@ -68,3 +68,6 @@ const LLUUID TERRAIN_MOUNTAIN_DETAIL	("303cd381-8560-7579-23f1-f0a880799740"); /
 const LLUUID TERRAIN_ROCK_DETAIL		("53a2f406-4895-1d13-d541-d2e3b86bc19c"); // VIEWER
 
 const LLUUID DEFAULT_WATER_NORMAL		("822ded49-9a6c-f61c-cb89-6df54f42cdf4"); // VIEWER
+
+const LLUUID IMG_CHECKERBOARD_RGBA     ("2585a0f3-4163-6dd1-0f34-ad48cb909e25"); // dataserver
+
diff --git a/indra/llcommon/imageids.h b/indra/llcommon/imageids.h
index e0c2683fdc33542a896a95559d5dafa10ad7c42c..18c8ecb0743765b06857558504cdd1bb16722376 100644
--- a/indra/llcommon/imageids.h
+++ b/indra/llcommon/imageids.h
@@ -66,4 +66,5 @@ LL_COMMON_API extern const LLUUID TERRAIN_ROCK_DETAIL;
 
 LL_COMMON_API extern const LLUUID DEFAULT_WATER_NORMAL;
 
+LL_COMMON_API extern const LLUUID IMG_CHECKERBOARD_RGBA;
 #endif
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5e566d6c7cf810e227ee0a1da6e378c4afb2f4a0..5ae2df39945b6b2517fae061c6895a578c0a8b65 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -95,6 +95,7 @@ LLAssetDictionary::LLAssetDictionary()
 	addEntry(LLAssetType::AT_LINK_FOLDER, 		new AssetEntry("FOLDER_LINK",		"link_f", 	"sym folder link",	false,		false,		true));
 	addEntry(LLAssetType::AT_MESH,              new AssetEntry("MESH",              "mesh",     "mesh",             false,      false,      false));
 	addEntry(LLAssetType::AT_WIDGET,            new AssetEntry("WIDGET",            "widget",   "widget",           false,      false,      false));
+	addEntry(LLAssetType::AT_PERSON,            new AssetEntry("PERSON",            "person",   "person",           false,      false,      false));
 	addEntry(LLAssetType::AT_NONE, 				new AssetEntry("NONE",				"-1",		NULL,		  		FALSE,		FALSE,		FALSE));
 
 };
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index d538accbf7289472d26965147c5879351498194a..69b01731e5dc2ed76d764a441764b0ec38448a11 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -112,6 +112,9 @@ class LL_COMMON_API LLAssetType
 		AT_WIDGET = 40,
 			// UI Widget: this is *not* an inventory asset type, only a viewer side asset (e.g. button, other ui items...)
 		
+		AT_PERSON = 45,
+			// A user uuid  which is not an inventory asset type, used in viewer only for adding a person to a chat via drag and drop.
+
 		AT_MESH = 49,
 			// Mesh data in our proprietary SLM format
 		
diff --git a/indra/llcommon/llavatarname.cpp b/indra/llcommon/llavatarname.cpp
index 3206843bf4a95e76f875d7e8b9f8c95dfd7d2f25..642bd82e90947978b33eacbe8eb884d330f8b14c 100644
--- a/indra/llcommon/llavatarname.cpp
+++ b/indra/llcommon/llavatarname.cpp
@@ -30,6 +30,7 @@
 #include "llavatarname.h"
 
 #include "lldate.h"
+#include "llframetimer.h"
 #include "llsd.h"
 
 // Store these in pre-built std::strings to avoid memory allocations in
@@ -42,6 +43,14 @@ static const std::string IS_DISPLAY_NAME_DEFAULT("is_display_name_default");
 static const std::string DISPLAY_NAME_EXPIRES("display_name_expires");
 static const std::string DISPLAY_NAME_NEXT_UPDATE("display_name_next_update");
 
+bool LLAvatarName::sUseDisplayNames = true;
+
+// Minimum time-to-live (in seconds) for a name entry.
+// Avatar name should always guarantee to expire reasonably soon by default
+// so if the failure to get a valid expiration time was due to something temporary 
+// we will eventually request and get the right data.
+const F64 MIN_ENTRY_LIFETIME = 60.0;
+
 LLAvatarName::LLAvatarName()
 :	mUsername(),
 	mDisplayName(),
@@ -61,6 +70,17 @@ bool LLAvatarName::operator<(const LLAvatarName& rhs) const
 		return mUsername < rhs.mUsername;
 }
 
+//static 
+void LLAvatarName::setUseDisplayNames(bool use)
+{
+	sUseDisplayNames = use;
+}
+//static 
+bool LLAvatarName::useDisplayNames() 
+{ 
+	return sUseDisplayNames; 
+}
+
 LLSD LLAvatarName::asLLSD() const
 {
 	LLSD sd;
@@ -85,21 +105,75 @@ void LLAvatarName::fromLLSD(const LLSD& sd)
 	mExpires = expires.secondsSinceEpoch();
 	LLDate next_update = sd[DISPLAY_NAME_NEXT_UPDATE];
 	mNextUpdate = next_update.secondsSinceEpoch();
+	
+	// Some avatars don't have explicit display names set. Force a legible display name here.
+	if (mDisplayName.empty())
+	{
+		mDisplayName = mUsername;
+	}
+}
+
+// Transform a string (typically provided by the legacy service) into a decent
+// avatar name instance.
+void LLAvatarName::fromString(const std::string& full_name)
+{
+	mDisplayName = full_name;
+	std::string::size_type index = full_name.find(' ');
+	if (index != std::string::npos)
+	{
+		// The name is in 2 parts (first last)
+		mLegacyFirstName = full_name.substr(0, index);
+		mLegacyLastName = full_name.substr(index+1);
+		if (mLegacyLastName != "Resident")
+		{
+			mUsername = mLegacyFirstName + "." + mLegacyLastName;
+			mDisplayName = full_name;
+			LLStringUtil::toLower(mUsername);
+		}
+		else
+		{
+			// Very old names do have a dummy "Resident" last name 
+			// that we choose to hide from users.
+			mUsername = mLegacyFirstName;
+			mDisplayName = mLegacyFirstName;
+		}
+	}
+	else
+	{
+		mLegacyFirstName = full_name;
+		mLegacyLastName = "";
+		mUsername = full_name;
+		mDisplayName = full_name;
+	}
+	mIsDisplayNameDefault = true;
+	mIsTemporaryName = true;
+	setExpires(MIN_ENTRY_LIFETIME);
+}
+
+void LLAvatarName::setExpires(F64 expires)
+{
+	mExpires = LLFrameTimer::getTotalSeconds() + expires;
 }
 
 std::string LLAvatarName::getCompleteName() const
 {
 	std::string name;
-	if (mUsername.empty() || mIsDisplayNameDefault)
-	// If the display name feature is off
-	// OR this particular display name is defaulted (i.e. based on user name),
-	// then display only the easier to read instance of the person's name.
+	if (sUseDisplayNames)
 	{
-		name = mDisplayName;
+		if (mUsername.empty() || mIsDisplayNameDefault)
+		{
+			// If this particular display name is defaulted (i.e. based on user name),
+			// then display only the easier to read instance of the person's name.
+			name = mDisplayName;
+		}
+		else
+		{
+			name = mDisplayName + " (" + mUsername + ")";
+		}
 	}
 	else
 	{
-		name = mDisplayName + " (" + mUsername + ")";
+		name = getUserName();
 	}
 	return name;
 }
@@ -118,3 +192,48 @@ std::string LLAvatarName::getLegacyName() const
 	name += mLegacyLastName;
 	return name;
 }
+
+std::string LLAvatarName::getDisplayName() const
+{
+	if (sUseDisplayNames)
+	{
+		return mDisplayName;
+	}
+	else
+	{
+		return getUserName();
+	}
+}
+
+std::string LLAvatarName::getUserName() const
+{
+	std::string name;
+	if (mLegacyLastName.empty() || (mLegacyLastName == "Resident"))
+	{
+		if (mLegacyFirstName.empty())
+		{
+			// If we cannot create a user name from the legacy strings, use the display name
+			name = mDisplayName;
+		}
+		else
+		{
+			// The last name might be empty if it defaulted to "Resident"
+			name = mLegacyFirstName;
+		}
+	}
+	else
+	{
+		name = mLegacyFirstName + " " + mLegacyLastName;
+	}
+	return name;
+}
+
+void LLAvatarName::dump() const
+{
+	LL_DEBUGS("AvNameCache") << "LLAvatarName: "
+	                         << "user '" << mUsername << "' "
+							 << "display '" << mDisplayName << "' "
+	                         << "expires in " << mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
+							 << LL_ENDL;
+}
+
diff --git a/indra/llcommon/llavatarname.h b/indra/llcommon/llavatarname.h
index ba258d6d52420788bf5256905bff53f2295426a2..7542a8dece0918da062061d0b10d1441a3198a1d 100644
--- a/indra/llcommon/llavatarname.h
+++ b/indra/llcommon/llavatarname.h
@@ -39,10 +39,27 @@ class LL_COMMON_API LLAvatarName
 	
 	bool operator<(const LLAvatarName& rhs) const;
 
+	// Conversion to and from LLSD (cache file or server response)
 	LLSD asLLSD() const;
-
 	void fromLLSD(const LLSD& sd);
 
+	// Used only in legacy mode when the display name capability is not provided server side
+	// or to otherwise create a temporary valid item.
+	void fromString(const std::string& full_name);
+	
+	// Set the name object to become invalid in "expires" seconds from now
+	void setExpires(F64 expires);
+
+	// Set and get the display name flag set by the user in preferences.
+	static void setUseDisplayNames(bool use);
+	static bool useDisplayNames();
+	
+	// A name object is valid if not temporary and not yet expired (default is expiration not checked)
+	bool isValidName(F64 max_unrefreshed = 0.0f) const { return !mIsTemporaryName && (mExpires >= max_unrefreshed); }
+	
+	// Return true if the name is made up from legacy or temporary data
+	bool isDisplayNameDefault() const { return mIsDisplayNameDefault; }
+	
 	// For normal names, returns "James Linden (james.linden)"
 	// When display names are disabled returns just "James Linden"
 	std::string getCompleteName() const;
@@ -51,11 +68,38 @@ class LL_COMMON_API LLAvatarName
 	// compatibility with systems like voice and muting
 	// *TODO: Eliminate this in favor of username only
 	std::string getLegacyName() const;
+	
+	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
+	// Takes the display name preference into account. This is truly the name that should 
+	// be used for all UI where an avatar name has to be used unless we truly want something else (rare)
+	std::string getDisplayName() const;
+	
+	// Returns "James Linden" or "bobsmith123 Resident"
+	// Used where we explicitely prefer or need a non UTF-8 legacy (ASCII) name
+	// Also used for backwards compatibility with systems like voice and muting
+	std::string getUserName() const;
+	
+	// Returns "james.linden" or the legacy name for very old names
+	std::string getAccountName() const { return mUsername; }
 
+	// Debug print of the object
+	void dump() const;
+	
+	// Names can change, so need to keep track of when name was
+	// last checked.
+	// Unix time-from-epoch seconds for efficiency
+	F64 mExpires;
+	
+	// You can only change your name every N hours, so record
+	// when the next update is allowed
+	// Unix time-from-epoch seconds
+	F64 mNextUpdate;
+	
+private:
 	// "bobsmith123" or "james.linden", US-ASCII only
 	std::string mUsername;
 
-	// "Jose' Sanchez" or "James Linden", UTF-8 encoded Unicode
+	// "José Sanchez" or "James Linden", UTF-8 encoded Unicode
 	// Contains data whether or not user has explicitly set
 	// a display name; may duplicate their username.
 	std::string mDisplayName;
@@ -81,15 +125,9 @@ class LL_COMMON_API LLAvatarName
 	// shown in UI, but are not serialized.
 	bool mIsTemporaryName;
 
-	// Names can change, so need to keep track of when name was
-	// last checked.
-	// Unix time-from-epoch seconds for efficiency
-	F64 mExpires;
-	
-	// You can only change your name every N hours, so record
-	// when the next update is allowed
-	// Unix time-from-epoch seconds
-	F64 mNextUpdate;
+	// Global flag indicating if display name should be used or not
+	// This will affect the output of the high level "get" methods
+	static bool sUseDisplayNames;
 };
 
 #endif
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index bc3bc3e74ac1cca5601a425a53891175c3e18555..c752859a3661f1116f8bc41ec43a36282dfc40ad 100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -30,6 +30,8 @@
 #include <map>
 #include <string>
 
+#include "llerror.h"
+
 struct LL_COMMON_API LLDictionaryEntry
 {
 	LLDictionaryEntry(const std::string &name);
diff --git a/indra/llcommon/llfasttimer.cpp b/indra/llcommon/llfasttimer.cpp
index 6970c290924e045eb8296f398028763b9fc71a68..9b15804e97b65998f8457a2e0f9625ae3b8edbe4 100644
--- a/indra/llcommon/llfasttimer.cpp
+++ b/indra/llcommon/llfasttimer.cpp
@@ -561,6 +561,12 @@ std::vector<LLFastTimer::NamedTimer*>& LLFastTimer::NamedTimer::getChildren()
 	return mChildren;
 }
 
+// static
+LLFastTimer::NamedTimer& LLFastTimer::NamedTimer::getRootNamedTimer()
+{
+        return *NamedTimerFactory::instance().getRootTimer();
+}
+
 //static
 void LLFastTimer::nextFrame()
 {
diff --git a/indra/llcommon/llfasttimer.h b/indra/llcommon/llfasttimer.h
index e42e549df58c6579de25f0f271a1225da74a93fd..81c4b78775574c931f8f7cb28bfef12b8725926b 100644
--- a/indra/llcommon/llfasttimer.h
+++ b/indra/llcommon/llfasttimer.h
@@ -91,6 +91,8 @@ class LL_COMMON_API LLFastTimer
 		U32 getHistoricalCount(S32 history_index = 0) const;
 		U32 getHistoricalCalls(S32 history_index = 0) const;
 
+		static NamedTimer& getRootNamedTimer();
+
 		void setFrameState(FrameState* state) { mFrameState = state; state->setNamedTimer(this); }
 		FrameState& getFrameState() const;
 
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c51d042a3d312d908d5c8b56cd47341ee43dad51..bc615ed39ec593de0cda0d2bd3caa1639d7dad06 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -56,6 +56,8 @@ std::string strerr(int errn)
 	return buffer;
 }
 
+typedef std::basic_ios<char,std::char_traits < char > > _Myios;
+
 #else
 // On Posix we want to call strerror_r(), but alarmingly, there are two
 // different variants. The one that returns int always populates the passed
@@ -324,9 +326,10 @@ const char *LLFile::tmpdir()
 
 /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
 
-#if USE_LLFILESTREAMS
+#if LL_WINDOWS
 
-LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int)	// protection currently unused
+LLFILE *	LLFile::_Fiopen(const std::string& filename, 
+		std::ios::openmode mode)
 {	// open a file
 	static const char *mods[] =
 	{	// fopen mode strings corresponding to valid[i]
@@ -385,117 +388,681 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in
 	return (0);
 }
 
-/************** input file stream ********************************/
+#endif /* LL_WINDOWS */
 
-void llifstream::close()
-{	// close the C stream
-	if (_Filebuffer && _Filebuffer->close() == 0)
+/************** llstdio file buffer ********************************/
+
+
+//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename,
+//	ios_base::openmode _Mode)
+//{
+//#if LL_WINDOWS
+//	_Filet *_File;
+//	if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0)
+//		return (0);	// open failed
+//
+//	_Init(_File, _Openfl);
+//	_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
+//	return (this);	// open succeeded
+//#else
+//	std::filebuf* _file = std::filebuf::open(_Filename, _Mode);
+//	if (NULL == _file) return NULL;
+//	return this;
+//#endif
+//}
+
+
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c)
+{
+	int_type __ret = traits_type::eof();
+	const bool __testeof = traits_type::eq_int_type(__c, __ret);
+	const bool __testout = _M_mode & ios_base::out;
+	if (__testout && !_M_reading)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
+		if (this->pbase() < this->pptr())
+		{
+			// If appropriate, append the overflow char.
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+
+			// Convert pending sequence to external representation,
+			// and output.
+			if (_convert_to_external(this->pbase(),
+					 this->pptr() - this->pbase()))
+			{
+				_M_set_buffer(0);
+				__ret = traits_type::not_eof(__c);
+			}
+		}
+		else if (_M_buf_size > 1)
+		{
+			// Overflow in 'uncommitted' mode: set _M_writing, set
+			// the buffer to the initial 'write' mode, and put __c
+			// into the buffer.
+			_M_set_buffer(0);
+			_M_writing = true;
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+			__ret = traits_type::not_eof(__c);
+		}
+		else
+		{
+			// Unbuffered.
+			char_type __conv = traits_type::to_char_type(__c);
+			if (__testeof || _convert_to_external(&__conv, 1))
+			{
+				_M_writing = true;
+				__ret = traits_type::not_eof(__c);
+			}
+		}
 	}
+	return __ret;
 }
 
-void llifstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
-{	// open a C stream with specified mode
+bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
+						std::streamsize __ilen)
+{
+	// Sizes of external and pending output.
+	streamsize __elen;
+	streamsize __plen;
+	if (__check_facet(_M_codecvt).always_noconv())
+	{
+		//__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1,
+						__ilen, _M_file.file());
+		__plen = __ilen;
+	}
+	else
+	{
+		// Worst-case number of external bytes needed.
+		// XXX Not done encoding() == -1.
+		streamsize __blen = __ilen * _M_codecvt->max_length();
+		char* __buf = static_cast<char*>(__builtin_alloca(__blen));
 
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot);
-	if(filep == NULL)
+		char* __bend;
+		const char_type* __iend;
+		codecvt_base::result __r;
+		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
+				__iend, __buf, __buf + __blen, __bend);
+
+		if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+			__blen = __bend - __buf;
+		else if (__r == codecvt_base::noconv)
+		{
+			// Same as the always_noconv case above.
+			__buf = reinterpret_cast<char*>(__ibuf);
+			__blen = __ilen;
+		}
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+									"conversion error"));
+  
+		//__elen = _M_file.xsputn(__buf, __blen);
+		__elen = fwrite(__buf, 1, __blen, _M_file.file());
+		__plen = __blen;
+
+		// Try once more for partial conversions.
+		if (__r == codecvt_base::partial && __elen == __plen)
+		{
+			const char_type* __iresume = __iend;
+			streamsize __rlen = this->pptr() - __iend;
+			__r = _M_codecvt->out(_M_state_cur, __iresume,
+					__iresume + __rlen, __iend, __buf,
+					__buf + __blen, __bend);
+			if (__r != codecvt_base::error)
+			{
+				__rlen = __bend - __buf;
+				//__elen = _M_file.xsputn(__buf, __rlen);
+				__elen = fwrite(__buf, 1, __rlen, _M_file.file());
+				__plen = __rlen;
+			}
+			else
+			{
+				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+										"conversion error"));
+			}
+		}
+	}
+	return __elen == __plen;
+}
+
+llstdio_filebuf::int_type llstdio_filebuf::underflow()
+{
+	int_type __ret = traits_type::eof();
+	const bool __testin = _M_mode & ios_base::in;
+	if (__testin)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		if (_M_writing)
+		{
+			if (overflow() == traits_type::eof())
+			return __ret;
+			//_M_set_buffer(-1);
+			//_M_writing = false;
+		}
+		// Check for pback madness, and if so switch back to the
+		// normal buffers and jet outta here before expensive
+		// fileops happen...
+		_M_destroy_pback();
+
+		if (this->gptr() < this->egptr())
+			return traits_type::to_int_type(*this->gptr());
+
+		// Get and convert input sequence.
+		const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+		// Will be set to true if ::fread() returns 0 indicating EOF.
+		bool __got_eof = false;
+		// Number of internal characters produced.
+		streamsize __ilen = 0;
+		codecvt_base::result __r = codecvt_base::ok;
+		if (__check_facet(_M_codecvt).always_noconv())
+		{
+			//__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
+			//			__buflen);
+			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1,
+						__buflen, _M_file.file());
+			if (__ilen == 0)
+				__got_eof = true;
+		}
+		else
+	    {
+			// Worst-case number of external bytes.
+			// XXX Not done encoding() == -1.
+			const int __enc = _M_codecvt->encoding();
+			streamsize __blen; // Minimum buffer size.
+			streamsize __rlen; // Number of chars to read.
+			if (__enc > 0)
+				__blen = __rlen = __buflen * __enc;
+			else
+			{
+				__blen = __buflen + _M_codecvt->max_length() - 1;
+				__rlen = __buflen;
+			}
+			const streamsize __remainder = _M_ext_end - _M_ext_next;
+			__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
+
+			// An imbue in 'read' mode implies first converting the external
+			// chars already present.
+			if (_M_reading && this->egptr() == this->eback() && __remainder)
+				__rlen = 0;
+
+			// Allocate buffer if necessary and move unconverted
+			// bytes to front.
+			if (_M_ext_buf_size < __blen)
+			{
+				char* __buf = new char[__blen];
+				if (__remainder)
+					__builtin_memcpy(__buf, _M_ext_next, __remainder);
+
+				delete [] _M_ext_buf;
+				_M_ext_buf = __buf;
+				_M_ext_buf_size = __blen;
+			}
+			else if (__remainder)
+				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
+
+			_M_ext_next = _M_ext_buf;
+			_M_ext_end = _M_ext_buf + __remainder;
+			_M_state_last = _M_state_cur;
+
+			do
+			{
+				if (__rlen > 0)
+				{
+					// Sanity check!
+					// This may fail if the return value of
+					// codecvt::max_length() is bogus.
+					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
+					{
+						__throw_ios_failure(__N("llstdio_filebuf::underflow "
+							"codecvt::max_length() "
+							"is not valid"));
+					}
+					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
+					streamsize __elen = fread(_M_ext_end, 1,
+						__rlen, _M_file.file());
+					if (__elen == 0)
+						__got_eof = true;
+					else if (__elen == -1)
+					break;
+					//_M_ext_end += __elen;
+				}
+
+				char_type* __iend = this->eback();
+				if (_M_ext_next < _M_ext_end)
+				{
+					__r = _M_codecvt->in(_M_state_cur, _M_ext_next,
+							_M_ext_end, _M_ext_next,
+							this->eback(),
+							this->eback() + __buflen, __iend);
+				}
+				if (__r == codecvt_base::noconv)
+				{
+					size_t __avail = _M_ext_end - _M_ext_buf;
+					__ilen = std::min(__avail, __buflen);
+					traits_type::copy(this->eback(),
+						reinterpret_cast<char_type*>
+						(_M_ext_buf), __ilen);
+					_M_ext_next = _M_ext_buf + __ilen;
+				}
+				else
+					__ilen = __iend - this->eback();
+
+				// _M_codecvt->in may return error while __ilen > 0: this is
+				// ok, and actually occurs in case of mixed encodings (e.g.,
+				// XML files).
+				if (__r == codecvt_base::error)
+					break;
+
+				__rlen = 1;
+			} while (__ilen == 0 && !__got_eof);
+		}
+
+		if (__ilen > 0)
+		{
+			_M_set_buffer(__ilen);
+			_M_reading = true;
+			__ret = traits_type::to_int_type(*this->gptr());
+		}
+		else if (__got_eof)
+		{
+			// If the actual end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without an
+			// intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+			// However, reaching it while looping on partial means that
+			// the file has got an incomplete character.
+			if (__r == codecvt_base::partial)
+				__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"incomplete character in file"));
+		}
+		else if (__r == codecvt_base::error)
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"invalid byte sequence in file"));
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"error reading the file"));
 	}
-	llassert(_Filebuffer == NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+	return __ret;
 }
 
-bool llifstream::is_open() const
-{	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n)
+{
+	// Clear out pback buffer before going on to the real deal...
+	streamsize __ret = 0;
+	if (_M_pback_init)
+	{
+		if (__n > 0 && this->gptr() == this->eback())
+		{
+			*__s++ = *this->gptr();
+			this->gbump(1);
+			__ret = 1;
+			--__n;
+		}
+		_M_destroy_pback();
+	}
+       
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n > __buflen we read directly instead of using the
+	// buffer repeatedly.
+	const bool __testin = _M_mode & ios_base::in;
+	const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+	if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
+		&& __testin && !_M_writing)
+	{
+		// First, copy the chars already present in the buffer.
+		const streamsize __avail = this->egptr() - this->gptr();
+		if (__avail != 0)
+		{
+			if (__avail == 1)
+				*__s = *this->gptr();
+			else
+				traits_type::copy(__s, this->gptr(), __avail);
+			__s += __avail;
+			this->gbump(__avail);
+			__ret += __avail;
+			__n -= __avail;
+		}
+
+		// Need to loop in case of short reads (relatively common
+		// with pipes).
+		streamsize __len;
+		for (;;)
+		{
+			//__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
+			__len = fread(reinterpret_cast<void*>(__s), 1, 
+						__n, _M_file.file());
+			if (__len == -1)
+				__throw_ios_failure(__N("llstdio_filebuf::xsgetn "
+										"error reading the file"));
+			if (__len == 0)
+				break;
+
+			__n -= __len;
+			__ret += __len;
+			if (__n == 0)
+				break;
+
+			__s += __len;
+		}
+
+		if (__n == 0)
+		{
+			_M_set_buffer(0);
+			_M_reading = true;
+		}
+		else if (__len == 0)
+		{
+			// If end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without
+			// an intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+		}
+	}
+	else
+		__ret += __streambuf_type::xsgetn(__s, __n);
+
+	return __ret;
 }
-llifstream::~llifstream()
+
+std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
 {
-	if (_ShouldClose)
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n is sufficiently large we write directly instead of
+	// using the buffer.
+	streamsize __ret = 0;
+	const bool __testout = _M_mode & ios_base::out;
+	if (__check_facet(_M_codecvt).always_noconv()
+		&& __testout && !_M_reading)
 	{
-		close();
+		// Measurement would reveal the best choice.
+		const streamsize __chunk = 1ul << 10;
+		streamsize __bufavail = this->epptr() - this->pptr();
+
+		// Don't mistake 'uncommitted' mode buffered with unbuffered.
+		if (!_M_writing && _M_buf_size > 1)
+			__bufavail = _M_buf_size - 1;
+
+		const streamsize __limit = std::min(__chunk, __bufavail);
+		if (__n >= __limit)
+		{
+			const streamsize __buffill = this->pptr() - this->pbase();
+			const char* __buf = reinterpret_cast<const char*>(this->pbase());
+			//__ret = _M_file.xsputn_2(__buf, __buffill,
+			//			reinterpret_cast<const char*>(__s), __n);
+			if (__buffill)
+			{
+				__ret = fwrite(__buf, 1, __buffill, _M_file.file());
+			}
+			if (__ret == __buffill)
+			{
+				__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
+								__n, _M_file.file());
+			}
+			if (__ret == __buffill + __n)
+			{
+				_M_set_buffer(0);
+				_M_writing = true;
+			}
+			if (__ret > __buffill)
+				__ret -= __buffill;
+			else
+				__ret = 0;
+		}
+		else
+			__ret = __streambuf_type::xsputn(__s, __n);
 	}
-	delete _Filebuffer;
+	else
+		__ret = __streambuf_type::xsputn(__s, __n);
+    return __ret;
 }
 
-llifstream::llifstream(const std::string& _Filename,
-	ios_base::openmode _Mode,
-	int _Prot)
-	: std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
+int llstdio_filebuf::sync()
+{
+	return (_M_file.sync() == 0 ? 0 : -1);
+}
+#endif
+
+/************** input file stream ********************************/
 
-{	// construct with named file and specified mode
-	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */
+
+llifstream::llifstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
+llifstream::llifstream(const std::string& _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
 }
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::in);
+}
+#endif
 
+// explicit
+llifstream::llifstream(const char* _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::in);
+}
+#endif
 
-/************** output file stream ********************************/
 
-bool llofstream::is_open() const
+// explicit
+llifstream::llifstream(_Filet *_File,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+#if !LL_WINDOWS
+// explicit
+llifstream::llifstream(int __fd,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llifstream::is_open() const
 {	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+	return _M_filebuf.is_open();
 }
 
-void llofstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot);
-	if(filep == NULL)
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		_Myios::clear();
 	}
-	llassert(_Filebuffer==NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-void llofstream::close()
+void llifstream::close()
 {	// close the C stream
-	if(is_open())
+	if (_M_filebuf.close() == 0)
 	{
-		if (_Filebuffer->close() == 0)
-		{
-			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		}
-		delete _Filebuffer;
-		_Filebuffer = NULL;
-		_ShouldClose = false;
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
 	}
 }
 
+
+/************** output file stream ********************************/
+
+
+llofstream::llofstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
 llofstream::llofstream(const std::string& _Filename,
-	std::ios_base::openmode _Mode,
-	int _Prot)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-{	// construct with named file and specified mode
-	open(_Filename, _Mode , _Prot);	/* Flawfinder: ignore */
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(const char* _Filename,
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(_Filet *_File,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
 }
+#endif
 
-llofstream::~llofstream()
+#if !LL_WINDOWS
+// explicit
+llofstream::llofstream(int __fd,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::ostream()
 {
-	// destroy the object
-	if (_ShouldClose)
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llofstream::is_open() const
+{	// test if C stream has been opened
+	return _M_filebuf.is_open();
+}
+
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{	// open a C stream with specified mode
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		close();
+		_Myios::clear();
 	}
-	delete _Filebuffer;
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-#endif // #if USE_LLFILESTREAMS
+void llofstream::close()
+{	// close the C stream
+	if (_M_filebuf.close() == 0)
+	{
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
+	}
+}
 
 /************** helper functions ********************************/
 
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index dd7d36513a06d13c81638c1d7eafbdac2e60ab9e..9d70db96ea83852d4365cf9f0096454bc2e41cec 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,16 +35,9 @@
  * Attempts to mostly mirror the POSIX style IO functions.
  */
 
-typedef FILE	LLFILE;
+typedef FILE LLFILE;
 
 #include <fstream>
-
-#ifdef LL_WINDOWS
-#define	USE_LLFILESTREAMS	1
-#else
-#define	USE_LLFILESTREAMS	0
-#endif
-
 #include <sys/stat.h>
 
 #if LL_WINDOWS
@@ -52,6 +45,8 @@ typedef FILE	LLFILE;
 typedef struct _stat	llstat;
 #else
 typedef struct stat		llstat;
+#include <ext/stdio_filebuf.h>
+#include <bits/postypes.h>
 #endif
 
 #ifndef S_ISREG
@@ -83,142 +78,342 @@ class LL_COMMON_API LLFile
 	static	int		stat(const std::string&	filename,llstat*	file_status);
 	static	bool	isdir(const std::string&	filename);
 	static	bool	isfile(const std::string&	filename);
-	static	LLFILE *	_Fiopen(const std::string& filename, std::ios::openmode mode,int);	// protection currently unused
+	static	LLFILE *	_Fiopen(const std::string& filename, 
+			std::ios::openmode mode);
 
 	static  const char * tmpdir();
 };
 
+/**
+ *  @brief Provides a layer of compatibility for C/POSIX.
+ *
+ *  This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and 
+ *  VC's basic_filebuf implementation.
+ *  This file buffer provides extensions for working with standard C FILE*'s 
+ *  and POSIX file descriptors for platforms that support this.
+*/
+namespace
+{
+#if LL_WINDOWS
+typedef std::filebuf						_Myfb;
+#else
+typedef  __gnu_cxx::stdio_filebuf< char >	_Myfb;
+typedef std::__c_file						_Filet;
+#endif /* LL_WINDOWS */
+}
 
-#if USE_LLFILESTREAMS
-
-class LL_COMMON_API llifstream	:	public	std::basic_istream < char , std::char_traits < char > >
+class LL_COMMON_API llstdio_filebuf : public _Myfb
 {
-	// input stream associated with a C stream
 public:
-	typedef std::basic_ifstream<char,std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits< char > > _Myios;
-
-	llifstream()
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
+	/**
+	 * deferred initialization / destruction
+	*/
+	llstdio_filebuf() : _Myfb() {}
+	virtual ~llstdio_filebuf() {} 
+
+	/**
+	 *  @param  f  An open @c FILE*.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *                Defaults to system's @c BUFSIZ.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  C @c FILE*.  The @c FILE* will not be automatically closed when the
+	 *  stdio_filebuf is closed/destroyed.
+	*/
+	llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
+		    //size_t __size = static_cast<size_t>(BUFSIZ)) :
+		    size_t __size = static_cast<size_t>(1)) :
+#if LL_WINDOWS
+		_Myfb(__f) {}
+#else
+		_Myfb(__f, __mode, __size) {}
+#endif
 
-	explicit llifstream(const std::string& _Filename,
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);
-
-	explicit llifstream(_Filet *_File)
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-	virtual ~llifstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
-	bool is_open() const;
-	void open(const std::string& _Filename,	/* Flawfinder: ignore */
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);	
-	void close();
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  s  The name of the file.
+	 *  @param  mode  The open mode flags.
+	 *  @return  @c this on success, NULL on failure
+	 *
+	 *  If a file is already open, this function immediately fails.
+	 *  Otherwise it tries to open the file named @a s using the flags
+	 *  given in @a mode.
+	*/
+	//llstdio_filebuf* open(const char *_Filename,
+	//		std::ios_base::openmode _Mode);
+
+	/**
+	 *  @param  fd  An open file descriptor.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  POSIX file descriptor. The file descriptor will be automatically
+	 *  closed when the stdio_filebuf is closed/destroyed.
+	*/
+#if !LL_WINDOWS
+	llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
+		//size_t __size = static_cast<size_t>(BUFSIZ)) :
+		size_t __size = static_cast<size_t>(1)) :
+		_Myfb(__fd, __mode, __size) {}
+#endif
 
-private:
-	_Myfb* _Filebuffer;	// the file buffer
-	bool _ShouldClose;
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+protected:
+	/** underflow() and uflow() functions are called to get the next
+	 *  character from the real input source when the buffer is empty.
+	 *  Buffered input uses underflow()
+	*/
+	/*virtual*/ int_type underflow();
+
+	/*  Convert internal byte sequence to external, char-based
+	 * sequence via codecvt.
+	*/
+	bool _convert_to_external(char_type*, std::streamsize);
+
+	/** The overflow() function is called to transfer characters to the
+	 *  real output destination when the buffer is full. A call to
+	 *  overflow(c) outputs the contents of the buffer plus the
+	 *  character c.
+	 *  Consume some sequence of the characters in the pending sequence.
+	*/
+	/*virtual*/ int_type overflow(int_type __c = traits_type::eof());
+
+	/** sync() flushes the underlying @c FILE* stream.
+	*/
+	/*virtual*/ int sync();
+
+	std::streamsize xsgetn(char_type*, std::streamsize);
+	std::streamsize xsputn(char_type*, std::streamsize);
+#endif
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::basic_ostream< char , std::char_traits < char > >
+/**
+ *  @brief  Controlling input for files.
+ *
+ *  This class supports reading from named files, using the inherited
+ *  functions from std::basic_istream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llifstream	:	public	std::istream
 {
+	// input stream associated with a C stream
 public:
-	typedef std::basic_ostream< char , std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits < char > > _Myios;
-
-	llofstream()
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
-
-	explicit llofstream(const std::string& _Filename,
-		std::ios_base::openmode _Mode = ios_base::out,
-		int _Prot = (int)std::ios_base::_Openprot);
-	
-
-	explicit llofstream(_Filet *_File)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),//_File)
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-
-	virtual ~llofstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llifstream();
+
+	/**
+	 *  @brief  Create an input file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+     *  @c ios_base::in is automatically included in @a mode.
+	*/
+	explicit llifstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+	explicit llifstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llifstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llifstream(int __fd,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llifstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
 	bool is_open() const;
 
-	void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot);	/* Flawfinder: ignore */
-
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|in).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
 	void close();
 
 private:
-	_Myfb *_Filebuffer;	// the file buffer
-	bool _ShouldClose;
-};
-
-
-
-#else
-//Use standard file streams on non windows platforms
-//#define	llifstream	std::ifstream
-//#define	llofstream	std::ofstream
-
-class LL_COMMON_API llifstream	:	public	std::ifstream
-{
-public:
-	llifstream() : std::ifstream()
-	{
-	}
-
-	explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in)
-		: std::ifstream(_Filename.c_str(), _Mode)
-	{
-	}
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in)	/* Flawfinder: ignore */
-	{
-		std::ifstream::open(_Filename.c_str(), _Mode);
-	}
+	llstdio_filebuf _M_filebuf;
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::ofstream
+/**
+ *  @brief  Controlling output for files.
+ *
+ *  This class supports writing to named files, using the inherited
+ *  functions from std::basic_ostream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llofstream	:	public	std::ostream
 {
 public:
-	llofstream() : std::ofstream()
-	{
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llofstream();
+
+	/**
+	 *  @brief  Create an output file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+	 *  @c ios_base::out|ios_base::trunc is automatically included in
+	 *  @a mode.
+	*/
+	explicit llofstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+	explicit llofstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llofstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llofstream(int __fd,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
-	explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out)
-		: std::ofstream(_Filename.c_str(), _Mode)
-	{
-	}
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llofstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
+	bool is_open() const;
 
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out)	/* Flawfinder: ignore */
-	{
-		std::ofstream::open(_Filename.c_str(), _Mode);
-	}
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|out).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void close();
 
+private:
+	llstdio_filebuf _M_filebuf;
 };
 
-#endif
 
 /**
  * @breif filesize helpers.
diff --git a/indra/llcommon/llfoldertype.h b/indra/llcommon/llfoldertype.h
old mode 100644
new mode 100755
diff --git a/indra/llcommon/llhandle.h b/indra/llcommon/llhandle.h
index 6af5e198d608eefd8e3a2fdb8b0fd52afbdd7d56..401e4d759ae048a43b07e618248bd9e83434f145 100644
--- a/indra/llcommon/llhandle.h
+++ b/indra/llcommon/llhandle.h
@@ -194,13 +194,6 @@ class LLHandleProvider
 		return mHandle; 
 	}
 
-protected:
-	typedef LLHandle<T> handle_type_t;
-	LLHandleProvider() 
-	{
-		// provided here to enforce T deriving from LLHandleProvider<T>
-	} 
-
 	template <typename U>
 	LLHandle<U> getDerivedHandle(typename boost::enable_if< typename boost::is_convertible<U*, T*> >::type* dummy = 0) const
 	{
@@ -209,6 +202,12 @@ class LLHandleProvider
 		return downcast_handle;
 	}
 
+protected:
+	typedef LLHandle<T> handle_type_t;
+	LLHandleProvider() 
+	{
+		// provided here to enforce T deriving from LLHandleProvider<T>
+	} 
 
 private:
 	mutable LLRootHandle<T> mHandle;
diff --git a/indra/llcommon/llinitparam.cpp b/indra/llcommon/llinitparam.cpp
index db72aa19b98ce2127e7892ff9cf1c12e12a8cb7b..89c831d296861561a71bdc0bf0afe5d3b21fa5ad 100644
--- a/indra/llcommon/llinitparam.cpp
+++ b/indra/llcommon/llinitparam.cpp
@@ -40,7 +40,9 @@ namespace LLInitParam
 	{
 		const U8* my_addr = reinterpret_cast<const U8*>(this);
 		const U8* block_addr = reinterpret_cast<const U8*>(enclosing_block);
-		mEnclosingBlockOffset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		U32 enclosing_block_offset = 0x7FFFffff & (U32)(my_addr - block_addr);
+		mEnclosingBlockOffsetLow = enclosing_block_offset & 0x0000ffff;
+		mEnclosingBlockOffsetHigh = (enclosing_block_offset & 0x007f0000) >> 16;
 	}
 
 	//
@@ -112,6 +114,35 @@ namespace LLInitParam
 		std::copy(src_block_data.mAllParams.begin(), src_block_data.mAllParams.end(), std::back_inserter(mAllParams));
 	}
 
+	void BlockDescriptor::addParam(const ParamDescriptorPtr in_param, const char* char_name)
+	{
+		// create a copy of the param descriptor in mAllParams
+		// so other data structures can store a pointer to it
+		mAllParams.push_back(in_param);
+		ParamDescriptorPtr param(mAllParams.back());
+
+		std::string name(char_name);
+		if ((size_t)param->mParamHandle > mMaxParamOffset)
+		{
+			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
+		}
+
+		if (name.empty())
+		{
+			mUnnamedParams.push_back(param);
+		}
+		else
+		{
+			// don't use insert, since we want to overwrite existing entries
+			mNamedParams[name] = param;
+		}
+
+		if (param->mValidationFunc)
+		{
+			mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
+		}
+	}
+
 	BlockDescriptor::BlockDescriptor()
 	:	mMaxParamOffset(0),
 		mInitializationState(UNINITIALIZED),
@@ -150,7 +181,8 @@ namespace LLInitParam
 
 	bool BaseBlock::submitValue(Parser::name_stack_t& name_stack, Parser& p, bool silent)
 	{
-		if (!deserializeBlock(p, std::make_pair(name_stack.begin(), name_stack.end()), true))
+		Parser::name_stack_range_t range = std::make_pair(name_stack.begin(), name_stack.end());
+		if (!deserializeBlock(p, range, true))
 		{
 			if (!silent)
 			{
@@ -196,12 +228,7 @@ namespace LLInitParam
 			if (serialize_func)
 			{
 				const Param* diff_param = diff_block ? diff_block->getParamFromHandle(param_handle) : NULL;
-				// each param descriptor remembers its serial number
-				// so we can inspect the same param under different names
-				// and see that it has the same number
-				name_stack.push_back(std::make_pair("", true));
 				serialize_func(*param, parser, name_stack, diff_param);
-				name_stack.pop_back();
 			}
 		}
 
@@ -295,7 +322,7 @@ namespace LLInitParam
 		return true;
 	}
 
-	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool ignored)
+	bool BaseBlock::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool ignored)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
 		bool names_left = name_stack_range.first != name_stack_range.second;
@@ -308,15 +335,12 @@ namespace LLInitParam
 		{
 			const std::string& top_name = name_stack_range.first->first;
 
-			ParamDescriptor::deserialize_func_t deserialize_func = NULL;
-			Param* paramp = NULL;
-
 			BlockDescriptor::param_map_t::iterator found_it = block_data.mNamedParams.find(top_name);
 			if (found_it != block_data.mNamedParams.end())
 			{
 				// find pointer to member parameter from offset table
-				paramp = getParamFromHandle(found_it->second->mParamHandle);
-				deserialize_func = found_it->second->mDeserializeFunc;
+				Param* paramp = getParamFromHandle(found_it->second->mParamHandle);
+				ParamDescriptor::deserialize_func_t deserialize_func = found_it->second->mDeserializeFunc;
 					
 				Parser::name_stack_range_t new_name_stack(name_stack_range.first, name_stack_range.second);
 				++new_name_stack.first;
@@ -358,36 +382,6 @@ namespace LLInitParam
 		return false;
 	}
 
-	//static 
-	void BaseBlock::addParam(BlockDescriptor& block_data, const ParamDescriptorPtr in_param, const char* char_name)
-	{
-		// create a copy of the param descriptor in mAllParams
-		// so other data structures can store a pointer to it
-		block_data.mAllParams.push_back(in_param);
-		ParamDescriptorPtr param(block_data.mAllParams.back());
-
-		std::string name(char_name);
-		if ((size_t)param->mParamHandle > block_data.mMaxParamOffset)
-		{
-			llerrs << "Attempted to register param with block defined for parent class, make sure to derive from LLInitParam::Block<YOUR_CLASS, PARAM_BLOCK_BASE_CLASS>" << llendl;
-		}
-
-		if (name.empty())
-		{
-			block_data.mUnnamedParams.push_back(param);
-		}
-		else
-		{
-			// don't use insert, since we want to overwrite existing entries
-			block_data.mNamedParams[name] = param;
-		}
-
-		if (param->mValidationFunc)
-		{
-			block_data.mValidationList.push_back(std::make_pair(param->mParamHandle, param->mValidationFunc));
-		}
-	}
-
 	void BaseBlock::addSynonym(Param& param, const std::string& synonym)
 	{
 		BlockDescriptor& block_data = mostDerivedBlockDescriptor();
@@ -460,7 +454,7 @@ namespace LLInitParam
 			if (merge_func)
 			{
 				Param* paramp = getParamFromHandle((*it)->mParamHandle);
-				llassert(paramp->mEnclosingBlockOffset == (*it)->mParamHandle);
+				llassert(paramp->getEnclosingBlockOffset() == (*it)->mParamHandle);
 				some_param_changed |= merge_func(*paramp, *other_paramp, overwrite);
 			}
 		}
diff --git a/indra/llcommon/llinitparam.h b/indra/llcommon/llinitparam.h
index 0dd6030fa2cf9d6ad5b527c2dda82c36eae74721..ae836645b90b9f9097f2482b84ebd662ef2859ca 100644
--- a/indra/llcommon/llinitparam.h
+++ b/indra/llcommon/llinitparam.h
@@ -38,6 +38,71 @@
 #include "llerror.h"
 #include "llstl.h"
 
+namespace LLTypeTags
+{
+	template <typename INNER_TYPE, int _SORT_ORDER>
+	struct TypeTagBase
+	{
+		typedef void		is_tag_t;
+		typedef INNER_TYPE	inner_t;
+		static const int	SORT_ORDER=_SORT_ORDER;
+	};
+
+	template <int VAL1, int VAL2>
+	struct GreaterThan
+	{
+		static const bool value = VAL1 > VAL2;
+	};
+
+	template<typename ITEM, typename REST, bool NEEDS_SWAP = GreaterThan<ITEM::SORT_ORDER, REST::SORT_ORDER>::value >
+	struct Swap
+	{
+		typedef typename ITEM::template Cons<REST>::value_t value_t;
+	};
+
+	template<typename ITEM, typename REST>
+	struct Swap<ITEM, REST, true>
+	{
+		typedef typename REST::template Cons<Swap<ITEM, typename REST::inner_t>::value_t>::value_t value_t;
+	};
+
+	template<typename T, typename SORTABLE = void>
+	struct IsSortable
+	{
+		static const bool value = false;
+	};
+
+	template<typename T>
+	struct IsSortable<T, typename T::is_tag_t>
+	{
+		static const bool value = true;
+	};
+
+	template<typename ITEM, typename REST, bool IS_REST_SORTABLE = IsSortable<REST>::value>
+	struct InsertInto
+	{
+		typedef typename ITEM::template Cons<REST>::value_t value_t;
+	};
+
+	template<typename ITEM, typename REST>
+	struct InsertInto <ITEM, REST, true>
+	{
+		typedef typename Swap<ITEM, REST>::value_t value_t;
+	};
+
+	template<typename T, bool SORTABLE = IsSortable<T>::value>
+	struct Sorted
+	{
+		typedef T value_t;
+	};
+
+	template<typename T>
+	struct Sorted <T, true>
+	{
+		typedef typename InsertInto<T, typename Sorted<typename T::inner_t>::value_t>::value_t value_t;
+	};
+}
+
 namespace LLInitParam
 {
 	// used to indicate no matching value to a given name when parsing
@@ -45,6 +110,8 @@ namespace LLInitParam
 
 	template<typename T> const T& defaultValue() { static T value; return value; }
 
+	// wraps comparison operator between any 2 values of the same type
+	// specialize to handle cases where equality isn't defined well, or at all
 	template <typename T, bool IS_BOOST_FUNCTION = boost::is_convertible<T, boost::function_base>::value >
     struct ParamCompare 
 	{
@@ -79,24 +146,123 @@ namespace LLInitParam
 
 	// helper functions and classes
 	typedef ptrdiff_t param_handle_t;
+	struct IS_A_BLOCK {};
+	struct NOT_BLOCK {};
+
+	// these templates allow us to distinguish between template parameters
+	// that derive from BaseBlock and those that don't
+	template<typename T, typename BLOCK_IDENTIFIER = void>
+	struct IsBlock
+	{
+		typedef NOT_BLOCK value_t;
+	};
+
+	template<typename T>
+	struct IsBlock<T, typename T::baseblock_base_class_t>
+	{
+		typedef IS_A_BLOCK value_t;
+	};
+
+	// ParamValue class directly manages the wrapped value
+	// by holding on to a copy (scalar params)
+	// or deriving from it (blocks)
+	// has specializations for custom value behavior
+	// and "tag" values like Lazy and Atomic
+	template<typename T, typename VALUE_IS_BLOCK = typename IsBlock<T>::value_t>
+	class ParamValue
+	{
+		typedef ParamValue<T, VALUE_IS_BLOCK>	self_t;
+
+	public:
+		typedef T	default_value_t;
+		typedef T	value_t;
+
+		ParamValue(): mValue() {}
+		ParamValue(const default_value_t& other) : mValue(other) {}
+
+		void setValue(const value_t& val)
+		{
+			mValue = val;
+		}
+
+		const value_t& getValue() const
+		{
+			return mValue;
+		}
+
+		T& getValue()
+		{
+			return mValue;
+		}
+
+	protected:
+		T mValue;
+	};
+
+	template<typename T>
+	class ParamValue<T, IS_A_BLOCK> 
+	:	public T
+	{
+		typedef ParamValue<T, IS_A_BLOCK>	self_t;
+	public:
+		typedef T	default_value_t;
+		typedef T	value_t;
+
+		ParamValue() 
+		:	T(),
+			mValidated(false)
+		{}
+
+		ParamValue(const default_value_t& other)
+		:	T(other),
+			mValidated(false)
+		{}
+
+		void setValue(const value_t& val)
+		{
+			*this = val;
+		}
+
+		const value_t& getValue() const
+		{
+			return *this;
+		}
+
+		T& getValue()
+		{
+			return *this;
+		}
+
+	protected:
+		mutable bool 	mValidated; // lazy validation flag
+	};
+
 
 	// empty default implementation of key cache
 	// leverages empty base class optimization
 	template <typename T>
 	class TypeValues
+	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
 	{
 	private:
 		struct Inaccessable{};
 	public:
 		typedef std::map<std::string, T> value_name_map_t;
 		typedef Inaccessable name_t;
+		typedef TypeValues<T> type_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
+		typedef typename param_value_t::value_t	value_t;
+
+		TypeValues(const typename param_value_t::value_t& val)
+		:	param_value_t(val)
+		{}
 
 		void setValueName(const std::string& key) {}
 		std::string getValueName() const { return ""; }
-		std::string calcValueName(const T& value) const { return ""; }
+		std::string calcValueName(const value_t& value) const { return ""; }
 		void clearValueName() const {}
 
-		static bool getValueFromName(const std::string& name, T& value)
+		static bool getValueFromName(const std::string& name, value_t& value)
 		{
 			return false;
 		}
@@ -111,15 +277,39 @@ namespace LLInitParam
 			return NULL;
 		}
 
+		void assignNamedValue(const Inaccessable& name)
+		{}
+
+		operator const value_t&() const
+		{
+			return param_value_t::getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return param_value_t::getValue();
+		}
+
 		static value_name_map_t* getValueNames() {return NULL;}
 	};
 
-	template <typename T, typename DERIVED_TYPE = TypeValues<T> >
+	// helper class to implement name value lookups
+	// and caching of last used name
+	template <typename T, typename DERIVED_TYPE = TypeValues<T>, bool IS_SPECIALIZED = true >
 	class TypeValuesHelper
+	:	public ParamValue<typename LLTypeTags::Sorted<T>::value_t>
 	{
+		typedef TypeValuesHelper<T, DERIVED_TYPE, IS_SPECIALIZED> self_t;
 	public:
 		typedef typename std::map<std::string, T> value_name_map_t;
 		typedef std::string name_t;
+		typedef self_t type_value_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t> param_value_t;
+		typedef typename param_value_t::value_t	value_t;
+
+		TypeValuesHelper(const typename param_value_t::value_t& val)
+		:	param_value_t(val)
+		{}
 
 		//TODO: cache key by index to save on param block size
 		void setValueName(const std::string& value_name) 
@@ -132,7 +322,7 @@ namespace LLInitParam
 			return mValueName; 
 		}
 
-		std::string calcValueName(const T& value) const
+		std::string calcValueName(const value_t& value) const
 		{
 			value_name_map_t* map = getValueNames();
 			for (typename value_name_map_t::iterator it = map->begin(), end_it = map->end();
@@ -153,7 +343,7 @@ namespace LLInitParam
 			mValueName.clear();
 		}
 
-		static bool getValueFromName(const std::string& name, T& value)
+		static bool getValueFromName(const std::string& name, value_t& value)
 		{
 			value_name_map_t* map = getValueNames();
 			typename value_name_map_t::iterator found_it = map->find(name);
@@ -195,18 +385,90 @@ namespace LLInitParam
 			return &sValues;
 		}
 
-		static void declare(const std::string& name, const T& value)
+		static void declare(const std::string& name, const value_t& value)
 		{
 			(*getValueNames())[name] = value;
 		}
 
+		void operator ()(const std::string& name)
+		{
+			*this = name;
+		}
+
+		void assignNamedValue(const std::string& name)
+		{
+			if (getValueFromName(name, param_value_t::getValue()))
+			{
+				setValueName(name);
+			}
+		}
+
+		operator const value_t&() const
+		{
+			return param_value_t::getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return param_value_t::getValue();
+		}
+
 	protected:
-		static void getName(const std::string& name, const T& value)
+		static void getName(const std::string& name, const value_t& value)
 		{}
 
 		mutable std::string	mValueName;
 	};
 
+	// string types can support custom named values, but need
+	// to disambiguate in code between a string that is a named value
+	// and a string that is a name
+	template <typename DERIVED_TYPE>
+	class TypeValuesHelper<std::string, DERIVED_TYPE, true>
+	:	public TypeValuesHelper<std::string, DERIVED_TYPE, false>
+	{
+	public:
+		typedef TypeValuesHelper<std::string, DERIVED_TYPE, true> self_t;
+		typedef TypeValuesHelper<std::string, DERIVED_TYPE, false> base_t;
+		typedef std::string value_t;
+		typedef std::string name_t;
+		typedef self_t type_value_t;
+
+		TypeValuesHelper(const std::string& val)
+		:	TypeValuesHelper(val)
+		{}
+
+		void operator ()(const std::string& name)
+	{
+			*this = name;
+		}
+
+		self_t& operator =(const std::string& name)
+		{
+			if (base_t::getValueFromName(name, ParamValue<std::string>::getValue()))
+			{
+				base_t::setValueName(name);
+			}
+			else
+			{
+				ParamValue<std::string>::setValue(name);
+			}
+			return *this;
+		}
+		
+		operator const value_t&() const
+		{
+			return ParamValue<std::string>::getValue();
+		}
+
+		const value_t& operator()() const
+		{
+			return ParamValue<std::string>::getValue();
+		}
+
+	};
+
+	// parser base class with mechanisms for registering readers/writers/inspectors of different types
 	class LL_COMMON_API Parser
 	{
 		LOG_CLASS(Parser);
@@ -223,82 +485,58 @@ namespace LLInitParam
 		typedef std::map<const std::type_info*, parser_write_func_t>	parser_write_func_map_t;
 		typedef std::map<const std::type_info*, parser_inspect_func_t>	parser_inspect_func_map_t;
 
-	private:
-		template<typename T, bool is_enum = boost::is_enum<T>::value>
-		struct ReaderWriter
-		{
-			static bool read(T& param, Parser* parser)
+	public:
+
+		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
+		:	mParseSilently(false),
+			mParserReadFuncs(&read_map),
+			mParserWriteFuncs(&write_map),
+			mParserInspectFuncs(&inspect_map)
+		{}
+
+		virtual ~Parser();
+
+		template <typename T> bool readValue(T& param, typename boost::disable_if<boost::is_enum<T> >::type* dummy = 0)
 			{
-				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(T));
-				if (found_it != parser->mParserReadFuncs->end())
+			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+			if (found_it != mParserReadFuncs->end())
 				{
-					return found_it->second(*parser, (void*)&param);
+				return found_it->second(*this, (void*)&param);
 				}
+			
 				return false;
 			}
 			
-			static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
+		template <typename T> bool readValue(T& param, typename boost::enable_if<boost::is_enum<T> >::type* dummy = 0)
 			{
-				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(T));
-				if (found_it != parser->mParserWriteFuncs->end())
+			parser_read_func_map_t::iterator found_it = mParserReadFuncs->find(&typeid(T));
+			if (found_it != mParserReadFuncs->end())
 				{
-					return found_it->second(*parser, (const void*)&param, name_stack);
+				return found_it->second(*this, (void*)&param);
 				}
-				return false;
-			}
-		};
-
-		// read enums as ints
-		template<typename T>
-		struct ReaderWriter<T, true>
+			else
 		{
-			static bool read(T& param, Parser* parser)
-			{
-				// read all enums as ints
-				parser_read_func_map_t::iterator found_it = parser->mParserReadFuncs->find(&typeid(S32));
-				if (found_it != parser->mParserReadFuncs->end())
+				found_it = mParserReadFuncs->find(&typeid(S32));
+				if (found_it != mParserReadFuncs->end())
 				{
-					S32 value;
-					if (found_it->second(*parser, (void*)&value))
-					{
-						param = (T)value;
-						return true;
+					S32 int_value;
+					bool parsed = found_it->second(*this, (void*)&int_value);
+					param = (T)int_value;
+					return parsed;
 					}
 				}
 				return false;
 			}
 
-			static bool write(const T& param, Parser* parser, name_stack_t& name_stack)
+		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
 			{
-				parser_write_func_map_t::iterator found_it = parser->mParserWriteFuncs->find(&typeid(S32));
-				if (found_it != parser->mParserWriteFuncs->end())
+			parser_write_func_map_t::iterator found_it = mParserWriteFuncs->find(&typeid(T));
+			if (found_it != mParserWriteFuncs->end())
 				{
-					return found_it->second(*parser, (const void*)&param, name_stack);
+				return found_it->second(*this, (const void*)&param, name_stack);
 				}
 				return false;
 			}
-		};
-
-	public:
-
-		Parser(parser_read_func_map_t& read_map, parser_write_func_map_t& write_map, parser_inspect_func_map_t& inspect_map)
-		:	mParseSilently(false),
-			mParserReadFuncs(&read_map),
-			mParserWriteFuncs(&write_map),
-			mParserInspectFuncs(&inspect_map)
-		{}
-
-		virtual ~Parser();
-
-		template <typename T> bool readValue(T& param)
-	    {
-			return ReaderWriter<T>::read(param, this);
-	    }
-
-		template <typename T> bool writeValue(const T& param, name_stack_t& name_stack)
-		{
-			return ReaderWriter<T>::write(param, this, name_stack);
-		}
 
 		// dispatch inspection to registered inspection functions, for each parameter in a param block
 		template <typename T> bool inspectValue(name_stack_t& name_stack, S32 min_count, S32 max_count, const possible_values_t* possible_values)
@@ -350,7 +588,7 @@ namespace LLInitParam
 		};
 
 		typedef bool(*merge_func_t)(Param&, const Param&, bool);
-		typedef bool(*deserialize_func_t)(Param&, Parser&, const Parser::name_stack_range_t&, bool);
+		typedef bool(*deserialize_func_t)(Param&, Parser&, Parser::name_stack_range_t&, bool);
 		typedef void(*serialize_func_t)(const Param&, Parser&, Parser::name_stack_t&, const Param* diff_param);
 		typedef void(*inspect_func_t)(const Param&, Parser&, Parser::name_stack_t&, S32 min_count, S32 max_count);
 		typedef bool(*validation_func_t)(const Param*);
@@ -395,6 +633,7 @@ namespace LLInitParam
 		} EInitializationState;
 
 		void aggregateBlockData(BlockDescriptor& src_block_data);
+		void addParam(ParamDescriptorPtr param, const char* name);
 
 		typedef boost::unordered_map<const std::string, ParamDescriptorPtr>						param_map_t; 
 		typedef std::vector<ParamDescriptorPtr>													param_list_t; 
@@ -410,48 +649,58 @@ namespace LLInitParam
 		class BaseBlock*				mCurrentBlockPtr;		// pointer to block currently being constructed
 	};
 
-	class LL_COMMON_API BaseBlock
-	{
-	public:
 		//TODO: implement in terms of owned_ptr
 		template<typename T>
-		class Lazy
+	class LazyValue
 		{
 		public:
-			Lazy()
+		LazyValue()
 				: mPtr(NULL)
 			{}
 
-			~Lazy()
+		~LazyValue()
 			{
 				delete mPtr;
 			}
 
-			Lazy(const Lazy& other)
+		LazyValue(const T& value)
 			{
-				if (other.mPtr)
+			mPtr = new T(value);
+		}
+
+		LazyValue(const LazyValue& other)
+		:	mPtr(NULL)
 				{
-					mPtr = new T(*other.mPtr);
+			*this = other;
 				}
-				else
+
+		LazyValue& operator = (const LazyValue& other)
 				{
+			if (!other.mPtr)
+			{
+				delete mPtr;
 					mPtr = NULL;
 				}
-			}
-
-			Lazy<T>& operator = (const Lazy<T>& other)
+			else
 			{
-				if (other.mPtr)
+				if (!mPtr)
 				{
 					mPtr = new T(*other.mPtr);
 				}
 				else
 				{
-					mPtr = NULL;
+					*mPtr = *(other.mPtr);
+				}
 				}
 				return *this;
 			}
 
+		bool operator==(const LazyValue& other) const
+		{
+			if (empty() || other.empty()) return false;
+			return *mPtr == *other.mPtr;
+		}
+
 			bool empty() const
 			{
 				return mPtr == NULL;
@@ -459,18 +708,29 @@ namespace LLInitParam
 
 			void set(const T& other)
 			{
-				delete mPtr;
+			if (!mPtr)
+			{
 				mPtr = new T(other);
 			}
+			else
+			{
+				*mPtr = other;
+			}
+		}
 
 			const T& get() const
 			{
-				return ensureInstance();
+			return *ensureInstance();
 			}
 
 			T& get()
 			{
-				return ensureInstance();
+			return *ensureInstance();
+		}
+
+		operator const T&() const
+		{ 
+			return get(); 
 			}
 
 		private:
@@ -485,13 +745,50 @@ namespace LLInitParam
 			}
 
 		private:
-			// if you get a compilation error with this, that means you are using a forward declared struct for T
-			// unfortunately, the type traits we rely on don't work with forward declared typed
-			//static const int dummy = sizeof(T);
 
 			mutable T* mPtr;
 		};
 
+	// root class of all parameter blocks
+
+	class LL_COMMON_API BaseBlock
+	{
+	public:
+		// lift block tags into baseblock namespace so derived classes do not need to qualify them
+		typedef LLInitParam::IS_A_BLOCK IS_A_BLOCK;
+		typedef LLInitParam::NOT_BLOCK NOT_A_BLOCK;
+
+		template<typename T>
+		struct Sequential : public LLTypeTags::TypeTagBase<T, 2>
+		{
+			template <typename S> struct Cons { typedef Sequential<ParamValue<S> > value_t; };
+			template <typename S> struct Cons<Sequential<S> > { typedef Sequential<S> value_t; };
+		};
+
+		template<typename T>
+		struct Atomic : public LLTypeTags::TypeTagBase<T, 1>
+		{
+			template <typename S> struct Cons { typedef Atomic<ParamValue<S> > value_t; };
+			template <typename S> struct Cons<Atomic<S> > { typedef Atomic<S> value_t; };
+		};
+
+		template<typename T, typename BLOCK_T = typename IsBlock<T>::value_t >
+		struct Lazy : public LLTypeTags::TypeTagBase<T, 0>
+		{
+			template <typename S> struct Cons
+			{
+				typedef Lazy<ParamValue<S, BLOCK_T>, BLOCK_T> value_t;
+			};
+			template <typename S> struct Cons<Lazy<S, IS_A_BLOCK> >
+			{
+				typedef Lazy<S, IS_A_BLOCK> value_t;
+			};
+			template <typename S> struct Cons<Lazy<S, NOT_A_BLOCK> >
+			{
+				typedef Lazy<S, BLOCK_T> value_t;
+			};
+		};
+
 		// "Multiple" constraint types, put here in root class to avoid ambiguity during use
 		struct AnyAmount
 		{
@@ -557,12 +854,12 @@ namespace LLInitParam
 		// Blocks can override this to do custom tracking of changes
 		virtual void paramChanged(const Param& changed_param, bool user_provided) {}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
 		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const;
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const BaseBlock& other)
@@ -576,10 +873,17 @@ namespace LLInitParam
 			return false;
 		}
 
-		static void addParam(BlockDescriptor& block_data, ParamDescriptorPtr param, const char* name);
-
 		ParamDescriptorPtr findParamDescriptor(const Param& param);
 
+		// take all provided params from other and apply to self
+		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			static BlockDescriptor sBlockDescriptor;
+			return sBlockDescriptor;
+		}
+
 	protected:
 		void init(BlockDescriptor& descriptor, BlockDescriptor& base_descriptor, size_t block_size);
 
@@ -588,25 +892,11 @@ namespace LLInitParam
 		{
 			return mergeBlock(block_data, source, overwrite);
 		}
-		// take all provided params from other and apply to self
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite);
-
-		static BlockDescriptor& selfBlockDescriptor()
-		{
-			static BlockDescriptor sBlockDescriptor;
-			return sBlockDescriptor;
-		}
 
 	private:
 		const std::string& getParamName(const BlockDescriptor& block_data, const Param* paramp) const;
 	};
 
-	template<typename T>
-	struct ParamCompare<BaseBlock::Lazy<T>, false >
-	{
-		static bool equals(const BaseBlock::Lazy<T>& a, const BaseBlock::Lazy<T>& b) { return !a.empty() || !b.empty(); }
-	};
-
 	class LL_COMMON_API Param
 	{
 	public:
@@ -635,256 +925,68 @@ namespace LLInitParam
 			// get address of enclosing BLOCK class using stored offset to enclosing BaseBlock class
 			return *const_cast<BaseBlock*>
 				(reinterpret_cast<const BaseBlock*>
-					(my_addr - (ptrdiff_t)(S32)mEnclosingBlockOffset));
+					(my_addr - (ptrdiff_t)getEnclosingBlockOffset()));
 		}
 
-	private:
-		friend class BaseBlock;
-
-		U32		mEnclosingBlockOffset:31;
-		U32		mIsProvided:1;
-
-	};
-
-	// these templates allow us to distinguish between template parameters
-	// that derive from BaseBlock and those that don't
-	template<typename T, typename Void = void>
-	struct IsBlock
-	{
-		static const bool value = false;
-		struct EmptyBase {};
-		typedef EmptyBase base_class_t;
-	};
-
-	template<typename T>
-	struct IsBlock<T, typename T::baseblock_base_class_t>
-	{
-		static const bool value = true;
-		typedef BaseBlock base_class_t;
-	};
-
-	template<typename T>
-	struct IsBlock<BaseBlock::Lazy<T>, typename T::baseblock_base_class_t >
-	{
-		static const bool value = true;
-		typedef BaseBlock base_class_t;
-	};
-
-	template<typename T, typename NAME_VALUE_LOOKUP, bool VALUE_IS_BLOCK = IsBlock<T>::value>
-	class ParamValue : public NAME_VALUE_LOOKUP
+		U32 getEnclosingBlockOffset() const
 	{
-	public:
-		typedef const T&							value_assignment_t;
-		typedef T									value_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, VALUE_IS_BLOCK>	self_t;
-
-		ParamValue(): mValue() {}
-		ParamValue(value_assignment_t other) : mValue(other) {}
-
-		void setValue(value_assignment_t val)
-		{
-			mValue = val;
-		}
-
-		value_assignment_t getValue() const
-		{
-			return mValue;
-		}
-
-		T& getValue()
-		{
-			return mValue;
-		}
-
-		operator value_assignment_t() const
-		{
-			return mValue;
-		}
-
-		value_assignment_t operator()() const
-		{
-			return mValue;
-		}
-
-		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(name, mValue))
-			{
-				setValueName(name);
-			}
-
-			return *this;
+			return ((U32)mEnclosingBlockOffsetHigh << 16) | (U32)mEnclosingBlockOffsetLow;
 		}
 
-	protected:
-		T mValue;
-	};
-
-	template<typename T, typename NAME_VALUE_LOOKUP>
-	class ParamValue<T, NAME_VALUE_LOOKUP, true> 
-	:	public T,
-		public NAME_VALUE_LOOKUP
-	{
-	public:
-		typedef const T&							value_assignment_t;
-		typedef T									value_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP, true>	self_t;
-
-		ParamValue() 
-		:	T(),
-			mValidated(false)
-		{}
-
-		ParamValue(value_assignment_t other)
-		:	T(other),
-			mValidated(false)
-		{}
-
-		void setValue(value_assignment_t val)
-		{
-			*this = val;
-		}
-
-		value_assignment_t getValue() const
-		{
-			return *this;
-		}
-
-		T& getValue()
-		{
-			return *this;
-		}
-
-		operator value_assignment_t() const
-		{
-			return *this;
-		}
-		
-		value_assignment_t operator()() const
-		{
-			return *this;
-		}
-
-		void operator ()(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			*this = name;
-		}
-
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(name, *this))
-			{
-				setValueName(name);
-			}
-
-			return *this;
-		}
-
-	protected:
-		mutable bool 	mValidated; // lazy validation flag
-	};
-
-	template<typename NAME_VALUE_LOOKUP>
-	class ParamValue<std::string, NAME_VALUE_LOOKUP, false>
-	: public NAME_VALUE_LOOKUP
-	{
-	public:
-		typedef const std::string&	value_assignment_t;
-		typedef std::string			value_t;
-		typedef ParamValue<std::string, NAME_VALUE_LOOKUP, false>	self_t;
-
-		ParamValue(): mValue() {}
-		ParamValue(value_assignment_t other) : mValue(other) {}
-
-		void setValue(value_assignment_t val)
-		{
-			if (NAME_VALUE_LOOKUP::getValueFromName(val, mValue))
-			{
-				NAME_VALUE_LOOKUP::setValueName(val);
-			}
-			else
-			{
-				mValue = val;
-			}
-		}
-
-		value_assignment_t getValue() const
-		{
-			return mValue;
-		}
-
-		std::string& getValue()
-		{
-			return mValue;
-		}
-
-		operator value_assignment_t() const
-		{
-			return mValue;
-		}
+	private:
+		friend class BaseBlock;
 
-		value_assignment_t operator()() const
-		{
-			return mValue;
-		}
+		//24 bits for member offset field and 1 bit for provided flag
+		U16		mEnclosingBlockOffsetLow;
+		U8		mEnclosingBlockOffsetHigh:7;
+		U8		mIsProvided:1;
 
-	protected:
-		std::string mValue;
 	};
 
-
 	template<typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
 	struct ParamIterator
 	{
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::const_iterator		const_iterator;
-		typedef typename std::vector<ParamValue<T, NAME_VALUE_LOOKUP> >::iterator			iterator;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::const_iterator	const_iterator;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t >::iterator			iterator;
 	};
 
-	// specialize for custom parsing/decomposition of specific classes
-	// e.g. TypedParam<LLRect> has left, top, right, bottom, etc...
+	// wrapper for parameter with a known type
+	// specialized to handle 4 cases:
+	// simple "scalar" value
+	// parameter that is itself a block
+	// multiple scalar values, stored in a vector
+	// multiple blocks, stored in a vector
 	template<typename	T,
 			typename	NAME_VALUE_LOOKUP = TypeValues<T>,
 			bool		HAS_MULTIPLE_VALUES = false,
-			bool		VALUE_IS_BLOCK = IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>
+			typename	VALUE_IS_BLOCK = typename IsBlock<ParamValue<typename LLTypeTags::Sorted<T>::value_t> >::value_t>
 	class TypedParam 
 	:	public Param, 
-		public ParamValue<T, NAME_VALUE_LOOKUP>
+		public NAME_VALUE_LOOKUP::type_value_t
 	{
+	protected:
+		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>	self_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>						param_value_t;
+		typedef typename param_value_t::default_value_t									default_value_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t								named_value_t;
 	public:
-		typedef	TypedParam<T, NAME_VALUE_LOOKUP, HAS_MULTIPLE_VALUES, VALUE_IS_BLOCK>		self_t;
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>											param_value_t;
-		typedef typename param_value_t::value_assignment_t				value_assignment_t;
-		typedef NAME_VALUE_LOOKUP															name_value_lookup_t;
+		typedef typename param_value_t::value_t											value_t;
 
-		using param_value_t::operator();
+		using named_value_t::operator();
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
-		:	Param(block_descriptor.mCurrentBlockPtr)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+		:	Param(block_descriptor.mCurrentBlockPtr),
+			named_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
- 				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
-
-			setValue(value);
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 			// no further names in stack, attempt to parse value now
@@ -893,9 +995,9 @@ namespace LLInitParam
 				std::string name;
 
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist()
+				if(named_value_t::valueNamesExist()
 					&& parser.readValue(name)
-					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+					&& named_value_t::getValueFromName(name, typed_param.getValue()))
 				{
 					typed_param.setValueName(name);
 					typed_param.setProvided();
@@ -939,7 +1041,9 @@ namespace LLInitParam
 				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
 				{
 					std::string calculated_key = typed_param.calcValueName(typed_param.getValue());
-					if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key))
+					if (calculated_key.size() 
+						&& (!diff_param 
+							|| !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), calculated_key)))
 					{
 						parser.writeValue(calculated_key, name_stack);
 					}
@@ -952,22 +1056,23 @@ namespace LLInitParam
 			// tell parser about our actual type
 			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
 			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
-			if (name_value_lookup_t::getPossibleValues())
+			if (named_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
 			}
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const value_t& val, bool flag_as_provided = true)
 		{
-			param_value_t::clearValueName();
+			named_value_t::clearValueName();
 			setValue(val);
 			setProvided(flag_as_provided);
 		}
 
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+		self_t& operator =(const typename named_value_t::name_t& name)
 		{
-			return static_cast<self_t&>(param_value_t::operator =(name));
+			named_value_t::assignNamedValue(name);
+			return *this;
 		}
 
 	protected:
@@ -992,41 +1097,47 @@ namespace LLInitParam
 			}
 			return false;
 		}
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	// parameter that is a block
 	template <typename T, typename NAME_VALUE_LOOKUP>
-	class TypedParam<T, NAME_VALUE_LOOKUP, false, true> 
+	class TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK> 
 	:	public Param,
-		public ParamValue<T, NAME_VALUE_LOOKUP>
+		public NAME_VALUE_LOOKUP::type_value_t
 	{
+	protected:
+		typedef ParamValue<typename LLTypeTags::Sorted<T>::value_t>	param_value_t;
+		typedef typename param_value_t::default_value_t				default_value_t;
+		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IS_A_BLOCK>	self_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t			named_value_t;
 	public:
-		typedef ParamValue<T, NAME_VALUE_LOOKUP>				param_value_t;
-		typedef typename param_value_t::value_assignment_t		value_assignment_t;
-		typedef TypedParam<T, NAME_VALUE_LOOKUP, false, true>	self_t;
-		typedef NAME_VALUE_LOOKUP								name_value_lookup_t;
+		using named_value_t::operator();
+		typedef typename param_value_t::value_t						value_t;
 
-		using param_value_t::operator();
-
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr),
-			param_value_t(value)
+			named_value_t(value)
 		{
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func, 
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
 		}
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
 			self_t& typed_param = static_cast<self_t&>(param);
 
@@ -1034,9 +1145,9 @@ namespace LLInitParam
 			{	// try to parse a known named value
 				std::string name;
 
-				if(name_value_lookup_t::valueNamesExist()
+				if(named_value_t::valueNamesExist()
 					&& parser.readValue(name)				
-					&& name_value_lookup_t::getValueFromName(name, typed_param.getValue()))
+					&& named_value_t::getValueFromName(name, typed_param.getValue()))
 				{
 					typed_param.setValueName(name);
 					typed_param.setProvided();
@@ -1068,9 +1179,9 @@ namespace LLInitParam
 			std::string key = typed_param.getValueName();
 			if (!key.empty())
 			{
-				if (!parser.writeValue(key, name_stack))
+				if (!diff_param || !ParamCompare<std::string>::equals(static_cast<const self_t*>(diff_param)->getValueName(), key))
 				{
-					return;
+					parser.writeValue(key, name_stack);
 				}
 			}
 			else
@@ -1081,8 +1192,16 @@ namespace LLInitParam
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
-			// I am a param that is also a block, so just recurse into my contents
 			const self_t& typed_param = static_cast<const self_t&>(param);
+
+			// tell parser about our actual type
+			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+			if (named_value_t::getPossibleValues())
+			{
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
+			}
+
 			typed_param.inspectBlock(parser, name_stack, min_count, max_count);
 		}
 
@@ -1100,32 +1219,34 @@ namespace LLInitParam
 		}
 
 		// assign block contents to this param-that-is-a-block
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const value_t& val, bool flag_as_provided = true)
 		{
 			setValue(val);
-			param_value_t::clearValueName();
+			named_value_t::clearValueName();
 			// force revalidation of block
 			// next call to isProvided() will update provision status based on validity
 			param_value_t::mValidated = false;
 			setProvided(flag_as_provided);
 		}
 
-		self_t& operator =(const typename NAME_VALUE_LOOKUP::name_t& name)
+		self_t& operator =(const typename named_value_t::name_t& name)
 		{
-			return static_cast<self_t&>(param_value_t::operator =(name));
+			named_value_t::assignNamedValue(name);
+			return *this;
 		}
 
 		// propagate changed status up to enclosing block
 		/*virtual*/ void paramChanged(const Param& changed_param, bool user_provided)
 		{ 
 			param_value_t::paramChanged(changed_param, user_provided);
+
 			if (user_provided)
 			{
 				// a child param has been explicitly changed
 				// so *some* aspect of this block is now provided
 				param_value_t::mValidated = false;
 				setProvided();
-				param_value_t::clearValueName();
+				named_value_t::clearValueName();
 			}
 			else
 			{
@@ -1149,7 +1270,7 @@ namespace LLInitParam
 
 			if (src_typed_param.anyProvided())
 			{
-				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::selfBlockDescriptor(), src_typed_param, overwrite))
+				if (dst_typed_param.mergeBlockParam(src_typed_param.isProvided(), dst_typed_param.isProvided(), param_value_t::getBlockDescriptor(), src_typed_param, overwrite))
 				{
 					dst_typed_param.clearValueName();
 					dst_typed_param.setProvided(true);
@@ -1158,56 +1279,72 @@ namespace LLInitParam
 			}
 			return false;
 		}
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func, 
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
-	// container of non-block parameters
+	// list of non-block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
-	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false> 
+	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK> 
 	:	public Param
 	{
+	protected:
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, NOT_BLOCK>		self_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
+		typedef container_t														default_value_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
+		
 	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, false>		self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>					param_value_t;
-		typedef typename std::vector<param_value_t>							container_t;
-		typedef const container_t&											value_assignment_t;
-
 		typedef typename param_value_t::value_t								value_t;
-		typedef NAME_VALUE_LOOKUP											name_value_lookup_t;
 		
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), std::back_inserter(mValues));
 
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
+
 			}
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{ 
+			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
 			value_t value;
+
+			// pop first element if empty string
+			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+			{
+				++new_name_stack_range.first;
+			}
+
 			// no further names in stack, attempt to parse value now
 			if (name_stack_range.first == name_stack_range.second)
 			{	
 				std::string name;
 				
 				// try to parse a known named value
-				if(name_value_lookup_t::valueNamesExist()
+				if(named_value_t::valueNamesExist()
 					&& parser.readValue(name)
-					&& name_value_lookup_t::getValueFromName(name, value))
+					&& named_value_t::getValueFromName(name, value))
 				{
 					typed_param.add(value);
 					typed_param.mValues.back().setValueName(name);
@@ -1225,14 +1362,14 @@ namespace LLInitParam
 		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
 		{
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			if (!typed_param.isProvided() || name_stack.empty()) return;
+			if (!typed_param.isProvided()) return;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
 				++it)
 			{
 				std::string key = it->getValueName();
-				name_stack.back().second = true;
+				name_stack.push_back(std::make_pair(std::string(), true));
 
 				if(key.empty())
 				// not parsed via name values, write out value directly
@@ -1254,19 +1391,21 @@ namespace LLInitParam
 						break;
 					}
 				}
+
+				name_stack.pop_back();
 			}
 		}
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
 			parser.inspectValue<VALUE_TYPE>(name_stack, min_count, max_count, NULL);
-			if (name_value_lookup_t::getPossibleValues())
+			if (named_value_t::getPossibleValues())
 			{
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, name_value_lookup_t::getPossibleValues());
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
 			}
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+		void set(const container_t& val, bool flag_as_provided = true)
 		{
 			mValues = val;
 			setProvided(flag_as_provided);
@@ -1274,26 +1413,24 @@ namespace LLInitParam
 
 		param_value_t& add()
 		{
-			mValues.push_back(param_value_t(value_t()));
+			mValues.push_back(value_t());
 			Param::setProvided();
 			return mValues.back();
 		}
 
 		self_t& add(const value_t& item)
 		{
-			param_value_t param_value;
-			param_value.setValue(item);
-			mValues.push_back(param_value);
+			mValues.push_back(item);
 			setProvided();
 			return *this;
 		}
 
-		self_t& add(const typename name_value_lookup_t::name_t& name)
+		self_t& add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (named_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1303,9 +1440,9 @@ namespace LLInitParam
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return mValues; } 
+		operator const container_t&() const { return mValues; } 
 		// explicit conversion		
-		value_assignment_t operator()() const { return mValues; }
+		const container_t& operator()() const { return mValues; }
 
 		typedef typename container_t::iterator iterator;
 		typedef typename container_t::const_iterator const_iterator;
@@ -1346,62 +1483,79 @@ namespace LLInitParam
 		}
 
 		container_t		mValues;
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
-	// container of block parameters
+	// list of block parameters
 	template <typename VALUE_TYPE, typename NAME_VALUE_LOOKUP>
-	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true> 
+	class TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK> 
 	:	public Param
 	{
+	protected:
+		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, IS_A_BLOCK>		self_t;
+		typedef ParamValue<typename LLTypeTags::Sorted<VALUE_TYPE>::value_t>	param_value_t;
+		typedef typename std::vector<typename NAME_VALUE_LOOKUP::type_value_t>	container_t;
+		typedef typename NAME_VALUE_LOOKUP::type_value_t						named_value_t;
+		typedef container_t														default_value_t;
+		typedef typename container_t::iterator									iterator;
+		typedef typename container_t::const_iterator							const_iterator;
 	public:
-		typedef TypedParam<VALUE_TYPE, NAME_VALUE_LOOKUP, true, true>	self_t;
-		typedef ParamValue<VALUE_TYPE, NAME_VALUE_LOOKUP>				param_value_t;
-		typedef typename std::vector<param_value_t>						container_t;
-		typedef const container_t&										value_assignment_t;
 		typedef typename param_value_t::value_t							value_t;
-		typedef NAME_VALUE_LOOKUP										name_value_lookup_t;
 
-		TypedParam(BlockDescriptor& block_descriptor, const char* name, value_assignment_t value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count) 
+		TypedParam(BlockDescriptor& block_descriptor, const char* name, const default_value_t& value, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count)
 		:	Param(block_descriptor.mCurrentBlockPtr)
 		{
 			std::copy(value.begin(), value.end(), back_inserter(mValues));
 
 			if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 			{
-				ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
-												block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
-												&mergeWith,
-												&deserializeParam,
-												&serializeParam,
-												validate_func,
-												&inspectParam,
-												min_count, max_count));
-				BaseBlock::addParam(block_descriptor, param_descriptor, name);
+				init(block_descriptor, validate_func, min_count, max_count, name);
 			}
 		} 
 
 		bool isProvided() const { return Param::anyProvided(); }
 
-		static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name) 
+		static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name) 
 		{ 
+			Parser::name_stack_range_t new_name_stack_range(name_stack_range);
 			self_t& typed_param = static_cast<self_t&>(param);
 			bool new_value = false;
+			bool new_array_value = false;
+
+			// pop first element if empty string
+			if (new_name_stack_range.first != new_name_stack_range.second && new_name_stack_range.first->first.empty())
+			{
+				new_array_value = new_name_stack_range.first->second;
+				++new_name_stack_range.first;
+			}
 
-			if (new_name || typed_param.mValues.empty())
+			if (new_name || new_array_value || typed_param.mValues.empty())
 			{
 				new_value = true;
 				typed_param.mValues.push_back(value_t());
 			}
-
 			param_value_t& value = typed_param.mValues.back();
 
 			if (name_stack_range.first == name_stack_range.second)
 			{	// try to parse a known named value
 				std::string name;
 
-				if(name_value_lookup_t::valueNamesExist()
+				if(named_value_t::valueNamesExist()
 					&& parser.readValue(name)
-					&& name_value_lookup_t::getValueFromName(name, value.getValue()))
+					&& named_value_t::getValueFromName(name, value.getValue()))
 				{
 					typed_param.mValues.back().setValueName(name);
 					typed_param.setProvided();
@@ -1410,9 +1564,13 @@ namespace LLInitParam
 			}
 
 			// attempt to parse block...
-			if(value.deserializeBlock(parser, name_stack_range, new_name))
+			if(value.deserializeBlock(parser, new_name_stack_range, new_name))
 			{
 				typed_param.setProvided();
+				if (new_array_value)
+				{
+					name_stack_range.first->second = false;
+				}
 				return true;
 			}
 
@@ -1428,13 +1586,13 @@ namespace LLInitParam
 		static void serializeParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, const Param* diff_param)
 		{
 			const self_t& typed_param = static_cast<const self_t&>(param);
-			if (!typed_param.isProvided() || name_stack.empty()) return;
+			if (!typed_param.isProvided()) return;
 
 			for (const_iterator it = typed_param.mValues.begin(), end_it = typed_param.mValues.end();
 				it != end_it;
 				++it)
 			{
-				name_stack.back().second = true;
+				name_stack.push_back(std::make_pair(std::string(), true));
 
 				std::string key = it->getValueName();
 				if (!key.empty())
@@ -1447,16 +1605,27 @@ namespace LLInitParam
 				{
 					it->serializeBlock(parser, name_stack, NULL);
 				}
+
+				name_stack.pop_back();
 			}
 		}
 
 		static void inspectParam(const Param& param, Parser& parser, Parser::name_stack_t& name_stack, S32 min_count, S32 max_count)
 		{
-			// I am a vector of blocks, so describe my contents recursively
-			param_value_t(value_t()).inspectBlock(parser, name_stack, min_count, max_count);
+			const param_value_t& value_param = param_value_t(value_t());
+
+			// tell parser about our actual type
+			parser.inspectValue<value_t>(name_stack, min_count, max_count, NULL);
+			// then tell it about string-based alternatives ("red", "blue", etc. for LLColor4)
+			if (named_value_t::getPossibleValues())
+			{
+				parser.inspectValue<std::string>(name_stack, min_count, max_count, named_value_t::getPossibleValues());
 		}
 
-		void set(value_assignment_t val, bool flag_as_provided = true)
+			value_param.inspectBlock(parser, name_stack, min_count, max_count);
+		}
+
+		void set(const container_t& val, bool flag_as_provided = true)
 		{
 			mValues = val;
 			setProvided(flag_as_provided);
@@ -1476,12 +1645,12 @@ namespace LLInitParam
 			return *this;
 		}
 
-		self_t& add(const typename name_value_lookup_t::name_t& name)
+		self_t& add(const typename named_value_t::name_t& name)
 		{
 			value_t value;
 
 			// try to parse a per type named value
-			if (name_value_lookup_t::getValueFromName(name, value))
+			if (named_value_t::getValueFromName(name, value))
 			{
 				add(value);
 				mValues.back().setValueName(name);
@@ -1490,12 +1659,10 @@ namespace LLInitParam
 		}
 
 		// implicit conversion
-		operator value_assignment_t() const { return mValues; } 
+		operator const container_t&() const { return mValues; } 
 		// explicit conversion
-		value_assignment_t operator()() const { return mValues; }
+		const container_t& operator()() const { return mValues; }
 
-		typedef typename container_t::iterator iterator;
-		typedef typename container_t::const_iterator const_iterator;
 		iterator begin() { return mValues.begin(); }
 		iterator end() { return mValues.end(); }
 		const_iterator begin() const { return mValues.begin(); }
@@ -1542,6 +1709,20 @@ namespace LLInitParam
 		}
 
 		container_t			mValues;
+
+	private:
+		void init( BlockDescriptor &block_descriptor, ParamDescriptor::validation_func_t validate_func, S32 min_count, S32 max_count, const char* name ) 
+		{
+			ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
+				block_descriptor.mCurrentBlockPtr->getHandleFromParam(this),
+				&mergeWith,
+				&deserializeParam,
+				&serializeParam,
+				validate_func,
+				&inspectParam,
+				min_count, max_count));
+			block_descriptor.addParam(param_descriptor, name);
+		}
 	};
 
 	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
@@ -1556,13 +1737,13 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
 		bool mergeBlockParam(bool source_provided, bool dest_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
@@ -1580,7 +1761,7 @@ namespace LLInitParam
 		bool mergeBlock(BlockDescriptor& block_data, const self_t& other, bool overwrite)
 		{
 			mCurChoice = other.mCurChoice;
-			return base_block_t::mergeBlock(selfBlockDescriptor(), other, overwrite);
+			return base_block_t::mergeBlock(getBlockDescriptor(), other, overwrite);
 		}
 
 		// clear out old choice when param has changed
@@ -1601,38 +1782,38 @@ namespace LLInitParam
 			base_block_t::paramChanged(changed_param, user_provided);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		ChoiceBlock()
 		:	mCurChoice(0)
 		{
-			BaseBlock::init(selfBlockDescriptor(), base_block_t::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), base_block_t::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		// Alternatives are mutually exclusive wrt other Alternatives in the same block.  
 		// One alternative in a block will always have isChosen() == true.
 		// At most one alternative in a block will have isProvided() == true.
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Alternative : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>	super_t;
+			typedef typename super_t::value_t				value_t;
+			typedef typename super_t::default_value_t		default_value_t;
+
 		public:
 			friend class ChoiceBlock<DERIVED_BLOCK>;
 
-			typedef Alternative<T, NAME_VALUE_LOOKUP>									self_t;
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
-
 			using super_t::operator =;
 
-			explicit Alternative(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1),
+			explicit Alternative(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1),
 				mOriginalValue(val)
 			{
 				// assign initial choice to first declared option
-				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr);
-				if (LL_UNLIKELY(DERIVED_BLOCK::selfBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
+				DERIVED_BLOCK* blockp = ((DERIVED_BLOCK*)DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr);
+				if (LL_UNLIKELY(DERIVED_BLOCK::getBlockDescriptor().mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					if(blockp->mCurChoice == 0)
 					{
@@ -1646,27 +1827,27 @@ namespace LLInitParam
 				static_cast<enclosing_block_t&>(Param::enclosingBlock()).paramChanged(*this, true);
 			}
 
-			void chooseAs(value_assignment_t val)
+			void chooseAs(const value_t& val)
 			{
 				super_t::set(val);
 			}
 
-			void operator =(value_assignment_t val)
+			void operator =(const value_t& val)
 			{
 				super_t::set(val);
 			}
 
-			void operator()(typename super_t::value_assignment_t val) 
+			void operator()(const value_t& val) 
 			{ 
 				super_t::set(val);
 			}
 
-			operator value_assignment_t() const 
+			operator const value_t&() const 
 			{
 				return (*this)();
 			} 
 
-			value_assignment_t operator()() const 
+			const value_t& operator()() const 
 			{ 
 				if (static_cast<enclosing_block_t&>(Param::enclosingBlock()).getCurrentChoice() == this)
 				{
@@ -1681,11 +1862,11 @@ namespace LLInitParam
 			}
 		
 		private:
-			T			mOriginalValue;
+			default_value_t mOriginalValue;
 		};
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
@@ -1705,6 +1886,8 @@ namespace LLInitParam
 	:	public BASE_BLOCK
 	{
 		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	self_t;
+
+	protected:
 		typedef Block<DERIVED_BLOCK, BASE_BLOCK>	block_t;
 
 	public:
@@ -1713,80 +1896,82 @@ namespace LLInitParam
 		// take all provided params from other and apply to self
 		bool overwriteFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, true);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, true);
 		}
 
 		// take all provided params that are not already provided, and apply to self
 		bool fillFrom(const self_t& other)
 		{
-			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(selfBlockDescriptor(), other, false);
+			return static_cast<DERIVED_BLOCK*>(this)->mergeBlock(getBlockDescriptor(), other, false);
 		}
 
-		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return selfBlockDescriptor(); }
-		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return selfBlockDescriptor(); }
+		virtual const BlockDescriptor& mostDerivedBlockDescriptor() const { return getBlockDescriptor(); }
+		virtual BlockDescriptor& mostDerivedBlockDescriptor() { return getBlockDescriptor(); }
 
 	protected:
 		Block()
 		{
 			//#pragma message("Parsing LLInitParam::Block")
-			BaseBlock::init(selfBlockDescriptor(), BASE_BLOCK::selfBlockDescriptor(), sizeof(DERIVED_BLOCK));
+			BaseBlock::init(getBlockDescriptor(), BASE_BLOCK::getBlockDescriptor(), sizeof(DERIVED_BLOCK));
 		}
 
 		//
 		// Nested classes for declaring parameters
 		//
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Optional : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
-		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
+			typedef typename super_t::value_t					value_t;
+			typedef typename super_t::default_value_t			default_value_t;
 
+		public:
 			using super_t::operator();
 			using super_t::operator =;
 			
-			explicit Optional(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, NULL, 0, 1)
+			explicit Optional(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, NULL, 0, 1)
 			{
 				//#pragma message("Parsing LLInitParam::Block::Optional")
 			}
 
-			Optional& operator =(value_assignment_t val)
+			Optional& operator =(const value_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(value_assignment_t val)
+			DERIVED_BLOCK& operator()(const value_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
 			}
 		};
 
-		template <typename T, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Mandatory : public TypedParam<T, NAME_VALUE_LOOKUP, false>
 		{
-		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, false, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>		super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, false>		super_t;
 			typedef Mandatory<T, NAME_VALUE_LOOKUP>										self_t;
-			typedef typename super_t::value_assignment_t								value_assignment_t;
+			typedef typename super_t::value_t					value_t;
+			typedef typename super_t::default_value_t			default_value_t;
 
+		public:
 			using super_t::operator();
 			using super_t::operator =;
 
 			// mandatory parameters require a name to be parseable
-			explicit Mandatory(const char* name = "", value_assignment_t val = defaultValue<T>())
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, val, &validate, 1, 1)
+			explicit Mandatory(const char* name = "", const default_value_t& val = defaultValue<default_value_t>())
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, val, &validate, 1, 1)
 			{}
 
-			Mandatory& operator =(value_assignment_t val)
+			Mandatory& operator =(const value_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+			DERIVED_BLOCK& operator()(const value_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1800,28 +1985,29 @@ namespace LLInitParam
 
 		};
 
-		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = TypeValues<T> >
+		template <typename T, typename RANGE = BaseBlock::AnyAmount, typename NAME_VALUE_LOOKUP = typename TypeValues<T>::type_value_t >
 		class Multiple : public TypedParam<T, NAME_VALUE_LOOKUP, true>
 		{
-		public:
-			typedef TypedParam<T, NAME_VALUE_LOOKUP, true, IsBlock<ParamValue<T, NAME_VALUE_LOOKUP> >::value>	super_t;
+			typedef TypedParam<T, NAME_VALUE_LOOKUP, true>	super_t;
 			typedef Multiple<T, RANGE, NAME_VALUE_LOOKUP>							self_t;
 			typedef typename super_t::container_t									container_t;
-			typedef typename super_t::value_assignment_t							value_assignment_t;
+			typedef typename super_t::value_t				value_t;
+
+		public:
 			typedef typename super_t::iterator										iterator;
 			typedef typename super_t::const_iterator								const_iterator;
 
 			explicit Multiple(const char* name = "")
-			:	super_t(DERIVED_BLOCK::selfBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
+			:	super_t(DERIVED_BLOCK::getBlockDescriptor(), name, container_t(), &validate, RANGE::minCount, RANGE::maxCount)
 			{}
 
-			Multiple& operator =(value_assignment_t val)
+			Multiple& operator =(const container_t& val)
 			{
 				set(val);
 				return *this;
 			}
 
-			DERIVED_BLOCK& operator()(typename super_t::value_assignment_t val)
+			DERIVED_BLOCK& operator()(const container_t& val)
 			{
 				super_t::set(val);
 				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
@@ -1834,13 +2020,15 @@ namespace LLInitParam
 			}
 		};
 
-		class Deprecated : public Param
+		// can appear in data files, but will ignored during parsing
+		// cannot read or write in code
+		class Ignored : public Param
 		{
 		public:
-			explicit Deprecated(const char* name)
-			:	Param(DERIVED_BLOCK::selfBlockDescriptor().mCurrentBlockPtr)
+			explicit Ignored(const char* name)
+			:	Param(DERIVED_BLOCK::getBlockDescriptor().mCurrentBlockPtr)
 			{
-				BlockDescriptor& block_descriptor = DERIVED_BLOCK::selfBlockDescriptor();
+				BlockDescriptor& block_descriptor = DERIVED_BLOCK::getBlockDescriptor();
 				if (LL_UNLIKELY(block_descriptor.mInitializationState == BlockDescriptor::INITIALIZING))
 				{
 					ParamDescriptorPtr param_descriptor = ParamDescriptorPtr(new ParamDescriptor(
@@ -1851,11 +2039,11 @@ namespace LLInitParam
 													NULL,
 													NULL, 
 													0, S32_MAX));
-					BaseBlock::addParam(block_descriptor, param_descriptor, name);
+					block_descriptor.addParam(param_descriptor, name);
 				}
 			}
 			
-			static bool deserializeParam(Param& param, Parser& parser, const Parser::name_stack_range_t& name_stack_range, bool new_name)
+			static bool deserializeParam(Param& param, Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 			{
 				if (name_stack_range.first == name_stack_range.second)
 				{
@@ -1868,19 +2056,46 @@ namespace LLInitParam
 			}
 		};
 
-		// different semantics for documentation purposes, but functionally identical
-		typedef Deprecated Ignored;
+		// can appear in data files, or be written to in code, but data will be ignored
+		// cannot be read in code
+		class Deprecated : public Ignored
+		{
+		public:
+			explicit Deprecated(const char* name) : Ignored(name) {}
 
-	protected:
-		static BlockDescriptor& selfBlockDescriptor()
+			// dummy writer interfaces
+			template<typename T>
+			Deprecated& operator =(const T& val)
+		{
+				// do nothing
+				return *this;
+			}
+
+			template<typename T>
+			DERIVED_BLOCK& operator()(const T& val)
+			{
+				// do nothing
+				return static_cast<DERIVED_BLOCK&>(Param::enclosingBlock());
+			}
+
+			template<typename T>
+			void set(const T& val, bool flag_as_provided = true)
+			{
+				// do nothing
+			}
+		};
+
+	public:
+		static BlockDescriptor& getBlockDescriptor()
 		{
 			static BlockDescriptor sBlockDescriptor;
 			return sBlockDescriptor;
 		}
 
-		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, bool is_block>
+	protected:
+		template <typename T, typename NAME_VALUE_LOOKUP, bool multiple, typename is_block>
 		void changeDefault(TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>& param, 
-			typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_assignment_t value)
+			const typename TypedParam<T, NAME_VALUE_LOOKUP, multiple, is_block>::value_t& value)
 		{
 			if (!param.isProvided())
 			{
@@ -1890,204 +2105,420 @@ namespace LLInitParam
 
 	};
 	
-	template <typename DERIVED_BLOCK, typename BASE_BLOCK = BaseBlock>
-	class BatchBlock
-	:	public Block<DERIVED_BLOCK, BASE_BLOCK>
+	template<typename T, typename BLOCK_T>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::IS_A_BLOCK>, BLOCK_T >, void>
+	{
+		typedef IS_A_BLOCK value_t;
+	};
+
+	template<typename T, typename BLOCK_T>
+	struct IsBlock<ParamValue<BaseBlock::Lazy<T, BaseBlock::NOT_A_BLOCK>, BLOCK_T >, void>
+	{
+		typedef NOT_BLOCK value_t;
+	};
+
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Atomic<T>, typename IsBlock<BaseBlock::Atomic<T> >::value_t >, BLOCK_IDENTIFIER>
+	{
+		typedef typename IsBlock<T>::value_t value_t;
+	};
+
+	template<typename T, typename BLOCK_IDENTIFIER>
+	struct IsBlock<ParamValue<BaseBlock::Sequential<T>, typename IsBlock<BaseBlock::Sequential<T> >::value_t >, BLOCK_IDENTIFIER>
+	{
+		typedef typename IsBlock<T>::value_t value_t;
+	};
+
+
+	template<typename T>
+	struct InnerMostType
 	{
+		typedef T value_t;
+	};
+
+	template<typename T>
+	struct InnerMostType<ParamValue<T, NOT_BLOCK> >
+	{
+		typedef typename InnerMostType<T>::value_t value_t;
+	};
+
+	template<typename T>
+	struct InnerMostType<ParamValue<T, IS_A_BLOCK> >
+	{
+		typedef typename InnerMostType<T>::value_t value_t;
+	};
+
+	template<typename T, typename BLOCK_T>
+	class ParamValue <BaseBlock::Atomic<T>, BLOCK_T>
+	{
+		typedef ParamValue <BaseBlock::Atomic<T>, BLOCK_T> self_t;
+
 	public:
-		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> self_t;
-		typedef Block<DERIVED_BLOCK, BASE_BLOCK> super_t;
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
+
+		ParamValue()
+		:	mValue(),
+			mValidated(false)
+		{}
 
-		BatchBlock()
+		ParamValue(const default_value_t& value)
+		:	mValue(value),
+			mValidated(false)
 		{}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		void setValue(const value_t& val)
+		{
+			mValue.setValue(val);
+		}
+
+		const value_t& getValue() const
+		{
+			return mValue.getValue();
+		}
+
+		value_t& getValue()
+		{
+			return mValue.getValue();
+		}
+
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			if (new_name)
 			{
-				// reset block
-				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
+				resetToDefault();
 			}
-			return super_t::deserializeBlock(p, name_stack_range, new_name);
+			return mValue.deserializeBlock(p, name_stack_range, new_name);
 		}
 
-		bool mergeBlock(BlockDescriptor& block_data, const BaseBlock& other, bool overwrite)
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
 		{
-			if (overwrite)
+			const BaseBlock* base_block = diff_block
+				? &(diff_block->mValue)
+				: NULL;
+			mValue.serializeBlock(p, name_stack, base_block);
+		}
+
+		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
 			{
-				*static_cast<DERIVED_BLOCK*>(this) = defaultBatchValue();
-				// merge individual parameters into destination
-				return super_t::mergeBlock(super_t::selfBlockDescriptor(), other, overwrite);
+			return mValue.inspectBlock(p, name_stack, min_count, max_count);
 			}
-			return false;
+
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			if ((overwrite && source_provided) // new values coming in on top or...
+				|| (!overwrite && !dst_provided)) // values being pushed under with nothing already there
+			{
+				// clear away what is there and take the new stuff as a whole
+				resetToDefault();
+				return mValue.mergeBlock(block_data, source.getValue(), overwrite);
 		}
-	protected:
-		static const DERIVED_BLOCK& defaultBatchValue()
+			
+
+			return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return value_t::getBlockDescriptor();
+		}
+
+
+		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+		void resetToDefault()
 		{
-			static DERIVED_BLOCK default_value;
-			return default_value;
+			static T default_value;
+			mValue = default_value;
 		}
+
+		T	mValue;
 	};
 
-	// FIXME: this specialization is not currently used, as it only matches against the BatchBlock base class
-	// and not the derived class with the actual params
-	template<typename DERIVED_BLOCK,
-			typename BASE_BLOCK,
-			typename NAME_VALUE_LOOKUP>
-	class ParamValue <BatchBlock<DERIVED_BLOCK, BASE_BLOCK>,
-					NAME_VALUE_LOOKUP,
-					true>
-	:	public NAME_VALUE_LOOKUP,
-		protected BatchBlock<DERIVED_BLOCK, BASE_BLOCK>
+	template<typename T>
+	class ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK>
 	{
+		typedef ParamValue <BaseBlock::Sequential<T>, IS_A_BLOCK> self_t;
+
 	public:
-		typedef BatchBlock<DERIVED_BLOCK, BASE_BLOCK> block_t;
-		typedef const BatchBlock<DERIVED_BLOCK, BASE_BLOCK>&	value_assignment_t;
-		typedef block_t value_t;
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
 
 		ParamValue()
-		:	block_t(),
+		:	mValue(),
 			mValidated(false)
-		{}
+		{
+			mCurParam = getBlockDescriptor().mAllParams.begin();
+		}
 
-		ParamValue(value_assignment_t other)
-		:	block_t(other),
+		ParamValue(const default_value_t& value)
+		:	mValue(value),
 			mValidated(false)
 		{
+			mCurParam = getBlockDescriptor().mAllParams.begin();
 		}
 
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
-			*this = val;
+			mValue.setValue(val);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
-			return *this;
+			return mValue.getValue();
 		}
 
-		BatchBlock<DERIVED_BLOCK, BASE_BLOCK>& getValue()
+		value_t& getValue()
 		{
-			return *this;
+			return mValue.getValue();
 		}
 
-		operator value_assignment_t() const
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
-			return *this;
+			if (new_name)
+			{
+				mCurParam = getBlockDescriptor().mAllParams.begin();
 		}
+			if (name_stack_range.first == name_stack_range.second 
+				&& mCurParam != getBlockDescriptor().mAllParams.end())
+			{
+				// deserialize to mCurParam
+				ParamDescriptor& pd = *(*mCurParam);
+				ParamDescriptor::deserialize_func_t deserialize_func = pd.mDeserializeFunc;
+				Param* paramp = mValue.getParamFromHandle(pd.mParamHandle);
 
-		value_assignment_t operator()() const
+				if (deserialize_func 
+					&& paramp 
+					&& deserialize_func(*paramp, p, name_stack_range, new_name))
 		{
-			return *this;
+					++mCurParam;
+					return true;
+				}
+				else
+				{
+					return false;
+				}
+		}
+			else
+			{
+				return mValue.deserializeBlock(p, name_stack_range, new_name);
+			}
+		}
+
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
+		{
+			const BaseBlock* base_block = diff_block
+				? &(diff_block->mValue)
+				: NULL;
+			mValue.serializeBlock(p, name_stack, base_block);
+		}
+
+		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+		{
+			return mValue.inspectBlock(p, name_stack, min_count, max_count);
+		}
+
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
+		{
+			return mValue.mergeBlock(block_data, source.getValue(), overwrite);
+		}
+
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.validateBlock(emit_errors);
+		}
+
+		static BlockDescriptor& getBlockDescriptor()
+		{
+			return value_t::getBlockDescriptor();
 		}
 
-	protected:
 		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+
+		BlockDescriptor::all_params_list_t::iterator	mCurParam;
+		T												mValue;
 	};
 
-	template<typename T, bool IS_BLOCK>
-	class ParamValue <BaseBlock::Lazy<T>,
-					TypeValues<T>,
-					IS_BLOCK>
-	:	public IsBlock<T>::base_class_t
+	template<typename T>
+	class ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK>
+	: public T
 	{
+		typedef ParamValue <BaseBlock::Sequential<T>, NOT_BLOCK> self_t;
+
 	public:
-		typedef ParamValue <BaseBlock::Lazy<T>, TypeValues<T>, false> self_t;
-		typedef const T& value_assignment_t;
-		typedef T value_t;
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef T									default_value_t;
+
+		ParamValue()
+		:	T(),
+			mValidated(false)
+		{}
+	
+		ParamValue(const default_value_t& value)
+		:	T(value.getValue()),
+			mValidated(false)
+		{}
+
+		mutable bool 	mValidated; // lazy validation flag
+	};
+
+	template<typename T, typename BLOCK_T>
+	class ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> 
+	{
+		typedef ParamValue <BaseBlock::Lazy<T, IS_A_BLOCK>, BLOCK_T> self_t;
+
+	public:
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef LazyValue<T>						default_value_t;
 	
 		ParamValue()
 		:	mValue(),
 			mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const default_value_t& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val)
+		ParamValue(const T& value)
+		:	mValue(value),
+			mValidated(false)
+		{}
+
+		void setValue(const value_t& val)
 		{
 			mValue.set(val);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
-		T& getValue()
+		value_t& getValue()
 		{
-			return mValue.get();
+			return mValue.get().getValue();
 		}
 
-		operator value_assignment_t() const
+		bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
-			return mValue.get();
+			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
 		}
 
-		value_assignment_t operator()() const
+		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const self_t* diff_block = NULL) const
 		{
-			return mValue.get();
+			if (mValue.empty()) return;
+			
+			const BaseBlock* base_block = (diff_block && !diff_block->mValue.empty())
+											? &(diff_block->mValue.get().getValue())
+											: NULL;
+			mValue.get().serializeBlock(p, name_stack, base_block);
 		}
 
-		bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
 		{
-			return mValue.get().deserializeBlock(p, name_stack_range, new_name);
+			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
 		}
 
-		void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const
+		bool mergeBlockParam(bool source_provided, bool dst_provided, BlockDescriptor& block_data, const self_t& source, bool overwrite)
 		{
-			if (mValue.empty()) return;
+			return source.mValue.empty() || mValue.get().mergeBlock(block_data, source.getValue(), overwrite);
+		}
 			
-			mValue.get().serializeBlock(p, name_stack, diff_block);
+		bool validateBlock(bool emit_errors = true) const
+		{
+			return mValue.empty() || mValue.get().validateBlock(emit_errors);
 		}
 
-		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
+		static BlockDescriptor& getBlockDescriptor()
 		{
-			if (mValue.empty()) return false;
+			return value_t::getBlockDescriptor();
+		}
 
-			return mValue.get().inspectBlock(p, name_stack, min_count, max_count);
+		mutable bool 	mValidated; // lazy validation flag
+
+	private:
+		LazyValue<T>	mValue;
+	};
+
+	template<typename T, typename BLOCK_T>
+	class ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T>
+		{
+		typedef ParamValue <BaseBlock::Lazy<T, NOT_BLOCK>, BLOCK_T> self_t;
+
+	public:
+		typedef typename InnerMostType<T>::value_t	value_t;
+		typedef LazyValue<T>						default_value_t;
+
+		ParamValue()
+		:	mValue(),
+			mValidated(false)
+		{}
+
+		ParamValue(const default_value_t& other)
+		:	mValue(other),
+			mValidated(false)
+		{}
+
+		ParamValue(const T& value)
+		:	mValue(value),
+			mValidated(false)
+		{}
+			
+		void setValue(const value_t& val)
+		{
+			mValue.set(val);
+		}
+
+		const value_t& getValue() const
+		{
+			return mValue.get().getValue();
+		}
+
+		value_t& getValue()
+		{
+			return mValue.get().getValue();
 		}
 
-	protected:
 		mutable bool 	mValidated; // lazy validation flag
 
 	private:
-		BaseBlock::Lazy<T>	mValue;
+		LazyValue<T>	mValue;
 	};
 
 	template <>
-	class ParamValue <LLSD,
-					TypeValues<LLSD>,
-					false>
-	:	public TypeValues<LLSD>,
-		public BaseBlock
+	class ParamValue <LLSD, NOT_BLOCK>
+	:	public BaseBlock
 	{
 	public:
-		typedef ParamValue<LLSD, TypeValues<LLSD>, false> self_t;
-		typedef const LLSD&	value_assignment_t;
+		typedef LLSD			value_t;
+		typedef LLSD			default_value_t;
 
 		ParamValue()
 		:	mValidated(false)
 		{}
 
-		ParamValue(value_assignment_t other)
+		ParamValue(const default_value_t& other)
 		:	mValue(other),
 			mValidated(false)
 		{}
 
-		void setValue(value_assignment_t val) { mValue = val; }
+		void setValue(const value_t& val) { mValue = val; }
 
-		value_assignment_t getValue() const { return mValue; }
+		const value_t& getValue() const { return mValue; }
 		LLSD& getValue() { return mValue; }
 
-		operator value_assignment_t() const { return mValue; }
-		value_assignment_t operator()() const { return mValue; }
-		
-
 		// block param interface
-		LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack_range, bool new_name);
+		LL_COMMON_API bool deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack_range, bool new_name);
 		LL_COMMON_API void serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block = NULL) const;
 		bool inspectBlock(Parser& p, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
 		{
@@ -2106,8 +2537,7 @@ namespace LLInitParam
 
 	template<typename T>
 	class CustomParamValue
-	:	public Block<ParamValue<T, TypeValues<T> > >,
-		public TypeValues<T>
+	:	public Block<ParamValue<T> >
 	{
 	public:
 		typedef enum e_value_age
@@ -2117,20 +2547,21 @@ namespace LLInitParam
 			BLOCK_AUTHORITATIVE		// mValue is derived from the block parameters, which are authoritative
 		} EValueAge;
 
-		typedef ParamValue<T, TypeValues<T> >	derived_t;
+		typedef ParamValue<T>			derived_t;
 		typedef CustomParamValue<T>				self_t;
 		typedef Block<derived_t>				block_t;
-		typedef const T&						value_assignment_t;
+		typedef T						default_value_t;
 		typedef T								value_t;
+		typedef void					baseblock_base_class_t;
 
 
-		CustomParamValue(const T& value = T())
+		CustomParamValue(const default_value_t& value = T())
 		:	mValue(value),
 			mValueAge(VALUE_AUTHORITATIVE),
 			mValidated(false)
 		{}
 
-		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t name_stack_range, bool new_name)
+		bool deserializeBlock(Parser& parser, Parser::name_stack_range_t& name_stack_range, bool new_name)
 		{
 			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// try to parse direct value T
@@ -2141,8 +2572,6 @@ namespace LLInitParam
 					typed_param.mValueAge = VALUE_AUTHORITATIVE;
 					typed_param.updateBlockFromValue(false);
 
-					typed_param.clearValueName();
-
 					return true;
 				}
 			}
@@ -2156,18 +2585,8 @@ namespace LLInitParam
 			const derived_t& typed_param = static_cast<const derived_t&>(*this);
 			const derived_t* diff_param = static_cast<const derived_t*>(diff_block);
 			
-			std::string key = typed_param.getValueName();
-
-			// first try to write out name of name/value pair
-			if (!key.empty())
-			{
-				if (!diff_param || !ParamCompare<std::string>::equals(diff_param->getValueName(), key))
-				{
-					parser.writeValue(key, name_stack);
-				}
-			}
 			// then try to serialize value directly
-			else if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
+			if (!diff_param || !ParamCompare<T>::equals(typed_param.getValue(), diff_param->getValue()))
             {
 				
 				if (!parser.writeValue(typed_param.getValue(), name_stack)) 
@@ -2197,19 +2616,6 @@ namespace LLInitParam
 			}
 		}
 
-		bool inspectBlock(Parser& parser, Parser::name_stack_t name_stack = Parser::name_stack_t(), S32 min_count = 0, S32 max_count = S32_MAX) const
-		{
-			// first, inspect with actual type...
-			parser.inspectValue<T>(name_stack, min_count, max_count, NULL);
-			if (TypeValues<T>::getPossibleValues())
-			{
-				//...then inspect with possible string values...
-				parser.inspectValue<std::string>(name_stack, min_count, max_count, TypeValues<T>::getPossibleValues());
-			}
-			// then recursively inspect contents...
-			return block_t::inspectBlock(parser, name_stack, min_count, max_count);
-		}
-
 		bool validateBlock(bool emit_errors = true) const
 		{
 			if (mValueAge == VALUE_NEEDS_UPDATE)
@@ -2217,7 +2623,6 @@ namespace LLInitParam
 				if (block_t::validateBlock(emit_errors))
 				{
 					// clear stale keyword associated with old value
-					TypeValues<T>::clearValueName();
 					mValueAge = BLOCK_AUTHORITATIVE;
 					static_cast<derived_t*>(const_cast<self_t*>(this))->updateValueFromBlock();
 					return true;
@@ -2247,17 +2652,15 @@ namespace LLInitParam
 			}
 		}
 			
-		void setValue(value_assignment_t val)
+		void setValue(const value_t& val)
 		{
-			derived_t& typed_param = static_cast<derived_t&>(*this);
 			// set param version number to be up to date, so we ignore block contents
 			mValueAge = VALUE_AUTHORITATIVE;
 			mValue = val;
-			typed_param.clearValueName();
 			static_cast<derived_t*>(this)->updateBlockFromValue(false);
 		}
 
-		value_assignment_t getValue() const
+		const value_t& getValue() const
 		{
 			validateBlock(true);
 			return mValue;
@@ -2269,20 +2672,10 @@ namespace LLInitParam
 			return mValue;
 		}
 
-		operator value_assignment_t() const
-		{
-			return getValue();
-		}
-
-		value_assignment_t operator()() const
-		{
-			return getValue();
-		}
-
 	protected:
 
 		// use this from within updateValueFromBlock() to set the value without making it authoritative
-		void updateValue(value_assignment_t value)
+		void updateValue(const value_t& value)
 		{
 			mValue = value;
 		}
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index 403df08990e48c3db81e81ad037ec91a74223e98..1eab270e3c75da0d53406dee4c52c4c46fc433c4 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -43,7 +43,7 @@
  * semantics: one instance per process, rather than one instance per module as
  * sometimes happens with data simply declared static.
  */
-class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
+class LL_COMMON_API LLInstanceTrackerBase
 {
 protected:
 	/// Get a process-unique void* pointer slot for the specified type_info
@@ -210,6 +210,9 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 	virtual const KEY& getKey() const { return mInstanceKey; }
 
 private:
+	LLInstanceTracker( const LLInstanceTracker& );
+	const LLInstanceTracker& operator=( const LLInstanceTracker& );
+
 	void add_(KEY key) 
 	{ 
 		mInstanceKey = key; 
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 41d3eb0bf369881da267876ef9224e7bcfaf9446..731e58bd20e5af682a31611f5f8bbee5080b9ef1 100644
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -100,7 +100,7 @@ LLSD LLMetricPerformanceTesterBasic::analyzeMetricPerformanceLog(std::istream& i
 	LLSD ret;
 	LLSD cur;
 	
-	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 	{
 		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
 		{
diff --git a/indra/llcommon/llrefcount.h b/indra/llcommon/llrefcount.h
index 8eb5d53f3f926324bfacda4ec4bc519a42fb571e..32ae15435a89e349a4605f0d943ef44f4b5a8cf8 100644
--- a/indra/llcommon/llrefcount.h
+++ b/indra/llcommon/llrefcount.h
@@ -27,6 +27,7 @@
 #define LLREFCOUNT_H
 
 #include <boost/noncopyable.hpp>
+#include <boost/intrusive_ptr.hpp>
 
 #define LL_REF_COUNT_DEBUG 0
 #if LL_REF_COUNT_DEBUG
@@ -86,4 +87,22 @@ class LL_COMMON_API LLRefCount
 #endif
 };
 
+/**
+ * intrusive pointer support
+ * this allows you to use boost::intrusive_ptr with any LLRefCount-derived type
+ */
+namespace boost
+{
+	inline void intrusive_ptr_add_ref(LLRefCount* p)
+	{
+		p->ref();
+	}
+
+	inline void intrusive_ptr_release(LLRefCount* p)
+	{
+		p->unref();
+	}
+};
+
+
 #endif
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index 853c427a13e87dfaeb5a209c2d755fa0d31aa3f4..bb0d60247e2c1ad63ada25668b5fd1385a1e2fdc 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -307,6 +307,10 @@ class LLRegistrySingleton
 		virtual ~StaticRegistrar() {}
 		StaticRegistrar(ref_const_key_t key, ref_const_value_t value)
 		{
+			if (singleton_t::instance().exists(key))
+			{
+				llerrs << "Duplicate registry entry under key \"" << key << "\"" << llendl;
+			}
 			singleton_t::instance().mStaticScope->add(key, value);
 		}
 	};
diff --git a/indra/llcommon/llsdparam.cpp b/indra/llcommon/llsdparam.cpp
index 0e29873bb01403bacc492661f48a7c1d88bf91fd..9f4460a988c20a25a808ee052f466f36b15ae3cd 100644
--- a/indra/llcommon/llsdparam.cpp
+++ b/indra/llcommon/llsdparam.cpp
@@ -223,10 +223,14 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
 	{
 		bool new_traversal = it->second;
 
-		LLSD* child_sd = it->first.empty() ? sd_to_write : &(*sd_to_write)[it->first];
-
-		if (child_sd->isArray())
+		LLSD* child_sd;
+		if (it->first.empty())
 		{
+			child_sd = sd_to_write;
+			if (child_sd->isUndefined())
+			{
+				*child_sd = LLSD::emptyArray();
+			}
 			if (new_traversal)
 			{
 				// write to new element at end
@@ -240,22 +244,7 @@ LLSD& LLParamSDParserUtilities::getSDWriteNode(LLSD& input, LLInitParam::Parser:
 		}
 		else
 		{
-			if (new_traversal 
-				&& child_sd->isDefined() 
-				&& !child_sd->isArray())
-			{
-				// copy child contents into first element of an array
-				LLSD new_array = LLSD::emptyArray();
-				new_array.append(*child_sd);
-				// assign array to slot that previously held the single value
-				*child_sd = new_array;
-				// return next element in that array
-				sd_to_write = &((*child_sd)[1]);
-			}
-			else
-			{
-				sd_to_write = child_sd;
-			}
+			sd_to_write = &(*sd_to_write)[it->first];
 		}
 		it->second = false;
 	}
@@ -283,8 +272,9 @@ void LLParamSDParserUtilities::readSDValues(read_sd_cb_t cb, const LLSD& sd, LLI
 			it != sd.endArray();
 			++it)
 		{
-			stack.back().second = true;
+			stack.push_back(make_pair(std::string(), true));
 			readSDValues(cb, *it, stack);
+			stack.pop_back();
 		}
 	}
 	else if (sd.isUndefined())
@@ -313,8 +303,14 @@ namespace LLInitParam
 {
 	// LLSD specialization
 	// block param interface
-	bool ParamValue<LLSD, TypeValues<LLSD>, false>::deserializeBlock(Parser& p, Parser::name_stack_range_t name_stack, bool new_name)
+	bool ParamValue<LLSD, NOT_BLOCK>::deserializeBlock(Parser& p, Parser::name_stack_range_t& name_stack, bool new_name)
 	{
+		if (name_stack.first == name_stack.second
+			&& p.readValue<LLSD>(mValue))
+		{
+			return true;
+		}
+
 		LLSD& sd = LLParamSDParserUtilities::getSDWriteNode(mValue, name_stack);
 
 		LLSD::String string;
@@ -328,15 +324,18 @@ namespace LLInitParam
 	}
 
 	//static
-	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
+	void ParamValue<LLSD, NOT_BLOCK>::serializeElement(Parser& p, const LLSD& sd, Parser::name_stack_t& name_stack)
 	{
 		p.writeValue<LLSD::String>(sd.asString(), name_stack);
 	}
 
-	void ParamValue<LLSD, TypeValues<LLSD>, false>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
+	void ParamValue<LLSD, NOT_BLOCK>::serializeBlock(Parser& p, Parser::name_stack_t& name_stack, const BaseBlock* diff_block) const
 	{
-		// read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
-		Parser::name_stack_t stack;
-		LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, stack);
+		// attempt to write LLSD out directly
+		if (!p.writeValue<LLSD>(mValue, name_stack))
+		{
+			// otherwise read from LLSD value and serialize out to parser (which could be LLSD, XUI, etc)
+			LLParamSDParserUtilities::readSDValues(boost::bind(&serializeElement, boost::ref(p), _1, _2), mValue, name_stack);
+		}
 	}
 }
diff --git a/indra/llcommon/llsdserialize.cpp b/indra/llcommon/llsdserialize.cpp
index 6b549e4b6f9655116d5fb76fedd6a0aea390ad42..ad4fce6f359b8dbb6277402ed615394c98de118a 100644
--- a/indra/llcommon/llsdserialize.cpp
+++ b/indra/llcommon/llsdserialize.cpp
@@ -1453,8 +1453,8 @@ S32 LLSDBinaryFormatter::format(const LLSD& data, std::ostream& ostr, U32 option
 	case LLSD::TypeUUID:
 	{
 		ostr.put('u');
-		LLSD::UUID value = data.asUUID();
-		ostr.write((const char*)(&value.mData), UUID_BYTES);
+		LLUUID temp = data.asUUID();
+		ostr.write((const char*)(&(temp.mData)), UUID_BYTES);
 		break;
 	}
 
diff --git a/indra/llcommon/llsdserialize.h b/indra/llcommon/llsdserialize.h
index 86e3fc864c065a694e8003dcc6a8d272b2f4b43b..e7a5507385c07bd0c05b42d2477336e04d6d3c1d 100644
--- a/indra/llcommon/llsdserialize.h
+++ b/indra/llcommon/llsdserialize.h
@@ -300,7 +300,7 @@ class LL_COMMON_API LLSDXMLParser : public LLSDParser
 	/** 
 	 * @brief Constructor
 	 */
-	LLSDXMLParser();
+	LLSDXMLParser(bool emit_errors=true);
 
 protected:
 	/** 
@@ -747,25 +747,25 @@ class LL_COMMON_API LLSDSerialize
 		return f->format(sd, str, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str)
+	static S32 fromXMLEmbedded(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
 		// no need for max_bytes since xml formatting is not
 		// subvertable by bad sizes.
-		LLPointer<LLSDXMLParser> p = new LLSDXMLParser;
+		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
 		return p->parse(str, sd, LLSDSerialize::SIZE_UNLIMITED);
 	}
 	// Line oriented parser, 30% faster than fromXML(), but can
 	// only be used when you know you have the complete XML
 	// document available in the stream.
-	static S32 fromXMLDocument(LLSD& sd, std::istream& str)
+	static S32 fromXMLDocument(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
-		LLPointer<LLSDXMLParser> p = new LLSDXMLParser();
+		LLPointer<LLSDXMLParser> p = new LLSDXMLParser(emit_errors);
 		return p->parseLines(str, sd);
 	}
-	static S32 fromXML(LLSD& sd, std::istream& str)
+	static S32 fromXML(LLSD& sd, std::istream& str, bool emit_errors=true)
 	{
-		return fromXMLEmbedded(sd, str);
-//		return fromXMLDocument(sd, str);
+		return fromXMLEmbedded(sd, str, emit_errors);
+//		return fromXMLDocument(sd, str, emit_errors);
 	}
 
 	/*
diff --git a/indra/llcommon/llsdserialize_xml.cpp b/indra/llcommon/llsdserialize_xml.cpp
index 34b3dbb99a3ff05dd5de91a06879b69ce5bcc5a6..cef743a7beab012a31a2b42233da8f33db9588b6 100644
--- a/indra/llcommon/llsdserialize_xml.cpp
+++ b/indra/llcommon/llsdserialize_xml.cpp
@@ -250,7 +250,7 @@ std::string LLSDXMLFormatter::escapeString(const std::string& in)
 class LLSDXMLParser::Impl
 {
 public:
-	Impl();
+	Impl(bool emit_errors);
 	~Impl();
 	
 	S32 parse(std::istream& input, LLSD& data);
@@ -294,6 +294,7 @@ class LLSDXMLParser::Impl
 	
 	static const XML_Char* findAttribute(const XML_Char* name, const XML_Char** pairs);
 	
+	bool mEmitErrors;
 
 	XML_Parser	mParser;
 
@@ -315,7 +316,8 @@ class LLSDXMLParser::Impl
 };
 
 
-LLSDXMLParser::Impl::Impl()
+LLSDXMLParser::Impl::Impl(bool emit_errors)
+	: mEmitErrors(emit_errors)
 {
 	mParser = XML_ParserCreate(NULL);
 	reset();
@@ -402,7 +404,10 @@ S32 LLSDXMLParser::Impl::parse(std::istream& input, LLSD& data)
 		{
 			((char*) buffer)[count ? count - 1 : 0] = '\0';
 		}
-		llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+		if (mEmitErrors)
+		{
+			llinfos << "LLSDXMLParser::Impl::parse: XML_STATUS_ERROR parsing:" << (char*) buffer << llendl;
+		}
 		data = LLSD();
 		return LLSDParser::PARSE_FAILURE;
 	}
@@ -480,7 +485,10 @@ S32 LLSDXMLParser::Impl::parseLines(std::istream& input, LLSD& data)
 	if (status == XML_STATUS_ERROR  
 		&& !mGracefullStop)
 	{
-		llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+		if (mEmitErrors)
+		{
+			llinfos << "LLSDXMLParser::Impl::parseLines: XML_STATUS_ERROR" << llendl;
+		}
 		return LLSDParser::PARSE_FAILURE;
 	}
 
@@ -897,7 +905,7 @@ LLSDXMLParser::Impl::Element LLSDXMLParser::Impl::readElement(const XML_Char* na
 /**
  * LLSDXMLParser
  */
-LLSDXMLParser::LLSDXMLParser() : impl(* new Impl)
+LLSDXMLParser::LLSDXMLParser(bool emit_errors /* = true */) : impl(* new Impl(emit_errors))
 {
 }
 
diff --git a/indra/llcommon/llthread.h b/indra/llcommon/llthread.h
index 5c8bbca2cadb651862a9fcac74c595b1108d1404..0fb89c56131f29ac8f71e68d18b69a98f1996b99 100644
--- a/indra/llcommon/llthread.h
+++ b/indra/llcommon/llthread.h
@@ -30,6 +30,7 @@
 #include "llapp.h"
 #include "llapr.h"
 #include "apr_thread_cond.h"
+#include "boost/intrusive_ptr.hpp"
 
 class LLThread;
 class LLMutex;
@@ -284,6 +285,22 @@ class LL_COMMON_API LLThreadSafeRefCount
 	S32	mRef; 
 };
 
+/**
+ * intrusive pointer support for LLThreadSafeRefCount
+ * this allows you to use boost::intrusive_ptr with any LLThreadSafeRefCount-derived type
+ */
+namespace boost
+{
+	inline void intrusive_ptr_add_ref(LLThreadSafeRefCount* p) 
+	{
+		p->ref();
+	}
+
+	inline void intrusive_ptr_release(LLThreadSafeRefCount* p) 
+	{
+		p->unref(); 
+	}
+};
 //============================================================================
 
 // Simple responder for self destructing callbacks
diff --git a/indra/llcommon/llversionserver.h b/indra/llcommon/llversionserver.h
index b19ba3bf7407eddf5d34dd1ace14e527e1cddc79..ef68a0eaf5cbd4b9272f8b35d70ed17b51c8f42c 100644
--- a/indra/llcommon/llversionserver.h
+++ b/indra/llcommon/llversionserver.h
@@ -30,7 +30,7 @@
 const S32 LL_VERSION_MAJOR = 2;
 const S32 LL_VERSION_MINOR = 1;
 const S32 LL_VERSION_PATCH = 0;
-const S32 LL_VERSION_BUILD = 13828;
+const S32 LL_VERSION_BUILD = 264760;
 
 const char * const LL_CHANNEL = "Second Life Server";
 
diff --git a/indra/llcommon/llversionviewer.h b/indra/llcommon/llversionviewer.h
index 6a5ff314e4cbc31cf09073150a699a94d8cf2b06..0ea130e86bfcd756a4b68506ebf9600d76a33eaf 100644
--- a/indra/llcommon/llversionviewer.h
+++ b/indra/llcommon/llversionviewer.h
@@ -28,9 +28,9 @@
 #define LL_LLVERSIONVIEWER_H
 
 const S32 LL_VERSION_MAJOR = 3;
-const S32 LL_VERSION_MINOR = 4;
-const S32 LL_VERSION_PATCH = 6;
-const S32 LL_VERSION_BUILD = 0;
+const S32 LL_VERSION_MINOR = 5;
+const S32 LL_VERSION_PATCH = 2;
+const S32 LL_VERSION_BUILD = 264760;
 
 const char * const LL_CHANNEL = "Second Life Developer";
 
diff --git a/indra/llcommon/stdenums.h b/indra/llcommon/stdenums.h
index 40b3364b36078961f92d9742e36765028ae284c9..efcbe76795827d379aca14a7495364093f519ca6 100644
--- a/indra/llcommon/stdenums.h
+++ b/indra/llcommon/stdenums.h
@@ -51,7 +51,8 @@ enum EDragAndDropType
 	DAD_LINK			= 14,
 	DAD_MESH            = 15,
 	DAD_WIDGET          = 16,
-	DAD_COUNT           = 17,   // number of types in this enum
+	DAD_PERSON          = 17,
+	DAD_COUNT           = 18,   // number of types in this enum
 };
 
 // Reasons for drags to be denied.
diff --git a/indra/llcommon/tests/bitpack_test.cpp b/indra/llcommon/tests/bitpack_test.cpp
index 4c3bc674af9d5e9a971684e6b3d4d559814169d3..afc0c18cd01ad7b6de21b547e1407e02bb4ba442 100644
--- a/indra/llcommon/tests/bitpack_test.cpp
+++ b/indra/llcommon/tests/bitpack_test.cpp
@@ -71,7 +71,6 @@ namespace tut
 		U8 packbuffer[255];
 		U8 unpackbuffer[255];
 		int pack_bufsize = 0;
-		int unpack_bufsize = 0;
 
 		LLBitPack bitpack(packbuffer, 255);
 
@@ -81,21 +80,20 @@ namespace tut
 		pack_bufsize = bitpack.flushBitPack();
 
 		LLBitPack bitunpack(packbuffer, pack_bufsize*8);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 0", unpackbuffer[0] == (U8) str[0]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 1", unpackbuffer[0] == (U8) str[1]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 2", unpackbuffer[0] == (U8) str[2]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 3", unpackbuffer[0] == (U8) str[3]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 4", unpackbuffer[0] == (U8) str[4]);
-		unpack_bufsize = bitunpack.bitUnpack(&unpackbuffer[0], 8);
+		bitunpack.bitUnpack(&unpackbuffer[0], 8);
 		ensure("bitPack: individual unpack: 5", unpackbuffer[0] == (U8) str[5]);
-		unpack_bufsize = bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
+		bitunpack.bitUnpack(unpackbuffer, 8*4); // Life
 		ensure_memory_matches("bitPack: 4 bytes unpack:", unpackbuffer, 4, str+6, 4);
-		ensure("keep compiler quiet", unpack_bufsize == unpack_bufsize);
 	}
 
 	// U32 packing
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 454695ff9f2593d5954d80e7d2d6b5fa70de7def..e769c3e22c77c38298a7f704c40c0bc2dc75a602 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -267,7 +267,6 @@ namespace tut
         {
             existing.insert(&*uki);
         }
-        Unkeyed* puk = NULL;
         try
         {
             // We don't expect the assignment to take place because we expect
@@ -280,7 +279,7 @@ namespace tut
             // realize we're testing the C++ implementation more than
             // Unkeyed's implementation, but this seems an important point to
             // nail down.
-            puk = new Unkeyed("throw");
+            new Unkeyed("throw");
         }
         catch (const Badness&)
         {
diff --git a/indra/llcrashlogger/CMakeLists.txt b/indra/llcrashlogger/CMakeLists.txt
index b2639aec304d5997fffd880c72896878f0938119..12986de8b2c3cf2b94b6c9e90a87ed9eaaeb07fa 100644
--- a/indra/llcrashlogger/CMakeLists.txt
+++ b/indra/llcrashlogger/CMakeLists.txt
@@ -16,6 +16,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llcrashlogger_SOURCE_FILES
     llcrashlogger.cpp
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index 34e25a8a715a2ac6fb695b9ae40cca427fa85e93..fb2d43e3b0d6c25af71214e8cf3f1bbe255198fd 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -147,7 +147,7 @@ void LLCrashLogger::gatherFiles()
 
 	// Look for it in the debug_info.log file
 	if (debug_log_file.is_open())
-	{		
+	{
 		LLSDSerialize::fromXML(mDebugLog, debug_log_file);
 
 		mCrashInPreviousExec = mDebugLog["CrashNotHandled"].asBoolean();
diff --git a/indra/llimage/CMakeLists.txt b/indra/llimage/CMakeLists.txt
index ea8c1a1107eef6c7f3b2be9cdbad5dce5d45c54c..e837b0cac2cbb25bc5d2587a7c1428d4866ec37c 100644
--- a/indra/llimage/CMakeLists.txt
+++ b/indra/llimage/CMakeLists.txt
@@ -7,12 +7,15 @@ include(LLCommon)
 include(LLImage)
 include(LLMath)
 include(LLVFS)
+include(LLKDU)
+include(LLImageJ2COJ)
 include(ZLIB)
 include(LLAddBuildTest)
 include(Tut)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     ${PNG_INCLUDE_DIRS}
@@ -56,8 +59,16 @@ list(APPEND llimage_SOURCE_FILES ${llimage_HEADER_FILES})
 add_library (llimage ${llimage_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
+if (USE_KDU)
+    target_link_libraries(llimage ${LLKDU_LIBRARIES})
+else (USE_KDU)
+    target_link_libraries(llimage ${LLIMAGEJ2COJ_LIBRARIES})
+endif (USE_KDU)
+
 target_link_libraries(llimage
-    llcommon
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
     ${JPEG_LIBRARIES}
     ${PNG_LIBRARIES}
     ${ZLIB_LIBRARIES}
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index a88ac148efa306f98cbc2689d0c57bc971bdbeec..1c25256e9521894a04c7e0b0230932d201f7c84b 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -640,6 +640,29 @@ void LLImageRaw::compositeUnscaled4onto3( LLImageRaw* src )
 	}
 }
 
+void LLImageRaw::copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill)
+{
+	LLImageRaw* dst = this;  // Just for clarity.
+
+	llassert( 1 == src->getComponents() );
+	llassert( 4 == dst->getComponents() );
+	llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+	S32 pixels = getWidth() * getHeight();
+	U8* src_data = src->getData();
+	U8* dst_data = dst->getData();
+	for ( S32 i = 0; i < pixels; i++ )
+	{
+		dst_data[0] = fill.mV[0];
+		dst_data[1] = fill.mV[1];
+		dst_data[2] = fill.mV[2];
+		dst_data[3] = src_data[0];
+		src_data += 1;
+		dst_data += 4;
+	}
+}
+
+
 // Fill the buffer with a constant color
 void LLImageRaw::fill( const LLColor4U& color )
 {
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 6cb1226da09748e93d5a77c94f854767d733aba5..4fc40ecff7703364b950cd7c8cdadd18266c5f3d 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -226,6 +226,11 @@ class LLImageRaw : public LLImageBase
 	// Src and dst are same size.  Src has 3 components.  Dst has 4 components.
 	void copyUnscaled3onto4( LLImageRaw* src );
 
+	// Src and dst are same size.  Src has 1 component.  Dst has 4 components.
+	// Alpha component is set to source alpha mask component.
+	// RGB components are set to fill color.
+	void copyUnscaledAlphaMask( LLImageRaw* src, const LLColor4U& fill);
+
 	// Src and dst can be any size.  Src and dst have same number of components.
 	void copyScaled( LLImageRaw* src );
 
diff --git a/indra/llimage/llimagetga.cpp b/indra/llimage/llimagetga.cpp
index 58426d31fa6837c174f6f389d28047bc28cc75a9..920ae2891f6caefa99b37ed30935047c34f21fe8 100644
--- a/indra/llimage/llimagetga.cpp
+++ b/indra/llimage/llimagetga.cpp
@@ -132,12 +132,12 @@ BOOL LLImageTGA::updateData()
 	**	  FIELD 2 :	COLOR MAP TYPE (1 BYTES)			
 	**	  FIELD 3 :	IMAGE TYPE CODE (1 BYTES)			
 	**					= 0	NO IMAGE DATA INCLUDED		
-	**					= 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
-	**					= 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
-	**					= 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
-	**					= 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
-	**					= 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
-	**					= 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
+	**					= (0001) 1	UNCOMPRESSED, COLOR-MAPPED IMAGE
+	**					= (0010) 2	UNCOMPRESSED, TRUE-COLOR IMAGE	
+	**					= (0011) 3	UNCOMPRESSED, BLACK AND WHITE IMAGE
+	**					= (1001) 9	RUN-LENGTH ENCODED COLOR-MAPPED IMAGE
+	**					= (1010) 10 RUN-LENGTH ENCODED TRUE-COLOR IMAGE
+	**					= (1011) 11 RUN-LENGTH ENCODED BLACK AND WHITE IMAGE
 	**	  FIELD 4 :	COLOR MAP SPECIFICATION	(5 BYTES)		
 	**				4.1 : COLOR MAP ORIGIN (2 BYTES)	
 	**				4.2 : COLOR MAP LENGTH (2 BYTES)	
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index fbf23bc3f09a760eee88c85f29cf41df9a1a5352..41d58c6deb5b2c476012deb32bccefe661a13b3e 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -75,13 +75,15 @@ LLInventoryObject::LLInventoryObject(const LLUUID& uuid,
 	mUUID(uuid),
 	mParentUUID(parent_uuid),
 	mType(type),
-	mName(name)
+	mName(name),
+	mCreationDate(0)
 {
 	correctInventoryName(mName);
 }
 
 LLInventoryObject::LLInventoryObject() :
-	mType(LLAssetType::AT_NONE)
+	mType(LLAssetType::AT_NONE),
+	mCreationDate(0)
 {
 }
 
@@ -275,6 +277,26 @@ void LLInventoryObject::correctInventoryName(std::string& name)
 	LLStringUtil::truncate(name, DB_INV_ITEM_NAME_STR_LEN);
 }
 
+time_t LLInventoryObject::getCreationDate() const
+{
+	return mCreationDate;
+}
+
+void LLInventoryObject::setCreationDate(time_t creation_date_utc)
+{
+	mCreationDate = creation_date_utc;
+}
+
+
+const std::string& LLInventoryItem::getDescription() const
+{
+	return mDescription;
+}
+
+const std::string& LLInventoryItem::getActualDescription() const
+{
+	return mDescription;
+}
 
 ///----------------------------------------------------------------------------
 /// Class LLInventoryItem
@@ -297,9 +319,10 @@ LLInventoryItem::LLInventoryItem(const LLUUID& uuid,
 	mDescription(desc),
 	mSaleInfo(sale_info),
 	mInventoryType(inv_type),
-	mFlags(flags),
-	mCreationDate(creation_date_utc)
+	mFlags(flags)
 {
+	mCreationDate = creation_date_utc;
+
 	LLStringUtil::replaceNonstandardASCII(mDescription, ' ');
 	LLStringUtil::replaceChar(mDescription, '|', ' ');
 	mPermissions.initMasks(inv_type);
@@ -312,9 +335,9 @@ LLInventoryItem::LLInventoryItem() :
 	mDescription(),
 	mSaleInfo(),
 	mInventoryType(LLInventoryType::IT_NONE),
-	mFlags(0),
-	mCreationDate(0)
+	mFlags(0)
 {
+	mCreationDate = 0;
 }
 
 LLInventoryItem::LLInventoryItem(const LLInventoryItem* other) :
@@ -374,16 +397,6 @@ void LLInventoryItem::setAssetUUID(const LLUUID& asset_id)
 }
 
 
-const std::string& LLInventoryItem::getDescription() const
-{
-	return mDescription;
-}
-
-time_t LLInventoryItem::getCreationDate() const
-{
-	return mCreationDate;
-}
-
 U32 LLInventoryItem::getCRC32() const
 {
 	// *FIX: Not a real crc - more of a checksum.
@@ -440,11 +453,6 @@ void LLInventoryItem::setFlags(U32 flags)
 	mFlags = flags;
 }
 
-void LLInventoryItem::setCreationDate(time_t creation_date_utc)
-{
-	mCreationDate = creation_date_utc;
-}
-
 // Currently only used in the Viewer to handle calling cards
 // where the creator is actually used to store the target.
 void LLInventoryItem::setCreator(const LLUUID& creator)
@@ -506,6 +514,12 @@ U32 LLInventoryItem::getFlags() const
 	return mFlags;
 }
 
+time_t LLInventoryItem::getCreationDate() const
+{
+	return mCreationDate;
+}
+
+
 // virtual
 void LLInventoryItem::packMessage(LLMessageSystem* msg) const
 {
diff --git a/indra/llinventory/llinventory.h b/indra/llinventory/llinventory.h
index 4dda41d325fe5a751e857944ab7078145d26decd..99716ed7be6d13290756c80b191385eed8c25d73 100644
--- a/indra/llinventory/llinventory.h
+++ b/indra/llinventory/llinventory.h
@@ -73,6 +73,7 @@ class LLInventoryObject : public LLRefCount
 	virtual LLAssetType::EType getType() const;
 	LLAssetType::EType getActualType() const; // bypasses indirection for linked items
 	BOOL getIsLinkType() const;
+	virtual time_t getCreationDate() const;
 	
 	//--------------------------------------------------------------------
 	// Mutators
@@ -83,6 +84,7 @@ class LLInventoryObject : public LLRefCount
 	virtual void rename(const std::string& new_name);
 	void setParent(const LLUUID& new_parent);
 	void setType(LLAssetType::EType type);
+	virtual void setCreationDate(time_t creation_date_utc); // only stored for items
 
 private:
 	// in place correction for inventory name string
@@ -111,6 +113,7 @@ class LLInventoryObject : public LLRefCount
 	LLUUID mParentUUID; // Parent category.  Root categories have LLUUID::NULL.
 	LLAssetType::EType mType;
 	std::string mName;
+	time_t mCreationDate; // seconds from 1/1/1970, UTC
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -157,6 +160,7 @@ class LLInventoryItem : public LLInventoryObject
 	virtual const LLUUID& getCreatorUUID() const;
 	virtual const LLUUID& getAssetUUID() const;
 	virtual const std::string& getDescription() const;
+	virtual const std::string& getActualDescription() const; // Does not follow links
 	virtual const LLSaleInfo& getSaleInfo() const;
 	virtual LLInventoryType::EType getInventoryType() const;
 	virtual U32 getFlags() const;
@@ -175,7 +179,6 @@ class LLInventoryItem : public LLInventoryObject
 	void setPermissions(const LLPermissions& perm);
 	void setInventoryType(LLInventoryType::EType inv_type);
 	void setFlags(U32 flags);
-	void setCreationDate(time_t creation_date_utc);
 	void setCreator(const LLUUID& creator); // only used for calling cards
 
 	// Check for changes in permissions masks and sale info
@@ -221,7 +224,6 @@ class LLInventoryItem : public LLInventoryObject
 	LLSaleInfo mSaleInfo;
 	LLInventoryType::EType mInventoryType;
 	U32 mFlags;
-	time_t mCreationDate; // seconds from 1/1/1970, UTC
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 8282d79b673736ffab072ba47aaae3bf92d4a256..8807b36117047dd08658ebe9feeaec5ef0fb5993 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -85,6 +85,7 @@ LLInventoryDictionary::LLInventoryDictionary()
 	addEntry(LLInventoryType::IT_GESTURE,             new InventoryEntry("gesture",   "gesture",       1, LLAssetType::AT_GESTURE)); 
 	addEntry(LLInventoryType::IT_MESH,                new InventoryEntry("mesh",      "mesh",          1, LLAssetType::AT_MESH));
 	addEntry(LLInventoryType::IT_WIDGET,              new InventoryEntry("widget",    "widget",        1, LLAssetType::AT_WIDGET));
+	addEntry(LLInventoryType::IT_PERSON,              new InventoryEntry("person",    "person",        1, LLAssetType::AT_PERSON));
 }
 
 
@@ -140,7 +141,7 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] =
 	LLInventoryType::IT_NONE,			// 42	AT_NONE
 	LLInventoryType::IT_NONE,			// 43	AT_NONE
 	LLInventoryType::IT_NONE,			// 44	AT_NONE
-	LLInventoryType::IT_NONE,			// 45	AT_NONE
+	LLInventoryType::IT_PERSON,			// 45	AT_PERSON
 	LLInventoryType::IT_NONE,			// 46	AT_NONE
 	LLInventoryType::IT_NONE,			// 47	AT_NONE
 	LLInventoryType::IT_NONE,			// 48	AT_NONE
diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h
index 4d1e0db04016126a4fc70df3b1f738bf78031c4e..fc3c78cf5062c7c0333a68585733ab2aa1320c1e 100644
--- a/indra/llinventory/llinventorytype.h
+++ b/indra/llinventory/llinventorytype.h
@@ -63,11 +63,59 @@ class LLInventoryType
 		IT_GESTURE = 20,
 		IT_MESH = 22,
 		IT_WIDGET = 23,
-		IT_COUNT = 24,
+		IT_PERSON = 24,
+		IT_COUNT = 25,
 
 		IT_NONE = -1
 	};
 
+	enum EIconName
+	{
+		ICONNAME_TEXTURE,
+		ICONNAME_SOUND,
+		ICONNAME_CALLINGCARD_ONLINE,
+		ICONNAME_CALLINGCARD_OFFLINE,
+		ICONNAME_LANDMARK,
+		ICONNAME_LANDMARK_VISITED,
+		ICONNAME_SCRIPT,
+		ICONNAME_CLOTHING,
+		ICONNAME_OBJECT,
+		ICONNAME_OBJECT_MULTI,
+		ICONNAME_NOTECARD,
+		ICONNAME_BODYPART,
+		ICONNAME_SNAPSHOT,
+		
+		ICONNAME_BODYPART_SHAPE,
+		ICONNAME_BODYPART_SKIN,
+		ICONNAME_BODYPART_HAIR,
+		ICONNAME_BODYPART_EYES,
+		ICONNAME_CLOTHING_SHIRT,
+		ICONNAME_CLOTHING_PANTS,
+		ICONNAME_CLOTHING_SHOES,
+		ICONNAME_CLOTHING_SOCKS,
+		ICONNAME_CLOTHING_JACKET,
+		ICONNAME_CLOTHING_GLOVES,
+		ICONNAME_CLOTHING_UNDERSHIRT,
+		ICONNAME_CLOTHING_UNDERPANTS,
+		ICONNAME_CLOTHING_SKIRT,
+		ICONNAME_CLOTHING_ALPHA,
+		ICONNAME_CLOTHING_TATTOO,
+
+		ICONNAME_ANIMATION,
+		ICONNAME_GESTURE,
+
+		ICONNAME_CLOTHING_PHYSICS,
+		
+		ICONNAME_LINKITEM,
+		ICONNAME_LINKFOLDER,
+		ICONNAME_MESH,
+
+		ICONNAME_INVALID,
+		ICONNAME_COUNT,
+		ICONNAME_NONE = -1
+	};
+
+
 	// machine transation between type and strings
 	static EType lookup(const std::string& name);
 	static const std::string &lookup(EType type);
diff --git a/indra/llkdu/CMakeLists.txt b/indra/llkdu/CMakeLists.txt
index bdac2eded7ec3d1723d147072fea27f1c0571335..b8f8b420c329cc8bc0c448c900f4d3ca34bfed41 100644
--- a/indra/llkdu/CMakeLists.txt
+++ b/indra/llkdu/CMakeLists.txt
@@ -41,7 +41,10 @@ set_source_files_properties(${llkdu_HEADER_FILES}
 list(APPEND llkdu_SOURCE_FILES ${llkdu_HEADER_FILES})
 
 if (USE_KDU)
-  add_library (${LLKDU_LIBRARIES} ${llkdu_SOURCE_FILES})
+  add_library (llkdu ${llkdu_SOURCE_FILES})
+
+  target_link_libraries(llkdu
+    ${KDU_LIBRARY})
   
   # Add tests
   if (LL_TESTS)
diff --git a/indra/llmath/CMakeLists.txt b/indra/llmath/CMakeLists.txt
index 5865ae030c2cac900207fc5e221036488e3ee351..0614fd92ef60f1bfaf8f1de1a52aca92ae888ae2 100644
--- a/indra/llmath/CMakeLists.txt
+++ b/indra/llmath/CMakeLists.txt
@@ -7,6 +7,7 @@ include(LLCommon)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     )
 
 set(llmath_SOURCE_FILES
@@ -99,6 +100,10 @@ list(APPEND llmath_SOURCE_FILES ${llmath_HEADER_FILES})
 
 add_library (llmath ${llmath_SOURCE_FILES})
 
+target_link_libraries(llmath
+    ${LLCOMMON_LIBRARIES}
+    )
+
 # Add tests
 if (LL_TESTS)
   include(LLAddBuildTest)
diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp
index 02c8d2b86f090f5150bdd8574338ceb3d0d1f6f6..3f06e6b99ed38d493f05416c2354185a1ebf20c4 100644
--- a/indra/llmath/llvolume.cpp
+++ b/indra/llmath/llvolume.cpp
@@ -6066,12 +6066,7 @@ BOOL LLVolumeFace::createUnCutCubeCap(LLVolume* volume, BOOL partial_build)
 	S32 max_t = volume->getPath().mPath.size();
 
 	// S32 i;
-	S32 num_vertices = 0, num_indices = 0;
 	S32	grid_size = (profile.size()-1)/4;
-	S32	quad_count = (grid_size * grid_size);
-
-	num_vertices = (grid_size+1)*(grid_size+1);
-	num_indices = quad_count * 4;
 
 	LLVector4a& min = mExtents[0];
 	LLVector4a& max = mExtents[1];
diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt
index d98781e9e62ba8ff79e689345f3975d3cec98d39..1a90c32fe4fd0ee38433164a7e7a0d59ddfb885a 100644
--- a/indra/llmessage/CMakeLists.txt
+++ b/indra/llmessage/CMakeLists.txt
@@ -218,6 +218,9 @@ add_library (llmessage ${llmessage_SOURCE_FILES})
 target_link_libraries(
   llmessage
   ${CURL_LIBRARIES}
+  ${LLCOMMON_LIBRARIES}
+  ${LLVFS_LIBRARES}
+  ${LLMATH_LIBRARIES}
   ${CARES_LIBRARIES}
   ${OPENSSL_LIBRARIES}
   ${CRYPTO_LIBRARIES}
@@ -243,7 +246,7 @@ if (LL_TESTS)
     ${LLVFS_LIBRARIES}
     ${LLMATH_LIBRARIES}
     ${LLCOMMON_LIBRARIES}
-      ${GOOGLEMOCK_LIBRARIES}
+    ${GOOGLEMOCK_LIBRARIES}
     )
 
   LL_ADD_INTEGRATION_TEST(
diff --git a/indra/llmessage/llavatarnamecache.cpp b/indra/llmessage/llavatarnamecache.cpp
index a6e2c89ba486a19f2927a790a27f52e882038118..9a68093427d241b8c8000edfdc18920598333b18 100644
--- a/indra/llmessage/llavatarnamecache.cpp
+++ b/indra/llmessage/llavatarnamecache.cpp
@@ -43,26 +43,26 @@ namespace LLAvatarNameCache
 {
 	use_display_name_signal_t mUseDisplayNamesSignal;
 
-	// Manual override for display names - can disable even if the region
-	// supports it.
-	bool sUseDisplayNames = true;
-
 	// Cache starts in a paused state until we can determine if the
 	// current region supports display names.
 	bool sRunning = false;
 	
+	// Use the People API (modern) for fetching name if true. Use the old legacy protocol if false.
+	// For testing, there's a UsePeopleAPI setting that can be flipped (must restart viewer).
+	bool sUsePeopleAPI = true;
+	
 	// Base lookup URL for name service.
 	// On simulator, loaded from indra.xml
 	// On viewer, usually a simulator capability (at People API team's request)
 	// Includes the trailing slash, like "http://pdp60.lindenlab.com:8000/agents/"
 	std::string sNameLookupURL;
 
-	// accumulated agent IDs for next query against service
+	// Accumulated agent IDs for next query against service
 	typedef std::set<LLUUID> ask_queue_t;
 	ask_queue_t sAskQueue;
 
-	// agent IDs that have been requested, but with no reply
-	// maps agent ID to frame time request was made
+	// Agent IDs that have been requested, but with no reply.
+	// Maps agent ID to frame time request was made.
 	typedef std::map<LLUUID, F64> pending_queue_t;
 	pending_queue_t sPendingQueue;
 
@@ -73,21 +73,21 @@ namespace LLAvatarNameCache
 	typedef std::map<LLUUID, callback_signal_t*> signal_map_t;
 	signal_map_t sSignalMap;
 
-	// names we know about
+	// The cache at last, i.e. avatar names we know about.
 	typedef std::map<LLUUID, LLAvatarName> cache_t;
 	cache_t sCache;
 
-	// Send bulk lookup requests a few times a second at most
-	// only need per-frame timing resolution
+	// Send bulk lookup requests a few times a second at most.
+	// Only need per-frame timing resolution.
 	LLFrameTimer sRequestTimer;
 
-    /// Maximum time an unrefreshed cache entry is allowed
+    // Maximum time an unrefreshed cache entry is allowed.
     const F64 MAX_UNREFRESHED_TIME = 20.0 * 60.0;
 
-    /// Time when unrefreshed cached names were checked last
+    // Time when unrefreshed cached names were checked last.
     static F64 sLastExpireCheck;
 
-	/// Time-to-live for a temp cache entry.
+	// Time-to-live for a temp cache entry.
 	const F64 TEMP_CACHE_ENTRY_LIFETIME = 60.0;
 
 	//-----------------------------------------------------------------------
@@ -95,26 +95,21 @@ namespace LLAvatarNameCache
 	//-----------------------------------------------------------------------
 
 	// Handle name response off network.
-	// Optionally skip adding to cache, used when this is a fallback to the
-	// legacy name system.
 	void processName(const LLUUID& agent_id,
-					 const LLAvatarName& av_name,
-					 bool add_to_cache);
+					 const LLAvatarName& av_name);
 
 	void requestNamesViaCapability();
 
-	// Legacy name system callback
+	// Legacy name system callbacks
 	void legacyNameCallback(const LLUUID& agent_id,
 							const std::string& full_name,
-							bool is_group
-							);
-
+							bool is_group);
+	void legacyNameFetch(const LLUUID& agent_id,
+						 const std::string& full_name,
+						 bool is_group);
+	
 	void requestNamesViaLegacy();
 
-	// Fill in an LLAvatarName with the legacy name data
-	void buildLegacyName(const std::string& full_name,
-						 LLAvatarName* av_name);
-
 	// Do a single callback to a given slot
 	void fireSignal(const LLUUID& agent_id,
 					const callback_slot_t& slot,
@@ -209,20 +204,11 @@ class LLAvatarNameResponder : public LLHTTPClient::Responder
 			// Use expiration time from header
 			av_name.mExpires = expires;
 
-			// Some avatars don't have explicit display names set
-			if (av_name.mDisplayName.empty())
-			{
-				av_name.mDisplayName = av_name.mUsername;
-			}
-
-			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << " "
-									 << "user '" << av_name.mUsername << "' "
-									 << "display '" << av_name.mDisplayName << "' "
-									 << "expires in " << expires - now << " seconds"
-									 << LL_ENDL;
+			LL_DEBUGS("AvNameCache") << "LLAvatarNameResponder::result for " << agent_id << LL_ENDL;
+			av_name.dump();
 			
 			// cache it and fire signals
-			LLAvatarNameCache::processName(agent_id, av_name, true);
+			LLAvatarNameCache::processName(agent_id, av_name);
 		}
 
 		// Same logic as error response case
@@ -279,40 +265,34 @@ void LLAvatarNameCache::handleAgentError(const LLUUID& agent_id)
         LL_WARNS("AvNameCache") << "LLAvatarNameCache get legacy for agent "
 								<< agent_id << LL_ENDL;
         gCacheName->get(agent_id, false,  // legacy compatibility
-                        boost::bind(&LLAvatarNameCache::legacyNameCallback,
-                                    _1, _2, _3));
+                        boost::bind(&LLAvatarNameCache::legacyNameFetch, _1, _2, _3));
     }
 	else
     {
-        // we have a chached (but probably expired) entry - since that would have
+        // we have a cached (but probably expired) entry - since that would have
         // been returned by the get method, there is no need to signal anyone
 
         // Clear this agent from the pending list
         LLAvatarNameCache::sPendingQueue.erase(agent_id);
 
         LLAvatarName& av_name = existing->second;
-        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent "
-                                 << agent_id 
-                                 << "user '" << av_name.mUsername << "' "
-                                 << "display '" << av_name.mDisplayName << "' "
-                                 << "expires in " << av_name.mExpires - LLFrameTimer::getTotalSeconds() << " seconds"
-                                 << LL_ENDL;
-		av_name.mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME; // reset expiry time so we don't constantly rerequest.
+        LL_DEBUGS("AvNameCache") << "LLAvatarNameCache use cache for agent " << agent_id << LL_ENDL;
+		av_name.dump();
+
+		 // Reset expiry time so we don't constantly rerequest.
+		av_name.setExpires(TEMP_CACHE_ENTRY_LIFETIME);
     }
 }
 
-void LLAvatarNameCache::processName(const LLUUID& agent_id,
-									const LLAvatarName& av_name,
-									bool add_to_cache)
+void LLAvatarNameCache::processName(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
-	if (add_to_cache)
-	{
-		sCache[agent_id] = av_name;
-	}
+	// Add to the cache
+	sCache[agent_id] = av_name;
 
+	// Suppress request from the queue
 	sPendingQueue.erase(agent_id);
 
-	// signal everyone waiting on this name
+	// Signal everyone waiting on this name
 	signal_map_t::iterator sig_it =	sSignalMap.find(agent_id);
 	if (sig_it != sSignalMap.end())
 	{
@@ -389,22 +369,33 @@ void LLAvatarNameCache::legacyNameCallback(const LLUUID& agent_id,
 										   const std::string& full_name,
 										   bool is_group)
 {
-	// Construct a dummy record for this name.  By convention, SLID is blank
-	// Never expires, but not written to disk, so lasts until end of session.
-	LLAvatarName av_name;
-	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameCallback "
-							 << "agent " << agent_id << " "
+	// Put the received data in the cache
+	legacyNameFetch(agent_id, full_name, is_group);
+	
+	// Retrieve the name and set it to never (or almost never...) expire: when we are using the legacy
+	// protocol, we do not get an expiration date for each name and there's no reason to ask the 
+	// data again and again so we set the expiration time to the largest value admissible.
+	std::map<LLUUID,LLAvatarName>::iterator av_record = sCache.find(agent_id);
+	LLAvatarName& av_name = av_record->second;
+	av_name.setExpires(MAX_UNREFRESHED_TIME);
+}
+
+void LLAvatarNameCache::legacyNameFetch(const LLUUID& agent_id,
+										const std::string& full_name,
+										bool is_group)
+{
+	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::legacyNameFetch "
+	                         << "agent " << agent_id << " "
 							 << "full name '" << full_name << "'"
-							 << ( is_group ? " [group]" : "" )
-							 << LL_ENDL;
-	buildLegacyName(full_name, &av_name);
-
-	// Add to cache, because if we don't we'll keep rerequesting the
-	// same record forever.  buildLegacyName should always guarantee
-	// that these records expire reasonably soon
-	// (in TEMP_CACHE_ENTRY_LIFETIME seconds), so if the failure was due
-	// to something temporary we will eventually request and get the right data.
-	processName(agent_id, av_name, true);
+	                         << ( is_group ? " [group]" : "" )
+	                         << LL_ENDL;
+	
+	// Construct an av_name record from this name.
+	LLAvatarName av_name;
+	av_name.fromString(full_name);
+	
+	// Add to cache: we're still using the new cache even if we're using the old (legacy) protocol.
+	processName(agent_id, av_name);
 }
 
 void LLAvatarNameCache::requestNamesViaLegacy()
@@ -426,25 +417,28 @@ void LLAvatarNameCache::requestNamesViaLegacy()
 		LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::requestNamesViaLegacy agent " << agent_id << LL_ENDL;
 
 		gCacheName->get(agent_id, false,  // legacy compatibility
-			boost::bind(&LLAvatarNameCache::legacyNameCallback,
-				_1, _2, _3));
+			boost::bind(&LLAvatarNameCache::legacyNameCallback, _1, _2, _3));
 	}
 }
 
-void LLAvatarNameCache::initClass(bool running)
+void LLAvatarNameCache::initClass(bool running, bool usePeopleAPI)
 {
 	sRunning = running;
+	sUsePeopleAPI = usePeopleAPI;
 }
 
 void LLAvatarNameCache::cleanupClass()
 {
+	sCache.clear();
 }
 
 void LLAvatarNameCache::importFile(std::istream& istr)
 {
 	LLSD data;
-	S32 parse_count = LLSDSerialize::fromXMLDocument(data, istr);
-	if (parse_count < 1) return;
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+	{
+		return;
+	}
 
 	// by convention LLSD storage is a map
 	// we only store one entry in the map
@@ -476,7 +470,7 @@ void LLAvatarNameCache::exportFile(std::ostream& ostr)
 		const LLUUID& agent_id = it->first;
 		const LLAvatarName& av_name = it->second;
 		// Do not write temporary or expired entries to the stored cache
-		if (!av_name.mIsTemporaryName && av_name.mExpires >= max_unrefreshed)
+		if (av_name.isValidName(max_unrefreshed))
 		{
 			// key must be a string
 			agents[agent_id.asString()] = av_name.asLLSD();
@@ -497,6 +491,11 @@ bool LLAvatarNameCache::hasNameLookupURL()
 	return !sNameLookupURL.empty();
 }
 
+bool LLAvatarNameCache::usePeopleAPI()
+{
+	return hasNameLookupURL() && sUsePeopleAPI;
+}
+
 void LLAvatarNameCache::idle()
 {
 	// By convention, start running at first idle() call
@@ -513,13 +512,12 @@ void LLAvatarNameCache::idle()
 
 	if (!sAskQueue.empty())
 	{
-        if (useDisplayNames())
+        if (usePeopleAPI())
         {
             requestNamesViaCapability();
         }
         else
         {
-            // ...fall back to legacy name cache system
             requestNamesViaLegacy();
         }
 	}
@@ -564,7 +562,7 @@ void LLAvatarNameCache::eraseUnrefreshed()
             if (av_name.mExpires < max_unrefreshed)
             {
                 LL_DEBUGS("AvNameCache") << it->first 
-                                         << " user '" << av_name.mUsername << "' "
+                                         << " user '" << av_name.getAccountName() << "' "
                                          << "expired " << now - av_name.mExpires << " secs ago"
                                          << LL_ENDL;
                 sCache.erase(it++);
@@ -578,20 +576,6 @@ void LLAvatarNameCache::eraseUnrefreshed()
 	}
 }
 
-void LLAvatarNameCache::buildLegacyName(const std::string& full_name,
-										LLAvatarName* av_name)
-{
-	llassert(av_name);
-	av_name->mUsername = "";
-	av_name->mDisplayName = full_name;
-	av_name->mIsDisplayNameDefault = true;
-	av_name->mIsTemporaryName = true;
-	av_name->mExpires = LLFrameTimer::getTotalSeconds() + TEMP_CACHE_ENTRY_LIFETIME;
-	LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::buildLegacyName "
-							 << full_name
-							 << LL_ENDL;
-}
-
 // fills in av_name if it has it in the cache, even if expired (can check expiry time)
 // returns bool specifying  if av_name was filled, false otherwise
 bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
@@ -599,38 +583,24 @@ bool LLAvatarNameCache::get(const LLUUID& agent_id, LLAvatarName *av_name)
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (useDisplayNames())
+		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+		if (it != sCache.end())
 		{
-			// ...use display names cache
-			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
-			if (it != sCache.end())
-			{
-				*av_name = it->second;
+			*av_name = it->second;
 
-				// re-request name if entry is expired
-				if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+			// re-request name if entry is expired
+			if (av_name->mExpires < LLFrameTimer::getTotalSeconds())
+			{
+				if (!isRequestPending(agent_id))
 				{
-					if (!isRequestPending(agent_id))
-					{
-						LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
-												 << "refresh agent " << agent_id
-												 << LL_ENDL;
-						sAskQueue.insert(agent_id);
-					}
+					LL_DEBUGS("AvNameCache") << "LLAvatarNameCache::get "
+											 << "refresh agent " << agent_id
+											 << LL_ENDL;
+					sAskQueue.insert(agent_id);
 				}
-				
-				return true;
-			}
-		}
-		else
-		{
-			// ...use legacy names cache
-			std::string full_name;
-			if (gCacheName->getFullName(agent_id, full_name))
-			{
-				buildLegacyName(full_name, av_name);
-				return true;
 			}
+				
+			return true;
 		}
 	}
 
@@ -661,30 +631,14 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 	if (sRunning)
 	{
 		// ...only do immediate lookups when cache is running
-		if (useDisplayNames())
+		std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
+		if (it != sCache.end())
 		{
-			// ...use new cache
-			std::map<LLUUID,LLAvatarName>::iterator it = sCache.find(agent_id);
-			if (it != sCache.end())
-			{
-				const LLAvatarName& av_name = it->second;
-				
-				if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
-				{
-					// ...name already exists in cache, fire callback now
-					fireSignal(agent_id, slot, av_name);
-					return connection;
-				}
-			}
-		}
-		else
-		{
-			// ...use old name system
-			std::string full_name;
-			if (gCacheName->getFullName(agent_id, full_name))
+			const LLAvatarName& av_name = it->second;
+			
+			if (av_name.mExpires > LLFrameTimer::getTotalSeconds())
 			{
-				LLAvatarName av_name;
-				buildLegacyName(full_name, &av_name);
+				// ...name already exists in cache, fire callback now
 				fireSignal(agent_id, slot, av_name);
 				return connection;
 			}
@@ -719,22 +673,13 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 
 void LLAvatarNameCache::setUseDisplayNames(bool use)
 {
-	if (use != sUseDisplayNames)
+	if (use != LLAvatarName::useDisplayNames())
 	{
-		sUseDisplayNames = use;
-		// flush our cache
-		sCache.clear();
-
+		LLAvatarName::setUseDisplayNames(use);
 		mUseDisplayNamesSignal();
 	}
 }
 
-bool LLAvatarNameCache::useDisplayNames()
-{
-	// Must be both manually set on and able to look up names.
-	return sUseDisplayNames && !sNameLookupURL.empty();
-}
-
 void LLAvatarNameCache::erase(const LLUUID& agent_id)
 {
 	sCache.erase(agent_id);
diff --git a/indra/llmessage/llavatarnamecache.h b/indra/llmessage/llavatarnamecache.h
index 79f170f7c8718b6485445f6c308c0dbcfbd9017a..2a8eb46187b1af5fbd308fbb551f6fe73f73a85f 100644
--- a/indra/llmessage/llavatarnamecache.h
+++ b/indra/llmessage/llavatarnamecache.h
@@ -37,33 +37,33 @@ class LLUUID;
 
 namespace LLAvatarNameCache
 {
-		
 	typedef boost::signals2::signal<void (void)> use_display_name_signal_t;
 
 	// Until the cache is set running, immediate lookups will fail and
 	// async lookups will be queued.  This allows us to block requests
 	// until we know if the first region supports display names.
-	void initClass(bool running);
+	void initClass(bool running, bool usePeopleAPI);
 	void cleanupClass();
 
+	// Import/export the name cache to file.
 	void importFile(std::istream& istr);
 	void exportFile(std::ostream& ostr);
 
-	// On the viewer, usually a simulator capabilitity
-	// If empty, name cache will fall back to using legacy name
-	// lookup system
+	// On the viewer, usually a simulator capabilitity.
+	// If empty, name cache will fall back to using legacy name lookup system.
 	void setNameLookupURL(const std::string& name_lookup_url);
 
-	// Do we have a valid lookup URL, hence are we trying to use the
-	// new display name lookup system?
+	// Do we have a valid lookup URL, i.e. are we trying to use the
+	// more recent display name lookup system?
 	bool hasNameLookupURL();
+	bool usePeopleAPI();
 	
 	// Periodically makes a batch request for display names not already in
-	// cache.  Call once per frame.
+	// cache. Called once per frame.
 	void idle();
 
 	// If name is in cache, returns true and fills in provided LLAvatarName
-	// otherwise returns false
+	// otherwise returns false.
 	bool get(const LLUUID& agent_id, LLAvatarName *av_name);
 
 	// Callback types for get() below
@@ -73,21 +73,19 @@ namespace LLAvatarNameCache
 	typedef callback_signal_t::slot_type callback_slot_t;
 	typedef boost::signals2::connection callback_connection_t;
 
-	// Fetches name information and calls callback.
-	// If name information is in cache, callback will be called immediately.
+	// Fetches name information and calls callbacks.
+	// If name information is in cache, callbacks will be called immediately.
 	callback_connection_t get(const LLUUID& agent_id, callback_slot_t slot);
 
-	// Allow display names to be explicitly disabled for testing.
+	// Set display name: flips the switch and triggers the callbacks.
 	void setUseDisplayNames(bool use);
-	bool useDisplayNames();
-
+	
+	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
 	void erase(const LLUUID& agent_id);
 
-    /// Provide some fallback for agents that return errors
+    /// Provide some fallback for agents that return errors.
 	void handleAgentError(const LLUUID& agent_id);
 
-	void insert(const LLUUID& agent_id, const LLAvatarName& av_name);
-
 	// Compute name expiration time from HTTP Cache-Control header,
 	// or return default value, in seconds from epoch.
 	F64 nameExpirationFromHeaders(LLSD headers);
diff --git a/indra/llmessage/llcachename.cpp b/indra/llmessage/llcachename.cpp
index 8f4af1984c7170beddab830091d7ed390f868ff8..267c48e1d2d5d692cc36c0792b0854eaa7ef0587 100644
--- a/indra/llmessage/llcachename.cpp
+++ b/indra/llmessage/llcachename.cpp
@@ -308,8 +308,10 @@ boost::signals2::connection LLCacheName::addObserver(const LLCacheNameCallback&
 bool LLCacheName::importFile(std::istream& istr)
 {
 	LLSD data;
-	if(LLSDSerialize::fromXMLDocument(data, istr) < 1)
+	if(LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(data, istr))
+	{
 		return false;
+	}
 
 	// We'll expire entries more than a week old
 	U32 now = (U32)time(NULL);
@@ -523,6 +525,7 @@ std::string LLCacheName::cleanFullName(const std::string& full_name)
 }
 
 //static 
+// Transform hard-coded name provided by server to a more legible username
 std::string LLCacheName::buildUsername(const std::string& full_name)
 {
 	// rare, but handle hard-coded error names returned from server
@@ -548,8 +551,9 @@ std::string LLCacheName::buildUsername(const std::string& full_name)
 		return username;
 	}
 
-	// if the input wasn't a correctly formatted legacy name just return it unchanged
-	return full_name;
+	// if the input wasn't a correctly formatted legacy name, just return it  
+	// cleaned up from a potential terminal "Resident"
+	return cleanFullName(full_name);
 }
 
 //static 
diff --git a/indra/llmessage/llcachename.h b/indra/llmessage/llcachename.h
index b108e37157a30613d9f008c11dcb94ac3e5183fd..d238c3a2476577c2aade72aad453c6b2a68a50fd 100644
--- a/indra/llmessage/llcachename.h
+++ b/indra/llmessage/llcachename.h
@@ -40,7 +40,7 @@ typedef boost::signals2::signal<void (const LLUUID& id,
                                       bool is_group)> LLCacheNameSignal;
 typedef LLCacheNameSignal::slot_type LLCacheNameCallback;
 
-// Old callback with user data for compatability
+// Old callback with user data for compatibility
 typedef void (*old_callback_t)(const LLUUID&, const std::string&, bool, void*);
 
 // Here's the theory:
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 8ffa8e4271120ba59a81efe9be0066547d0c1575..47041a2880710e50e201cca400a3e35f44511b0d 100644
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -175,9 +175,11 @@ void LLCurl::Responder::completedRaw(
 {
 	LLSD content;
 	LLBufferStream istr(channels, buffer.get());
-	if (!LLSDSerialize::fromXML(content, istr))
+	const bool emit_errors = false;
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(content, istr, emit_errors))
 	{
 		llinfos << "Failed to deserialize LLSD. " << mURL << " [" << status << "]: " << reason << llendl;
+		content["reason"] = reason;
 	}
 
 	completed(status, reason, content);
diff --git a/indra/llmessage/lldbstrings.h b/indra/llmessage/lldbstrings.h
index 9bf1b3eda4707e6f8a8e05368a4b820e592c8ca8..e23d17d5b6f310b288f93e1aa5f0ef150c8748bf 100644
--- a/indra/llmessage/lldbstrings.h
+++ b/indra/llmessage/lldbstrings.h
@@ -156,18 +156,6 @@ const S32 DB_USER_SKILLS_BUF_SIZE		= 255;
 const S32 DB_NV_NAME_STR_LEN			= 128;
 const S32 DB_NV_NAME_BUF_SIZE			= 129;
 
-// votes.vote_text						varchar(254)
-const S32 DB_VOTE_TEXT_STR_LEN			= 254;
-const S32 DB_VOTE_TEXT_BUF_SIZE			= 255;
-
-// vpte type text						varchar(9)
-const S32 DB_VOTE_TYPE_STR_LEN			= 9;
-const S32 DB_VOTE_TYPE_BUF_SIZE			= 10;
-
-// vote result text
-const S32 DB_VOTE_RESULT_BUF_LEN		= 8;
-const S32 DB_VOTE_RESULT_BUF_SIZE		= 9;
-
 // user_start_location.location_name	varchar(254)
 const S32 DB_START_LOCATION_STR_LEN		= 254;
 const S32 DB_START_LOCATION_BUF_SIZE	= 255;
diff --git a/indra/llmessage/llhttpassetstorage.cpp b/indra/llmessage/llhttpassetstorage.cpp
index d6ed08055e7764052586b9181ec1072649217883..7dcf160c9ba9c3ccb8d88a4b84d09cdbbac7d01f 100644
--- a/indra/llmessage/llhttpassetstorage.cpp
+++ b/indra/llmessage/llhttpassetstorage.cpp
@@ -747,9 +747,9 @@ LLAssetRequest* LLHTTPAssetStorage::findNextRequest(LLAssetStorage::request_list
 	request_list_t::iterator running_end   = running.end();
 
 	request_list_t::iterator pending_iter = pending.begin();
-	request_list_t::iterator pending_end  = pending.end();
+
 	// Loop over all pending requests until we miss finding it in the running list.
-	for (; pending_iter != pending_end; ++pending_iter)
+	for (; pending_iter != pending.end(); ++pending_iter)
 	{
 		LLAssetRequest* req = *pending_iter;
 		// Look for this pending request in the running list.
diff --git a/indra/llmessage/llhttpclient.cpp b/indra/llmessage/llhttpclient.cpp
old mode 100644
new mode 100755
index 0c325a68aaed740a04a71019a4163b86b64ad999..3561459bb40f28da675fed5bb755aa4d3eb83af9
--- a/indra/llmessage/llhttpclient.cpp
+++ b/indra/llmessage/llhttpclient.cpp
@@ -222,7 +222,11 @@ static void request(
 {
 	if (!LLHTTPClient::hasPump())
 	{
-		responder->completed(U32_MAX, "No pump", LLSD());
+		if (responder)
+		{
+			responder->completed(U32_MAX, "No pump", LLSD());
+		}
+		delete body_injector;
 		return;
 	}
 	LLPumpIO::chain_t chain;
@@ -230,8 +234,13 @@ static void request(
 	LLURLRequest* req = new LLURLRequest(method, url);
 	if(!req->isValid())//failed
 	{
-		delete req ;
-		return ;
+		if (responder)
+		{
+			responder->completed(498, "Internal Error - curl failure", LLSD());
+		}
+		delete req;
+		delete body_injector;
+		return;
 	}
 
 	req->setSSLVerifyCallback(LLHTTPClient::getCertVerifyCallback(), (void *)req);
diff --git a/indra/llmessage/llhttpclientadapter.cpp b/indra/llmessage/llhttpclientadapter.cpp
index f5d7a9abb6019442ad932e66237b39342fe788d1..0b59209af1b6d1efea5e01150b4d92fcd29ac6bf 100644
--- a/indra/llmessage/llhttpclientadapter.cpp
+++ b/indra/llmessage/llhttpclientadapter.cpp
@@ -43,8 +43,11 @@ void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr respo
 void LLHTTPClientAdapter::get(const std::string& url, LLCurl::ResponderPtr responder, const LLSD& headers) 
 {
 	LLSD empty_pragma_header = headers;
-	// as above
-	empty_pragma_header["Pragma"] = " ";
+	if (!empty_pragma_header.has("Pragma"))
+	{
+		// as above
+		empty_pragma_header["Pragma"] = " ";
+	}
 	LLHTTPClient::get(url, responder, empty_pragma_header);
 }
 
diff --git a/indra/llmessage/llinstantmessage.cpp b/indra/llmessage/llinstantmessage.cpp
index d68e0c423e51804c24d4c960901c0f6789ec141e..b0275c161b913be2c17d6fa1a130b4e607dde327 100644
--- a/indra/llmessage/llinstantmessage.cpp
+++ b/indra/llmessage/llinstantmessage.cpp
@@ -43,14 +43,6 @@
 const U8 IM_ONLINE = 0;
 const U8 IM_OFFLINE = 1;
 
-const S32 VOTE_YES = 1;
-const S32 VOTE_NO = 0;
-const S32 VOTE_ABSTAIN = -1;
-
-const S32 VOTE_MAJORITY = 0;
-const S32 VOTE_SUPER_MAJORITY = 1;
-const S32 VOTE_UNANIMOUS = 2;
-
 const char EMPTY_BINARY_BUCKET[] = "";
 const S32 EMPTY_BINARY_BUCKET_SIZE = 1;
 const U32 NO_TIMESTAMP = 0;
@@ -69,7 +61,6 @@ LLIMInfo::LLIMInfo() :
 	mViewerThinksToIsOnline(false),
 	mIMType(IM_NOTHING_SPECIAL),
 	mTimeStamp(0),
-	mSource(IM_FROM_SIM),
 	mTTL(IM_TTL)
 {
 }
@@ -88,7 +79,6 @@ LLIMInfo::LLIMInfo(
 	LLSD data,
 	U8 offline,
 	U32 timestamp,
-	EIMSource source,
 	S32 ttl) :
 	mFromID(from_id),
 	mFromGroup(from_group),
@@ -104,14 +94,12 @@ LLIMInfo::LLIMInfo(
 	mName(name),
 	mMessage(message),
 	mData(data),
-	mSource(source),
 	mTTL(ttl)
 {
 }
 
-LLIMInfo::LLIMInfo(LLMessageSystem* msg, EIMSource source, S32 ttl) :
+LLIMInfo::LLIMInfo(LLMessageSystem* msg, S32 ttl) :
 	mViewerThinksToIsOnline(false),
-	mSource(source),
 	mTTL(ttl)
 {
 	unpackMessageBlock(msg);
@@ -326,7 +314,6 @@ LLSD im_info_to_llsd(LLPointer<LLIMInfo> im_info)
 	param_message["region_id"] = im_info->mRegionID;
 	param_message["position"] = ll_sd_from_vector3(im_info->mPosition);
 	param_message["data"] = im_info->mData;
-	param_message["source"]= im_info->mSource;
 	param_message["ttl"] = im_info->mTTL;
 
 	LLSD param_agent;
@@ -359,7 +346,6 @@ LLPointer<LLIMInfo> llsd_to_im_info(const LLSD& im_info_sd)
 		param_message["data"],
 		(U8) param_message["offline"].asInteger(),
 		(U32) param_message["timestamp"].asInteger(),
-		(EIMSource)param_message["source"].asInteger(),
 		param_message["ttl"].asInteger());
 
 	return im_info;
@@ -381,7 +367,6 @@ LLPointer<LLIMInfo> LLIMInfo::clone()
 			mData,
 			mOffline,
 			mTimeStamp,
-			mSource,
 			mTTL);
 }
 
diff --git a/indra/llmessage/llinstantmessage.h b/indra/llmessage/llinstantmessage.h
index e0dae376b4b65166876a3edcfb925571c84d10e4..db4a38ea9e968668632ae8f81ee188fec70388c4 100644
--- a/indra/llmessage/llinstantmessage.h
+++ b/indra/llmessage/llinstantmessage.h
@@ -115,8 +115,8 @@ enum EInstantMessage
 	// viewer, since you can't IM an object yet.
 	IM_FROM_TASK = 19,
 
-	// sent an IM to a busy user, this is the auto response
-	IM_BUSY_AUTO_RESPONSE = 20,
+	// sent an IM to a do not disturb user, this is the auto response
+	IM_DO_NOT_DISTURB_AUTO_RESPONSE = 20,
 
 	// Shows the message in the console and chat history
 	IM_CONSOLE_AND_CHAT_HISTORY = 21,
@@ -164,57 +164,9 @@ enum EInstantMessage
 };
 
 
-// Hooks for quickly hacking in experimental admin debug messages 
-// without needing to recompile the viewer
-// *NOTE: This functionality has been moved to be a string based
-// operation so that we don't even have to do a full recompile. This
-// enumeration will be phased out soon.
-enum EGodlikeRequest
-{
-	GOD_WANTS_NOTHING,
-
-	// for requesting physics information about an object
-	GOD_WANTS_PHYSICS_INFO,
-	
-	// two unused requests that can be appropriated for debug 
-	// purposes (no viewer recompile necessary)
-	GOD_WANTS_FOO,
-	GOD_WANTS_BAR,
-
-	// to dump simulator terrain data to terrain.raw file
-	GOD_WANTS_TERRAIN_SAVE,
-	// to load simulator terrain data from terrain.raw file
-	GOD_WANTS_TERRAIN_LOAD,
-
-	GOD_WANTS_TOGGLE_AVATAR_GEOMETRY,	// HACK for testing new avatar geom
-
-	// real-time telehub operations
-	GOD_WANTS_TELEHUB_INFO,
-	GOD_WANTS_CONNECT_TELEHUB,
-	GOD_WANTS_DELETE_TELEHUB,
-	GOD_WANTS_ADD_TELEHUB_SPAWNPOINT,
-	GOD_WANTS_REMOVE_TELEHUB_SPAWNPOINT,
-
-};
-
-enum EIMSource
-{
-	IM_FROM_VIEWER,
-	IM_FROM_DATASERVER,
-	IM_FROM_SIM
-};
-
 extern const U8 IM_ONLINE;
 extern const U8 IM_OFFLINE;
 
-extern const S32 VOTE_YES;
-extern const S32 VOTE_NO;
-extern const S32 VOTE_ABSTAIN;
-
-extern const S32 VOTE_MAJORITY;
-extern const S32 VOTE_SUPER_MAJORITY;
-extern const S32 VOTE_UNANIMOUS;
-
 extern const char EMPTY_BINARY_BUCKET[];
 extern const S32 EMPTY_BINARY_BUCKET_SIZE;
 
@@ -234,7 +186,6 @@ class LLIMInfo : public LLRefCount
 
 public:
 	LLIMInfo(LLMessageSystem* msg, 
-			EIMSource source = IM_FROM_SIM, 
 			S32 ttl = IM_TTL);
 
 	LLIMInfo(
@@ -251,7 +202,6 @@ class LLIMInfo : public LLRefCount
 		LLSD data,
 		U8 offline,
 		U32 timestamp,
-		EIMSource source,
 		S32 ttl = IM_TTL);
 
 	void packInstantMessage(LLMessageSystem* msg) const;
@@ -274,7 +224,6 @@ class LLIMInfo : public LLRefCount
 	std::string mMessage;
 	LLSD mData;
 
-	EIMSource mSource;
 	S32 mTTL;
 };
 
diff --git a/indra/llmessage/lliosocket.cpp b/indra/llmessage/lliosocket.cpp
index 0287026659a1b4406356a4cecfd5592a0e2e31b9..2043bae5e7c0b6c8d42d0d5e9f7d75826577e6be 100644
--- a/indra/llmessage/lliosocket.cpp
+++ b/indra/llmessage/lliosocket.cpp
@@ -592,6 +592,15 @@ LLIOPipe::EStatus LLIOServerSocket::process_impl(
 	PUMP_DEBUG;
 	apr_pool_t* new_pool = NULL;
 	apr_status_t status = apr_pool_create(&new_pool, mPool);
+	if(ll_apr_warn_status(status))
+	{
+		if(new_pool)
+		{	
+			apr_pool_destroy(new_pool);
+		}
+		return STATUS_ERROR;
+	}
+
 	apr_socket_t* socket = NULL;
 	status = apr_socket_accept(
 		&socket,
diff --git a/indra/llmessage/llregionflags.h b/indra/llmessage/llregionflags.h
index 7b796a0fa875f92785ac0f0c376338c453188f97..1cf940918b72ff4b8aaa0a89977d8714b7f58080 100644
--- a/indra/llmessage/llregionflags.h
+++ b/indra/llmessage/llregionflags.h
@@ -28,95 +28,98 @@
 #define LL_LLREGIONFLAGS_H
 
 // Can you be hurt here? Should health be on?
-const U32 REGION_FLAGS_ALLOW_DAMAGE				= (1 << 0);
+const U64 REGION_FLAGS_ALLOW_DAMAGE				= (1 << 0);
 
 // Can you make landmarks here?
-const U32 REGION_FLAGS_ALLOW_LANDMARK			= (1 << 1);
+const U64 REGION_FLAGS_ALLOW_LANDMARK			= (1 << 1);
 
 // Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_ALLOW_SET_HOME			= (1 << 2);
+const U64 REGION_FLAGS_ALLOW_SET_HOME			= (1 << 2);
 
 // Do we reset the home position when someone teleports away from here?
-const U32 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
+const U64 REGION_FLAGS_RESET_HOME_ON_TELEPORT	= (1 << 3);
 
 // Does the sun move?
-const U32 REGION_FLAGS_SUN_FIXED				= (1 << 4);
+const U64 REGION_FLAGS_SUN_FIXED				= (1 << 4);
 
 // Can't change the terrain heightfield, even on owned parcels,
 // but can plant trees and grass.
-const U32 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
+const U64 REGION_FLAGS_BLOCK_TERRAFORM			= (1 << 6);
 
 // Can't release, sell, or buy land.
-const U32 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);
+const U64 REGION_FLAGS_BLOCK_LAND_RESELL		= (1 << 7);
 
 // All content wiped once per night
-const U32 REGION_FLAGS_SANDBOX					= (1 << 8);
-const U32 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies
-const U32 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);
-const U32 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics
-const U32 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
-const U32 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
-const U32 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);
+const U64 REGION_FLAGS_SANDBOX					= (1 << 8);
+const U64 REGION_FLAGS_SKIP_COLLISIONS			= (1 << 12); // Pin all non agent rigid bodies
+const U64 REGION_FLAGS_SKIP_SCRIPTS				= (1 << 13);
+const U64 REGION_FLAGS_SKIP_PHYSICS				= (1 << 14); // Skip all physics
+const U64 REGION_FLAGS_EXTERNALLY_VISIBLE		= (1 << 15);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT = (1 << 16);
+const U64 REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT = (1 << 17);
+const U64 REGION_FLAGS_BLOCK_DWELL				= (1 << 18);
 
 // Is flight allowed?
-const U32 REGION_FLAGS_BLOCK_FLY				= (1 << 19);	
+const U64 REGION_FLAGS_BLOCK_FLY				= (1 << 19);	
 
 // Is direct teleport (p2p) allowed?
-const U32 REGION_FLAGS_ALLOW_DIRECT_TELEPORT	= (1 << 20);
+const U64 REGION_FLAGS_ALLOW_DIRECT_TELEPORT	= (1 << 20);
 
 // Is there an administrative override on scripts in the region at the
 // moment. This is the similar skip scripts, except this flag is
 // presisted in the database on an estate level.
-const U32 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);
+const U64 REGION_FLAGS_ESTATE_SKIP_SCRIPTS		= (1 << 21);
 
-const U32 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);
+const U64 REGION_FLAGS_RESTRICT_PUSHOBJECT		= (1 << 22);
 
-const U32 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23);
+const U64 REGION_FLAGS_DENY_ANONYMOUS			= (1 << 23);
 
-const U32 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
+const U64 REGION_FLAGS_ALLOW_PARCEL_CHANGES		= (1 << 26);
 
-const U32 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
+const U64 REGION_FLAGS_ALLOW_VOICE = (1 << 28);
 
-const U32 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
-const U32 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
+const U64 REGION_FLAGS_BLOCK_PARCEL_SEARCH = (1 << 29);
+const U64 REGION_FLAGS_DENY_AGEUNVERIFIED	= (1 << 30);
 
-const U32 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
+const U64 REGION_FLAGS_DEFAULT = REGION_FLAGS_ALLOW_LANDMARK |
 								 REGION_FLAGS_ALLOW_SET_HOME |
                                  REGION_FLAGS_ALLOW_PARCEL_CHANGES |
                                  REGION_FLAGS_ALLOW_VOICE;
 
 
-const U32 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
-const U32 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK 
+const U64 REGION_FLAGS_PRELUDE_SET = REGION_FLAGS_RESET_HOME_ON_TELEPORT;
+const U64 REGION_FLAGS_PRELUDE_UNSET = REGION_FLAGS_ALLOW_LANDMARK 
 									   | REGION_FLAGS_ALLOW_SET_HOME;
 
-const U32 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
+const U64 REGION_FLAGS_ESTATE_MASK = REGION_FLAGS_EXTERNALLY_VISIBLE
 									 | REGION_FLAGS_SUN_FIXED
 									 | REGION_FLAGS_DENY_ANONYMOUS
 									 | REGION_FLAGS_DENY_AGEUNVERIFIED;
 
-inline BOOL is_prelude( U32 flags )
+inline BOOL is_prelude( U64 flags )
 {
 	// definition of prelude does not depend on fixed-sun
 	return 0 == (flags & REGION_FLAGS_PRELUDE_UNSET)
 		   && 0 != (flags & REGION_FLAGS_PRELUDE_SET);
 }
 
-inline U32 set_prelude_flags(U32 flags)
+inline U64 set_prelude_flags(U64 flags)
 {
 	// also set the sun-fixed flag
 	return ((flags & ~REGION_FLAGS_PRELUDE_UNSET)
 			| (REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
 }
 
-inline U32 unset_prelude_flags(U32 flags)
+inline U64 unset_prelude_flags(U64 flags)
 {
 	// also unset the fixed-sun flag
 	return ((flags | REGION_FLAGS_PRELUDE_UNSET) 
 			& ~(REGION_FLAGS_PRELUDE_SET | REGION_FLAGS_SUN_FIXED));
 }
 
+// Region protocols
+const U64 REGION_PROTOCOLS_AGENT_APPEARANCE_SERVICE = (1 << 0);
+
 // estate constants. Need to match first few etries in indra.estate table.
 const U32 ESTATE_ALL = 0; // will not match in db, reserved key for logic
 const U32 ESTATE_MAINLAND = 1;
diff --git a/indra/llmessage/llurlrequest.cpp b/indra/llmessage/llurlrequest.cpp
index 227efdb07af27b33dc6574336367ebae5b560cc7..627d5918392f94b9d307890d6e225d57dbbbab00 100644
--- a/indra/llmessage/llurlrequest.cpp
+++ b/indra/llmessage/llurlrequest.cpp
@@ -174,6 +174,10 @@ LLURLRequest::~LLURLRequest()
 void LLURLRequest::setURL(const std::string& url)
 {
 	mDetail->mURL = url;
+	if (url.empty())
+	{
+		llwarns << "empty URL specified" << llendl;
+	}
 }
 
 std::string LLURLRequest::getURL() const
diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp
index d7658862da4f3eb2f83816d55587bfaff43ccd64..39cfb6019e5af4cfdaf2b88e8e3a55a4401571e4 100644
--- a/indra/llmessage/message_prehash.cpp
+++ b/indra/llmessage/message_prehash.cpp
@@ -279,6 +279,8 @@ char const* const _PREHASH_GrabOffset = LLMessageStringTable::getInstance()->get
 char const* const _PREHASH_SimPort = LLMessageStringTable::getInstance()->getString("SimPort");
 char const* const _PREHASH_PricePerMeter = LLMessageStringTable::getInstance()->getString("PricePerMeter");
 char const* const _PREHASH_RegionFlags = LLMessageStringTable::getInstance()->getString("RegionFlags");
+char const* const _PREHASH_RegionFlagsExtended = LLMessageStringTable::getInstance()->getString("RegionFlagsExtended");
+char const* const _PREHASH_RegionProtocols = LLMessageStringTable::getInstance()->getString("RegionProtocols");
 char const* const _PREHASH_VoteResult = LLMessageStringTable::getInstance()->getString("VoteResult");
 char const* const _PREHASH_ParcelDirFeeEstimate = LLMessageStringTable::getInstance()->getString("ParcelDirFeeEstimate");
 char const* const _PREHASH_ModifyBlock = LLMessageStringTable::getInstance()->getString("ModifyBlock");
@@ -305,6 +307,8 @@ char const* const _PREHASH_ViewerStartAuction = LLMessageStringTable::getInstanc
 char const* const _PREHASH_StartAuction = LLMessageStringTable::getInstance()->getString("StartAuction");
 char const* const _PREHASH_DuplicateFlags = LLMessageStringTable::getInstance()->getString("DuplicateFlags");
 char const* const _PREHASH_RegionInfo2 = LLMessageStringTable::getInstance()->getString("RegionInfo2");
+char const* const _PREHASH_RegionInfo3 = LLMessageStringTable::getInstance()->getString("RegionInfo3");
+char const* const _PREHASH_RegionInfo4 = LLMessageStringTable::getInstance()->getString("RegionInfo4");
 char const* const _PREHASH_TextColor = LLMessageStringTable::getInstance()->getString("TextColor");
 char const* const _PREHASH_SlaveID = LLMessageStringTable::getInstance()->getString("SlaveID");
 char const* const _PREHASH_Charter = LLMessageStringTable::getInstance()->getString("Charter");
@@ -1376,3 +1380,6 @@ char const* const _PREHASH_ProductSKU = LLMessageStringTable::getInstance()->get
 char const* const _PREHASH_SeeAVs = LLMessageStringTable::getInstance()->getString("SeeAVs");
 char const* const _PREHASH_AnyAVSounds = LLMessageStringTable::getInstance()->getString("AnyAVSounds");
 char const* const _PREHASH_GroupAVSounds = LLMessageStringTable::getInstance()->getString("GroupAVSounds");
+char const* const _PREHASH_AppearanceData = LLMessageStringTable::getInstance()->getString("AppearanceData");
+char const* const _PREHASH_AppearanceVersion = LLMessageStringTable::getInstance()->getString("AppearanceVersion");
+char const* const _PREHASH_CofVersion = LLMessageStringTable::getInstance()->getString("CofVersion");
diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h
index da2b613f539022bc58bfaa2013d7b77272e365d1..573e10dc0bc2dc630d5a1153693e79e2434ece7b 100644
--- a/indra/llmessage/message_prehash.h
+++ b/indra/llmessage/message_prehash.h
@@ -279,6 +279,8 @@ extern char const* const _PREHASH_GrabOffset;
 extern char const* const _PREHASH_SimPort;
 extern char const* const _PREHASH_PricePerMeter;
 extern char const* const _PREHASH_RegionFlags;
+extern char const* const _PREHASH_RegionFlagsExtended;
+extern char const* const _PREHASH_RegionProtocols;
 extern char const* const _PREHASH_VoteResult;
 extern char const* const _PREHASH_ParcelDirFeeEstimate;
 extern char const* const _PREHASH_ModifyBlock;
@@ -305,6 +307,8 @@ extern char const* const _PREHASH_ViewerStartAuction;
 extern char const* const _PREHASH_StartAuction;
 extern char const* const _PREHASH_DuplicateFlags;
 extern char const* const _PREHASH_RegionInfo2;
+extern char const* const _PREHASH_RegionInfo3;
+extern char const* const _PREHASH_RegionInfo4;
 extern char const* const _PREHASH_TextColor;
 extern char const* const _PREHASH_SlaveID;
 extern char const* const _PREHASH_Charter;
@@ -1376,4 +1380,7 @@ extern char const* const _PREHASH_ProductSKU;
 extern char const* const _PREHASH_SeeAVs;
 extern char const* const _PREHASH_AnyAVSounds;
 extern char const* const _PREHASH_GroupAVSounds;
+extern char const* const _PREHASH_AppearanceData;
+extern char const* const _PREHASH_AppearanceVersion;
+extern char const* const _PREHASH_CofVersion;
 #endif
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index 7c3def6024e6a3abbd3ae474b13a3460dc120098..87cbafa404c441e83a481e0302fbfe021c7096bf 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -47,37 +47,6 @@
 
 namespace tut
 {
-	LLSD storage;
-
-	class LLSDStorageNode : public LLHTTPNode
-	{
-	public:
-		LLSD simpleGet() const					{ return storage; }
-		LLSD simplePut(const LLSD& value) const	{ storage = value; return LLSD(); }
-	};
-
-	class ErrorNode : public LLHTTPNode
-	{
-	public:
-		void get(ResponsePtr r, const LLSD& context) const
-			{ r->status(599, "Intentional error"); }
-		void post(ResponsePtr r, const LLSD& context, const LLSD& input) const
-			{ r->status(input["status"], input["reason"]); }
-	};
-
-	class TimeOutNode : public LLHTTPNode
-	{
-	public:
-		void get(ResponsePtr r, const LLSD& context) const
-		{
-            /* do nothing, the request will eventually time out */ 
-		}
-	};
-
-	LLHTTPRegistration<LLSDStorageNode> gStorageNode("/test/storage");
-	LLHTTPRegistration<ErrorNode>		gErrorNode("/test/error");
-	LLHTTPRegistration<TimeOutNode>		gTimeOutNode("/test/timeout");
-
 	struct HTTPClientTestData
 	{
 	public:
@@ -91,7 +60,6 @@ namespace tut
 			ensure("Set environment variable PORT to local test server port", PORT);
 			apr_pool_create(&mPool, NULL);
 			LLCurl::initClass(false);
-			mServerPump = new LLPumpIO(mPool);
 			mClientPump = new LLPumpIO(mPool);
 
 			LLHTTPClient::setPump(*mClientPump);
@@ -99,20 +67,11 @@ namespace tut
 
 		~HTTPClientTestData()
 		{
-			delete mServerPump;
 			delete mClientPump;
 			LLProxy::cleanupClass();
 			apr_pool_destroy(mPool);
 		}
 
-		void setupTheServer()
-		{
-			LLHTTPNode& root = LLIOHTTPServer::create(mPool, *mServerPump, 8888);
-
-			LLHTTPStandardServices::useServices();
-			LLHTTPRegistrar::buildAllServices(root);
-		}
-
 		void runThePump(float timeout = 100.0f)
 		{
 			LLTimer timer;
@@ -120,11 +79,7 @@ namespace tut
 
 			while(!mSawCompleted && !mSawCompletedHeader && !timer.hasExpired())
 			{
-				if (mServerPump)
-				{
-					mServerPump->pump();
-					mServerPump->callback();
-				}
+				LLFrameTimer::updateFrameTime();
 				if (mClientPump)
 				{
 					mClientPump->pump();
@@ -133,18 +88,11 @@ namespace tut
 			}
 		}
 
-		void killServer()
-		{
-			delete mServerPump;
-			mServerPump = NULL;
-		}
-
 		const char* const PORT;
 		const std::string local_server;
 
 	private:
 		apr_pool_t* mPool;
-		LLPumpIO* mServerPump;
 		LLPumpIO* mClientPump;
 
 	protected:
@@ -288,14 +236,12 @@ namespace tut
 		sd["list"][1]["three"] = 3;
 		sd["list"][1]["four"] = 4;
 		
-		setupTheServer();
-
-		LLHTTPClient::post("http://localhost:8888/web/echo", sd, newResult());
+		LLHTTPClient::post(local_server + "web/echo", sd, newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure_equals("echoed result matches", getResult(), sd);
 	}
-
+		
 	template<> template<>
 		void HTTPClientTestObject::test<4>()
 	{
@@ -303,12 +249,11 @@ namespace tut
 
 		sd["message"] = "This is my test message.";
 
-		setupTheServer();
-		LLHTTPClient::put("http://localhost:8888/test/storage", sd, newResult());
+		LLHTTPClient::put(local_server + "test/storage", sd, newResult());
 		runThePump();
 		ensureStatusOK();
 
-		LLHTTPClient::get("http://localhost:8888/test/storage", newResult());
+		LLHTTPClient::get(local_server + "test/storage", newResult());
 		runThePump();
 		ensureStatusOK();
 		ensure_equals("echoed result matches", getResult(), sd);
@@ -322,9 +267,7 @@ namespace tut
 		sd["status"] = 543;
 		sd["reason"] = "error for testing";
 
-		setupTheServer();
-
-		LLHTTPClient::post("http://localhost:8888/test/error", sd, newResult());
+		LLHTTPClient::post(local_server + "test/error", sd, newResult());
 		runThePump();
 		ensureStatusError();
 		ensure_contains("reason", mReason, sd["reason"]);
@@ -333,23 +276,16 @@ namespace tut
 	template<> template<>
 		void HTTPClientTestObject::test<6>()
 	{
-		setupTheServer();
-
-		LLHTTPClient::get("http://localhost:8888/test/timeout", newResult());
-		runThePump(1.0f);
-		killServer();
-		runThePump();
+		const F32 timeout = 1.0f;
+		LLHTTPClient::get(local_server + "test/timeout", newResult(), LLSD(), timeout);
+		runThePump(timeout * 5.0f);
 		ensureStatusError();
-		ensure_equals("reason", mReason, "STATUS_ERROR");
+		ensure_equals("reason", mReason, "STATUS_EXPIRED");
 	}
 
 	template<> template<>
 		void HTTPClientTestObject::test<7>()
 	{
-		// Can not use the little mini server.  The blocking request
-		// won't ever let it run.  Instead get from a known LLSD
-		// source and compare results with the non-blocking get which
-		// is tested against the mini server earlier.
 		LLHTTPClient::get(local_server, newResult());
 		runThePump();
 		ensureStatusOK();
diff --git a/indra/llmessage/tests/test_llsdmessage_peer.py b/indra/llmessage/tests/test_llsdmessage_peer.py
index fe4f3a8c011b095ab7b020f5b6d01c1216bc30a7..e45249b1cba1ca41b539b2dfa1d2aff1034409fe 100644
--- a/indra/llmessage/tests/test_llsdmessage_peer.py
+++ b/indra/llmessage/tests/test_llsdmessage_peer.py
@@ -39,6 +39,9 @@
 from indra.util.fastest_elementtree import parse as xml_parse
 from indra.base import llsd
 from testrunner import freeport, run, debug, VERBOSE
+import time
+
+_storage=None
 
 class TestHTTPRequestHandler(BaseHTTPRequestHandler):
     """This subclass of BaseHTTPRequestHandler is to receive and echo
@@ -90,21 +93,14 @@ def do_POST(self):
         # Read the provided POST data.
         self.answer(self.read_xml())
 
+    def do_PUT(self):
+        # Read the provided PUT data.
+        self.answer(self.read_xml())
+
     def answer(self, data, withdata=True):
+        global _storage
         debug("%s.answer(%s): self.path = %r", self.__class__.__name__, data, self.path)
-        if "fail" not in self.path:
-            data = data.copy()          # we're going to modify
-            # Ensure there's a "reply" key in data, even if there wasn't before
-            data["reply"] = data.get("reply", llsd.LLSD("success"))
-            response = llsd.format_xml(data)
-            debug("success: %s", response)
-            self.send_response(200)
-            self.send_header("Content-type", "application/llsd+xml")
-            self.send_header("Content-Length", str(len(response)))
-            self.end_headers()
-            if withdata:
-                self.wfile.write(response)
-        else:                           # fail requested
+        if "fail" in self.path or "test/error" in self.path: # fail requested
             status = data.get("status", 500)
             # self.responses maps an int status to a (short, long) pair of
             # strings. We want the longer string. That's why we pass a string
@@ -117,6 +113,30 @@ def answer(self, data, withdata=True):
                                                    "without providing a reason" % status))[1])
             debug("fail requested: %s: %r", status, reason)
             self.send_error(status, reason)
+        else:
+            if "web/echo" in self.path:
+                pass
+            elif "test/timeout" in self.path:
+                time.sleep(5.0)
+                return
+            elif "test/storage" in self.path:
+                if "GET" == self.command:
+                    data = _storage
+                else:
+                    _storage = data
+                    data = "ok"
+            else:
+                data = data.copy()          # we're going to modify
+                # Ensure there's a "reply" key in data, even if there wasn't before
+                data["reply"] = data.get("reply", llsd.LLSD("success"))
+            response = llsd.format_xml(data)
+            debug("success: %s", response)
+            self.send_response(200)
+            self.send_header("Content-type", "application/llsd+xml")
+            self.send_header("Content-Length", str(len(response)))
+            self.end_headers()
+            if withdata:
+                self.wfile.write(response)
 
     if not VERBOSE:
         # When VERBOSE is set, skip both these overrides because they exist to
diff --git a/indra/llplugin/CMakeLists.txt b/indra/llplugin/CMakeLists.txt
index 1353b7a4587161b2abbed44697bebdf99d9b46f2..75d89aac785d4c44f0d28210951a65ea3b104d5b 100644
--- a/indra/llplugin/CMakeLists.txt
+++ b/indra/llplugin/CMakeLists.txt
@@ -22,6 +22,10 @@ include_directories(
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLQTWEBKIT_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llplugin_SOURCE_FILES
     llpluginclassmedia.cpp
diff --git a/indra/llplugin/llpluginprocessparent.cpp b/indra/llplugin/llpluginprocessparent.cpp
index 71a6145b581b519fd02e70a8fb3c58be04a07653..a4da7674d593f2f44965b6d92798f114a6fab984 100644
--- a/indra/llplugin/llpluginprocessparent.cpp
+++ b/indra/llplugin/llpluginprocessparent.cpp
@@ -31,6 +31,7 @@
 #include "llpluginprocessparent.h"
 #include "llpluginmessagepipe.h"
 #include "llpluginmessageclasses.h"
+#include "llsdserialize.h"
 #include "stringize.h"
 
 #include "llapr.h"
@@ -836,7 +837,7 @@ void LLPluginProcessParent::receiveMessageRaw(const std::string &message)
 	LL_DEBUGS("Plugin") << "Received: " << message << LL_ENDL;
 	
 	LLPluginMessage parsed;
-	if(parsed.parse(message) != -1)
+	if(LLSDParser::PARSE_FAILURE != parsed.parse(message))
 	{
 		if(parsed.hasValue("blocking_request"))
 		{
diff --git a/indra/llplugin/slplugin/CMakeLists.txt b/indra/llplugin/slplugin/CMakeLists.txt
index 8183467dc5bcdaa8ae57521a8bca8f4075a8b583..03412d95d528d5ef79e8ba88505c562c7c5940ae 100644
--- a/indra/llplugin/slplugin/CMakeLists.txt
+++ b/indra/llplugin/slplugin/CMakeLists.txt
@@ -12,6 +12,9 @@ include_directories(
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLCOMMON_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt
index e4d9de7eb64cea94020c14ecaa08f66bebb9aa52..1768a06a279f316eb66ae62ecd0db086fd105ca9 100644
--- a/indra/llprimitive/CMakeLists.txt
+++ b/indra/llprimitive/CMakeLists.txt
@@ -14,10 +14,14 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
+    )
 
 set(llprimitive_SOURCE_FILES
     llmaterialtable.cpp
@@ -59,6 +63,15 @@ list(APPEND llprimitive_SOURCE_FILES ${llprimitive_HEADER_FILES})
 
 add_library (llprimitive ${llprimitive_SOURCE_FILES})
 
+target_link_libraries(llprimitive
+    ${LLCOMMON_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLMESSAGE_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLPHYSICSEXTENSIONS_LIBRARIES}
+    )
+
+
 #add unit tests
 if (LL_TESTS)
     INCLUDE(LLAddBuildTest)
diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp
index 946251f38399a24933a46b61843de41c80e1c130..c340fc2d353af999925b9768faa888341b83bb03 100644
--- a/indra/llprimitive/llprimitive.cpp
+++ b/indra/llprimitive/llprimitive.cpp
@@ -38,6 +38,7 @@
 #include "lldatapacker.h"
 #include "llsdutil_math.h"
 #include "llprimtexturelist.h"
+#include "imageids.h"
 
 /**
  * exported constants
@@ -1230,94 +1231,78 @@ BOOL LLPrimitive::packTEMessage(LLDataPacker &dp) const
 	return FALSE;
 }
 
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name)
+S32 LLPrimitive::parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec)
 {
-	return(unpackTEMessage(mesgsys,block_name,-1));
-}
-
-S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
-{
-	// use a negative block_num to indicate a single-block read (a non-variable block)
 	S32 retval = 0;
-	const U32 MAX_TES = 32;
-
-	// Avoid construction of 32 UUIDs per call. JC
-
-	U8     image_data[MAX_TES*16];
-	U8	  colors[MAX_TES*4];
-	F32    scale_s[MAX_TES];
-	F32    scale_t[MAX_TES];
-	S16    offset_s[MAX_TES];
-	S16    offset_t[MAX_TES];
-	S16    image_rot[MAX_TES];
-	U8	   bump[MAX_TES];
-	U8	   media_flags[MAX_TES];
-    U8     glow[MAX_TES];
-	
-	const U32 MAX_TE_BUFFER = 4096;
-	U8 packed_buffer[MAX_TE_BUFFER];
-	U8 *cur_ptr = packed_buffer;
-
-	U32 size;
-	U32 face_count = 0;
 
 	if (block_num < 0)
 	{
-		size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
+		tec.size = mesgsys->getSizeFast(block_name, _PREHASH_TextureEntry);
 	}
 	else
 	{
-		size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
+		tec.size = mesgsys->getSizeFast(block_name, block_num, _PREHASH_TextureEntry);
 	}
 
-	if (size == 0)
+	if (tec.size == 0)
 	{
+		tec.face_count = 0;
 		return retval;
 	}
 
 	if (block_num < 0)
 	{
-		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, 0, MAX_TE_BUFFER);
+		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, 0, LLTEContents::MAX_TE_BUFFER);
 	}
 	else
 	{
-		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, packed_buffer, 0, block_num, MAX_TE_BUFFER);
+		mesgsys->getBinaryDataFast(block_name, _PREHASH_TextureEntry, tec.packed_buffer, 0, block_num, LLTEContents::MAX_TE_BUFFER);
 	}
 
-	face_count = getNumTEs();
+	tec.face_count = llmin((U32)getNumTEs(),(U32)LLTEContents::MAX_TES);
 
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_data, 16, face_count, MVT_LLUUID);
+	U8 *cur_ptr = tec.packed_buffer;
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_data, 16, tec.face_count, MVT_LLUUID);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)colors, 4, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.colors, 4, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_s, 4, face_count, MVT_F32);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_s, 4, tec.face_count, MVT_F32);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)scale_t, 4, face_count, MVT_F32);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.scale_t, 4, tec.face_count, MVT_F32);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_s, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_s, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)offset_t, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.offset_t, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)image_rot, 2, face_count, MVT_S16Array);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.image_rot, 2, tec.face_count, MVT_S16Array);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)bump, 1, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.bump, 1, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)media_flags, 1, face_count, MVT_U8);
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.media_flags, 1, tec.face_count, MVT_U8);
 	cur_ptr++;
-	cur_ptr += unpackTEField(cur_ptr, packed_buffer+size, (U8 *)glow, 1, face_count, MVT_U8);
-	
+	cur_ptr += unpackTEField(cur_ptr, tec.packed_buffer+tec.size, (U8 *)tec.glow, 1, tec.face_count, MVT_U8);
+
+	retval = 1;
+	return retval;
+}
+
+S32 LLPrimitive::applyParsedTEMessage(LLTEContents& tec)
+{
+	S32 retval = 0;
+
 	LLColor4 color;
 	LLColor4U coloru;
-	for (U32 i = 0; i < face_count; i++)
-	{
-		retval |= setTETexture(i, ((LLUUID*)image_data)[i]);
-		retval |= setTEScale(i, scale_s[i], scale_t[i]);
-		retval |= setTEOffset(i, (F32)offset_s[i] / (F32)0x7FFF, (F32) offset_t[i] / (F32) 0x7FFF);
-		retval |= setTERotation(i, ((F32)image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
-		retval |= setTEBumpShinyFullbright(i, bump[i]);
-		retval |= setTEMediaTexGen(i, media_flags[i]);
-		retval |= setTEGlow(i, (F32)glow[i] / (F32)0xFF);
-		coloru = LLColor4U(colors + 4*i);
+	for (U32 i = 0; i < tec.face_count; i++)
+	{
+		LLUUID& req_id = ((LLUUID*)tec.image_data)[i];
+		retval |= setTETexture(i, req_id);
+		retval |= setTEScale(i, tec.scale_s[i], tec.scale_t[i]);
+		retval |= setTEOffset(i, (F32)tec.offset_s[i] / (F32)0x7FFF, (F32) tec.offset_t[i] / (F32) 0x7FFF);
+		retval |= setTERotation(i, ((F32)tec.image_rot[i] / TEXTURE_ROTATION_PACK_FACTOR) * F_TWO_PI);
+		retval |= setTEBumpShinyFullbright(i, tec.bump[i]);
+		retval |= setTEMediaTexGen(i, tec.media_flags[i]);
+		retval |= setTEGlow(i, (F32)tec.glow[i] / (F32)0xFF);
+		coloru = LLColor4U(tec.colors + 4*i);
 
 		// Note:  This is an optimization to send common colors (1.f, 1.f, 1.f, 1.f)
 		// as all zeros.  However, the subtraction and addition must be done in unsigned
@@ -1334,6 +1319,15 @@ S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_nam
 	return retval;
 }
 
+S32 LLPrimitive::unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num)
+{
+	LLTEContents tec;
+	S32 retval = parseTEMessage(mesgsys, block_name, block_num, tec);
+	if (!retval)
+		return retval;
+	return applyParsedTEMessage(tec);
+}
+
 S32 LLPrimitive::unpackTEMessage(LLDataPacker &dp)
 {
 	// use a negative block_num to indicate a single-block read (a non-variable block)
diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h
index 8dcaa8c740b58c47f742e0c340c099de627a79eb..6a8b59c81cce09cd03587168227b60d950f07011 100644
--- a/indra/llprimitive/llprimitive.h
+++ b/indra/llprimitive/llprimitive.h
@@ -289,6 +289,34 @@ class LLLightImageParams : public LLNetworkData
 };
 
 
+// This code is not naming-standards compliant. Leaving it like this for
+// now to make the connection to code in
+// 	BOOL packTEMessage(LLDataPacker &dp) const;
+// more obvious. This should be refactored to remove the duplication, at which
+// point we can fix the names as well.
+// - Vir
+struct LLTEContents
+{
+	static const U32 MAX_TES = 32;
+
+	U8     image_data[MAX_TES*16];
+	U8	  colors[MAX_TES*4];
+	F32    scale_s[MAX_TES];
+	F32    scale_t[MAX_TES];
+	S16    offset_s[MAX_TES];
+	S16    offset_t[MAX_TES];
+	S16    image_rot[MAX_TES];
+	U8	   bump[MAX_TES];
+	U8	   media_flags[MAX_TES];
+    U8     glow[MAX_TES];
+	
+	static const U32 MAX_TE_BUFFER = 4096;
+	U8 packed_buffer[MAX_TE_BUFFER];
+
+	U32 size;
+	U32 face_count;
+};
+
 class LLPrimitive : public LLXform
 {
 public:
@@ -360,9 +388,10 @@ class LLPrimitive : public LLXform
 	S32 unpackTEField(U8 *cur_ptr, U8 *buffer_end, U8 *data_ptr, U8 data_size, U8 face_count, EMsgVariableType type);
 	BOOL packTEMessage(LLMessageSystem *mesgsys) const;
 	BOOL packTEMessage(LLDataPacker &dp) const;
-	S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name);
 	S32 unpackTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num); // Variable num of blocks
 	BOOL unpackTEMessage(LLDataPacker &dp);
+	S32 parseTEMessage(LLMessageSystem* mesgsys, char const* block_name, const S32 block_num, LLTEContents& tec);
+	S32 applyParsedTEMessage(LLTEContents& tec);
 	
 #ifdef CHECK_FOR_FINITE
 	inline void setPosition(const LLVector3& pos);
diff --git a/indra/llrender/CMakeLists.txt b/indra/llrender/CMakeLists.txt
index 516af933165621055fac01849732f0ad7114167c..669b70aa433a25bc131b9d78f1d2573aed4cd6ee 100644
--- a/indra/llrender/CMakeLists.txt
+++ b/indra/llrender/CMakeLists.txt
@@ -3,7 +3,7 @@
 project(llrender)
 
 include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
 include(FreeType)
 include(LLCommon)
 include(LLImage)
@@ -25,21 +25,31 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llrender_SOURCE_FILES
     llcubemap.cpp
+    llfontbitmapcache.cpp
     llfontfreetype.cpp
     llfontgl.cpp
-    llfontbitmapcache.cpp
     llfontregistry.cpp
+    llgl.cpp
     llgldbg.cpp
     llglslshader.cpp
+    llgltexture.cpp
     llimagegl.cpp
     llpostprocess.cpp
+    llrender.cpp
+    llrender2dutils.cpp
     llrendernavprim.cpp
     llrendersphere.cpp
+    llrendertarget.cpp
     llshadermgr.cpp
     lltexture.cpp
+    lluiimage.cpp
     llvertexbuffer.cpp
     )
     
@@ -56,14 +66,17 @@ set(llrender_HEADER_FILES
     llglheaders.h
     llglslshader.h
     llglstates.h
+    llgltexture.h
     llgltypes.h
     llimagegl.h
     llpostprocess.h
     llrender.h
+    llrender2dutils.h
     llrendernavprim.h
     llrendersphere.h
     llshadermgr.h
     lltexture.h
+    lluiimage.h
     llvertexbuffer.h
     )
 
@@ -72,33 +85,47 @@ set_source_files_properties(${llrender_HEADER_FILES}
 
 list(APPEND llrender_SOURCE_FILES ${llrender_HEADER_FILES})
 
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  copy_server_sources(
-      llgl
-      llrender
-      )
-
-
-  set_source_files_properties(
-    ${server_SOURCE_FILES}
-    PROPERTIES
-    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
-    )
+if (BUILD_HEADLESS)
   add_library (llrenderheadless
     ${llrender_SOURCE_FILES}
-    ${server_SOURCE_FILES}
     )
-else (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  list(APPEND llrender_SOURCE_FILES
-      llgl.cpp
-      llrender.cpp
-      llrendertarget.cpp
-      )
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+
+  set_property(TARGET llrenderheadless
+    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
+    )
+
+  target_link_libraries(llrenderheadless
+    ${LLCOMMON_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLRENDER_HEADLESS_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLWINDOW_HEADLESS_LIBRARIES}
+    ${OPENGL_HEADLESS_LIBRARIES})
+
+endif (BUILD_HEADLESS)
+
 add_library (llrender ${llrender_SOURCE_FILES})
+
+if (SDL_FOUND)
+  set_property(TARGET llrender
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+    )
+endif (SDL_FOUND)
+
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
 target_link_libraries(llrender 
-    llimage 
+    ${LLCOMMON_LIBRARIES}
+    ${LLIMAGE_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLRENDER_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLXML_LIBRARIES}
+    ${LLVFS_LIBRARIES}
+    ${LLWINDOW_LIBRARIES}
     ${FREETYPE_LIBRARIES}
     ${OPENGL_LIBRARIES})
+
diff --git a/indra/llrender/llfontfreetype.cpp b/indra/llrender/llfontfreetype.cpp
index 66d4ad2d87dc57013039f769abd67a4cf1bbafeb..058bef43a566079881309508da4a20244ff874b0 100644
--- a/indra/llrender/llfontfreetype.cpp
+++ b/indra/llrender/llfontfreetype.cpp
@@ -485,14 +485,11 @@ void LLFontFreetype::renderGlyph(U32 glyph_index) const
 	if (mFTFace == NULL)
 		return;
 
-	int error = FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT );
-	llassert(!error);
+	llassert_always(! FT_Load_Glyph(mFTFace, glyph_index, FT_LOAD_FORCE_AUTOHINT) );
 
-	error = FT_Render_Glyph(mFTFace->glyph, gFontRenderMode);
+	llassert_always(! FT_Render_Glyph(mFTFace->glyph, gFontRenderMode) );
 
 	mRenderGlyphCount++;
-	
-	llassert(!error);
 }
 
 void LLFontFreetype::reset(F32 vert_dpi, F32 horz_dpi)
diff --git a/indra/llrender/llfontgl.cpp b/indra/llrender/llfontgl.cpp
index 647512eb2edff26b935ea737bdf98ef86cfddd10..c4f36cabd049bf615a59b929723e66ab21280010 100644
--- a/indra/llrender/llfontgl.cpp
+++ b/indra/llrender/llfontgl.cpp
@@ -541,7 +541,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 	
 	BOOL clip = FALSE;
 	F32 cur_x = 0;
-	F32 drawn_x = 0;
 
 	S32 start_of_last_word = 0;
 	BOOL in_word = FALSE;
@@ -599,6 +598,11 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 		if(!fgi)
 		{
 			fgi = mFontFreetype->getGlyphInfo(wch);
+
+			if (NULL == fgi)
+			{
+				return 0;
+			}
 		}
 
 		// account for glyphs that run beyond the starting point for the next glyphs
@@ -624,7 +628,6 @@ S32 LLFontGL::maxDrawableChars(const llwchar* wchars, F32 max_pixels, S32 max_ch
 
 		// Round after kerning.
 		cur_x = (F32)llround(cur_x);
-		drawn_x = cur_x;
 	}
 
 	if( clip )
diff --git a/indra/llrender/llfontregistry.cpp b/indra/llrender/llfontregistry.cpp
index b5bdba996ffeb4ea2a558c3574a5fe99cfd528f4..f5ca8d5b04c82b7848b5bac7c828dad7bf2523b4 100644
--- a/indra/llrender/llfontregistry.cpp
+++ b/indra/llrender/llfontregistry.cpp
@@ -223,7 +223,7 @@ std::string currentOsName()
 	return "Windows";
 #elif LL_DARWIN
 	return "Mac";
-#elif LL_SDL
+#elif LL_SDL || LL_MESA_HEADLESS
 	return "Linux";
 #else
 	return "";
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 9e4857b6bca5b864e1f3a060df7d6148dde09e6f..c8a8e9fcf7c052ffd854ee5dbe7e5df132370731 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -597,11 +597,6 @@ bool LLGLManager::initGL()
 	if (mGLVendor.substr(0,4) == "ATI ")
 	{
 		mGLVendorShort = "ATI";
-		BOOL mobile = FALSE;
-		if (mGLRenderer.find("MOBILITY") != std::string::npos)
-		{
-			mobile = TRUE;
-		}
 		mIsATI = TRUE;
 
 #if LL_WINDOWS && !LL_MESA_HEADLESS
@@ -1489,9 +1484,8 @@ void assert_glerror()
 
 void clear_glerror()
 {
-	//  Create or update texture to be used with this data 
-	GLenum error;
-	error = glGetError();
+	glGetError();
+	glGetError();
 }
 
 ///////////////////////////////////////////////////////////////
diff --git a/indra/llrender/llglslshader.h b/indra/llrender/llglslshader.h
index 5c68cb46eb3b79a9811bc16a9cb146af902a6dc5..cf21101e35a2b064d9d121e826589b7f2a4435c9 100644
--- a/indra/llrender/llglslshader.h
+++ b/indra/llrender/llglslshader.h
@@ -159,6 +159,8 @@ class LLGLSLShader
 extern LLGLSLShader			gUIProgram;
 //output vec4(color.rgb,color.a*tex0[tc0].a)
 extern LLGLSLShader			gSolidColorProgram;
+//Alpha mask shader (declared here so llappearance can access properly)
+extern LLGLSLShader			gAlphaMaskProgram;
 
 
 #endif
diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d06ed5e57bf4229bf1e6e4d4bf8a2e7d66915336
--- /dev/null
+++ b/indra/llrender/llgltexture.cpp
@@ -0,0 +1,396 @@
+/** 
+ * @file llgltexture.cpp
+ * @brief Opengl texture implementation
+ *
+ * $LicenseInfo:firstyear=2000&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#include "linden_common.h"
+#include "llgltexture.h"
+
+
+// static
+S32 LLGLTexture::getTotalNumOfCategories() 
+{
+	return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
+}
+
+// static
+//index starts from zero.
+S32 LLGLTexture::getIndexFromCategory(S32 category) 
+{
+	return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
+}
+
+//static 
+S32 LLGLTexture::getCategoryFromIndex(S32 index)
+{
+	return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
+}
+
+LLGLTexture::LLGLTexture(BOOL usemipmaps)
+{
+	init();
+	mUseMipMaps = usemipmaps;
+}
+
+LLGLTexture::LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)
+{
+	init();
+	mFullWidth = width ;
+	mFullHeight = height ;
+	mUseMipMaps = usemipmaps;
+	mComponents = components ;
+	setTexelsPerImage();
+}
+
+LLGLTexture::LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps)
+{
+	init();
+	mUseMipMaps = usemipmaps ;
+	// Create an empty image of the specified size and width
+	mGLTexturep = new LLImageGL(raw, usemipmaps) ;
+}
+
+LLGLTexture::~LLGLTexture()
+{
+	cleanup();
+}
+
+void LLGLTexture::init()
+{
+	mBoostLevel = LLGLTexture::BOOST_NONE;
+
+	mFullWidth = 0;
+	mFullHeight = 0;
+	mTexelsPerImage = 0 ;
+	mUseMipMaps = FALSE ;
+	mComponents = 0 ;
+
+	mTextureState = NO_DELETE ;
+	mDontDiscard = FALSE;
+	mNeedsGLTexture = FALSE ;
+}
+
+void LLGLTexture::cleanup()
+{
+	if(mGLTexturep)
+	{
+		mGLTexturep->cleanup();
+	}
+}
+
+// virtual
+void LLGLTexture::dump()
+{
+	if(mGLTexturep)
+	{
+		mGLTexturep->dump();
+	}
+}
+
+void LLGLTexture::setBoostLevel(S32 level)
+{
+	if(mBoostLevel != level)
+	{
+		mBoostLevel = level ;
+		if(mBoostLevel != LLGLTexture::BOOST_NONE)
+		{
+			setNoDelete() ;		
+		}
+	}
+}
+
+void LLGLTexture::forceActive()
+{
+	mTextureState = ACTIVE ; 
+}
+
+void LLGLTexture::setActive() 
+{ 
+	if(mTextureState != NO_DELETE)
+	{
+		mTextureState = ACTIVE ; 
+	}
+}
+
+//set the texture to stay in memory
+void LLGLTexture::setNoDelete() 
+{ 
+	mTextureState = NO_DELETE ;
+}
+
+void LLGLTexture::generateGLTexture() 
+{	
+	if(mGLTexturep.isNull())
+	{
+		mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
+	}
+}
+
+LLImageGL* LLGLTexture::getGLTexture() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep ;
+}
+
+BOOL LLGLTexture::createGLTexture() 
+{
+	if(mGLTexturep.isNull())
+	{
+		generateGLTexture() ;
+	}
+
+	return mGLTexturep->createGLTexture() ;
+}
+
+BOOL LLGLTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
+{
+	llassert(mGLTexturep.notNull()) ;	
+
+	BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
+
+	if(ret)
+	{
+		mFullWidth = mGLTexturep->getCurrentWidth() ;
+		mFullHeight = mGLTexturep->getCurrentHeight() ; 
+		mComponents = mGLTexturep->getComponents() ;	
+		setTexelsPerImage();
+	}
+
+	return ret ;
+}
+
+void LLGLTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
+{
+	llassert(mGLTexturep.notNull()) ;
+	
+	mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
+}
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
+{
+	llassert(mGLTexturep.notNull()) ;
+	mGLTexturep->setAddressMode(mode) ;
+}
+void LLGLTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
+{
+	llassert(mGLTexturep.notNull()) ;
+	mGLTexturep->setFilteringOption(option) ;
+}
+
+//virtual
+S32	LLGLTexture::getWidth(S32 discard_level) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getWidth(discard_level) ;
+}
+
+//virtual
+S32	LLGLTexture::getHeight(S32 discard_level) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getHeight(discard_level) ;
+}
+
+S32 LLGLTexture::getMaxDiscardLevel() const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getMaxDiscardLevel() ;
+}
+S32 LLGLTexture::getDiscardLevel() const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getDiscardLevel() ;
+}
+S8  LLGLTexture::getComponents() const 
+{ 
+	llassert(mGLTexturep.notNull()) ;
+	
+	return mGLTexturep->getComponents() ;
+}
+
+LLGLuint LLGLTexture::getTexName() const 
+{ 
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexName() ; 
+}
+
+BOOL LLGLTexture::hasGLTexture() const 
+{
+	if(mGLTexturep.notNull())
+	{
+		return mGLTexturep->getHasGLTexture() ;
+	}
+	return FALSE ;
+}
+
+BOOL LLGLTexture::getBoundRecently() const
+{
+	if(mGLTexturep.notNull())
+	{
+		return mGLTexturep->getBoundRecently() ;
+	}
+	return FALSE ;
+}
+
+LLTexUnit::eTextureType LLGLTexture::getTarget(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+	return mGLTexturep->getTarget() ;
+}
+
+BOOL LLGLTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
+}
+
+BOOL LLGLTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
+}
+
+void LLGLTexture::setGLTextureCreated (bool initialized)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	mGLTexturep->setGLTextureCreated (initialized) ;
+}
+
+void  LLGLTexture::setCategory(S32 category) 
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	mGLTexturep->setCategory(category) ;
+}
+
+LLTexUnit::eTextureAddressMode LLGLTexture::getAddressMode(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getAddressMode() ;
+}
+
+S32 LLGLTexture::getTextureMemory() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->mTextureMemory ;
+}
+
+LLGLenum LLGLTexture::getPrimaryFormat() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getPrimaryFormat() ;
+}
+
+BOOL LLGLTexture::getIsAlphaMask() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getIsAlphaMask() ;
+}
+
+BOOL LLGLTexture::getMask(const LLVector2 &tc)
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getMask(tc) ;
+}
+
+F32 LLGLTexture::getTimePassedSinceLastBound()
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTimePassedSinceLastBound() ;
+}
+BOOL LLGLTexture::getMissed() const 
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getMissed() ;
+}
+
+BOOL LLGLTexture::isJustBound() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->isJustBound() ;
+}
+
+void LLGLTexture::forceUpdateBindStats(void) const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->forceUpdateBindStats() ;
+}
+
+U32 LLGLTexture::getTexelsInAtlas() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexelsInAtlas() ;
+}
+
+U32 LLGLTexture::getTexelsInGLTexture() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getTexelsInGLTexture() ;
+}
+
+BOOL LLGLTexture::isGLTextureCreated() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->isGLTextureCreated() ;
+}
+
+S32  LLGLTexture::getDiscardLevelInAtlas() const
+{
+	llassert(mGLTexturep.notNull()) ;
+
+	return mGLTexturep->getDiscardLevelInAtlas() ;
+}
+
+void LLGLTexture::destroyGLTexture() 
+{
+	if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
+	{
+		mGLTexturep->destroyGLTexture() ;
+		mTextureState = DELETED ;
+	}
+}
+
+void LLGLTexture::setTexelsPerImage()
+{
+	S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
+	mTexelsPerImage = (F32)fullwidth * fullheight;
+}
+
+
diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h
new file mode 100644
index 0000000000000000000000000000000000000000..e69b322d6059aa5a047f7e6b59184f6215c5327c
--- /dev/null
+++ b/indra/llrender/llgltexture.h
@@ -0,0 +1,199 @@
+/** 
+ * @file llglviewertexture.h
+ * @brief Object for managing opengl textures
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#ifndef LL_GL_TEXTURE_H
+#define LL_GL_TEXTURE_H
+
+#include "lltexture.h"
+#include "llgl.h"
+
+class LLImageRaw;
+
+//
+//this the parent for the class LLViewerTexture
+//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//
+class LLGLTexture : public LLTexture
+{
+public:
+	enum
+	{
+		MAX_IMAGE_SIZE_DEFAULT = 1024,
+		INVALID_DISCARD_LEVEL = 0x7fff
+	};
+
+	enum EBoostLevel
+	{
+		BOOST_NONE 			= 0,
+		BOOST_AVATAR_BAKED	,
+		BOOST_AVATAR		,
+		BOOST_CLOUDS		,
+		BOOST_SCULPTED      ,
+		
+		BOOST_HIGH 			= 10,
+		BOOST_BUMP          ,
+		BOOST_TERRAIN		, // has to be high priority for minimap / low detail
+		BOOST_SELECTED		,		
+		BOOST_AVATAR_BAKED_SELF	,
+		BOOST_AVATAR_SELF	, // needed for baking avatar
+		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
+		BOOST_HUD			,
+		BOOST_ICON			,
+		BOOST_UI			,
+		BOOST_PREVIEW		,
+		BOOST_MAP			,
+		BOOST_MAP_VISIBLE	,		
+		BOOST_MAX_LEVEL,
+
+		//other texture Categories
+		LOCAL = BOOST_MAX_LEVEL,
+		AVATAR_SCRATCH_TEX,
+		DYNAMIC_TEX,
+		MEDIA,
+		ATLAS,
+		OTHER,
+		MAX_GL_IMAGE_CATEGORY
+	};
+
+	typedef enum 
+	{
+		DELETED = 0,         //removed from memory
+		DELETION_CANDIDATE,  //ready to be removed from memory
+		INACTIVE,            //not be used for the last certain period (i.e., 30 seconds).
+		ACTIVE,              //just being used, can become inactive if not being used for a certain time (10 seconds).
+		NO_DELETE = 99       //stay in memory, can not be removed.
+	} LLGLTextureState;
+
+	static S32 getTotalNumOfCategories() ;
+	static S32 getIndexFromCategory(S32 category) ;
+	static S32 getCategoryFromIndex(S32 index) ;
+
+protected:
+	virtual ~LLGLTexture();
+	LOG_CLASS(LLGLTexture);
+
+public:
+	LLGLTexture(BOOL usemipmaps = TRUE);
+	LLGLTexture(const LLImageRaw* raw, BOOL usemipmaps) ;
+	LLGLTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) ;
+
+	virtual void dump();	// debug info to llinfos
+
+	virtual const LLUUID& getID() const = 0;
+
+	void setBoostLevel(S32 level);
+	S32  getBoostLevel() { return mBoostLevel; }
+
+	S32 getFullWidth() const { return mFullWidth; }
+	S32 getFullHeight() const { return mFullHeight; }	
+
+	void generateGLTexture() ;
+	void destroyGLTexture() ;
+
+	//---------------------------------------------------------------------------------------------
+	//functions to access LLImageGL
+	//---------------------------------------------------------------------------------------------
+	/*virtual*/S32	       getWidth(S32 discard_level = -1) const;
+	/*virtual*/S32	       getHeight(S32 discard_level = -1) const;
+
+	BOOL       hasGLTexture() const ;
+	LLGLuint   getTexName() const ;		
+	BOOL       createGLTexture() ;
+	BOOL       createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLGLTexture::OTHER);
+
+	void       setFilteringOption(LLTexUnit::eTextureFilterOptions option);
+	void       setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
+	void       setAddressMode(LLTexUnit::eTextureAddressMode mode);
+	BOOL       setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
+	BOOL       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
+	void       setGLTextureCreated (bool initialized);
+	void       setCategory(S32 category) ;
+
+	LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
+	S32        getMaxDiscardLevel() const;
+	S32        getDiscardLevel() const;
+	S8         getComponents() const;
+	BOOL       getBoundRecently() const;
+	S32        getTextureMemory() const ;
+	LLGLenum   getPrimaryFormat() const;
+	BOOL       getIsAlphaMask() const ;
+	LLTexUnit::eTextureType getTarget(void) const ;
+	BOOL       getMask(const LLVector2 &tc);
+	F32        getTimePassedSinceLastBound();
+	BOOL       getMissed() const ;
+	BOOL       isJustBound()const ;
+	void       forceUpdateBindStats(void) const;
+
+	U32        getTexelsInAtlas() const ;
+	U32        getTexelsInGLTexture() const ;
+	BOOL       isGLTextureCreated() const ;
+	S32        getDiscardLevelInAtlas() const ;
+	LLGLTextureState getTextureState() const { return mTextureState; }
+	
+	//---------------------------------------------------------------------------------------------
+	//end of functions to access LLImageGL
+	//---------------------------------------------------------------------------------------------
+
+	//-----------------
+	/*virtual*/ void setActive() ;
+	void forceActive() ;
+	void setNoDelete() ;
+	void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
+	BOOL getDontDiscard() const { return mDontDiscard; }
+	//-----------------	
+
+private:
+	void cleanup();
+	void init();
+
+protected:
+	void setTexelsPerImage();
+
+	//note: do not make this function public.
+	/*virtual*/ LLImageGL* getGLTexture() const ;
+
+protected:
+	S32 mBoostLevel;				// enum describing priority level
+	S32 mFullWidth;
+	S32 mFullHeight;
+	BOOL mUseMipMaps;
+	S8  mComponents;
+	F32 mTexelsPerImage;			// Texels per image.
+	mutable S8  mNeedsGLTexture;
+
+	//GL texture
+	LLPointer<LLImageGL> mGLTexturep ;
+	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc)
+
+protected:
+	LLGLTextureState  mTextureState ;
+
+
+};
+
+#endif // LL_GL_TEXTURE_H
+
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index a4d7872ec25e0091152a4da7de8e60f2df09e5ed..249b8da880e2b79e9ccc078de7f89a81c61cc986 100644
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -74,6 +74,9 @@ S32 LLImageGL::sCurTexSizeBar = -1 ;
 S32 LLImageGL::sCurTexPickSize = -1 ;
 S32 LLImageGL::sMaxCategories = 1 ;
 
+//optimization for when we don't need to calculate mIsMask
+BOOL LLImageGL::sSkipAnalyzeAlpha;
+
 //------------------------
 //****************************************************************************************************
 //End for texture auditing use only
@@ -169,8 +172,9 @@ BOOL is_little_endian()
 	return (*c == 0x78) ;
 }
 //static 
-void LLImageGL::initClass(S32 num_catagories) 
+void LLImageGL::initClass(S32 num_catagories, BOOL skip_analyze_alpha /* = false */)
 {
+	sSkipAnalyzeAlpha = skip_analyze_alpha;
 }
 
 //static 
@@ -611,14 +615,16 @@ void LLImageGL::setImage(const LLImageRaw* imageraw)
 	setImage(rawdata, FALSE);
 }
 
+static LLFastTimer::DeclareTimer FTM_SET_IMAGE("setImage");
 void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 {
+	LLFastTimer t(FTM_SET_IMAGE);
 	bool is_compressed = false;
 	if (mFormatPrimary >= GL_COMPRESSED_RGBA_S3TC_DXT1_EXT && mFormatPrimary <= GL_COMPRESSED_RGBA_S3TC_DXT5_EXT)
 	{
 		is_compressed = true;
 	}
-
+	
 	
 	
 	if (mUseMipMaps)
@@ -738,8 +744,9 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 				S32 w = width, h = height;
 				const U8* prev_mip_data = 0;
 				const U8* cur_mip_data = 0;
-				S32 prev_mip_size = 0;
+#ifdef SHOW_ASSERT
 				S32 cur_mip_size = 0;
+#endif
 				
 				mMipLevels = nummips;
 
@@ -748,18 +755,24 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 					if (m==0)
 					{
 						cur_mip_data = data_in;
+#ifdef SHOW_ASSERT
 						cur_mip_size = width * height * mComponents; 
+#endif
 					}
 					else
 					{
 						S32 bytes = w * h * mComponents;
+#ifdef SHOW_ASSERT
 						llassert(prev_mip_data);
-						llassert(prev_mip_size == bytes*4);
+						llassert(cur_mip_size == bytes*4);
+#endif
 						U8* new_data = new U8[bytes];
 						llassert_always(new_data);
 						LLImageBase::generateMip(prev_mip_data, new_data, w, h, mComponents);
 						cur_mip_data = new_data;
+#ifdef SHOW_ASSERT
 						cur_mip_size = bytes; 
+#endif
 					}
 					llassert(w > 0 && h > 0 && cur_mip_data);
 					{
@@ -792,7 +805,6 @@ void LLImageGL::setImage(const U8* data_in, BOOL data_hasmips)
 						delete[] prev_mip_data;
 					}
 					prev_mip_data = cur_mip_data;
-					prev_mip_size = cur_mip_size;
 					w >>= 1;
 					h >>= 1;
 				}
@@ -1053,8 +1065,10 @@ BOOL LLImageGL::setSubImageFromFrameBuffer(S32 fb_x, S32 fb_y, S32 x_pos, S32 y_
 }
 
 // static
+static LLFastTimer::DeclareTimer FTM_GENERATE_TEXTURES("generate textures");
 void LLImageGL::generateTextures(LLTexUnit::eTextureType type, U32 format, S32 numTextures, U32 *textures)
 {
+	LLFastTimer t(FTM_GENERATE_TEXTURES);
 	bool empty = true;
 
 	dead_texturelist_t::iterator iter = sDeadTextureList[type].find(format);
@@ -1115,8 +1129,10 @@ void LLImageGL::deleteTextures(LLTexUnit::eTextureType type, U32 format, S32 mip
 }
 
 // static
+static LLFastTimer::DeclareTimer FTM_SET_MANUAL_IMAGE("setManualImage");
 void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 width, S32 height, U32 pixformat, U32 pixtype, const void *pixels, bool allow_compression)
 {
+	LLFastTimer t(FTM_SET_MANUAL_IMAGE);
 	bool use_scratch = false;
 	U32* scratch = NULL;
 	if (LLRender::sGLCoreProfile)
@@ -1220,9 +1236,10 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 
 //create an empty GL texture: just create a texture name
 //the texture is assiciate with some image by calling glTexImage outside LLImageGL
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE1("createGLTexture()");
 BOOL LLImageGL::createGLTexture()
 {
-	if (gHeadlessClient) return FALSE;
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE1);
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1250,9 +1267,10 @@ BOOL LLImageGL::createGLTexture()
 	return TRUE ;
 }
 
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE2("createGLTexture(raw)");
 BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
 {
-	if (gHeadlessClient) return FALSE;
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE2);
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1324,8 +1342,10 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S
 	return createGLTexture(discard_level, rawdata, FALSE, usename);
 }
 
+static LLFastTimer::DeclareTimer FTM_CREATE_GL_TEXTURE3("createGLTexture3(data)");
 BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_hasmips, S32 usename)
 {
+	LLFastTimer t(FTM_CREATE_GL_TEXTURE3);
 	llassert(data_in);
 	stop_glerror();
 
@@ -1702,6 +1722,12 @@ BOOL LLImageGL::getBoundRecently() const
 	return (BOOL)(sLastFrameTime - mLastBindTime < MIN_TEXTURE_LIFETIME);
 }
 
+BOOL LLImageGL::getIsAlphaMask() const
+{
+	llassert_always(!sSkipAnalyzeAlpha);
+	return mIsMask;
+}
+
 void LLImageGL::setTarget(const LLGLenum target, const LLTexUnit::eTextureType bind_target)
 {
 	mTarget = target;
@@ -1799,7 +1825,7 @@ void LLImageGL::calcAlphaChannelOffsetAndStride()
 
 void LLImageGL::analyzeAlpha(const void* data_in, U32 w, U32 h)
 {
-	if(!mNeedsAlphaAndPickMask)
+	if(sSkipAnalyzeAlpha || !mNeedsAlphaAndPickMask)
 	{
 		return ;
 	}
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index cf3c484c79df58a4bbeb17e2b84dd2ffab4a7e4d..57a052b25888ae370519dd4cf638cb8e6697f273 100644
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -142,7 +142,7 @@ class LLImageGL : public LLRefCount
 	BOOL getHasGLTexture() const { return mTexName != 0; }
 	LLGLuint getTexName() const { return mTexName; }
 
-	BOOL getIsAlphaMask() const { return mIsMask; }
+	BOOL getIsAlphaMask() const;
 
 	BOOL getIsResident(BOOL test_now = FALSE); // not const
 
@@ -262,11 +262,12 @@ class LLImageGL : public LLRefCount
 #endif
 
 public:
-	static void initClass(S32 num_catagories) ;
+	static void initClass(S32 num_catagories, BOOL skip_analyze_alpha = false); 
 	static void cleanupClass() ;
 
 private:
 	static S32 sMaxCategories;
+	static BOOL sSkipAnalyzeAlpha;
 	
 	//the flag to allow to call readBackRaw(...).
 	//can be removed if we do not use that function at all.
diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp
index 4597d0626065b40af486b541f45390dd4090f62c..c60eb8d9d9169271dad585f042c302e52f65e970 100644
--- a/indra/llrender/llrender.cpp
+++ b/indra/llrender/llrender.cpp
@@ -357,7 +357,6 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap)
 }
 
 // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
 bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
 {
 	if (mIndex < 0) return false;
@@ -380,7 +379,6 @@ bool LLTexUnit::bind(LLRenderTarget* renderTarget, bool bindDepth)
 
 	return true;
 }
-#endif // LL_MESA_HEADLESS
 
 bool LLTexUnit::bindManual(eTextureType type, U32 texture, bool hasMips)
 {
diff --git a/indra/llrender/llrender2dutils.cpp b/indra/llrender/llrender2dutils.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d3cfbaf03a7bb05046ac2265e36fdf45384c5732
--- /dev/null
+++ b/indra/llrender/llrender2dutils.cpp
@@ -0,0 +1,1608 @@
+/** 
+ * @file llrender2dutils.cpp
+ * @brief GL function implementations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+// Linden library includes
+#include "v2math.h"
+#include "m3math.h"
+#include "v4color.h"
+#include "llfontgl.h"
+#include "llrender.h"
+#include "llrect.h"
+#include "llgl.h"
+#include "lltexture.h"
+
+// Project includes
+#include "llrender2dutils.h"
+#include "lluiimage.h"
+
+
+//
+// Globals
+//
+const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
+/*static*/ LLVector2		LLRender2D::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLImageProviderInterface* LLRender2D::sImageProvider = NULL;
+
+//
+// Functions
+//
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
+{
+	if (x < left || right < x) return FALSE;
+	if (y < bottom || top < y) return FALSE;
+	return TRUE;
+}
+
+
+// Puts GL into 2D drawing mode by turning off lighting, setting to an
+// orthographic projection, etc.
+void gl_state_for_2d(S32 width, S32 height)
+{
+	stop_glerror();
+	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
+	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
+
+	gGL.matrixMode(LLRender::MM_PROJECTION);
+	gGL.loadIdentity();
+	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
+	gGL.matrixMode(LLRender::MM_MODELVIEW);
+	gGL.loadIdentity();
+	stop_glerror();
+}
+
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin( LLRender::LINES );
+		gGL.vertex2i( rect.mLeft,		rect.mTop );
+		gGL.vertex2i( rect.mRight,	rect.mBottom );
+		gGL.vertex2i( rect.mLeft,		rect.mBottom );
+		gGL.vertex2i( rect.mRight,	rect.mTop );
+	gGL.end();
+}
+
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
+{
+	gGL.color4fv(color.mV);
+	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
+}
+
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	left += LLFontGL::sCurOrigin.mX;
+	right += LLFontGL::sCurOrigin.mX;
+	bottom += LLFontGL::sCurOrigin.mY;
+	top += LLFontGL::sCurOrigin.mY;
+
+	gGL.loadUIIdentity();
+	gl_rect_2d(llfloor((F32)left * LLRender2D::sGLScaleFactor.mV[VX]) - pixel_offset,
+				llfloor((F32)top * LLRender2D::sGLScaleFactor.mV[VY]) + pixel_offset,
+				llfloor((F32)right * LLRender2D::sGLScaleFactor.mV[VX]) + pixel_offset,
+				llfloor((F32)bottom * LLRender2D::sGLScaleFactor.mV[VY]) - pixel_offset,
+				filled);
+	gGL.popUIMatrix();
+}
+
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	// Counterclockwise quad will face the viewer
+	if( filled )
+	{ 
+		gGL.begin( LLRender::QUADS );
+			gGL.vertex2i(left, top);
+			gGL.vertex2i(left, bottom);
+			gGL.vertex2i(right, bottom);
+			gGL.vertex2i(right, top);
+		gGL.end();
+	}
+	else
+	{
+		if( gGLManager.mATIOffsetVerticalLines )
+		{
+			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+			gGL.begin( LLRender::LINES );
+
+				// Verticals 
+				gGL.vertex2i(left + 1, top);
+				gGL.vertex2i(left + 1, bottom);
+
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+
+				// Horizontals
+				top--;
+				right--;
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(right, top);
+			gGL.end();
+		}
+		else
+		{
+			top--;
+			right--;
+			gGL.begin( LLRender::LINE_STRIP );
+				gGL.vertex2i(left, top);
+				gGL.vertex2i(left, bottom);
+				gGL.vertex2i(right, bottom);
+				gGL.vertex2i(right, top);
+				gGL.vertex2i(left, top);
+			gGL.end();
+		}
+	}
+	stop_glerror();
+}
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( left, top, right, bottom, filled );
+}
+
+
+void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
+{
+	gGL.color4fv( color.mV );
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+// Given a rectangle on the screen, draws a drop shadow _outside_
+// the right and bottom edges of it.  Along the right it has width "lines"
+// and along the bottom it has height "lines".
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
+{
+	stop_glerror();
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	// HACK: Overlap with the rectangle by a single pixel.
+	right--;
+	bottom++;
+	lines++;
+
+	LLColor4 end_color = start_color;
+	end_color.mV[VALPHA] = 0.f;
+
+	gGL.begin(LLRender::QUADS);
+
+	// Right edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		top-lines);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right+lines, bottom);
+	gGL.vertex2i(right+lines, top-lines);
+
+	// Bottom edge, CCW faces screen
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left+lines,	bottom-lines);
+	gGL.vertex2i(right,		bottom-lines);
+
+	// bottom left Corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(left+lines,	bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(left,		bottom);
+	// make the bottom left corner not sharp
+	gGL.vertex2i(left+1,		bottom-lines+1);
+	gGL.vertex2i(left+lines,	bottom-lines);
+
+	// bottom right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i(right,		bottom);
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i(right,		bottom-lines);
+	// make the rightmost corner not sharp
+	gGL.vertex2i(right+lines-1,	bottom-lines+1);
+	gGL.vertex2i(right+lines,	bottom);
+
+	// top right corner
+	gGL.color4fv(start_color.mV);
+	gGL.vertex2i( right,			top-lines );
+	gGL.color4fv(end_color.mV);
+	gGL.vertex2i( right+lines,	top-lines );
+	// make the corner not sharp
+	gGL.vertex2i( right+lines-1,	top-1 );
+	gGL.vertex2i( right,			top );
+
+	gGL.end();
+	stop_glerror();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
+{
+	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
+	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
+	{
+		x1++;
+		x2++;
+		y1++;
+		y2++;
+	}
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv( color.mV );
+
+	gGL.begin(LLRender::LINES);
+		gGL.vertex2i(x1, y1);
+		gGL.vertex2i(x2, y2);
+	gGL.end();
+}
+
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.color4fv(color.mV);
+
+	if (filled)
+	{
+		gGL.begin(LLRender::TRIANGLES);
+	}
+	else
+	{
+		gGL.begin(LLRender::LINE_LOOP);
+	}
+	gGL.vertex2i(x1, y1);
+	gGL.vertex2i(x2, y2);
+	gGL.vertex2i(x3, y3);
+	gGL.end();
+}
+
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
+{
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	length = llmin((S32)(max_frac*(right - left)), length);
+	length = llmin((S32)(max_frac*(top - bottom)), length);
+	gGL.begin(LLRender::LINES);
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left + length, top);
+	
+	gGL.vertex2i(left, top);
+	gGL.vertex2i(left, top - length);
+
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left + length, bottom);
+	
+	gGL.vertex2i(left, bottom);
+	gGL.vertex2i(left, bottom + length);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right - length, top);
+
+	gGL.vertex2i(right, top);
+	gGL.vertex2i(right, top - length);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right - length, bottom);
+
+	gGL.vertex2i(right, bottom);
+	gGL.vertex2i(right, bottom + length);
+	gGL.end();
+}
+
+
+void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// scale screen size of borders down
+	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
+	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
+
+	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
+	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
+}
+
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
+{
+	stop_glerror();
+
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	// add in offset of current image to current UI translation
+	const LLVector3 ui_scale = gGL.getUIScale();
+	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
+
+	F32 uv_width = uv_outer_rect.getWidth();
+	F32 uv_height = uv_outer_rect.getHeight();
+
+	// shrink scaling region to be proportional to clipped image region
+	LLRectf uv_center_rect(
+		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
+		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
+		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
+
+	F32 image_width = image->getWidth(0);
+	F32 image_height = image->getHeight(0);
+
+	S32 image_natural_width = llround(image_width * uv_width);
+	S32 image_natural_height = llround(image_height * uv_height);
+
+	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
+								uv_center_rect.mTop * image_height,
+								uv_center_rect.mRight * image_width,
+								uv_center_rect.mBottom * image_height);
+
+	{	// scale fixed region of image to drawn region
+		draw_center_rect.mRight += width - image_natural_width;
+		draw_center_rect.mTop += height - image_natural_height;
+
+		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
+		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
+
+		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
+		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
+
+		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
+
+		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
+		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
+		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
+		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
+	}
+
+	LLRectf draw_outer_rect(ui_translation.mV[VX], 
+							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
+							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
+							ui_translation.mV[VY]);
+
+	LLGLSUIDefault gls_ui;
+	
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gSolidColorProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
+			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
+		}
+	}
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+	
+	const S32 NUM_VERTICES = 9 * 4; // 9 quads
+	LLVector2 uv[NUM_VERTICES];
+	LLVector3 pos[NUM_VERTICES];
+
+	S32 index = 0;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw bottom right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		// draw left 
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw right 
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		// draw top left
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top middle
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		// draw top right
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
+		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
+		index++;
+
+		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+	}
+	gGL.end();
+
+	if (solid_color)
+	{
+		if (LLGLSLShader::sNoFixedFunction)
+		{
+			gUIProgram.bind();
+		}
+		else
+		{
+			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
+		}
+	}
+}
+
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
+}
+
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
+{
+	if (NULL == image)
+	{
+		llwarns << "image == NULL; aborting function" << llendl;
+		return;
+	}
+
+	LLGLSUIDefault gls_ui;
+
+
+	gGL.getTexUnit(0)->bind(image, true);
+
+	gGL.color4fv(color.mV);
+
+	if (degrees == 0.f)
+	{
+		const S32 NUM_VERTICES = 4; // 9 quads
+		LLVector2 uv[NUM_VERTICES];
+		LLVector3 pos[NUM_VERTICES];
+
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 ui_scale = gGL.getUIScale();
+			LLVector3 ui_translation = gGL.getUITranslation();
+			ui_translation.mV[VX] += x;
+			ui_translation.mV[VY] += y;
+			ui_translation.scaleVec(ui_scale);
+			S32 index = 0;
+			S32 scaled_width = llround(width * ui_scale.mV[VX]);
+			S32 scaled_height = llround(height * ui_scale.mV[VY]);
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
+			index++;
+
+			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
+			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
+			index++;
+
+			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
+		}
+		gGL.end();
+	}
+	else
+	{
+		gGL.pushUIMatrix();
+		gGL.translateUI((F32)x, (F32)y, 0.f);
+	
+		F32 offset_x = F32(width/2);
+		F32 offset_y = F32(height/2);
+
+		gGL.translateUI(offset_x, offset_y, 0.f);
+
+		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
+		
+		gGL.getTexUnit(0)->bind(image, true);
+
+		gGL.color4fv(color.mV);
+		
+		gGL.begin(LLRender::QUADS);
+		{
+			LLVector3 v;
+
+			v = LLVector3(offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+
+			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
+			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
+			gGL.vertex2f(v.mV[0], v.mV[1] );
+		}
+		gGL.end();
+		gGL.popUIMatrix();
+	}
+}
+
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
+{
+	phase = fmod(phase, 1.f);
+
+	S32 shift = S32(phase * 4.f) % 4;
+
+	// Stippled line
+	LLGLEnable stipple(GL_LINE_STIPPLE);
+	
+	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
+
+	gGL.flush();
+	glLineWidth(2.5f);
+
+	if (!LLGLSLShader::sNoFixedFunction)
+	{
+		glLineStipple(2, 0x3333 << shift);
+	}
+
+	gGL.begin(LLRender::LINES);
+	{
+		gGL.vertex3fv( start.mV );
+		gGL.vertex3fv( end.mV );
+	}
+	gGL.end();
+
+	LLRender2D::setLineWidth(1.f);
+}
+
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
+{
+	if (end_angle < start_angle)
+	{
+		end_angle += F_TWO_PI;
+	}
+
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = (end_angle - start_angle) / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = cosf(start_angle) * radius;
+		F32 y = sinf(start_angle) * radius;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_STRIP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		gGL.translateUI(center_x, center_y, 0.f);
+
+		// Inexact, but reasonably fast.
+		F32 delta = F_TWO_PI / steps;
+		F32 sin_delta = sin( delta );
+		F32 cos_delta = cos( delta );
+		F32 x = radius;
+		F32 y = 0.f;
+
+		if (filled)
+		{
+			gGL.begin(LLRender::TRIANGLE_FAN);
+			gGL.vertex2f(0.f, 0.f);
+			// make sure circle is complete
+			steps += 1;
+		}
+		else
+		{
+			gGL.begin(LLRender::LINE_LOOP);
+		}
+
+		while( steps-- )
+		{
+			// Successive rotations
+			gGL.vertex2f( x, y );
+			F32 x_new = x * cos_delta - y * sin_delta;
+			y = x * sin_delta +  y * cos_delta;
+			x = x_new;
+		}
+		gGL.end();
+	}
+	gGL.popUIMatrix();
+}
+
+// Renders a ring with sides (tube shape)
+void gl_deep_circle( F32 radius, F32 depth, S32 steps )
+{
+	F32 x = radius;
+	F32 y = 0.f;
+	F32 angle_delta = F_TWO_PI / (F32)steps;
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		S32 step = steps + 1; // An extra step to close the circle.
+		while( step-- )
+		{
+			gGL.vertex3f( x, y, depth );
+			gGL.vertex3f( x, y, 0.f );
+
+			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
+			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
+			x = x_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
+{
+	gGL.pushUIMatrix();
+	{
+		gGL.translateUI(0.f, 0.f, -width / 2);
+		if( render_center )
+		{
+			gGL.color4fv(center_color.mV);
+			gGL.diffuseColor4fv(center_color.mV);
+			gl_deep_circle( radius, width, steps );
+		}
+		else
+		{
+			gGL.diffuseColor4fv(side_color.mV);
+			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
+			gGL.translateUI(0.f, 0.f, width);
+			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
+		}
+	}
+	gGL.popUIMatrix();
+}
+
+// Draw gray and white checkerboard with black border
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
+{
+	if (!LLGLSLShader::sNoFixedFunction)
+	{ 
+	// Initialize the first time this is called.
+	const S32 PIXELS = 32;
+	static GLubyte checkerboard[PIXELS * PIXELS];
+	static BOOL first = TRUE;
+	if( first )
+	{
+		for( S32 i = 0; i < PIXELS; i++ )
+		{
+			for( S32 j = 0; j < PIXELS; j++ )
+			{
+				checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
+			}
+		}
+		first = FALSE;
+	}
+	
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	// ...white squares
+	gGL.color4f( 1.f, 1.f, 1.f, alpha );
+	gl_rect_2d(rect);
+
+	// ...gray squares
+	gGL.color4f( .7f, .7f, .7f, alpha );
+	gGL.flush();
+
+		glPolygonStipple( checkerboard );
+
+		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
+		gl_rect_2d(rect);
+	}
+	else
+	{ //polygon stipple is deprecated, use "Checker" texture
+		LLPointer<LLUIImage> img = LLRender2D::getUIImage("Checker");
+		gGL.getTexUnit(0)->bind(img->getImage());
+		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
+		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
+
+		LLColor4 color(1.f, 1.f, 1.f, alpha);
+		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
+
+		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
+			img->getImage(), color, uv_rect);
+	}
+	
+	gGL.flush();
+}
+
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = F_TWO_PI / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius;
+	F32 y1 = 0.f;
+	F32 x2 = inner_radius;
+	F32 y2 = 0.f;
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+// Draws the area between two concentric circles, like
+// a doughnut or washer.
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+{
+	const F32 DELTA = (end_radians - start_radians) / steps;
+	const F32 SIN_DELTA = sin( DELTA );
+	const F32 COS_DELTA = cos( DELTA );
+
+	F32 x1 = outer_radius * cos( start_radians );
+	F32 y1 = outer_radius * sin( start_radians );
+	F32 x2 = inner_radius * cos( start_radians );
+	F32 y2 = inner_radius * sin( start_radians );
+
+	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	{
+		steps += 1; // An extra step to close the circle.
+		while( steps-- )
+		{
+			gGL.color4fv(outer_color.mV);
+			gGL.vertex2f( x1, y1 );
+			gGL.color4fv(inner_color.mV);
+			gGL.vertex2f( x2, y2 );
+
+			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
+			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
+			x1 = x1_new;
+
+			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
+			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
+			x2 = x2_new;
+		}
+	}
+	gGL.end();
+}
+
+void gl_rect_2d_simple_tex( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2i(width, height);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2i(0, height);
+
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2i(0, 0);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2i(width, 0);
+	
+	gGL.end();
+}
+
+void gl_rect_2d_simple( S32 width, S32 height )
+{
+	gGL.begin( LLRender::QUADS );
+		gGL.vertex2i(width, height);
+		gGL.vertex2i(0, height);
+		gGL.vertex2i(0, 0);
+		gGL.vertex2i(width, 0);
+	gGL.end();
+}
+
+void gl_segmented_rect_2d_tex(const S32 left, 
+							  const S32 top, 
+							  const S32 right, 
+							  const S32 bottom, 
+							  const S32 texture_width, 
+							  const S32 texture_height, 
+							  const S32 border_size, 
+							  const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(0.f, 0.f);
+		gGL.vertex2f(0.f, 0.f);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv(border_width_left.mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+		gGL.vertex2fv((width_vec - border_width_right).mV);
+
+		gGL.texCoord2f(1.f, 0.f);
+		gGL.vertex2fv(width_vec.mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		// draw left 
+		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv(border_height_bottom.mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		// draw middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		// draw right 
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + border_height_bottom).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		// draw top left
+		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		gGL.texCoord2f(0.f, 1.f);
+		gGL.vertex2fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+
+		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((border_width_left + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
+		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
+
+		gGL.texCoord2f(1.f, 1.f);
+		gGL.vertex2fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+//FIXME: rewrite to use scissor?
+void gl_segmented_rect_2d_fragment_tex(const S32 left, 
+									   const S32 top, 
+									   const S32 right, 
+									   const S32 bottom, 
+									   const S32 texture_width, 
+									   const S32 texture_height, 
+									   const S32 border_size, 
+									   const F32 start_fragment, 
+									   const F32 end_fragment, 
+									   const U32 edges)
+{
+	S32 width = llabs(right - left);
+	S32 height = llabs(top - bottom);
+
+	gGL.pushUIMatrix();
+
+	gGL.translateUI((F32)left, (F32)bottom, 0.f);
+	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
+
+	if (border_uv_scale.mV[VX] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
+	}
+	if (border_uv_scale.mV[VY] > 0.5f)
+	{
+		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
+	}
+
+	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
+	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
+	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
+	LLVector2 width_vec((F32)width, 0.f);
+	LLVector2 height_vec(0.f, (F32)height);
+
+	F32 middle_start = border_scale / (F32)width;
+	F32 middle_end = 1.f - middle_start;
+
+	F32 u_min;
+	F32 u_max;
+	LLVector2 x_min;
+	LLVector2 x_max;
+
+	gGL.begin(LLRender::QUADS);
+	{
+		if (start_fragment < middle_start)
+		{
+			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
+			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
+			x_min = (start_fragment / middle_start) * border_width_left;
+			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
+
+			// draw bottom left
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw left 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+			
+			// draw top left
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_start || start_fragment < middle_end)
+		{
+			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
+
+			// draw bottom middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv(x_min.mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
+			gGL.vertex2fv((x_max).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top middle
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+
+		if (end_fragment > middle_end)
+		{
+			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
+			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
+			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
+			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
+
+			// draw bottom right
+			gGL.texCoord2f(u_min, 0.f);
+			gGL.vertex2fv((x_min).mV);
+
+			gGL.texCoord2f(u_max, 0.f);
+			gGL.vertex2fv(x_max.mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			// draw right 
+			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + border_height_bottom).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			// draw top right
+			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
+			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
+
+			gGL.texCoord2f(u_max, 1.f);
+			gGL.vertex2fv((x_max + height_vec).mV);
+
+			gGL.texCoord2f(u_min, 1.f);
+			gGL.vertex2fv((x_min + height_vec).mV);
+		}
+	}
+	gGL.end();
+
+	gGL.popUIMatrix();
+}
+
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, 
+							 const LLVector3& width_vec, const LLVector3& height_vec)
+{
+	gGL.begin(LLRender::QUADS);
+	{
+		// draw bottom left
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3f(0.f, 0.f, 0.f);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+		// draw bottom middle
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		// draw bottom right
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mBottom);
+		gGL.vertex3fv(width_vec.mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		// draw left 
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+		// draw middle
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		// draw right 
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mBottom);
+		gGL.vertex3fv((width_vec + center_draw_rect.mBottom * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		// draw top left
+		gGL.texCoord2f(clip_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((height_vec).mV);
+
+		// draw top middle
+		gGL.texCoord2f(center_uv_rect.mLeft, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mLeft, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mLeft * width_vec + height_vec).mV);
+
+		// draw top right
+		gGL.texCoord2f(center_uv_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, center_uv_rect.mTop);
+		gGL.vertex3fv((width_vec + center_draw_rect.mTop * height_vec).mV);
+
+		gGL.texCoord2f(clip_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((width_vec + height_vec).mV);
+
+		gGL.texCoord2f(center_uv_rect.mRight, clip_rect.mTop);
+		gGL.vertex3fv((center_draw_rect.mRight * width_vec + height_vec).mV);
+	}
+	gGL.end();
+
+}
+
+// static
+void LLRender2D::initClass(LLImageProviderInterface* image_provider,
+						   const LLVector2* scale_factor)
+{
+	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+	sImageProvider = image_provider;
+}
+
+// static
+void LLRender2D::cleanupClass()
+{
+	if(sImageProvider)
+	{
+		sImageProvider->cleanUp();
+	}
+}
+
+
+//static
+void LLRender2D::translate(F32 x, F32 y, F32 z)
+{
+	gGL.translateUI(x,y,z);
+	LLFontGL::sCurOrigin.mX += (S32) x;
+	LLFontGL::sCurOrigin.mY += (S32) y;
+	LLFontGL::sCurDepth += z;
+}
+
+//static
+void LLRender2D::pushMatrix()
+{
+	gGL.pushUIMatrix();
+	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
+}
+
+//static
+void LLRender2D::popMatrix()
+{
+	gGL.popUIMatrix();
+	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
+	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
+	LLFontGL::sOriginStack.pop_back();
+}
+
+//static 
+void LLRender2D::loadIdentity()
+{
+	gGL.loadUIIdentity(); 
+	LLFontGL::sCurOrigin.mX = 0;
+	LLFontGL::sCurOrigin.mY = 0;
+	LLFontGL::sCurDepth = 0.f;
+}
+
+//static
+void LLRender2D::setScaleFactor(const LLVector2 &scale_factor)
+{
+	sGLScaleFactor = scale_factor;
+}
+
+//static
+void LLRender2D::setLineWidth(F32 width)
+{
+	gGL.flush();
+	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
+}
+
+//static
+LLPointer<LLUIImage> LLRender2D::getUIImageByID(const LLUUID& image_id, S32 priority)
+{
+	if (sImageProvider)
+	{
+		return sImageProvider->getUIImageByID(image_id, priority);
+	}
+	else
+	{
+		return NULL;
+	}
+}
+
+//static 
+LLPointer<LLUIImage> LLRender2D::getUIImage(const std::string& name, S32 priority)
+{
+	if (!name.empty() && sImageProvider)
+		return sImageProvider->getUIImage(name, priority);
+	else
+		return NULL;
+}
+
diff --git a/indra/llrender/llrender2dutils.h b/indra/llrender/llrender2dutils.h
new file mode 100644
index 0000000000000000000000000000000000000000..4884422c58057df9baad42e9e01ecaef598df9c9
--- /dev/null
+++ b/indra/llrender/llrender2dutils.h
@@ -0,0 +1,163 @@
+/** 
+ * @file llrender2dutils.h
+ * @brief GL function declarations for immediate-mode gl drawing.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+// All immediate-mode gl drawing should happen here.
+
+
+#ifndef LL_RENDER2DUTILS_H
+#define LL_RENDER2DUTILS_H
+
+#include "llpointer.h"		// LLPointer<>
+#include "llrect.h"
+#include "llglslshader.h"
+
+class LLColor4; 
+class LLVector3;
+class LLVector2;
+class LLUIImage;
+class LLUUID;
+
+extern const LLColor4 UI_VERTEX_COLOR;
+
+BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
+void gl_state_for_2d(S32 width, S32 height);
+
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
+void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
+void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
+void gl_rect_2d_simple( S32 width, S32 height );
+
+void gl_draw_x(const LLRect& rect, const LLColor4& color);
+
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
+void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
+void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
+void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
+
+void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
+
+void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
+void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
+void gl_deep_circle( F32 radius, F32 depth );
+void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
+void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
+void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
+
+void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
+
+void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
+
+void gl_rect_2d_simple_tex( S32 width, S32 height );
+
+// segmented rectangles
+
+/*
+   TL |______TOP_________| TR 
+     /|                  |\  
+   _/_|__________________|_\_
+   L| |    MIDDLE        | |R
+   _|_|__________________|_|_
+    \ |    BOTTOM        | /  
+   BL\|__________________|/ BR
+      |                  |    
+*/
+
+typedef enum e_rounded_edge
+{
+	ROUNDED_RECT_LEFT	= 0x1, 
+	ROUNDED_RECT_TOP	= 0x2, 
+	ROUNDED_RECT_RIGHT	= 0x4, 
+	ROUNDED_RECT_BOTTOM	= 0x8,
+	ROUNDED_RECT_ALL	= 0xf
+}ERoundedEdge;
+
+
+void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
+void gl_segmented_rect_3d_tex(const LLRectf& clip_rect, const LLRectf& center_uv_rect, const LLRectf& center_draw_rect, const LLVector3& width_vec, const LLVector3& height_vec);
+
+inline void gl_rect_2d( const LLRect& rect, BOOL filled )
+{
+	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
+}
+
+inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
+{
+	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
+}
+
+class LLImageProviderInterface;
+
+class LLRender2D
+{
+	LOG_CLASS(LLRender2D);
+public:
+	static void initClass(LLImageProviderInterface* image_provider,
+						  const LLVector2* scale_factor);
+	static void cleanupClass();
+
+	static void pushMatrix();
+	static void popMatrix();
+	static void loadIdentity();
+	static void translate(F32 x, F32 y, F32 z = 0.0f);
+
+	static void setLineWidth(F32 width);
+	static void setScaleFactor(const LLVector2& scale_factor);
+
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+
+	static LLVector2		sGLScaleFactor;
+private:
+	static LLImageProviderInterface* sImageProvider;
+};
+
+class LLImageProviderInterface
+{
+protected:
+	LLImageProviderInterface() {};
+	virtual ~LLImageProviderInterface() {};
+public:
+	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
+	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
+	virtual void cleanUp() = 0;
+};
+
+
+extern LLGLSLShader gSolidColorProgram;
+extern LLGLSLShader gUIProgram;
+
+#endif // LL_RENDER2DUTILS_H
+
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index c1b96a43da4439b5cc47a796174db2e215d9981f..5fb4fc8e520b3b26bf549c62d4e8351c734eb9f4 100644
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -579,3 +579,5 @@ void LLRenderTarget::getViewport(S32* viewport)
 	viewport[3] = mResY;
 }
 
+
+
diff --git a/indra/llrender/llrendertarget.h b/indra/llrender/llrendertarget.h
index cf15f66d318c8902bff8d4fd74cd33736d8c591c..765a727b5b9ea358403491e9ac6bebec8e185fc3 100644
--- a/indra/llrender/llrendertarget.h
+++ b/indra/llrender/llrendertarget.h
@@ -28,7 +28,6 @@
 #define LL_LLRENDERTARGET_H
 
 // LLRenderTarget is unavailible on the mapserver since it uses FBOs.
-#if !LL_MESA_HEADLESS
 
 #include "llgl.h"
 #include "llrender.h"
@@ -156,7 +155,5 @@ class LLRenderTarget
 	static LLRenderTarget* sBoundTarget;
 };
 
-#endif //!LL_MESA_HEADLESS
-
 #endif
 
diff --git a/indra/llrender/lltexture.h b/indra/llrender/lltexture.h
index 569a65c2e0862f4c2b1c1e1a051642f9fe4b9175..093bac20d14c9457f06af0075b205b00850d28c0 100644
--- a/indra/llrender/lltexture.h
+++ b/indra/llrender/lltexture.h
@@ -38,10 +38,9 @@ class LLTexUnit ;
 class LLFontGL ;
 
 //
-//this is an abstract class as the parent for the class LLViewerTexture
-//through the following virtual functions, the class LLViewerTexture can be reached from /llrender.
+//this is an abstract class as the parent for the class LLGLTexture
 //
-class LLTexture : public LLRefCount
+class LLTexture : public virtual LLRefCount
 {
 	friend class LLTexUnit ;
 	friend class LLFontGL ;
@@ -53,7 +52,7 @@ class LLTexture : public LLRefCount
 	LLTexture(){}
 
 	//
-	//interfaces to access LLViewerTexture
+	//interfaces to access LLGLTexture
 	//
 	virtual S8         getType() const = 0 ;
 	virtual void       setKnownDrawSize(S32 width, S32 height) = 0 ;
diff --git a/indra/llui/lluiimage.cpp b/indra/llrender/lluiimage.cpp
similarity index 69%
rename from indra/llui/lluiimage.cpp
rename to indra/llrender/lluiimage.cpp
index 1d9ce29ba98acd5ee95438c7f7d6b134ad454170..b954b66350c9a4c771f1de2a07b587c5e5cb9e73 100644
--- a/indra/llui/lluiimage.cpp
+++ b/indra/llrender/lluiimage.cpp
@@ -31,7 +31,7 @@
 
 // Project includes
 #include "lluiimage.h"
-#include "llui.h"
+#include "llrender2dutils.h"
 
 LLUIImage::LLUIImage(const std::string& name, LLPointer<LLTexture> image)
 :	mName(name),
@@ -112,6 +112,50 @@ void LLUIImage::drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4&
 	drawSolid(border_rect, color);
 }
 
+void LLUIImage::draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, 
+						const LLRect& rect, const LLColor4& color)
+{
+	F32 border_scale = 1.f;
+	F32 border_height = (1.f - mScaleRegion.getHeight()) * getHeight();
+	F32 border_width = (1.f - mScaleRegion.getWidth()) * getWidth();
+	if (rect.getHeight() < border_height || rect.getWidth() < border_width)
+	{
+		 if(border_height - rect.getHeight() > border_width - rect.getWidth())
+		 {
+			 border_scale = (F32)rect.getHeight() / border_height;
+		 }
+		 else
+		 {
+			border_scale = (F32)rect.getWidth() / border_width;
+		 }
+	}
+
+	LLRender2D::pushMatrix();
+	{ 
+		LLVector3 rect_origin = origin_agent + (rect.mLeft * x_axis) + (rect.mBottom * y_axis); 
+		LLRender2D::translate(rect_origin.mV[VX],
+						rect_origin.mV[VY], 
+						rect_origin.mV[VZ]);
+		gGL.getTexUnit(0)->bind(getImage());
+		gGL.color4fv(color.mV);
+
+		LLRectf center_uv_rect(mClipRegion.mLeft + mScaleRegion.mLeft * mClipRegion.getWidth(),
+							mClipRegion.mBottom + mScaleRegion.mTop * mClipRegion.getHeight(),
+							mClipRegion.mLeft + mScaleRegion.mRight * mClipRegion.getWidth(),
+							mClipRegion.mBottom + mScaleRegion.mBottom * mClipRegion.getHeight());
+		gl_segmented_rect_3d_tex(mClipRegion,
+								center_uv_rect,
+								LLRectf(border_width * border_scale * 0.5f / (F32)rect.getWidth(),
+										(rect.getHeight() - (border_height * border_scale * 0.5f)) / (F32)rect.getHeight(),
+										(rect.getWidth() - (border_width * border_scale * 0.5f)) / (F32)rect.getWidth(),
+										(border_height * border_scale * 0.5f) / (F32)rect.getHeight()),
+								rect.getWidth() * x_axis, 
+								rect.getHeight() * y_axis);
+		
+	} LLRender2D::popMatrix();
+}
+
+
 S32 LLUIImage::getWidth() const
 { 
 	// return clipped dimensions of actual image area
@@ -155,7 +199,7 @@ void LLUIImage::onImageLoaded()
 
 namespace LLInitParam
 {
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{
 		// The keyword "none" is specifically requesting a null image
 		// do not default to current value. Used to overwrite template images. 
@@ -165,14 +209,14 @@ namespace LLInitParam
 			return;
 		}
 
-		LLUIImage* imagep =  LLUI::getUIImage(name());
+		LLUIImage* imagep =  LLRender2D::getUIImage(name());
 		if (imagep)
 		{
 			updateValue(imagep);
 		}
 	}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue() == NULL)
 		{
diff --git a/indra/llui/lluiimage.h b/indra/llrender/lluiimage.h
similarity index 95%
rename from indra/llui/lluiimage.h
rename to indra/llrender/lluiimage.h
index f07e8fa7465392e181d98ca577ef281ea46735d9..7817ba1c7b644323dc475de799ee2a61b4acb1cf 100644
--- a/indra/llui/lluiimage.h
+++ b/indra/llrender/lluiimage.h
@@ -64,7 +64,9 @@ class LLUIImage : public LLRefCount
 	void drawBorder(S32 x, S32 y, S32 width, S32 height, const LLColor4& color, S32 border_width) const;
 	void drawBorder(const LLRect& rect, const LLColor4& color, S32 border_width) const { drawBorder(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(), color, border_width); }
 	void drawBorder(S32 x, S32 y, const LLColor4& color, S32 border_width) const { drawBorder(x, y, getWidth(), getHeight(), color, border_width); }
-	
+
+	void draw3D(const LLVector3& origin_agent, const LLVector3& x_axis, const LLVector3& y_axis, const LLRect& rect, const LLColor4& color);
+
 	const std::string& getName() const { return mName; }
 
 	virtual S32 getWidth() const;
@@ -92,7 +94,7 @@ class LLUIImage : public LLRefCount
 namespace LLInitParam
 {
 	template<>
-	class ParamValue<LLUIImage*, TypeValues<LLUIImage*> > 
+	class ParamValue<LLUIImage*> 
 	:	public CustomParamValue<LLUIImage*>
 	{
 		typedef boost::add_reference<boost::add_const<LLUIImage*>::type>::type	T_const_ref;
@@ -100,7 +102,7 @@ namespace LLInitParam
 	public:
 		Optional<std::string> name;
 
-		ParamValue(LLUIImage* const& image)
+		ParamValue(LLUIImage* const& image = NULL)
 		:	super_t(image)
 		{
 			updateBlockFromValue(false);
diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp
index dfbd8cd4eed705dfaacba315bb56114ff03a1593..4909b43e8aa126be2975054d6eec33fc08c8d4f0 100644
--- a/indra/llrender/llvertexbuffer.cpp
+++ b/indra/llrender/llvertexbuffer.cpp
@@ -402,7 +402,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 {
 	if (sLastMask != data_mask)
 	{
-		bool error = false;
 
 		if (gGLManager.mGLSLVersionMajor < 2 && gGLManager.mGLSLVersionMinor < 30)
 		{
@@ -469,7 +468,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 						{
 							if (gDebugSession)
 							{
-								error = true;
 								gFailLog << "Bad client state! " << array[i] << " disabled." << std::endl;
 							}
 							else
@@ -489,7 +487,6 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 					{ //needs to be disabled, make sure it was (DEBUG TEMPORARY)
 						if (gDebugSession)
 						{
-							error = true;
 							gFailLog << "Bad client state! " << array[i] << " enabled." << std::endl;
 						}
 						else
@@ -548,8 +545,10 @@ void LLVertexBuffer::setupClientArrays(U32 data_mask)
 }
 
 //static
+static LLFastTimer::DeclareTimer FTM_VB_DRAW_ARRAYS("drawArrays");
 void LLVertexBuffer::drawArrays(U32 mode, const std::vector<LLVector3>& pos, const std::vector<LLVector3>& norm)
 {
+	LLFastTimer t(FTM_VB_DRAW_ARRAYS);
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
 	gGL.syncMatrices();
 
@@ -784,6 +783,7 @@ void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const
 	placeFence();
 }
 
+static LLFastTimer::DeclareTimer FTM_GL_DRAW_ARRAYS("GL draw arrays");
 void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 {
 	llassert(!LLGLSLShader::sNoFixedFunction || LLGLSLShader::sCurBoundShaderPtr != NULL);
@@ -818,8 +818,11 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const
 		return;
 	}
 
-	stop_glerror();
-	glDrawArrays(sGLMode[mode], first, count);
+	{
+		LLFastTimer t2(FTM_GL_DRAW_ARRAYS);
+		stop_glerror();
+		glDrawArrays(sGLMode[mode], first, count);
+	}
 	stop_glerror();
 	placeFence();
 }
@@ -1565,8 +1568,10 @@ volatile U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, boo
 				{
 					if (map_range)
 					{
+#ifndef LL_MESA_HEADLESS
 						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
 						glBufferParameteriAPPLE(GL_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
 						src = (U8*) glMapBufferARB(GL_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 					else
@@ -1740,8 +1745,10 @@ volatile U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range
 				{
 					if (map_range)
 					{
+#ifndef LL_MESA_HEADLESS
 						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_SERIALIZED_MODIFY_APPLE, GL_FALSE);
 						glBufferParameteriAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_BUFFER_FLUSHING_UNMAP_APPLE, GL_FALSE);
+#endif
 						src = (U8*) glMapBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, GL_WRITE_ONLY_ARB);
 					}
 					else
@@ -1868,7 +1875,9 @@ void LLVertexBuffer::unmapBuffer()
 						}
 						else if (gGLManager.mHasFlushBufferRange)
 						{
+#ifndef LL_MESA_HEADLESS
 							glFlushMappedBufferRangeAPPLE(GL_ARRAY_BUFFER_ARB, offset, length);
+#endif
 						}
 						stop_glerror();
 					}
@@ -1934,7 +1943,9 @@ void LLVertexBuffer::unmapBuffer()
 						else if (gGLManager.mHasFlushBufferRange)
 						{
 #ifdef GL_APPLE_flush_buffer_range
+#ifndef LL_MESA_HEADLESS
 							glFlushMappedBufferRangeAPPLE(GL_ELEMENT_ARRAY_BUFFER_ARB, offset, length);
+#endif
 #endif
 						}
 						stop_glerror();
@@ -2209,7 +2220,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			setup = setup || bindBuffer || bindIndices;
 		}
 
-		bool error = false;
 		if (gDebugGL && !mGLArray)
 		{
 			GLint buff;
@@ -2218,7 +2228,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 			{
 				if (gDebugSession)
 				{
-					error = true;
 					gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl;
 				}
 				else
@@ -2234,7 +2243,6 @@ void LLVertexBuffer::setBuffer(U32 data_mask)
 				{
 					if (gDebugSession)
 					{
-						error = true;
 						gFailLog << "Invalid GL index buffer bound: " << buff <<  std::endl;
 					}
 					else
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index d92b6aa1c07f66806f89ce0992ff6cda7e5fedf7..34a08603fabdb165486892b21c9cc69b2faf6923 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -25,6 +25,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LIBS_PREBUILD_DIR}/include/hunspell
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llui_SOURCE_FILES
     llaccordionctrl.cpp
@@ -33,6 +37,7 @@ set(llui_SOURCE_FILES
     llbadgeholder.cpp
     llbadgeowner.cpp
     llbutton.cpp
+    llchatentry.cpp
     llcheckboxctrl.cpp
     llclipboard.cpp
     llcombobox.cpp
@@ -46,12 +51,16 @@ set(llui_SOURCE_FILES
     lleditmenuhandler.cpp
     llf32uictrl.cpp
     llfiltereditor.cpp
+    llflashtimer.cpp
     llflatlistview.cpp
     llfloater.cpp
     llfloaterreg.cpp
     llfloaterreglistener.cpp
     llflyoutbutton.cpp 
     llfocusmgr.cpp
+    llfolderview.cpp
+    llfolderviewitem.cpp
+    llfolderviewmodel.cpp
     llfunctorregistry.cpp
     lliconctrl.cpp
     llkeywords.cpp
@@ -66,7 +75,6 @@ set(llui_SOURCE_FILES
     llmultislider.cpp
     llmultisliderctrl.cpp
     llnotifications.cpp
-    llnotificationslistener.cpp
     llnotificationsutil.cpp
     llpanel.cpp
     llprogressbar.cpp
@@ -109,7 +117,6 @@ set(llui_SOURCE_FILES
     lluicolortable.cpp
     lluictrl.cpp
     lluictrlfactory.cpp
-    lluiimage.cpp
     lluistring.cpp
     llundo.cpp
     llurlaction.cpp
@@ -135,6 +142,7 @@ set(llui_HEADER_FILES
     llbadgeowner.h
     llbutton.h
     llcallbackmap.h
+    llchatentry.h
     llcheckboxctrl.h
     llclipboard.h
     llcombobox.h
@@ -148,12 +156,16 @@ set(llui_HEADER_FILES
     lleditmenuhandler.h
     llf32uictrl.h
     llfiltereditor.h 
+    llflashtimer.h
     llflatlistview.h
     llfloater.h
     llfloaterreg.h
     llfloaterreglistener.h
     llflyoutbutton.h 
     llfocusmgr.h
+    llfolderview.h
+    llfolderviewitem.h
+    llfolderviewmodel.h
     llfunctorregistry.h
     llhelp.h
     lliconctrl.h
@@ -171,7 +183,6 @@ set(llui_HEADER_FILES
     llmultislider.h
     llnotificationptr.h
     llnotifications.h
-    llnotificationslistener.h
     llnotificationsutil.h
     llnotificationtemplate.h
     llnotificationvisibilityrule.h
@@ -219,7 +230,6 @@ set(llui_HEADER_FILES
     lluifwd.h
     llui.h
     lluicolor.h
-    lluiimage.h
     lluistring.h
     llundo.h
     llurlaction.h
diff --git a/indra/llui/llaccordionctrltab.cpp b/indra/llui/llaccordionctrltab.cpp
index c025cd7939e5443cd6581d24be2821d0fd199b80..43462bd2447687df1eb83b407eaa8fc12f63009f 100644
--- a/indra/llui/llaccordionctrltab.cpp
+++ b/indra/llui/llaccordionctrltab.cpp
@@ -184,7 +184,7 @@ void LLAccordionCtrlTab::LLAccordionCtrlTabHeader::setTitleFontStyle(std::string
 	if (mHeaderTextbox)
 	{
 		std::string text = mHeaderTextbox->getText();
-		mStyleParams.font(mHeaderTextbox->getDefaultFont());
+		mStyleParams.font(mHeaderTextbox->getFont());
 		mStyleParams.font.style(style);
 		mHeaderTextbox->setText(text, mStyleParams);
 	}
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 705fe165593111289a16243100e002db8c138b2c..a8149a9a1dae6372f63f1d644ae28d8554e318f7 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -105,6 +105,7 @@ LLButton::Params::Params()
 	badge("badge"),
 	handle_right_mouse("handle_right_mouse"),
 	held_down_delay("held_down_delay"),
+	button_flash_enable("button_flash_enable", false),
 	button_flash_count("button_flash_count"),
 	button_flash_rate("button_flash_rate")
 {
@@ -171,9 +172,24 @@ LLButton::LLButton(const LLButton::Params& p)
 	mHeldDownSignal(NULL),
 	mUseDrawContextAlpha(p.use_draw_context_alpha),
 	mHandleRightMouse(p.handle_right_mouse),
-	mButtonFlashCount(p.button_flash_count),
-	mButtonFlashRate(p.button_flash_rate)
+	mFlashingTimer(NULL)
 {
+	if (p.button_flash_enable)
+	{
+		// If optional parameter "p.button_flash_count" is not provided, LLFlashTimer will be
+		// used instead it a "default" value from gSavedSettings.getS32("FlashCount")).
+		// Likewise, missing "p.button_flash_rate" is replaced by gSavedSettings.getF32("FlashPeriod").
+		// Note: flashing should be allowed in settings.xml (boolean key "EnableButtonFlashing").
+		S32 flash_count = p.button_flash_count.isProvided()? p.button_flash_count : 0;
+		F32 flash_rate = p.button_flash_rate.isProvided()? p.button_flash_rate : 0.0;
+		mFlashingTimer = new LLFlashTimer ((LLFlashTimer::callback_t)NULL, flash_count, flash_rate);
+	}
+	else
+	{
+		mButtonFlashCount = p.button_flash_count;
+		mButtonFlashRate = p.button_flash_rate;
+	}
+
 	static LLUICachedControl<S32> llbutton_orig_h_pad ("UIButtonOrigHPad", 0);
 	static Params default_params(LLUICtrlFactory::getDefaultParams<LLButton>());
 
@@ -267,6 +283,11 @@ LLButton::~LLButton()
 	delete mMouseDownSignal;
 	delete mMouseUpSignal;
 	delete mHeldDownSignal;
+
+	if (mFlashingTimer)
+	{
+		mFlashingTimer->unset();
+	}
 }
 
 // HACK: Committing a button is the same as instantly clicking it.
@@ -591,22 +612,6 @@ void LLButton::draw()
 {
 	static LLCachedControl<bool> sEnableButtonFlashing(*LLUI::sSettingGroups["config"], "EnableButtonFlashing", true);
 	F32 alpha = mUseDrawContextAlpha ? getDrawContext().mAlpha : getCurrentTransparency();
-	bool flash = FALSE;
-
-	if( mFlashing)
-	{
-		if ( sEnableButtonFlashing)
-		{
-			F32 elapsed = mFlashingTimer.getElapsedTimeF32();
-			S32 flash_count = S32(elapsed * mButtonFlashRate * 2.f);
-			// flash on or off?
-			flash = (flash_count % 2 == 0) || flash_count > S32((F32)mButtonFlashCount * 2.f);
-		}
-		else
-		{ // otherwise just highlight button in flash color
-			flash = true;
-		}
-	}
 
 	bool pressed_by_keyboard = FALSE;
 	if (hasFocus())
@@ -631,9 +636,21 @@ void LLButton::draw()
 	bool selected = getToggleState();
 	
 	bool use_glow_effect = FALSE;
-	LLColor4 glow_color = LLColor4::white;
+	LLColor4 highlighting_color = LLColor4::white;
+	LLColor4 glow_color;
 	LLRender::eBlendType glow_type = LLRender::BT_ADD_WITH_ALPHA;
 	LLUIImage* imagep = NULL;
+
+    //  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))
+	{
+		mFlashing = false;
+	}
+
+	bool flash = mFlashing && sEnableButtonFlashing;
+
 	if (pressed && mDisplayPressedState)
 	{
 		imagep = selected ? mImagePressedSelected : mImagePressed;
@@ -699,15 +716,20 @@ void LLButton::draw()
 			imagep = mImageFlash;
 		}
 		// else use usual flashing via flash_color
-		else
+		else if (mFlashingTimer)
 		{
 			LLColor4 flash_color = mFlashBgColor.get();
 			use_glow_effect = TRUE;
 			glow_type = LLRender::BT_ALPHA; // blend the glow
-			if (mNeedsHighlight) // highlighted AND flashing
-				glow_color = (glow_color*0.5f + flash_color*0.5f) % 2.0f; // average between flash and highlight colour, with sum of the opacity
-			else
+
+			if (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress())
+			{
 				glow_color = flash_color;
+			}
+			else if (mNeedsHighlight)
+			{
+                glow_color = highlighting_color;
+			}
 		}
 	}
 
@@ -756,8 +778,7 @@ void LLButton::draw()
 	if (use_glow_effect)
 	{
 		mCurGlowStrength = lerp(mCurGlowStrength,
-					mFlashing ? (flash? 1.0 : 0.0)
-					: mHoverGlowStrength,
+					mFlashing ? (mFlashingTimer->isCurrentlyHighlighted() || !mFlashingTimer->isFlashingInProgress() || mNeedsHighlight? 1.0 : 0.0) : mHoverGlowStrength,
 					LLCriticalDamp::getInterpolant(0.05f));
 	}
 	else
@@ -944,21 +965,26 @@ void LLButton::setToggleState(BOOL b)
 	{
 		setControlValue(b); // will fire LLControlVariable callbacks (if any)
 		setValue(b);        // may or may not be redundant
+		setFlashing(false);	// stop flash state whenever the selected/unselected state if reset
 		// Unselected label assignments
 		autoResize();
 	}
 }
 
-void LLButton::setFlashing( BOOL b )	
+void LLButton::setFlashing(bool b)	
 { 
-	if ((bool)b != mFlashing)
+	if (mFlashingTimer)
 	{
 		mFlashing = b; 
-		mFlashingTimer.reset();
+		(b ? mFlashingTimer->startFlashing() : mFlashingTimer->stopFlashing());
+	}
+	else if (b != mFlashing)
+	{
+		mFlashing = b; 
+		mFrameTimer.reset();
 	}
 }
 
-
 BOOL LLButton::toggleState()			
 {
     bool flipped = ! getToggleState();
diff --git a/indra/llui/llbutton.h b/indra/llui/llbutton.h
index deaa0823c610a16be0fa85f770e31bbc59529dee..060db59a8a6e088eb1661357961a7f4bf4317871 100644
--- a/indra/llui/llbutton.h
+++ b/indra/llui/llbutton.h
@@ -30,6 +30,7 @@
 #include "lluuid.h"
 #include "llbadgeowner.h"
 #include "llcontrol.h"
+#include "llflashtimer.h"
 #include "lluictrl.h"
 #include "v4color.h"
 #include "llframetimer.h"
@@ -133,6 +134,7 @@ class LLButton
 
 		Optional<bool>				handle_right_mouse;
 
+		Optional<bool>				button_flash_enable;
 		Optional<S32>				button_flash_count;
 		Optional<F32>				button_flash_rate;
 
@@ -199,8 +201,9 @@ class LLButton
 	void			setToggleState(BOOL b);
 
 	void			setHighlight(bool b);
-	void			setFlashing( BOOL b );
+	void			setFlashing( bool b );
 	BOOL			getFlashing() const		{ return mFlashing; }
+    LLFlashTimer*   getFlashTimer() {return mFlashingTimer;}
 
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
 	LLFontGL::HAlign getHAlign() const						{ return mHAlign; }
@@ -373,7 +376,8 @@ class LLButton
 	bool						mForcePressedState;
 	bool						mDisplayPressedState;
 
-	LLFrameTimer				mFlashingTimer;
+	LLFrameTimer				mFrameTimer;
+	LLFlashTimer *				mFlashingTimer;
 
 	bool						mHandleRightMouse;
 };
diff --git a/indra/llui/llchatentry.cpp b/indra/llui/llchatentry.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..6a1b48a08a3d4b52754fdeb6158569ab54b18e82
--- /dev/null
+++ b/indra/llui/llchatentry.cpp
@@ -0,0 +1,257 @@
+/**
+ * @file llchatentry.cpp
+ * @brief LLChatEntry implementation
+ *
+ * $LicenseInfo:firstyear=2001&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 "linden_common.h"
+#include "llscrollcontainer.h"
+
+#include "llchatentry.h"
+
+static LLDefaultChildRegistry::Register<LLChatEntry> r("chat_editor");
+
+LLChatEntry::Params::Params()
+:	has_history("has_history", true),
+ 	is_expandable("is_expandable", false),
+ 	expand_lines_count("expand_lines_count", 1)
+{}
+
+LLChatEntry::LLChatEntry(const Params& p)
+:	LLTextEditor(p),
+ 	mTextExpandedSignal(NULL),
+ 	mHasHistory(p.has_history),
+ 	mIsExpandable(p.is_expandable),
+ 	mExpandLinesCount(p.expand_lines_count),
+ 	mPrevLinesCount(0),
+	mSingleLineMode(false),
+	mPrevExpandedLineCount(S32_MAX)
+{
+	// Initialize current history line iterator
+	mCurrentHistoryLine = mLineHistory.begin();
+
+	mAutoIndent = false;
+}
+
+LLChatEntry::~LLChatEntry()
+{
+	delete mTextExpandedSignal;
+}
+
+void LLChatEntry::draw()
+{
+	if(mIsExpandable)
+	{
+		expandText();
+	}
+
+	LLTextEditor::draw();
+}
+
+void LLChatEntry::onCommit()
+{
+	updateHistory();
+	LLTextEditor::onCommit();
+}
+
+boost::signals2::connection LLChatEntry::setTextExpandedCallback(const commit_signal_t::slot_type& cb)
+{
+	if (!mTextExpandedSignal)
+	{
+		mTextExpandedSignal = new commit_signal_t();
+	}
+	return mTextExpandedSignal->connect(cb);
+}
+
+void LLChatEntry::expandText()
+{
+	S32 line_count = mSingleLineMode ? 1 : mExpandLinesCount;
+
+	int visible_lines_count = llabs(getVisibleLines(true).first - getVisibleLines(true).second);
+	bool can_changed = getLineCount() <= line_count || line_count < mPrevExpandedLineCount ;
+	mPrevExpandedLineCount = line_count;
+
+	// true if pasted text has more lines than expand height limit and expand limit is not reached yet
+	bool text_pasted = (getLineCount() > line_count) && (visible_lines_count < line_count);
+
+	if (mIsExpandable && (can_changed || text_pasted || mSingleLineMode) && getLineCount() != mPrevLinesCount)
+	{
+		int lines_height = 0;
+		if (text_pasted)
+		{
+			// text is pasted and now mLineInfoList.size() > mExpandLineCounts and mLineInfoList is not empty,
+			// so lines_height is the sum of the last 'expanded_line_count' lines height
+			lines_height = (mLineInfoList.end() - line_count)->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+		else
+		{
+			lines_height = mLineInfoList.begin()->mRect.mTop - mLineInfoList.back().mRect.mBottom;
+		}
+
+		int height = mVPad * 2 +  lines_height;
+
+		LLRect doc_rect = getRect();
+		doc_rect.setOriginAndSize(doc_rect.mLeft, doc_rect.mBottom, doc_rect.getWidth(), height);
+		setShape(doc_rect);
+
+		mPrevLinesCount = getLineCount();
+
+		if (mTextExpandedSignal)
+		{
+			(*mTextExpandedSignal)(this, LLSD() );
+		}
+
+		needsReflow();
+	}
+}
+
+// line history support
+void LLChatEntry::updateHistory()
+{
+	// On history enabled, remember committed line and
+	// reset current history line number.
+	// Be sure only to remember lines that are not empty and that are
+	// different from the last on the list.
+	if (mHasHistory && getLength())
+	{
+		// Add text to history, ignoring duplicates
+		if (mLineHistory.empty() || getText() != mLineHistory.back())
+		{
+			mLineHistory.push_back(getText());
+		}
+
+		mCurrentHistoryLine = mLineHistory.end();
+	}
+}
+
+void LLChatEntry::beforeValueChange()
+{
+    if(this->getLength() == 0 && !mLabel.empty())
+    {
+        this->clearSegments();
+    }
+}
+
+void LLChatEntry::onValueChange(S32 start, S32 end)
+{
+    //Internally resetLabel() must meet a condition before it can reset the label
+    resetLabel();
+}
+
+bool LLChatEntry::useLabel()
+{
+    return !getLength() && !mLabel.empty();
+}
+
+void LLChatEntry::onFocusReceived()
+{
+
+}
+
+void LLChatEntry::onFocusLost()
+{
+
+}
+
+BOOL LLChatEntry::handleSpecialKey(const KEY key, const MASK mask)
+{
+	BOOL handled = FALSE;
+
+    // In the case of a chat entry, pressing RETURN when something is selected
+    // should NOT erase the selection (unlike a notecard, for example)
+    if (key == KEY_RETURN)
+    {
+        endOfDoc();
+        startSelection();
+        endSelection();
+    }
+
+	LLTextEditor::handleSpecialKey(key, mask);
+
+	switch(key)
+	{
+	case KEY_RETURN:
+		if (MASK_NONE == mask)
+		{
+			needsReflow();
+		}
+		break;
+
+	case KEY_UP:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && mCurrentHistoryLine > mLineHistory.begin())
+			{
+				setText(*(--mCurrentHistoryLine));
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	case KEY_DOWN:
+		if (mHasHistory && MASK_CONTROL == mask)
+		{
+			if (!mLineHistory.empty() && mCurrentHistoryLine < (mLineHistory.end() - 1) )
+			{
+				setText(*(++mCurrentHistoryLine));
+				endOfDoc();
+			}
+			else if (!mLineHistory.empty() && mCurrentHistoryLine == (mLineHistory.end() - 1) )
+			{
+				mCurrentHistoryLine++;
+				std::string empty("");
+				setText(empty);
+				needsReflow();
+				endOfDoc();
+			}
+			else
+			{
+				LLUI::reportBadKeystroke();
+			}
+			handled = TRUE;
+		}
+		break;
+
+	default:
+		break;
+	}
+
+	return handled;
+}
+
+void LLChatEntry::enableSingleLineMode(bool single_line_mode)
+{
+	if (mScroller)
+	{
+		mScroller->setSize(single_line_mode ? 0 : -1);
+	}
+
+	mSingleLineMode = single_line_mode;
+	mPrevLinesCount = -1;
+	setWordWrap(!single_line_mode);
+}
diff --git a/indra/llui/llchatentry.h b/indra/llui/llchatentry.h
new file mode 100644
index 0000000000000000000000000000000000000000..49c8d21450c9fa05d81c632f1ab79147a161d711
--- /dev/null
+++ b/indra/llui/llchatentry.h
@@ -0,0 +1,106 @@
+/**
+ * @file llchatentry.h
+ * @author Paul Guslisty
+ * @brief Text editor widget which is used for user input
+ *
+ * Features:
+ *			Optional line history so previous entries can be recalled by CTRL UP/DOWN
+ *			Optional auto-resize behavior on input chat field
+ *
+ * $LicenseInfo:firstyear=2001&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 LLCHATENTRY_H_
+#define LLCHATENTRY_H_
+
+#include "lltexteditor.h"
+
+class LLChatEntry : public LLTextEditor
+{
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLTextEditor::Params>
+	{
+		Optional<bool>		has_history,
+							is_expandable;
+
+		Optional<int>		expand_lines_count;
+
+		Params();
+	};
+
+	virtual ~LLChatEntry();
+
+protected:
+
+	friend class LLUICtrlFactory;
+	LLChatEntry(const Params& p);
+    /*virtual*/ void    beforeValueChange();
+    /*virtual*/ void    onValueChange(S32 start, S32 end);
+    /*virtual*/ bool    useLabel();
+
+public:
+
+	virtual void	draw();
+	virtual	void	onCommit();
+    /*virtual*/ void	onFocusReceived();
+    /*virtual*/ void	onFocusLost();
+
+	void enableSingleLineMode(bool single_line_mode);
+	boost::signals2::connection setTextExpandedCallback(const commit_signal_t::slot_type& cb);
+
+private:
+
+	/**
+	 * Implements auto-resize behavior.
+	 * When user's typing reaches the right edge of the chat field
+	 * the chat field expands vertically by one line. The bottom of
+	 * the chat field remains bottom-justified. The chat field does
+	 * not expand beyond mExpandLinesCount.
+	 */
+	void	expandText();
+
+	/**
+	 * Implements line history so previous entries can be recalled by CTRL UP/DOWN
+	 */
+	void	updateHistory();
+
+	BOOL	handleSpecialKey(const KEY key, const MASK mask);
+
+
+	// Fired when text height expanded to mExpandLinesCount
+	commit_signal_t*			mTextExpandedSignal;
+
+	// line history support:
+	typedef std::vector<std::string>	line_history_t;
+	line_history_t::iterator			mCurrentHistoryLine;	// currently browsed history line
+	line_history_t						mLineHistory;			// line history storage
+	bool								mHasHistory;			// flag for enabled/disabled line history
+	bool								mIsExpandable;
+	bool								mSingleLineMode;
+
+	S32									mExpandLinesCount;
+	S32									mPrevLinesCount;
+	S32									mPrevExpandedLineCount;
+};
+
+#endif /* LLCHATENTRY_H_ */
diff --git a/indra/llui/llcheckboxctrl.cpp b/indra/llui/llcheckboxctrl.cpp
index 4fe444c1a4880848dcc5337a574c5eb35ed131c6..5525520d78cc527e7b147cbba2211c5551799760 100644
--- a/indra/llui/llcheckboxctrl.cpp
+++ b/indra/llui/llcheckboxctrl.cpp
@@ -107,7 +107,7 @@ LLCheckBoxCtrl::LLCheckBoxCtrl(const LLCheckBoxCtrl::Params& p)
 	LLButton::Params params = p.check_button;
 	params.rect(btn_rect);
 	//params.control_name(p.control_name);
-	params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onButtonPress, this, _2));
+	params.click_callback.function(boost::bind(&LLCheckBoxCtrl::onCommit, this));
 	params.commit_on_return(false);
 	// Checkboxes only allow boolean initial values, but buttons can
 	// take any LLSD.
@@ -123,18 +123,6 @@ LLCheckBoxCtrl::~LLCheckBoxCtrl()
 	// Children all cleaned up by default view destructor.
 }
 
-
-// static
-void LLCheckBoxCtrl::onButtonPress( const LLSD& data )
-{
-	//if (mRadioStyle)
-	//{
-	//	setValue(TRUE);
-	//}
-
-	onCommit();
-}
-
 void LLCheckBoxCtrl::onCommit()
 {
 	if( getEnabled() )
diff --git a/indra/llui/llcheckboxctrl.h b/indra/llui/llcheckboxctrl.h
index 67d8091a97f1cc66290ee8c6d612ae2f2c9785e0..5ce45b21351ce3f929a84e9e6a3f3d271a95a8d6 100644
--- a/indra/llui/llcheckboxctrl.h
+++ b/indra/llui/llcheckboxctrl.h
@@ -103,8 +103,6 @@ class LLCheckBoxCtrl
 	
 	virtual void		setControlName(const std::string& control_name, LLView* context);
 
-	void				onButtonPress(const LLSD& data);
-
 	virtual BOOL		isDirty()	const;		// Returns TRUE if the user has modified this control.
 	virtual void		resetDirty();			// Clear dirty state
 
diff --git a/indra/llui/llcombobox.cpp b/indra/llui/llcombobox.cpp
index 41e5d74042f112f8eae50ea0af3c250442d21e5c..d4e14d94190bcaa4d5d8c4867b8f8737d94cfc8c 100644
--- a/indra/llui/llcombobox.cpp
+++ b/indra/llui/llcombobox.cpp
@@ -551,7 +551,7 @@ void LLComboBox::showList()
 	LLCoordWindow window_size;
 	getWindow()->getSize(&window_size);
 	//HACK: shouldn't have to know about scale here
-	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::sGLScaleFactor.mV[VY]) - 50 );
+	mList->fitContents( 192, llfloor((F32)window_size.mY / LLUI::getScaleFactor().mV[VY]) - 50 );
 
 	// Make sure that we can see the whole list
 	LLRect root_view_local;
diff --git a/indra/llui/llcommandmanager.cpp b/indra/llui/llcommandmanager.cpp
index 0e2f3f1961b784ebea0d731ceedca6403453c8ac..625fb8e87024c7cfc5f2a8d646737dabe181be76 100644
--- a/indra/llui/llcommandmanager.cpp
+++ b/indra/llui/llcommandmanager.cpp
@@ -63,6 +63,7 @@ LLCommand::Params::Params()
 	, is_running_parameters("is_running_parameters")
 	, is_starting_function("is_starting_function")
 	, is_starting_parameters("is_starting_parameters")
+	, is_flashing_allowed("is_flashing_allowed", false)
 {
 }
 
@@ -83,6 +84,7 @@ LLCommand::LLCommand(const LLCommand::Params& p)
 	, mIsRunningParameters(p.is_running_parameters)
 	, mIsStartingFunction(p.is_starting_function)
 	, mIsStartingParameters(p.is_starting_parameters)
+	, mIsFlashingAllowed(p.is_flashing_allowed)
 {
 }
 
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index a7276a48aa5cb146e72d70020c57ccb2662b477f..ff5a8a325738b1c9a511cbd3df93b96683c357ca 100644
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -111,6 +111,8 @@ class LLCommand
 		Optional<std::string>	is_starting_function;
 		Optional<LLSD>			is_starting_parameters;
 
+		Optional<bool>			is_flashing_allowed;
+
 		Params();
 	};
 
@@ -138,6 +140,8 @@ class LLCommand
 	const std::string& isStartingFunctionName() const { return mIsStartingFunction; }
 	const LLSD& isStartingParameters() const { return mIsStartingParameters; }
 
+	bool isFlashingAllowed() const { return mIsFlashingAllowed; }
+
 private:
 	LLCommandId mIdentifier;
 
@@ -161,6 +165,8 @@ class LLCommand
 
 	std::string mIsStartingFunction;
 	LLSD        mIsStartingParameters;
+
+	bool		mIsFlashingAllowed;
 };
 
 
diff --git a/indra/llui/llconsole.cpp b/indra/llui/llconsole.cpp
index 161496b1f5a36b9a37bb8875e4c9d64c8e6c0396..c216d593a249693700ab7e2f01c3da3f77a0a5d4 100644
--- a/indra/llui/llconsole.cpp
+++ b/indra/llui/llconsole.cpp
@@ -243,7 +243,6 @@ void LLConsole::draw()
 void LLConsole::Paragraph::makeParagraphColorSegments (const LLColor4 &color) 
 {
 	LLSD paragraph_color_segments;
-	LLColor4 lcolor=color;
 	
 	paragraph_color_segments[0]["text"] =wstring_to_utf8str(mParagraphText);
 	LLSD color_sd = color.getValue();
diff --git a/indra/llui/lldockcontrol.cpp b/indra/llui/lldockcontrol.cpp
index af39e41fa6bd4898e652accdd2a409b48cd7970a..bd42497cb66b8957f7a07bd3df7d3e0a1a03a508 100644
--- a/indra/llui/lldockcontrol.cpp
+++ b/indra/llui/lldockcontrol.cpp
@@ -31,7 +31,6 @@
 
 LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		const LLUIImagePtr& dockTongue, DocAt dockAt, get_allowed_rect_callback_t get_allowed_rect_callback) :
-		mDockWidget(dockWidget),
 		mDockableFloater(dockableFloater),
 		mDockTongue(dockTongue),
 		mDockTongueX(0),
@@ -39,6 +38,11 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 {
 	mDockAt = dockAt;
 
+	if (dockWidget != NULL)
+	{
+		mDockWidgetHandle = dockWidget->getHandle();
+	}
+
 	if (dockableFloater->isDocked())
 	{
 		on();
@@ -62,7 +66,7 @@ LLDockControl::LLDockControl(LLView* dockWidget, LLFloater* dockableFloater,
 		repositionDockable();
 	}
 
-	if (mDockWidget != NULL)
+	if (getDock() != NULL)
 	{
 		mDockWidgetVisible = isDockVisible();
 	}
@@ -78,14 +82,15 @@ LLDockControl::~LLDockControl()
 
 void LLDockControl::setDock(LLView* dockWidget)
 {
-	mDockWidget = dockWidget;
-	if (mDockWidget != NULL)
+	if (dockWidget != NULL)
 	{
+		mDockWidgetHandle = dockWidget->getHandle();
 		repositionDockable();
 		mDockWidgetVisible = isDockVisible();
 	}
 	else
 	{
+		mDockWidgetHandle = LLHandle<LLView>();
 		mDockWidgetVisible = false;
 	}
 }
@@ -97,8 +102,8 @@ void LLDockControl::getAllowedRect(LLRect& rect)
 
 void LLDockControl::repositionDockable()
 {
-	if (!mDockWidget) return;
-	LLRect dockRect = mDockWidget->calcScreenRect();
+	if (!getDock()) return;
+	LLRect dockRect = getDock()->calcScreenRect();
 	LLRect rootRect;
 	LLRect floater_rect = mDockableFloater->calcScreenRect();
 	mGetAllowedRectCallback(rootRect);
@@ -150,13 +155,13 @@ bool LLDockControl::isDockVisible()
 {
 	bool res = true;
 
-	if (mDockWidget != NULL)
+	if (getDock() != NULL)
 	{
 		//we should check all hierarchy
-		res = mDockWidget->isInVisibleChain();
+		res = getDock()->isInVisibleChain();
 		if (res)
 		{
-			LLRect dockRect = mDockWidget->calcScreenRect();
+			LLRect dockRect = getDock()->calcScreenRect();
 
 			switch (mDockAt)
 			{
@@ -169,7 +174,7 @@ bool LLDockControl::isDockVisible()
 				// assume that parent for all dockable floaters
 				// is the root view
 				LLRect dockParentRect =
-						mDockWidget->getRootView()->calcScreenRect();
+						getDock()->getRootView()->calcScreenRect();
 				if (dockRect.mRight <= dockParentRect.mLeft
 						|| dockRect.mLeft >= dockParentRect.mRight)
 				{
@@ -189,7 +194,7 @@ bool LLDockControl::isDockVisible()
 void LLDockControl::moveDockable()
 {
 	// calculate new dockable position
-	LLRect dockRect = mDockWidget->calcScreenRect();
+	LLRect dockRect = getDock()->calcScreenRect();
 	LLRect rootRect;
 	mGetAllowedRectCallback(rootRect);
 
@@ -263,7 +268,7 @@ void LLDockControl::moveDockable()
 
 
 		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		dockParentRect = getDock()->getParent()->calcScreenRect();
 		if (dockRect.getCenterX() < dockParentRect.mLeft)
 		{
 			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
@@ -299,7 +304,7 @@ void LLDockControl::moveDockable()
 		}
 
 		// calculate dock tongue position
-		dockParentRect = mDockWidget->getParent()->calcScreenRect();
+		dockParentRect = getDock()->getParent()->calcScreenRect();
 		if (dockRect.getCenterX() < dockParentRect.mLeft)
 		{
 			mDockTongueX = dockParentRect.mLeft - mDockTongue->getWidth() / 2;
diff --git a/indra/llui/lldockcontrol.h b/indra/llui/lldockcontrol.h
index c9602011f654d3c5a92fb8ead6ad71bb5695fe5a..98a9c7236d79ca9788cee21ba55f7933d55331f9 100644
--- a/indra/llui/lldockcontrol.h
+++ b/indra/llui/lldockcontrol.h
@@ -63,7 +63,7 @@ class LLDockControl
 	void setDock(LLView* dockWidget);
 	LLView* getDock()
 	{
-		return mDockWidget;
+		return mDockWidgetHandle.get();
 	}
 	void repositionDockable();
 	void drawToungue();
@@ -83,7 +83,7 @@ class LLDockControl
 	bool mRecalculateDockablePosition;
 	bool mDockWidgetVisible;
 	DocAt mDockAt;
-	LLView* mDockWidget;
+	LLHandle<LLView> mDockWidgetHandle;
 	LLRect mPrevDockRect;
 	LLRect mRootRect;
 	LLRect mFloaterRect;
diff --git a/indra/llui/llflashtimer.cpp b/indra/llui/llflashtimer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e49628acd59c8a5c424990d742f1c58417d6262f
--- /dev/null
+++ b/indra/llui/llflashtimer.cpp
@@ -0,0 +1,100 @@
+/**
+ * @file llflashtimer.cpp
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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 "../newview/llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+#include "../newview/llviewercontrol.h"
+#include "lleventtimer.h"
+
+LLFlashTimer::LLFlashTimer(callback_t cb, S32 count, F32 period)
+		: LLEventTimer(period)
+		, mCallback(cb)
+		, mCurrentTickCount(0)
+        , mIsFlashingInProgress(false)
+        , mIsCurrentlyHighlighted(false)
+        , mUnset(false)
+{
+	mEventTimer.stop();
+
+	// By default use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
+	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
+	// in runtime. So, both settings are made as required restart.
+	mFlashCount = 2 * ((count > 0) ? count : gSavedSettings.getS32("FlashCount"));
+	if (mPeriod <= 0)
+	{
+		mPeriod = gSavedSettings.getF32("FlashPeriod");
+	}
+}
+
+void LLFlashTimer::unset()
+{
+	mUnset = true;
+	mCallback = NULL;
+}
+
+BOOL LLFlashTimer::tick()
+{
+	mIsCurrentlyHighlighted = !mIsCurrentlyHighlighted;
+
+	if (mCallback)
+	{
+		mCallback(mIsCurrentlyHighlighted);
+	}
+
+	if (++mCurrentTickCount >= mFlashCount)
+	{
+		stopFlashing();
+	}
+
+	return mUnset;
+}
+
+void LLFlashTimer::startFlashing()
+{
+	mIsFlashingInProgress = true;
+	mIsCurrentlyHighlighted = true;
+	mEventTimer.start();
+}
+
+void LLFlashTimer::stopFlashing()
+{
+	mEventTimer.stop();
+	mIsFlashingInProgress = false;
+	mIsCurrentlyHighlighted = false;
+	mCurrentTickCount = 0;
+}
+
+bool LLFlashTimer::isFlashingInProgress()
+{
+	return mIsFlashingInProgress;
+}
+
+bool LLFlashTimer::isCurrentlyHighlighted()
+{
+	return mIsCurrentlyHighlighted;
+}
+
+
diff --git a/indra/llui/llflashtimer.h b/indra/llui/llflashtimer.h
new file mode 100644
index 0000000000000000000000000000000000000000..c60f99a8eac40650cb01bff70d3709d51d3dfba1
--- /dev/null
+++ b/indra/llui/llflashtimer.h
@@ -0,0 +1,73 @@
+/**
+ * @file llflashtimer.h
+ * @brief LLFlashTimer class implementation
+ *
+ * $LicenseInfo:firstyear=2002&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_FLASHTIMER_H
+#define LL_FLASHTIMER_H
+
+#include "lleventtimer.h"
+
+class LLFlashTimer : public LLEventTimer
+{
+public:
+
+	typedef boost::function<void (bool)> callback_t;
+
+	/**
+	 * Constructor.
+	 *
+	 * @param count - how many times callback should be called (twice to not change original state)
+	 * @param period - how frequently callback should be called
+	 * @param cb - callback to be called each tick
+	 */
+	LLFlashTimer(callback_t cb = NULL, S32 count = 0, F32 period = 0.0);
+	~LLFlashTimer() {};
+
+	/*virtual*/ BOOL tick();
+
+	void startFlashing();
+	void stopFlashing();
+
+	bool isFlashingInProgress();
+	bool isCurrentlyHighlighted();
+	/*
+	 * Use this instead of deleting this object.
+	 * The next call to tick() will return true and that will destroy this object.
+	 */
+	void unset();
+
+private:
+	callback_t		mCallback;
+	/**
+	 * How many times parent will blink.
+	 */
+	S32 mFlashCount;
+	S32 mCurrentTickCount;
+	bool mIsCurrentlyHighlighted;
+	bool mIsFlashingInProgress;
+	bool mUnset;
+};
+
+#endif /* LL_FLASHTIMER_H */
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 1594be25122245a9447cb113c047c2361eab278a..09e27a264aa151399208526cf86d02ee21d7ba2d 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -64,6 +64,8 @@
 // use this to control "jumping" behavior when Ctrl-Tabbing
 const S32 TABBED_FLOATER_OFFSET = 0;
 
+extern LLControlGroup gSavedSettings;
+
 namespace LLInitParam
 {
 	void TypeValues<LLFloaterEnums::EOpenPositioning>::declareValues()
@@ -627,6 +629,17 @@ void LLFloater::setVisible( BOOL visible )
 	storeVisibilityControl();
 }
 
+
+void LLFloater::setIsSingleInstance(BOOL is_single_instance)
+{
+	mSingleInstance = is_single_instance;
+	if (!mIsReuseInitialized)
+	{
+		mReuseInstance = is_single_instance; // reuse single-instance floaters by default
+	}
+}
+
+
 // virtual
 void LLFloater::handleVisibilityChange ( BOOL new_visibility )
 {
@@ -642,14 +655,20 @@ void LLFloater::openFloater(const LLSD& key)
 {
 	llinfos << "Opening floater " << getName() << llendl;
 	mKey = key; // in case we need to open ourselves again
-	
+
 	if (getSoundFlags() != SILENT 
 	// don't play open sound for hosted (tabbed) windows
 		&& !getHost() 
 		&& !getFloaterHost()
 		&& (!getVisible() || isMinimized()))
 	{
-		make_ui_sound("UISndWindowOpen");
+        //Don't play a sound for incoming voice call based upon chat preference setting
+        bool playSound = !(getName() == "incoming call" && gSavedSettings.getBOOL("PlaySoundIncomingVoiceCall") == FALSE);
+
+        if(playSound)
+        {
+            make_ui_sound("UISndWindowOpen");
+        }
 	}
 
 	//RN: for now, we don't allow rehosting from one multifloater to another
@@ -713,6 +732,33 @@ void LLFloater::closeFloater(bool app_quitting)
 			make_ui_sound("UISndWindowClose");
 		}
 
+		gFocusMgr.clearLastFocusForGroup(this);
+
+			if (hasFocus())
+			{
+				// Do this early, so UI controls will commit before the
+				// window is taken down.
+				releaseFocus();
+
+				// give focus to dependee floater if it exists, and we had focus first
+				if (isDependent())
+				{
+					LLFloater* dependee = mDependeeHandle.get();
+					if (dependee && !dependee->isDead())
+					{
+						dependee->setFocus(TRUE);
+					}
+				}
+			}
+
+
+		//If floater is a dependent, remove it from parent (dependee)
+        LLFloater* dependee = mDependeeHandle.get();
+        if (dependee)
+        {
+            dependee->removeDependentFloater(this);
+        }
+
 		// now close dependent floater
 		for(handle_set_iter_t dependent_it = mDependents.begin();
 			dependent_it != mDependents.end(); )
@@ -731,28 +777,6 @@ void LLFloater::closeFloater(bool app_quitting)
 		}
 		
 		cleanupHandles();
-		gFocusMgr.clearLastFocusForGroup(this);
-
-		if (hasFocus())
-		{
-			// Do this early, so UI controls will commit before the
-			// window is taken down.
-			releaseFocus();
-
-			// give focus to dependee floater if it exists, and we had focus first
-			if (isDependent())
-			{
-				LLFloater* dependee = mDependeeHandle.get();
-				if (dependee && !dependee->isDead())
-				{
-					dependee->setFocus(TRUE);
-				}
-			}
-
-			// STORM-1879: since this floater has focus, treat the closeFloater- call
-			// like a click on the close-button, and close gear- and contextmenus
-			LLMenuGL::sMenuContainer->hideMenus();
-		}
 
 		dirtyRect();
 
@@ -788,6 +812,20 @@ void LLFloater::closeFloater(bool app_quitting)
 	}
 }
 
+/*virtual*/
+void LLFloater::closeHostedFloater()
+{
+	// When toggling *visibility*, close the host instead of the floater when hosted
+	if (getHost())
+	{
+		getHost()->closeFloater();
+	}
+	else
+	{
+		closeFloater();
+	}
+}
+
 /*virtual*/
 void LLFloater::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
@@ -1188,7 +1226,6 @@ void LLFloater::setMinimized(BOOL minimize)
 	{
 		// minimized flag should be turned on before release focus
 		mMinimized = TRUE;
-
 		mExpandedRect = getRect();
 
 		// If the floater has been dragged while minimized in the
@@ -1261,7 +1298,6 @@ void LLFloater::setMinimized(BOOL minimize)
 		}
 
 		setOrigin( mExpandedRect.mLeft, mExpandedRect.mBottom );
-
 		if (mButtonsEnabled[BUTTON_RESTORE])
 		{
 			mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
@@ -1297,7 +1333,6 @@ void LLFloater::setMinimized(BOOL minimize)
 
 		// Reshape *after* setting mMinimized
 		reshape( mExpandedRect.getWidth(), mExpandedRect.getHeight(), TRUE );
-		applyPositioning(NULL, false);
 	}
 
 	make_ui_sound("UISndWindowClose");
@@ -1419,7 +1454,6 @@ void LLFloater::setHost(LLMultiFloater* host)
 		mButtonScale = 1.f;
 		//mButtonsEnabled[BUTTON_TEAR_OFF] = FALSE;
 	}
-	updateTitleButtons();
 	if (host)
 	{
 		mHostHandle = host->getHandle();
@@ -1429,6 +1463,8 @@ void LLFloater::setHost(LLMultiFloater* host)
 	{
 		mHostHandle.markDead();
 	}
+    
+	updateTitleButtons();
 }
 
 void LLFloater::moveResizeHandlesToFront()
@@ -1585,10 +1621,19 @@ void LLFloater::bringToFront( S32 x, S32 y )
 
 
 // virtual
-void LLFloater::setVisibleAndFrontmost(BOOL take_focus)
+void LLFloater::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
 {
-	setVisible(TRUE);
-	setFrontmost(take_focus);
+	LLMultiFloater* hostp = getHost();
+	if (hostp)
+	{
+		hostp->setVisible(TRUE);
+		hostp->setFrontmost(take_focus);
+	}
+	else
+	{
+		setVisible(TRUE);
+		setFrontmost(take_focus);
+	}
 }
 
 void LLFloater::setFrontmost(BOOL take_focus)
@@ -1670,10 +1715,12 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		gFloaterView->addChild(self);
 
 		self->openFloater(self->getKey());
-		
-		// only force position for floaters that don't have that data saved
-		if (self->mRectControl.empty())
+		if (self->mSaveRect && !self->mRectControl.empty())
 		{
+			self->applyRectControl();
+		}
+		else
+		{   // only force position for floaters that don't have that data saved
 			new_rect.setLeftTopAndSize(host_floater->getRect().mLeft + 5, host_floater->getRect().mTop - floater_header_size - 5, self->getRect().getWidth(), self->getRect().getHeight());
 			self->setRect(new_rect);
 		}
@@ -1687,6 +1734,10 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
 		if (new_host)
 		{
+			if (self->mSaveRect)
+			{
+				self->storeRectControl();
+			}
 			self->setMinimized(FALSE); // to reenable minimize button if it was minimized
 			new_host->showFloater(self);
 			// make sure host is visible
@@ -1695,6 +1746,7 @@ void LLFloater::onClickTearOff(LLFloater* self)
 		self->setTornOff(false);
 	}
 	self->updateTitleButtons();
+    self->setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
 }
 
 // static
@@ -1720,6 +1772,18 @@ void LLFloater::onClickHelp( LLFloater* self )
 	}
 }
 
+void LLFloater::initRectControl()
+{
+	// save_rect and save_visibility only apply to registered floaters
+	if (mSaveRect)
+	{
+		std::string ctrl_name = getControlName(mInstanceName, mKey);
+		mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
+		mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
+		mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
+	}
+}
+
 // static
 void LLFloater::closeFrontmostFloater()
 {
@@ -2164,7 +2228,8 @@ LLFloaterView::LLFloaterView (const Params& p)
 	mFocusCycleMode(FALSE),
 	mMinimizePositionVOffset(0),
 	mSnapOffsetBottom(0),
-	mSnapOffsetRight(0)
+	mSnapOffsetRight(0),
+	mFrontChild(NULL)
 {
 	mSnapView = getHandle();
 }
@@ -2313,6 +2378,17 @@ LLRect LLFloaterView::findNeighboringPosition( LLFloater* reference_floater, LLF
 
 void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 {
+	if (mFrontChild == child)
+	{
+		if (give_focus && !gFocusMgr.childHasKeyboardFocus(child))
+		{
+			child->setFocus(TRUE);
+		}
+		return;
+	}
+
+	mFrontChild = child;
+
 	// *TODO: make this respect floater's mAutoFocus value, instead of
 	// using parameter
 	if (child->getHost())
@@ -2320,15 +2396,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 		// this floater is hosted elsewhere and hence not one of our children, abort
 		return;
 	}
-	std::vector<LLView*> floaters_to_move;
+	std::vector<LLFloater*> floaters_to_move;
 	// Look at all floaters...tab
-	for ( child_list_const_iter_t child_it = getChildList()->begin(); child_it != getChildList()->end(); ++child_it)
+	for (child_list_const_iter_t child_it = beginChild(); child_it != endChild(); ++child_it)
 	{
-		LLView* viewp = *child_it;
-		LLFloater *floater = (LLFloater *)viewp;
+		LLFloater* floater = dynamic_cast<LLFloater*>(*child_it);
 
 		// ...but if I'm a dependent floater...
-		if (child->isDependent())
+		if (floater && child->isDependent())
 		{
 			// ...look for floaters that have me as a dependent...
 			LLFloater::handle_set_iter_t found_dependent = floater->mDependents.find(child->getHandle());
@@ -2336,15 +2411,14 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 			if (found_dependent != floater->mDependents.end())
 			{
 				// ...and make sure all children of that floater (including me) are brought to front...
-				for(LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
-					dependent_it != floater->mDependents.end(); )
+				for (LLFloater::handle_set_iter_t dependent_it = floater->mDependents.begin();
+					dependent_it != floater->mDependents.end(); ++dependent_it)
 				{
 					LLFloater* sibling = dependent_it->get();
 					if (sibling)
 					{
 						floaters_to_move.push_back(sibling);
 					}
-					++dependent_it;
 				}
 				//...before bringing my parent to the front...
 				floaters_to_move.push_back(floater);
@@ -2352,10 +2426,10 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 		}
 	}
 
-	std::vector<LLView*>::iterator view_it;
-	for(view_it = floaters_to_move.begin(); view_it != floaters_to_move.end(); ++view_it)
+	std::vector<LLFloater*>::iterator floater_it;
+	for(floater_it = floaters_to_move.begin(); floater_it != floaters_to_move.end(); ++floater_it)
 	{
-		LLFloater* floaterp = (LLFloater*)(*view_it);
+		LLFloater* floaterp = *floater_it;
 		sendChildToFront(floaterp);
 
 		// always unminimize dependee, but allow dependents to stay minimized
@@ -2367,23 +2441,19 @@ void LLFloaterView::bringToFront(LLFloater* child, BOOL give_focus)
 	floaters_to_move.clear();
 
 	// ...then bringing my own dependents to the front...
-	for(LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
-		dependent_it != child->mDependents.end(); )
+	for (LLFloater::handle_set_iter_t dependent_it = child->mDependents.begin();
+		dependent_it != child->mDependents.end(); ++dependent_it)
 	{
 		LLFloater* dependent = dependent_it->get();
 		if (dependent)
 		{
 			sendChildToFront(dependent);
-			//don't un-minimize dependent windows automatically
-			// respect user's wishes
-			//dependent->setMinimized(FALSE);
 		}
-		++dependent_it;
 	}
 
 	// ...and finally bringing myself to front 
 	// (do this last, so that I'm left in front at end of this call)
-	if( *getChildList()->begin() != child ) 
+	if (*beginChild() != child)
 	{
 		sendChildToFront(child);
 	}
@@ -2923,21 +2993,14 @@ void LLFloaterView::popVisibleAll(const skip_list_t& skip_list)
 
 void LLFloater::setInstanceName(const std::string& name)
 {
-	if (name == mInstanceName)
-		return;
+	if (name != mInstanceName)
+	{
 	llassert_always(mInstanceName.empty());
 	mInstanceName = name;
 	if (!mInstanceName.empty())
 	{
 		std::string ctrl_name = getControlName(mInstanceName, mKey);
-
-		// save_rect and save_visibility only apply to registered floaters
-		if (mSaveRect)
-		{
-			mRectControl = LLFloaterReg::declareRectControl(ctrl_name);
-			mPosXControl = LLFloaterReg::declarePosXControl(ctrl_name);
-			mPosYControl = LLFloaterReg::declarePosYControl(ctrl_name);
-		}
+			initRectControl();
 		if (!mVisibilityControl.empty())
 		{
 			mVisibilityControl = LLFloaterReg::declareVisibilityControl(ctrl_name);
@@ -2948,6 +3011,7 @@ void LLFloater::setInstanceName(const std::string& name)
 		}
 	}
 }
+}
 
 void LLFloater::setKey(const LLSD& newkey)
 {
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index aef63bcf93633b7ddbfd31700674a9ba258fee4a..4dba1e645f5bdcf3d6319180c24efa89879c8170 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -217,13 +217,17 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	/*virtual*/ void setFocus( BOOL b );
 	/*virtual*/ void setIsChrome(BOOL is_chrome);
 	/*virtual*/ void setRect(const LLRect &rect);
+                void setIsSingleInstance(BOOL is_single_instance);
 
 	void 			initFloater(const Params& p);
 
 	void			openFloater(const LLSD& key = LLSD());
 
 	// If allowed, close the floater cleanly, releasing focus.
-	void			closeFloater(bool app_quitting = false);
+	virtual void	closeFloater(bool app_quitting = false);
+
+	// Close the floater or its host. Use when hidding or toggling a floater instance.
+	virtual void	closeHostedFloater();
 
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 	
@@ -301,6 +305,7 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	/*virtual*/ void handleVisibilityChange ( BOOL new_visibility ); // do not override
 	
 	void			setFrontmost(BOOL take_focus = TRUE);
+    virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());    
 	
 	// Defaults to false.
 	virtual BOOL	canSaveAs() const { return FALSE; }
@@ -324,6 +329,8 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	virtual void    setDocked(bool docked, bool pop_on_undock = true);
 
 	virtual void    setTornOff(bool torn_off) { mTornOff = torn_off; }
+	bool isTornOff() {return mTornOff;}
+	void setOpenPositioning(LLFloaterEnums::EOpenPositioning pos) {mPositioning = pos;}
 
 
 	// Close the floater returned by getFrontmostClosableFloater() and 
@@ -354,6 +361,7 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 
 	void			stackWith(LLFloater& other);
 
+	virtual void    initRectControl();
 	virtual bool	applyRectControl();
 	bool			applyDockState();
 	void			applyPositioning(LLFloater* other, bool on_open);
@@ -367,7 +375,6 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	void		 	setInstanceName(const std::string& name);
 	
 	virtual void	bringToFront(S32 x, S32 y);
-	virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE);    
 	
 	void			setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
 	const LLRect&	getExpandedRect() const { return mExpandedRect; }
@@ -441,9 +448,10 @@ class LLFloater : public LLPanel, public LLInstanceTracker<LLFloater>
 	LLUIString		mTitle;
 	LLUIString		mShortTitle;
 	
-	BOOL			mSingleInstance;	// TRUE if there is only ever one instance of the floater
-	bool			mReuseInstance;		// true if we want to hide the floater when we close it instead of destroying it
-	std::string		mInstanceName;		// Store the instance name so we can remove ourselves from the list
+	BOOL			mSingleInstance;	  // TRUE if there is only ever one instance of the floater
+	bool			mReuseInstance;		  // true if we want to hide the floater when we close it instead of destroying it
+    bool            mIsReuseInitialized;  // true if mReuseInstance already set from parameters
+	std::string		mInstanceName;		  // Store the instance name so we can remove ourselves from the list
 	
 	BOOL			mCanTearOff;
 	BOOL			mCanMinimize;
@@ -570,6 +578,7 @@ class LLFloaterView : public LLUICtrl
 	S32				mMinimizePositionVOffset;
 	typedef std::vector<std::pair<LLHandle<LLFloater>, boost::signals2::connection> > hidden_floaters_t;
 	hidden_floaters_t mHiddenFloaters;
+	LLFloater *		mFrontChild;
 };
 
 //
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 306caf2b91be82137fa44d6589cae5dbbe754d4a..1cdddf0d5b93e830eabc4776cabcfb26bf3dd6e0 100644
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -264,17 +264,9 @@ bool LLFloaterReg::hideInstance(const std::string& name, const LLSD& key)
 	LLFloater* instance = findInstance(name, key); 
 	if (instance)
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
-		return true;
-	}
-	else
-	{
-		return false;
+		instance->closeHostedFloater();
 	}
+	return (instance != NULL);
 }
 
 //static
@@ -284,11 +276,7 @@ bool LLFloaterReg::toggleInstance(const std::string& name, const LLSD& key)
 	LLFloater* instance = findInstance(name, key); 
 	if (LLFloater::isShown(instance))
 	{
-		// When toggling *visibility*, close the host instead of the floater when hosted
-		if (instance->getHost())
-			instance->getHost()->closeFloater();
-		else
-			instance->closeFloater();
+		instance->closeHostedFloater();
 		return false;
 	}
 	else
@@ -481,31 +469,58 @@ void LLFloaterReg::toggleInstanceOrBringToFront(const LLSD& sdname, const LLSD&
 	//       * Also, if it is not on top, bring it forward when focus is given.
 	// * Else the target floater is open, close it.
 	// 
-
 	std::string name = sdname.asString();
 	LLFloater* instance = getInstance(name, key); 
+	
 
 	if (!instance)
 	{
 		lldebugs << "Unable to get instance of floater '" << name << "'" << llendl;
+		return;
 	}
-	else if (instance->isMinimized())
+	
+	// If hosted, we need to take that into account
+	LLFloater* host = instance->getHost();
+	
+	if (host)
 	{
-		instance->setMinimized(FALSE);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isShown())
-	{
-		instance->openFloater(key);
-		instance->setVisibleAndFrontmost();
-	}
-	else if (!instance->isFrontmost())
-	{
-		instance->setVisibleAndFrontmost();
+		if (host->isMinimized() || !host->isShown() || !host->isFrontmost())
+		{
+			host->setMinimized(FALSE);
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost(true, key);
+		}
+		else if (!instance->getVisible())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost(true, key);
+			instance->setFocus(TRUE);
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 	else
 	{
-		instance->closeFloater();
+		if (instance->isMinimized())
+		{
+			instance->setMinimized(FALSE);
+			instance->setVisibleAndFrontmost(true, key);
+		}
+		else if (!instance->isShown())
+		{
+			instance->openFloater(key);
+			instance->setVisibleAndFrontmost(true, key);
+		}
+		else if (!instance->isFrontmost())
+		{
+			instance->setVisibleAndFrontmost(true, key);
+		}
+		else
+		{
+			instance->closeHostedFloater();
+		}
 	}
 }
 
diff --git a/indra/newview/llfolderview.cpp b/indra/llui/llfolderview.cpp
similarity index 62%
rename from indra/newview/llfolderview.cpp
rename to indra/llui/llfolderview.cpp
index 8e540a0cc83f17cdcd3b2a79f63937469dbe7ebe..8aa1eb7cd59b68196cd660c169914ce8b3f30a47 100644
--- a/indra/newview/llfolderview.cpp
+++ b/indra/llui/llfolderview.cpp
@@ -24,39 +24,20 @@
  * $/LicenseInfo$
  */
 
-#include "llviewerprecompiledheaders.h"
+#include "linden_common.h"
 
 #include "llfolderview.h"
-
-#include "llcallbacklist.h"
-#include "llinventorybridge.h"
+#include "llfolderviewmodel.h"
 #include "llclipboard.h" // *TODO: remove this once hack below gone.
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llinventorypanel.h"
-#include "llfoldertype.h"
-#include "llfloaterinventory.h"// hacked in for the bonus context menu items.
 #include "llkeyboard.h"
 #include "lllineeditor.h"
 #include "llmenugl.h"
 #include "llpanel.h"
-#include "llpreview.h"
 #include "llscrollcontainer.h" // hack to allow scrolling
-#include "lltooldraganddrop.h"
+#include "lltextbox.h"
 #include "lltrans.h"
 #include "llui.h"
-#include "llviewertexture.h"
-#include "llviewertexturelist.h"
-#include "llviewerjointattachment.h"
-#include "llviewermenu.h"
 #include "lluictrlfactory.h"
-#include "llviewercontrol.h"
-#include "llviewerfoldertype.h"
-#include "llviewerwindow.h"
-#include "llvoavatar.h"
-#include "llfloaterproperties.h"
-#include "llnotificationsutil.h"
 
 // Linden library includes
 #include "lldbstrings.h"
@@ -64,7 +45,6 @@
 #include "llfontgl.h"
 #include "llgl.h" 
 #include "llrender.h"
-#include "llinventory.h"
 
 // Third-party library includes
 #include <algorithm>
@@ -76,11 +56,7 @@
 const S32 RENAME_WIDTH_PAD = 4;
 const S32 RENAME_HEIGHT_PAD = 1;
 const S32 AUTO_OPEN_STACK_DEPTH = 16;
-const S32 MIN_ITEM_WIDTH_VISIBLE = LLFolderViewItem::ICON_WIDTH
-			+ LLFolderViewItem::ICON_PAD 
-			+ LLFolderViewItem::ARROW_SIZE 
-			+ LLFolderViewItem::TEXT_PAD 
-			+ /*first few characters*/ 40;
+
 const S32 MINIMUM_RENAMER_WIDTH = 80;
 
 // *TODO: move in params in xml if necessary. Requires modification of LLFolderView & LLInventoryPanel Params.
@@ -94,42 +70,6 @@ enum {
 
 F32 LLFolderView::sAutoOpenTime = 1.f;
 
-void delete_selected_item(void* user_data);
-void copy_selected_item(void* user_data);
-void open_selected_items(void* user_data);
-void properties_selected_items(void* user_data);
-void paste_items(void* user_data);
-
-
-//---------------------------------------------------------------------------
-
-// Tells all folders in a folderview to sort their items
-// (and only their items, not folders) by a certain function.
-class LLSetItemSortFunction : public LLFolderViewFunctor
-{
-public:
-	LLSetItemSortFunction(U32 ordering)
-		: mSortOrder(ordering) {}
-	virtual ~LLSetItemSortFunction() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-
-	U32 mSortOrder;
-};
-
-
-// Set the sort order.
-void LLSetItemSortFunction::doFolder(LLFolderViewFolder* folder)
-{
-	folder->setItemSortOrder(mSortOrder);
-}
-
-// Do nothing.
-void LLSetItemSortFunction::doItem(LLFolderViewItem* item)
-{
-	return;
-}
-
 //---------------------------------------------------------------------------
 
 // Tells all folders in a folderview to close themselves
@@ -154,7 +94,6 @@ class LLCloseAllFoldersFunctor : public LLFolderViewFunctor
 };
 
 
-// Set the sort order.
 void LLCloseAllFoldersFunctor::doFolder(LLFolderViewFolder* folder)
 {
 	folder->setOpenArrangeRecursively(mOpen);
@@ -177,7 +116,7 @@ const LLRect LLFolderViewScrollContainer::getScrolledViewRect() const
 		LLFolderView* folder_view = dynamic_cast<LLFolderView*>(mScrolledView);
 		if (folder_view)
 		{
-			S32 height = folder_view->mRunningHeight;
+			S32 height = folder_view->getRect().getHeight();
 
 			rect = mScrolledView->getRect();
 			rect.setLeftTopAndSize(rect.mLeft, rect.mTop, rect.getWidth(), height);
@@ -195,27 +134,25 @@ LLFolderViewScrollContainer::LLFolderViewScrollContainer(const LLScrollContainer
 /// Class LLFolderView
 ///----------------------------------------------------------------------------
 LLFolderView::Params::Params()
-:	task_id("task_id"),
-	title("title"),
+:	title("title"),
 	use_label_suffix("use_label_suffix"),
 	allow_multiselect("allow_multiselect", true),
 	show_empty_message("show_empty_message", true),
-	show_load_status("show_load_status", true),
-	use_ellipses("use_ellipses", false)
+	use_ellipses("use_ellipses", false),
+    options_menu("options_menu", "")
 {
+	folder_indentation = -4;
 }
 
 
 // Default constructor
 LLFolderView::LLFolderView(const Params& p)
 :	LLFolderViewFolder(p),
-	mRunningHeight(0),
 	mScrollContainer( NULL ),
 	mPopupMenuHandle(),
 	mAllowMultiSelect(p.allow_multiselect),
 	mShowEmptyMessage(p.show_empty_message),
 	mShowFolderHierarchy(FALSE),
-	mSourceID(p.task_id),
 	mRenameItem( NULL ),
 	mNeedsScroll( FALSE ),
 	mUseLabelSuffix(p.use_label_suffix),
@@ -223,9 +160,6 @@ LLFolderView::LLFolderView(const Params& p)
 	mNeedsAutoSelect( FALSE ),
 	mAutoSelectOverride(FALSE),
 	mNeedsAutoRename(FALSE),
-	mDebugFilters(FALSE),
-	mSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME),	// This gets overridden by a pref immediately
-	mFilter( new LLInventoryFilter(p.title) ),
 	mShowSelectionContext(FALSE),
 	mShowSingleSelection(FALSE),
 	mArrangeGeneration(0),
@@ -236,33 +170,28 @@ LLFolderView::LLFolderView(const Params& p)
 	mParentPanel(p.parent_panel),
 	mUseEllipses(p.use_ellipses),
 	mDraggingOverItem(NULL),
-	mStatusTextBox(NULL)
+	mStatusTextBox(NULL),
+	mShowItemLinkOverlays(p.show_item_link_overlays),
+	mViewModel(p.view_model)
 {
+	mViewModel->setFolderView(this);
 	mRoot = this;
 
-	mShowLoadStatus = p.show_load_status();
-
 	LLRect rect = p.rect;
 	LLRect new_rect(rect.mLeft, rect.mBottom + getRect().getHeight(), rect.mLeft + getRect().getWidth(), rect.mBottom);
 	setRect( rect );
 	reshape(rect.getWidth(), rect.getHeight());
-	mIsOpen = TRUE; // this view is always open.
 	mAutoOpenItems.setDepth(AUTO_OPEN_STACK_DEPTH);
 	mAutoOpenCandidate = NULL;
 	mAutoOpenTimer.stop();
 	mKeyboardSelection = FALSE;
-	const LLFolderViewItem::Params& item_params =
-		LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	S32 indentation = item_params.folder_indentation();
-	mIndentation = -indentation; // children start at indentation 0
-	gIdleCallbacks.addFunction(idle, this);
+	mIndentation = p.folder_indentation;
 
 	//clear label
 	// go ahead and render root folder as usual
 	// just make sure the label ("Inventory Folder") never shows up
 	mLabel = LLStringUtil::null;
 
-	//mRenamer->setWriteableBgColor(LLColor4::white);
 	// Escape is handled by reverting the rename, not commiting it (default behavior)
 	LLLineEditor::Params params;
 	params.name("ren");
@@ -279,10 +208,11 @@ LLFolderView::LLFolderView(const Params& p)
 	// Textbox
 	LLTextBox::Params text_p;
 	LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-	LLRect new_r = LLRect(rect.mLeft + ICON_PAD,
-			      rect.mTop - TEXT_PAD,
+    //mIconPad, mTextPad are set in folder_view_item.xml
+	LLRect new_r = LLRect(rect.mLeft + mIconPad,
+			      rect.mTop - mTextPad,
 			      rect.mRight,
-			      rect.mTop - TEXT_PAD - font->getLineHeight());
+			      rect.mTop - mTextPad - font->getLineHeight());
 	text_p.rect(new_r);
 	text_p.name(std::string(p.name));
 	text_p.font(font);
@@ -299,7 +229,7 @@ LLFolderView::LLFolderView(const Params& p)
 
 
 	// make the popup menu available
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_inventory.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
+	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>(p.options_menu, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
 	if (!menu)
 	{
 		menu = LLUICtrlFactory::getDefaultWidget<LLMenuGL>("inventory_menu");
@@ -307,7 +237,7 @@ LLFolderView::LLFolderView(const Params& p)
 	menu->setBackgroundColor(LLUIColorTable::instance().getColor("MenuPopupBgColor"));
 	mPopupMenuHandle = menu->getHandle();
 
-	mListener->openItem();
+	mViewModelItem->openItem();
 }
 
 // Destroys the object
@@ -326,7 +256,6 @@ LLFolderView::~LLFolderView( void )
 	mStatusTextBox = NULL;
 
 	mAutoOpenItems.removeAllNodes();
-	gIdleCallbacks.deleteFunction(idle, this);
 
 	if (mPopupMenuHandle.get()) mPopupMenuHandle.get()->die();
 
@@ -335,10 +264,7 @@ LLFolderView::~LLFolderView( void )
 	mItems.clear();
 	mFolders.clear();
 
-	mItemMap.clear();
-
-	delete mFilter;
-	mFilter = NULL;
+	mViewModel = NULL;
 }
 
 BOOL LLFolderView::canFocusChildren() const
@@ -346,46 +272,9 @@ BOOL LLFolderView::canFocusChildren() const
 	return FALSE;
 }
 
-static LLFastTimer::DeclareTimer FTM_SORT("Sort Inventory");
-
-void LLFolderView::setSortOrder(U32 order)
-{
-	if (order != mSortOrder)
-	{
-		LLFastTimer t(FTM_SORT);
-		
-		mSortOrder = order;
-
-		sortBy(order);
-		arrangeAll();
-	}
-}
-
-
-U32 LLFolderView::getSortOrder() const
+void LLFolderView::addFolder( LLFolderViewFolder* folder)
 {
-	return mSortOrder;
-}
-
-BOOL LLFolderView::addFolder( LLFolderViewFolder* folder)
-{
-	// enforce sort order of My Inventory followed by Library
-	if (folder->getListener()->getUUID() == gInventory.getLibraryRootFolderID())
-	{
-		mFolders.push_back(folder);
-	}
-	else
-	{
-		mFolders.insert(mFolders.begin(), folder);
-	}
-	folder->setShowLoadStatus(mShowLoadStatus);
-	folder->setOrigin(0, 0);
-	folder->reshape(getRect().getWidth(), 0);
-	folder->setVisible(FALSE);
-	addChild( folder );
-	folder->dirtyFilter();
-	folder->requestArrange();
-	return TRUE;
+	LLFolderViewFolder::addFolder(folder);
 }
 
 void LLFolderView::closeAllFolders()
@@ -405,145 +294,39 @@ void LLFolderView::openTopLevelFolders()
 	}
 }
 
-void LLFolderView::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
-	// call base class to do proper recursion
-	LLFolderViewFolder::setOpenArrangeRecursively(openitem, recurse);
-	// make sure root folder is always open
-	mIsOpen = TRUE;
-}
-
-static LLFastTimer::DeclareTimer FTM_ARRANGE("Arrange");
-
 // This view grows and shrinks to enclose all of its children items and folders.
-S32 LLFolderView::arrange( S32* unused_width, S32* unused_height, S32 filter_generation )
-{
-	if (getListener()->getUUID().notNull())
+// *width should be 0
+// conform show folder state works
+S32 LLFolderView::arrange( S32* unused_width, S32* unused_height )
 	{
-		if (mNeedsSort)
-		{
-			mFolders.sort(mSortFunction);
-			mItems.sort(mSortFunction);
-			mNeedsSort = false;
-		}
-	}
-
-	LLFastTimer t2(FTM_ARRANGE);
-
-	filter_generation = mFilter->getMinRequiredGeneration();
 	mMinWidth = 0;
+	S32 target_height;
 
-	mHasVisibleChildren = hasFilteredDescendants(filter_generation);
-	// arrange always finishes, so optimistically set the arrange generation to the most current
-	mLastArrangeGeneration = getRoot()->getArrangeGeneration();
+	LLFolderViewFolder::arrange(&mMinWidth, &target_height);
 
-	LLInventoryFilter::EFolderShow show_folder_state =
-		getRoot()->getFilter()->getShowFolderState();
+	LLRect scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
+	reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 
-	S32 total_width = LEFT_PAD;
-	S32 running_height = mDebugFilters ? LLFontGL::getFontMonospace()->getLineHeight() : 0;
-	S32 target_height = running_height;
-	S32 parent_item_height = getRect().getHeight();
-
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		LLFolderViewFolder* folderp = (*fit);
-		if (getDebugFilters())
-		{
-			folderp->setVisible(TRUE);
-		}
-		else
-		{
-			folderp->setVisible((show_folder_state == LLInventoryFilter::SHOW_ALL_FOLDERS || // always show folders?
-								 (folderp->getFiltered(filter_generation) || folderp->hasFilteredDescendants(filter_generation))));
-		}
-
-		if (folderp->getVisible())
-		{
-			S32 child_height = 0;
-			S32 child_width = 0;
-			S32 child_top = parent_item_height - running_height;
-			
-			target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
-			mMinWidth = llmax(mMinWidth, child_width);
-			total_width = llmax( total_width, child_width );
-			running_height += child_height;
-			folderp->setOrigin( ICON_PAD, child_top - (*fit)->getRect().getHeight() );
-		}
-	}
-
-	for (items_t::iterator iter = mItems.begin();
-		 iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		LLFolderViewItem* itemp = (*iit);
-		itemp->setVisible(itemp->getFiltered(filter_generation));
-
-		if (itemp->getVisible())
-		{
-			S32 child_width = 0;
-			S32 child_height = 0;
-			S32 child_top = parent_item_height - running_height;
-			
-			target_height += itemp->arrange( &child_width, &child_height, filter_generation );
-			itemp->reshape(itemp->getRect().getWidth(), child_height);
-
-			mMinWidth = llmax(mMinWidth, child_width);
-			total_width = llmax( total_width, child_width );
-			running_height += child_height;
-			itemp->setOrigin( ICON_PAD, child_top - itemp->getRect().getHeight() );
-		}
-	}
-
-	if(!mHasVisibleChildren)// is there any filtered items ?
-	{
-		//Nope. We need to display status textbox, let's reserve some place for it
-		running_height = mStatusTextBox->getTextPixelHeight();
-		target_height = running_height;
-	}
-
-	mRunningHeight = running_height;
-	LLRect scroll_rect = mScrollContainer->getContentWindowRect();
-	reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
-
-	LLRect new_scroll_rect = mScrollContainer->getContentWindowRect();
+	LLRect new_scroll_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	if (new_scroll_rect.getWidth() != scroll_rect.getWidth())
 	{
-		reshape( llmax(scroll_rect.getWidth(), total_width), running_height );
+		reshape( llmax(scroll_rect.getWidth(), mMinWidth), llround(mCurHeight) );
 	}
 
 	// move item renamer text field to item's new position
 	updateRenamerPosition();
 
-	mTargetHeight = (F32)target_height;
 	return llround(mTargetHeight);
 }
 
-const std::string LLFolderView::getFilterSubString(BOOL trim)
-{
-	return mFilter->getFilterSubString(trim);
-}
+static LLFastTimer::DeclareTimer FTM_FILTER("Filter Folder View");
 
-static LLFastTimer::DeclareTimer FTM_FILTER("Filter Inventory");
-
-void LLFolderView::filter( LLInventoryFilter& filter )
+void LLFolderView::filter( LLFolderViewFilter& filter )
 {
 	LLFastTimer t2(FTM_FILTER);
-	filter.setFilterCount(llclamp(gSavedSettings.getS32("FilterItemsPerFrame"), 1, 5000));
+	filter.setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
 
-	if (getCompletedFilterGeneration() < filter.getCurrentGeneration())
-	{
-		mPassedFilter = FALSE;
-		mMinWidth = 0;
-		LLFolderViewFolder::filter(filter);
-	}
-	else
-	{
-		mPassedFilter = TRUE;
-	}
+	getViewModelItem()->filter(filter);
 }
 
 void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
@@ -555,7 +338,7 @@ void LLFolderView::reshape(S32 width, S32 height, BOOL called_from_parent)
 		scroll_rect = mScrollContainer->getContentWindowRect();
 	}
 	width  = llmax(mMinWidth, scroll_rect.getWidth());
-	height = llmax(mRunningHeight, scroll_rect.getHeight());
+	height = llmax(llround(mCurHeight), scroll_rect.getHeight());
 
 	// Restrict width within scroll container's width
 	if (mUseEllipses && mScrollContainer)
@@ -616,6 +399,10 @@ LLFolderViewItem* LLFolderView::getCurSelectedItem( void )
 	return NULL;
 }
 
+LLFolderView::selected_items_t& LLFolderView::getSelectedItems( void )
+{
+    return mSelectedItems;
+}
 
 // Record the selected item and pass it down the hierachy.
 BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
@@ -653,30 +440,6 @@ BOOL LLFolderView::setSelection(LLFolderViewItem* selection, BOOL openitem,
 	return rv;
 }
 
-void LLFolderView::setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus)
-{
-	LLFolderViewItem* itemp = getItemByID(obj_id);
-	if(itemp && itemp->getListener())
-	{
-		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
-		mSelectThisID.setNull();
-		return;
-	}
-	else
-	{
-		// save the desired item to be selected later (if/when ready)
-		mSelectThisID = obj_id;
-	}
-}
-
-void LLFolderView::updateSelection()
-{
-	if (mSelectThisID.notNull())
-	{
-		setSelectionByID(mSelectThisID, false);
-	}
-}
-
 BOOL LLFolderView::changeSelection(LLFolderViewItem* selection, BOOL selected)
 {
 	BOOL rv = FALSE;
@@ -727,9 +490,6 @@ void LLFolderView::sanitizeSelection()
 	// and we want to preserve context
 	LLFolderViewItem* original_selected_item = getCurSelectedItem();
 
-	// Cache "Show all folders" filter setting
-	BOOL show_all_folders = (getRoot()->getFilter()->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS);
-
 	std::vector<LLFolderViewItem*> items_to_remove;
 	selected_items_t::iterator item_iter;
 	for (item_iter = mSelectedItems.begin(); item_iter != mSelectedItems.end(); ++item_iter)
@@ -737,24 +497,19 @@ void LLFolderView::sanitizeSelection()
 		LLFolderViewItem* item = *item_iter;
 
 		// ensure that each ancestor is open and potentially passes filtering
-		BOOL visible = item->potentiallyVisible(); // initialize from filter state for this item
+		BOOL visible = false;
+		if(item->getViewModelItem() != NULL)
+		{
+			visible = item->getViewModelItem()->potentiallyVisible(); // initialize from filter state for this item
+		}
 		// modify with parent open and filters states
 		LLFolderViewFolder* parent_folder = item->getParentFolder();
-		if ( parent_folder )
-		{
-			if ( show_all_folders )
-			{	// "Show all folders" is on, so this folder is visible
-				visible = TRUE;
-			}
-			else
-			{	// Move up through parent folders and see what's visible
+		// Move up through parent folders and see what's visible
 				while(parent_folder)
 				{
-					visible = visible && parent_folder->isOpen() && parent_folder->potentiallyVisible();
+			visible = visible && parent_folder->isOpen() && parent_folder->getViewModelItem()->potentiallyVisible();
 					parent_folder = parent_folder->getParentFolder();
 				}
-			}
-		}
 
 		//  deselect item if any ancestor is closed or didn't pass filter requirements.
 		if (!visible)
@@ -804,7 +559,7 @@ void LLFolderView::sanitizeSelection()
 				parent_folder;
 				parent_folder = parent_folder->getParentFolder())
 			{
-				if (parent_folder->potentiallyVisible())
+				if (parent_folder->getViewModelItem() && parent_folder->getViewModelItem()->potentiallyVisible())
 				{
 					// give initial selection to first ancestor folder that potentially passes the filter
 					if (!new_selection)
@@ -843,42 +598,30 @@ void LLFolderView::clearSelection()
 	}
 
 	mSelectedItems.clear();
-	mSelectThisID.setNull();
 }
 
-std::set<LLUUID> LLFolderView::getSelectionList() const
+std::set<LLFolderViewItem*> LLFolderView::getSelectionList() const
 {
-	std::set<LLUUID> selection;
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); 
-		 item_it != mSelectedItems.end(); 
-		 ++item_it)
-	{
-		selection.insert((*item_it)->getListener()->getUUID());
-	}
+	std::set<LLFolderViewItem*> selection;
+	std::copy(mSelectedItems.begin(), mSelectedItems.end(), std::inserter(selection, selection.begin()));
 	return selection;
 }
 
-BOOL LLFolderView::startDrag(LLToolDragAndDrop::ESource source)
+bool LLFolderView::startDrag()
 {
-	std::vector<EDragAndDropType> types;
-	uuid_vec_t cargo_ids;
+	std::vector<LLFolderViewModelItem*> selected_items;
 	selected_items_t::iterator item_it;
-	BOOL can_drag = TRUE;
+
 	if (!mSelectedItems.empty())
 	{
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
-			EDragAndDropType type = DAD_NONE;
-			LLUUID id = LLUUID::null;
-			can_drag = can_drag && (*item_it)->getListener()->startDrag(&type, &id);
-
-			types.push_back(type);
-			cargo_ids.push_back(id);
+			selected_items.push_back((*item_it)->getViewModelItem());
 		}
 
-		LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, source, mSourceID); 
+		return getFolderViewModel()->startDrag(selected_items);
 	}
-	return can_drag;
+	return false;
 }
 
 void LLFolderView::commitRename( const LLSD& data )
@@ -888,16 +631,6 @@ void LLFolderView::commitRename( const LLSD& data )
 
 void LLFolderView::draw()
 {
-	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", LLColor4::white);
-	if (mDebugFilters)
-	{
-		std::string current_filter_string = llformat("Current Filter: %d, Least Filter: %d, Auto-accept Filter: %d",
-										mFilter->getCurrentGeneration(), mFilter->getMinRequiredGeneration(), mFilter->getMustPassGeneration());
-		LLFontGL::getFontMonospace()->renderUTF8(current_filter_string, 0, 2, 
-			getRect().getHeight() - LLFontGL::getFontMonospace()->getLineHeight(), LLColor4(0.5f, 0.5f, 0.8f, 1.f), 
-			LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, S32_MAX, S32_MAX, NULL, FALSE );
-	}
-
 	//LLFontGL* font = getLabelFontForStyle(mLabelStyle);
 
 	// if cursor has moved off of me during drag and drop
@@ -907,52 +640,18 @@ void LLFolderView::draw()
 		closeAutoOpenedFolders();
 	}
 
-	// while dragging, update selection rendering to reflect single/multi drag status
-	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
-	{
-		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
-		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
-		{
-			setShowSingleSelection(TRUE);
-		}
-		else
-		{
-			setShowSingleSelection(FALSE);
-		}
-	}
-	else
-	{
-		setShowSingleSelection(FALSE);
-	}
-
-
-	if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout") || !mSearchString.size())
+	if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout") || !mSearchString.size())
 	{
 		mSearchString.clear();
 	}
 
-	if (hasVisibleChildren()
-		|| mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS)
+	if (hasVisibleChildren())
 	{
-		mStatusText.clear();
 		mStatusTextBox->setVisible( FALSE );
 	}
 	else if (mShowEmptyMessage)
 	{
-		if (LLInventoryModelBackgroundFetch::instance().folderFetchActive() || mCompletedFilterGeneration < mFilter->getMinRequiredGeneration())
-		{
-			mStatusText = LLTrans::getString("Searching");
-		}
-		else
-		{
-			if (getFilter())
-			{
-				LLStringUtil::format_map_t args;
-				args["[SEARCH_TERM]"] = LLURI::escape(getFilter()->getFilterSubStringOrig());
-				mStatusText = LLTrans::getString(getFilter()->getEmptyLookupMessage(), args);
-			}
-		}
-		mStatusTextBox->setValue(mStatusText);
+		mStatusTextBox->setValue(getFolderViewModel()->getStatusText());
 		mStatusTextBox->setVisible( TRUE );
 		
 		// firstly reshape message textbox with current size. This is necessary to
@@ -969,7 +668,11 @@ void LLFolderView::draw()
 			// This will indirectly call ::arrange and reshape of the status textbox.
 			// We should call this method to also notify parent about required rect.
 			// See EXT-7564, EXT-7047.
-			arrangeFromRoot();
+			S32 height = 0;
+			S32 width = 0;
+			S32 total_height = arrange( &width, &height );
+			notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+
 			LLUI::popMatrix();
 			LLUI::pushMatrix();
 			LLUI::translate((F32)getRect().mLeft, (F32)getRect().mBottom);
@@ -996,7 +699,7 @@ void LLFolderView::finishRenamingItem( void )
 
 	closeRenamer();
 
-	// List is re-sorted alphabeticly, so scroll to make sure the selected item is visible.
+	// List is re-sorted alphabetically, so scroll to make sure the selected item is visible.
 	scrollToShowSelection();
 }
 
@@ -1005,68 +708,12 @@ void LLFolderView::closeRenamer( void )
 	if (mRenamer && mRenamer->getVisible())
 	{
 		// Triggers onRenamerLost() that actually closes the renamer.
-		gViewerWindow->removePopup(mRenamer);
+		LLUI::removePopup(mRenamer);
 	}
 }
 
-void LLFolderView::removeSelectedItems( void )
+void LLFolderView::removeSelectedItems()
 {
-	if (mSelectedItems.empty()) return;
-	LLSD args;
-	args["QUESTION"] = LLTrans::getString(mSelectedItems.size() > 1 ? "DeleteItems" :  "DeleteItem");
-	LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLFolderView::onItemsRemovalConfirmation, this, _1, _2));
-}
-
-bool isDescendantOfASelectedItem(LLFolderViewItem* item, const std::vector<LLFolderViewItem*>& selectedItems)
-{
-	LLFolderViewItem* item_parent = dynamic_cast<LLFolderViewItem*>(item->getParent());
-
-	if (item_parent)
-	{
-		for(std::vector<LLFolderViewItem*>::const_iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
-		{
-			const LLFolderViewItem* const selected_item = (*it);
-
-			LLFolderViewItem* parent = item_parent;
-
-			while (parent)
-			{
-				if (selected_item == parent)
-				{
-					return true;
-				}
-
-				parent = dynamic_cast<LLFolderViewItem*>(parent->getParent());
-			}
-		}
-	}
-
-	return false;
-}
-
-// static
-void LLFolderView::removeCutItems()
-{
-	// There's no item in "cut" mode on the clipboard -> exit
-	if (!LLClipboard::instance().isCutMode())
-		return;
-
-	// Get the list of clipboard item uuids and iterate through them
-	LLDynamicArray<LLUUID> objects;
-	LLClipboard::instance().pasteFromClipboard(objects);
-	for (LLDynamicArray<LLUUID>::const_iterator iter = objects.begin();
-		 iter != objects.end();
-		 ++iter)
-	{
-		gInventory.removeObject(*iter);
-	}
-}
-
-void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	if (option != 0) return; // canceled
-
 	if(getVisible() && getEnabled())
 	{
 		// just in case we're removing the renaming item.
@@ -1097,68 +744,38 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 		// iterate through the new container.
 		count = items.size();
 		LLUUID new_selection_id;
+		LLFolderViewItem* item_to_select = getNextUnselectedItem();
+
 		if(count == 1)
 		{
 			LLFolderViewItem* item_to_delete = items[0];
 			LLFolderViewFolder* parent = item_to_delete->getParentFolder();
-			LLFolderViewItem* new_selection = item_to_delete->getNextOpenNode(FALSE);
-			if (!new_selection)
-			{
-				new_selection = item_to_delete->getPreviousOpenNode(FALSE);
-			}
 			if(parent)
 			{
-				if (parent->removeItem(item_to_delete))
+				if (item_to_delete->remove())
 				{
 					// change selection on successful delete
-					if (new_selection)
-					{
-						setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-					}
-					else
-					{
-						setSelectionFromRoot(NULL, mParentPanel->hasFocus());
-					}
+					setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 				}
 			}
 			arrangeAll();
 		}
 		else if (count > 1)
 		{
-			LLDynamicArray<LLFolderViewEventListener*> listeners;
-			LLFolderViewEventListener* listener;
-			LLFolderViewItem* last_item = items[count - 1];
-			LLFolderViewItem* new_selection = last_item->getNextOpenNode(FALSE);
-			while(new_selection && new_selection->isSelected())
-			{
-				new_selection = new_selection->getNextOpenNode(FALSE);
-			}
-			if (!new_selection)
-			{
-				new_selection = last_item->getPreviousOpenNode(FALSE);
-				while (new_selection && (new_selection->isSelected() || isDescendantOfASelectedItem(new_selection, items)))
-				{
-					new_selection = new_selection->getPreviousOpenNode(FALSE);
-				}
-			}
-			if (new_selection)
-			{
-				setSelectionFromRoot(new_selection, new_selection->isOpen(), mParentPanel->hasFocus());
-			}
-			else
-			{
-				setSelectionFromRoot(NULL, mParentPanel->hasFocus());
-			}
+			LLDynamicArray<LLFolderViewModelItem*> listeners;
+			LLFolderViewModelItem* listener;
+
+			setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 
 			for(S32 i = 0; i < count; ++i)
 			{
-				listener = items[i]->getListener();
-				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewEventListener*>::FAIL))
+				listener = items[i]->getViewModelItem();
+				if(listener && (listeners.find(listener) == LLDynamicArray<LLFolderViewModelItem*>::FAIL))
 				{
 					listeners.put(listener);
 				}
 			}
-			listener = listeners.get(0);
+			listener = static_cast<LLFolderViewModelItem*>(listeners.get(0));
 			if(listener)
 			{
 				listener->removeBatch(listeners);
@@ -1169,82 +786,6 @@ void LLFolderView::onItemsRemovalConfirmation(const LLSD& notification, const LL
 	}
 }
 
-// open the selected item.
-void LLFolderView::openSelectedItems( void )
-{
-	if(getVisible() && getEnabled())
-	{
-		if (mSelectedItems.size() == 1)
-		{
-			mSelectedItems.front()->openItem();
-		}
-		else
-		{
-			LLMultiPreview* multi_previewp = new LLMultiPreview();
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				// IT_{OBJECT,ATTACHMENT} creates LLProperties
-				// floaters; others create LLPreviews.  Put
-				// each one in the right type of container.
-				LLFolderViewEventListener* listener = (*item_it)->getListener();
-				bool is_prop = listener && (listener->getInventoryType() == LLInventoryType::IT_OBJECT || listener->getInventoryType() == LLInventoryType::IT_ATTACHMENT);
-				if (is_prop)
-					LLFloater::setFloaterHost(multi_propertiesp);
-				else
-					LLFloater::setFloaterHost(multi_previewp);
-				(*item_it)->openItem();
-			}
-
-			LLFloater::setFloaterHost(NULL);
-			// *NOTE: LLMulti* will safely auto-delete when open'd
-			// without any children.
-			multi_previewp->openFloater(LLSD());
-			multi_propertiesp->openFloater(LLSD());
-		}
-	}
-}
-
-void LLFolderView::propertiesSelectedItems( void )
-{
-	if(getVisible() && getEnabled())
-	{
-		if (mSelectedItems.size() == 1)
-		{
-			LLFolderViewItem* folder_item = mSelectedItems.front();
-			if(!folder_item) return;
-			folder_item->getListener()->showProperties();
-		}
-		else
-		{
-			LLMultiProperties* multi_propertiesp = new LLMultiProperties();
-
-			LLFloater::setFloaterHost(multi_propertiesp);
-
-			selected_items_t::iterator item_it;
-			for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-			{
-				(*item_it)->getListener()->showProperties();
-			}
-
-			LLFloater::setFloaterHost(NULL);
-			multi_propertiesp->openFloater(LLSD());
-		}
-	}
-}
-
-void LLFolderView::changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type)
-{
-	LLFolderBridge *folder_bridge = LLFolderBridge::sSelf.get();
-
-	if (!folder_bridge) return;
-	LLViewerInventoryCategory *cat = folder_bridge->getCategory();
-	if (!cat) return;
-	cat->changeType(new_folder_type);
-}
-
 void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 {
 	if ((mAutoOpenItems.check() == item) || 
@@ -1268,7 +809,7 @@ void LLFolderView::autoOpenItem( LLFolderViewFolder* item )
 	mAutoOpenItems.push(item);
 	
 	item->setOpen(TRUE);
-	LLRect content_rect = mScrollContainer->getContentWindowRect();
+	LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 	LLRect constraint_rect(0,content_rect.getHeight(), content_rect.getWidth(), 0);
 	scrollToShowItem(item, constraint_rect);
 }
@@ -1329,7 +870,7 @@ BOOL LLFolderView::canCopy() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		if (!item->getListener()->isItemCopyable())
+		if (!item->getViewModelItem()->isItemCopyable())
 		{
 			return FALSE;
 		}
@@ -1345,11 +886,11 @@ void LLFolderView::copy()
 	S32 count = mSelectedItems.size();
 	if(getVisible() && getEnabled() && (count > 0))
 	{
-		LLFolderViewEventListener* listener = NULL;
+		LLFolderViewModelItem* listener = NULL;
 		selected_items_t::iterator item_it;
 		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
 		{
-			listener = (*item_it)->getListener();
+			listener = (*item_it)->getViewModelItem();
 			if(listener)
 			{
 				listener->copyToClipboard();
@@ -1369,7 +910,7 @@ BOOL LLFolderView::canCut() const
 	for (selected_items_t::const_iterator selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 	{
 		const LLFolderViewItem* item = *selected_it;
-		const LLFolderViewEventListener* listener = item->getListener();
+		const LLFolderViewModelItem* listener = item->getViewModelItem();
 
 		if (!listener || !listener->isItemRemovable())
 		{
@@ -1383,20 +924,28 @@ void LLFolderView::cut()
 {
 	// clear the inventory clipboard
 	LLClipboard::instance().reset();
-	S32 count = mSelectedItems.size();
-	if(getVisible() && getEnabled() && (count > 0))
+	if(getVisible() && getEnabled() && (mSelectedItems.size() > 0))
 	{
-		LLFolderViewEventListener* listener = NULL;
-		selected_items_t::iterator item_it;
-		for (item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
+		// Find out which item will be selected once the selection will be cut
+		LLFolderViewItem* item_to_select = getNextUnselectedItem();
+		
+		// Get the selection: removeItem() modified mSelectedItems and makes iterating on it unwise
+		std::set<LLFolderViewItem*> inventory_selected = getSelectionList();
+
+		// Move each item to the clipboard and out of their folder
+		for (std::set<LLFolderViewItem*>::iterator item_it = inventory_selected.begin(); item_it != inventory_selected.end(); ++item_it)
 		{
-			listener = (*item_it)->getListener();
-			if(listener)
+			LLFolderViewItem* item_to_cut = *item_it;
+			LLFolderViewModelItem* listener = item_to_cut->getViewModelItem();
+			if (listener)
 			{
 				listener->cutToClipboard();
+				listener->removeItem();
 			}
 		}
-		LLFolderView::removeCutItems();
+		
+		// Update the selection
+		setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, mParentPanel->hasFocus());
 	}
 	mSearchString.clear();
 }
@@ -1415,11 +964,11 @@ BOOL LLFolderView::canPaste() const
 		{
 			// *TODO: only check folders and parent folders of items
 			const LLFolderViewItem* item = (*item_it);
-			const LLFolderViewEventListener* listener = item->getListener();
+			const LLFolderViewModelItem* listener = item->getViewModelItem();
 			if(!listener || !listener->isClipboardPasteable())
 			{
 				const LLFolderViewFolder* folderp = item->getParentFolder();
-				listener = folderp->getListener();
+				listener = folderp->getViewModelItem();
 				if (!listener || !listener->isClipboardPasteable())
 				{
 					return FALSE;
@@ -1437,24 +986,24 @@ void LLFolderView::paste()
 	if(getVisible() && getEnabled())
 	{
 		// find set of unique folders to paste into
-		std::set<LLFolderViewItem*> folder_set;
+		std::set<LLFolderViewFolder*> folder_set;
 
 		selected_items_t::iterator selected_it;
 		for (selected_it = mSelectedItems.begin(); selected_it != mSelectedItems.end(); ++selected_it)
 		{
 			LLFolderViewItem* item = *selected_it;
-			LLFolderViewEventListener* listener = item->getListener();
-			if (listener->getInventoryType() != LLInventoryType::IT_CATEGORY)
+			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(item);
+			if (folder == NULL)
 			{
-				item = item->getParentFolder();
+				folder = item->getParentFolder();
 			}
-			folder_set.insert(item);
+			folder_set.insert(folder);
 		}
 
-		std::set<LLFolderViewItem*>::iterator set_iter;
+		std::set<LLFolderViewFolder*>::iterator set_iter;
 		for(set_iter = folder_set.begin(); set_iter != folder_set.end(); ++set_iter)
 		{
-			LLFolderViewEventListener* listener = (*set_iter)->getListener();
+			LLFolderViewModelItem* listener = (*set_iter)->getViewModelItem();
 			if(listener && listener->isClipboardPasteable())
 			{
 				listener->pasteFromClipboard();
@@ -1476,8 +1025,8 @@ void LLFolderView::startRenamingSelectedItem( void )
 	{
 		item = mSelectedItems.front();
 	}
-	if(getVisible() && getEnabled() && (count == 1) && item && item->getListener() &&
-	   item->getListener()->isItemRenameable())
+	if(getVisible() && getEnabled() && (count == 1) && item && item->getViewModelItem() &&
+	   item->getViewModelItem()->isItemRenameable())
 	{
 		mRenameItem = item;
 
@@ -1490,7 +1039,7 @@ void LLFolderView::startRenamingSelectedItem( void )
 		// set focus will fail unless item is visible
 		mRenamer->setFocus( TRUE );
 		mRenamer->setTopLostCallback(boost::bind(&LLFolderView::onRenamerLost, this));
-		gViewerWindow->addPopup(mRenamer);
+		LLUI::addPopup(mRenamer);
 	}
 }
 
@@ -1506,12 +1055,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 		LLMenuGL::sMenuContainer->hideMenus();
 	}
 
-	LLView *item = NULL;
-	if (getChildCount() > 0)
-	{
-		item = *(getChildList()->begin());
-	}
-
 	switch( key )
 	{
 	case KEY_F2:
@@ -1529,11 +1072,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 				mSearchString.clear();
 				handled = TRUE;
 			}
-			else
-			{
-				LLFolderView::openSelectedItems();
-				handled = TRUE;
-			}
 		}
 		break;
 
@@ -1548,25 +1086,37 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 
 	case KEY_PAGE_UP:
 		mSearchString.clear();
+		if (mScrollContainer)
+		{
 		mScrollContainer->pageUp(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_PAGE_DOWN:
 		mSearchString.clear();
+		if (mScrollContainer)
+		{
 		mScrollContainer->pageDown(30);
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_HOME:
 		mSearchString.clear();
+		if (mScrollContainer)
+		{
 		mScrollContainer->goToTop();
+		}
 		handled = TRUE;
 		break;
 
 	case KEY_END:
 		mSearchString.clear();
+		if (mScrollContainer)
+		{
 		mScrollContainer->goToBottom();
+		}
 		break;
 
 	case KEY_DOWN:
@@ -1590,12 +1140,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (next->isSelected())
 					{
 						// shrink selection
-						changeSelectionFromRoot(last_selected, FALSE);
+						changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == next->getParentFolder())
 					{
 						// grow selection
-						changeSelectionFromRoot(next, TRUE);
+						changeSelection(next, TRUE);
 					}
 				}
 			}
@@ -1654,12 +1204,12 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 					if (prev->isSelected())
 					{
 						// shrink selection
-						changeSelectionFromRoot(last_selected, FALSE);
+						changeSelection(last_selected, FALSE);
 					}
 					else if (last_selected->getParentFolder() == prev->getParentFolder())
 					{
 						// grow selection
-						changeSelectionFromRoot(prev, TRUE);
+						changeSelection(prev, TRUE);
 					}
 				}
 			}
@@ -1719,20 +1269,6 @@ BOOL LLFolderView::handleKeyHere( KEY key, MASK mask )
 		break;
 	}
 
-	if (!handled && mParentPanel->hasFocus())
-	{
-		if (key == KEY_BACKSPACE)
-		{
-			mSearchTimer.reset();
-			if (mSearchString.size())
-			{
-				mSearchString.erase(mSearchString.size() - 1, 1);
-			}
-			search(getCurSelectedItem(), mSearchString, FALSE);
-			handled = TRUE;
-		}
-	}
-
 	return handled;
 }
 
@@ -1762,7 +1298,7 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
 		}
 
 		//do text search
-		if (mSearchTimer.getElapsedTimeF32() > gSavedSettings.getF32("TypeAheadTimeout"))
+		if (mSearchTimer.getElapsedTimeF32() > LLUI::sSettingGroups["config"]->getF32("TypeAheadTimeout"))
 		{
 			mSearchString.clear();
 		}
@@ -1780,29 +1316,6 @@ BOOL LLFolderView::handleUnicodeCharHere(llwchar uni_char)
 }
 
 
-BOOL LLFolderView::canDoDelete() const
-{
-	if (mSelectedItems.size() == 0) return FALSE;
-
-	for (selected_items_t::const_iterator item_it = mSelectedItems.begin(); item_it != mSelectedItems.end(); ++item_it)
-	{
-		if (!(*item_it)->getListener()->isItemRemovable())
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-void LLFolderView::doDelete()
-{
-	if(mSelectedItems.size() > 0)
-	{				
-		removeSelectedItems();
-	}
-}
-
-
 BOOL LLFolderView::handleMouseDown( S32 x, S32 y, MASK mask )
 {
 	mKeyboardSelection = FALSE;
@@ -1853,7 +1366,7 @@ BOOL LLFolderView::search(LLFolderViewItem* first_item, const std::string &searc
 			}
 		}
 
-		const std::string current_item_label(search_item->getSearchableLabel());
+		const std::string current_item_label(search_item->getViewModelItem()->getSearchableName());
 		S32 search_string_length = llmin(upper_case_string.size(), current_item_label.size());
 		if (!current_item_label.compare(0, search_string_length, upper_case_string))
 		{
@@ -1897,19 +1410,23 @@ BOOL LLFolderView::handleRightMouseDown( S32 x, S32 y, MASK mask )
 	S32 count = mSelectedItems.size();
 	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
 	if (   handled
-		&& ( count > 0 && (hasVisibleChildren() || mFilter->getShowFolderState() == LLInventoryFilter::SHOW_ALL_FOLDERS) ) // show menu only if selected items are visible
+		&& ( count > 0 && (hasVisibleChildren()) ) // show menu only if selected items are visible
 		&& menu )
 	{
 		if (mCallbackRegistrar)
+        {
 			mCallbackRegistrar->pushScope();
+        }
 
 		updateMenuOptions(menu);
 	   
 		menu->updateParent(LLMenuGL::sMenuContainer);
 		LLMenuGL::showPopup(this, menu, x, y);
 		if (mCallbackRegistrar)
+        {
 			mCallbackRegistrar->popScope();
 	}
+	}
 	else
 	{
 		if (menu && menu->getVisible())
@@ -1972,24 +1489,8 @@ BOOL LLFolderView::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// by the folder which is the hierarchy root.
 	if (!handled)
 	{
-		if (getListener()->getUUID().notNull())
-		{
 			handled = LLFolderViewFolder::handleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
 		}
-		else
-		{
-			if (!mFolders.empty())
-			{
-				// dispatch to last folder as a hack to support "Contents" folder in object inventory
-				handled = mFolders.back()->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
-			}
-		}
-	}
-
-	if (handled)
-	{
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderView" << llendl;
-	}
 
 	return handled;
 }
@@ -2033,18 +1534,16 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 	if(item)
 	{
 		LLRect local_rect = item->getLocalRect();
-		LLRect item_scrolled_rect; // item position relative to display area of scroller
-		LLRect visible_doc_rect = mScrollContainer->getVisibleContentRect();
-		
 		S32 icon_height = mIcon.isNull() ? 0 : mIcon->getHeight(); 
 		S32 label_height = getLabelFontForStyle(mLabelStyle)->getLineHeight(); 
 		// when navigating with keyboard, only move top of opened folder on screen, otherwise show whole folder
-		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + ICON_PAD) : local_rect.getHeight(); 
+		S32 max_height_to_show = item->isOpen() && mScrollContainer->hasFocus() ? (llmax( icon_height, label_height ) + item->getIconPad()) : local_rect.getHeight();
 		
 		// get portion of item that we want to see...
 		LLRect item_local_rect = LLRect(item->getIndentation(), 
 										local_rect.getHeight(), 
-										llmin(MIN_ITEM_WIDTH_VISIBLE, local_rect.getWidth()), 
+                                        //+40 is supposed to include few first characters
+										llmin(item->getLabelXPos() - item->getIndentation() + 40, local_rect.getWidth()), 
 										llmax(0, local_rect.getHeight() - max_height_to_show));
 
 		LLRect item_doc_rect;
@@ -2058,8 +1557,8 @@ void LLFolderView::scrollToShowItem(LLFolderViewItem* item, const LLRect& constr
 
 LLRect LLFolderView::getVisibleRect()
 {
-	S32 visible_height = mScrollContainer->getRect().getHeight();
-	S32 visible_width = mScrollContainer->getRect().getWidth();
+	S32 visible_height = (mScrollContainer ? mScrollContainer->getRect().getHeight() : 0);
+	S32 visible_width  = (mScrollContainer ? mScrollContainer->getRect().getWidth()  : 0);
 	LLRect visible_rect;
 	visible_rect.setLeftTopAndSize(-getRect().mLeft, visible_height - getRect().mBottom, visible_width, visible_height);
 	return visible_rect;
@@ -2088,159 +1587,28 @@ void LLFolderView::setShowSingleSelection(BOOL show)
 	}
 }
 
-void LLFolderView::addItemID(const LLUUID& id, LLFolderViewItem* itemp)
-{
-	mItemMap[id] = itemp;
-}
-
-void LLFolderView::removeItemID(const LLUUID& id)
-{
-	mItemMap.erase(id);
-}
-
-LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
-LLFolderViewItem* LLFolderView::getItemByID(const LLUUID& id)
-{
-	LLFastTimer _(FTM_GET_ITEM_BY_ID);
-	if (id == getListener()->getUUID())
-	{
-		return this;
-	}
-
-	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
-	map_it = mItemMap.find(id);
-	if (map_it != mItemMap.end())
-	{
-		return map_it->second;
-	}
-
-	return NULL;
-}
-
-LLFolderViewFolder* LLFolderView::getFolderByID(const LLUUID& id)
-{
-	if (id == getListener()->getUUID())
-	{
-		return this;
-	}
-
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();
-		 ++iter)
-	{
-		LLFolderViewFolder *folder = (*iter);
-		if (folder->getListener()->getUUID() == id)
-		{
-			return folder;
-		}
-	}
-	return NULL;
-}
-
-bool LLFolderView::doToSelected(LLInventoryModel* model, const LLSD& userdata)
-{
-	std::string action = userdata.asString();
-	
-	if ("rename" == action)
-	{
-		startRenamingSelectedItem();
-		return true;
-	}
-	if ("delete" == action)
-	{
-		removeSelectedItems();
-		return true;
-	}
-	if (("copy" == action) || ("cut" == action))
-	{
-		// Clear the clipboard before we start adding things on it
-		LLClipboard::instance().reset();
-	}
-
-	static const std::string change_folder_string = "change_folder_type_";
-	if (action.length() > change_folder_string.length() && 
-		(action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
-	{
-		LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
-		changeType(model, new_folder_type);
-		return true;
-	}
-
-
-	std::set<LLUUID> selected_items = getSelectionList();
-
-	LLMultiPreview* multi_previewp = NULL;
-	LLMultiProperties* multi_propertiesp = NULL;
-
-	if (("task_open" == action  || "open" == action) && selected_items.size() > 1)
-	{
-		multi_previewp = new LLMultiPreview();
-		gFloaterView->addChild(multi_previewp);
-
-		LLFloater::setFloaterHost(multi_previewp);
-	
-	}
-	else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
-	{
-		multi_propertiesp = new LLMultiProperties();
-		gFloaterView->addChild(multi_propertiesp);
-
-		LLFloater::setFloaterHost(multi_propertiesp);
-	}
-
-	std::set<LLUUID>::iterator set_iter;
-
-	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
-	{
-		LLFolderViewItem* folder_item = getItemByID(*set_iter);
-		if(!folder_item) continue;
-		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
-		if(!bridge) continue;
-		bridge->performAction(model, action);
-	}
-
-	LLFloater::setFloaterHost(NULL);
-	if (multi_previewp)
-	{
-		multi_previewp->openFloater(LLSD());
-	}
-	else if (multi_propertiesp)
-	{
-		multi_propertiesp->openFloater(LLSD());
-	}
-
-	return true;
-}
-
 static LLFastTimer::DeclareTimer FTM_AUTO_SELECT("Open and Select");
 static LLFastTimer::DeclareTimer FTM_INVENTORY("Inventory");
 
 // Main idle routine
-void LLFolderView::doIdle()
+void LLFolderView::update()
 {
 	// If this is associated with the user's inventory, don't do anything
 	// until that inventory is loaded up.
-	const LLInventoryPanel *inventory_panel = dynamic_cast<LLInventoryPanel*>(mParentPanel);
-	if (inventory_panel && !inventory_panel->getIsViewsInitialized())
-	{
-		return;
-	}
-	
 	LLFastTimer t2(FTM_INVENTORY);
 
-	BOOL debug_filters = gSavedSettings.getBOOL("DebugInventoryFilters");
-	if (debug_filters != getDebugFilters())
+	if (getFolderViewModel()->getFilter().isModified() && getFolderViewModel()->getFilter().isNotDefault())
 	{
-		mDebugFilters = debug_filters;
-		arrangeAll();
+		mNeedsAutoSelect = TRUE;
 	}
-	BOOL filter_modified_and_active = mFilter->isModified() && mFilter->isNotDefault();
-	mNeedsAutoSelect = filter_modified_and_active &&
-						!(gFocusMgr.childHasKeyboardFocus(this) || gFocusMgr.getMouseCapture());
-	mFilter->clearModified();
-
 	// filter to determine visibility before arranging
-	filterFromRoot();
+	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))
+	{
+		getFolderViewModel()->getFilter().clearModified();
+	}
 
 	// automatically show matching items, and select first one if we had a selection
 	if (mNeedsAutoSelect)
@@ -2248,7 +1616,7 @@ void LLFolderView::doIdle()
 		LLFastTimer t3(FTM_AUTO_SELECT);
 		// select new item only if a filtered item not currently selected
 		LLFolderViewItem* selected_itemp = mSelectedItems.empty() ? NULL : mSelectedItems.back();
-		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->potentiallyVisible()))
+		if (!mAutoSelectOverride && (!selected_itemp || !selected_itemp->getViewModelItem()->potentiallyVisible()))
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -2258,7 +1626,7 @@ void LLFolderView::doIdle()
 
 		// Open filtered folders for folder views with mAutoSelectOverride=TRUE.
 		// Used by LLPlacesFolderView.
-		if (!mFilter->getFilterSubString().empty())
+		if (getFolderViewModel()->getFilter().showAllResults())
 		{
 			// these are named variables to get around gcc not binding non-const references to rvalues
 			// and functor application is inherently non-const to allow for stateful functors
@@ -2269,16 +1637,30 @@ void LLFolderView::doIdle()
 		scrollToShowSelection();
 	}
 
-	BOOL filter_finished = mCompletedFilterGeneration >= mFilter->getCurrentGeneration() 
-						&& !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+	BOOL filter_finished = getViewModelItem()->passedFilter()
+						&& mViewModel->contentsReady();
 	if (filter_finished 
-		|| gFocusMgr.childHasKeyboardFocus(inventory_panel) 
-		|| gFocusMgr.childHasMouseCapture(inventory_panel))
+		|| gFocusMgr.childHasKeyboardFocus(mParentPanel)
+		|| gFocusMgr.childHasMouseCapture(mParentPanel))
 	{
 		// finishing the filter process, giving focus to the folder view, or dragging the scrollbar all stop the auto select process
 		mNeedsAutoSelect = FALSE;
 	}
 
+  BOOL is_visible = isInVisibleChain();
+
+  //Puts folders/items in proper positions
+  if ( is_visible )
+  {
+    sanitizeSelection();
+    if( needsArrange() )
+    {
+      S32 height = 0;
+      S32 width = 0;
+      S32 total_height = arrange( &width, &height );
+      notifyParent(LLSD().with("action", "size_changes").with("height", total_height));
+    }
+  }
 
 	// during filtering process, try to pin selected item's location on screen
 	// this will happen when searching your inventory and when new items arrive
@@ -2290,22 +1672,30 @@ void LLFolderView::doIdle()
 			// lets pin it!
 			mPinningSelectedItem = TRUE;
 
-			LLRect visible_content_rect = mScrollContainer->getVisibleContentRect();
+      //Computes visible area 
+			const LLRect visible_content_rect = (mScrollContainer ? mScrollContainer->getVisibleContentRect() : LLRect());
 			LLFolderViewItem* selected_item = mSelectedItems.back();
 
+      //Computes location of selected content, content outside visible area will be scrolled to using below code
 			LLRect item_rect;
 			selected_item->localRectToOtherView(selected_item->getLocalRect(), &item_rect, this);
-			// if item is visible in scrolled region
-			if (visible_content_rect.overlaps(item_rect))
+			
+      //Computes intersected region of the selected content and visible area
+      LLRect overlap_rect(item_rect);
+      overlap_rect.intersectWith(visible_content_rect);
+
+      //Don't scroll when the selected content exists within the visible area
+			if (overlap_rect.getHeight() >= selected_item->getItemHeight())
 			{
 				// then attempt to keep it in same place on screen
 				mScrollConstraintRect = item_rect;
 				mScrollConstraintRect.translate(-visible_content_rect.mLeft, -visible_content_rect.mBottom);
 			}
+      //Scroll because the selected content is outside the visible area
 			else
 			{
 				// otherwise we just want it onscreen somewhere
-				LLRect content_rect = mScrollContainer->getContentWindowRect();
+				LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 				mScrollConstraintRect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 			}
 		}
@@ -2328,22 +1718,10 @@ void LLFolderView::doIdle()
 	else
 	{
 		// during normal use (page up/page down, etc), just try to fit item on screen
-		LLRect content_rect = mScrollContainer->getContentWindowRect();
+		LLRect content_rect = (mScrollContainer ? mScrollContainer->getContentWindowRect() : LLRect());
 		constraint_rect.setOriginAndSize(0, 0, content_rect.getWidth(), content_rect.getHeight());
 	}
 
-
-	BOOL is_visible = isInVisibleChain();
-
-	if ( is_visible )
-	{
-		sanitizeSelection();
-		if( needsArrange() )
-		{
-			arrangeFromRoot();
-		}
-	}
-
 	if (mSelectedItems.size() && mNeedsScroll)
 	{
 		scrollToShowItem(mSelectedItems.back(), constraint_rect);
@@ -2364,17 +1742,6 @@ void LLFolderView::doIdle()
 	mSignalSelectCallback = FALSE;
 }
 
-
-//static
-void LLFolderView::idle(void* user_data)
-{
-	LLFolderView* self = (LLFolderView*)user_data;
-	if ( self )
-	{	// Do the real idle 
-		self->doIdle();
-	}
-}
-
 void LLFolderView::dumpSelectionInformation()
 {
 	llinfos << "LLFolderView::dumpSelectionInformation()" << llendl;
@@ -2392,13 +1759,13 @@ void LLFolderView::updateRenamerPosition()
 	if(mRenameItem)
 	{
 		// See also LLFolderViewItem::draw()
-		S32 x = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mRenameItem->getIndentation();
+		S32 x = mRenameItem->getLabelXPos();
 		S32 y = mRenameItem->getRect().getHeight() - mRenameItem->getItemHeight() - RENAME_HEIGHT_PAD;
 		mRenameItem->localPointToScreen( x, y, &x, &y );
 		screenPointToLocal( x, y, &x, &y );
 		mRenamer->setOrigin( x, y );
 
-		LLRect scroller_rect(0, 0, gViewerWindow->getWindowWidthScaled(), 0);
+		LLRect scroller_rect(0, 0, (S32)LLUI::getWindowSize().mV[VX], 0);
 		if (mScrollContainer)
 		{
 			scroller_rect = mScrollContainer->getContentWindowRect();
@@ -2425,14 +1792,15 @@ void LLFolderView::updateMenuOptions(LLMenuGL* menu)
 
 	// Successively filter out invalid options
 
-	U32 flags = FIRST_SELECTED_ITEM;
+	U32 multi_select_flag = (mSelectedItems.size() > 1 ? ITEM_IN_MULTI_SELECTION : 0x0);
+	U32 flags = multi_select_flag | FIRST_SELECTED_ITEM;
 	for (selected_items_t::iterator item_itor = mSelectedItems.begin();
 			item_itor != mSelectedItems.end();
 			++item_itor)
 	{
 		LLFolderViewItem* selected_item = (*item_itor);
 		selected_item->buildContextMenu(*menu, flags);
-		flags = 0x0;
+		flags = multi_select_flag;
 	}
 
 	addNoOptions(menu);
@@ -2545,7 +1913,7 @@ void LLFolderView::onRenamerLost()
 
 	if( mRenameItem )
 	{
-		setSelectionFromRoot( mRenameItem, TRUE );
+		setSelection( mRenameItem, TRUE );
 		mRenameItem = NULL;
 	}
 }
@@ -2569,72 +1937,12 @@ LLFolderViewItem* LLFolderView::getNextUnselectedItem()
 	return new_selection;
 }
 
-LLInventoryFilter* LLFolderView::getFilter()
+S32 LLFolderView::getItemHeight()
 {
-	return mFilter;
-}
-
-void LLFolderView::setFilterPermMask( PermissionMask filter_perm_mask )
-{
-	mFilter->setFilterPermissions(filter_perm_mask);
-}
-
-U32 LLFolderView::getFilterObjectTypes() const
-{
-	return mFilter->getFilterObjectTypes();
-}
-
-PermissionMask LLFolderView::getFilterPermissions() const
-{
-	return mFilter->getFilterPermissions();
-}
-
-BOOL LLFolderView::isFilterModified()
+	if(!hasVisibleChildren())
 {
-	return mFilter->isNotDefault();
+		//We need to display status textbox, let's reserve some place for it
+		return llmax(0, mStatusTextBox->getTextPixelHeight());
 }
-
-void delete_selected_item(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->removeSelectedItems();
-	}
-}
-
-void copy_selected_item(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->copy();
-	}
-}
-
-void paste_items(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->paste();
-	}
-}
-
-void open_selected_items(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->openSelectedItems();
-	}
-}
-
-void properties_selected_items(void* user_data)
-{
-	if(user_data)
-	{
-		LLFolderView* fv = reinterpret_cast<LLFolderView*>(user_data);
-		fv->propertiesSelectedItems();
-	}
+	return 0;
 }
diff --git a/indra/newview/llfolderview.h b/indra/llui/llfolderview.h
similarity index 69%
rename from indra/newview/llfolderview.h
rename to indra/llui/llfolderview.h
index 3f78312a98553c51091d798b07bf45582630d4bb..11fccdace440cb00f692c709961f3526a466ae5b 100644
--- a/indra/newview/llfolderview.h
+++ b/indra/llui/llfolderview.h
@@ -39,19 +39,16 @@
 
 #include "lluictrl.h"
 #include "v4color.h"
-#include "lldarray.h"
 #include "stdenums.h"
 #include "lldepthstack.h"
 #include "lleditmenuhandler.h"
 #include "llfontgl.h"
 #include "llscrollcontainer.h"
-#include "lltooldraganddrop.h"
-#include "llviewertexture.h"
 
-class LLFolderViewEventListener;
+class LLFolderViewModelInterface;
 class LLFolderViewFolder;
 class LLFolderViewItem;
-class LLInventoryModel;
+class LLFolderViewFilter;
 class LLPanel;
 class LLLineEditor;
 class LLMenuGL;
@@ -90,136 +87,104 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
 	{
 		Mandatory<LLPanel*>	    parent_panel;
-		Optional<LLUUID>        task_id;
 		Optional<std::string>   title;
 		Optional<bool>			use_label_suffix,
 								allow_multiselect,
 								show_empty_message,
-								show_load_status,
-								use_ellipses;
+								use_ellipses,
+								show_item_link_overlays;
+		Mandatory<LLFolderViewModelInterface*>	view_model;
+        Mandatory<std::string>   options_menu;
+
 
 		Params();
 	};
 
 	friend class LLFolderViewScrollContainer;
+    typedef std::deque<LLFolderViewItem*> selected_items_t;
 
 	LLFolderView(const Params&);
 	virtual ~LLFolderView( void );
 
 	virtual BOOL canFocusChildren() const;
 
+	virtual const LLFolderView*	getRoot() const { return this; }
 	virtual LLFolderView*	getRoot() { return this; }
 
-	// FolderViews default to sort by name. This will change that,
-	// and resort the items if necessary.
-	void setSortOrder(U32 order);
-	void setFilterPermMask(PermissionMask filter_perm_mask);
-	
+	LLFolderViewModelInterface* getFolderViewModel() { return mViewModel; }
+	const LLFolderViewModelInterface* getFolderViewModel() const { return mViewModel; }
+
 	typedef boost::signals2::signal<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)> signal_t;
 	void setSelectCallback(const signal_t::slot_type& cb) { mSelectSignal.connect(cb); }
 	void setReshapeCallback(const signal_t::slot_type& cb) { mReshapeSignal.connect(cb); }
 	
-	// filter is never null
-	LLInventoryFilter* getFilter();
-	const std::string getFilterSubString(BOOL trim = FALSE);
-	U32 getFilterObjectTypes() const;
-	PermissionMask getFilterPermissions() const;
-	// *NOTE: use getFilter()->getShowFolderState();
-	//LLInventoryFilter::EFolderShow getShowFolderState();
-	U32 getSortOrder() const;
-	BOOL isFilterModified();
-
 	bool getAllowMultiSelect() { return mAllowMultiSelect; }
 
 	// Close all folders in the view
 	void closeAllFolders();
 	void openTopLevelFolders();
 
-	virtual void toggleOpen() {};
-	virtual void setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse);
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
+	virtual void addFolder( LLFolderViewFolder* folder);
 
 	// Find width and height of this object and its children. Also
 	// makes sure that this view and its children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
+	virtual S32 getItemHeight();
 
 	void arrangeAll() { mArrangeGeneration++; }
 	S32 getArrangeGeneration() { return mArrangeGeneration; }
 
-	// Apply filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
+	// applies filters to control visibility of items
+	virtual void filter( LLFolderViewFilter& filter);
 
 	// Get the last selected item
 	virtual LLFolderViewItem* getCurSelectedItem( void );
+    selected_items_t& getSelectedItems( void );
 
 	// Record the selected item and pass it down the hierarchy.
 	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus);
+		BOOL take_keyboard_focus = TRUE);
 
-	// Used by menu callbacks
-	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
-
-	// Called once a frame to update the selection if mSelectThisID has been set
-	void updateSelection();
-
-	// This method is used to toggle the selection of an item. 
-	// Walks children and keeps track of selected objects.
+	// This method is used to toggle the selection of an item. Walks
+	// children, and keeps track of selected objects.
 	virtual BOOL changeSelection(LLFolderViewItem* selection, BOOL selected);
 
-	virtual std::set<LLUUID> getSelectionList() const;
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
 
-	// Make sure if ancestor is selected, descendents are not
+	// Make sure if ancestor is selected, descendants are not
 	void sanitizeSelection();
-	void clearSelection();
+	virtual void clearSelection();
 	void addToSelectionList(LLFolderViewItem* item);
 	void removeFromSelectionList(LLFolderViewItem* item);
 
-	BOOL startDrag(LLToolDragAndDrop::ESource source);
+	bool startDrag();
 	void setDragAndDropThisFrame() { mDragAndDropThisFrame = TRUE; }
 	void setDraggingOverItem(LLFolderViewItem* item) { mDraggingOverItem = item; }
 	LLFolderViewItem* getDraggingOverItem() { return mDraggingOverItem; }
 
 	// Deletion functionality
  	void removeSelectedItems();
- 	static void removeCutItems();
-
-	// Open the selected item
-	void openSelectedItems( void );
-	void propertiesSelectedItems( void );
-
-	// Change the folder type
-	void changeType(LLInventoryModel *model, LLFolderType::EType new_folder_type);
 
 	void autoOpenItem(LLFolderViewFolder* item);
 	void closeAutoOpenedFolders();
 	BOOL autoOpenTest(LLFolderViewFolder* item);
+	BOOL isOpen() const { return TRUE; } // root folder always open
 
 	// Copy & paste
-	virtual void	copy();
 	virtual BOOL	canCopy() const;
+	virtual void	copy();
 
-	virtual void	cut();
 	virtual BOOL	canCut() const;
+	virtual void	cut();
 
-	virtual void	paste();
 	virtual BOOL	canPaste() const;
-
-	virtual void	doDelete();
-	virtual BOOL	canDoDelete() const;
+	virtual void	paste();
 
 	LLFolderViewItem* getNextUnselectedItem();
-	
+
 	// Public rename functionality - can only start the process
 	void startRenamingSelectedItem( void );
 
-	// These functions were used when there was only one folderview,
-	// and relied on that concept. This functionality is now handled
-	// by the listeners and the lldraganddroptool.
-	//LLFolderViewItem*	getMovingItem() { return mMovingItem; }
-	//void setMovingItem( LLFolderViewItem* item ) { mMovingItem = item; }
-	//void				dragItemIntoFolder( LLFolderViewItem* moving_item, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-	//void				dragFolderIntoFolder( LLFolderViewFolder* moving_folder, LLFolderViewFolder* dst_folder, BOOL drop, BOOL* accept );
-
 	// LLView functionality
 	///*virtual*/ BOOL handleKey( KEY key, MASK mask, BOOL called_from_parent );
 	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
@@ -250,16 +215,9 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	BOOL getShowSingleSelection() { return mShowSingleSelection; }
 	F32  getSelectionFadeElapsedTime() { return mMultiSelectionFadeTimer.getElapsedTimeF32(); }
 	bool getUseEllipses() { return mUseEllipses; }
+	S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
 
-	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
-	void removeItemID(const LLUUID& id);
-	LLFolderViewItem* getItemByID(const LLUUID& id);
-	LLFolderViewFolder* getFolderByID(const LLUUID& id);
-	
-	bool doToSelected(LLInventoryModel* model, const LLSD& userdata);
-	
-	void	doIdle();						// Real idle routine
-	static void idle(void* user_data);		// static glue to doIdle()
+	void	update();						// needs to be called periodically (e.g. once per frame)
 
 	BOOL needsAutoSelect() { return mNeedsAutoSelect && !mAutoSelectOverride; }
 	BOOL needsAutoRename() { return mNeedsAutoRename; }
@@ -267,9 +225,9 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	void setPinningSelectedItem(BOOL val) { mPinningSelectedItem = val; }
 	void setAutoSelectOverride(BOOL val) { mAutoSelectOverride = val; }
 
-	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
+	bool showItemLinkOverlays() { return mShowItemLinkOverlays; }
 
-	BOOL getDebugFilters() { return mDebugFilters; }
+	void setCallbackRegistrar(LLUICtrl::CommitCallbackRegistry::ScopedRegistrar* registrar) { mCallbackRegistrar = registrar; }
 
 	LLPanel* getParentPanel() { return mParentPanel; }
 	// DEBUG only
@@ -298,18 +256,15 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	
 	BOOL addNoOptions(LLMenuGL* menu) const;
 
-	void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response);
 
 protected:
 	LLHandle<LLView>					mPopupMenuHandle;
 	
-	typedef std::deque<LLFolderViewItem*> selected_items_t;
 	selected_items_t				mSelectedItems;
 	BOOL							mKeyboardSelection;
 	BOOL							mAllowMultiSelect;
 	BOOL							mShowEmptyMessage;
 	BOOL							mShowFolderHierarchy;
-	LLUUID							mSourceID;
 
 	// Renaming variables and methods
 	LLFolderViewItem*				mRenameItem;  // The item currently being renamed
@@ -322,15 +277,13 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	BOOL							mAutoSelectOverride;
 	BOOL							mNeedsAutoRename;
 	bool							mUseLabelSuffix;
+	bool							mShowItemLinkOverlays;
 	
-	BOOL							mDebugFilters;
-	U32								mSortOrder;
 	LLDepthStack<LLFolderViewFolder>	mAutoOpenItems;
 	LLFolderViewFolder*				mAutoOpenCandidate;
 	LLFrameTimer					mAutoOpenTimer;
 	LLFrameTimer					mSearchTimer;
 	std::string						mSearchString;
-	LLInventoryFilter*				mFilter;
 	BOOL							mShowSelectionContext;
 	BOOL							mShowSingleSelection;
 	LLFrameTimer					mMultiSelectionFadeTimer;
@@ -340,13 +293,11 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 	signal_t						mReshapeSignal;
 	S32								mSignalSelectCallback;
 	S32								mMinWidth;
-	S32								mRunningHeight;
-	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	BOOL							mDragAndDropThisFrame;
 	
-	LLUUID							mSelectThisID; // if non null, select this item
-	
 	LLPanel*						mParentPanel;
+	
+	LLFolderViewModelInterface*		mViewModel;
 
 	/**
 	 * Is used to determine if we need to cut text In LLFolderViewItem to avoid horizontal scroll.
@@ -367,11 +318,82 @@ class LLFolderView : public LLFolderViewFolder, public LLEditMenuHandler
 
 };
 
-bool sort_item_name(LLFolderViewItem* a, LLFolderViewItem* b);
-bool sort_item_date(LLFolderViewItem* a, LLFolderViewItem* b);
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLFolderViewFunctor
+//
+// Simple abstract base class for applying a functor to folders and
+// items in a folder view hierarchy. This is suboptimal for algorithms
+// that only work folders or only work on items, but I'll worry about
+// that later when it's determined to be too slow.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLFolderViewFunctor
+{
+public:
+	virtual ~LLFolderViewFunctor() {}
+	virtual void doFolder(LLFolderViewFolder* folder) = 0;
+	virtual void doItem(LLFolderViewItem* item) = 0;
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// Class LLSelectFirstFilteredItem
+//
+// This will select the first *item* found in the hierarchy. If no item can be
+// selected, the first matching folder will.
+// Since doFolder() is done first but we prioritize item selection, we let the 
+// first filtered folder set the selection and raise a folder flag.
+// The selection might be overridden by the first filtered item in doItem()  
+// which checks an item flag. Since doFolder() checks the item flag too, the first
+// item will still be selected if items were to be done first and folders second.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+{
+public:
+	LLSelectFirstFilteredItem() : mItemSelected(FALSE), mFolderSelected(FALSE) {}
+	virtual ~LLSelectFirstFilteredItem() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+	BOOL wasItemSelected() { return mItemSelected || mFolderSelected; }
+protected:
+	BOOL mItemSelected;
+	BOOL mFolderSelected;
+};
+
+class LLOpenFilteredFolders : public LLFolderViewFunctor
+{
+public:
+	LLOpenFilteredFolders()  {}
+	virtual ~LLOpenFilteredFolders() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
+
+class LLSaveFolderState : public LLFolderViewFunctor
+{
+public:
+	LLSaveFolderState() : mApply(FALSE) {}
+	virtual ~LLSaveFolderState() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item) {}
+	void setApply(BOOL apply);
+	void clearOpenFolders() { mOpenFolders.clear(); }
+protected:
+	std::set<LLUUID> mOpenFolders;
+	BOOL mApply;
+};
+
+class LLOpenFoldersWithSelection : public LLFolderViewFunctor
+{
+public:
+	LLOpenFoldersWithSelection() {}
+	virtual ~LLOpenFoldersWithSelection() {}
+	virtual void doFolder(LLFolderViewFolder* folder);
+	virtual void doItem(LLFolderViewItem* item);
+};
 
 // Flags for buildContextMenu()
 const U32 SUPPRESS_OPEN_ITEM = 0x1;
 const U32 FIRST_SELECTED_ITEM = 0x2;
+const U32 ITEM_IN_MULTI_SELECTION = 0x4;
 
 #endif // LL_LLFOLDERVIEW_H
diff --git a/indra/llui/llfolderviewitem.cpp b/indra/llui/llfolderviewitem.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..fdb4108afbf48e485d37e994312419c02f7289b2
--- /dev/null
+++ b/indra/llui/llfolderviewitem.cpp
@@ -0,0 +1,2095 @@
+/** 
+* @file llfolderviewitem.cpp
+* @brief Items and folders that can appear in a hierarchical folder view
+*
+* $LicenseInfo:firstyear=2001&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2010, Linden Research, Inc.
+* 
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU Lesser General Public
+* License as published by the Free Software Foundation;
+* version 2.1 of the License only.
+* 
+* This library is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+* Lesser General Public License for more details.
+* 
+* You should have received a copy of the GNU Lesser General Public
+* License along with this library; if not, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+* 
+* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+* $/LicenseInfo$
+*/
+#include "../newview/llviewerprecompiledheaders.h"
+
+#include "llflashtimer.h"
+
+#include "linden_common.h"
+#include "llfolderviewitem.h"
+#include "llfolderview.h"
+#include "llfolderviewmodel.h"
+#include "llpanel.h"
+#include "llcriticaldamp.h"
+#include "llclipboard.h"
+#include "llfocusmgr.h"		// gFocusMgr
+#include "lltrans.h"
+#include "llwindow.h"
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewItem
+///----------------------------------------------------------------------------
+
+static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
+
+// statics 
+std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
+
+bool LLFolderViewItem::sColorSetInitialized = false;
+LLUIColor LLFolderViewItem::sFgColor;
+LLUIColor LLFolderViewItem::sHighlightBgColor;
+LLUIColor LLFolderViewItem::sFlashBgColor;
+LLUIColor LLFolderViewItem::sFocusOutlineColor;
+LLUIColor LLFolderViewItem::sMouseOverColor;
+LLUIColor LLFolderViewItem::sFilterBGColor;
+LLUIColor LLFolderViewItem::sFilterTextColor;
+LLUIColor LLFolderViewItem::sSuffixColor;
+LLUIColor LLFolderViewItem::sSearchStatusColor;
+
+// only integers can be initialized in header
+const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
+const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+
+//static
+LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
+{
+	LLFontGL* rtn = sFonts[style];
+	if (!rtn) // grab label font with this style, lazily
+	{
+		LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
+		rtn = LLFontGL::getFont(labelfontdesc);
+		if (!rtn)
+		{
+			rtn = LLFontGL::getFontDefault();
+		}
+		sFonts[style] = rtn;
+	}
+	return rtn;
+}
+
+//static
+void LLFolderViewItem::initClass()
+{
+}
+
+//static
+void LLFolderViewItem::cleanupClass()
+{
+	sFonts.clear();
+}
+
+
+// NOTE: Optimize this, we call it a *lot* when opening a large inventory
+LLFolderViewItem::Params::Params()
+:	root(),
+	listener(),
+	folder_arrow_image("folder_arrow_image"),
+	folder_indentation("folder_indentation"),
+	selection_image("selection_image"),
+	item_height("item_height"),
+	item_top_pad("item_top_pad"),
+	creation_date(),
+	allow_open("allow_open", true),
+	font_color("font_color"),
+	font_highlight_color("font_highlight_color"),
+    left_pad("left_pad", 0),
+    icon_pad("icon_pad", 0),
+    icon_width("icon_width", 0),
+    text_pad("text_pad", 0),
+    text_pad_right("text_pad_right", 0),
+    arrow_size("arrow_size", 0),
+    max_folder_item_overlap("max_folder_item_overlap", 0)
+{ }
+
+// Default constructor
+LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
+:	LLView(p),
+	mLabelWidth(0),
+	mLabelWidthDirty(false),
+    mLabelPaddingRight(DEFAULT_LABEL_PADDING_RIGHT),
+	mParentFolder( NULL ),
+	mIsSelected( FALSE ),
+	mIsCurSelection( FALSE ),
+	mSelectPending(FALSE),
+	mLabelStyle( LLFontGL::NORMAL ),
+	mHasVisibleChildren(FALSE),
+    mLocalIndentation(p.folder_indentation),
+	mIndentation(0),
+	mItemHeight(p.item_height),
+	mControlLabelRotation(0.f),
+	mDragAndDropTarget(FALSE),
+	mLabel(p.name),
+	mRoot(p.root),
+	mViewModelItem(p.listener),
+	mIsMouseOverTitle(false),
+	mAllowOpen(p.allow_open),
+	mFontColor(p.font_color),
+	mFontHighlightColor(p.font_highlight_color),
+    mLeftPad(p.left_pad),
+    mIconPad(p.icon_pad),
+    mIconWidth(p.icon_width),
+    mTextPad(p.text_pad),
+    mTextPadRight(p.text_pad_right),
+    mArrowSize(p.arrow_size),
+    mMaxFolderItemOverlap(p.max_folder_item_overlap)
+{
+	if (!sColorSetInitialized)
+	{
+		sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+		sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+		sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+		sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+		sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+		sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
+		sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
+		sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
+		sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
+		sColorSetInitialized = true;
+	}
+
+	if (mViewModelItem)
+	{
+		mViewModelItem->setFolderViewItem(this);
+	}
+}
+
+// Destroys the object
+LLFolderViewItem::~LLFolderViewItem()
+{
+	mViewModelItem = NULL;
+}
+
+BOOL LLFolderViewItem::postBuild()
+{
+	refresh();
+	return TRUE;
+}
+
+
+LLFolderView* LLFolderViewItem::getRoot()
+{
+	return mRoot;
+}
+
+const LLFolderView* LLFolderViewItem::getRoot() const
+{
+	return mRoot;
+}
+// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
+BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
+{
+	LLFolderViewItem* root = this;
+	while( root->mParentFolder )
+	{
+		if( root->mParentFolder == potential_ancestor )
+		{
+			return TRUE;
+		}
+		root = root->mParentFolder;
+	}
+	return FALSE;
+}
+
+LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
+{
+	if (!mParentFolder)
+	{
+		return NULL;
+	}
+
+	LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
+	while(itemp && !itemp->getVisible())
+	{
+		LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
+		if (itemp == next_itemp) 
+		{
+			// hit last item
+			return itemp->getVisible() ? itemp : this;
+		}
+		itemp = next_itemp;
+	}
+
+	return itemp;
+}
+
+LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
+{
+	if (!mParentFolder)
+	{
+		return NULL;
+	}
+
+	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
+
+	// Skip over items that are invisible or are hidden from the UI.
+	while(itemp && !itemp->getVisible())
+	{
+		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
+		if (itemp == next_itemp) 
+		{
+			// hit first item
+			return itemp->getVisible() ? itemp : this;
+		}
+		itemp = next_itemp;
+	}
+
+	return itemp;
+}
+
+BOOL LLFolderViewItem::passedFilter(S32 filter_generation) 
+{
+	return getViewModelItem()->passedFilter(filter_generation);
+}
+
+void LLFolderViewItem::refresh()
+{
+	LLFolderViewModelItem& vmi = *getViewModelItem();
+
+	mLabel = vmi.getDisplayName();
+
+	setToolTip(vmi.getName());
+	mIcon = vmi.getIcon();
+	mIconOpen = vmi.getIconOpen();
+	mIconOverlay = vmi.getIconOverlay();
+
+	if (mRoot->useLabelSuffix())
+	{
+		mLabelStyle = vmi.getLabelStyle();
+		mLabelSuffix = vmi.getLabelSuffix();
+	}
+
+	mLabelWidthDirty = true;
+	vmi.dirtyFilter();
+}
+
+// Utility function for LLFolderView
+void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
+									 BOOL take_keyboard_focus)
+{
+	LLFolderView* root = getRoot();
+	if (getParentFolder())
+	{
+	getParentFolder()->requestArrange();
+	}
+	if(set_selection)
+	{
+		getRoot()->setSelection(this, TRUE, take_keyboard_focus);
+		if(root)
+		{
+			root->scrollToShowSelection();
+		}
+	}		
+}
+
+
+std::set<LLFolderViewItem*> LLFolderViewItem::getSelectionList() const
+{
+	std::set<LLFolderViewItem*> selection;
+	return selection;
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+void LLFolderViewItem::addToFolder(LLFolderViewFolder* folder)
+{
+	folder->addItem(this);
+}
+
+
+// Finds width and height of this object and its children.  Also
+// makes sure that this view and its children are the right size.
+S32 LLFolderViewItem::arrange( S32* width, S32* height )
+{
+	// Only indent deeper items in hierarchy
+	mIndentation = (getParentFolder())
+		? getParentFolder()->getIndentation() + mLocalIndentation
+		: 0;
+	if (mLabelWidthDirty)
+	{
+		mLabelWidth = getLabelXPos() + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + mLabelPaddingRight; 
+		mLabelWidthDirty = false;
+	}
+
+	*width = llmax(*width, mLabelWidth); 
+
+	// determine if we need to use ellipses to avoid horizontal scroll. EXT-719
+	bool use_ellipses = getRoot()->getUseEllipses();
+	if (use_ellipses)
+	{
+		// limit to set rect to avoid horizontal scrollbar
+		*width = llmin(*width, getRoot()->getRect().getWidth());
+	}
+	*height = getItemHeight();
+	return *height;
+}
+
+S32 LLFolderViewItem::getItemHeight()
+{
+	return mItemHeight;
+}
+
+S32 LLFolderViewItem::getLabelXPos()
+{
+    return getIndentation() + mArrowSize + mTextPad + mIconWidth + mIconPad;
+}
+
+S32 LLFolderViewItem::getIconPad()
+{
+    return mIconPad;
+}
+
+S32 LLFolderViewItem::getTextPad()
+{
+    return mTextPad;
+}
+
+// *TODO: This can be optimized a lot by simply recording that it is
+// selected in the appropriate places, and assuming that set selection
+// means 'deselect' for a leaf item. Do this optimization after
+// multiple selection is implemented to make sure it all plays nice
+// together.
+BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
+{
+	if (selection == this && !mIsSelected)
+	{
+		selectItem();
+	}
+	else if (mIsSelected)	// Deselect everything else.
+	{
+		deselectItem();
+	}
+	return mIsSelected;
+}
+
+BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+	if (selection == this)
+	{
+		if (mIsSelected)
+		{
+			deselectItem();
+		}
+		else
+		{
+			selectItem();
+		}
+		return TRUE;
+	}
+	return FALSE;
+}
+
+void LLFolderViewItem::deselectItem(void)
+{
+	mIsSelected = FALSE;
+}
+
+void LLFolderViewItem::selectItem(void)
+{
+	if (mIsSelected == FALSE)
+	{
+		mIsSelected = TRUE;
+		getViewModelItem()->selectItem();
+	}
+}
+
+BOOL LLFolderViewItem::isMovable()
+{
+	return getViewModelItem()->isItemMovable();
+}
+
+BOOL LLFolderViewItem::isRemovable()
+{
+	return getViewModelItem()->isItemRemovable();
+}
+
+void LLFolderViewItem::destroyView()
+{
+	getRoot()->removeFromSelectionList(this);
+
+	if (mParentFolder)
+	{
+		// removeView deletes me
+		mParentFolder->extractItem(this);
+	}
+	delete this;
+}
+
+// Call through to the viewed object and return true if it can be
+// removed.
+//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
+BOOL LLFolderViewItem::remove()
+{
+	if(!isRemovable())
+	{
+		return FALSE;
+	}
+	return getViewModelItem()->removeItem();
+}
+
+// Build an appropriate context menu for the item.
+void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+	getViewModelItem()->buildContextMenu(menu, flags);
+}
+
+void LLFolderViewItem::openItem( void )
+{
+	if (mAllowOpen)
+	{
+		getViewModelItem()->openItem();
+	}
+}
+
+void LLFolderViewItem::rename(const std::string& new_name)
+{
+	if( !new_name.empty() )
+	{
+		getViewModelItem()->renameItem(new_name);
+	}
+}
+
+const std::string& LLFolderViewItem::getName( void ) const
+{
+	static const std::string noName("");
+	return getViewModelItem() ? getViewModelItem()->getName() : noName;
+}
+
+// LLView functionality
+BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+	if(!mIsSelected)
+	{
+		getRoot()->setSelection(this, FALSE);
+	}
+	make_ui_sound("UISndClick");
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	if (LLView::childrenHandleMouseDown(x, y, mask))
+	{
+		return TRUE;
+	}
+	
+	// No handler needed for focus lost since this class has no
+	// state that depends on it.
+	gFocusMgr.setMouseCapture( this );
+    
+	if (!mIsSelected)
+	{
+		if(mask & MASK_CONTROL)
+		{
+			getRoot()->changeSelection(this, !mIsSelected);
+		}
+		else if (mask & MASK_SHIFT)
+		{
+			getParentFolder()->extendSelectionTo(this);
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+		}
+		make_ui_sound("UISndClick");
+	}
+	else
+	{
+		// If selected, we reserve the decision of deselecting/reselecting to the mouse up moment.
+		// This is necessary so we maintain selection consistent when starting a drag.
+		mSelectPending = TRUE;
+	}
+
+	mDragStartX = x;
+	mDragStartY = y;
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
+{
+	static LLCachedControl<S32> drag_and_drop_threshold(*LLUI::sSettingGroups["config"],"DragAndDropDistanceThreshold");
+
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+	if( hasMouseCapture() && isMovable() )
+	{
+			LLFolderView* root = getRoot();
+
+		if( (x - mDragStartX) * (x - mDragStartX) + (y - mDragStartY) * (y - mDragStartY) > drag_and_drop_threshold() * drag_and_drop_threshold() 
+			&& root->getCurSelectedItem()
+			&& root->startDrag())
+		{
+					// RN: when starting drag and drop, clear out last auto-open
+					root->autoOpenTest(NULL);
+					root->setShowSelectionContext(TRUE);
+
+					// Release keyboard focus, so that if stuff is dropped into the
+					// world, pressing the delete key won't blow away the inventory
+					// item.
+					gFocusMgr.setKeyboardFocus(NULL);
+
+			getWindow()->setCursor(UI_CURSOR_ARROW);
+		}
+		else if (x != mDragStartX || y != mDragStartY)
+		{
+			getWindow()->setCursor(UI_CURSOR_NOLOCKED);
+		}
+
+		return TRUE;
+	}
+	else
+	{
+		getRoot()->setShowSelectionContext(FALSE);
+		getWindow()->setCursor(UI_CURSOR_ARROW);
+		// let parent handle this then...
+		return FALSE;
+	}
+}
+
+
+BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+	openItem();
+	return TRUE;
+}
+
+BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	if (LLView::childrenHandleMouseUp(x, y, mask))
+	{
+		return TRUE;
+	}
+	
+	// if mouse hasn't moved since mouse down...
+	if ( pointInView(x, y) && mSelectPending )
+	{
+		//...then select
+		if(mask & MASK_CONTROL)
+		{
+			getRoot()->changeSelection(this, !mIsSelected);
+		}
+		else if (mask & MASK_SHIFT)
+		{
+			getParentFolder()->extendSelectionTo(this);
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+		}
+	}
+
+	mSelectPending = FALSE;
+
+	if( hasMouseCapture() )
+	{
+		if (getRoot())
+		{
+		getRoot()->setShowSelectionContext(FALSE);
+		}
+		gFocusMgr.setMouseCapture( NULL );
+	}
+	return TRUE;
+}
+
+void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	mIsMouseOverTitle = false;
+}
+
+BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+										 EDragAndDropType cargo_type,
+										 void* cargo_data,
+										 EAcceptance* accept,
+										 std::string& tooltip_msg)
+{
+	BOOL handled = FALSE;
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+		handled = accepted;
+		if (accepted)
+		{
+			mDragAndDropTarget = TRUE;
+			*accept = ACCEPT_YES_MULTI;
+		}
+		else
+		{
+			*accept = ACCEPT_NO;
+		}
+	if(mParentFolder && !handled)
+	{
+		// store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
+		mRoot->setDraggingOverItem(this);
+		handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
+		mRoot->setDraggingOverItem(NULL);
+	}
+	if (handled)
+	{
+		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
+	}
+
+	return handled;
+}
+
+void LLFolderViewItem::drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color)
+{
+	//--------------------------------------------------------------------------------//
+	// Draw open folder arrow
+	//
+	const S32 TOP_PAD = default_params.item_top_pad;
+
+	if (hasVisibleChildren() || getViewModelItem()->hasChildren())
+	{
+		LLUIImage* arrow_image = default_params.folder_arrow_image;
+		gl_draw_scaled_rotated_image(
+			mIndentation, getRect().getHeight() - mArrowSize - mTextPad - TOP_PAD,
+			mArrowSize, mArrowSize, mControlLabelRotation, arrow_image->getImage(), fg_color);
+	}
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightAllowed()
+{
+	return mIsSelected;
+}
+
+/*virtual*/ bool LLFolderViewItem::isHighlightActive()
+{
+	return mIsCurSelection;
+}
+
+void LLFolderViewItem::drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor,  
+                                                        const LLUIColor &focusOutlineColor, const LLUIColor &mouseOverColor)
+{
+    const S32 focus_top = getRect().getHeight();
+    const S32 focus_bottom = getRect().getHeight() - mItemHeight;
+    const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
+    const S32 FOCUS_LEFT = 1;
+	
+	// Determine which background color to use for highlighting
+	LLUIColor bgColor = (isFlashing() ? flashColor : selectColor);
+
+    //--------------------------------------------------------------------------------//
+    // Draw highlight for selected items
+	// Note: Always render "current" item or flashing item, only render other selected 
+	// items if mShowSingleSelection is FALSE.
+    //
+    if (isHighlightAllowed())	
+    							
+    {
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+		
+		// Highlight for selected but not current items
+        if (!isHighlightActive() && !isFlashing())
+        {
+			LLColor4 bg_color = bgColor;
+            // do time-based fade of extra objects
+            F32 fade_time = (getRoot() ? getRoot()->getSelectionFadeElapsedTime() : 0.0f);
+            if (getRoot() && getRoot()->getShowSingleSelection())
+            {
+                // fading out
+                bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
+            }
+            else
+            {
+                // fading in
+                bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
+            }
+        	gl_rect_2d(FOCUS_LEFT,
+					   focus_top,
+					   getRect().getWidth() - 2,
+					   focus_bottom,
+					   bg_color, hasKeyboardFocus);
+        }
+
+		// Highlight for currently selected or flashing item
+        if (isHighlightActive())
+        {
+			// Background
+        	gl_rect_2d(FOCUS_LEFT,
+                focus_top,
+                getRect().getWidth() - 2,
+                focus_bottom,
+                bgColor, hasKeyboardFocus);
+			// Outline
+            gl_rect_2d(FOCUS_LEFT, 
+                focus_top, 
+                getRect().getWidth() - 2,
+                focus_bottom,
+                focusOutlineColor, FALSE);
+        }
+
+        if (folder_open)
+        {
+            gl_rect_2d(FOCUS_LEFT,
+                focus_bottom + 1, // overlap with bottom edge of above rect
+                getRect().getWidth() - 2,
+                0,
+                focusOutlineColor, FALSE);
+            if (showContent && !isFlashing())
+            {
+                gl_rect_2d(FOCUS_LEFT,
+                    focus_bottom + 1,
+                    getRect().getWidth() - 2,
+                    0,
+                    bgColor, TRUE);
+            }
+        }
+    }
+    else if (mIsMouseOverTitle)
+    {
+        gl_rect_2d(FOCUS_LEFT,
+            focus_top, 
+            getRect().getWidth() - 2,
+            focus_bottom,
+            mouseOverColor, FALSE);
+    }
+
+    //--------------------------------------------------------------------------------//
+    // Draw DragNDrop highlight
+    //
+    if (mDragAndDropTarget)
+    {
+        gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+        gl_rect_2d(FOCUS_LEFT, 
+            focus_top, 
+            getRect().getWidth() - 2,
+            focus_bottom,
+            bgColor, FALSE);
+        if (folder_open)
+        {
+            gl_rect_2d(FOCUS_LEFT,
+                focus_bottom + 1, // overlap with bottom edge of above rect
+                getRect().getWidth() - 2,
+                0,
+                bgColor, FALSE);
+        }
+        mDragAndDropTarget = FALSE;
+    }
+}
+
+void LLFolderViewItem::drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x)
+{
+    //--------------------------------------------------------------------------------//
+    // Draw the actual label text
+    //
+    font->renderUTF8(mLabel, 0, x, y, color,
+        LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+        S32_MAX, getRect().getWidth() - (S32) x - mLabelPaddingRight, &right_x, TRUE);
+}
+
+void LLFolderViewItem::draw()
+{
+    const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+    const BOOL filled = show_context || (getRoot() ? getRoot()->getParentPanel()->hasFocus() : FALSE); // If we have keyboard focus, draw selection filled
+
+	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+	const S32 TOP_PAD = default_params.item_top_pad;
+	
+	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+
+    getViewModelItem()->update();
+
+    drawOpenFolderArrow(default_params, sFgColor);
+
+    drawHighlight(show_context, filled, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+
+	//--------------------------------------------------------------------------------//
+	// Draw open icon
+	//
+	const S32 icon_x = mIndentation + mArrowSize + mTextPad;
+	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
+ 	{
+		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
+	}
+	else if (mIcon)
+	{
+ 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+ 	}
+
+	if (mIconOverlay && getRoot()->showItemLinkOverlays())
+	{
+		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
+	}
+
+	//--------------------------------------------------------------------------------//
+	// Exit if no label to draw
+	//
+	if (mLabel.empty())
+	{
+		return;
+	}
+
+	std::string::size_type filter_string_length = mViewModelItem->hasFilterStringMatch() ? mViewModelItem->getFilterStringSize() : 0;
+	F32 right_x  = 0;
+	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+	F32 text_left = (F32)getLabelXPos();
+	std::string combined_string = mLabel + mLabelSuffix;
+
+	if (filter_string_length > 0)
+	{
+		S32 left = llround(text_left) + font->getWidth(combined_string, 0, mViewModelItem->getFilterStringOffset()) - 2;
+		S32 right = left + font->getWidth(combined_string, mViewModelItem->getFilterStringOffset(), filter_string_length) + 2;
+		S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
+		S32 top = getRect().getHeight() - TOP_PAD;
+
+		LLUIImage* box_image = default_params.selection_image;
+		LLRect box_rect(left, top, right, bottom);
+		box_image->draw(box_rect, sFilterBGColor);
+    }
+
+    LLColor4 color = (mIsSelected && filled) ? mFontHighlightColor : mFontColor;
+    drawLabel(font, text_left, y, color, right_x);
+
+	//--------------------------------------------------------------------------------//
+	// Draw label suffix
+	//
+	if (!mLabelSuffix.empty())
+	{
+		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
+						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+						  S32_MAX, S32_MAX, &right_x, FALSE );
+	}
+    
+	//--------------------------------------------------------------------------------//
+	// Highlight string match
+	//
+    if (filter_string_length > 0)
+    {
+        F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mViewModelItem->getFilterStringOffset());
+        F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad - (F32)TOP_PAD;
+        font->renderUTF8( combined_string, mViewModelItem->getFilterStringOffset(), match_string_left, yy,
+            sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
+            filter_string_length, S32_MAX, &right_x, FALSE );
+    }
+
+    //Gilbert Linden 9-20-2012: Although this should be legal, removing it because it causes the mLabelSuffix rendering to
+    //be distorted...oddly. I initially added this in but didn't need it after all. So removing to prevent unnecessary bug.
+    //LLView::draw();
+}
+
+const LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void ) const
+{
+	return getRoot()->getFolderViewModel();
+}
+
+LLFolderViewModelInterface* LLFolderViewItem::getFolderViewModel( void )
+{
+	return getRoot()->getFolderViewModel();
+}
+
+bool LLFolderViewItem::isInSelection() const
+{
+	return mIsSelected || (mParentFolder && mParentFolder->isInSelection());
+}
+
+
+
+///----------------------------------------------------------------------------
+/// Class LLFolderViewFolder
+///----------------------------------------------------------------------------
+
+LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): 
+	LLFolderViewItem( p ),
+	mIsOpen(FALSE),
+	mExpanderHighlighted(FALSE),
+	mCurHeight(0.f),
+	mTargetHeight(0.f),
+	mAutoOpenCountdown(0.f),
+	mLastArrangeGeneration( -1 ),
+	mLastCalculatedWidth(0)
+{
+}
+
+void LLFolderViewFolder::updateLabelRotation()
+{
+	if (mAutoOpenCountdown != 0.f)
+	{
+		mControlLabelRotation = mAutoOpenCountdown * -90.f;
+	}
+	else if (isOpen())
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
+	}
+	else
+	{
+		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
+	}
+}
+
+// Destroys the object
+LLFolderViewFolder::~LLFolderViewFolder( void )
+{
+	// The LLView base class takes care of object destruction. make sure that we
+	// don't have mouse or keyboard focus
+	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
+}
+
+// addToFolder() returns TRUE if it succeeds. FALSE otherwise
+void LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder)
+{
+	folder->addFolder(this);
+}
+
+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.
+S32 LLFolderViewFolder::arrange( S32* width, S32* height )
+{
+	// sort before laying out contents
+	getRoot()->getFolderViewModel()->sort(this);
+
+	LLFastTimer t2(FTM_ARRANGE);
+
+	// evaluate mHasVisibleChildren
+	mHasVisibleChildren = false;
+	if (getViewModelItem()->descendantsPassedFilter())
+	{
+		// We have to verify that there's at least one child that's not filtered out
+		bool found = false;
+		// Try the items first
+		for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
+		{
+			LLFolderViewItem* itemp = (*iit);
+			found = itemp->passedFilter();
+			if (found)
+				break;
+		}
+		if (!found)
+		{
+			// If no item found, try the folders
+			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+			{
+				LLFolderViewFolder* folderp = (*fit);
+				found = folderp->passedFilter();
+				if (found)
+					break;
+			}
+		}
+
+		mHasVisibleChildren = found;
+	}
+
+	// calculate height as a single item (without any children), and reshapes rectangle to match
+	LLFolderViewItem::arrange( width, height );
+
+	// clamp existing animated height so as to never get smaller than a single item
+	mCurHeight = llmax((F32)*height, mCurHeight);
+
+	// initialize running height value as height of single item in case we have no children
+	F32 running_height = (F32)*height;
+	F32 target_height = (F32)*height;
+
+	// are my children visible?
+	if (needsArrange())
+	{
+		// set last arrange generation first, in case children are animating
+		// and need to be arranged again
+		mLastArrangeGeneration = getRoot()->getArrangeGeneration();
+		if (isOpen())
+		{
+			// Add sizes of children
+			S32 parent_item_height = getRect().getHeight();
+
+			for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
+			{
+				LLFolderViewFolder* folderp = (*fit);
+				folderp->setVisible(folderp->passedFilter()); // passed filter or has descendants that passed filter
+
+				if (folderp->getVisible())
+				{
+					S32 child_width = *width;
+					S32 child_height = 0;
+					S32 child_top = parent_item_height - llround(running_height);
+
+					target_height += folderp->arrange( &child_width, &child_height );
+
+					running_height += (F32)child_height;
+					*width = llmax(*width, child_width);
+					folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
+				}
+			}
+			for(items_t::iterator iit = mItems.begin();
+				iit != mItems.end(); ++iit)
+			{
+				LLFolderViewItem* itemp = (*iit);
+				itemp->setVisible(itemp->passedFilter());
+
+				if (itemp->getVisible())
+				{
+					S32 child_width = *width;
+					S32 child_height = 0;
+					S32 child_top = parent_item_height - llround(running_height);
+
+					target_height += itemp->arrange( &child_width, &child_height );
+					// don't change width, as this item is as wide as its parent folder by construction
+					itemp->reshape( itemp->getRect().getWidth(), child_height);
+
+					running_height += (F32)child_height;
+					*width = llmax(*width, child_width);
+					itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
+				}
+			}
+		}
+
+		mTargetHeight = target_height;
+		// cache this width so next time we can just return it
+		mLastCalculatedWidth = *width;
+	}
+	else
+	{
+		// just use existing width
+		*width = mLastCalculatedWidth;
+	}
+
+	// animate current height towards target height
+	if (llabs(mCurHeight - mTargetHeight) > 1.f)
+	{
+		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(isOpen() ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
+
+		requestArrange();
+
+		// hide child elements that fall out of current animated height
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			// number of pixels that bottom of folder label is from top of parent folder
+			if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() 
+				> llround(mCurHeight) + mMaxFolderItemOverlap)
+			{
+				// hide if beyond current folder height
+				(*fit)->setVisible(FALSE);
+			}
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			// number of pixels that bottom of item label is from top of parent folder
+			if (getRect().getHeight() - (*iit)->getRect().mBottom
+				> llround(mCurHeight) + mMaxFolderItemOverlap)
+			{
+				(*iit)->setVisible(FALSE);
+			}
+		}
+	}
+	else
+	{
+		mCurHeight = mTargetHeight;
+	}
+
+	// don't change width as this item is already as wide as its parent folder
+	reshape(getRect().getWidth(),llround(mCurHeight));
+
+	// pass current height value back to parent
+	*height = llround(mCurHeight);
+
+	return llround(mTargetHeight);
+}
+
+BOOL LLFolderViewFolder::needsArrange()
+{
+	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
+}
+
+// Passes selection information on to children and record selection
+// information if necessary.
+BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
+                                      BOOL take_keyboard_focus)
+{
+	BOOL rv = FALSE;
+	if (selection == this)
+	{
+		if (!isSelected())
+		{
+			selectItem();
+		}
+		rv = TRUE;
+	}
+	else
+	{
+		if (isSelected())
+		{
+			deselectItem();
+		}
+		rv = FALSE;
+	}
+	BOOL child_selected = FALSE;
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
+		{
+			rv = TRUE;
+			child_selected = TRUE;
+		}
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
+		{
+			rv = TRUE;
+			child_selected = TRUE;
+		}
+	}
+	if(openitem && child_selected)
+	{
+		setOpenArrangeRecursively(TRUE);
+	}
+	return rv;
+}
+
+// This method is used to change the selection of an item.
+// Recursively traverse all children; if 'selection' is 'this' then change
+// the select status if necessary.
+// Returns TRUE if the selection state of this folder, or of a child, was changed.
+BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
+{
+	BOOL rv = FALSE;
+	if(selection == this)
+	{
+		if (isSelected() != selected)
+		{
+			rv = TRUE;
+			if (selected)
+			{
+				selectItem();
+			}
+			else
+			{
+				deselectItem();
+			}
+		}
+	}
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		if((*fit)->changeSelection(selection, selected))
+		{
+			rv = TRUE;
+		}
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		if((*iit)->changeSelection(selection, selected))
+		{
+			rv = TRUE;
+		}
+	}
+	return rv;
+}
+
+LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
+{
+	if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
+
+	std::deque<LLFolderViewFolder*> item_a_ancestors;
+
+	LLFolderViewFolder* parent = item_a->getParentFolder();
+	while(parent)
+	{
+		item_a_ancestors.push_back(parent);
+		parent = parent->getParentFolder();
+	}
+
+	std::deque<LLFolderViewFolder*> item_b_ancestors;
+	
+	parent = item_b->getParentFolder();
+	while(parent)
+	{
+		item_b_ancestors.push_back(parent);
+		parent = parent->getParentFolder();
+	}
+
+	LLFolderViewFolder* common_ancestor = item_a->getRoot();
+
+	while(item_a_ancestors.size() > item_b_ancestors.size())
+	{
+		item_a = item_a_ancestors.front();
+		item_a_ancestors.pop_front();
+	}
+
+	while(item_b_ancestors.size() > item_a_ancestors.size())
+	{
+		item_b = item_b_ancestors.front();
+		item_b_ancestors.pop_front();
+	}
+
+	while(item_a_ancestors.size())
+	{
+		common_ancestor = item_a_ancestors.front();
+
+		if (item_a_ancestors.front() == item_b_ancestors.front())
+		{
+			// which came first, sibling a or sibling b?
+			for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
+				it != end_it;
+				++it)
+			{
+				LLFolderViewItem* item = *it;
+
+				if (item == item_a)
+				{
+					reverse = false;
+					return common_ancestor;
+				}
+				if (item == item_b)
+				{
+					reverse = true;
+					return common_ancestor;
+				}
+			}
+
+			for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
+				it != end_it;
+				++it)
+			{
+				LLFolderViewItem* item = *it;
+
+				if (item == item_a)
+				{
+					reverse = false;
+					return common_ancestor;
+				}
+				if (item == item_b)
+				{
+					reverse = true;
+					return common_ancestor;
+				}
+			}
+			break;
+		}
+
+		item_a = item_a_ancestors.front();
+		item_a_ancestors.pop_front();
+		item_b = item_b_ancestors.front();
+		item_b_ancestors.pop_front();
+	}
+
+	return NULL;
+}
+
+void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
+{
+	bool selecting = start == NULL;
+	if (reverse)
+	{
+		for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+		for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+	}
+	else
+	{
+		for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+		for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
+			it != end_it;
+			++it)
+		{
+			if (*it == end)
+			{
+				return;
+			}
+
+			if (selecting)
+			{
+				items.push_back(*it);
+			}
+
+			if (*it == start)
+			{
+				selecting = true;
+			}
+		}
+	}
+}
+
+void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
+{
+	if (getRoot()->getAllowMultiSelect() == FALSE) return;
+
+	LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
+	if (cur_selected_item == NULL)
+	{
+		cur_selected_item = new_selection;
+	}
+
+
+	bool reverse = false;
+	LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
+	if (!common_ancestor) return;
+
+	LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
+	LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
+
+	std::vector<LLFolderViewItem*> items_to_select_forward;
+
+	while(cur_folder != common_ancestor)
+	{
+		cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
+			
+		last_selected_item_from_cur = cur_folder;
+		cur_folder = cur_folder->getParentFolder();
+	}
+
+	std::vector<LLFolderViewItem*> items_to_select_reverse;
+
+	LLFolderViewItem* last_selected_item_from_new = new_selection;
+	cur_folder = new_selection->getParentFolder();
+	while(cur_folder != common_ancestor)
+	{
+		cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
+
+		last_selected_item_from_new = cur_folder;
+		cur_folder = cur_folder->getParentFolder();
+	}
+
+	common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
+
+	for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
+		it != end_it;
+		++it)
+	{
+		items_to_select_forward.push_back(*it);
+	}
+
+	LLFolderView* root = getRoot();
+
+	for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
+		it != end_it;
+		++it)
+	{
+		LLFolderViewItem* item = *it;
+		if (item->isSelected())
+		{
+			root->removeFromSelectionList(item);
+		}
+		else
+		{
+			item->selectItem();
+		}
+		root->addToSelectionList(item);
+	}
+
+	if (new_selection->isSelected())
+	{
+		root->removeFromSelectionList(new_selection);
+	}
+	else
+	{
+		new_selection->selectItem();
+	}
+	root->addToSelectionList(new_selection);
+}
+
+
+void LLFolderViewFolder::destroyView()
+{
+    while (!mItems.empty())
+    {
+    	LLFolderViewItem *itemp = mItems.back();
+    	itemp->destroyView(); // LLFolderViewItem::destroyView() removes entry from mItems
+    }
+
+	while (!mFolders.empty())
+	{
+		LLFolderViewFolder *folderp = mFolders.back();
+		folderp->destroyView(); // LLFolderVievFolder::destroyView() removes entry from mFolders
+	}
+
+	LLFolderViewItem::destroyView();
+}
+
+// extractItem() removes the specified item from the folder, but
+// doesn't delete it.
+void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
+{
+	if (item->isSelected())
+		getRoot()->clearSelection();
+	items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
+	if(it == mItems.end())
+	{
+		// This is an evil downcast. However, it's only doing
+		// pointer comparison to find if (which it should be ) the
+		// item is in the container, so it's pretty safe.
+		LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
+		folders_t::iterator ft;
+		ft = std::find(mFolders.begin(), mFolders.end(), f);
+		if (ft != mFolders.end())
+		{
+			mFolders.erase(ft);
+		}
+	}
+	else
+	{
+		mItems.erase(it);
+	}
+	//item has been removed, need to update filter
+	getViewModelItem()->removeChild(item->getViewModelItem());
+	//because an item is going away regardless of filter status, force rearrange
+	requestArrange();
+	removeChild(item);
+}
+
+BOOL LLFolderViewFolder::isMovable()
+{
+	if( !(getViewModelItem()->isItemMovable()) )
+	{
+			return FALSE;
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			if(!(*iit)->isMovable())
+			{
+				return FALSE;
+			}
+		}
+
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			if(!(*fit)->isMovable())
+			{
+				return FALSE;
+			}
+		}
+	return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::isRemovable()
+{
+	if( !(getViewModelItem()->isItemRemovable()) )
+	{
+			return FALSE;
+		}
+
+		for (items_t::iterator iter = mItems.begin();
+			iter != mItems.end();)
+		{
+			items_t::iterator iit = iter++;
+			if(!(*iit)->isRemovable())
+			{
+				return FALSE;
+			}
+		}
+
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			if(!(*fit)->isRemovable())
+			{
+				return FALSE;
+			}
+		}
+	return TRUE;
+}
+
+// this is an internal method used for adding items to folders. 
+void LLFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+	if (item->getParentFolder())
+	{
+		item->getParentFolder()->extractItem(item);
+	}
+	item->setParentFolder(this);
+
+	mItems.push_back(item);
+	
+	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
+	item->setVisible(FALSE);
+	
+	addChild(item);
+
+	// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+	// Note: this happens when models are created before views or shared between views
+	if (!item->getViewModelItem()->hasParent())
+	{
+		getViewModelItem()->addChild(item->getViewModelItem());
+	}
+}
+
+// this is an internal method used for adding items to folders. 
+void LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
+{
+	if (folder->mParentFolder)
+	{
+		folder->mParentFolder->extractItem(folder);
+	}
+	folder->mParentFolder = this;
+	mFolders.push_back(folder);
+	folder->setOrigin(0, 0);
+	folder->reshape(getRect().getWidth(), 0);
+	folder->setVisible(FALSE);
+	// rearrange all descendants too, as our indentation level might have changed
+	//folder->requestArrange();
+	//requestSort();
+
+	addChild(folder);
+
+	// When the model is already hooked into a hierarchy (i.e. has a parent), do not reparent it
+	// Note: this happens when models are created before views or shared between views
+	if (!folder->getViewModelItem()->hasParent())
+	{
+		getViewModelItem()->addChild(folder->getViewModelItem());
+	}
+}
+
+void LLFolderViewFolder::requestArrange()
+{ 
+	if ( mLastArrangeGeneration != -1)
+	{
+		mLastArrangeGeneration = -1; 
+		// flag all items up to root
+		if (mParentFolder)
+		{
+			mParentFolder->requestArrange();
+		}
+	}
+}
+
+void LLFolderViewFolder::toggleOpen()
+{
+	setOpen(!isOpen());
+}
+
+// Force a folder open or closed
+void LLFolderViewFolder::setOpen(BOOL openitem)
+{
+	setOpenArrangeRecursively(openitem);
+}
+
+void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
+{
+	BOOL was_open = isOpen();
+	mIsOpen = openitem;
+		if(!was_open && openitem)
+		{
+		getViewModelItem()->openItem();
+		}
+		else if(was_open && !openitem)
+		{
+		getViewModelItem()->closeItem();
+	}
+
+	if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
+	{
+		for (folders_t::iterator iter = mFolders.begin();
+			iter != mFolders.end();)
+		{
+			folders_t::iterator fit = iter++;
+			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */
+		}
+	}
+	if (mParentFolder
+		&&	(recurse == RECURSE_UP
+			|| recurse == RECURSE_UP_DOWN))
+	{
+		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
+	}
+
+	if (was_open != isOpen())
+	{
+		requestArrange();
+	}
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
+													BOOL drop,
+													EDragAndDropType c_type,
+													void* cargo_data,
+													EAcceptance* accept,
+													std::string& tooltip_msg)
+{
+	BOOL accepted = mViewModelItem->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
+	if (accepted) 
+	{
+		mDragAndDropTarget = TRUE;
+		*accept = ACCEPT_YES_MULTI;
+	}
+	else 
+	{
+		*accept = ACCEPT_NO;
+	}
+
+	// drag and drop to child item, so clear pending auto-opens
+	getRoot()->autoOpenTest(NULL);
+
+	return TRUE;
+}
+
+void LLFolderViewFolder::openItem( void )
+{
+	toggleOpen();
+}
+
+void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
+{
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		functor.doItem((*fit));
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		functor.doItem((*iit));
+	}
+}
+
+void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
+{
+	functor.doFolder(this);
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		(*fit)->applyFunctorRecursively(functor);
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		functor.doItem((*iit));
+	}
+}
+
+// LLView functionality
+BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
+										   BOOL drop,
+										   EDragAndDropType cargo_type,
+										   void* cargo_data,
+										   EAcceptance* accept,
+										   std::string& tooltip_msg)
+{
+	BOOL handled = FALSE;
+
+	if (isOpen())
+	{
+		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
+	}
+
+	if (!handled)
+	{
+		handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
+
+		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
+	}
+
+	return TRUE;
+}
+
+BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
+													   BOOL drop,
+													   EDragAndDropType cargo_type,
+													   void* cargo_data,
+													   EAcceptance* accept,
+													   std::string& tooltip_msg)
+{
+	BOOL accepted = getViewModelItem()->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
+	
+	if (accepted) 
+	{
+		mDragAndDropTarget = TRUE;
+		*accept = ACCEPT_YES_MULTI;
+	}
+	else 
+	{
+		*accept = ACCEPT_NO;
+	}
+	
+	if (!drop && accepted)
+	{
+		getRoot()->autoOpenTest(this);
+	}
+	
+	return TRUE;
+}
+
+
+BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	if( isOpen() )
+	{
+		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
+	}
+	if (!handled)
+	{
+		handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
+	}
+	return handled;
+}
+
+
+BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
+{
+	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
+
+	BOOL handled = LLView::handleHover(x, y, mask);
+
+	if (!handled)
+	{
+		// this doesn't do child processing
+		handled = LLFolderViewItem::handleHover(x, y, mask);
+	}
+
+	return handled;
+}
+
+BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+	if( isOpen() )
+	{
+		handled = childrenHandleMouseDown(x,y,mask) != NULL;
+	}
+	if( !handled )
+	{
+		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
+		{
+			toggleOpen();
+			handled = TRUE;
+		}
+		else
+		{
+			// do normal selection logic
+			handled = LLFolderViewItem::handleMouseDown(x, y, mask);
+		}
+	}
+
+	return handled;
+}
+
+BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
+{
+	BOOL handled = FALSE;
+	if( isOpen() )
+	{
+		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
+	}
+	if( !handled )
+	{
+		if(mIndentation < x && x < mIndentation + (isCollapsed() ? 0 : mArrowSize) + mTextPad)
+		{
+			// don't select when user double-clicks plus sign
+			// so as not to contradict single-click behavior
+			toggleOpen();
+		}
+		else
+		{
+			getRoot()->setSelection(this, FALSE);
+			toggleOpen();
+		}
+		handled = TRUE;
+	}
+	return handled;
+}
+
+void LLFolderViewFolder::draw()
+{
+	updateLabelRotation();
+
+	LLFolderViewItem::draw();
+
+	// draw children if root folder, or any other folder that is open or animating to closed state
+	if( getRoot() == this || (isOpen() || mCurHeight != mTargetHeight ))
+	{
+		LLView::draw();
+	}
+
+	mExpanderHighlighted = FALSE;
+}
+
+// this does prefix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+	BOOL found_item = FALSE;
+
+	LLFolderViewItem* result = NULL;
+	// when not starting from a given item, start at beginning
+	if(item == NULL)
+	{
+		found_item = TRUE;
+	}
+
+	// find current item among children
+	folders_t::iterator fit = mFolders.begin();
+	folders_t::iterator fend = mFolders.end();
+
+	items_t::iterator iit = mItems.begin();
+	items_t::iterator iend = mItems.end();
+
+	// if not trivially starting at the beginning, we have to find the current item
+	if (!found_item)
+	{
+		// first, look among folders, since they are always above items
+		for(; fit != fend; ++fit)
+		{
+			if(item == (*fit))
+			{
+				found_item = TRUE;
+				// if we are on downwards traversal
+				if (include_children && (*fit)->isOpen())
+				{
+					// look for first descendant
+					return (*fit)->getNextFromChild(NULL, TRUE);
+				}
+				// otherwise advance to next folder
+				++fit;
+				include_children = TRUE;
+				break;
+			}
+		}
+
+		// didn't find in folders?  Check items...
+		if (!found_item)
+		{
+			for(; iit != iend; ++iit)
+			{
+				if(item == (*iit))
+				{
+					found_item = TRUE;
+					// point to next item
+					++iit;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!found_item)
+	{
+		// you should never call this method with an item that isn't a child
+		// so we should always find something
+		llassert(FALSE);
+		return NULL;
+	}
+
+	// at this point, either iit or fit point to a candidate "next" item
+	// if both are out of range, we need to punt up to our parent
+
+	// now, starting from found folder, continue through folders
+	// searching for next visible folder
+	while(fit != fend && !(*fit)->getVisible())
+	{
+		// turn on downwards traversal for next folder
+		++fit;
+	} 
+
+	if (fit != fend)
+	{
+		result = (*fit);
+	}
+	else
+	{
+		// otherwise, scan for next visible item
+		while(iit != iend && !(*iit)->getVisible())
+		{
+			++iit;
+		} 
+
+		// check to see if we have a valid item
+		if (iit != iend)
+		{
+			result = (*iit);
+		}
+	}
+
+	if( !result && mParentFolder )
+	{
+		// If there are no siblings or children to go to, recurse up one level in the tree
+		// and skip children for this folder, as we've already discounted them
+		result = mParentFolder->getNextFromChild(this, FALSE);
+	}
+
+	return result;
+}
+
+// this does postfix traversal, as folders are listed above their contents
+LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
+{
+	BOOL found_item = FALSE;
+
+	LLFolderViewItem* result = NULL;
+	// when not starting from a given item, start at end
+	if(item == NULL)
+	{
+		found_item = TRUE;
+	}
+
+	// find current item among children
+	folders_t::reverse_iterator fit = mFolders.rbegin();
+	folders_t::reverse_iterator fend = mFolders.rend();
+
+	items_t::reverse_iterator iit = mItems.rbegin();
+	items_t::reverse_iterator iend = mItems.rend();
+
+	// if not trivially starting at the end, we have to find the current item
+	if (!found_item)
+	{
+		// first, look among items, since they are always below the folders
+		for(; iit != iend; ++iit)
+		{
+			if(item == (*iit))
+			{
+				found_item = TRUE;
+				// point to next item
+				++iit;
+				break;
+			}
+		}
+
+		// didn't find in items?  Check folders...
+		if (!found_item)
+		{
+			for(; fit != fend; ++fit)
+			{
+				if(item == (*fit))
+				{
+					found_item = TRUE;
+					// point to next folder
+					++fit;
+					break;
+				}
+			}
+		}
+	}
+
+	if (!found_item)
+	{
+		// you should never call this method with an item that isn't a child
+		// so we should always find something
+		llassert(FALSE);
+		return NULL;
+	}
+
+	// at this point, either iit or fit point to a candidate "next" item
+	// if both are out of range, we need to punt up to our parent
+
+	// now, starting from found item, continue through items
+	// searching for next visible item
+	while(iit != iend && !(*iit)->getVisible())
+	{
+		++iit;
+	} 
+
+	if (iit != iend)
+	{
+		// we found an appropriate item
+		result = (*iit);
+	}
+	else
+	{
+		// otherwise, scan for next visible folder
+		while(fit != fend && !(*fit)->getVisible())
+		{
+			++fit;
+		} 
+
+		// check to see if we have a valid folder
+		if (fit != fend)
+		{
+			// try selecting child element of this folder
+			if ((*fit)->isOpen() && include_children)
+			{
+				result = (*fit)->getPreviousFromChild(NULL);
+			}
+			else
+			{
+				result = (*fit);
+			}
+		}
+	}
+
+	if( !result )
+	{
+		// If there are no siblings or children to go to, recurse up one level in the tree
+		// which gets back to this folder, which will only be visited if it is a valid, visible item
+		result = this;
+	}
+
+	return result;
+}
+
diff --git a/indra/newview/llfolderviewitem.h b/indra/llui/llfolderviewitem.h
old mode 100644
new mode 100755
similarity index 53%
rename from indra/newview/llfolderviewitem.h
rename to indra/llui/llfolderviewitem.h
index 577b6b54a26a4918f79292d50a6a93431fb1d93a..ca31931e19443d94400473c4c1189fcc50217c71
--- a/indra/newview/llfolderviewitem.h
+++ b/indra/llui/llfolderviewitem.h
@@ -26,55 +26,16 @@
 #ifndef LLFOLDERVIEWITEM_H
 #define LLFOLDERVIEWITEM_H
 
+#include "llflashtimer.h"
 #include "llview.h"
-#include "lldarray.h"  // *TODO: Eliminate, forward declare
 #include "lluiimage.h"
 
-class LLFontGL;
 class LLFolderView;
-class LLFolderViewEventListener;
+class LLFolderViewModelItem;
 class LLFolderViewFolder;
 class LLFolderViewFunctor;
-class LLFolderViewItem;
-class LLFolderViewListenerFunctor;
-class LLInventoryFilter;
-class LLMenuGL;
-class LLUIImage;
-class LLViewerInventoryItem;
-
-// These are grouping of inventory types.
-// Order matters when sorting system folders to the top.
-enum EInventorySortGroup
-{ 
-	SG_SYSTEM_FOLDER, 
-	SG_TRASH_FOLDER, 
-	SG_NORMAL_FOLDER, 
-	SG_ITEM 
-};
-
-// *TODO: do we really need one sort object per folder?
-// can we just have one of these per LLFolderView ?
-class LLInventorySort
-{
-public:
-	LLInventorySort() 
-		: mSortOrder(0),
-		mByDate(false),
-		mSystemToTop(false),
-		mFoldersByName(false) { }
-
-	// Returns true if order has changed
-	bool updateSort(U32 order);
-	U32 getSort() { return mSortOrder; }
-	bool isByDate() { return mByDate; }
-
-	bool operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b);
-private:
-	U32  mSortOrder;
-	bool mByDate;
-	bool mSystemToTop;
-	bool mFoldersByName;
-};
+class LLFolderViewFilter;
+class LLFolderViewModelInterface;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewItem
@@ -86,134 +47,130 @@ class LLInventorySort
 class LLFolderViewItem : public LLView
 {
 public:
-	static void initClass();
-	static void cleanupClass();
-
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
-		Optional<LLUIImage*>					icon;
-		Optional<LLUIImage*>					icon_open;  // used for folders
-		Optional<LLUIImage*>					icon_overlay;  // for links
-		Optional<LLFolderView*>					root;
-		Mandatory<LLFolderViewEventListener*>	listener;
-
-		Optional<LLUIImage*>					folder_arrow_image;
-		Optional<S32>							folder_indentation; // pixels
-		Optional<LLUIImage*>					selection_image;
-		Optional<S32>							item_height; // pixels
-		Optional<S32>							item_top_pad; // pixels
-
-		Optional<S32>							creation_date; //UTC seconds
-
+		Optional<LLUIImage*>						folder_arrow_image,
+													selection_image;
+		Mandatory<LLFolderView*>					root;
+		Mandatory<LLFolderViewModelItem*>			listener;
+
+		Optional<S32>								folder_indentation, // pixels
+													item_height,
+													item_top_pad;
+
+		Optional<time_t>							creation_date;
+		Optional<bool>								allow_open;
+
+		Optional<LLUIColor>                         font_color;
+		Optional<LLUIColor>                         font_highlight_color;
+		
+        Optional<S32>                               left_pad,
+                                                    icon_pad,
+                                                    icon_width,
+                                                    text_pad,
+                                                    text_pad_right,
+                                                    arrow_size,
+                                                    max_folder_item_overlap;
 		Params();
 	};
 
-	// layout constants
-	static const S32 LEFT_PAD = 5;
-	// LEFT_INDENTATION is set via folder_indentation above
-	static const S32 ICON_PAD = 2;
-	static const S32 ICON_WIDTH = 16;
-	static const S32 TEXT_PAD = 1;
-	static const S32 TEXT_PAD_RIGHT = 4;
-	static const S32 ARROW_SIZE = 12;
-	static const S32 MAX_FOLDER_ITEM_OVERLAP = 2;
-	// animation parameters
-	static const F32 FOLDER_CLOSE_TIME_CONSTANT;
-	static const F32 FOLDER_OPEN_TIME_CONSTANT;
-
-	// Mostly for debugging printout purposes.
-	const std::string& getSearchableLabel() { return mSearchableLabel; }
-	
-	BOOL isLoading() const { return mIsLoading; }
 
-private:
-	BOOL						mIsSelected;
+	static const S32    DEFAULT_LABEL_PADDING_RIGHT = 4;
+	// animation parameters
+	static const F32	FOLDER_CLOSE_TIME_CONSTANT,
+						FOLDER_OPEN_TIME_CONSTANT;
 
 protected:
 	friend class LLUICtrlFactory;
-	friend class LLFolderViewEventListener;
+	friend class LLFolderViewModelItem;
 
 	LLFolderViewItem(const Params& p);
 
 	std::string					mLabel;
-	std::string					mSearchableLabel;
 	S32							mLabelWidth;
 	bool						mLabelWidthDirty;
-	time_t						mCreationDate;
+    S32                         mLabelPaddingRight;
 	LLFolderViewFolder*			mParentFolder;
-	LLFolderViewEventListener*	mListener;
-	BOOL						mIsCurSelection;
-	BOOL						mSelectPending;
+	LLPointer<LLFolderViewModelItem> mViewModelItem;
 	LLFontGL::StyleFlags		mLabelStyle;
 	std::string					mLabelSuffix;
-	LLUIImagePtr				mIcon;
-	std::string					mStatusText;
-	LLUIImagePtr				mIconOpen;
-	LLUIImagePtr				mIconOverlay;
-	BOOL						mHasVisibleChildren;
+	LLUIImagePtr				mIcon,
+								mIconOpen,
+								mIconOverlay;
+    S32                         mLocalIndentation;
 	S32							mIndentation;
 	S32							mItemHeight;
-	BOOL						mPassedFilter;
-	S32							mLastFilterGeneration;
-	std::string::size_type		mStringMatchOffset;
+	S32							mDragStartX,
+								mDragStartY;
+
+    S32                         mLeftPad,
+                                mIconPad,
+                                mIconWidth,
+                                mTextPad,
+                                mTextPadRight,
+                                mArrowSize,
+                                mMaxFolderItemOverlap;
+
 	F32							mControlLabelRotation;
 	LLFolderView*				mRoot;
-	BOOL						mDragAndDropTarget;
-	BOOL                        mIsLoading;
-	LLTimer                     mTimeSinceRequestStart;
-	bool						mShowLoadStatus;
-	bool						mIsMouseOverTitle;
-
-	// helper function to change the selection from the root.
-	void changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected);
+	bool						mHasVisibleChildren,
+								mIsCurSelection,
+								mDragAndDropTarget,
+								mIsMouseOverTitle,
+								mAllowOpen,
+								mSelectPending;
+	
+	LLUIColor                   mFontColor;
+	LLUIColor                   mFontHighlightColor;
+
+	// For now assuming all colors are the same in derived classes.
+	static bool                 sColorSetInitialized;
+	static LLUIColor			sFgColor;
+	static LLUIColor			sFgDisabledColor;
+	static LLUIColor			sHighlightBgColor;
+	static LLUIColor			sFlashBgColor;
+	static LLUIColor			sFocusOutlineColor;
+	static LLUIColor			sMouseOverColor;
+	static LLUIColor			sFilterBGColor;
+	static LLUIColor			sFilterTextColor;
+	static LLUIColor			sSuffixColor;
+	static LLUIColor			sSearchStatusColor;
 
 	// this is an internal method used for adding items to folders. A
 	// no-op at this level, but reimplemented in derived classes.
-	virtual BOOL addItem(LLFolderViewItem*) { return FALSE; }
-	virtual BOOL addFolder(LLFolderViewFolder*) { return FALSE; }
+	virtual void addItem(LLFolderViewItem*) { }
+	virtual void addFolder(LLFolderViewFolder*) { }
+	virtual bool isHighlightAllowed();
+	virtual bool isHighlightActive();
+	virtual bool isFlashing() { return false; }
+	virtual void setFlashState(bool) { }
 
 	static LLFontGL* getLabelFontForStyle(U8 style);
 
-	virtual void setCreationDate(time_t creation_date_utc)	{ mCreationDate = creation_date_utc; }
+	BOOL						mIsSelected;
 
 public:
+	static void initClass();
+	static void cleanupClass();
+
 	BOOL postBuild();
 
-	// This function clears the currently selected item, and records
-	// the specified selected item appropriately for display and use
-	// in the UI. If open is TRUE, then folders are opened up along
-	// the way to the selection.
-	void setSelectionFromRoot(LLFolderViewItem* selection, BOOL openitem,
-		BOOL take_keyboard_focus = TRUE);
-
-	// This function is called when the folder view is dirty. It's
-	// implemented here but called by derived classes when folding the
-	// views.
-	void arrangeFromRoot();
-	void filterFromRoot( void );
-	
+	virtual void openItem( void );
+
 	void arrangeAndSet(BOOL set_selection, BOOL take_keyboard_focus);
 
 	virtual ~LLFolderViewItem( void );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	enum { ARRANGE = TRUE, DO_NOT_ARRANGE = FALSE };
-	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
-
-	virtual EInventorySortGroup getSortGroup() const;
+	virtual void addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
 	virtual S32 getItemHeight();
-
-	// applies filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
-
-	// updates filter serial number and optionally propagated value up to root
-	S32		getLastFilterGeneration() { return mLastFilterGeneration; }
-
-	virtual void	dirtyFilter();
+    virtual S32 getLabelXPos();
+    S32 getIconPad();
+    S32 getTextPad();
 
 	// If 'selection' is 'this' then note that otherwise ignore.
 	// Returns TRUE if this item ends up being selected.
@@ -231,7 +188,7 @@ class LLFolderViewItem : public LLView
 	virtual void selectItem();
 
 	// gets multiple-element selection
-	virtual std::set<LLUUID> getSelectionList() const;
+	virtual std::set<LLFolderViewItem*> getSelectionList() const;
 
 	// Returns true is this object and all of its children can be removed (deleted by user)
 	virtual BOOL isRemovable();
@@ -253,74 +210,54 @@ class LLFolderViewItem : public LLView
 
 	BOOL hasVisibleChildren() { return mHasVisibleChildren; }
 
-	void setShowLoadStatus(bool status) { mShowLoadStatus = status; }
-
 	// Call through to the viewed object and return true if it can be
 	// removed. Returns true if it's removed.
 	//virtual BOOL removeRecursively(BOOL single_item);
 	BOOL remove();
 
 	// Build an appropriate context menu for the item.	Flags unused.
-	void buildContextMenu(LLMenuGL& menu, U32 flags);
+	void buildContextMenu(class LLMenuGL& menu, U32 flags);
 
 	// This method returns the actual name of the thing being
 	// viewed. This method will ask the viewed object itself.
 	const std::string& getName( void ) const;
 
-	const std::string& getSearchableLabel( void ) const;
-
 	// This method returns the label displayed on the view. This
 	// method was primarily added to allow sorting on the folder
 	// contents possible before the entire view has been constructed.
 	const std::string& getLabel() const { return mLabel; }
 
-	// Used for sorting, like getLabel() above.
-	virtual time_t getCreationDate() const { return mCreationDate; }
-
 	LLFolderViewFolder* getParentFolder( void ) { return mParentFolder; }
 	const LLFolderViewFolder* getParentFolder( void ) const { return mParentFolder; }
 
+	void setParentFolder(LLFolderViewFolder* parent) { mParentFolder = parent; }
+
 	LLFolderViewItem* getNextOpenNode( BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousOpenNode( BOOL include_children = TRUE );
 
-	const LLFolderViewEventListener* getListener( void ) const { return mListener; }
-	LLFolderViewEventListener* getListener( void ) { return mListener; }
-	
-	// Gets the inventory item if it exists (null otherwise)
-	LLViewerInventoryItem * getInventoryItem(void);
+	const LLFolderViewModelItem* getViewModelItem( void ) const { return mViewModelItem; }
+	LLFolderViewModelItem* getViewModelItem( void ) { return mViewModelItem; }
+
+	const LLFolderViewModelInterface* getFolderViewModel( void ) const;
+	LLFolderViewModelInterface* getFolderViewModel( void );
 
 	// just rename the object.
 	void rename(const std::string& new_name);
 
-	// open
-	virtual void openItem( void );
-	virtual void preview(void);
-
-	// Show children (unfortunate that this is called "open")
+	// Show children
 	virtual void setOpen(BOOL open = TRUE) {};
-
 	virtual BOOL isOpen() const { return FALSE; }
 
 	virtual LLFolderView*	getRoot();
+	virtual const LLFolderView*	getRoot() const;
 	BOOL			isDescendantOf( const LLFolderViewFolder* potential_ancestor );
 	S32				getIndentation() { return mIndentation; }
 
-	virtual BOOL	potentiallyVisible(); // do we know for a fact that this item won't be displayed?
-	virtual BOOL	potentiallyFiltered(); // do we know for a fact that this item has been filtered out?
-
-	virtual BOOL	getFiltered();
-	virtual BOOL	getFiltered(S32 filter_generation);
-	virtual void	setFiltered(BOOL filtered, S32 filter_generation);
-
-	// change the icon
-	void setIcon(LLUIImagePtr icon);
+	virtual BOOL	passedFilter(S32 filter_generation = -1);
 
 	// refresh information from the object being viewed.
-	void refreshFromListener();
 	virtual void refresh();
 
-	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
-
 	// LLView functionality
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
@@ -330,25 +267,23 @@ class LLFolderViewItem : public LLView
 
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 
-	virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return NULL; }
+	//virtual LLView* findChildView(const std::string& name, BOOL recurse) const { return LLView::findChildView(name, recurse); }
 
 	//	virtual void handleDropped();
 	virtual void draw();
+	void drawOpenFolderArrow(const Params& default_params, const LLUIColor& fg_color);
+    void drawHighlight(const BOOL showContent, const BOOL hasKeyboardFocus, const LLUIColor &selectColor, const LLUIColor &flashColor, const LLUIColor &outlineColor, const LLUIColor &mouseOverColor);
+    void drawLabel(const LLFontGL * font, const F32 x, const F32 y, const LLColor4& color, F32 &right_x);
 	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
 
 private:
 	static std::map<U8, LLFontGL*> sFonts; // map of styles to fonts
 };
 
-
-// function used for sorting.
-typedef bool (*sort_order_f)(LLFolderViewItem* a, LLFolderViewItem* b);
-
-
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLFolderViewFolder
 //
@@ -363,33 +298,26 @@ class LLFolderViewFolder : public LLFolderViewItem
 	LLFolderViewFolder( const LLFolderViewItem::Params& );
 	friend class LLUICtrlFactory;
 
-public:
-	typedef enum e_trash
-	{
-		UNKNOWN, TRASH, NOT_TRASH
-	} ETrash;
+	void updateLabelRotation();
+	virtual bool isCollapsed() { return FALSE; }
 
+public:
 	typedef std::list<LLFolderViewItem*> items_t;
 	typedef std::list<LLFolderViewFolder*> folders_t;
 
 protected:
 	items_t mItems;
 	folders_t mFolders;
-	LLInventorySort	mSortFunction;
 
 	BOOL		mIsOpen;
 	BOOL		mExpanderHighlighted;
 	F32			mCurHeight;
 	F32			mTargetHeight;
 	F32			mAutoOpenCountdown;
-	time_t		mSubtreeCreationDate;
-	mutable ETrash mAmTrash;
 	S32			mLastArrangeGeneration;
 	S32			mLastCalculatedWidth;
-	S32			mCompletedFilterGeneration;
 	S32			mMostFilteredDescendantGeneration;
 	bool		mNeedsSort;
-	bool		mPassedFolderFilter;
 
 public:
 	typedef enum e_recurse_type
@@ -403,48 +331,25 @@ class LLFolderViewFolder : public LLFolderViewItem
 
 	virtual ~LLFolderViewFolder( void );
 
-	virtual BOOL	potentiallyVisible();
-
 	LLFolderViewItem* getNextFromChild( LLFolderViewItem*, BOOL include_children = TRUE );
 	LLFolderViewItem* getPreviousFromChild( LLFolderViewItem*, BOOL include_children = TRUE  );
 
 	// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-	virtual BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+	virtual void addToFolder(LLFolderViewFolder* folder);
 
 	// Finds width and height of this object and it's children.  Also
 	// makes sure that this view and it's children are the right size.
-	virtual S32 arrange( S32* width, S32* height, S32 filter_generation );
+	virtual S32 arrange( S32* width, S32* height );
 
 	BOOL needsArrange();
-	void requestSort();
-
-	// Returns the sort group (system, trash, folder) for this folder.
-	virtual EInventorySortGroup getSortGroup() const;
 
-	virtual void	setCompletedFilterGeneration(S32 generation, BOOL recurse_up);
-	virtual S32		getCompletedFilterGeneration() { return mCompletedFilterGeneration; }
-
-	BOOL hasFilteredDescendants(S32 filter_generation);
-	BOOL hasFilteredDescendants();
-
-	// applies filters to control visibility of inventory items
-	virtual void filter( LLInventoryFilter& filter);
-	virtual void setFiltered(BOOL filtered, S32 filter_generation);
-	virtual BOOL getFiltered();
-	virtual BOOL getFiltered(S32 filter_generation);
-
-	virtual void dirtyFilter();
-	
-	// folder-specific filtering (filter status propagates top down instead of bottom up)
-	void filterFolder(LLInventoryFilter& filter);
-	void setFilteredFolder(bool filtered, S32 filter_generation);
-	bool getFilteredFolder(S32 filter_generation);
+	bool descendantsPassedFilter(S32 filter_generation = -1);
 
 	// Passes selection information on to children and record
 	// selection information if necessary.
 	// Returns TRUE if this object (or a child) ends up being selected.
 	// If 'openitem' is TRUE then folders are opened up along the way to the selection.
-	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus);
+	virtual BOOL setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus = TRUE);
 
 	// This method is used to change the selection of an item.
 	// Recursively traverse all children; if 'selection' is 'this' then change
@@ -464,31 +369,13 @@ class LLFolderViewFolder : public LLFolderViewItem
 	// destroys this folder, and all children
 	virtual void destroyView();
 
-	// If this folder can be removed, remove all children that can be
-	// removed, return TRUE if this is empty after the operation and
-	// it's viewed folder object can be removed.
-	//virtual BOOL removeRecursively(BOOL single_item);
-	//virtual BOOL remove();
-
-	// remove the specified item (and any children) if
-	// possible. Return TRUE if the item was deleted.
-	BOOL removeItem(LLFolderViewItem* item);
-
-	// simply remove the view (and any children) Don't bother telling
-	// the listeners.
-	void removeView(LLFolderViewItem* item);
-
 	// extractItem() removes the specified item from the folder, but
 	// doesn't delete it.
-	void extractItem( LLFolderViewItem* item );
+	virtual void extractItem( LLFolderViewItem* item );
 
 	// This function is called by a child that needs to be resorted.
 	void resort(LLFolderViewItem* item);
 
-	void setItemSortOrder(U32 ordering);
-	void sortBy(U32);
-	//BOOL (*func)(LLFolderViewItem* a, LLFolderViewItem* b));
-
 	void setAutoOpenCountdown(F32 countdown) { mAutoOpenCountdown = countdown; }
 
 	// folders can be opened. This will usually be called by internal
@@ -499,8 +386,7 @@ class LLFolderViewFolder : public LLFolderViewItem
 	virtual void setOpen(BOOL openitem = TRUE);
 
 	// Called when a child is refreshed.
-	// don't rearrange child folder contents unless explicitly requested
-	virtual void requestArrange(BOOL include_descendants = FALSE);
+	virtual void requestArrange();
 
 	// internal method which doesn't update the entire view. This
 	// method was written because the list iterators destroy the state
@@ -513,65 +399,60 @@ class LLFolderViewFolder : public LLFolderViewItem
 
 	// special case if an object is dropped on the child.
 	BOOL handleDragAndDropFromChild(MASK mask,
-		BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
+									BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
 
-	void applyFunctorRecursively(LLFolderViewFunctor& functor);
-	virtual void applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor);
 
 	// Just apply this functor to the folder's immediate children.
 	void applyFunctorToChildren(LLFolderViewFunctor& functor);
+	// apply this functor to the folder's descendants.
+	void applyFunctorRecursively(LLFolderViewFunctor& functor);
 
 	virtual void openItem( void );
-	virtual BOOL addItem(LLFolderViewItem* item);
-	virtual BOOL addFolder( LLFolderViewFolder* folder);
 
 	// LLView functionality
 	virtual BOOL handleHover(S32 x, S32 y, MASK mask);
 	virtual BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
 	virtual BOOL handleDoubleClick( S32 x, S32 y, MASK mask );
-	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-		EDragAndDropType cargo_type,
-		void* cargo_data,
-		EAcceptance* accept,
-		std::string& tooltip_msg);
-	BOOL handleDragAndDropToThisFolder(MASK mask, BOOL drop,
+	virtual BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, 
+									BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+									std::string& tooltip_msg);
+	BOOL handleDragAndDropToThisFolder(MASK mask, 
+										BOOL drop,
 									   EDragAndDropType cargo_type,
 									   void* cargo_data,
 									   EAcceptance* accept,
 									   std::string& tooltip_msg);
 	virtual void draw();
 
-	time_t getCreationDate() const;
-	bool isTrash() const;
-
-	folders_t::const_iterator getFoldersBegin() const { return mFolders.begin(); }
-	folders_t::const_iterator getFoldersEnd() const { return mFolders.end(); }
+	folders_t::iterator getFoldersBegin() { return mFolders.begin(); }
+	folders_t::iterator getFoldersEnd() { return mFolders.end(); }
 	folders_t::size_type getFoldersCount() const { return mFolders.size(); }
 
 	items_t::const_iterator getItemsBegin() const { return mItems.begin(); }
 	items_t::const_iterator getItemsEnd() const { return mItems.end(); }
 	items_t::size_type getItemsCount() const { return mItems.size(); }
+
 	LLFolderViewFolder* getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse);
 	void gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse,  std::vector<LLFolderViewItem*>& items);
-};
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewListenerFunctor
-//
-// This simple abstract base class can be used to applied to all
-// listeners in a hierarchy.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+	// internal functions for tracking folders and items separately
+	// use addToFolder() virtual method to ensure folders are always added to mFolders
+	// and not mItems
+	void addItem(LLFolderViewItem* item);
+	void addFolder( LLFolderViewFolder* folder);
 
-class LLFolderViewListenerFunctor
-{
-public:
-	virtual ~LLFolderViewListenerFunctor() {}
-	virtual void operator()(LLFolderViewEventListener* listener) = 0;
+	//WARNING: do not call directly...use the appropriate LLFolderViewModel-derived class instead
+	template<typename SORT_FUNC> void sortFolders(const SORT_FUNC& func) { mFolders.sort(func); }
+	template<typename SORT_FUNC> void sortItems(const SORT_FUNC& func) { mItems.sort(func); }
 };
 
+
 #endif  // LLFOLDERVIEWITEM_H
diff --git a/indra/llui/llfolderviewmodel.cpp b/indra/llui/llfolderviewmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3593804554aa722b08ed9943423b059b19a6f7a4
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.cpp
@@ -0,0 +1,68 @@
+/** 
+ * @file llfolderviewmodel.cpp
+ * @brief Implementation of the view model collection of classes.
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llfolderviewmodel.h"
+#include "lltrans.h"
+
+bool LLFolderViewModelCommon::needsSort(LLFolderViewModelItem* item)
+{
+	return item->getSortVersion() < mTargetSortVersion;
+}
+
+std::string LLFolderViewModelCommon::getStatusText()
+{
+	if (!contentsReady() || mFolderView->getViewModelItem()->getLastFilterGeneration() < getFilter().getCurrentGeneration())
+	{
+		return LLTrans::getString("Searching");
+	}
+	else
+	{
+		return getFilter().getEmptyLookupMessage();
+	}
+}
+
+void LLFolderViewModelCommon::filter()
+{
+	getFilter().setFilterCount(llclamp(LLUI::sSettingGroups["config"]->getS32("FilterItemsPerFrame"), 1, 5000));
+	mFolderView->getViewModelItem()->filter(getFilter());
+}
+
+bool LLFolderViewModelItemCommon::hasFilterStringMatch()
+{
+	return mStringMatchOffsetFilter != std::string::npos;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringOffset()
+{
+	return mStringMatchOffsetFilter;
+}
+
+std::string::size_type LLFolderViewModelItemCommon::getFilterStringSize()
+{
+	return mRootViewModel.getFilter().getFilterStringSize();
+}
diff --git a/indra/llui/llfolderviewmodel.h b/indra/llui/llfolderviewmodel.h
new file mode 100644
index 0000000000000000000000000000000000000000..1b61212c0eadf6e9de74777a52de31e8df456ab2
--- /dev/null
+++ b/indra/llui/llfolderviewmodel.h
@@ -0,0 +1,444 @@
+/** 
+ * @file llfolderviewmodel.h
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+#ifndef LLFOLDERVIEWMODEL_H
+#define LLFOLDERVIEWMODEL_H
+
+#include "llfontgl.h"	// just for StyleFlags enum
+#include "llfolderview.h"
+
+// These are grouping of inventory types.
+// Order matters when sorting system folders to the top.
+enum EInventorySortGroup
+{
+	SG_SYSTEM_FOLDER,
+	SG_TRASH_FOLDER,
+	SG_NORMAL_FOLDER,
+	SG_ITEM
+};
+
+class LLFontGL;
+class LLInventoryModel;
+class LLMenuGL;
+class LLUIImage;
+class LLUUID;
+class LLFolderViewItem;
+class LLFolderViewFolder;
+
+class LLFolderViewFilter
+{
+public:
+	enum EFilterModified
+	{
+		FILTER_NONE,				// nothing to do, already filtered
+		FILTER_RESTART,				// restart filtering from scratch
+		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
+		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
+	};
+
+public:
+
+	LLFolderViewFilter() {}
+	virtual ~LLFolderViewFilter() {}
+
+	// +-------------------------------------------------------------------+
+	// + Execution And Results
+	// +-------------------------------------------------------------------+
+	virtual bool 				check(const LLFolderViewModelItem* item) = 0;
+	virtual bool				checkFolder(const LLFolderViewModelItem* folder) const = 0;
+
+	virtual void 				setEmptyLookupMessage(const std::string& message) = 0;
+	virtual std::string			getEmptyLookupMessage() const = 0;
+
+	virtual bool				showAllResults() const = 0;
+
+	virtual std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const = 0;
+	virtual std::string::size_type getFilterStringSize() const = 0;
+	// +-------------------------------------------------------------------+
+	// + Status
+	// +-------------------------------------------------------------------+
+	virtual bool 				isActive() const = 0;
+	virtual bool 				isModified() const = 0;
+	virtual void 				clearModified() = 0;
+	virtual const std::string& 	getName() const = 0;
+	virtual const std::string& 	getFilterText() = 0;
+	//RN: this is public to allow system to externally force a global refilter
+	virtual void 				setModified(EFilterModified behavior = FILTER_RESTART) = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Count
+	// +-------------------------------------------------------------------+
+	virtual void 				setFilterCount(S32 count) = 0;
+	virtual S32 				getFilterCount() const = 0;
+	virtual void 				decrementFilterCount() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Default
+	// +-------------------------------------------------------------------+
+	virtual bool 				isDefault() const = 0;
+	virtual bool 				isNotDefault() const = 0;
+	virtual void 				markDefault() = 0;
+	virtual void 				resetDefault() = 0;
+
+	// +-------------------------------------------------------------------+
+	// + Generation
+	// +-------------------------------------------------------------------+
+	virtual S32 				getCurrentGeneration() const = 0;
+	virtual S32 				getFirstSuccessGeneration() const = 0;
+	virtual S32 				getFirstRequiredGeneration() const = 0;
+};
+
+class LLFolderViewModelInterface
+{
+public:
+	virtual ~LLFolderViewModelInterface() {}
+	virtual void requestSortAll() = 0;
+
+	virtual void sort(class LLFolderViewFolder*) = 0;
+	virtual void filter() = 0;
+
+	virtual bool contentsReady() = 0;
+	virtual void setFolderView(LLFolderView* folder_view) = 0;
+	virtual LLFolderViewFilter& getFilter() = 0;
+	virtual const LLFolderViewFilter& getFilter() const = 0;
+	virtual std::string getStatusText() = 0;
+
+	virtual bool startDrag(std::vector<LLFolderViewModelItem*>& items) = 0;
+};
+
+// This is an abstract base class that users of the folderview classes
+// would use to bridge the folder view with the underlying data
+class LLFolderViewModelItem : public LLRefCount
+{
+public:
+	LLFolderViewModelItem() { }
+	virtual ~LLFolderViewModelItem() { }
+
+	virtual void update() {}	//called when drawing
+	virtual const std::string& getName() const = 0;
+	virtual const std::string& getDisplayName() const = 0;
+	virtual const std::string& getSearchableName() const = 0;
+
+	virtual LLPointer<LLUIImage> getIcon() const = 0;
+	virtual LLPointer<LLUIImage> getIconOpen() const { return getIcon(); }
+	virtual LLPointer<LLUIImage> getIconOverlay() const { return NULL; }
+
+	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
+	virtual std::string getLabelSuffix() const = 0;
+
+	virtual void openItem( void ) = 0;
+	virtual void closeItem( void ) = 0;
+	virtual void selectItem(void) = 0;
+
+	virtual BOOL isItemRenameable() const = 0;
+	virtual BOOL renameItem(const std::string& new_name) = 0;
+
+	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
+	virtual void move( LLFolderViewModelItem* parent_listener ) = 0;
+
+	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
+	virtual BOOL removeItem() = 0;
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) = 0;
+
+	virtual BOOL isItemCopyable() const = 0;
+	virtual BOOL copyToClipboard() const = 0;
+	virtual BOOL cutToClipboard() const = 0;
+
+	virtual BOOL isClipboardPasteable() const = 0;
+	virtual void pasteFromClipboard() = 0;
+	virtual void pasteLinkFromClipboard() = 0;
+
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
+	
+	virtual bool potentiallyVisible() = 0; // is the item definitely visible or we haven't made up our minds yet?
+
+	virtual bool filter( LLFolderViewFilter& filter) = 0;
+	virtual bool passedFilter(S32 filter_generation = -1) = 0;
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) = 0;
+	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) = 0;
+	virtual void setPassedFolderFilter(bool passed, S32 filter_generation) = 0;
+	virtual void dirtyFilter() = 0;
+	virtual bool hasFilterStringMatch() = 0;
+	virtual std::string::size_type getFilterStringOffset() = 0;
+	virtual std::string::size_type getFilterStringSize() = 0;
+
+	virtual S32	getLastFilterGeneration() const = 0;
+
+	virtual bool hasChildren() const = 0;
+	virtual void addChild(LLFolderViewModelItem* child) = 0;
+	virtual void removeChild(LLFolderViewModelItem* child) = 0;
+
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. Returns TRUE if a drop is possible/happened,
+	// otherwise FALSE.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) = 0;
+
+	virtual void requestSort() = 0;
+	virtual S32 getSortVersion() = 0;
+	virtual void setSortVersion(S32 version) = 0;
+	virtual void setParent(LLFolderViewModelItem* parent) = 0;
+	virtual bool hasParent() = 0;
+
+protected:
+
+	friend class LLFolderViewItem;
+	virtual void setFolderViewItem(LLFolderViewItem* folder_view_item) = 0;
+
+};
+
+
+class LLFolderViewModelItemCommon : public LLFolderViewModelItem
+{
+public:
+	LLFolderViewModelItemCommon(LLFolderViewModelInterface& root_view_model)
+	:	mSortVersion(-1),
+		mPassedFilter(true),
+		mPassedFolderFilter(true),
+		mStringMatchOffsetFilter(std::string::npos),
+		mStringFilterSize(0),
+		mFolderViewItem(NULL),
+		mLastFilterGeneration(-1),
+		mLastFolderFilterGeneration(-1),
+		mMostFilteredDescendantGeneration(-1),
+		mParent(NULL),
+		mRootViewModel(root_view_model)
+	{
+		mChildren.clear();
+	}
+
+	void requestSort() { mSortVersion = -1; }
+	S32 getSortVersion() { return mSortVersion; }
+	void setSortVersion(S32 version) { mSortVersion = version;}
+
+	S32	getLastFilterGeneration() const { return mLastFilterGeneration; }
+	S32	getLastFolderFilterGeneration() const { return mLastFolderFilterGeneration; }
+	void dirtyFilter()
+	{
+		mLastFilterGeneration = -1;
+		mLastFolderFilterGeneration = -1;
+
+		// bubble up dirty flag all the way to root
+		if (mParent)
+		{
+			mParent->dirtyFilter();
+		}	
+	}
+	bool hasFilterStringMatch();
+	std::string::size_type getFilterStringOffset();
+	std::string::size_type getFilterStringSize();
+	
+	typedef std::list<LLFolderViewModelItem*> child_list_t;
+
+	virtual void addChild(LLFolderViewModelItem* child) 
+	{ 
+		// Avoid duplicates: bail out if that child is already present in the list
+		// Note: this happens when models are created before views
+		child_list_t::const_iterator iter;
+		for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+		{
+			if (child == *iter)
+			{
+				return;
+			}
+		}
+		mChildren.push_back(child); 
+		child->setParent(this); 
+		dirtyFilter();
+		requestSort();
+	}
+	virtual void removeChild(LLFolderViewModelItem* child) 
+	{ 
+		mChildren.remove(child); 
+		child->setParent(NULL); 
+		dirtyFilter();
+	}
+	
+	virtual void clearChildren()
+	{
+		// As this is cleaning the whole list of children wholesale, we do need to delete the pointed objects
+		// This is different and not equivalent to calling removeChild() on each child
+		std::for_each(mChildren.begin(), mChildren.end(), DeletePointer());
+		mChildren.clear();
+		dirtyFilter();
+	}
+	
+	child_list_t::const_iterator getChildrenBegin() const { return mChildren.begin(); }
+	child_list_t::const_iterator getChildrenEnd() const { return mChildren.end(); }
+	child_list_t::size_type getChildrenCount() const { return mChildren.size(); }
+	
+	void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0)
+	{
+		mPassedFilter = passed;
+		mLastFilterGeneration = filter_generation;
+		mStringMatchOffsetFilter = string_offset;
+		mStringFilterSize = string_size;
+	}
+
+	void setPassedFolderFilter(bool passed, S32 filter_generation)
+	{
+		mPassedFolderFilter = passed;
+		mLastFolderFilterGeneration = filter_generation;
+	}
+
+	virtual bool potentiallyVisible()
+	{
+		return passedFilter() // we've passed the filter
+			|| getLastFilterGeneration() < mRootViewModel.getFilter().getFirstSuccessGeneration() // or we don't know yet
+			|| descendantsPassedFilter();
+	}
+
+	virtual bool passedFilter(S32 filter_generation = -1) 
+	{ 
+		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);
+	}
+
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1)
+	{ 
+		if (filter_generation < 0) filter_generation = mRootViewModel.getFilter().getFirstSuccessGeneration();
+		return mMostFilteredDescendantGeneration >= filter_generation; 
+	}
+
+
+protected:
+	virtual void setParent(LLFolderViewModelItem* parent) { mParent = parent; }
+	virtual bool hasParent() { return mParent != NULL; }
+
+	S32						mSortVersion;
+	bool					mPassedFilter;
+	bool					mPassedFolderFilter;
+	std::string::size_type	mStringMatchOffsetFilter;
+	std::string::size_type	mStringFilterSize;
+
+	S32						mLastFilterGeneration;
+	S32						mLastFolderFilterGeneration;
+	S32						mMostFilteredDescendantGeneration;
+
+	child_list_t			mChildren;
+	LLFolderViewModelItem*	mParent;
+	LLFolderViewModelInterface& mRootViewModel;
+
+	void setFolderViewItem(LLFolderViewItem* folder_view_item) { mFolderViewItem = folder_view_item;}
+	LLFolderViewItem*		mFolderViewItem;
+};
+
+
+
+class LLFolderViewModelCommon : public LLFolderViewModelInterface
+{
+public:
+	LLFolderViewModelCommon()
+	:	mTargetSortVersion(0),
+		mFolderView(NULL)
+	{}
+
+	virtual void requestSortAll()
+	{
+		// sort everything
+		mTargetSortVersion++;
+	}
+	virtual std::string getStatusText();
+	virtual void filter();
+
+	void setFolderView(LLFolderView* folder_view) { mFolderView = folder_view;}
+
+protected:
+	bool needsSort(class LLFolderViewModelItem* item);
+
+	S32 mTargetSortVersion;
+	LLFolderView* mFolderView;
+
+};
+
+template <typename SORT_TYPE, typename ITEM_TYPE, typename FOLDER_TYPE, typename FILTER_TYPE>
+class LLFolderViewModel : public LLFolderViewModelCommon
+{
+public:
+	LLFolderViewModel(){}
+	virtual ~LLFolderViewModel() {}
+
+	typedef SORT_TYPE		SortType;
+	typedef ITEM_TYPE		ItemType;
+	typedef FOLDER_TYPE		FolderType;
+	typedef FILTER_TYPE		FilterType;
+
+	virtual SortType& getSorter()					 { return mSorter; }
+	virtual const SortType& getSorter() const 		 { return mSorter; }
+	virtual void setSorter(const SortType& sorter) 	 { mSorter = sorter; requestSortAll(); }
+
+	virtual FilterType& getFilter() 				 { return mFilter; }
+	virtual const FilterType& getFilter() const		 { return mFilter; }
+	virtual void setFilter(const FilterType& filter) { mFilter = filter; }
+
+	// By default, we assume the content is available. If a network fetch mechanism is implemented for the model,
+	// this method needs to be overloaded and return the relevant fetch status.
+	virtual bool contentsReady()					{ return true; }
+
+
+	struct ViewModelCompare
+	{
+		ViewModelCompare(const SortType& sorter)
+		:	mSorter(sorter)
+		{}
+
+		bool operator () (const LLFolderViewItem* a, const LLFolderViewItem* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		bool operator () (const LLFolderViewFolder* a, const LLFolderViewFolder* b) const
+		{
+			return mSorter(static_cast<const ItemType*>(a->getViewModelItem()), static_cast<const ItemType*>(b->getViewModelItem()));
+		}
+
+		const SortType& mSorter;
+	};
+
+	void sort(LLFolderViewFolder* folder)
+	{
+		if (needsSort(folder->getViewModelItem()))
+		{
+			folder->sortFolders(ViewModelCompare(getSorter()));
+			folder->sortItems(ViewModelCompare(getSorter()));
+			folder->getViewModelItem()->setSortVersion(mTargetSortVersion);
+			folder->requestArrange();
+		}
+	}
+
+protected:
+	SortType		mSorter;
+	FilterType		mFilter;
+};
+
+#endif // LLFOLDERVIEWMODEL_H
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index 899cc3a326304e7aecd40c4e5dcd21b0ba59fe78..beac21244192a1dcd9637237693db331eeb381c0 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -69,7 +69,6 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 	bool registerFunctor(const std::string& name, ResponseFunctor f)
 	{
 		bool retval = true;
-		typename FunctorMap::iterator it = mMap.find(name);
 		if (mMap.count(name) == 0)
 		{
 			mMap[name] = f;
@@ -96,7 +95,6 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 
 	FUNCTOR_TYPE getFunctor(const std::string& name)
 	{
-		typename FunctorMap::iterator it = mMap.find(name);
 		if (mMap.count(name) != 0)
 		{
 			return mMap[name];
diff --git a/indra/llui/llkeywords.cpp b/indra/llui/llkeywords.cpp
index c1cd04186bda56afc329e0a255bc46269f56408f..795dacdbb069702ee69888eba6cd72200847c316 100644
--- a/indra/llui/llkeywords.cpp
+++ b/indra/llui/llkeywords.cpp
@@ -367,7 +367,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
 
 	const llwchar* base = wtext.c_str();
 	const llwchar* cur = base;
-	const llwchar* line = NULL;
 
 	while( *cur )
 	{
@@ -385,9 +384,6 @@ void LLKeywords::findSegments(std::vector<LLTextSegmentPtr>* seg_list, const LLW
 				}
 			}
 
-			// Start of a new line
-			line = cur;
-
 			// Skip white space
 			while( *cur && isspace(*cur) && (*cur != '\n')  )
 			{
diff --git a/indra/llui/lllayoutstack.cpp b/indra/llui/lllayoutstack.cpp
index 4c730286da86a6b0a6dbbfca12216aa211db5f75..e33ac1d5c263bbd4e6d441db4d2a442af83d87c9 100644
--- a/indra/llui/lllayoutstack.cpp
+++ b/indra/llui/lllayoutstack.cpp
@@ -32,11 +32,10 @@
 
 #include "lllocalcliprect.h"
 #include "llpanel.h"
-#include "llresizebar.h"
 #include "llcriticaldamp.h"
 #include "boost/foreach.hpp"
 
-static const F32 MIN_FRACTIONAL_SIZE = 0.0f;
+static const F32 MIN_FRACTIONAL_SIZE = 0.00001f;
 static const F32 MAX_FRACTIONAL_SIZE = 1.f;
 
 static LLDefaultChildRegistry::Register<LLLayoutStack> register_layout_stack("layout_stack");
@@ -71,7 +70,7 @@ LLLayoutPanel::LLLayoutPanel(const Params& p)
 	mCollapseAmt(0.f),
 	mVisibleAmt(1.f), // default to fully visible
 	mResizeBar(NULL),
-	mFractionalSize(MIN_FRACTIONAL_SIZE),
+	mFractionalSize(0.f),
 	mTargetDim(0),
 	mIgnoreReshape(false),
 	mOrientation(LLLayoutStack::HORIZONTAL)
@@ -477,7 +476,6 @@ void LLLayoutStack::createResizeBar(LLLayoutPanel* panelp)
 		if (lp->mResizeBar == NULL)
 		{
 			LLResizeBar::Side side = (mOrientation == HORIZONTAL) ? LLResizeBar::RIGHT : LLResizeBar::BOTTOM;
-			LLRect resize_bar_rect = getRect();
 
 			LLResizeBar::Params resize_params;
 			resize_params.name("resize");
@@ -521,7 +519,7 @@ void LLLayoutStack::updateFractionalSizes()
 	{
 		if (panelp->mAutoResize)
 		{
-			total_resizable_dim += llmax(0, panelp->getLayoutDim() - panelp->getRelevantMinDim());
+			total_resizable_dim += llmax(MIN_FRACTIONAL_SIZE, (F32)(panelp->getLayoutDim() - panelp->getRelevantMinDim()));
 		}
 	}
 
@@ -672,12 +670,12 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 	S32 new_dim = (mOrientation == HORIZONTAL)
 					? new_rect.getWidth()
 					: new_rect.getHeight();
-	S32 delta_dim = new_dim - resized_panel->getVisibleDim();
-	if (delta_dim == 0) return;
+	S32 delta_panel_dim = new_dim - resized_panel->getVisibleDim();
+	if (delta_panel_dim == 0) return;
 
 	F32 total_visible_fraction = 0.f;
 	F32 delta_auto_resize_headroom = 0.f;
-	F32 original_auto_resize_headroom = 0.f;
+	F32 old_auto_resize_headroom = 0.f;
 
 	LLLayoutPanel* other_resize_panel = NULL;
 	LLLayoutPanel* following_panel = NULL;
@@ -686,7 +684,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 	{
 		if (panelp->mAutoResize)
 		{
-			original_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
+			old_auto_resize_headroom += (F32)(panelp->mTargetDim - panelp->getRelevantMinDim());
 			if (panelp->getVisible() && !panelp->mCollapsed)
 			{
 				total_visible_fraction += panelp->mFractionalSize;
@@ -704,25 +702,24 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		}
 	}
 
-
 	if (resized_panel->mAutoResize)
 	{
 		if (!other_resize_panel || !other_resize_panel->mAutoResize)
 		{
-			delta_auto_resize_headroom += delta_dim;	
+			delta_auto_resize_headroom += delta_panel_dim;	
 		}
 	}
 	else 
 	{
 		if (!other_resize_panel || other_resize_panel->mAutoResize)
 		{
-			delta_auto_resize_headroom -= delta_dim;
+			delta_auto_resize_headroom -= delta_panel_dim;
 		}
 	}
 
 	F32 fraction_given_up = 0.f;
 	F32 fraction_remaining = 1.f;
-	F32 updated_auto_resize_headroom = original_auto_resize_headroom + delta_auto_resize_headroom;
+	F32 new_auto_resize_headroom = old_auto_resize_headroom + delta_auto_resize_headroom;
 
 	enum
 	{
@@ -734,7 +731,14 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 
 	BOOST_FOREACH(LLLayoutPanel* panelp, mPanels)
 	{
-		if (!panelp->getVisible() || panelp->mCollapsed) continue;
+		if (!panelp->getVisible() || panelp->mCollapsed) 
+		{
+			if (panelp->mAutoResize) 
+			{
+				fraction_remaining -= panelp->mFractionalSize;
+			}
+			continue;
+		}
 
 		if (panelp == resized_panel)
 		{
@@ -746,9 +750,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		case BEFORE_RESIZED_PANEL:
 			if (panelp->mAutoResize)
 			{	// freeze current size as fraction of overall auto_resize space
-				F32 fractional_adjustment_factor = updated_auto_resize_headroom == 0.f
+				F32 fractional_adjustment_factor = new_auto_resize_headroom == 0.f
 													? 1.f
-													: original_auto_resize_headroom / updated_auto_resize_headroom;
+													: old_auto_resize_headroom / new_auto_resize_headroom;
 				F32 new_fractional_size = llclamp(panelp->mFractionalSize * fractional_adjustment_factor,
 													MIN_FRACTIONAL_SIZE,
 													MAX_FRACTIONAL_SIZE);
@@ -765,9 +769,9 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		case RESIZED_PANEL:
 			if (panelp->mAutoResize)
 			{	// freeze new size as fraction
-				F32 new_fractional_size = (updated_auto_resize_headroom == 0.f)
+				F32 new_fractional_size = (new_auto_resize_headroom == 0.f)
 					? MAX_FRACTIONAL_SIZE
-					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / updated_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
+					: llclamp(total_visible_fraction * (F32)(new_dim - panelp->getRelevantMinDim()) / new_auto_resize_headroom, MIN_FRACTIONAL_SIZE, MAX_FRACTIONAL_SIZE);
 				fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
 				fraction_remaining -= panelp->mFractionalSize;
 				panelp->mFractionalSize = new_fractional_size;
@@ -790,8 +794,13 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 				}
 				else
 				{
+					if (new_auto_resize_headroom < 1.f)
+					{
+						new_auto_resize_headroom = 1.f;
+					}
+
 					F32 new_fractional_size = llclamp(total_visible_fraction * (F32)(panelp->mTargetDim - panelp->getRelevantMinDim() + delta_auto_resize_headroom) 
-														/ updated_auto_resize_headroom,
+														/ new_auto_resize_headroom,
 													MIN_FRACTIONAL_SIZE,
 													MAX_FRACTIONAL_SIZE);
 					fraction_given_up -= new_fractional_size - panelp->mFractionalSize;
@@ -800,7 +809,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 			}
 			else
 			{
-				panelp->mTargetDim -= delta_dim;
+				panelp->mTargetDim -= delta_panel_dim;
 			}
 			which_panel = AFTER_RESIZED_PANEL;
 			break;
@@ -816,7 +825,7 @@ void LLLayoutStack::updatePanelRect( LLLayoutPanel* resized_panel, const LLRect&
 		}
 	}
 	updateLayout();
-	normalizeFractionalSizes();
+	//normalizeFractionalSizes();
 }
 
 void LLLayoutStack::reshape(S32 width, S32 height, BOOL called_from_parent)
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index 648cd5fdce202d209758295b4f72da4228ff1569..02c664f1a060bbcaa51d93143d31ef4f2b168c27 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -29,6 +29,7 @@
 #define LL_LLLAYOUTSTACK_H
 
 #include "llpanel.h"
+#include "llresizebar.h"
 
 
 class LLLayoutPanel;
@@ -178,6 +179,9 @@ friend class LLUICtrlFactory;
 	F32 getAutoResizeFactor() const;
 	F32 getVisibleAmount() const;
 	S32 getVisibleDim() const;
+	LLResizeBar* getResizeBar() { return mResizeBar; }
+
+	bool isCollapsed() const { return mCollapsed;}
 
 	void setOrientation(LLLayoutStack::ELayoutOrientation orientation);
 	void storeOriginalDim();
diff --git a/indra/llui/lllineeditor.cpp b/indra/llui/lllineeditor.cpp
index 48d49af58810e4e4eccc3a73072ddd2821a431ae..5478e85e13a01842bb4f359d95e2167d398491b5 100644
--- a/indra/llui/lllineeditor.cpp
+++ b/indra/llui/lllineeditor.cpp
@@ -157,8 +157,7 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 	mHighlightColor(p.highlight_color()),
 	mPreeditBgColor(p.preedit_bg_color()),
 	mGLFont(p.font),
-	mContextMenuHandle(),
-	mAutoreplaceCallback()
+	mContextMenuHandle()
 {
 	llassert( mMaxLengthBytes > 0 );
 
@@ -203,6 +202,14 @@ LLLineEditor::LLLineEditor(const LLLineEditor::Params& p)
 LLLineEditor::~LLLineEditor()
 {
 	mCommitOnFocusLost = FALSE;
+    
+    // Make sure no context menu linger around once the widget is deleted
+	LLContextMenu* menu = static_cast<LLContextMenu*>(mContextMenuHandle.get());
+	if (menu)
+	{
+        menu->hide();
+    }
+	setContextMenu(NULL);
 
 	// calls onCommit() while LLLineEditor still valid
 	gFocusMgr.releaseFocusIfNeeded( this );
@@ -971,12 +978,6 @@ void LLLineEditor::addChar(const llwchar uni_char)
 		LLUI::reportBadKeystroke();
 	}
 
-	if (!mReadOnly && mAutoreplaceCallback != NULL)
-	{
-		// call callback
-		mAutoreplaceCallback(mText, mCursorPos);
-	}
-
 	getWindow()->hideCursorUntilMouseMove();
 }
 
@@ -2022,8 +2023,8 @@ void LLLineEditor::draw()
 				LLRect screen_pos = calcScreenRect();
 				LLCoordGL ime_pos( screen_pos.mLeft + pixels_after_scroll, screen_pos.mTop - lineeditor_v_pad );
 
-				ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-				ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+				ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+				ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 				getWindow()->setLanguageTextInput( ime_pos );
 			}
 		}
@@ -2570,7 +2571,7 @@ void LLLineEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLLineEditor::getPreeditFontSize() const
 {
-	return llround(mGLFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround(mGLFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 void LLLineEditor::setReplaceNewlinesWithSpaces(BOOL replace)
diff --git a/indra/llui/lllineeditor.h b/indra/llui/lllineeditor.h
index 71dd53f60838a880fa47a1230017d849492a18eb..40f931ecc1e9b0d08fefa7d8a85c1f9b1f7e1b5d 100644
--- a/indra/llui/lllineeditor.h
+++ b/indra/llui/lllineeditor.h
@@ -189,9 +189,6 @@ class LLLineEditor
 	virtual BOOL	setTextArg( const std::string& key, const LLStringExplicit& text );
 	virtual BOOL	setLabelArg( const std::string& key, const LLStringExplicit& text );
 
-	typedef boost::function<void(LLUIString&, S32&)> autoreplace_callback_t;
-	autoreplace_callback_t mAutoreplaceCallback;
-	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
 	void			setLabel(const LLStringExplicit &new_label) { mLabel = new_label; }
 	const std::string& 	getLabel()	{ return mLabel.getString(); }
 
diff --git a/indra/llui/llloadingindicator.cpp b/indra/llui/llloadingindicator.cpp
index 6ac38f5ad40ab0634a8241be158e5b1bf3e0cc7e..1ede5b706f9db44488bf041b892915fc81cefe76 100644
--- a/indra/llui/llloadingindicator.cpp
+++ b/indra/llui/llloadingindicator.cpp
@@ -52,7 +52,7 @@ LLLoadingIndicator::LLLoadingIndicator(const Params& p)
 
 void LLLoadingIndicator::initFromParams(const Params& p)
 {
-	BOOST_FOREACH(LLUIImage* image, p.images.image)
+	BOOST_FOREACH(LLUIImage* image, p.images().image)
 	{
 		mImages.push_back(image);
 	}
diff --git a/indra/llui/llloadingindicator.h b/indra/llui/llloadingindicator.h
index c1f979c1113f6bb9916c905f178f9e55b09be187..ffcb329f42d9db879fe99ebba19f3f154280e6d3 100644
--- a/indra/llui/llloadingindicator.h
+++ b/indra/llui/llloadingindicator.h
@@ -51,7 +51,7 @@ class LLLoadingIndicator
 	LOG_CLASS(LLLoadingIndicator);
 public:
 
-	struct Images : public LLInitParam::BatchBlock<Images>
+	struct Images : public LLInitParam::Block<Images>
 	{
 		Multiple<LLUIImage*>	image;
 
@@ -62,8 +62,8 @@ class LLLoadingIndicator
 
 	struct Params : public LLInitParam::Block<Params, LLUICtrl::Params>
 	{
-		Optional<F32>			images_per_sec;
-		Optional<Images>		images;
+		Optional<F32>				images_per_sec;
+		Optional<Atomic<Images> >	images;
 
 		Params()
 		:	images_per_sec("images_per_sec", 1.0f),
diff --git a/indra/llui/lllocalcliprect.cpp b/indra/llui/lllocalcliprect.cpp
index 6841301219427752c66f74675a2f5201d15a7fae..0620e0f52d972af82466c07e3fea403801a930ab 100644
--- a/indra/llui/lllocalcliprect.cpp
+++ b/indra/llui/lllocalcliprect.cpp
@@ -33,7 +33,7 @@
 
 
 LLScreenClipRect::LLScreenClipRect(const LLRect& rect, BOOL enabled)
-:	mScissorState(GL_SCISSOR_TEST),
+	:	mScissorState(GL_SCISSOR_TEST),
 	mEnabled(enabled)
 {
 	if (mEnabled)
@@ -88,10 +88,10 @@ void LLScreenClipRect::updateScissorRegion()
 	LLRect rect = sClipRectStack.top();
 	stop_glerror();
 	S32 x,y,w,h;
-	x = llfloor(rect.mLeft * LLUI::sGLScaleFactor.mV[VX]);
-	y = llfloor(rect.mBottom * LLUI::sGLScaleFactor.mV[VY]);
-	w = llmax(0, llceil(rect.getWidth() * LLUI::sGLScaleFactor.mV[VX])) + 1;
-	h = llmax(0, llceil(rect.getHeight() * LLUI::sGLScaleFactor.mV[VY])) + 1;
+	x = llfloor(rect.mLeft * LLUI::getScaleFactor().mV[VX]);
+	y = llfloor(rect.mBottom * LLUI::getScaleFactor().mV[VY]);
+	w = llmax(0, llceil(rect.getWidth() * LLUI::getScaleFactor().mV[VX])) + 1;
+	h = llmax(0, llceil(rect.getHeight() * LLUI::getScaleFactor().mV[VY])) + 1;
 	glScissor( x,y,w,h );
 	stop_glerror();
 }
@@ -100,10 +100,10 @@ void LLScreenClipRect::updateScissorRegion()
 // LLLocalClipRect
 //---------------------------------------------------------------------------
 LLLocalClipRect::LLLocalClipRect(const LLRect& rect, BOOL enabled /* = TRUE */)
-:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
-					rect.mTop + LLFontGL::sCurOrigin.mY, 
-					rect.mRight + LLFontGL::sCurOrigin.mX, 
-					rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
+	:	LLScreenClipRect(LLRect(rect.mLeft + LLFontGL::sCurOrigin.mX, 
+	rect.mTop + LLFontGL::sCurOrigin.mY, 
+	rect.mRight + LLFontGL::sCurOrigin.mX, 
+	rect.mBottom + LLFontGL::sCurOrigin.mY), enabled)
 {}
 
 LLLocalClipRect::~LLLocalClipRect()
diff --git a/indra/llui/llmenubutton.cpp b/indra/llui/llmenubutton.cpp
index 50d59f79f4eb837356e2391d3c547278e6f7975d..746ade464892e5b5444c0287f56765c2140e43be 100644
--- a/indra/llui/llmenubutton.cpp
+++ b/indra/llui/llmenubutton.cpp
@@ -44,33 +44,27 @@ void LLMenuButton::MenuPositions::declareValues()
 
 LLMenuButton::Params::Params()
 :	menu_filename("menu_filename"),
-	position("position", MP_BOTTOM_LEFT)
+	position("menu_position", MP_BOTTOM_LEFT)
 {
+	addSynonym(position, "position");
 }
 
 
 LLMenuButton::LLMenuButton(const LLMenuButton::Params& p)
 :	LLButton(p),
 	mIsMenuShown(false),
-	mMenuPosition(p.position)
+	mMenuPosition(p.position),
+	mOwnMenu(false)
 {
 	std::string menu_filename = p.menu_filename;
 
-	if (!menu_filename.empty())
-	{
-		LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
-		if (!menu)
-		{
-			llwarns << "Error loading menu_button menu" << llendl;
-			return;
-		}
-
-		menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
-
-		mMenuHandle = menu->getHandle();
+	setMenu(menu_filename, mMenuPosition);
+	updateMenuOrigin();
+}
 
-		updateMenuOrigin();
-	}
+LLMenuButton::~LLMenuButton()
+{
+	cleanup();
 }
 
 boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_signal_t::slot_type& cb )
@@ -80,9 +74,7 @@ boost::signals2::connection LLMenuButton::setMouseDownCallback( const mouse_sign
 
 void LLMenuButton::hideMenu()
 {
-	if(mMenuHandle.isDead()) return;
-
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (menu)
 	{
 		menu->setVisible(FALSE);
@@ -94,19 +86,39 @@ LLToggleableMenu* LLMenuButton::getMenu()
 	return dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
 }
 
-void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/)
+void LLMenuButton::setMenu(const std::string& menu_filename, EMenuPosition position /*MP_TOP_LEFT*/)
+{
+	if (menu_filename.empty())
+	{
+		return;
+	}
+
+	LLToggleableMenu* menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(menu_filename, LLMenuGL::sMenuContainer, LLMenuHolderGL::child_registry_t::instance());
+	if (!menu)
+	{
+		llwarns << "Error loading menu_button menu" << llendl;
+		return;
+	}
+
+	setMenu(menu, position, true);
+}
+
+void LLMenuButton::setMenu(LLToggleableMenu* menu, EMenuPosition position /*MP_TOP_LEFT*/, bool take_ownership /*false*/)
 {
 	if (!menu) return;
 
+	cleanup(); // destroy the previous memnu if we own it
+
 	mMenuHandle = menu->getHandle();
 	mMenuPosition = position;
+	mOwnMenu = take_ownership;
 
 	menu->setVisibilityChangeCallback(boost::bind(&LLMenuButton::onMenuVisibilityChange, this, _2));
 }
 
 BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
 {
-	if (mMenuHandle.isDead()) return FALSE;
+	if (!getMenu()) return FALSE;
 
 	if( KEY_RETURN == key && mask == MASK_NONE && !gKeyboard->getKeyRepeated(key))
 	{
@@ -118,7 +130,7 @@ BOOL LLMenuButton::handleKeyHere(KEY key, MASK mask )
 		return TRUE;
 	}
 
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (menu && menu->getVisible() && key == KEY_ESCAPE && mask == MASK_NONE)
 	{
 		menu->setVisible(FALSE);
@@ -139,9 +151,12 @@ BOOL LLMenuButton::handleMouseDown(S32 x, S32 y, MASK mask)
 
 void LLMenuButton::toggleMenu()
 {
-	if(mMenuHandle.isDead()) return;
+	if (mValidateSignal && !(*mValidateSignal)(this, LLSD()))
+	{
+		return;
+	}
 
-	LLToggleableMenu* menu = dynamic_cast<LLToggleableMenu*>(mMenuHandle.get());
+	LLToggleableMenu* menu = getMenu();
 	if (!menu) return;
 
 	// Store the button rectangle to toggle menu visibility if a mouse event
@@ -170,7 +185,8 @@ void LLMenuButton::toggleMenu()
 
 void LLMenuButton::updateMenuOrigin()
 {
-	if (mMenuHandle.isDead()) return;
+	LLToggleableMenu* menu = getMenu();
+	if (!menu) return;
 
 	LLRect rect = getRect();
 
@@ -179,12 +195,12 @@ void LLMenuButton::updateMenuOrigin()
 		case MP_TOP_LEFT:
 		{
 			mX = rect.mLeft;
-			mY = rect.mTop + mMenuHandle.get()->getRect().getHeight();
+			mY = rect.mTop + menu->getRect().getHeight();
 			break;
 		}
 		case MP_TOP_RIGHT:
 		{
-			const LLRect& menu_rect = mMenuHandle.get()->getRect();
+			const LLRect& menu_rect = menu->getRect();
 			mX = rect.mRight - menu_rect.getWidth();
 			mY = rect.mTop + menu_rect.getHeight();
 			break;
@@ -211,3 +227,11 @@ void LLMenuButton::onMenuVisibilityChange(const LLSD& param)
 		mIsMenuShown = false;
 	}
 }
+
+void LLMenuButton::cleanup()
+{
+	if (mMenuHandle.get() && mOwnMenu)
+	{
+		mMenuHandle.get()->die();
+	}
+}
diff --git a/indra/llui/llmenubutton.h b/indra/llui/llmenubutton.h
index e2396e7fb2a9366ab539ec3992b7f99218b6bfa7..67ec1983b3f1e0478a9febf4a5f94a8d79a24406 100644
--- a/indra/llui/llmenubutton.h
+++ b/indra/llui/llmenubutton.h
@@ -34,6 +34,8 @@ class LLToggleableMenu;
 class LLMenuButton
 : public LLButton
 {
+	LOG_CLASS(LLMenuButton);
+
 public:
 	typedef enum e_menu_position
 	{
@@ -53,7 +55,7 @@ class LLMenuButton
 	{
 		// filename for it's toggleable menu
 		Optional<std::string>	menu_filename;
-		Optional<EMenuPosition>	position;
+		Optional<EMenuPosition, MenuPositions>	position;
 	
 		Params();
 	};
@@ -68,13 +70,15 @@ class LLMenuButton
 	void hideMenu();
 
 	LLToggleableMenu* getMenu();
-	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT);
+	void setMenu(const std::string& menu_filename, EMenuPosition position = MP_TOP_LEFT);
+	void setMenu(LLToggleableMenu* menu, EMenuPosition position = MP_TOP_LEFT, bool take_ownership = false);
 
 	void setMenuPosition(EMenuPosition position) { mMenuPosition = position; }
 
 protected:
 	friend class LLUICtrlFactory;
 	LLMenuButton(const Params&);
+	~LLMenuButton();
 
 	void toggleMenu();
 	void updateMenuOrigin();
@@ -82,11 +86,14 @@ class LLMenuButton
 	void onMenuVisibilityChange(const LLSD& param);
 
 private:
+	void cleanup();
+
 	LLHandle<LLView>		mMenuHandle;
 	bool					mIsMenuShown;
 	EMenuPosition			mMenuPosition;
 	S32						mX;
 	S32						mY;
+	bool					mOwnMenu; // true if we manage the menu lifetime
 };
 
 
diff --git a/indra/llui/llmenugl.cpp b/indra/llui/llmenugl.cpp
index cd6cc6a75e18ae4b8f7fe4edc75d73b329b4dd5f..f7bf39c897b8351e0163c8f92125084a843b3a7a 100644
--- a/indra/llui/llmenugl.cpp
+++ b/indra/llui/llmenugl.cpp
@@ -593,12 +593,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseDown(S32 x, S32 y, MASK mask)
 	{
 		// the menu items are in the child list in bottom up order
 		LLView* prev_menu_item = parent_menu->findNextSibling(this);
-		return prev_menu_item ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+		return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseDown(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
 	}
 	else
 	{
 		LLView* next_menu_item = parent_menu->findPrevSibling(this);
-		return next_menu_item ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
+		return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseDown(x, 0, mask) : FALSE;
 	}
 }
 
@@ -608,12 +608,12 @@ BOOL LLMenuItemSeparatorGL::handleMouseUp(S32 x, S32 y, MASK mask)
 	if (y > getRect().getHeight() / 2)
 	{
 		LLView* prev_menu_item = parent_menu->findNextSibling(this);
-		return prev_menu_item ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
+		return (prev_menu_item && prev_menu_item->getVisible() && prev_menu_item->getEnabled()) ? prev_menu_item->handleMouseUp(x, prev_menu_item->getRect().getHeight(), mask) : FALSE;
 	}
 	else
 	{
 		LLView* next_menu_item = parent_menu->findPrevSibling(this);
-		return next_menu_item ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
+		return (next_menu_item && next_menu_item->getVisible() && next_menu_item->getEnabled()) ? next_menu_item->handleMouseUp(x, 0, mask) : FALSE;
 	}
 }
 
@@ -1751,35 +1751,50 @@ void LLMenuGL::setCanTearOff(BOOL tear_off)
 
 bool LLMenuGL::addChild(LLView* view, S32 tab_group)
 {
-	if (LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view))
+	LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+	if (menup)
 	{
-		appendMenu(menup);
-		return true;
+		return appendMenu(menup);
 	}
-	else if (LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view))
+	
+	LLMenuItemGL* itemp = dynamic_cast<LLMenuItemGL*>(view);
+	if (itemp)
 	{
-		append(itemp);
-		return true;
+		return append(itemp);
 	}
+	
 	return false;
 }
 
 // Used in LLContextMenu and in LLTogleableMenu
-// to add an item of context menu branch
+
+// Add an item to the context menu branch
 bool LLMenuGL::addContextChild(LLView* view, S32 tab_group)
 {
 	LLContextMenu* context = dynamic_cast<LLContextMenu*>(view);
 	if (context)
+	{
 		return appendContextSubMenu(context);
+	}
 
 	LLMenuItemSeparatorGL* separator = dynamic_cast<LLMenuItemSeparatorGL*>(view);
 	if (separator)
+	{
 		return append(separator);
+	}
 
 	LLMenuItemGL* item = dynamic_cast<LLMenuItemGL*>(view);
 	if (item)
+	{
 		return append(item);
-
+	}
+	
+	LLMenuGL* menup = dynamic_cast<LLMenuGL*>(view);
+	if (menup)
+	{
+		return appendMenu(menup);
+	}
+	
 	return false;
 }
 
@@ -2446,6 +2461,56 @@ void LLMenuGL::empty( void )
 	deleteAllChildren();
 }
 
+// erase group of items from menu
+void LLMenuGL::erase( S32 begin, S32 end, bool arrange/* = true*/)
+{
+	S32 items = mItems.size();
+
+	if ( items == 0 || begin >= end || begin < 0 || end > items )
+	{
+		return;
+	}
+
+	item_list_t::iterator start_position = mItems.begin();
+	std::advance(start_position, begin);
+
+	item_list_t::iterator end_position = mItems.begin();
+	std::advance(end_position, end);
+
+	for (item_list_t::iterator position_iter = start_position; position_iter != end_position; position_iter++)
+	{
+		LLUICtrl::removeChild(*position_iter);
+	}
+
+	mItems.erase(start_position, end_position);
+
+	if (arrange)
+	{
+		needsArrange();
+	}
+}
+
+// add new item at position
+void LLMenuGL::insert( S32 position, LLView * ctrl, bool arrange /*= true*/ )
+{
+	LLMenuItemGL * item = dynamic_cast<LLMenuItemGL *>(ctrl);
+
+	if (NULL == item || position < 0 || position >= mItems.size())
+	{
+		return;
+	}
+
+	item_list_t::iterator position_iter = mItems.begin();
+	std::advance(position_iter, position);
+	mItems.insert(position_iter, item);
+	LLUICtrl::addChild(item);
+
+	if (arrange)
+	{
+		needsArrange();
+	}
+}
+
 // Adjust rectangle of the menu
 void LLMenuGL::setLeftAndBottom(S32 left, S32 bottom)
 {
@@ -2487,7 +2552,8 @@ BOOL LLMenuGL::append( LLMenuItemGL* item )
 // add a separator to this menu
 BOOL LLMenuGL::addSeparator()
 {
-	LLMenuItemGL* separator = new LLMenuItemSeparatorGL();
+	LLMenuItemSeparatorGL::Params p;
+	LLMenuItemGL* separator = LLUICtrlFactory::create<LLMenuItemSeparatorGL>(p);
 	return addChild(separator);
 }
 
@@ -3080,7 +3146,17 @@ 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())
+	//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();
+			 itor != menu->getChildList()->end();
+			 ++itor)
+	{
+		LLView *menu_item = (*itor);
+		item_enabled = item_enabled || menu_item->getEnabled();
+	}
+
+	if(menu->getChildList()->empty() || !item_enabled)
 	{
 		return;
 	}
@@ -4039,11 +4115,6 @@ BOOL LLContextMenu::handleRightMouseUp( S32 x, S32 y, MASK mask )
 	return result;
 }
 
-void LLContextMenu::draw()
-{
-	LLMenuGL::draw();
-}
-
 bool LLContextMenu::addChild(LLView* view, S32 tab_group)
 {
 	return addContextChild(view, tab_group);
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 00899020bc087e00f75274c66a385dbaed8ccd32..51df5df1f8231b3dc327b2fadbcfc56056cd5759 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -478,6 +478,12 @@ class LLMenuGL
 	// remove all items on the menu
 	void empty( void );
 
+	// erase group of items from menu
+	void erase( S32 begin, S32 end, bool arrange = true );
+
+	// add new item at position
+	void insert( S32 begin, LLView * ctrl, bool arrange = true );
+
 	void			setItemLastSelected(LLMenuItemGL* item);	// must be in menu
 	U32				getItemCount();				// number of menu items
 	LLMenuItemGL*	getItem(S32 number);		// 0 = first item
@@ -675,8 +681,6 @@ class LLContextMenu
 	// can't set visibility directly, must call show or hide
 	virtual void	setVisible			(BOOL visible);
 	
-	virtual void	draw				();
-	
 	virtual void	show				(S32 x, S32 y, LLView* spawning_view = NULL);
 	virtual void	hide				();
 
@@ -698,7 +702,6 @@ class LLContextMenu
 	LLHandle<LLView>			mSpawningViewHandle;
 };
 
-
 //-----------------------------------------------------------------------------
 // class LLContextMenuBranch
 // A branch to another context menu
diff --git a/indra/llui/llmultifloater.cpp b/indra/llui/llmultifloater.cpp
index aa5f577897daae00fd68342b4dd8ebf08616e9ff..179b251cdbc5929b0788e9b427c5f16418bf459a 100644
--- a/indra/llui/llmultifloater.cpp
+++ b/indra/llui/llmultifloater.cpp
@@ -41,8 +41,8 @@ LLMultiFloater::LLMultiFloater(const LLSD& key, const LLFloater::Params& params)
 	  mTabContainer(NULL),
 	  mTabPos(LLTabContainer::TOP),
 	  mAutoResize(TRUE),
-	  mOrigMinWidth(0),
-	  mOrigMinHeight(0)
+	  mOrigMinWidth(params.min_width),
+	  mOrigMinHeight(params.min_height)
 {
 }
 
@@ -173,7 +173,7 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
 	else if (floaterp->getHost())
 	{
 		// floaterp is hosted by somebody else and
-		// this is adding it, so remove it from it's old host
+		// this is adding it, so remove it from its old host
 		floaterp->getHost()->removeFloater(floaterp);
 	}
 	else if (floaterp->getParent() == gFloaterView)
@@ -188,11 +188,13 @@ void LLMultiFloater::addFloater(LLFloater* floaterp, BOOL select_added_floater,
 	floater_data.mHeight = floaterp->getRect().getHeight();
 	floater_data.mCanMinimize = floaterp->isMinimizeable();
 	floater_data.mCanResize = floaterp->isResizable();
+    floater_data.mSaveRect = floaterp->mSaveRect;
 
 	// remove minimize and close buttons
 	floaterp->setCanMinimize(FALSE);
 	floaterp->setCanResize(FALSE);
 	floaterp->setCanDrag(FALSE);
+	floaterp->mSaveRect = FALSE;
 	floaterp->storeRectControl();
 	// avoid double rendering of floater background (makes it more opaque)
 	floaterp->setBackgroundVisible(FALSE);
@@ -291,6 +293,7 @@ void LLMultiFloater::removeFloater(LLFloater* floaterp)
 	{
 		LLFloaterData& floater_data = found_data_it->second;
 		floaterp->setCanMinimize(floater_data.mCanMinimize);
+		floaterp->mSaveRect = floater_data.mSaveRect;
 		if (!floater_data.mCanResize)
 		{
 			// restore original size
@@ -468,23 +471,12 @@ BOOL LLMultiFloater::postBuild()
 
 void LLMultiFloater::updateResizeLimits()
 {
-	static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
-	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
-	S32 floater_header_size = default_params.header_height;
-	S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
 	// initialize minimum size constraint to the original xml values.
 	S32 new_min_width = mOrigMinWidth;
 	S32 new_min_height = mOrigMinHeight;
-	// possibly increase minimum size constraint due to children's minimums.
-	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
-	{
-		LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
-		if (floaterp)
-		{
-			new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
-			new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
-		}
-	}
+
+	computeResizeLimits(new_min_width, new_min_height);
+
 	setResizeLimits(new_min_width, new_min_height);
 
 	S32 cur_height = getRect().getHeight();
@@ -510,3 +502,22 @@ void LLMultiFloater::updateResizeLimits()
 		gFloaterView->adjustToFitScreen(this, TRUE);
 	}
 }
+
+void LLMultiFloater::computeResizeLimits(S32& new_min_width, S32& new_min_height)
+{
+	static LLUICachedControl<S32> tabcntr_close_btn_size ("UITabCntrCloseBtnSize", 0);
+	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+	S32 floater_header_size = default_params.header_height;
+	S32 tabcntr_header_height = LLPANEL_BORDER_WIDTH + tabcntr_close_btn_size;
+
+	// possibly increase minimum size constraint due to children's minimums.
+	for (S32 tab_idx = 0; tab_idx < mTabContainer->getTabCount(); ++tab_idx)
+	{
+		LLFloater* floaterp = (LLFloater*)mTabContainer->getPanelByIndex(tab_idx);
+		if (floaterp)
+		{
+			new_min_width = llmax(new_min_width, floaterp->getMinWidth() + LLPANEL_BORDER_WIDTH * 2);
+			new_min_height = llmax(new_min_height, floaterp->getMinHeight() + floater_header_size + tabcntr_header_height);
+		}
+	}
+}
diff --git a/indra/llui/llmultifloater.h b/indra/llui/llmultifloater.h
index 9fa917eca1883325d3cc8377a0b0e937137bfef9..d9922126503e2773c573661298a4558ddea5293c 100644
--- a/indra/llui/llmultifloater.h
+++ b/indra/llui/llmultifloater.h
@@ -45,8 +45,8 @@ class LLMultiFloater : public LLFloater
 	
 	virtual BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void draw();
-	/*virtual*/ void setVisible(BOOL visible);
+	virtual void draw();
+	virtual void setVisible(BOOL visible);
 	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
 	/*virtual*/ bool addChild(LLView* view, S32 tab_group = 0);
 
@@ -79,10 +79,11 @@ class LLMultiFloater : public LLFloater
 protected:
 	struct LLFloaterData
 	{
-		S32		mWidth;
-		S32		mHeight;
-		BOOL	mCanMinimize;
-		BOOL	mCanResize;
+		S32		    mWidth;
+		S32		    mHeight;
+		BOOL	    mCanMinimize;
+		BOOL	    mCanResize;
+		BOOL        mSaveRect;
 	};
 
 	LLTabContainer*		mTabContainer;
@@ -93,6 +94,9 @@ class LLMultiFloater : public LLFloater
 	LLTabContainer::TabPosition mTabPos;
 	BOOL				mAutoResize;
 	S32					mOrigMinWidth, mOrigMinHeight;  // logically const but initialized late
+
+private:
+	virtual void computeResizeLimits(S32& new_min_width, S32& new_min_height);
 };
 
 #endif  // LL_MULTI_FLOATER_H
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 2bf88532c6605f5040e5b578cf628843d2a1fc76..1789f003b91ecd843aba930d724b22e4184e4f48 100644
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -39,7 +39,6 @@
 #include "lldir.h"
 #include "llsdserialize.h"
 #include "lltrans.h"
-#include "llnotificationslistener.h"
 #include "llstring.h"
 #include "llsdparam.h"
 #include "llsdutil.h"
@@ -60,7 +59,8 @@ void NotificationPriorityValues::declareValues()
 }
 
 LLNotificationForm::FormElementBase::FormElementBase()
-:	name("name")
+:	name("name"),
+	enabled("enabled", true)
 {}
 
 LLNotificationForm::FormIgnore::FormIgnore()
@@ -104,39 +104,7 @@ LLNotificationForm::Params::Params()
 	form_elements("")
 {}
 
-// Local channel for persistent notifications
-// Stores only persistent notifications.
-// Class users can use connectChanged() to process persistent notifications
-// (see LLNotificationStorage for example).
-class LLPersistentNotificationChannel : public LLNotificationChannel
-{
-	LOG_CLASS(LLPersistentNotificationChannel);
-public:
-	LLPersistentNotificationChannel() :
-		LLNotificationChannel("Persistent", "Visible", &notificationFilter, LLNotificationComparators::orderByUUID())
-	{
-	}
-
-private:
 
-	// The channel gets all persistent notifications except those that have been canceled
-	static bool notificationFilter(LLNotificationPtr pNotification)
-	{
-		bool handle_notification = false;
-
-		handle_notification = pNotification->isPersistent()
-			&& !pNotification->isCancelled();
-
-		return handle_notification;
-	}
-
-	void onDelete(LLNotificationPtr pNotification)
-	{
-		// we want to keep deleted notifications in our log, otherwise some 
-		// notifications will be lost on exit.
-		mItems.insert(pNotification);
-	}
-};
 
 bool filterIgnoredNotifications(LLNotificationPtr notification)
 {
@@ -210,6 +178,14 @@ LLNotificationForm::LLNotificationForm()
 {
 }
 
+LLNotificationForm::LLNotificationForm( const LLNotificationForm& other )
+{
+	mFormData 	   = other.mFormData;
+	mIgnore 	   = other.mIgnore;
+	mIgnoreMsg 	   = other.mIgnoreMsg;
+	mIgnoreSetting = other.mIgnoreSetting;
+	mInvertSetting = other.mInvertSetting;
+}
 
 LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotificationForm::Params& p) 
 :	mIgnore(IGNORE_NO),
@@ -246,14 +222,6 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 	LLParamSDParser parser;
 	parser.writeSD(mFormData, p.form_elements);
 
-	if (!mFormData.isArray())
-	{
-		// change existing contents to a one element array
-		LLSD new_llsd_array = LLSD::emptyArray();
-		new_llsd_array.append(mFormData);
-		mFormData = new_llsd_array;
-	}
-
 	for (LLSD::array_iterator it = mFormData.beginArray(), end_it = mFormData.endArray();
 		it != end_it;
 		++it)
@@ -300,7 +268,7 @@ LLSD LLNotificationForm::getElement(const std::string& element_name)
 }
 
 
-bool LLNotificationForm::hasElement(const std::string& element_name)
+bool LLNotificationForm::hasElement(const std::string& element_name) const
 {
 	for (LLSD::array_const_iterator it = mFormData.beginArray();
 		it != mFormData.endArray();
@@ -311,7 +279,48 @@ bool LLNotificationForm::hasElement(const std::string& element_name)
 	return false;
 }
 
-void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value)
+void LLNotificationForm::getElements(LLSD& elements, S32 offset)
+{
+    //Finds elements that the template did not add
+    LLSD::array_const_iterator it = mFormData.beginArray() + offset;
+
+    //Keeps track of only the dynamic elements
+    for(; it != mFormData.endArray(); ++it)
+    {
+        elements.append(*it);
+    }
+}
+
+bool LLNotificationForm::getElementEnabled(const std::string& element_name) const
+{
+	for (LLSD::array_const_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name)
+		{
+			return (*it)["enabled"].asBoolean();
+		}
+	}
+
+	return false;
+}
+
+void LLNotificationForm::setElementEnabled(const std::string& element_name, bool enabled)
+{
+	for (LLSD::array_iterator it = mFormData.beginArray();
+		it != mFormData.endArray();
+		++it)
+	{
+		if ((*it)["name"].asString() == element_name)
+		{
+			(*it)["enabled"] = enabled;
+		}
+	}
+}
+
+
+void LLNotificationForm::addElement(const std::string& type, const std::string& name, const LLSD& value, bool enabled)
 {
 	LLSD element;
 	element["type"] = type;
@@ -319,6 +328,7 @@ void LLNotificationForm::addElement(const std::string& type, const std::string&
 	element["text"] = name;
 	element["value"] = value;
 	element["index"] = mFormData.size();
+	element["enabled"] = enabled;
 	mFormData.append(element);
 }
 
@@ -408,14 +418,19 @@ LLNotificationTemplate::LLNotificationTemplate(const LLNotificationTemplate::Par
 	mURLOption(p.url.option),
 	mURLTarget(p.url.target),
 	mUnique(p.unique.isProvided()),
+	mCombineBehavior(p.unique.combine),
 	mPriority(p.priority),
 	mPersist(p.persist),
-	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name())
+	mDefaultFunctor(p.functor.isProvided() ? p.functor() : p.name()),
+	mLogToChat(p.log_to_chat),
+	mLogToIM(p.log_to_im),
+	mShowToast(p.show_toast),
+    mSoundName("")
 {
 	if (p.sound.isProvided()
 		&& LLUI::sSettingGroups["config"]->controlExists(p.sound))
 	{
-		mSoundEffect = LLUUID(LLUI::sSettingGroups["config"]->getString(p.sound));
+		mSoundName = p.sound;
 	}
 
 	BOOST_FOREACH(const LLNotificationTemplate::UniquenessContext& context, p.unique.contexts)
@@ -460,18 +475,20 @@ LLNotificationVisibilityRule::LLNotificationVisibilityRule(const LLNotificationV
 	}
 }
 
-LLNotification::LLNotification(const LLNotification::Params& p) : 
+LLNotification::LLNotification(const LLSDParamAdapter<Params>& p) : 
 	mTimestamp(p.time_stamp), 
 	mSubstitutions(p.substitutions),
 	mPayload(p.payload),
-	mExpiresAt(0),
+	mExpiresAt(p.expiry),
 	mTemporaryResponder(false),
 	mRespondedTo(false),
 	mPriority(p.priority),
 	mCancelled(false),
 	mIgnored(false),
 	mResponderObj(NULL),
-	mIsReusable(false)
+	mId(p.id.isProvided() ? p.id : LLUUID::generateNewID()),
+	mOfferFromAgent(p.offer_from_agent),
+    mIsDND(p.is_dnd)
 {
 	if (p.functor.name.isChosen())
 	{
@@ -494,52 +511,52 @@ LLNotification::LLNotification(const LLNotification::Params& p) :
 		mResponderObj = p.responder;
 	}
 
-	mId.generate();
 	init(p.name, p.form_elements);
 }
 
 
-LLNotification::LLNotification(const LLSD& sd) :
-	mTemporaryResponder(false),
-	mRespondedTo(false),
-	mCancelled(false),
-	mIgnored(false),
-	mResponderObj(NULL),
-	mIsReusable(false)
-{ 
-	mId.generate();
-	mSubstitutions = sd["substitutions"];
-	mPayload = sd["payload"]; 
-	mTimestamp = sd["time"]; 
-	mExpiresAt = sd["expiry"];
-	mPriority = (ENotificationPriority)sd["priority"].asInteger();
-	mResponseFunctorName = sd["responseFunctor"].asString();
-	std::string templatename = sd["name"].asString();
-	init(templatename, LLSD());
-	// replace form with serialized version
-	mForm = LLNotificationFormPtr(new LLNotificationForm(sd["form"]));
-}
-
-
-LLSD LLNotification::asLLSD()
+LLSD LLNotification::asLLSD(bool excludeTemplateElements)
 {
-	LLSD output;
-	output["id"] = mId;
-	output["name"] = mTemplatep->mName;
-	output["form"] = getForm()->asLLSD();
-	output["substitutions"] = mSubstitutions;
-	output["payload"] = mPayload;
-	output["time"] = mTimestamp;
-	output["expiry"] = mExpiresAt;
-	output["priority"] = (S32)mPriority;
-	output["responseFunctor"] = mResponseFunctorName;
-	output["reusable"] = mIsReusable;
+	LLParamSDParser parser;
 
-	if(mResponder)
-	{
-		output["responder"] = mResponder->asLLSD();
+	Params p;
+	p.id = mId;
+	p.name = mTemplatep->mName;
+	p.substitutions = mSubstitutions;
+	p.payload = mPayload;
+	p.time_stamp = mTimestamp;
+	p.expiry = mExpiresAt;
+	p.priority = mPriority;
+
+    LLNotificationFormPtr templateForm = mTemplatep->mForm;
+    LLSD formElements = mForm->asLLSD();
+
+    //All form elements (dynamic or not)
+    if(!excludeTemplateElements)
+    {
+        p.form_elements = formElements;
+    }
+    //Only dynamic form elements (exclude template elements)
+    else if(templateForm->getNumElements() < formElements.size())
+    {
+        LLSD dynamicElements;
+        //Offset to dynamic elements and store them
+        mForm->getElements(dynamicElements, templateForm->getNumElements());
+        p.form_elements = dynamicElements;
+    }
+    
+    if(mResponder)
+    {
+        p.functor.responder_sd = mResponder->asLLSD();
+    }
+    
+	if(!mResponseFunctorName.empty())
+	{
+		p.functor.name = mResponseFunctorName;
 	}
 
+	LLSD output;
+	parser.writeSD(output, p);
 	return output;
 }
 
@@ -569,7 +586,6 @@ void LLNotification::updateFrom(LLNotificationPtr other)
 	mRespondedTo = other->mRespondedTo;
 	mResponse = other->mResponse;
 	mTemporaryResponder = other->mTemporaryResponder;
-	mIsReusable = other->isReusable();
 
 	update();
 }
@@ -668,7 +684,7 @@ void LLNotification::respond(const LLSD& response)
 		return;
 	}
 
-	if (mTemporaryResponder && !isReusable())
+	if (mTemporaryResponder)
 	{
 		LLNotificationFunctorRegistry::instance().unregisterFunctor(mResponseFunctorName);
 		mResponseFunctorName = "";
@@ -829,7 +845,7 @@ void LLNotification::init(const std::string& template_name, const LLSD& form_ele
 	//mSubstitutions["_ARGS"] = get_all_arguments_as_text(mSubstitutions);
 
 	mForm = LLNotificationFormPtr(new LLNotificationForm(*mTemplatep->mForm));
-	mForm->append(form_elements);
+    mForm->append(form_elements);
 
 	// apply substitution to form labels
 	mForm->formatElements(mSubstitutions);
@@ -897,6 +913,49 @@ std::string LLNotification::getURL() const
 	return (mTemplatep ? url : "");
 }
 
+bool LLNotification::canLogToChat() const
+{
+	return mTemplatep->mLogToChat;
+}
+
+bool LLNotification::canLogToIM() const
+{
+	return mTemplatep->mLogToIM;
+}
+
+bool LLNotification::canShowToast() const
+{
+	return mTemplatep->mShowToast;
+}
+
+bool LLNotification::hasFormElements() const
+{
+	return mTemplatep->mForm->getNumElements() != 0;
+}
+
+void LLNotification::playSound()
+{ 
+    make_ui_sound(mTemplatep->mSoundName.c_str());
+}
+
+LLNotification::ECombineBehavior LLNotification::getCombineBehavior() const
+{
+	return mTemplatep->mCombineBehavior;
+}
+
+void LLNotification::updateForm( const LLNotificationFormPtr& form )
+{
+	mForm = form;
+}
+
+void LLNotification::repost()
+{
+	mRespondedTo = false;
+	LLNotifications::instance().update(shared_from_this());
+}
+
+
+
 // =========================================================
 // LLNotificationChannel implementation
 // ---
@@ -957,7 +1016,7 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	std::string cmd = payload["sigtype"];
 	LLNotificationSet::iterator foundItem = mItems.find(pNotification);
 	bool wasFound = (foundItem != mItems.end());
-	bool passesFilter = mFilter(pNotification);
+	bool passesFilter = mFilter ? mFilter(pNotification) : true;
 	
 	// first, we offer the result of the filter test to the simple
 	// signals for pass/fail. One of these is guaranteed to be called.
@@ -966,10 +1025,12 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 	bool abortProcessing = false;
 	if (passesFilter)
 	{
+		onFilterPass(pNotification);
 		abortProcessing = mPassedFilter(payload);
 	}
 	else
 	{
+		onFilterFail(pNotification);
 		abortProcessing = mFailedFilter(payload);
 	}
 	
@@ -987,8 +1048,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		{
 			// not in our list, add it and say so
 			mItems.insert(pNotification);
-			abortProcessing = mChanged(payload);
 			onLoad(pNotification);
+			abortProcessing = mChanged(payload);
 		}
 	}
 	else if (cmd == "change")
@@ -1003,18 +1064,18 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 			{
 				// it already existed, so this is a change
 				// since it changed in place, all we have to do is resend the signal
-				abortProcessing = mChanged(payload);
 				onChange(pNotification);
+				abortProcessing = mChanged(payload);
 			}
 			else
 			{
 				// not in our list, add it and say so
 				mItems.insert(pNotification);
+				onChange(pNotification);
 				// our payload is const, so make a copy before changing it
 				LLSD newpayload = payload;
 				newpayload["sigtype"] = "add";
 				abortProcessing = mChanged(newpayload);
-				onChange(pNotification);
 			}
 		}
 		else
@@ -1023,11 +1084,11 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 			{
 				// it already existed, so this is a delete
 				mItems.erase(pNotification);
+				onChange(pNotification);
 				// our payload is const, so make a copy before changing it
 				LLSD newpayload = payload;
 				newpayload["sigtype"] = "delete";
 				abortProcessing = mChanged(newpayload);
-				onChange(pNotification);
 			}
 			// didn't pass, not on our list, do nothing
 		}
@@ -1041,8 +1102,8 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		{
 			// not in our list, add it and say so
 			mItems.insert(pNotification);
-			abortProcessing = mChanged(payload);
 			onAdd(pNotification);
+			abortProcessing = mChanged(payload);
 		}
 	}
 	else if (cmd == "delete")
@@ -1050,65 +1111,35 @@ bool LLNotificationChannelBase::updateItem(const LLSD& payload, LLNotificationPt
 		// if we have it in our list, pass on the delete, then delete it, else do nothing
 		if (wasFound)
 		{
+			onDelete(pNotification);
 			abortProcessing = mChanged(payload);
-			// do not delete the notification to make LLChatHistory::appendMessage add notification panel to IM window
-			if( ! pNotification->isReusable() )
-			{
-				mItems.erase(pNotification);
-				onDelete(pNotification);
-			}
+			mItems.erase(pNotification);
 		}
 	}
 	return abortProcessing;
 }
 
-/* static */
-LLNotificationChannelPtr LLNotificationChannel::buildChannel(const std::string& name, 
-															 const std::string& parent,
-															 LLNotificationFilter filter, 
-															 LLNotificationComparator comparator)
+LLNotificationChannel::LLNotificationChannel(const Params& p)
+:	LLNotificationChannelBase(p.filter()),
+	LLInstanceTracker<LLNotificationChannel, std::string>(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString()),
+	mName(p.name.isProvided() ? p.name : LLUUID::generateNewID().asString())
+{
+	BOOST_FOREACH(const std::string& source, p.sources)
 {
-	// note: this is not a leak; notifications are self-registering.
-	// This factory helps to prevent excess deletions by making sure all smart
-	// pointers to notification channels come from the same source
-	new LLNotificationChannel(name, parent, filter, comparator);
-	return LLNotifications::instance().getChannel(name);
+		connectToChannel(source);
+	}
 }
 
 
 LLNotificationChannel::LLNotificationChannel(const std::string& name, 
 											 const std::string& parent,
-											 LLNotificationFilter filter, 
-											 LLNotificationComparator comparator) : 
-LLNotificationChannelBase(filter, comparator),
-mName(name),
-mParent(parent)
-{
-	// store myself in the channel map
-	LLNotifications::instance().addChannel(LLNotificationChannelPtr(this));
+											 LLNotificationFilter filter) 
+:	LLNotificationChannelBase(filter),
+	LLInstanceTracker<LLNotificationChannel, std::string>(name),
+	mName(name)
+{
 	// bind to notification broadcast
-	if (parent.empty())
-	{
-		LLNotifications::instance().connectChanged(
-			boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
-	}
-	else
-	{
-		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(parent);
-		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
-	}
-}
-
-
-void LLNotificationChannel::setComparator(LLNotificationComparator comparator) 
-{ 
-	mComparator = comparator; 
-	LLNotificationSet s2(mComparator);
-	s2.insert(mItems.begin(), mItems.end());
-	mItems.swap(s2);
-	
-	// notify clients that we've been resorted
-	mChanged(LLSD().with("sigtype", "sort")); 
+	connectToChannel(parent);
 }
 
 bool LLNotificationChannel::isEmpty() const
@@ -1131,6 +1162,11 @@ LLNotificationChannel::Iterator LLNotificationChannel::end()
 	return mItems.end();
 }
 
+size_t LLNotificationChannel::size()
+{
+	return mItems.size();
+}
+
 std::string LLNotificationChannel::summarize()
 {
 	std::string s("Channel '");
@@ -1144,22 +1180,33 @@ std::string LLNotificationChannel::summarize()
 	return s;
 }
 
+void LLNotificationChannel::connectToChannel( const std::string& channel_name )
+{
+	if (channel_name.empty())
+	{
+		LLNotifications::instance().connectChanged(
+			boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+	}
+	else
+	{
+		LLNotificationChannelPtr p = LLNotifications::instance().getChannel(channel_name);
+		p->connectChanged(boost::bind(&LLNotificationChannelBase::updateItem, this, _1));
+	}
+}
 
 // ---
 // END OF LLNotificationChannel implementation
 // =========================================================
 
 
-// =========================================================
+// ==============================================	===========
 // LLNotifications implementation
 // ---
-LLNotifications::LLNotifications() : LLNotificationChannelBase(LLNotificationFilters::includeEverything,
-															   LLNotificationComparators::orderByUUID()),
-									mIgnoreAllNotifications(false)
+LLNotifications::LLNotifications() 
+:	LLNotificationChannelBase(LLNotificationFilters::includeEverything),
+	mIgnoreAllNotifications(false)
 {
 	LLUICtrl::CommitCallbackRegistry::currentRegistrar().add("Notification.Show", boost::bind(&LLNotifications::addFromCallback, this, _2));
-
-    mListener.reset(new LLNotificationsListener(*this));
 }
 
 
@@ -1196,7 +1243,15 @@ bool LLNotifications::uniqueFilter(LLNotificationPtr pNotif)
 		if (pNotif != existing_notification 
 			&& pNotif->isEquivalentTo(existing_notification))
 		{
-			return false;
+			if (pNotif->getCombineBehavior() == LLNotification::CANCEL_OLD)
+			{
+				cancel(existing_notification);
+				return true;
+			}
+			else
+			{
+				return false;
+			}
 		}
 	}
 
@@ -1236,43 +1291,43 @@ bool LLNotifications::failedUniquenessTest(const LLSD& payload)
 		return false;
 	}
 
-	// Update the existing unique notification with the data from this particular instance...
-	// This guarantees that duplicate notifications will be collapsed to the one
-	// most recently triggered
-	for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
-		existing_it != mUniqueNotifications.end();
-		++existing_it)
+	switch(pNotif->getCombineBehavior())
 	{
-		LLNotificationPtr existing_notification = existing_it->second;
-		if (pNotif != existing_notification 
-			&& pNotif->isEquivalentTo(existing_notification))
+	case  LLNotification::REPLACE_WITH_NEW:
+		// Update the existing unique notification with the data from this particular instance...
+		// This guarantees that duplicate notifications will be collapsed to the one
+		// most recently triggered
+		for (LLNotificationMap::iterator existing_it = mUniqueNotifications.find(pNotif->getName());
+			existing_it != mUniqueNotifications.end();
+			++existing_it)
 		{
-			// copy notification instance data over to oldest instance
-			// of this unique notification and update it
-			existing_notification->updateFrom(pNotif);
-			// then delete the new one
-			cancel(pNotif);
+			LLNotificationPtr existing_notification = existing_it->second;
+			if (pNotif != existing_notification 
+				&& pNotif->isEquivalentTo(existing_notification))
+			{
+				// copy notification instance data over to oldest instance
+				// of this unique notification and update it
+				existing_notification->updateFrom(pNotif);
+				// then delete the new one
+				cancel(pNotif);
+			}
 		}
+		break;
+	case LLNotification::KEEP_OLD:
+		break;
+	case LLNotification::CANCEL_OLD:
+		// already handled by filter logic
+		break;
+	default:
+		break;
 	}
 
 	return false;
 }
 
-
-void LLNotifications::addChannel(LLNotificationChannelPtr pChan)
-{
-	mChannels[pChan->getName()] = pChan;
-}
-
 LLNotificationChannelPtr LLNotifications::getChannel(const std::string& channelName)
 {
-	ChannelMap::iterator p = mChannels.find(channelName);
-	if(p == mChannels.end())
-	{
-		llerrs << "Did not find channel named " << channelName << llendl;
-		return LLNotificationChannelPtr();
-	}
-	return p->second;
+	return LLNotificationChannelPtr(LLNotificationChannel::getInstance(channelName));
 }
 
 
@@ -1288,24 +1343,21 @@ void LLNotifications::createDefaultChannels()
 {
 	// now construct the various channels AFTER loading the notifications,
 	// because the history channel is going to rewrite the stored notifications file
-	LLNotificationChannel::buildChannel("Enabled", "",
-		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this));
-	LLNotificationChannel::buildChannel("Expiration", "Enabled",
-		boost::bind(&LLNotifications::expirationFilter, this, _1));
-	LLNotificationChannel::buildChannel("Unexpired", "Enabled",
-		!boost::bind(&LLNotifications::expirationFilter, this, _1)); // use negated bind
-	LLNotificationChannel::buildChannel("Unique", "Unexpired",
-		boost::bind(&LLNotifications::uniqueFilter, this, _1));
-	LLNotificationChannel::buildChannel("Ignore", "Unique",
-		filterIgnoredNotifications);
-	LLNotificationChannel::buildChannel("VisibilityRules", "Ignore",
-		boost::bind(&LLNotifications::isVisibleByRules, this, _1));
-	LLNotificationChannel::buildChannel("Visible", "VisibilityRules",
-		&LLNotificationFilters::includeEverything);
-
-	// create special persistent notification channel
-	// this isn't a leak, don't worry about the empty "new"
-	new LLPersistentNotificationChannel();
+	mDefaultChannels.push_back(new LLNotificationChannel("Enabled", "",
+		!boost::bind(&LLNotifications::getIgnoreAllNotifications, this)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Expiration", "Enabled",
+		boost::bind(&LLNotifications::expirationFilter, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Unexpired", "Enabled",
+		!boost::bind(&LLNotifications::expirationFilter, this, _1))); // use negated bind
+	mDefaultChannels.push_back(new LLNotificationChannel("Unique", "Unexpired",
+		boost::bind(&LLNotifications::uniqueFilter, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Ignore", "Unique",
+		filterIgnoredNotifications));
+	mDefaultChannels.push_back(new LLNotificationChannel("VisibilityRules", "Ignore",
+		boost::bind(&LLNotifications::isVisibleByRules, this, _1)));
+	mDefaultChannels.push_back(new LLNotificationChannel("Visible", "VisibilityRules",
+		&LLNotificationFilters::includeEverything));
+	mDefaultChannels.push_back(new LLPersistentNotificationChannel());
 
 	// connect action methods to these channels
 	LLNotifications::instance().getChannel("Enabled")->
@@ -1537,34 +1589,32 @@ void LLNotifications::addFromCallback(const LLSD& name)
 	add(name.asString(), LLSD(), LLSD());
 }
 
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-									   const LLSD& substitutions, 
-									   const LLSD& payload)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.name = name;
 	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
 }
 
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-									   const LLSD& substitutions, 
-									   const LLSD& payload, 
-									   const std::string& functor_name)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, const std::string& functor_name)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.name = functor_name;
-	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
+	return add(LLNotification::Params().name(name)
+										.substitutions(substitutions)
+										.payload(payload)
+										.functor(functor_p));	
 }
 							  
 //virtual
-LLNotificationPtr LLNotifications::add(const std::string& name, 
-										const LLSD& substitutions, 
-										const LLSD& payload, 
-										LLNotificationFunctorRegistry::ResponseFunctor functor)
+LLNotificationPtr LLNotifications::add(const std::string& name, const LLSD& substitutions, const LLSD& payload, LLNotificationFunctorRegistry::ResponseFunctor functor)
 {
 	LLNotification::Params::Functor functor_p;
 	functor_p.function = functor;
-	return add(LLNotification::Params().name(name).substitutions(substitutions).payload(payload).functor(functor_p));	
+	return add(LLNotification::Params().name(name)
+										.substitutions(substitutions)
+										.payload(payload)
+										.functor(functor_p));	
 }
 
 // generalized add function that takes a parameter block object for more complex instantiations
@@ -1595,12 +1645,11 @@ void LLNotifications::cancel(LLNotificationPtr pNotif)
 	if (pNotif == NULL || pNotif->isCancelled()) return;
 
 	LLNotificationSet::iterator it=mItems.find(pNotif);
-	if (it == mItems.end())
+	if (it != mItems.end())
 	{
-		llerrs << "Attempted to delete nonexistent notification " << pNotif->getName() << llendl;
+		pNotif->cancel();
+		updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
 	}
-	pNotif->cancel();
-	updateItem(LLSD().with("sigtype", "delete").with("id", pNotif->id()), pNotif);
 }
 
 void LLNotifications::cancelByName(const std::string& name)
@@ -1639,7 +1688,7 @@ void LLNotifications::update(const LLNotificationPtr pNotif)
 
 LLNotificationPtr LLNotifications::find(LLUUID uuid)
 {
-	LLNotificationPtr target = LLNotificationPtr(new LLNotification(uuid));
+	LLNotificationPtr target = LLNotificationPtr(new LLNotification(LLNotification::Params().id(uuid)));
 	LLNotificationSet::iterator it=mItems.find(target);
 	if (it == mItems.end())
 	{
@@ -1778,22 +1827,18 @@ std::ostream& operator<<(std::ostream& s, const LLNotification& notification)
 	return s;
 }
 
-//static
-void LLPostponedNotification::lookupName(LLPostponedNotification* thiz,
-										 const LLUUID& id,
+void LLPostponedNotification::lookupName(const LLUUID& id,
 										 bool is_group)
 {
 	if (is_group)
 	{
 		gCacheName->getGroup(id,
 			boost::bind(&LLPostponedNotification::onGroupNameCache,
-				thiz, _1, _2, _3));
+				this, _1, _2, _3));
 	}
 	else
 	{
-		LLAvatarNameCache::get(id,
-			boost::bind(&LLPostponedNotification::onAvatarNameCache,
-				thiz, _1, _2));
+		fetchAvatarName(id);
 	}
 }
 
@@ -1804,9 +1849,24 @@ void LLPostponedNotification::onGroupNameCache(const LLUUID& id,
 	finalizeName(full_name);
 }
 
+void LLPostponedNotification::fetchAvatarName(const LLUUID& id)
+{
+	if (id.notNull())
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLPostponedNotification::onAvatarNameCache, this, _1, _2));
+	}
+}
+
 void LLPostponedNotification::onAvatarNameCache(const LLUUID& agent_id,
 												const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	std::string name = av_name.getCompleteName();
 
 	// from PE merge - we should figure out if this is the right thing to do
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index d7534c416dccdccaff5314bc1258e31d34e62ca4..87573c2a56bdb4fe17f0e240563208504271aff3 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -87,17 +87,16 @@
 #include <boost/shared_ptr.hpp>
 #include <boost/enable_shared_from_this.hpp>
 #include <boost/type_traits.hpp>
+#include <boost/signals2.hpp>
 
-// we want to minimize external dependencies, but this one is important
-#include "llsd.h"
-
-// and we need this to manage the notification callbacks
 #include "llevents.h"
 #include "llfunctorregistry.h"
-#include "llpointer.h"
 #include "llinitparam.h"
-#include "llnotificationslistener.h"
+#include "llmortician.h"
 #include "llnotificationptr.h"
+#include "llpointer.h"
+#include "llrefcount.h"
+#include "llsdparam.h"
 
 class LLAvatarName;
 typedef enum e_notification_priority
@@ -164,6 +163,7 @@ class LLNotificationForm
 	struct FormElementBase : public LLInitParam::Block<FormElementBase>
 	{
 		Optional<std::string>	name;
+		Optional<bool>			enabled;
 
 		FormElementBase();
 	};
@@ -233,16 +233,21 @@ class LLNotificationForm
 	} EIgnoreType;
 
 	LLNotificationForm();
+	LLNotificationForm(const LLNotificationForm&);
 	LLNotificationForm(const LLSD& sd);
 	LLNotificationForm(const std::string& name, const Params& p);
 
+	void fromLLSD(const LLSD& sd);
 	LLSD asLLSD() const;
 
 	S32 getNumElements() { return mFormData.size(); }
 	LLSD getElement(S32 index) { return mFormData.get(index); }
 	LLSD getElement(const std::string& element_name);
-	bool hasElement(const std::string& element_name);
-	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD());
+    void getElements(LLSD& elements, S32 offset = 0);
+	bool hasElement(const std::string& element_name) const;
+	bool getElementEnabled(const std::string& element_name) const;
+	void setElementEnabled(const std::string& element_name, bool enabled);
+	void addElement(const std::string& type, const std::string& name, const LLSD& value = LLSD(), bool enabled = true);
 	void formatElements(const LLSD& substitutions);
 	// appends form elements from another form serialized as LLSD
 	void append(const LLSD& sub_form);
@@ -296,42 +301,52 @@ LOG_CLASS(LLNotification);
 friend class LLNotifications;
 
 public:
+
 	// parameter object used to instantiate a new notification
 	struct Params : public LLInitParam::Block<Params>
 	{
 		friend class LLNotification;
 	
 		Mandatory<std::string>					name;
-
-		// optional
-		Optional<LLSD>							substitutions;
-		Optional<LLSD>							payload;
+		Optional<LLUUID>						id;
+		Optional<LLSD>							substitutions,
+												form_elements,
+												payload;
 		Optional<ENotificationPriority, NotificationPriorityValues>	priority;
-		Optional<LLSD>							form_elements;
-		Optional<LLDate>						time_stamp;
+		Optional<LLDate>						time_stamp,
+												expiry;
 		Optional<LLNotificationContext*>		context;
 		Optional<void*>							responder;
+		Optional<bool>							offer_from_agent;
+        Optional<bool>							is_dnd;
 
 		struct Functor : public LLInitParam::ChoiceBlock<Functor>
 		{
 			Alternative<std::string>										name;
 			Alternative<LLNotificationFunctorRegistry::ResponseFunctor>	function;
 			Alternative<LLNotificationResponderPtr>						responder;
+            Alternative<LLSD>						                    responder_sd;
 
 			Functor()
-			:	name("functor_name"),
+			:	name("responseFunctor"),
 				function("functor"),
-				responder("responder")
+				responder("responder"),
+                responder_sd("responder_sd")
 			{}
 		};
 		Optional<Functor>						functor;
 
 		Params()
 		:	name("name"),
+			id("id"),
 			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-			time_stamp("time_stamp"),
+			time_stamp("time"),
 			payload("payload"),
-			form_elements("form_elements")
+			form_elements("form"),
+			substitutions("substitutions"),
+			expiry("expiry"),
+			offer_from_agent("offer_from_agent", false),
+            is_dnd("is_dnd", false)
 		{
 			time_stamp = LLDate::now();
 			responder = NULL;
@@ -340,9 +355,13 @@ friend class LLNotifications;
 		Params(const std::string& _name) 
 		:	name("name"),
 			priority("priority", NOTIFICATION_PRIORITY_UNSPECIFIED),
-			time_stamp("time_stamp"),
+			time_stamp("time"),
 			payload("payload"),
-			form_elements("form_elements")
+			form_elements("form"),
+			substitutions("substitutions"),
+			expiry("expiry"),
+			offer_from_agent("offer_from_agent", false),
+            is_dnd("is_dnd", false)
 		{
 			functor.name = _name;
 			name = _name;
@@ -355,7 +374,7 @@ friend class LLNotifications;
 
 private:
 	
-	LLUUID mId;
+	const LLUUID mId;
 	LLSD mPayload;
 	LLSD mSubstitutions;
 	LLDate mTimestamp;
@@ -367,8 +386,9 @@ friend class LLNotifications;
 	ENotificationPriority mPriority;
 	LLNotificationFormPtr mForm;
 	void* mResponderObj; // TODO - refactor/remove this field
-	bool mIsReusable;
 	LLNotificationResponderPtr mResponder;
+	bool mOfferFromAgent;
+    bool mIsDND;
 
 	// a reference to the template
 	LLNotificationTemplatePtr mTemplatep;
@@ -392,18 +412,10 @@ friend class LLNotifications;
 
 	void init(const std::string& template_name, const LLSD& form_elements);
 
-	LLNotification(const Params& p);
-
-	// this is just for making it easy to look things up in a set organized by UUID -- DON'T USE IT
-	// for anything real!
- LLNotification(LLUUID uuid) : mId(uuid), mCancelled(false), mRespondedTo(false), mIgnored(false), mPriority(NOTIFICATION_PRIORITY_UNSPECIFIED), mTemporaryResponder(false) {}
-
 	void cancel();
 
 public:
-
-	// constructor from a saved notification
-	LLNotification(const LLSD& sd);
+	LLNotification(const LLSDParamAdapter<Params>& p);
 
 	void setResponseFunctor(std::string const &responseFunctorName);
 
@@ -446,7 +458,12 @@ friend class LLNotifications;
 	// ["time"] = time at which notification was generated;
 	// ["expiry"] = time at which notification expires;
 	// ["responseFunctor"] = name of registered functor that handles responses to notification;
-	LLSD asLLSD();
+	LLSD asLLSD(bool excludeTemplateElements = false);
+
+	const LLNotificationFormPtr getForm();
+	void updateForm(const LLNotificationFormPtr& form);
+
+	void repost();
 
 	void respond(const LLSD& sd);
 	void respondWithDefault();
@@ -507,6 +524,21 @@ friend class LLNotifications;
 		return mTimestamp;
 	}
 
+	bool getOfferFromAgent() const
+	{
+		return mOfferFromAgent;
+	}
+
+    bool isDND() const
+    {
+        return mIsDND;
+    }
+
+    void setDND(const bool flag)
+    {
+        mIsDND = flag;
+    }
+
 	std::string getType() const;
 	std::string getMessage() const;
 	std::string getFooter() const;
@@ -514,8 +546,21 @@ friend class LLNotifications;
 	std::string getURL() const;
 	S32 getURLOption() const;
     S32 getURLOpenExternally() const;
+	bool canLogToChat() const;
+	bool canLogToIM() const;
+	bool canShowToast() const;
+	bool hasFormElements() const;
+    void playSound();
+
+	typedef enum e_combine_behavior
+	{
+		REPLACE_WITH_NEW,
+		KEEP_OLD,
+		CANCEL_OLD
+
+	} ECombineBehavior;
 	
-	const LLNotificationFormPtr getForm();
+	ECombineBehavior getCombineBehavior() const;
 
 	const LLDate getExpiration() const
 	{
@@ -532,10 +577,6 @@ friend class LLNotifications;
 		return mId;
 	}
 
-	bool isReusable() { return mIsReusable; }
-
-	void setReusable(bool reusable) { mIsReusable = reusable; }
-	
 	// comparing two notifications normally means comparing them by UUID (so we can look them
 	// up quickly this way)
 	bool operator<(const LLNotification& rhs) const
@@ -647,44 +688,17 @@ namespace LLNotificationFilters
 
 namespace LLNotificationComparators
 {
-	typedef enum e_direction { ORDER_DECREASING, ORDER_INCREASING } EDirection;
-
-	// generic order functor that takes method or member variable reference
-	template<typename T>
-	struct orderBy
+	struct orderByUUID
 	{
-		typedef boost::function<T (LLNotificationPtr)> field_t;
-        	orderBy(field_t field, EDirection direction = ORDER_INCREASING) : mField(field), mDirection(direction) {}
 		bool operator()(LLNotificationPtr lhs, LLNotificationPtr rhs)
 		{
-			if (mDirection == ORDER_DECREASING)
-			{
-				return mField(lhs) > mField(rhs);
-			}
-			else
-			{
-				return mField(lhs) < mField(rhs);
-			}
+			return lhs->id() < rhs->id();
 		}
-
-		field_t mField;
-		EDirection mDirection;
-	};
-
-	struct orderByUUID : public orderBy<const LLUUID&>
-	{
-		orderByUUID(EDirection direction = ORDER_INCREASING) : orderBy<const LLUUID&>(&LLNotification::id, direction) {}
-	};
-
-	struct orderByDate : public orderBy<const LLDate&>
-	{
-		orderByDate(EDirection direction = ORDER_INCREASING) : orderBy<const LLDate&>(&LLNotification::getDate, direction) {}
 	};
 };
 
 typedef boost::function<bool (LLNotificationPtr)> LLNotificationFilter;
-typedef boost::function<bool (LLNotificationPtr, LLNotificationPtr)> LLNotificationComparator;
-typedef std::set<LLNotificationPtr, LLNotificationComparator> LLNotificationSet;
+typedef std::set<LLNotificationPtr, LLNotificationComparators::orderByUUID> LLNotificationSet;
 typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 
 // ========================================================
@@ -705,12 +719,14 @@ typedef std::multimap<std::string, LLNotificationPtr> LLNotificationMap;
 // all of the built-in tests should attach to the "Visible" channel
 //
 class LLNotificationChannelBase :
-	public LLEventTrackable
+	public LLEventTrackable,
+	public LLRefCount
 {
 	LOG_CLASS(LLNotificationChannelBase);
 public:
-	LLNotificationChannelBase(LLNotificationFilter filter, LLNotificationComparator comp) : 
-		mFilter(filter), mItems(comp) 
+	LLNotificationChannelBase(LLNotificationFilter filter) 
+	:	mFilter(filter), 
+		mItems() 
 	{}
 	virtual ~LLNotificationChannelBase() {}
 	// you can also connect to a Channel, so you can be notified of
@@ -776,6 +792,9 @@ class LLNotificationChannelBase :
 	virtual void onDelete(LLNotificationPtr p) {}
 	virtual void onChange(LLNotificationPtr p) {}
 
+	virtual void onFilterPass(LLNotificationPtr p) {}
+	virtual void onFilterFail(LLNotificationPtr p) {}
+
 	bool updateItem(const LLSD& payload, LLNotificationPtr pNotification);
 	LLNotificationFilter mFilter;
 };
@@ -785,64 +804,53 @@ class LLNotificationChannelBase :
 // destroy it, but if it becomes necessary to do so, the shared_ptr model
 // will ensure that we don't leak resources.
 class LLNotificationChannel;
-typedef boost::shared_ptr<LLNotificationChannel> LLNotificationChannelPtr;
+typedef boost::intrusive_ptr<LLNotificationChannel> LLNotificationChannelPtr;
 
 // manages a list of notifications
 // Note that if this is ever copied around, we might find ourselves with multiple copies
 // of a queue with notifications being added to different nonequivalent copies. So we 
-// make it inherit from boost::noncopyable, and then create a map of shared_ptr to manage it.
-// 
-// NOTE: LLNotificationChannel is self-registering. The *correct* way to create one is to 
-// do something like:
-//		LLNotificationChannel::buildChannel("name", "parent"...);
-// This returns an LLNotificationChannelPtr, which you can store, or
-// you can then retrieve the channel by using the registry:
-//		LLNotifications::instance().getChannel("name")...
+// make it inherit from boost::noncopyable, and then create a map of LLPointer to manage it.
 //
 class LLNotificationChannel : 
 	boost::noncopyable, 
-	public LLNotificationChannelBase
+	public LLNotificationChannelBase,
+	public LLInstanceTracker<LLNotificationChannel, std::string>
 {
 	LOG_CLASS(LLNotificationChannel);
 
 public:  
+	// Notification Channels have a filter, which determines which notifications
+	// will be added to this channel. 
+	// Channel filters cannot change.
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Mandatory<std::string>				name;
+		Optional<LLNotificationFilter>		filter;
+		Multiple<std::string>				sources;
+	};
+
+	LLNotificationChannel(const Params& p = Params());
+	LLNotificationChannel(const std::string& name, const std::string& parent, LLNotificationFilter filter);
+
 	virtual ~LLNotificationChannel() {}
 	typedef LLNotificationSet::iterator Iterator;
     
 	std::string getName() const { return mName; }
-	std::string getParentChannelName() { return mParent; }
+    
+	void connectToChannel(const std::string& channel_name);
     
     bool isEmpty() const;
     S32 size() const;
     
     Iterator begin();
     Iterator end();
+	size_t size();
 
-    // Channels have a comparator to control sort order;
-	// the default sorts by arrival date
-    void setComparator(LLNotificationComparator comparator);
-	
 	std::string summarize();
 
-	// factory method for constructing these channels; since they're self-registering,
-	// we want to make sure that you can't use new to make them
-	static LLNotificationChannelPtr buildChannel(const std::string& name, const std::string& parent,
-						LLNotificationFilter filter=LLNotificationFilters::includeEverything, 
-						LLNotificationComparator comparator=LLNotificationComparators::orderByUUID());
-	
-protected:
-    // Notification Channels have a filter, which determines which notifications
-	// will be added to this channel. 
-	// Channel filters cannot change.
-	// Channels have a protected constructor so you can't make smart pointers that don't 
-	// come from our internal reference; call NotificationChannel::build(args)
-	LLNotificationChannel(const std::string& name, const std::string& parent,
-						  LLNotificationFilter filter, LLNotificationComparator comparator);
-
 private:
 	std::string mName;
 	std::string mParent;
-	LLNotificationComparator mComparator;
 };
 
 // An interface class to provide a clean linker seam to the LLNotifications class.
@@ -925,10 +933,6 @@ class LLNotifications :
 
 	void createDefaultChannels();
 
-	typedef std::map<std::string, LLNotificationChannelPtr> ChannelMap;
-	ChannelMap mChannels;
-
-	void addChannel(LLNotificationChannelPtr pChan);
 	LLNotificationChannelPtr getChannel(const std::string& channelName);
 	
 	std::string getGlobalString(const std::string& key) const;
@@ -966,7 +970,7 @@ class LLNotifications :
 
 	bool mIgnoreAllNotifications;
 
-    boost::scoped_ptr<LLNotificationsListener> mListener;
+	std::vector<LLNotificationChannelPtr> mDefaultChannels;
 };
 
 /**
@@ -979,7 +983,7 @@ class LLNotifications :
  *  1 create class derived from LLPostponedNotification;
  *  2 call LLPostponedNotification::add method;
  */
-class LLPostponedNotification
+class LLPostponedNotification : public LLMortician
 {
 public:
 	/**
@@ -997,26 +1001,38 @@ class LLPostponedNotification
 		thiz->mParams = params;
 
 		// Avoid header file dependency on llcachename.h
-		lookupName(thiz, id, is_group);
+		thiz->lookupName(id, is_group);
 	}
 
 private:
-	static void lookupName(LLPostponedNotification* thiz, const LLUUID& id, bool is_group);
+	void lookupName(const LLUUID& id, bool is_group);
 	// only used for groups
 	void onGroupNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
 	// only used for avatars
+	void fetchAvatarName(const LLUUID& id);
 	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
 	// used for both group and avatar names
 	void finalizeName(const std::string& name);
 
 	void cleanup()
 	{
-		delete this;
+		die();
 	}
 
 protected:
-	LLPostponedNotification() {}
-	virtual ~LLPostponedNotification() {}
+	LLPostponedNotification()
+		: mParams(),
+		mName(),
+		mAvatarNameCacheConnection()
+	{}
+
+	virtual ~LLPostponedNotification()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 
 	/**
 	 * Abstract method provides possibility to modify notification parameters and
@@ -1027,6 +1043,58 @@ class LLPostponedNotification
 
 	LLNotification::Params mParams;
 	std::string mName;
+	boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+// Stores only persistent notifications.
+// Class users can use connectChanged() to process persistent notifications
+// (see LLPersistentNotificationStorage for example).
+class LLPersistentNotificationChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLPersistentNotificationChannel);
+public:
+	LLPersistentNotificationChannel() 
+		:	LLNotificationChannel("Persistent", "Visible", &notificationFilter)
+	{
+	}
+
+	typedef std::vector<LLNotificationPtr> history_list_t;
+	history_list_t::iterator beginHistory() { sortHistory(); return mHistory.begin(); }
+	history_list_t::iterator endHistory() { return mHistory.end(); }
+
+private:
+
+	struct sortByTime
+	{
+		S32 operator ()(const LLNotificationPtr& a, const LLNotificationPtr& b)
+		{
+			return a->getDate() < b->getDate();
+		}
+	};
+
+	void sortHistory()
+	{
+		std::sort(mHistory.begin(), mHistory.end(), sortByTime());
+	}
+
+
+	// The channel gets all persistent notifications except those that have been canceled
+	static bool notificationFilter(LLNotificationPtr pNotification)
+	{
+		bool handle_notification = false;
+
+		handle_notification = pNotification->isPersistent()
+			&& !pNotification->isCancelled();
+
+		return handle_notification;
+	}
+
+	void onAdd(LLNotificationPtr p) 
+	{
+		mHistory.push_back(p);
+	}
+
+	std::vector<LLNotificationPtr> mHistory;
 };
 
 #endif//LL_LLNOTIFICATIONS_H
diff --git a/indra/llui/llnotificationslistener.cpp b/indra/llui/llnotificationslistener.cpp
deleted file mode 100644
index 3bbeb3a77845aae010cb1f40ade9f3b989f1ce18..0000000000000000000000000000000000000000
--- a/indra/llui/llnotificationslistener.cpp
+++ /dev/null
@@ -1,354 +0,0 @@
-/**
- * @file   llnotificationslistener.cpp
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Implementation for llnotificationslistener.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "linden_common.h"
-#include "llnotificationslistener.h"
-#include "llnotifications.h"
-#include "llnotificationtemplate.h"
-#include "llsd.h"
-#include "llui.h"
-
-LLNotificationsListener::LLNotificationsListener(LLNotifications & notifications) :
-    LLEventAPI("LLNotifications",
-               "LLNotifications listener to (e.g.) pop up a notification"),
-    mNotifications(notifications)
-{
-    add("requestAdd",
-        "Add a notification with specified [\"name\"], [\"substitutions\"] and [\"payload\"].\n"
-        "If optional [\"reply\"] specified, arrange to send user response on that LLEventPump.",
-        &LLNotificationsListener::requestAdd);
-    add("listChannels",
-        "Post to [\"reply\"] a map of info on existing channels",
-        &LLNotificationsListener::listChannels,
-        LLSD().with("reply", LLSD()));
-    add("listChannelNotifications",
-        "Post to [\"reply\"] an array of info on notifications in channel [\"channel\"]",
-        &LLNotificationsListener::listChannelNotifications,
-        LLSD().with("reply", LLSD()).with("channel", LLSD()));
-    add("respond",
-        "Respond to notification [\"uuid\"] with data in [\"response\"]",
-        &LLNotificationsListener::respond,
-        LLSD().with("uuid", LLSD()));
-    add("cancel",
-        "Cancel notification [\"uuid\"]",
-        &LLNotificationsListener::cancel,
-        LLSD().with("uuid", LLSD()));
-    add("ignore",
-        "Ignore future notification [\"name\"]\n"
-        "(from <notification name= > in notifications.xml)\n"
-        "according to boolean [\"ignore\"].\n"
-        "If [\"name\"] is omitted or undefined, [un]ignore all future notifications.\n"
-        "Note that ignored notifications are not forwarded unless intercepted before\n"
-        "the \"Ignore\" channel.",
-        &LLNotificationsListener::ignore);
-    add("forward",
-        "Forward to [\"pump\"] future notifications on channel [\"channel\"]\n"
-        "according to boolean [\"forward\"]. When enabled, only types matching\n"
-        "[\"types\"] are forwarded, as follows:\n"
-        "omitted or undefined: forward all notifications\n"
-        "string: forward only the specific named [sig]type\n"
-        "array of string: forward any notification matching any named [sig]type.\n"
-        "When boolean [\"respond\"] is true, we auto-respond to each forwarded\n"
-        "notification.",
-        &LLNotificationsListener::forward,
-        LLSD().with("channel", LLSD()));
-}
-
-// This is here in the .cpp file so we don't need the definition of class
-// Forwarder in the header file.
-LLNotificationsListener::~LLNotificationsListener()
-{
-}
-
-void LLNotificationsListener::requestAdd(const LLSD& event_data) const
-{
-	if(event_data.has("reply"))
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"],
-						   boost::bind(&LLNotificationsListener::NotificationResponder, 
-									   this, 
-									   event_data["reply"].asString(), 
-									   _1, _2
-									   )
-						   );
-	}
-	else
-	{
-		mNotifications.add(event_data["name"], 
-						   event_data["substitutions"], 
-						   event_data["payload"]);
-	}
-}
-
-void LLNotificationsListener::NotificationResponder(const std::string& reply_pump, 
-										const LLSD& notification, 
-										const LLSD& response) const
-{
-	LLSD reponse_event;
-	reponse_event["notification"] = notification;
-	reponse_event["response"] = response;
-	LLEventPumps::getInstance()->obtain(reply_pump).post(reponse_event);
-}
-
-void LLNotificationsListener::listChannels(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    for (LLNotifications::ChannelMap::const_iterator cmi(mNotifications.mChannels.begin()),
-                                                     cmend(mNotifications.mChannels.end());
-         cmi != cmend; ++cmi)
-    {
-        LLSD channelInfo;
-        channelInfo["parent"] = cmi->second->getParentChannelName();
-        response[cmi->first] = channelInfo;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::listChannelNotifications(const LLSD& params) const
-{
-    LLReqID reqID(params);
-    LLSD response(reqID.makeResponse());
-    LLNotificationChannelPtr channel(mNotifications.getChannel(params["channel"]));
-    if (channel)
-    {
-        LLSD notifications(LLSD::emptyArray());
-        for (LLNotificationChannel::Iterator ni(channel->begin()), nend(channel->end());
-             ni != nend; ++ni)
-        {
-            notifications.append(asLLSD(*ni));
-        }
-        response["notifications"] = notifications;
-    }
-    LLEventPumps::instance().obtain(params["reply"]).post(response);
-}
-
-void LLNotificationsListener::respond(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        notification->respond(params["response"]);
-    }
-}
-
-void LLNotificationsListener::cancel(const LLSD& params) const
-{
-    LLNotificationPtr notification(mNotifications.find(params["uuid"]));
-    if (notification)
-    {
-        mNotifications.cancel(notification);
-    }
-}
-
-void LLNotificationsListener::ignore(const LLSD& params) const
-{
-    // Calling a method named "ignore", but omitting its "ignore" Boolean
-    // argument, should by default cause something to be ignored. Explicitly
-    // pass ["ignore"] = false to cancel ignore.
-    bool ignore = true;
-    if (params.has("ignore"))
-    {
-        ignore = params["ignore"].asBoolean();
-    }
-    // This method can be used to affect either a single notification name or
-    // all future notifications. The two use substantially different mechanisms.
-    if (params["name"].isDefined())
-    {
-        // ["name"] was passed: ignore just that notification
-		LLNotificationTemplatePtr templatep = mNotifications.getTemplate(params["name"]);
-		if (templatep)
-		{
-			templatep->mForm->setIgnored(ignore);
-		}
-    }
-    else
-    {
-        // no ["name"]: ignore all future notifications
-        mNotifications.setIgnoreAllNotifications(ignore);
-    }
-}
-
-class LLNotificationsListener::Forwarder: public LLEventTrackable
-{
-    LOG_CLASS(LLNotificationsListener::Forwarder);
-public:
-    Forwarder(LLNotifications& llnotifications, const std::string& channel):
-        mNotifications(llnotifications),
-        mRespond(false)
-    {
-        // Connect to the specified channel on construction. Because
-        // LLEventTrackable is a base, we should automatically disconnect when
-        // destroyed.
-        LLNotificationChannelPtr channelptr(llnotifications.getChannel(channel));
-        if (channelptr)
-        {
-            // Insert our processing as a "passed filter" listener. This way
-            // we get to run before all the "changed" listeners, and we get to
-            // swipe it (hide it from the other listeners) if desired.
-            channelptr->connectPassedFilter(boost::bind(&Forwarder::handle, this, _1));
-        }
-    }
-
-    void setPumpName(const std::string& name) { mPumpName = name; }
-    void setTypes(const LLSD& types) { mTypes = types; }
-    void setRespond(bool respond) { mRespond = respond; }
-
-private:
-    bool handle(const LLSD& notification) const;
-    bool matchType(const LLSD& filter, const std::string& type) const;
-
-    LLNotifications& mNotifications;
-    std::string mPumpName;
-    LLSD mTypes;
-    bool mRespond;
-};
-
-void LLNotificationsListener::forward(const LLSD& params)
-{
-    std::string channel(params["channel"]);
-    // First decide whether we're supposed to start forwarding or stop it.
-    // Default to true.
-    bool forward = true;
-    if (params.has("forward"))
-    {
-        forward = params["forward"].asBoolean();
-    }
-    if (! forward)
-    {
-        // This is a request to stop forwarding notifications on the specified
-        // channel. The rest of the params don't matter.
-        // Because mForwarders contains scoped_ptrs, erasing the map entry
-        // DOES delete the heap Forwarder object. Because Forwarder derives
-        // from LLEventTrackable, destroying it disconnects it from the
-        // channel.
-        mForwarders.erase(channel);
-        return;
-    }
-    // From here on, we know we're being asked to start (or modify) forwarding
-    // on the specified channel. Find or create an appropriate Forwarder.
-    ForwarderMap::iterator
-        entry(mForwarders.insert(ForwarderMap::value_type(channel, ForwarderMap::mapped_type())).first);
-    if (! entry->second)
-    {
-        entry->second.reset(new Forwarder(mNotifications, channel));
-    }
-    // Now, whether this Forwarder is brand-new or not, update it with the new
-    // request info.
-    Forwarder& fwd(*entry->second);
-    fwd.setPumpName(params["pump"]);
-    fwd.setTypes(params["types"]);
-    fwd.setRespond(params["respond"]);
-}
-
-bool LLNotificationsListener::Forwarder::handle(const LLSD& notification) const
-{
-    LL_INFOS("LLNotificationsListener") << "handle(" << notification << ")" << LL_ENDL;
-    if (notification["sigtype"].asString() == "delete")
-    {
-        LL_INFOS("LLNotificationsListener") << "ignoring delete" << LL_ENDL;
-        // let other listeners see the "delete" operation
-        return false;
-    }
-    LLNotificationPtr note(mNotifications.find(notification["id"]));
-    if (! note)
-    {
-        LL_INFOS("LLNotificationsListener") << notification["id"] << " not found" << LL_ENDL;
-        return false;
-    }
-    if (! matchType(mTypes, note->getType()))
-    {
-        LL_INFOS("LLNotificationsListener") << "didn't match types " << mTypes << LL_ENDL;
-        // We're not supposed to intercept this particular notification. Let
-        // other listeners process it.
-        return false;
-    }
-    LL_INFOS("LLNotificationsListener") << "sending via '" << mPumpName << "'" << LL_ENDL;
-    // This is a notification we care about. Forward it through specified
-    // LLEventPump.
-    LLEventPumps::instance().obtain(mPumpName).post(asLLSD(note));
-    // Are we also being asked to auto-respond?
-    if (mRespond)
-    {
-        LL_INFOS("LLNotificationsListener") << "should respond" << LL_ENDL;
-        note->respond(LLSD::emptyMap());
-        // Did that succeed in removing the notification? Only cancel() if
-        // it's still around -- otherwise we get an LL_ERRS crash!
-        note = mNotifications.find(notification["id"]);
-        if (note)
-        {
-            LL_INFOS("LLNotificationsListener") << "respond() didn't clear, canceling" << LL_ENDL;
-            mNotifications.cancel(note);
-        }
-    }
-    // If we've auto-responded to this notification, then it's going to be
-    // deleted. Other listeners would get the change operation, try to look it
-    // up and be baffled by lookup failure. So when we auto-respond, suppress
-    // this notification: don't pass it to other listeners.
-    return mRespond;
-}
-
-bool LLNotificationsListener::Forwarder::matchType(const LLSD& filter, const std::string& type) const
-{
-    // Decide whether this notification matches filter:
-    // undefined: forward all notifications
-    if (filter.isUndefined())
-    {
-        return true;
-    }
-    // array of string: forward any notification matching any named type
-    if (filter.isArray())
-    {
-        for (LLSD::array_const_iterator ti(filter.beginArray()), tend(filter.endArray());
-             ti != tend; ++ti)
-        {
-            if (ti->asString() == type)
-            {
-                return true;
-            }
-        }
-        // Didn't match any entry in the array
-        return false;
-    }
-    // string: forward only the specific named type
-    return (filter.asString() == type);
-}
-
-LLSD LLNotificationsListener::asLLSD(LLNotificationPtr note)
-{
-    LLSD notificationInfo(note->asLLSD());
-    // For some reason the following aren't included in LLNotification::asLLSD().
-    notificationInfo["summary"] = note->summarize();
-    notificationInfo["id"]      = note->id();
-    notificationInfo["type"]    = note->getType();
-    notificationInfo["message"] = note->getMessage();
-    notificationInfo["label"]   = note->getLabel();
-    return notificationInfo;
-}
diff --git a/indra/llui/llnotificationslistener.h b/indra/llui/llnotificationslistener.h
deleted file mode 100644
index f9f7641de6c5fb1f8d4d7073a435d73d7348fc5b..0000000000000000000000000000000000000000
--- a/indra/llui/llnotificationslistener.h
+++ /dev/null
@@ -1,69 +0,0 @@
-/**
- * @file   llnotificationslistener.h
- * @author Brad Kittenbrink
- * @date   2009-07-08
- * @brief  Wrap subset of LLNotifications API in event API for test scripts.
- * 
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNOTIFICATIONSLISTENER_H
-#define LL_LLNOTIFICATIONSLISTENER_H
-
-#include "lleventapi.h"
-#include "llnotificationptr.h"
-#include <boost/shared_ptr.hpp>
-#include <map>
-#include <string>
-
-class LLNotifications;
-class LLSD;
-
-class LLNotificationsListener : public LLEventAPI
-{
-public:
-    LLNotificationsListener(LLNotifications & notifications);
-    ~LLNotificationsListener();
-
-private:
-    void requestAdd(LLSD const & event_data) const;
-
-	void NotificationResponder(const std::string& replypump, 
-							   const LLSD& notification, 
-							   const LLSD& response) const;
-
-    void listChannels(const LLSD& params) const;
-    void listChannelNotifications(const LLSD& params) const;
-    void respond(const LLSD& params) const;
-    void cancel(const LLSD& params) const;
-    void ignore(const LLSD& params) const;
-    void forward(const LLSD& params);
-
-    static LLSD asLLSD(LLNotificationPtr);
-
-    class Forwarder;
-    typedef std::map<std::string, boost::shared_ptr<Forwarder> > ForwarderMap;
-    ForwarderMap mForwarders;
-	LLNotifications & mNotifications;
-};
-
-#endif // LL_LLNOTIFICATIONSLISTENER_H
diff --git a/indra/llui/llnotificationtemplate.h b/indra/llui/llnotificationtemplate.h
index b3b0bae86271527fa91b309533b51bfb2582f4dd..18a82190b53b16471e9dd32e1cbd7ab69c5b9c4c 100644
--- a/indra/llui/llnotificationtemplate.h
+++ b/indra/llui/llnotificationtemplate.h
@@ -49,7 +49,6 @@
 //#include "llfunctorregistry.h"
 //#include "llpointer.h"
 #include "llinitparam.h"
-//#include "llnotificationslistener.h"
 //#include "llnotificationptr.h"
 //#include "llcachename.h"
 #include "llnotifications.h"
@@ -61,6 +60,18 @@ typedef boost::shared_ptr<LLNotificationForm> LLNotificationFormPtr;
 // from the appropriate local language directory).
 struct LLNotificationTemplate
 {
+	struct CombineBehaviorNames
+		:	public LLInitParam::TypeValuesHelper<LLNotification::ECombineBehavior, CombineBehaviorNames>
+	{
+		static void declareValues()
+		{
+			declare("replace_with_new", LLNotification::REPLACE_WITH_NEW);
+			declare("keep_old", LLNotification::KEEP_OLD);
+			declare("cancel_old", LLNotification::CANCEL_OLD);
+		}
+	};
+
+
 	struct GlobalString : public LLInitParam::Block<GlobalString>
 	{
 		Mandatory<std::string>	name,
@@ -94,9 +105,11 @@ struct LLNotificationTemplate
 		Optional<LLInitParam::Flag>	dummy_val;
 	public:
 		Multiple<UniquenessContext>	contexts;
+		Optional<LLNotification::ECombineBehavior, CombineBehaviorNames> combine;
 
 		UniquenessConstraint()
 		:	contexts("context"),
+			combine("combine", LLNotification::REPLACE_WITH_NEW),
 			dummy_val("")
 		{}
 	};
@@ -183,7 +196,10 @@ struct LLNotificationTemplate
 	struct Params : public LLInitParam::Block<Params>
 	{
 		Mandatory<std::string>			name;
-		Optional<bool>					persist;
+		Optional<bool>					persist,
+										log_to_im,
+										show_toast,
+										log_to_chat;
 		Optional<std::string>			functor,
 										icon,
 										label,
@@ -204,6 +220,9 @@ struct LLNotificationTemplate
 		Params()
 		:	name("name"),
 			persist("persist", false),
+			log_to_im("log_to_im", false),
+			show_toast("show_toast", true),
+			log_to_chat("log_to_chat", true),
 			functor("functor"),
 			icon("icon"),
 			label("label"),
@@ -262,6 +281,7 @@ struct LLNotificationTemplate
     // (used for things like progress indications, or repeating warnings
     // like "the grid is going down in N minutes")
     bool mUnique;
+	LLNotification::ECombineBehavior mCombineBehavior;
     // if we want to be unique only if a certain part of the payload or substitutions args
 	// are constant specify the field names for the payload. The notification will only be
     // combined if all of the fields named in the context are identical in the
@@ -302,12 +322,15 @@ struct LLNotificationTemplate
     LLNotificationFormPtr mForm;
 	// default priority for notifications of this type
 	ENotificationPriority mPriority;
-	// UUID of the audio file to be played when this notification arrives
-	// this is loaded as a name, but looked up to get the UUID upon template load.
-	// If null, it wasn't specified.
-	LLUUID mSoundEffect;
+	// Stores the sound name which can then be used to play the sound using make_ui_sound
+	std::string mSoundName;
 	// List of tags that rules can match against.
 	std::list<std::string> mTags;
+
+	// inject these notifications into chat/IM streams
+	bool mLogToChat;
+	bool mLogToIM;
+	bool mShowToast;
 };
 
 #endif //LL_LLNOTIFICATION_TEMPLATE_H
diff --git a/indra/llui/llresizebar.cpp b/indra/llui/llresizebar.cpp
index ba90fa5e0c57287d11f60a77ce0d59c057dd4b65..15e56cbfe5ac2542ee80759093d29aac892959e9 100644
--- a/indra/llui/llresizebar.cpp
+++ b/indra/llui/llresizebar.cpp
@@ -45,7 +45,8 @@ LLResizeBar::LLResizeBar(const LLResizeBar::Params& p)
 	mSide( p.side ),
 	mSnappingEnabled(p.snapping_enabled),
 	mAllowDoubleClickSnapping(p.allow_double_click_snapping),
-	mResizingView(p.resizing_view)
+	mResizingView(p.resizing_view),
+	mResizeListener(NULL)
 {
 	setFollowsNone();
 	// set up some generically good follow code.
@@ -300,6 +301,11 @@ BOOL LLResizeBar::handleHover(S32 x, S32 y, MASK mask)
 		}
 	}
 
+	if (mResizeListener)
+	{
+		mResizeListener(NULL);
+	}
+
 	return handled;
 } // end LLResizeBar::handleHover
 
diff --git a/indra/llui/llresizebar.h b/indra/llui/llresizebar.h
index 6daf191918558f1076a3dea4fb43ef23094db756..8190a95a71b14212fa8435554eb016c45d566f52 100644
--- a/indra/llui/llresizebar.h
+++ b/indra/llui/llresizebar.h
@@ -71,6 +71,7 @@ class LLResizeBar : public LLView
 	void			setEnableSnapping(BOOL enable) { mSnappingEnabled = enable; }
 	void			setAllowDoubleClickSnapping(BOOL allow) { mAllowDoubleClickSnapping = allow; }
 	bool			canResize() { return getEnabled() && mMaxSize > mMinSize; }
+	void            setResizeListener(boost::function<void(void*)> listener) {mResizeListener = listener;}
 
 private:
 	S32				mDragLastScreenX;
@@ -84,6 +85,7 @@ class LLResizeBar : public LLView
 	BOOL			mSnappingEnabled;
 	BOOL			mAllowDoubleClickSnapping;
 	LLView*			mResizingView;
+	boost::function<void(void*)>  mResizeListener;
 };
 
 #endif  // LL_RESIZEBAR_H
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 5d3bf7a670084727bbfa6951d84be13615ad16da..13887cbe735793e81261c57f2aef2ae4169eb15a 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -642,3 +642,8 @@ void LLScrollbar::onLineDownBtnPressed( const LLSD& data )
 {
 	changeLine( mStepSize, TRUE );
 }
+
+void LLScrollbar::setThickness(S32 thickness)
+{
+	mThickness = thickness < 0 ? LLUI::sSettingGroups["config"]->getS32("UIScrollbarSize") : thickness;
+}
diff --git a/indra/llui/llscrollbar.h b/indra/llui/llscrollbar.h
index ff74f753b9fa85d623bff8a8429a7113e45fd353..21fd2d631ed340921063e7c312e9bcad6cba122d 100644
--- a/indra/llui/llscrollbar.h
+++ b/indra/llui/llscrollbar.h
@@ -124,6 +124,9 @@ class LLScrollbar
 
 	void				onLineUpBtnPressed(const LLSD& data);
 	void				onLineDownBtnPressed(const LLSD& data);
+		
+	S32					getThickness() const { return mThickness; }
+	void				setThickness(S32 thickness);
 
 private:
 	void				updateThumbRect();
diff --git a/indra/llui/llscrollcontainer.cpp b/indra/llui/llscrollcontainer.cpp
index 2fd187a526803d1c62a01243c597620e0b2ee1e3..cbcce0ece545fa7e7617fa5ad6f3f4a1127da877 100644
--- a/indra/llui/llscrollcontainer.cpp
+++ b/indra/llui/llscrollcontainer.cpp
@@ -73,7 +73,8 @@ LLScrollContainer::Params::Params()
 	hide_scrollbar("hide_scrollbar"),
 	min_auto_scroll_rate("min_auto_scroll_rate", 100),
 	max_auto_scroll_rate("max_auto_scroll_rate", 1000),
-	reserve_scroll_corner("reserve_scroll_corner", false)
+	reserve_scroll_corner("reserve_scroll_corner", false),
+	size("size", -1)
 {}
 
 
@@ -88,9 +89,12 @@ LLScrollContainer::LLScrollContainer(const LLScrollContainer::Params& p)
 	mReserveScrollCorner(p.reserve_scroll_corner),
 	mMinAutoScrollRate(p.min_auto_scroll_rate),
 	mMaxAutoScrollRate(p.max_auto_scroll_rate),
-	mScrolledView(NULL)
+	mScrolledView(NULL),
+	mSize(p.size)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	LLRect border_rect( 0, getRect().getHeight(), getRect().getWidth(), 0 );
 	LLViewBorder::Params params;
 	params.name("scroll border");
@@ -276,7 +280,6 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
 												  EAcceptance* accept,
 												  std::string& tooltip_msg)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
 	// Scroll folder view if needed.  Never accepts a drag or drop.
 	*accept = ACCEPT_NO;
 	BOOL handled = autoScroll(x, y);
@@ -292,7 +295,8 @@ BOOL LLScrollContainer::handleDragAndDrop(S32 x, S32 y, MASK mask,
 
 bool LLScrollContainer::autoScroll(S32 x, S32 y)
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
 
 	bool scrolling = false;
 	if( mScrollbar[HORIZONTAL]->getVisible() || mScrollbar[VERTICAL]->getVisible() )
@@ -365,7 +369,9 @@ bool LLScrollContainer::autoScroll(S32 x, S32 y)
 void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height, BOOL* show_h_scrollbar, BOOL* show_v_scrollbar ) const
 {
 	const LLRect& doc_rect = getScrolledViewRect();
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	S32 doc_width = doc_rect.getWidth();
 	S32 doc_height = doc_rect.getHeight();
 
@@ -406,7 +412,9 @@ void LLScrollContainer::calcVisibleSize( S32 *visible_width, S32 *visible_height
 
 void LLScrollContainer::draw()
 {
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	if (mAutoScrolling)
 	{
 		// add acceleration to autoscroll
@@ -515,7 +523,9 @@ void LLScrollContainer::updateScroll()
 	{
 		return;
 	}
-	static LLUICachedControl<S32> scrollbar_size ("UIScrollbarSize", 0);
+	static LLUICachedControl<S32> scrollbar_size_control ("UIScrollbarSize", 0);
+	S32 scrollbar_size = (mSize == -1 ? scrollbar_size_control : mSize);
+
 	LLRect doc_rect = mScrolledView->getRect();
 	S32 doc_width = doc_rect.getWidth();
 	S32 doc_height = doc_rect.getHeight();
@@ -716,3 +726,9 @@ S32 LLScrollContainer::getBorderWidth() const
 	return 0;
 }
 
+void LLScrollContainer::setSize(S32 size)
+{
+	mSize = size;
+	mScrollbar[VERTICAL]->setThickness(size);
+	mScrollbar[HORIZONTAL]->setThickness(size);
+}
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index d87c95b3d759f2348b6657c833c13c398f9cbbb4..4eb43539b8d097413681be3d5b0832050b7d00b6 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -68,6 +68,7 @@ class LLScrollContainer : public LLUICtrl
 							max_auto_scroll_rate;
 		Optional<LLUIColor>	bg_color;
 		Optional<LLScrollbar::callback_t> scroll_callback;
+		Optional<S32>		size;
 		
 		Params();
 	};
@@ -116,6 +117,9 @@ class LLScrollContainer : public LLUICtrl
 	
 	bool autoScroll(S32 x, S32 y);
 
+	S32 getSize() const { return mSize; }
+	void setSize(S32 thickness);
+
 protected:
 	LLView*		mScrolledView;
 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index d332aa933ec39fda710a7feff999761d70090146..7f04c92b27c07ad7da55d8dc2915671d68fefb64 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -1801,6 +1801,9 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 			// (N.B. callbacks don't take const refs as id is local scope)
 			bool is_group = (mContextMenuType == MENU_GROUP);
 			LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+			registrar.add("Url.ShowProfile", boost::bind(&LLScrollListCtrl::showProfile, id, is_group));
+			registrar.add("Url.SendIM", boost::bind(&LLScrollListCtrl::sendIM, id));
+			registrar.add("Url.AddFriend", boost::bind(&LLScrollListCtrl::addFriend, id));
 			registrar.add("Url.Execute", boost::bind(&LLScrollListCtrl::showNameDetails, id, is_group));
 			registrar.add("Url.CopyLabel", boost::bind(&LLScrollListCtrl::copyNameToClipboard, id, is_group));
 			registrar.add("Url.CopyUrl", boost::bind(&LLScrollListCtrl::copySLURLToClipboard, id, is_group));
@@ -1821,11 +1824,33 @@ BOOL LLScrollListCtrl::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return FALSE;
 }
 
-void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+void LLScrollListCtrl::showProfile(std::string id, bool is_group)
 {
 	// show the resident's profile or the group profile
 	std::string sltype = is_group ? "group" : "agent";
 	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
+	LLUrlAction::showProfile(slurl);
+}
+
+void LLScrollListCtrl::sendIM(std::string id)
+{
+	// send im to the resident
+	std::string slurl = "secondlife:///app/agent/" + id + "/about";
+	LLUrlAction::sendIM(slurl);
+}
+
+void LLScrollListCtrl::addFriend(std::string id)
+{
+	// add resident to friends list
+	std::string slurl = "secondlife:///app/agent/" + id + "/about";
+	LLUrlAction::addFriend(slurl);
+}
+
+void LLScrollListCtrl::showNameDetails(std::string id, bool is_group)
+{
+	// open the resident's details or the group details
+	std::string sltype = is_group ? "group" : "agent";
+	std::string slurl = "secondlife:///app/" + sltype + "/" + id + "/about";
 	LLUrlAction::clickAction(slurl);
 }
 
@@ -1841,7 +1866,7 @@ void LLScrollListCtrl::copyNameToClipboard(std::string id, bool is_group)
 	{
 		LLAvatarName av_name;
 		LLAvatarNameCache::get(LLUUID(id), &av_name);
-		name = av_name.getLegacyName();
+		name = av_name.getAccountName();
 	}
 	LLUrlAction::copyURLToClipboard(name);
 }
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 38450b6313baa4a330e516f1b554e9dc65607ef6..8fa06cc49945016319424c4ddb494fb40a59413f 100644
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -430,6 +430,9 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 	BOOL			setSort(S32 column, BOOL ascending);
 	S32				getLinesPerPage();
 
+	static void		showProfile(std::string id, bool is_group);
+	static void		sendIM(std::string id);
+	static void		addFriend(std::string id);
 	static void		showNameDetails(std::string id, bool is_group);
 	static void		copyNameToClipboard(std::string id, bool is_group);
 	static void		copySLURLToClipboard(std::string id, bool is_group);
diff --git a/indra/llui/llspellcheck.cpp b/indra/llui/llspellcheck.cpp
index a189375fbea58d3c2f9a4469c09c8bf0c7bccbf9..250372da5ba461823ffb2b0902f9e3edd6a1163e 100644
--- a/indra/llui/llspellcheck.cpp
+++ b/indra/llui/llspellcheck.cpp
@@ -145,10 +145,14 @@ void LLSpellChecker::refreshDictionaryMap()
 
 	// Load dictionary information (file name, friendly name, ...)
 	llifstream user_file(user_path + DICT_FILE_MAIN, std::ios::binary);
-	if ( (!user_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) || (0 == sDictMap.size()) )
+	if ( (!user_file.is_open()) 
+		|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, user_file)) 
+		|| (0 == sDictMap.size()) )
 	{
 		llifstream app_file(app_path + DICT_FILE_MAIN, std::ios::binary);
-		if ( (!app_file.is_open()) || (0 == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) || (0 == sDictMap.size()) )
+		if ( (!app_file.is_open()) 
+			|| (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXMLDocument(sDictMap, app_file)) 
+			|| (0 == sDictMap.size()) )
 		{
 			return;
 		}
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index 934879cdfd1dbd573b2ede3a8275c13be48b4001..8a728df2e7226d4b3e604f1cf3108abd3ebee9fe 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -52,6 +52,7 @@ LLSpinCtrl::Params::Params()
 :	label_width("label_width"),
 	decimal_digits("decimal_digits"),
 	allow_text_entry("allow_text_entry", true),
+	allow_digits_only("allow_digits_only", false),
 	label_wrap("label_wrap", false),
 	text_enabled_color("text_enabled_color"),
 	text_disabled_color("text_disabled_color"),
@@ -129,6 +130,10 @@ LLSpinCtrl::LLSpinCtrl(const LLSpinCtrl::Params& p)
 	params.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
 	mEditor = LLUICtrlFactory::create<LLLineEditor> (params);
 	mEditor->setFocusReceivedCallback( boost::bind(&LLSpinCtrl::onEditorGainFocus, _1, this ));
+	if (p.allow_digits_only)
+	{
+		mEditor->setPrevalidateInput(LLTextValidate::validateNonNegativeS32NoSpace);
+	}
 	//RN: this seems to be a BAD IDEA, as it makes the editor behavior different when it has focus
 	// than when it doesn't.  Instead, if you always have to double click to select all the text, 
 	// it's easier to understand
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 87814f838e8d2c47a814b0036dd1fb23520a988e..e34add879d5155ad039b2d118a01546f1787798b 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -44,6 +44,7 @@ class LLSpinCtrl
 		Optional<S32> label_width;
 		Optional<U32> decimal_digits;
 		Optional<bool> allow_text_entry;
+		Optional<bool> allow_digits_only;
 		Optional<bool> label_wrap;
 
 		Optional<LLUIColor> text_enabled_color;
diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp
index 5fc2cc350dc7b347bda5a7325c76182e40f86d68..fd981557047697b291af17e4791b04de1d723234 100644
--- a/indra/llui/lltabcontainer.cpp
+++ b/indra/llui/lltabcontainer.cpp
@@ -506,8 +506,8 @@ void LLTabContainer::draw()
 		}
 	}
 
-	mPrevArrowBtn->setFlashing(FALSE);
-	mNextArrowBtn->setFlashing(FALSE);
+	mPrevArrowBtn->setFlashing(false);
+	mNextArrowBtn->setFlashing(false);
 }
 
 
@@ -1209,11 +1209,17 @@ void LLTabContainer::removeTabPanel(LLPanel* child)
 				update_images(mTabList[mTabList.size()-2], mLastTabParams, getTabPosition());
 			}
 
-			removeChild( tuple->mButton );
+			if (!getTabsHidden())
+			{
+				// We need to remove tab buttons only if the tabs are not hidden.
+				removeChild( tuple->mButton );
+			}
  			delete tuple->mButton;
+            tuple->mButton = NULL;
 
  			removeChild( tuple->mTabPanel );
 // 			delete tuple->mTabPanel;
+            tuple->mTabPanel = NULL;
 			
 			mTabList.erase( iter );
 			delete tuple;
@@ -1275,9 +1281,11 @@ void LLTabContainer::deleteAllTabs()
 
 		removeChild( tuple->mButton );
 		delete tuple->mButton;
+        tuple->mButton = NULL;
 
  		removeChild( tuple->mTabPanel );
 // 		delete tuple->mTabPanel;
+        tuple->mTabPanel = NULL;
 	}
 
 	// Actually delete the tuples themselves
@@ -1480,13 +1488,20 @@ BOOL LLTabContainer::setTab(S32 which)
 		{
 			LLTabTuple* tuple = *iter;
 			BOOL is_selected = ( tuple == selected_tuple );
-			tuple->mButton->setUseEllipses(mUseTabEllipses);
-			tuple->mButton->setHAlign(mFontHalign);
-			tuple->mTabPanel->setVisible( is_selected );
-// 			tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
-			tuple->mButton->setToggleState( is_selected );
-			// RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
-			tuple->mButton->setTabStop( is_selected );
+            // Although the selected tab must be complete, we may have hollow LLTabTuple tucked in the list
+            if (tuple && tuple->mButton)
+            {
+                tuple->mButton->setUseEllipses(mUseTabEllipses);
+                tuple->mButton->setHAlign(mFontHalign);
+                tuple->mButton->setToggleState( is_selected );
+                // RN: this limits tab-stops to active button only, which would require arrow keys to switch tabs
+                tuple->mButton->setTabStop( is_selected );
+            }
+            if (tuple && tuple->mTabPanel)
+            {
+                tuple->mTabPanel->setVisible( is_selected );
+                //tuple->mTabPanel->setFocus(is_selected); // not clear that we want to do this here.
+            }
 			
 			if (is_selected)
 			{
@@ -1513,7 +1528,7 @@ BOOL LLTabContainer::setTab(S32 which)
 					else
 					{
 						S32 available_width_with_arrows = getRect().getWidth() - mRightTabBtnOffset - 2 * (LLPANEL_BORDER_WIDTH + tabcntr_arrow_btn_size  + tabcntr_arrow_btn_size + 1);
-						S32 running_tab_width = tuple->mButton->getRect().getWidth();
+						S32 running_tab_width = (tuple && tuple->mButton ? tuple->mButton->getRect().getWidth() : 0);
 						S32 j = i - 1;
 						S32 min_scroll_pos = i;
 						if (running_tab_width < available_width_with_arrows)
@@ -1521,7 +1536,7 @@ BOOL LLTabContainer::setTab(S32 which)
 							while (j >= 0)
 							{
 								LLTabTuple* other_tuple = getTab(j);
-								running_tab_width += other_tuple->mButton->getRect().getWidth();
+								running_tab_width += (other_tuple && other_tuple->mButton ? other_tuple->mButton->getRect().getWidth() : 0);
 								if (running_tab_width > available_width_with_arrows)
 								{
 									break;
@@ -1557,8 +1572,7 @@ BOOL LLTabContainer::selectTabByName(const std::string& name)
 	LLPanel* panel = getPanelByName(name);
 	if (!panel)
 	{
-		llwarns << "LLTabContainer::selectTabByName("
-			<< name << ") failed" << llendl;
+		llwarns << "LLTabContainer::selectTabByName(" << name << ") failed" << llendl;
 		return FALSE;
 	}
 
diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h
index cebace2ceba344847fb59859adfe0e69761d20d4..57862fc626c0374c49a863a238836b0d4963553e 100644
--- a/indra/llui/lltabcontainer.h
+++ b/indra/llui/lltabcontainer.h
@@ -188,10 +188,11 @@ class LLTabContainer : public LLPanel
 	void		selectFirstTab();
 	void		selectLastTab();
 	void		selectNextTab();
-	 void		selectPrevTab();
+	void		selectPrevTab();
 	BOOL 		selectTabPanel( LLPanel* child );
 	BOOL 		selectTab(S32 which);
 	BOOL 		selectTabByName(const std::string& title);
+    void        setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
 
 	BOOL        getTabPanelFlashing(LLPanel* child);
 	void		setTabPanelFlashing(LLPanel* child, BOOL state);
@@ -242,8 +243,6 @@ class LLTabContainer : public LLPanel
 
 	void setTabsHidden(BOOL hidden)		{ mTabsHidden = hidden; }
 	BOOL getTabsHidden() const			{ return mTabsHidden; }
-	
-	void setCurrentPanelIndex(S32 index) { mCurrentTabIdx = index; }
 
 	void scrollPrev() { mScrollPos = llmax(0, mScrollPos-1); } // No wrap
 	void scrollNext() { mScrollPos = llmin(mScrollPos+1, mMaxScrollPos); } // No wrap
diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp
index 3815eec447e73908208ff8680bd03bc9aa983466..e70992129a6fd9a754422365ec9e846e51f8a128 100644
--- a/indra/llui/lltextbase.cpp
+++ b/indra/llui/lltextbase.cpp
@@ -46,6 +46,7 @@
 
 const F32	CURSOR_FLASH_DELAY = 1.0f;  // in seconds
 const S32	CURSOR_THICKNESS = 2;
+const F32	TRIPLE_CLICK_INTERVAL = 0.3f;	// delay between double and triple click.
 
 LLTextBase::line_info::line_info(S32 index_start, S32 index_end, LLRect rect, S32 line_num) 
 :	mDocIndexStart(index_start), 
@@ -145,6 +146,7 @@ LLTextBase::Params::Params()
 :	cursor_color("cursor_color"),
 	text_color("text_color"),
 	text_readonly_color("text_readonly_color"),
+	text_tentative_color("text_tentative_color"),
 	bg_visible("bg_visible", false),
 	border_visible("border_visible", false),
 	bg_readonly_color("bg_readonly_color"),
@@ -179,7 +181,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 :	LLUICtrl(p, LLTextViewModelPtr(new LLTextViewModel)),
 	mURLClickSignal(NULL),
 	mMaxTextByteLength( p.max_text_length ),
-	mDefaultFont(p.font),
+	mFont(p.font),
 	mFontShadow(p.font_shadow),
 	mPopupMenu(NULL),
 	mReadOnly(p.read_only),
@@ -190,6 +192,7 @@ LLTextBase::LLTextBase(const LLTextBase::Params &p)
 	mFgColor(p.text_color),
 	mBorderVisible( p.border_visible ),
 	mReadOnlyFgColor(p.text_readonly_color),
+	mTentativeFgColor(p.text_tentative_color()),
 	mWriteableBgColor(p.bg_writeable_color),
 	mReadOnlyBgColor(p.bg_readonly_color),
 	mFocusBgColor(p.bg_focus_color),
@@ -319,21 +322,26 @@ bool LLTextBase::truncate()
 	return did_truncate;
 }
 
-const LLStyle::Params& LLTextBase::getDefaultStyleParams()
+const LLStyle::Params& LLTextBase::getStyleParams()
 {
 	//FIXME: convert mDefaultStyle to a flyweight http://www.boost.org/doc/libs/1_40_0/libs/flyweight/doc/index.html
 	//and eliminate color member values
 	if (mStyleDirty)
 	{
-		  mDefaultStyle
+		  mStyle
 				  .color(LLUIColor(&mFgColor))						// pass linked color instead of copy of mFGColor
 				  .readonly_color(LLUIColor(&mReadOnlyFgColor))
 				  .selected_color(LLUIColor(&mTextSelectedColor))
-				  .font(mDefaultFont)
+				  .font(mFont)
 				  .drop_shadow(mFontShadow);
 		  mStyleDirty = false;
 	}
-	return mDefaultStyle;
+	return mStyle;
+}
+
+void LLTextBase::beforeValueChange()
+{
+
 }
 
 void LLTextBase::onValueChange(S32 start, S32 end)
@@ -351,7 +359,6 @@ void LLTextBase::drawSelectionBackground()
 
 		S32 selection_left		= llmin( mSelectionStart, mSelectionEnd );
 		S32 selection_right		= llmax( mSelectionStart, mSelectionEnd );
-		LLRect selection_rect = mVisibleTextRect;
 
 		// Skip through the lines we aren't drawing.
 		LLRect content_display_rect = getVisibleDocumentRect();
@@ -436,6 +443,7 @@ void LLTextBase::drawSelectionBackground()
 			++rect_it)
 		{
 			LLRect selection_rect = *rect_it;
+			selection_rect = *rect_it;
 			selection_rect.translate(mVisibleTextRect.mLeft - content_display_rect.mLeft, mVisibleTextRect.mBottom - content_display_rect.mBottom);
 			gl_rect_2d(selection_rect, selection_color);
 		}
@@ -513,8 +521,8 @@ void LLTextBase::drawCursor()
 			LLRect screen_pos = calcScreenRect();
 			LLCoordGL ime_pos( screen_pos.mLeft + llfloor(cursor_rect.mLeft), screen_pos.mBottom + llfloor(cursor_rect.mTop) );
 
-			ime_pos.mX = (S32) (ime_pos.mX * LLUI::sGLScaleFactor.mV[VX]);
-			ime_pos.mY = (S32) (ime_pos.mY * LLUI::sGLScaleFactor.mV[VY]);
+			ime_pos.mX = (S32) (ime_pos.mX * LLUI::getScaleFactor().mV[VX]);
+			ime_pos.mY = (S32) (ime_pos.mY * LLUI::getScaleFactor().mV[VY]);
 			getWindow()->setLanguageTextInput( ime_pos );
 		}
 	}
@@ -522,11 +530,17 @@ void LLTextBase::drawCursor()
 
 void LLTextBase::drawText()
 {
-	const S32 text_len = getLength();
-	if( text_len <= 0 )
+	S32 text_len = getLength();
+
+	if (text_len <= 0 && mLabel.empty())
 	{
 		return;
 	}
+	else if (useLabel())
+	{
+		text_len = mLabel.getWString().length();
+	}
+
 	S32 selection_left = -1;
 	S32 selection_right = -1;
 	// Draw selection even if we don't have keyboard focus for search/replace
@@ -592,7 +606,8 @@ void LLTextBase::drawText()
 
 				// Find the start of the first word
 				U32 word_start = seg_start, word_end = -1;
-				while ( (word_start < wstrText.length()) && (!LLStringOps::isAlpha(wstrText[word_start])) )
+				U32 text_length = wstrText.length();
+				while ( (word_start < text_length) && (!LLStringOps::isAlpha(wstrText[word_start])) )
 				{
 					word_start++;
 				}
@@ -614,11 +629,15 @@ void LLTextBase::drawText()
 						break;
 					}
 
-					// Don't process words shorter than 3 characters
-					std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
-					if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+					if (word_start < text_length && word_end <= text_length && word_end > word_start)
 					{
-						mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+						std::string word = wstring_to_utf8str(wstrText.substr(word_start, word_end - word_start));
+
+						// Don't process words shorter than 3 characters
+						if ( (word.length() >= 3) && (!LLSpellChecker::instance().checkSpelling(word)) )
+						{
+							mMisspellRanges.push_back(std::pair<U32, U32>(word_start, word_end));
+						}
 					}
 
 					// Find the start of the next word
@@ -739,6 +758,8 @@ void LLTextBase::drawText()
 
 S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::segment_vec_t* segments )
 {
+    beforeValueChange();
+
 	S32 old_len = getLength();		// length() returns character length
 	S32 insert_len = wstr.length();
 
@@ -770,7 +791,7 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 	else
 	{
 		// create default editable segment to hold new text
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		default_segment = new LLNormalTextSegment( sp, pos, pos + insert_len, *this);
 	}
 
@@ -814,6 +835,8 @@ S32 LLTextBase::insertStringNoUndo(S32 pos, const LLWString &wstr, LLTextBase::s
 
 S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 {
+
+    beforeValueChange();
 	segment_set_t::iterator seg_iter = getSegIterContaining(pos);
 	while(seg_iter != mSegments.end())
 	{
@@ -872,6 +895,8 @@ S32 LLTextBase::removeStringNoUndo(S32 pos, S32 length)
 
 S32 LLTextBase::overwriteCharNoUndo(S32 pos, llwchar wc)
 {
+    beforeValueChange();
+
 	if (pos > (S32)getLength())
 	{
 		return 0;
@@ -890,7 +915,7 @@ void LLTextBase::createDefaultSegment()
 	// ensures that there is always at least one segment
 	if (mSegments.empty())
 	{
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLTextSegmentPtr default_segment = new LLNormalTextSegment( sp, 0, getLength() + 1, *this);
 		mSegments.insert(default_segment);
 		default_segment->linkToDocument(this);
@@ -980,6 +1005,13 @@ void LLTextBase::insertSegment(LLTextSegmentPtr segment_to_insert)
 
 BOOL LLTextBase::handleMouseDown(S32 x, S32 y, MASK mask)
 {
+	// handle triple click
+	if (!mTripleClickTimer.hasExpired())
+	{
+		selectAll();
+		return TRUE;
+	}
+
 	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
 	if (cur_segment && cur_segment->handleMouseDown(x, y, mask))
 	{
@@ -1054,6 +1086,14 @@ BOOL LLTextBase::handleRightMouseUp(S32 x, S32 y, MASK mask)
 
 BOOL LLTextBase::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
+	//Don't start triple click timer if user have clicked on scrollbar
+	mVisibleTextRect = mScroller ? mScroller->getContentWindowRect() : getLocalRect();
+	if (x >= mVisibleTextRect.mLeft && x <= mVisibleTextRect.mRight
+	    && y >= mVisibleTextRect.mBottom && y <= mVisibleTextRect.mTop)
+	{
+		mTripleClickTimer.setTimerExpirySec(TRIPLE_CLICK_INTERVAL);
+	}
+
 	LLTextSegmentPtr cur_segment = getSegmentAtLocalPos(x, y);
 	if (cur_segment && cur_segment->handleDoubleClick(x, y, mask))
 	{
@@ -1338,6 +1378,25 @@ void LLTextBase::onSpellCheckSettingsChange()
 	mSpellCheckStart = mSpellCheckEnd = -1;
 }
 
+void LLTextBase::onFocusReceived()
+{
+	LLUICtrl::onFocusReceived();
+	if (!getLength() && !mLabel.empty())
+	{
+		// delete label which is LLLabelTextSegment
+		clearSegments();
+	}
+}
+
+void LLTextBase::onFocusLost()
+{
+	LLUICtrl::onFocusLost();
+	if (!getLength() && !mLabel.empty())
+	{
+		resetLabel();
+	}
+}
+
 // Sets the scrollbar from the cursor position
 void LLTextBase::updateScrollFromCursor()
 {
@@ -1859,6 +1918,7 @@ void LLTextBase::createUrlContextMenu(S32 x, S32 y, const std::string &in_url)
 	registrar.add("Url.Execute", boost::bind(&LLUrlAction::executeSLURL, 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.ShowOnMap", boost::bind(&LLUrlAction::showLocationOnMap, url));
 	registrar.add("Url.CopyLabel", boost::bind(&LLUrlAction::copyLabelToClipboard, url));
 	registrar.add("Url.CopyUrl", boost::bind(&LLUrlAction::copyURLToClipboard, url));
@@ -1924,7 +1984,7 @@ static LLFastTimer::DeclareTimer FTM_PARSE_HTML("Parse HTML");
 void LLTextBase::appendTextImpl(const std::string &new_text, const LLStyle::Params& input_params)
 {
 	LLStyle::Params style_params(input_params);
-	style_params.fillFrom(getDefaultStyleParams());
+	style_params.fillFrom(getStyleParams());
 
 	S32 part = (S32)LLTextParser::WHOLE;
 	if (mParseHTML && !style_params.is_link) // Don't search for URLs inside a link segment (STORM-358).
@@ -2009,6 +2069,44 @@ void LLTextBase::appendText(const std::string &new_text, bool prepend_newline, c
 	appendTextImpl(new_text,input_params);
 }
 
+void LLTextBase::setLabel(const LLStringExplicit& label)
+{
+	mLabel = label;
+	resetLabel();
+}
+
+BOOL LLTextBase::setLabelArg(const std::string& key, const LLStringExplicit& text )
+{
+	mLabel.setArg(key, text);
+	return TRUE;
+}
+
+void LLTextBase::resetLabel()
+{
+	if (useLabel())
+	{
+		clearSegments();
+
+		LLStyle* style = new LLStyle(getStyleParams());
+		style->setColor(mTentativeFgColor);
+		LLStyleConstSP sp(style);
+
+		LLTextSegmentPtr label = new LLLabelTextSegment(sp, 0, mLabel.getWString().length() + 1, *this);
+		insertSegment(label);
+	}
+}
+
+bool LLTextBase::useLabel()
+{
+    return !getLength() && !mLabel.empty() && !hasFocus();
+}
+
+void LLTextBase::setFont(const LLFontGL* font)
+{
+	mFont = font;
+	mStyleDirty = true;
+}
+
 void LLTextBase::needsReflow(S32 index)
 {
 	lldebugs << "reflow on object " << (void*)this << " index = " << mReflowIndex << ", new index = " << index << llendl;
@@ -2239,7 +2337,6 @@ const LLWString& LLTextBase::getWText() const
 S32 LLTextBase::getDocIndexFromLocalCoord( S32 local_x, S32 local_y, BOOL round, bool hit_past_end_of_line) const
 {
 	// Figure out which line we're nearest to.
-	LLRect visible_region = getVisibleDocumentRect();
 	LLRect doc_rect = mDocumentView->getRect();
 
 	S32 doc_y = local_y - doc_rect.mBottom;
@@ -2399,7 +2496,7 @@ LLRect LLTextBase::getLocalRectFromDocIndex(S32 pos) const
 	{ 
 		// return default height rect in upper left
 		local_rect = content_window_rect;
-		local_rect.mBottom = local_rect.mTop - mDefaultFont->getLineHeight();
+		local_rect.mBottom = local_rect.mTop - mFont->getLineHeight();
 		return local_rect;
 	}
 
@@ -2904,7 +3001,7 @@ F32 LLNormalTextSegment::drawClippedSegment(S32 seg_start, S32 seg_end, S32 sele
 {
 	F32 alpha = LLViewDrawContext::getCurrentContext().mAlpha;
 
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	F32 right_x = rect.mLeft;
 	if (!mStyle->isVisible())
@@ -3067,7 +3164,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 	if (num_chars > 0)
 	{
 		height = mFontHeight;
-		const LLWString &text = mEditor.getWText();
+		const LLWString &text = getWText();
 		// if last character is a newline, then return true, forcing line break
 		width = mStyle->getFont()->getWidth(text.c_str(), mStart + first_char, num_chars);
 	}
@@ -3076,7 +3173,7 @@ bool LLNormalTextSegment::getDimensions(S32 first_char, S32 num_chars, S32& widt
 
 S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 	return mStyle->getFont()->charFromPixelOffset(text.c_str(), mStart + start_offset,
 											   (F32)segment_local_x_coord,
 											   F32_MAX,
@@ -3086,7 +3183,7 @@ S32	LLNormalTextSegment::getOffset(S32 segment_local_x_coord, S32 start_offset,
 
 S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 line_offset, S32 max_chars) const
 {
-	const LLWString &text = mEditor.getWText();
+	const LLWString &text = getWText();
 
 	LLUIImagePtr image = mStyle->getImage();
 	if( image.notNull())
@@ -3104,7 +3201,23 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	LLFontGL::EWordWrapStyle word_wrap_style = (line_offset == 0) 
 		? LLFontGL::WORD_BOUNDARY_IF_POSSIBLE 
 		: LLFontGL::ONLY_WORD_BOUNDARIES;
-	S32 num_chars = mStyle->getFont()->maxDrawableChars(text.c_str() + segment_offset + mStart, 
+	
+	
+	LLWString offsetString(text.c_str() + segment_offset + mStart);
+
+	if(getLength() < segment_offset + mStart)
+	{
+		llerrs << "getLength() < segment_offset + mStart\t getLength()\t" << getLength() << "\tsegment_offset:\t" 
+						<< segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << "\tmax_chars\t" << max_chars << llendl;
+	}
+
+	if(offsetString.length() + 1 < max_chars)
+	{
+		llerrs << "offsetString.length() + 1 < max_chars\t max_chars:\t" << max_chars << "\toffsetString.length():\t" << offsetString.length()
+			<< getLength() << "\tsegment_offset:\t" << segment_offset << "\tmStart:\t" << mStart << "\tsegments\t" << mEditor.mSegments.size() << llendl;
+	}
+	
+	S32 num_chars = mStyle->getFont()->maxDrawableChars(offsetString.c_str(), 
 												(F32)num_pixels,
 												max_chars, 
 												word_wrap_style);
@@ -3122,7 +3235,7 @@ S32	LLNormalTextSegment::getNumChars(S32 num_pixels, S32 segment_offset, S32 lin
 	S32 last_char_in_run = mStart + segment_offset + num_chars;
 	// check length first to avoid indexing off end of string
 	if (last_char_in_run < mEnd 
-		&& (last_char_in_run >= mEditor.getLength() ))
+		&& (last_char_in_run >= getLength()))
 	{
 		num_chars++;
 	}
@@ -3140,6 +3253,39 @@ void LLNormalTextSegment::dump() const
 		llendl;
 }
 
+/*virtual*/
+const LLWString& LLNormalTextSegment::getWText()	const
+{
+	return mEditor.getWText();
+}
+
+/*virtual*/
+const S32 LLNormalTextSegment::getLength() const
+{
+	return mEditor.getLength();
+}
+
+LLLabelTextSegment::LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor )
+:	LLNormalTextSegment(style, start, end, editor)
+{
+}
+
+LLLabelTextSegment::LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible)
+:	LLNormalTextSegment(color, start, end, editor, is_visible)
+{
+}
+
+/*virtual*/
+const LLWString& LLLabelTextSegment::getWText()	const
+{
+	return mEditor.getWlabel();
+}
+/*virtual*/
+const S32 LLLabelTextSegment::getLength() const
+{
+	return mEditor.getWlabel().length();
+}
+
 //
 // LLOnHoverChangeableTextSegment
 //
@@ -3344,3 +3490,7 @@ F32	LLImageTextSegment::draw(S32 start, S32 end, S32 selection_start, S32 select
 	return 0.0;
 }
 
+void LLTextBase::setWordWrap(bool wrap)
+{
+	mWordWrap = wrap;
+}
diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h
index 90b147cee1dfc35d853a3e221dca9a46ea6d22c8..20a73387b57a3193ae3dc0d5150d2a5f98d6d25b 100644
--- a/indra/llui/lltextbase.h
+++ b/indra/llui/lltextbase.h
@@ -41,6 +41,7 @@
 
 #include <boost/signals2.hpp>
 
+class LLScrollContainer;
 class LLContextMenu;
 class LLUrlMatch;
 
@@ -106,7 +107,7 @@ class LLNormalTextSegment : public LLTextSegment
 public:
 	LLNormalTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
 	LLNormalTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
-	~LLNormalTextSegment();
+	virtual ~LLNormalTextSegment();
 
 	/*virtual*/ bool				getDimensions(S32 first_char, S32 num_chars, S32& width, S32& height) const;
 	/*virtual*/ S32					getOffset(S32 segment_local_x_coord, S32 start_offset, S32 num_chars, bool round) const;
@@ -131,6 +132,9 @@ class LLNormalTextSegment : public LLTextSegment
 protected:
 	F32					drawClippedSegment(S32 seg_start, S32 seg_end, S32 selection_start, S32 selection_end, LLRect rect);
 
+	virtual		const LLWString&	getWText()	const;
+	virtual		const S32			getLength()	const;
+
 protected:
 	class LLTextBase&	mEditor;
 	LLStyleConstSP		mStyle;
@@ -140,6 +144,21 @@ class LLNormalTextSegment : public LLTextSegment
 	boost::signals2::connection mImageLoadedConnection;
 };
 
+// This text segment is the same as LLNormalTextSegment, the only difference
+// is that LLNormalTextSegment draws value of LLTextBase (LLTextBase::getWText()),
+// but LLLabelTextSegment draws label of the LLTextBase (LLTextBase::mLabel)
+class LLLabelTextSegment : public LLNormalTextSegment
+{
+public:
+	LLLabelTextSegment( LLStyleConstSP style, S32 start, S32 end, LLTextBase& editor );
+	LLLabelTextSegment( const LLColor4& color, S32 start, S32 end, LLTextBase& editor, BOOL is_visible = TRUE);
+
+protected:
+
+	/*virtual*/	const LLWString&	getWText()	const;
+	/*virtual*/	const S32			getLength()	const;
+};
+
 // Text segment that changes it's style depending of mouse pointer position ( is it inside or outside segment)
 class LLOnHoverChangeableTextSegment : public LLNormalTextSegment
 {
@@ -251,6 +270,7 @@ class LLTextBase
 		Optional<LLUIColor>		cursor_color,
 								text_color,
 								text_readonly_color,
+								text_tentative_color,
 								bg_readonly_color,
 								bg_writeable_color,
 								bg_focus_color,
@@ -314,6 +334,9 @@ class LLTextBase
 	/*virtual*/ BOOL		canDeselect() const;
 	/*virtual*/ void		deselect();
 
+	virtual void	onFocusReceived();
+	virtual void	onFocusLost();
+
 	// LLSpellCheckMenuHandler overrides
 	/*virtual*/ bool		getSpellCheck() const;
 
@@ -351,6 +374,21 @@ class LLTextBase
 	const LLWString&       	getWText() const;
 
 	void					appendText(const std::string &new_text, bool prepend_newline, const LLStyle::Params& input_params = LLStyle::Params());
+
+	void					setLabel(const LLStringExplicit& label);
+	virtual BOOL			setLabelArg(const std::string& key, const LLStringExplicit& text );
+
+	const	std::string& 	getLabel()	{ return mLabel.getString(); }
+	const	LLWString&		getWlabel() { return mLabel.getWString();}
+
+	/**
+	 * If label is set, draws text label (which is LLLabelTextSegment)
+	 * that is visible when no user text provided
+	 */
+	void					resetLabel();
+
+	void					setFont(const LLFontGL* font);
+
 	// force reflow of text
 	void					needsReflow(S32 index = 0);
 
@@ -390,13 +428,16 @@ class LLTextBase
 	bool					scrolledToStart();
 	bool					scrolledToEnd();
 
-	const LLFontGL*			getDefaultFont() const					{ return mDefaultFont; }
+	const LLFontGL*			getFont() const					{ return mFont; }
 
 	virtual void			appendLineBreakSegment(const LLStyle::Params& style_params);
 	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);
 
+	void					setWordWrap(bool wrap);
+	LLScrollContainer*		getScrollContainer() const { return mScroller; }
+
 protected:
 	// helper structs
 	struct compare_bottom;
@@ -464,7 +505,9 @@ class LLTextBase
 	LLTextBase(const Params &p);
 	virtual ~LLTextBase();
 	void							initFromParams(const Params& p);
+    virtual void					beforeValueChange();
 	virtual void					onValueChange(S32 start, S32 end);
+    virtual bool                    useLabel();
 
 	// draw methods
 	void							drawSelectionBackground(); // draws the black box behind the selected text
@@ -490,7 +533,7 @@ class LLTextBase
 	void							createDefaultSegment();
 	virtual void					updateSegments();
 	void							insertSegment(LLTextSegmentPtr segment_to_insert);
-	const LLStyle::Params&			getDefaultStyleParams();
+	const LLStyle::Params&			getStyleParams();
 
 	//  manage lines
 	S32								getLineStart( S32 line ) const;
@@ -535,15 +578,16 @@ class LLTextBase
 	LLRect						mTextBoundingRect;
 
 	// default text style
-	LLStyle::Params				mDefaultStyle;
+	LLStyle::Params				mStyle;
 	bool						mStyleDirty;
-	const LLFontGL* const		mDefaultFont;		// font that is used when none specified, can only be set by constructor
-	const LLFontGL::ShadowType	mFontShadow;		// shadow style, can only be set by constructor
+	const LLFontGL*				mFont;
+	const LLFontGL::ShadowType	mFontShadow;
 
 	// colors
 	LLUIColor					mCursorColor;
 	LLUIColor					mFgColor;
 	LLUIColor					mReadOnlyFgColor;
+	LLUIColor					mTentativeFgColor;
 	LLUIColor					mWriteableBgColor;
 	LLUIColor					mReadOnlyBgColor;
 	LLUIColor					mFocusBgColor;
@@ -558,7 +602,8 @@ class LLTextBase
 	// selection
 	S32							mSelectionStart;
 	S32							mSelectionEnd;
-	
+	LLTimer		                mTripleClickTimer;
+
 	BOOL						mIsSelecting;		// Are we in the middle of a drag-select? 
 
 	// spell checking
@@ -587,12 +632,13 @@ class LLTextBase
 	bool						mClip;				// clip text to widget rect
 	bool						mClipPartial;		// false if we show lines that are partially inside bounding rect
 	bool						mPlainText;			// didn't use Image or Icon segments
+	bool						mAutoIndent;
 	S32							mMaxTextByteLength;	// Maximum length mText is allowed to be in bytes
 
 	// support widgets
 	LLContextMenu*				mPopupMenu;
 	LLView*						mDocumentView;
-	class LLScrollContainer*	mScroller;
+	LLScrollContainer*			mScroller;
 
 	// transient state
 	S32							mReflowIndex;		// index at which to start reflow.  S32_MAX indicates no reflow needed.
@@ -602,6 +648,7 @@ class LLTextBase
 	// Fired when a URL link is clicked
 	commit_signal_t*			mURLClickSignal;
 
+	LLUIString					mLabel;	// text label that is visible when no user text provided
 };
 
 #endif
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 46fbd1e6a0f72c442a6d358e1ef92ff6d261e4ba..834f21309707f71d92f85d9cd2978d62b394fb17 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -237,6 +237,7 @@ LLTextEditor::Params::Params()
 	embedded_items("embedded_items", false),
 	ignore_tab("ignore_tab", true),
 	show_line_numbers("show_line_numbers", false),
+	auto_indent("auto_indent", true),
 	default_color("default_color"),
     commit_on_focus_lost("commit_on_focus_lost", false),
 	show_context_menu("show_context_menu"),
@@ -247,11 +248,13 @@ LLTextEditor::Params::Params()
 
 LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	LLTextBase(p),
+	mAutoreplaceCallback(),
 	mBaseDocIsPristine(TRUE),
 	mPristineCmd( NULL ),
 	mLastCmd( NULL ),
 	mDefaultColor(		p.default_color() ),
 	mShowLineNumbers ( p.show_line_numbers ),
+	mAutoIndent(p.auto_indent),
 	mCommitOnFocusLost( p.commit_on_focus_lost),
 	mAllowEmbeddedItems( p.embedded_items ),
 	mMouseDownX(0),
@@ -260,7 +263,8 @@ LLTextEditor::LLTextEditor(const LLTextEditor::Params& p) :
 	mPrevalidateFunc(p.prevalidate_callback()),
 	mContextMenu(NULL),
 	mShowContextMenu(p.show_context_menu),
-	mEnableTooltipPaste(p.enable_tooltip_paste)
+	mEnableTooltipPaste(p.enable_tooltip_paste),
+	mPassDelete(FALSE)
 {
 	mSourceID.generate();
 
@@ -952,12 +956,18 @@ S32 LLTextEditor::insert(S32 pos, const LLWString &wstr, bool group_with_next_op
 S32 LLTextEditor::remove(S32 pos, S32 length, bool group_with_next_op)
 {
 	S32 end_pos = getEditableIndex(pos + length, true);
+	BOOL removedChar = FALSE;
 
 	segment_vec_t segments_to_remove;
 	// store text segments
 	getSegmentsInRange(segments_to_remove, pos, pos + length, false);
+	
+	if(pos <= end_pos)
+	{
+		removedChar = execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+	}
 
-	return execute( new TextCmdRemove( pos, group_with_next_op, end_pos - pos, segments_to_remove ) );
+	return removedChar;
 }
 
 S32 LLTextEditor::overwriteChar(S32 pos, llwchar wc)
@@ -1096,7 +1106,25 @@ void LLTextEditor::addChar(llwchar wc)
 	}
 
 	setCursorPos(mCursorPos + addChar( mCursorPos, wc ));
+
+	if (!mReadOnly && mAutoreplaceCallback != NULL)
+	{
+		// autoreplace the text, if necessary
+		S32 replacement_start;
+		S32 replacement_length;
+		LLWString replacement_string;
+		S32 new_cursor_pos = mCursorPos;
+		mAutoreplaceCallback(replacement_start, replacement_length, replacement_string, new_cursor_pos, getWText());
+
+		if (replacement_length > 0 || !replacement_string.empty())
+		{
+			remove(replacement_start, replacement_length, true);
+			insert(replacement_start, replacement_string, false, LLTextSegmentPtr());
+			setCursorPos(new_cursor_pos);
+		}
+	}
 }
+
 void LLTextEditor::addLineBreakChar()
 {
 	if( !getEnabled() )
@@ -1621,7 +1649,10 @@ BOOL LLTextEditor::handleSpecialKey(const KEY key, const MASK mask)
 			{
 				deleteSelection(FALSE);
 			}
-			autoIndent(); // TODO: make this optional
+			if (mAutoIndent)
+			{
+				autoIndent();
+			}
 		}
 		else
 		{
@@ -1792,7 +1823,7 @@ BOOL LLTextEditor::handleUnicodeCharHere(llwchar uni_char)
 // virtual
 BOOL LLTextEditor::canDoDelete() const
 {
-	return !mReadOnly && ( hasSelection() || (mCursorPos < getLength()) );
+	return !mReadOnly && ( !mPassDelete || ( hasSelection() || (mCursorPos < getLength())) );
 }
 
 void LLTextEditor::doDelete()
@@ -2061,7 +2092,7 @@ void LLTextEditor::drawPreeditMarker()
 		return;
 	}
 		
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	S32 line_start = getLineStart(cur_line);
 	S32 line_y = mVisibleTextRect.mTop - line_height;
@@ -2100,16 +2131,16 @@ void LLTextEditor::drawPreeditMarker()
 				S32 preedit_left = mVisibleTextRect.mLeft;
 				if (left > line_start)
 				{
-					preedit_left += mDefaultFont->getWidth(text, line_start, left - line_start);
+					preedit_left += mFont->getWidth(text, line_start, left - line_start);
 				}
 				S32 preedit_right = mVisibleTextRect.mLeft;
 				if (right < line_end)
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, right - line_start);
+					preedit_right += mFont->getWidth(text, line_start, right - line_start);
 				}
 				else
 				{
-					preedit_right += mDefaultFont->getWidth(text, line_start, line_end - line_start);
+					preedit_right += mFont->getWidth(text, line_start, line_end - line_start);
 				}
 
 				if (mPreeditStandouts[i])
@@ -2490,7 +2521,6 @@ void LLTextEditor::updateSegments()
 		mKeywords.findSegments(&segment_list, getWText(), mDefaultColor.get(), *this);
 
 		clearSegments();
-		segment_set_t::iterator insert_it = mSegments.begin();
 		for (segment_vec_t::iterator list_it = segment_list.begin(); list_it != segment_list.end(); ++list_it)
 		{
 			insertSegment(*list_it);
@@ -2784,11 +2814,11 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 
     const LLWString textString(getWText());
 	const llwchar * const text = textString.c_str();
-	const S32 line_height = mDefaultFont->getLineHeight();
+	const S32 line_height = mFont->getLineHeight();
 
 	if (coord)
 	{
-		const S32 query_x = mVisibleTextRect.mLeft + mDefaultFont->getWidth(text, current_line_start, query - current_line_start);
+		const S32 query_x = mVisibleTextRect.mLeft + mFont->getWidth(text, current_line_start, query - current_line_start);
 		const S32 query_y = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height - line_height / 2;
 		S32 query_screen_x, query_screen_y;
 		localPointToScreen(query_x, query_y, &query_screen_x, &query_screen_y);
@@ -2800,17 +2830,17 @@ BOOL LLTextEditor::getPreeditLocation(S32 query_offset, LLCoordGL *coord, LLRect
 		S32 preedit_left = mVisibleTextRect.mLeft;
 		if (preedit_left_position > current_line_start)
 		{
-			preedit_left += mDefaultFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
+			preedit_left += mFont->getWidth(text, current_line_start, preedit_left_position - current_line_start);
 		}
 
 		S32 preedit_right = mVisibleTextRect.mLeft;
 		if (preedit_right_position < current_line_end)
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, preedit_right_position - current_line_start);
 		}
 		else
 		{
-			preedit_right += mDefaultFont->getWidth(text, current_line_start, current_line_end - current_line_start);
+			preedit_right += mFont->getWidth(text, current_line_start, current_line_end - current_line_start);
 		}
 
 		const S32 preedit_top = mVisibleTextRect.mTop - (current_line - first_visible_line) * line_height;
@@ -2887,7 +2917,7 @@ void LLTextEditor::markAsPreedit(S32 position, S32 length)
 
 S32 LLTextEditor::getPreeditFontSize() const
 {
-	return llround((F32)mDefaultFont->getLineHeight() * LLUI::sGLScaleFactor.mV[VY]);
+	return llround((F32)mFont->getLineHeight() * LLUI::getScaleFactor().mV[VY]);
 }
 
 BOOL LLTextEditor::isDirty() const
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index e60fe03e58f86d0bb6ed4d8d0fa0174357501b86..969e0727047f7ff4659d9783bd91914e3229b42b 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -65,7 +65,8 @@ class LLTextEditor :
 								show_line_numbers,
 								commit_on_focus_lost,
 								show_context_menu,
-								enable_tooltip_paste;
+								enable_tooltip_paste,
+								auto_indent;
 
 		//colors
 		Optional<LLUIColor>		default_color;
@@ -157,6 +158,11 @@ class LLTextEditor :
 	BOOL			isPristine() const;
 	BOOL			allowsEmbeddedItems() const { return mAllowEmbeddedItems; }
 
+	// Autoreplace (formerly part of LLLineEditor)
+	typedef boost::function<void(S32&, S32&, LLWString&, S32&, const LLWString&)> autoreplace_callback_t;
+	autoreplace_callback_t mAutoreplaceCallback;
+	void			setAutoreplaceCallback(autoreplace_callback_t cb) { mAutoreplaceCallback = cb; }
+
 	//
 	// Text manipulation
 	//
@@ -203,6 +209,8 @@ class LLTextEditor :
 	void			setShowContextMenu(bool show) { mShowContextMenu = show; }
 	bool			getShowContextMenu() const { return mShowContextMenu; }
 
+	void			setPassDelete(BOOL b) { mPassDelete = b; }
+
 protected:
 	void			showContextMenu(S32 x, S32 y);
 	void			drawPreeditMarker();
@@ -215,8 +223,8 @@ class LLTextEditor :
 	S32				indentLine( S32 pos, S32 spaces );
 	void			unindentLineBeforeCloseBrace();
 
+	virtual	BOOL	handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleNavigationKey(const KEY key, const MASK mask);
-	BOOL			handleSpecialKey(const KEY key, const MASK mask);
 	BOOL			handleSelectionKey(const KEY key, const MASK mask);
 	BOOL			handleControlKey(const KEY key, const MASK mask);
 
@@ -280,6 +288,7 @@ class LLTextEditor :
 	LLUIColor			mDefaultColor;
 
 	BOOL				mShowLineNumbers;
+	bool				mAutoIndent;
 
 	/*virtual*/ void	updateSegments();
 	void				updateLinkSegments();
@@ -325,6 +334,7 @@ class LLTextEditor :
 	bool			mShowContextMenu;
 	bool			mParseOnTheFly;
 	bool			mEnableTooltipPaste;
+	bool			mPassDelete;
 
 	LLUUID			mSourceID;
 
diff --git a/indra/llui/lltoggleablemenu.h b/indra/llui/lltoggleablemenu.h
index 4717b0d0ba3b4ee7c7550daff015ff0c574eb23c..dfe70cbf546e870f3e791140e87ead17cae13a04 100644
--- a/indra/llui/lltoggleablemenu.h
+++ b/indra/llui/lltoggleablemenu.h
@@ -60,6 +60,8 @@ class LLToggleableMenu : public LLMenuGL
 	// its visibility off.
 	bool toggleVisibility();
 	
+	LLHandle<LLToggleableMenu> getHandle() { return getDerivedHandle<LLToggleableMenu>(); }
+
 protected:
 	bool mClosedByButtonClick;
 	LLRect mButtonRect;
diff --git a/indra/llui/lltoolbar.cpp b/indra/llui/lltoolbar.cpp
index 63b7e452d2ad1c4340d465ac1b8648951ec17d44..3d9f5cbbc232822be501c93860ec10342c2a0a15 100644
--- a/indra/llui/lltoolbar.cpp
+++ b/indra/llui/lltoolbar.cpp
@@ -653,7 +653,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	S32 max_row_length = 0;
 
 	S32 max_length;
-	S32 max_total_girth;
 	S32 cur_start;
 	S32 cur_row ;
 	S32 row_pad_start;
@@ -664,7 +663,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	if (orientation == LLLayoutStack::HORIZONTAL)
 	{
 		max_length = getRect().getWidth() - mPadLeft - mPadRight;
-		max_total_girth = getRect().getHeight() - mPadTop - mPadBottom;
 		row_pad_start = mPadLeft;
 		row_pad_end = mPadRight;
 		cur_row = mPadTop;
@@ -673,7 +671,6 @@ void LLToolBar::updateLayoutAsNeeded()
 	else // VERTICAL
 	{
 		max_length = getRect().getHeight() - mPadTop - mPadBottom;
-		max_total_girth = getRect().getWidth() - mPadLeft - mPadRight;
 		row_pad_start = mPadTop;
 		row_pad_end = mPadBottom;
 		cur_row = mPadLeft;
@@ -841,7 +838,6 @@ void LLToolBar::draw()
 	if (mDragAndDropTarget && !mButtonCommands.empty())
 	{
 		LLRect caret_rect = caret->getRect();
-		LLRect toolbar_rect = getRect();
 		if (getOrientation(mSideType) == LLLayoutStack::HORIZONTAL)
 		{
 			caret->setRect(LLRect(mDragx-caret_rect.getWidth()/2+1,
@@ -872,8 +868,15 @@ void LLToolBar::reshape(S32 width, S32 height, BOOL called_from_parent)
 
 void LLToolBar::createButtons()
 {
+	std::set<LLUUID> set_flashing;
+
 	BOOST_FOREACH(LLToolBarButton* button, mButtons)
 	{
+        if (button->getFlashTimer() && button->getFlashTimer()->isFlashingInProgress())
+        {
+        	set_flashing.insert(button->getCommandId().uuid());
+        }
+
 		if (mButtonRemoveSignal)
 		{
 			(*mButtonRemoveSignal)(button);
@@ -896,6 +899,11 @@ void LLToolBar::createButtons()
 		{
 			(*mButtonAddSignal)(button);
 		}
+
+		if (set_flashing.find(button->getCommandId().uuid()) != set_flashing.end())
+		{
+			button->setFlashing(true);
+		}
 	}
 	mNeedsLayout = true;
 }
@@ -920,6 +928,7 @@ LLToolBarButton* LLToolBar::createButton(const LLCommandId& id)
 	button_p.label = LLTrans::getString(commandp->labelRef());
 	button_p.tool_tip = LLTrans::getString(commandp->tooltipRef());
 	button_p.image_overlay = LLUI::getUIImage(commandp->icon());
+	button_p.button_flash_enable = commandp->isFlashingAllowed();
 	button_p.overwriteFrom(mButtonParams[mButtonType]);
 	LLToolBarButton* button = LLUICtrlFactory::create<LLToolBarButton>(button_p);
 
@@ -1046,10 +1055,9 @@ BOOL LLToolBar::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// Convert drag position into insert position and rank 
 	if (!isReadOnly() && handled && !drop)
 	{
-		LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
-		LLAssetType::EType type = inv_item->getType();
-		if (type == LLAssetType::AT_WIDGET)
+		if (cargo_type == DAD_WIDGET)
 		{
+			LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
 			LLCommandId dragged_command(inv_item->getUUID());
 			int orig_rank = getRankFromPosition(dragged_command);
 			mDragRank = getRankFromPosition(x, y);
diff --git a/indra/llui/lltooltip.cpp b/indra/llui/lltooltip.cpp
index 7f1566d64a427b936633f6584f9ff247f8621fec..f52a3b332305c313686831d6fedb40413c20c13c 100644
--- a/indra/llui/lltooltip.cpp
+++ b/indra/llui/lltooltip.cpp
@@ -288,7 +288,7 @@ void LLToolTip::initFromParams(const LLToolTip::Params& p)
 		mTextBox->setText(p.message());
 	}
 
-	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth());
+	S32 text_width = llmin(p.max_width(), mTextBox->getTextPixelWidth() + 1);
 	S32 text_height = mTextBox->getTextPixelHeight();
 	mTextBox->reshape(text_width, text_height);
 	if (mInfoButton)
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index 6d2bc1837cee68b895c284830e45bbbcbf600b28..0ddb14973831628f9fc1922909aaafc6e7dd11a6 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -39,6 +39,7 @@
 #include "llrect.h"
 #include "lldir.h"
 #include "llgl.h"
+#include "llsd.h"
 
 // Project includes
 #include "llcommandmanager.h"
@@ -69,15 +70,13 @@
 //
 // Globals
 //
-const LLColor4 UI_VERTEX_COLOR(1.f, 1.f, 1.f, 1.f);
 
 // Language for UI construction
 std::map<std::string, std::string> gTranslation;
 std::list<std::string> gUntranslated;
 /*static*/ LLUI::settings_map_t LLUI::sSettingGroups;
-/*static*/ LLImageProviderInterface* LLUI::sImageProvider = NULL;
 /*static*/ LLUIAudioCallback LLUI::sAudioCallback = NULL;
-/*static*/ LLVector2		LLUI::sGLScaleFactor(1.f, 1.f);
+/*static*/ LLUIAudioCallback LLUI::sDeferredAudioCallback = NULL;
 /*static*/ LLWindow*		LLUI::sWindow = NULL;
 /*static*/ LLView*			LLUI::sRootView = NULL;
 /*static*/ BOOL                         LLUI::sDirty = FALSE;
@@ -101,16 +100,18 @@ static LLDefaultChildRegistry::Register<LLToolBar> register_toolbar("toolbar");
 //
 // Functions
 //
-void make_ui_sound(const char* namep)
+
+LLUUID find_ui_sound(const char * namep)
 {
 	std::string name = ll_safe_string(namep);
+	LLUUID uuid = LLUUID(NULL);
 	if (!LLUI::sSettingGroups["config"]->controlExists(name))
 	{
 		llwarns << "tried to make UI sound for unknown sound name: " << name << llendl;	
 	}
 	else
 	{
-		LLUUID uuid(LLUI::sSettingGroups["config"]->getString(name));
+		uuid = LLUUID(LLUI::sSettingGroups["config"]->getString(name));
 		if (uuid.isNull())
 		{
 			if (LLUI::sSettingGroups["config"]->getString(name) == LLUUID::null.asString())
@@ -124,7 +125,6 @@ void make_ui_sound(const char* namep)
 			{
 				llwarns << "UI sound named: " << name << " does not translate to a valid uuid" << llendl;	
 			}
-
 		}
 		else if (LLUI::sAudioCallback != NULL)
 		{
@@ -132,1497 +132,38 @@ void make_ui_sound(const char* namep)
 			{
 				llinfos << "UI sound name: " << name << llendl;	
 			}
-			LLUI::sAudioCallback(uuid);
-		}
-	}
-}
-
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom)
-{
-	if (x < left || right < x) return FALSE;
-	if (y < bottom || top < y) return FALSE;
-	return TRUE;
-}
-
-
-// Puts GL into 2D drawing mode by turning off lighting, setting to an
-// orthographic projection, etc.
-void gl_state_for_2d(S32 width, S32 height)
-{
-	stop_glerror();
-	F32 window_width = (F32) width;//gViewerWindow->getWindowWidth();
-	F32 window_height = (F32) height;//gViewerWindow->getWindowHeight();
-
-	gGL.matrixMode(LLRender::MM_PROJECTION);
-	gGL.loadIdentity();
-	gGL.ortho(0.0f, llmax(window_width, 1.f), 0.0f, llmax(window_height,1.f), -1.0f, 1.0f);
-	gGL.matrixMode(LLRender::MM_MODELVIEW);
-	gGL.loadIdentity();
-	stop_glerror();
-}
-
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin( LLRender::LINES );
-		gGL.vertex2i( rect.mLeft,		rect.mTop );
-		gGL.vertex2i( rect.mRight,	rect.mBottom );
-		gGL.vertex2i( rect.mLeft,		rect.mBottom );
-		gGL.vertex2i( rect.mRight,	rect.mTop );
-	gGL.end();
-}
-
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset, BOOL filled)
-{
-	gGL.color4fv(color.mV);
-	gl_rect_2d_offset_local(left, top, right, bottom, pixel_offset, filled);
-}
-
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	left += LLFontGL::sCurOrigin.mX;
-	right += LLFontGL::sCurOrigin.mX;
-	bottom += LLFontGL::sCurOrigin.mY;
-	top += LLFontGL::sCurOrigin.mY;
-
-	gGL.loadUIIdentity();
-	gl_rect_2d(llfloor((F32)left * LLUI::sGLScaleFactor.mV[VX]) - pixel_offset,
-				llfloor((F32)top * LLUI::sGLScaleFactor.mV[VY]) + pixel_offset,
-				llfloor((F32)right * LLUI::sGLScaleFactor.mV[VX]) + pixel_offset,
-				llfloor((F32)bottom * LLUI::sGLScaleFactor.mV[VY]) - pixel_offset,
-				filled);
-	gGL.popUIMatrix();
-}
-
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled )
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	// Counterclockwise quad will face the viewer
-	if( filled )
-	{ 
-		gGL.begin( LLRender::QUADS );
-			gGL.vertex2i(left, top);
-			gGL.vertex2i(left, bottom);
-			gGL.vertex2i(right, bottom);
-			gGL.vertex2i(right, top);
-		gGL.end();
-	}
-	else
-	{
-		if( gGLManager.mATIOffsetVerticalLines )
-		{
-			// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-			gGL.begin( LLRender::LINES );
-
-				// Verticals 
-				gGL.vertex2i(left + 1, top);
-				gGL.vertex2i(left + 1, bottom);
-
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-
-				// Horizontals
-				top--;
-				right--;
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(right, top);
-			gGL.end();
-		}
-		else
-		{
-			top--;
-			right--;
-			gGL.begin( LLRender::LINE_STRIP );
-				gGL.vertex2i(left, top);
-				gGL.vertex2i(left, bottom);
-				gGL.vertex2i(right, bottom);
-				gGL.vertex2i(right, top);
-				gGL.vertex2i(left, top);
-			gGL.end();
-		}
-	}
-	stop_glerror();
-}
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( left, top, right, bottom, filled );
-}
-
-
-void gl_rect_2d( const LLRect& rect, const LLColor4& color, BOOL filled )
-{
-	gGL.color4fv( color.mV );
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-// Given a rectangle on the screen, draws a drop shadow _outside_
-// the right and bottom edges of it.  Along the right it has width "lines"
-// and along the bottom it has height "lines".
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines)
-{
-	stop_glerror();
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	// HACK: Overlap with the rectangle by a single pixel.
-	right--;
-	bottom++;
-	lines++;
-
-	LLColor4 end_color = start_color;
-	end_color.mV[VALPHA] = 0.f;
-
-	gGL.begin(LLRender::QUADS);
-
-	// Right edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		top-lines);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right+lines, bottom);
-	gGL.vertex2i(right+lines, top-lines);
-
-	// Bottom edge, CCW faces screen
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left+lines,	bottom-lines);
-	gGL.vertex2i(right,		bottom-lines);
-
-	// bottom left Corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(left+lines,	bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(left,		bottom);
-	// make the bottom left corner not sharp
-	gGL.vertex2i(left+1,		bottom-lines+1);
-	gGL.vertex2i(left+lines,	bottom-lines);
-
-	// bottom right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i(right,		bottom);
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i(right,		bottom-lines);
-	// make the rightmost corner not sharp
-	gGL.vertex2i(right+lines-1,	bottom-lines+1);
-	gGL.vertex2i(right+lines,	bottom);
-
-	// top right corner
-	gGL.color4fv(start_color.mV);
-	gGL.vertex2i( right,			top-lines );
-	gGL.color4fv(end_color.mV);
-	gGL.vertex2i( right+lines,	top-lines );
-	// make the corner not sharp
-	gGL.vertex2i( right+lines-1,	top-1 );
-	gGL.vertex2i( right,			top );
-
-	gGL.end();
-	stop_glerror();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2 )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color )
-{
-	// Work around bug in ATI driver: vertical lines are offset by (-1,-1)
-	if( (x1 == x2) && gGLManager.mATIOffsetVerticalLines )
-	{
-		x1++;
-		x2++;
-		y1++;
-		y2++;
-	}
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv( color.mV );
-
-	gGL.begin(LLRender::LINES);
-		gGL.vertex2i(x1, y1);
-		gGL.vertex2i(x2, y2);
-	gGL.end();
-}
-
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.color4fv(color.mV);
-
-	if (filled)
-	{
-		gGL.begin(LLRender::TRIANGLES);
-	}
-	else
-	{
-		gGL.begin(LLRender::LINE_LOOP);
-	}
-	gGL.vertex2i(x1, y1);
-	gGL.vertex2i(x2, y2);
-	gGL.vertex2i(x3, y3);
-	gGL.end();
-}
-
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac)
-{
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	length = llmin((S32)(max_frac*(right - left)), length);
-	length = llmin((S32)(max_frac*(top - bottom)), length);
-	gGL.begin(LLRender::LINES);
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left + length, top);
-	
-	gGL.vertex2i(left, top);
-	gGL.vertex2i(left, top - length);
-
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left + length, bottom);
-	
-	gGL.vertex2i(left, bottom);
-	gGL.vertex2i(left, bottom + length);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right - length, top);
-
-	gGL.vertex2i(right, top);
-	gGL.vertex2i(right, top - length);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right - length, bottom);
-
-	gGL.vertex2i(right, bottom);
-	gGL.vertex2i(right, bottom + length);
-	gGL.end();
-}
-
-
-void gl_draw_image( S32 x, S32 y, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect )
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-	gl_draw_scaled_rotated_image( x, y, width, height, 0.f, image, color, uv_rect );
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// scale screen size of borders down
-	F32 border_width_fraction = (F32)border_width / (F32)image->getWidth(0);
-	F32 border_height_fraction = (F32)border_height / (F32)image->getHeight(0);
-
-	LLRectf scale_rect(border_width_fraction, 1.f - border_height_fraction, 1.f - border_width_fraction, border_height_fraction);
-	gl_draw_scaled_image_with_border(x, y, width, height, image, color, solid_color, uv_rect, scale_rect);
-}
-
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color, BOOL solid_color, const LLRectf& uv_outer_rect, const LLRectf& center_rect)
-{
-	stop_glerror();
-
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	// add in offset of current image to current UI translation
-	const LLVector3 ui_scale = gGL.getUIScale();
-	const LLVector3 ui_translation = (gGL.getUITranslation() + LLVector3(x, y, 0.f)).scaledVec(ui_scale);
-
-	F32 uv_width = uv_outer_rect.getWidth();
-	F32 uv_height = uv_outer_rect.getHeight();
-
-	// shrink scaling region to be proportional to clipped image region
-	LLRectf uv_center_rect(
-		uv_outer_rect.mLeft + (center_rect.mLeft * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mTop * uv_height),
-		uv_outer_rect.mLeft + (center_rect.mRight * uv_width),
-		uv_outer_rect.mBottom + (center_rect.mBottom * uv_height));
-
-	F32 image_width = image->getWidth(0);
-	F32 image_height = image->getHeight(0);
-
-	S32 image_natural_width = llround(image_width * uv_width);
-	S32 image_natural_height = llround(image_height * uv_height);
-
-	LLRectf draw_center_rect(	uv_center_rect.mLeft * image_width,
-								uv_center_rect.mTop * image_height,
-								uv_center_rect.mRight * image_width,
-								uv_center_rect.mBottom * image_height);
-
-	{	// scale fixed region of image to drawn region
-		draw_center_rect.mRight += width - image_natural_width;
-		draw_center_rect.mTop += height - image_natural_height;
-
-		F32 border_shrink_width = llmax(0.f, draw_center_rect.mLeft - draw_center_rect.mRight);
-		F32 border_shrink_height = llmax(0.f, draw_center_rect.mBottom - draw_center_rect.mTop);
-
-		F32 shrink_width_ratio = center_rect.getWidth() == 1.f ? 0.f : border_shrink_width / ((F32)image_natural_width * (1.f - center_rect.getWidth()));
-		F32 shrink_height_ratio = center_rect.getHeight() == 1.f ? 0.f : border_shrink_height / ((F32)image_natural_height * (1.f - center_rect.getHeight()));
-
-		F32 shrink_scale = 1.f - llmax(shrink_width_ratio, shrink_height_ratio);
-
-		draw_center_rect.mLeft = llround(ui_translation.mV[VX] + (F32)draw_center_rect.mLeft * shrink_scale * ui_scale.mV[VX]);
-		draw_center_rect.mTop = llround(ui_translation.mV[VY] + lerp((F32)height, (F32)draw_center_rect.mTop, shrink_scale) * ui_scale.mV[VY]);
-		draw_center_rect.mRight = llround(ui_translation.mV[VX] + lerp((F32)width, (F32)draw_center_rect.mRight, shrink_scale) * ui_scale.mV[VX]);
-		draw_center_rect.mBottom = llround(ui_translation.mV[VY] + (F32)draw_center_rect.mBottom * shrink_scale * ui_scale.mV[VY]);
-	}
-
-	LLRectf draw_outer_rect(ui_translation.mV[VX], 
-							ui_translation.mV[VY] + height * ui_scale.mV[VY], 
-							ui_translation.mV[VX] + width * ui_scale.mV[VX], 
-							ui_translation.mV[VY]);
-
-	LLGLSUIDefault gls_ui;
-	
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gSolidColorProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureColorBlend(LLTexUnit::TBO_REPLACE, LLTexUnit::TBS_PREV_COLOR);
-			gGL.getTexUnit(0)->setTextureAlphaBlend(LLTexUnit::TBO_MULT, LLTexUnit::TBS_TEX_ALPHA, LLTexUnit::TBS_VERT_ALPHA);
-		}
-	}
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-	
-	const S32 NUM_VERTICES = 9 * 4; // 9 quads
-	LLVector2 uv[NUM_VERTICES];
-	LLVector3 pos[NUM_VERTICES];
-
-	S32 index = 0;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw bottom right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		// draw left 
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw right 
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mBottom);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mBottom, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		// draw top left
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top middle
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mLeft, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mLeft, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		// draw top right
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_center_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_center_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_outer_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_outer_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		uv[index] = LLVector2(uv_center_rect.mRight, uv_outer_rect.mTop);
-		pos[index] = LLVector3(draw_center_rect.mRight, draw_outer_rect.mTop, 0.f);
-		index++;
-
-		gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-	}
-	gGL.end();
-
-	if (solid_color)
-	{
-		if (LLGLSLShader::sNoFixedFunction)
-		{
-			gUIProgram.bind();
-		}
-		else
-		{
-			gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT);
-		}
-	}
-}
-
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	gl_draw_scaled_rotated_image( x, y, image->getWidth(0), image->getHeight(0), degrees, image, color, uv_rect );
-}
-
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees, LLTexture* image, const LLColor4& color, const LLRectf& uv_rect)
-{
-	if (NULL == image)
-	{
-		llwarns << "image == NULL; aborting function" << llendl;
-		return;
-	}
-
-	LLGLSUIDefault gls_ui;
-
-
-	gGL.getTexUnit(0)->bind(image, true);
-
-	gGL.color4fv(color.mV);
-
-	if (degrees == 0.f)
-	{
-		const S32 NUM_VERTICES = 4; // 9 quads
-		LLVector2 uv[NUM_VERTICES];
-		LLVector3 pos[NUM_VERTICES];
-
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 ui_scale = gGL.getUIScale();
-			LLVector3 ui_translation = gGL.getUITranslation();
-			ui_translation.mV[VX] += x;
-			ui_translation.mV[VY] += y;
-			ui_translation.scaleVec(ui_scale);
-			S32 index = 0;
-			S32 scaled_width = llround(width * ui_scale.mV[VX]);
-			S32 scaled_height = llround(height * ui_scale.mV[VY]);
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mTop);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY] + scaled_height, 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mLeft, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX], ui_translation.mV[VY], 0.f);
-			index++;
-
-			uv[index] = LLVector2(uv_rect.mRight, uv_rect.mBottom);
-			pos[index] = LLVector3(ui_translation.mV[VX] + scaled_width, ui_translation.mV[VY], 0.f);
-			index++;
-
-			gGL.vertexBatchPreTransformed(pos, uv, NUM_VERTICES);
-		}
-		gGL.end();
-	}
-	else
-	{
-		gGL.pushUIMatrix();
-		gGL.translateUI((F32)x, (F32)y, 0.f);
-	
-		F32 offset_x = F32(width/2);
-		F32 offset_y = F32(height/2);
-
-		gGL.translateUI(offset_x, offset_y, 0.f);
-
-		LLMatrix3 quat(0.f, 0.f, degrees*DEG_TO_RAD);
-		
-		gGL.getTexUnit(0)->bind(image, true);
-
-		gGL.color4fv(color.mV);
-		
-		gGL.begin(LLRender::QUADS);
-		{
-			LLVector3 v;
-
-			v = LLVector3(offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mTop);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(-offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mLeft, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-
-			v = LLVector3(offset_x, -offset_y, 0.f) * quat;
-			gGL.texCoord2f(uv_rect.mRight, uv_rect.mBottom);
-			gGL.vertex2f(v.mV[0], v.mV[1] );
-		}
-		gGL.end();
-		gGL.popUIMatrix();
-	}
-}
-
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase )
-{
-	phase = fmod(phase, 1.f);
-
-	S32 shift = S32(phase * 4.f) % 4;
-
-	// Stippled line
-	LLGLEnable stipple(GL_LINE_STIPPLE);
-	
-	gGL.color4f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE], color.mV[VALPHA]);
-
-	gGL.flush();
-	glLineWidth(2.5f);
-
-	if (!LLGLSLShader::sNoFixedFunction)
-	{
-		glLineStipple(2, 0x3333 << shift);
-	}
-
-	gGL.begin(LLRender::LINES);
-	{
-		gGL.vertex3fv( start.mV );
-		gGL.vertex3fv( end.mV );
-	}
-	gGL.end();
-
-	LLUI::setLineWidth(1.f);
-}
-
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle)
-{
-	if (end_angle < start_angle)
-	{
-		end_angle += F_TWO_PI;
-	}
-
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = (end_angle - start_angle) / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = cosf(start_angle) * radius;
-		F32 y = sinf(start_angle) * radius;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_STRIP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-void gl_circle_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled)
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gGL.translateUI(center_x, center_y, 0.f);
-
-		// Inexact, but reasonably fast.
-		F32 delta = F_TWO_PI / steps;
-		F32 sin_delta = sin( delta );
-		F32 cos_delta = cos( delta );
-		F32 x = radius;
-		F32 y = 0.f;
-
-		if (filled)
-		{
-			gGL.begin(LLRender::TRIANGLE_FAN);
-			gGL.vertex2f(0.f, 0.f);
-			// make sure circle is complete
-			steps += 1;
-		}
-		else
-		{
-			gGL.begin(LLRender::LINE_LOOP);
-		}
-
-		while( steps-- )
-		{
-			// Successive rotations
-			gGL.vertex2f( x, y );
-			F32 x_new = x * cos_delta - y * sin_delta;
-			y = x * sin_delta +  y * cos_delta;
-			x = x_new;
-		}
-		gGL.end();
-	}
-	gGL.popUIMatrix();
-}
-
-// Renders a ring with sides (tube shape)
-void gl_deep_circle( F32 radius, F32 depth, S32 steps )
-{
-	F32 x = radius;
-	F32 y = 0.f;
-	F32 angle_delta = F_TWO_PI / (F32)steps;
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
-	{
-		S32 step = steps + 1; // An extra step to close the circle.
-		while( step-- )
-		{
-			gGL.vertex3f( x, y, depth );
-			gGL.vertex3f( x, y, 0.f );
-
-			F32 x_new = x * cosf(angle_delta) - y * sinf(angle_delta);
-			y = x * sinf(angle_delta) +  y * cosf(angle_delta);
-			x = x_new;
-		}
-	}
-	gGL.end();
-}
-
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center )
-{
-	gGL.pushUIMatrix();
-	{
-		gGL.translateUI(0.f, 0.f, -width / 2);
-		if( render_center )
-		{
-			gGL.color4fv(center_color.mV);
-			gGL.diffuseColor4fv(center_color.mV);
-			gl_deep_circle( radius, width, steps );
-		}
-		else
-		{
-			gGL.diffuseColor4fv(side_color.mV);
-			gl_washer_2d(radius, radius - width, steps, side_color, side_color);
-			gGL.translateUI(0.f, 0.f, width);
-			gl_washer_2d(radius - width, radius, steps, side_color, side_color);
-		}
-	}
-	gGL.popUIMatrix();
-}
-
-// Draw gray and white checkerboard with black border
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha)
-{
-	if (!LLGLSLShader::sNoFixedFunction)
-	{ 
-		// Initialize the first time this is called.
-		const S32 PIXELS = 32;
-		static GLubyte checkerboard[PIXELS * PIXELS];
-		static BOOL first = TRUE;
-		if( first )
-		{
-			for( S32 i = 0; i < PIXELS; i++ )
-			{
-				for( S32 j = 0; j < PIXELS; j++ )
-				{
-					checkerboard[i * PIXELS + j] = ((i & 1) ^ (j & 1)) * 0xFF;
-				}
-			}
-			first = FALSE;
 		}
-	
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-		// ...white squares
-		gGL.color4f( 1.f, 1.f, 1.f, alpha );
-		gl_rect_2d(rect);
-
-		// ...gray squares
-		gGL.color4f( .7f, .7f, .7f, alpha );
-		gGL.flush();
-
-		glPolygonStipple( checkerboard );
-
-		LLGLEnable polygon_stipple(GL_POLYGON_STIPPLE);
-		gl_rect_2d(rect);
 	}
-	else
-	{ //polygon stipple is deprecated, use "Checker" texture
-		LLPointer<LLUIImage> img = LLUI::getUIImage("Checker");
-		gGL.getTexUnit(0)->bind(img->getImage());
-		gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_WRAP);
-		gGL.getTexUnit(0)->setTextureFilteringOption(LLTexUnit::TFO_POINT);
-
-		LLColor4 color(1.f, 1.f, 1.f, alpha);
-		LLRectf uv_rect(0, 0, rect.getWidth()/32.f, rect.getHeight()/32.f);
 
-		gl_draw_scaled_image(rect.mLeft, rect.mBottom, rect.getWidth(), rect.getHeight(),
-			img->getImage(), color, uv_rect);
-	}
-	
-	gGL.flush();
+	return uuid;
 }
 
-
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+void make_ui_sound(const char* namep)
 {
-	const F32 DELTA = F_TWO_PI / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius;
-	F32 y1 = 0.f;
-	F32 x2 = inner_radius;
-	F32 y2 = 0.f;
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	LLUUID soundUUID = find_ui_sound(namep);
+	if(soundUUID.notNull())
 	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
+		LLUI::sAudioCallback(soundUUID);
 	}
-	gGL.end();
 }
 
-// Draws the area between two concentric circles, like
-// a doughnut or washer.
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color)
+void make_ui_sound_deferred(const char* namep)
 {
-	const F32 DELTA = (end_radians - start_radians) / steps;
-	const F32 SIN_DELTA = sin( DELTA );
-	const F32 COS_DELTA = cos( DELTA );
-
-	F32 x1 = outer_radius * cos( start_radians );
-	F32 y1 = outer_radius * sin( start_radians );
-	F32 x2 = inner_radius * cos( start_radians );
-	F32 y2 = inner_radius * sin( start_radians );
-
-	gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-	gGL.begin( LLRender::TRIANGLE_STRIP  );
+	LLUUID soundUUID = find_ui_sound(namep);
+	if(soundUUID.notNull())
 	{
-		steps += 1; // An extra step to close the circle.
-		while( steps-- )
-		{
-			gGL.color4fv(outer_color.mV);
-			gGL.vertex2f( x1, y1 );
-			gGL.color4fv(inner_color.mV);
-			gGL.vertex2f( x2, y2 );
-
-			F32 x1_new = x1 * COS_DELTA - y1 * SIN_DELTA;
-			y1 = x1 * SIN_DELTA +  y1 * COS_DELTA;
-			x1 = x1_new;
-
-			F32 x2_new = x2 * COS_DELTA - y2 * SIN_DELTA;
-			y2 = x2 * SIN_DELTA +  y2 * COS_DELTA;
-			x2 = x2_new;
-		}
+		LLUI::sDeferredAudioCallback(soundUUID);
 	}
-	gGL.end();
-}
-
-void gl_rect_2d_simple_tex( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2i(width, height);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2i(0, height);
-
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2i(0, 0);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2i(width, 0);
-	
-	gGL.end();
-}
-
-void gl_rect_2d_simple( S32 width, S32 height )
-{
-	gGL.begin( LLRender::QUADS );
-		gGL.vertex2i(width, height);
-		gGL.vertex2i(0, height);
-		gGL.vertex2i(0, 0);
-		gGL.vertex2i(width, 0);
-	gGL.end();
-}
-
-void gl_segmented_rect_2d_tex(const S32 left, 
-							  const S32 top, 
-							  const S32 right, 
-							  const S32 bottom, 
-							  const S32 texture_width, 
-							  const S32 texture_height, 
-							  const S32 border_size, 
-							  const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex2f(0.f, 0.f);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv(border_width_left.mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-		gGL.vertex2fv((width_vec - border_width_right).mV);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex2fv(width_vec.mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		// draw left 
-		gGL.texCoord2f(0.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv(border_height_bottom.mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		// draw middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		// draw right 
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + border_height_bottom).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex2fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((border_width_left + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-
-		gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((border_width_left + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_uv_scale.mV[VY]);
-		gGL.vertex2fv((width_vec + height_vec - border_height_top).mV);
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex2fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-		gGL.vertex2fv((width_vec - border_width_right + height_vec).mV);
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-//FIXME: rewrite to use scissor?
-void gl_segmented_rect_2d_fragment_tex(const S32 left, 
-									   const S32 top, 
-									   const S32 right, 
-									   const S32 bottom, 
-									   const S32 texture_width, 
-									   const S32 texture_height, 
-									   const S32 border_size, 
-									   const F32 start_fragment, 
-									   const F32 end_fragment, 
-									   const U32 edges)
-{
-	S32 width = llabs(right - left);
-	S32 height = llabs(top - bottom);
-
-	gGL.pushUIMatrix();
-
-	gGL.translateUI((F32)left, (F32)bottom, 0.f);
-	LLVector2 border_uv_scale((F32)border_size / (F32)texture_width, (F32)border_size / (F32)texture_height);
-
-	if (border_uv_scale.mV[VX] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VX];
-	}
-	if (border_uv_scale.mV[VY] > 0.5f)
-	{
-		border_uv_scale *= 0.5f / border_uv_scale.mV[VY];
-	}
-
-	F32 border_scale = llmin((F32)border_size, (F32)width * 0.5f, (F32)height * 0.5f);
-	LLVector2 border_width_left = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_width_right = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? LLVector2(border_scale, 0.f) : LLVector2::zero;
-	LLVector2 border_height_bottom = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 border_height_top = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? LLVector2(0.f, border_scale) : LLVector2::zero;
-	LLVector2 width_vec((F32)width, 0.f);
-	LLVector2 height_vec(0.f, (F32)height);
-
-	F32 middle_start = border_scale / (F32)width;
-	F32 middle_end = 1.f - middle_start;
-
-	F32 u_min;
-	F32 u_max;
-	LLVector2 x_min;
-	LLVector2 x_max;
-
-	gGL.begin(LLRender::QUADS);
-	{
-		if (start_fragment < middle_start)
-		{
-			u_min = (start_fragment / middle_start) * border_uv_scale.mV[VX];
-			u_max = llmin(end_fragment / middle_start, 1.f) * border_uv_scale.mV[VX];
-			x_min = (start_fragment / middle_start) * border_width_left;
-			x_max = llmin(end_fragment / middle_start, 1.f) * border_width_left;
-
-			// draw bottom left
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw left 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-			
-			// draw top left
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_start || start_fragment < middle_end)
-		{
-			x_min = border_width_left + ((llclamp(start_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-			x_max = border_width_left + ((llclamp(end_fragment, middle_start, middle_end) - middle_start)) * width_vec;
-
-			// draw bottom middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv(x_min.mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 0.f);
-			gGL.vertex2fv((x_max).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top middle
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(1.f - border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(border_uv_scale.mV[VX], 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-
-		if (end_fragment > middle_end)
-		{
-			u_min = (1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_uv_scale.mV[VX];
-			u_max = (1.f - ((end_fragment - middle_end) / middle_start)) * border_uv_scale.mV[VX];
-			x_min = width_vec - ((1.f - llmax(0.f, ((start_fragment - middle_end) / middle_start))) * border_width_right);
-			x_max = width_vec - ((1.f - ((end_fragment - middle_end) / middle_start)) * border_width_right);
-
-			// draw bottom right
-			gGL.texCoord2f(u_min, 0.f);
-			gGL.vertex2fv((x_min).mV);
-
-			gGL.texCoord2f(u_max, 0.f);
-			gGL.vertex2fv(x_max.mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			// draw right 
-			gGL.texCoord2f(u_min, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + border_height_bottom).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			// draw top right
-			gGL.texCoord2f(u_min, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_min + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f - border_uv_scale.mV[VY]);
-			gGL.vertex2fv((x_max + height_vec - border_height_top).mV);
-
-			gGL.texCoord2f(u_max, 1.f);
-			gGL.vertex2fv((x_max + height_vec).mV);
-
-			gGL.texCoord2f(u_min, 1.f);
-			gGL.vertex2fv((x_min + height_vec).mV);
-		}
-	}
-	gGL.end();
-
-	gGL.popUIMatrix();
-}
-
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, 
-							  const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec,
-							  const U32 edges)
-{
-	LLVector3 left_border_width = ((edges & (~(U32)ROUNDED_RECT_RIGHT)) != 0) ? border_width : LLVector3::zero;
-	LLVector3 right_border_width = ((edges & (~(U32)ROUNDED_RECT_LEFT)) != 0) ? border_width : LLVector3::zero;
-
-	LLVector3 top_border_height = ((edges & (~(U32)ROUNDED_RECT_BOTTOM)) != 0) ? border_height : LLVector3::zero;
-	LLVector3 bottom_border_height = ((edges & (~(U32)ROUNDED_RECT_TOP)) != 0) ? border_height : LLVector3::zero;
-
-
-	gGL.begin(LLRender::QUADS);
-	{
-		// draw bottom left
-		gGL.texCoord2f(0.f, 0.f);
-		gGL.vertex3f(0.f, 0.f, 0.f);
-
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
-
-		// draw bottom middle
-		gGL.texCoord2f(border_scale.mV[VX], 0.f);
-		gGL.vertex3fv(left_border_width.mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		// draw bottom right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 0.f);
-		gGL.vertex3fv((width_vec - right_border_width).mV);
-
-		gGL.texCoord2f(1.f, 0.f);
-		gGL.vertex3fv(width_vec.mV);
-
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		// draw left 
-		gGL.texCoord2f(0.f, border_scale.mV[VY]);
-		gGL.vertex3fv(bottom_border_height.mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
-
-		// draw middle
-		gGL.texCoord2f(border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		// draw right 
-		gGL.texCoord2f(1.f - border_scale.mV[VX], border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f, border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + bottom_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		// draw top left
-		gGL.texCoord2f(0.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
-
-		gGL.texCoord2f(0.f, 1.f);
-		gGL.vertex3fv((height_vec).mV);
-
-		// draw top middle
-		gGL.texCoord2f(border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((left_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
-
-		gGL.texCoord2f(border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((left_border_width + height_vec).mV);
-
-		// draw top right
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f - border_scale.mV[VY]);
-		gGL.vertex3fv((width_vec + height_vec - top_border_height).mV);
-
-		gGL.texCoord2f(1.f, 1.f);
-		gGL.vertex3fv((width_vec + height_vec).mV);
-
-		gGL.texCoord2f(1.f - border_scale.mV[VX], 1.f);
-		gGL.vertex3fv((width_vec - right_border_width + height_vec).mV);
-	}
-	gGL.end();
-
-}
-
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec)
-{
-	gl_segmented_rect_3d_tex(border_scale, border_width, border_height, width_vec, height_vec, ROUNDED_RECT_TOP);
 }
 
 void LLUI::initClass(const settings_map_t& settings,
 					 LLImageProviderInterface* image_provider,
 					 LLUIAudioCallback audio_callback,
+					 LLUIAudioCallback deferred_audio_callback,
 					 const LLVector2* scale_factor,
 					 const std::string& language)
 {
+	LLRender2D::initClass(image_provider,scale_factor);
 	sSettingGroups = settings;
 
 	if ((get_ptr_in_map(sSettingGroups, std::string("config")) == NULL) ||
@@ -1632,9 +173,8 @@ void LLUI::initClass(const settings_map_t& settings,
 		llerrs << "Failure to initialize configuration groups" << llendl;
 	}
 
-	sImageProvider = image_provider;
 	sAudioCallback = audio_callback;
-	sGLScaleFactor = (scale_factor == NULL) ? LLVector2(1.f, 1.f) : *scale_factor;
+	sDeferredAudioCallback = deferred_audio_callback;
 	sWindow = NULL; // set later in startup
 	LLFontGL::sShadowColor = LLUIColorTable::instance().getColor("ColorDropShadow");
 
@@ -1668,10 +208,7 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	if(sImageProvider)
-	{
-	sImageProvider->cleanUp();
-}
+	LLRender2D::cleanupClass();
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
@@ -1695,60 +232,12 @@ void LLUI::dirtyRect(LLRect rect)
 	}		
 }
  
-
-//static
-void LLUI::translate(F32 x, F32 y, F32 z)
-{
-	gGL.translateUI(x,y,z);
-	LLFontGL::sCurOrigin.mX += (S32) x;
-	LLFontGL::sCurOrigin.mY += (S32) y;
-	LLFontGL::sCurDepth += z;
-}
-
-//static
-void LLUI::pushMatrix()
-{
-	gGL.pushUIMatrix();
-	LLFontGL::sOriginStack.push_back(std::make_pair(LLFontGL::sCurOrigin, LLFontGL::sCurDepth));
-}
-
-//static
-void LLUI::popMatrix()
-{
-	gGL.popUIMatrix();
-	LLFontGL::sCurOrigin = LLFontGL::sOriginStack.back().first;
-	LLFontGL::sCurDepth = LLFontGL::sOriginStack.back().second;
-	LLFontGL::sOriginStack.pop_back();
-}
-
-//static 
-void LLUI::loadIdentity()
-{
-	gGL.loadUIIdentity(); 
-	LLFontGL::sCurOrigin.mX = 0;
-	LLFontGL::sCurOrigin.mY = 0;
-	LLFontGL::sCurDepth = 0.f;
-}
-
-//static
-void LLUI::setScaleFactor(const LLVector2 &scale_factor)
-{
-	sGLScaleFactor = scale_factor;
-}
-
-//static
-void LLUI::setLineWidth(F32 width)
-{
-	gGL.flush();
-	glLineWidth(width * lerp(sGLScaleFactor.mV[VX], sGLScaleFactor.mV[VY], 0.5f));
-}
-
 //static 
 void LLUI::setMousePositionScreen(S32 x, S32 y)
 {
 	S32 screen_x, screen_y;
-	screen_x = llround((F32)x * sGLScaleFactor.mV[VX]);
-	screen_y = llround((F32)y * sGLScaleFactor.mV[VY]);
+	screen_x = llround((F32)x * getScaleFactor().mV[VX]);
+	screen_y = llround((F32)y * getScaleFactor().mV[VY]);
 	
 	LLView::getWindow()->setCursorPosition(LLCoordGL(screen_x, screen_y).convert());
 }
@@ -1759,8 +248,8 @@ void LLUI::getMousePositionScreen(S32 *x, S32 *y)
 	LLCoordWindow cursor_pos_window;
 	getWindow()->getCursorPosition(&cursor_pos_window);
 	LLCoordGL cursor_pos_gl(cursor_pos_window.convert());
-	*x = llround((F32)cursor_pos_gl.mX / sGLScaleFactor.mV[VX]);
-	*y = llround((F32)cursor_pos_gl.mY / sGLScaleFactor.mV[VX]);
+	*x = llround((F32)cursor_pos_gl.mX / getScaleFactor().mV[VX]);
+	*y = llround((F32)cursor_pos_gl.mY / getScaleFactor().mV[VX]);
 }
 
 //static 
@@ -1874,21 +363,21 @@ LLVector2 LLUI::getWindowSize()
 	LLCoordWindow window_rect;
 	sWindow->getSize(&window_rect);
 
-	return LLVector2(window_rect.mX / sGLScaleFactor.mV[VX], window_rect.mY / sGLScaleFactor.mV[VY]);
+	return LLVector2(window_rect.mX / getScaleFactor().mV[VX], window_rect.mY / getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y)
 {
-	*gl_x = llround((F32)screen_x * sGLScaleFactor.mV[VX]);
-	*gl_y = llround((F32)screen_y * sGLScaleFactor.mV[VY]);
+	*gl_x = llround((F32)screen_x * getScaleFactor().mV[VX]);
+	*gl_y = llround((F32)screen_y * getScaleFactor().mV[VY]);
 }
 
 //static
 void LLUI::glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y)
 {
-	*screen_x = llround((F32)gl_x / sGLScaleFactor.mV[VX]);
-	*screen_y = llround((F32)gl_y / sGLScaleFactor.mV[VY]);
+	*screen_x = llround((F32)gl_x / getScaleFactor().mV[VX]);
+	*screen_y = llround((F32)gl_y / getScaleFactor().mV[VY]);
 }
 
 //static
@@ -1905,27 +394,6 @@ void LLUI::glRectToScreen(const LLRect& gl, LLRect *screen)
 	glPointToScreen(gl.mRight, gl.mBottom, &screen->mRight, &screen->mBottom);
 }
 
-//static
-LLPointer<LLUIImage> LLUI::getUIImageByID(const LLUUID& image_id, S32 priority)
-{
-	if (sImageProvider)
-	{
-		return sImageProvider->getUIImageByID(image_id, priority);
-	}
-	else
-	{
-		return NULL;
-	}
-}
-
-//static 
-LLPointer<LLUIImage> LLUI::getUIImage(const std::string& name, S32 priority)
-{
-	if (!name.empty() && sImageProvider)
-		return sImageProvider->getUIImage(name, priority);
-	else
-		return NULL;
-}
 
 LLControlGroup& LLUI::getControlControlGroup (const std::string& controlname)
 {
@@ -2067,7 +535,7 @@ const LLView* LLUI::resolvePath(const LLView* context, const std::string& path)
 
 namespace LLInitParam
 {
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color),
 		red("red"),
 		green("green"),
@@ -2078,7 +546,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+	void ParamValue<LLUIColor>::updateValueFromBlock()
 	{
 		if (control.isProvided() && !control().empty())
 		{
@@ -2090,7 +558,7 @@ namespace LLInitParam
 		}
 	}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		LLColor4 color = getValue();
 		red.set(color.mV[VRED], make_block_authoritative);
@@ -2106,7 +574,7 @@ namespace LLInitParam
 			&& !(b->getFontDesc() < a->getFontDesc());
 	}
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp),
 		name("name"),
 		size("size"),
@@ -2120,7 +588,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{
 		const LLFontGL* res_fontp = LLFontGL::getFontByName(name);
 		if (res_fontp)
@@ -2143,7 +611,7 @@ namespace LLInitParam
 		}
 	}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		if (getValue())
 		{
@@ -2153,7 +621,7 @@ namespace LLInitParam
 		}
 	}
 
-	ParamValue<LLRect, TypeValues<LLRect> >::ParamValue(const LLRect& rect)
+	ParamValue<LLRect>::ParamValue(const LLRect& rect)
 	:	super_t(rect),
 		left("left"),
 		top("top"),
@@ -2165,7 +633,7 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLRect, TypeValues<LLRect> >::updateValueFromBlock()
+	void ParamValue<LLRect>::updateValueFromBlock()
 	{
 		LLRect rect;
 
@@ -2229,7 +697,7 @@ namespace LLInitParam
 		updateValue(rect);
 	}
 	
-	void ParamValue<LLRect, TypeValues<LLRect> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLRect>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		// because of the ambiguity in specifying a rect by position and/or dimensions
 		// we use the lowest priority pairing so that any valid pairing in xui 
@@ -2246,7 +714,7 @@ namespace LLInitParam
 		height.set(value.getHeight(), make_block_authoritative);
 	}
 
-	ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::ParamValue(const LLCoordGL& coord)
+	ParamValue<LLCoordGL>::ParamValue(const LLCoordGL& coord)
 	:	super_t(coord),
 		x("x"),
 		y("y")
@@ -2254,12 +722,12 @@ namespace LLInitParam
 		updateBlockFromValue(false);
 	}
 
-	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateValueFromBlock()
+	void ParamValue<LLCoordGL>::updateValueFromBlock()
 	{
 		updateValue(LLCoordGL(x, y));
 	}
 	
-	void ParamValue<LLCoordGL, TypeValues<LLCoordGL> >::updateBlockFromValue(bool make_block_authoritative)
+	void ParamValue<LLCoordGL>::updateBlockFromValue(bool make_block_authoritative)
 	{
 		x.set(getValue().mX, make_block_authoritative);
 		y.set(getValue().mY, make_block_authoritative);
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index c5a12d2b315ec4febfc42468ac23f59d593b4b8f..0a0e0e164ec830191b912707ee8d37e169ec7827 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -1,6 +1,6 @@
 /** 
  * @file llui.h
- * @brief GL function declarations and other general static UI services.
+ * @brief General static UI services.
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,121 +24,37 @@
  * $/LicenseInfo$
  */
 
-// All immediate-mode gl drawing should happen here.
 
 #ifndef LL_LLUI_H
 #define LL_LLUI_H
 
-#include "llpointer.h"		// LLPointer<>
 #include "llrect.h"
 #include "llcontrol.h"
 #include "llcoord.h"
-#include "llglslshader.h"
+#include "v2math.h"
 #include "llinitparam.h"
 #include "llregistry.h"
+#include "llrender2dutils.h"
+#include "llpointer.h"
 #include "lluicolor.h"
 #include "lluicolortable.h"
+#include "lluiimage.h"
 #include <boost/signals2.hpp>
 #include "lllazyvalue.h"
 #include "llframetimer.h"
 #include <limits>
 
-// LLUIFactory
-#include "llsd.h"
-
 // for initparam specialization
 #include "llfontgl.h"
 
 
-class LLColor4; 
-class LLVector3;
-class LLVector2;
-class LLUIImage;
 class LLUUID;
 class LLWindow;
 class LLView;
 class LLHelp;
 
-// UI colors
-extern const LLColor4 UI_VERTEX_COLOR;
 void make_ui_sound(const char* name);
-
-BOOL ui_point_in_rect(S32 x, S32 y, S32 left, S32 top, S32 right, S32 bottom);
-void gl_state_for_2d(S32 width, S32 height);
-
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2);
-void gl_line_2d(S32 x1, S32 y1, S32 x2, S32 y2, const LLColor4 &color );
-void gl_triangle_2d(S32 x1, S32 y1, S32 x2, S32 y2, S32 x3, S32 y3, const LLColor4& color, BOOL filled);
-void gl_rect_2d_simple( S32 width, S32 height );
-
-void gl_draw_x(const LLRect& rect, const LLColor4& color);
-
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, BOOL filled = TRUE );
-void gl_rect_2d(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &color, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d_offset_local( S32 left, S32 top, S32 right, S32 bottom, S32 pixel_offset = 0, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, BOOL filled = TRUE );
-void gl_rect_2d(const LLRect& rect, const LLColor4& color, BOOL filled = TRUE );
-void gl_rect_2d_checkerboard(const LLRect& rect, GLfloat alpha = 1.0f);
-
-void gl_drop_shadow(S32 left, S32 top, S32 right, S32 bottom, const LLColor4 &start_color, S32 lines);
-
-void gl_circle_2d(F32 x, F32 y, F32 radius, S32 steps, BOOL filled);
-void gl_arc_2d(F32 center_x, F32 center_y, F32 radius, S32 steps, BOOL filled, F32 start_angle, F32 end_angle);
-void gl_deep_circle( F32 radius, F32 depth );
-void gl_ring( F32 radius, F32 width, const LLColor4& center_color, const LLColor4& side_color, S32 steps, BOOL render_center );
-void gl_corners_2d(S32 left, S32 top, S32 right, S32 bottom, S32 length, F32 max_frac);
-void gl_washer_2d(F32 outer_radius, F32 inner_radius, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-void gl_washer_segment_2d(F32 outer_radius, F32 inner_radius, F32 start_radians, F32 end_radians, S32 steps, const LLColor4& inner_color, const LLColor4& outer_color);
-
-void gl_draw_image(S32 x, S32 y, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_rotated_image(S32 x, S32 y, F32 degrees, LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_rotated_image(S32 x, S32 y, S32 width, S32 height, F32 degrees,LLTexture* image, const LLColor4& color = UI_VERTEX_COLOR, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 border_width, S32 border_height, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-void gl_draw_scaled_image_with_border(S32 x, S32 y, S32 width, S32 height, LLTexture* image, const LLColor4 &color, BOOL solid_color = FALSE, const LLRectf& uv_rect = LLRectf(0.f, 1.f, 1.f, 0.f), const LLRectf& scale_rect = LLRectf(0.f, 1.f, 1.f, 0.f));
-
-void gl_stippled_line_3d( const LLVector3& start, const LLVector3& end, const LLColor4& color, F32 phase = 0.f ); 
-
-void gl_rect_2d_simple_tex( S32 width, S32 height );
-
-// segmented rectangles
-
-/*
-   TL |______TOP_________| TR 
-     /|                  |\  
-   _/_|__________________|_\_
-   L| |    MIDDLE        | |R
-   _|_|__________________|_|_
-    \ |    BOTTOM        | /  
-   BL\|__________________|/ BR
-      |                  |    
-*/
-
-typedef enum e_rounded_edge
-{
-	ROUNDED_RECT_LEFT	= 0x1, 
-	ROUNDED_RECT_TOP	= 0x2, 
-	ROUNDED_RECT_RIGHT	= 0x4, 
-	ROUNDED_RECT_BOTTOM	= 0x8,
-	ROUNDED_RECT_ALL	= 0xf
-}ERoundedEdge;
-
-
-void gl_segmented_rect_2d_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_2d_fragment_tex(const S32 left, const S32 top, const S32 right, const S32 bottom, const S32 texture_width, const S32 texture_height, const S32 border_size, const F32 start_fragment, const F32 end_fragment, const U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec, U32 edges = ROUNDED_RECT_ALL);
-void gl_segmented_rect_3d_tex_top(const LLVector2& border_scale, const LLVector3& border_width, const LLVector3& border_height, const LLVector3& width_vec, const LLVector3& height_vec);
-
-inline void gl_rect_2d( const LLRect& rect, BOOL filled )
-{
-	gl_rect_2d( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, filled );
-}
-
-inline void gl_rect_2d_offset_local( const LLRect& rect, S32 pixel_offset, BOOL filled)
-{
-	gl_rect_2d_offset_local( rect.mLeft, rect.mTop, rect.mRight, rect.mBottom, pixel_offset, filled );
-}
+void make_ui_sound_deferred(const char * name);
 
 class LLImageProviderInterface;
 
@@ -275,15 +191,16 @@ class LLUI
 	static void initClass(const settings_map_t& settings,
 						  LLImageProviderInterface* image_provider,
 						  LLUIAudioCallback audio_callback = NULL,
+						  LLUIAudioCallback deferred_audio_callback = NULL,
 						  const LLVector2 *scale_factor = NULL,
 						  const std::string& language = LLStringUtil::null);
 	static void cleanupClass();
 	static void setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t&, const clear_popups_t& );
 
-	static void pushMatrix();
-	static void popMatrix();
-	static void loadIdentity();
-	static void translate(F32 x, F32 y, F32 z = 0.0f);
+	static void pushMatrix() { LLRender2D::pushMatrix(); }
+	static void popMatrix() { LLRender2D::popMatrix(); }
+	static void loadIdentity() { LLRender2D::loadIdentity(); }
+	static void translate(F32 x, F32 y, F32 z = 0.0f) { LLRender2D::translate(x, y, z); }
 
 	static LLRect	sDirtyRect;
 	static BOOL		sDirty;
@@ -328,10 +245,13 @@ class LLUI
 	static void getMousePositionScreen(S32 *x, S32 *y);
 	static void setMousePositionLocal(const LLView* viewp, S32 x, S32 y);
 	static void getMousePositionLocal(const LLView* viewp, S32 *x, S32 *y);
-	static void setScaleFactor(const LLVector2& scale_factor);
-	static void setLineWidth(F32 width);
-	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0);
-	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0);
+	static LLVector2& getScaleFactor() { return LLRender2D::sGLScaleFactor; }
+	static void setScaleFactor(const LLVector2& scale_factor) { LLRender2D::setScaleFactor(scale_factor); }
+	static void setLineWidth(F32 width) { LLRender2D::setLineWidth(width); }
+	static LLPointer<LLUIImage> getUIImageByID(const LLUUID& image_id, S32 priority = 0)
+		{ return LLRender2D::getUIImageByID(image_id, priority); }
+	static LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority = 0)
+		{ return LLRender2D::getUIImage(name, priority); }
 	static LLVector2 getWindowSize();
 	static void screenPointToGL(S32 screen_x, S32 screen_y, S32 *gl_x, S32 *gl_y);
 	static void glPointToScreen(S32 gl_x, S32 gl_y, S32 *screen_x, S32 *screen_y);
@@ -360,12 +280,11 @@ class LLUI
 	//
 	static settings_map_t sSettingGroups;
 	static LLUIAudioCallback sAudioCallback;
-	static LLVector2		sGLScaleFactor;
+	static LLUIAudioCallback sDeferredAudioCallback;
 	static LLWindow*		sWindow;
 	static LLView*			sRootView;
 	static LLHelp*			sHelpImpl;
 private:
-	static LLImageProviderInterface* sImageProvider;
 	static std::vector<std::string> sXUIPaths;
 	static LLFrameTimer		sMouseIdleTimer;
 	static add_popup_t		sAddPopupFunc;
@@ -376,18 +295,6 @@ class LLUI
 
 // Moved LLLocalClipRect to lllocalcliprect.h
 
-//RN: maybe this needs to moved elsewhere?
-class LLImageProviderInterface
-{
-protected:
-	LLImageProviderInterface() {};
-	virtual ~LLImageProviderInterface() {};
-public:
-	virtual LLPointer<LLUIImage> getUIImage(const std::string& name, S32 priority) = 0;
-	virtual LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority) = 0;
-	virtual void cleanUp() = 0;
-};
-
 class LLCallbackRegistry
 {
 public:
@@ -436,10 +343,11 @@ class LLRegisterWith
 
 	// this avoids a MSVC bug where non-referenced static members are "optimized" away
 	// even if their constructors have side effects
-	void reference()
+	S32 reference()
 	{
 		S32 dummy;
 		dummy = 0;
+		return dummy;
 	}
 };
 
@@ -507,7 +415,7 @@ class LLUICachedControl : public LLCachedControl<T>
 namespace LLInitParam
 {
 	template<>
-	class ParamValue<LLRect, TypeValues<LLRect> > 
+	class ParamValue<LLRect> 
 	:	public CustomParamValue<LLRect>
 	{
         typedef CustomParamValue<LLRect> super_t;
@@ -526,7 +434,7 @@ namespace LLInitParam
 	};
 
 	template<>
-	class ParamValue<LLUIColor, TypeValues<LLUIColor> > 
+	class ParamValue<LLUIColor> 
 	:	public CustomParamValue<LLUIColor>
 	{
         typedef CustomParamValue<LLUIColor> super_t;
@@ -544,7 +452,7 @@ namespace LLInitParam
 	};
 
 	template<>
-	class ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> > 
+	class ParamValue<const LLFontGL*> 
 	:	public CustomParamValue<const LLFontGL* >
 	{
         typedef CustomParamValue<const LLFontGL*> super_t;
@@ -584,7 +492,7 @@ namespace LLInitParam
 
 
 	template<>
-	class ParamValue<LLCoordGL, TypeValues<LLCoordGL> >
+	class ParamValue<LLCoordGL>
 	:	public CustomParamValue<LLCoordGL>
 	{
 		typedef CustomParamValue<LLCoordGL> super_t;
@@ -598,7 +506,4 @@ namespace LLInitParam
 	};
 }
 
-extern LLGLSLShader gSolidColorProgram;
-extern LLGLSLShader gUIProgram;
-
 #endif
diff --git a/indra/llui/lluictrlfactory.cpp b/indra/llui/lluictrlfactory.cpp
index bd06476936a3e25b324942b7516768fb9118e0cd..60fee47ae058acb7e2a413896b6ab02df4e5002a 100644
--- a/indra/llui/lluictrlfactory.cpp
+++ b/indra/llui/lluictrlfactory.cpp
@@ -247,13 +247,13 @@ const LLInitParam::BaseBlock& get_empty_param_block()
 
 // adds a widget and its param block to various registries
 //static 
-void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& tag)
+void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const std::type_info* param_block_type, const std::string& name)
 {
 	// associate parameter block type with template .xml file
-	std::string* existing_tag = LLWidgetNameRegistry::instance().getValue(param_block_type);
-	if (existing_tag != NULL)
+	std::string* existing_name = LLWidgetNameRegistry::instance().getValue(param_block_type);
+	if (existing_name != NULL)
 	{
-		if(*existing_tag != tag)
+		if(*existing_name != name)
 		{
 			std::cerr << "Duplicate entry for T::Params, try creating empty param block in derived classes that inherit T::Params" << std::endl;
 			// forcing crash here
@@ -262,19 +262,15 @@ void LLUICtrlFactory::registerWidget(const std::type_info* widget_type, const st
 		}
 		else
 		{
-			// widget already registered
+			// widget already registered this name
 			return;
 		}
 	}
-	LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, tag);
+
+	LLWidgetNameRegistry::instance().defaultRegistrar().add(param_block_type, name);
 	//FIXME: comment this in when working on schema generation
 	//LLWidgetTypeRegistry::instance().defaultRegistrar().add(tag, widget_type);
 	//LLDefaultParamBlockRegistry::instance().defaultRegistrar().add(widget_type, &get_empty_param_block<T>);
 }
 
-//static 
-const std::string* LLUICtrlFactory::getWidgetTag(const std::type_info* widget_type)
-{
-	return LLWidgetNameRegistry::instance().getValue(widget_type);
-}
 
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index f6971261d714403bdff98d3d60100d159335e11a..876bb5ef46fe9a519037565ca0e5fc1b7ea0e9c1 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -98,7 +98,7 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 		ParamDefaults()
 		{
 			// look up template file for this param block...
-			const std::string* param_block_tag = getWidgetTag(&typeid(PARAM_BLOCK));
+			const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
 			if (param_block_tag)
 			{	// ...and if it exists, back fill values using the most specific template first
 				PARAM_BLOCK params;
@@ -132,7 +132,6 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	template<typename T>
 	static const typename T::Params& getDefaultParams()
 	{
-		//#pragma message("Generating ParamDefaults")
 		return ParamDefaults<typename T::Params, 0>::instance().get();
 	}
 
@@ -285,8 +284,6 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	}
 
 
-	static const std::string* getWidgetTag(const std::type_info* widget_type);
-
 	// this exists to get around dependency on llview
 	static void setCtrlParent(LLView* view, LLView* parent, S32 tab_group);
 
diff --git a/indra/llui/llurlaction.cpp b/indra/llui/llurlaction.cpp
index fd9b3d9a6d33f6d26b89f7482dcf1b09841cf3d6..f51aeaec1315b56e1fa4c560cd4fc4a6305ce201 100644
--- a/indra/llui/llurlaction.cpp
+++ b/indra/llui/llurlaction.cpp
@@ -24,7 +24,6 @@
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
-
 #include "linden_common.h"
 
 #include "llurlaction.h"
@@ -32,6 +31,7 @@
 #include "llwindow.h"
 #include "llurlregistry.h"
 
+
 // global state for the callback functions
 LLUrlAction::url_callback_t 		LLUrlAction::sOpenURLCallback;
 LLUrlAction::url_callback_t 		LLUrlAction::sOpenURLInternalCallback;
@@ -157,3 +157,34 @@ void LLUrlAction::showProfile(std::string url)
 		}
 	}
 }
+
+std::string LLUrlAction::getUserID(std::string url)
+{
+	LLURI uri(url);
+	LLSD path_array = uri.pathArray();
+	std::string id_str;
+	if (path_array.size() == 4)
+	{
+		id_str = path_array.get(2).asString();
+	}
+	return id_str;
+}
+
+void LLUrlAction::sendIM(std::string url)
+{
+	std::string id_str = getUserID(url);
+	if (LLUUID::validate(id_str))
+	{
+		executeSLURL("secondlife:///app/agent/" + id_str + "/im");
+	}
+}
+
+void LLUrlAction::addFriend(std::string url)
+{
+	std::string id_str = getUserID(url);
+	if (LLUUID::validate(id_str))
+	{
+		executeSLURL("secondlife:///app/agent/" + id_str + "/requestfriend");
+	}
+}
+
diff --git a/indra/llui/llurlaction.h b/indra/llui/llurlaction.h
index c34960b82622345aeccc014335f9a01dd5df204a..e31cd71a20769acd176ab616a3ce37160a93c6d9 100644
--- a/indra/llui/llurlaction.h
+++ b/indra/llui/llurlaction.h
@@ -76,6 +76,9 @@ class LLUrlAction
 
 	/// 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 void sendIM(std::string url);
+	static void addFriend(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 a9e8fbb4e4fbfc26f8880119d86bb0c17ae65835..99ee6888889be5b03cfb9558a2012f9bf704d8ad 100644
--- a/indra/llui/llurlentry.cpp
+++ b/indra/llui/llurlentry.cpp
@@ -340,7 +340,8 @@ std::string LLUrlEntrySLURL::getLocation(const std::string &url) const
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/about
 //
-LLUrlEntryAgent::LLUrlEntryAgent()
+LLUrlEntryAgent::LLUrlEntryAgent() :
+	mAvatarNameCacheConnection()
 {
 	mPattern = boost::regex(APP_HEADER_REGEX "/agent/[\\da-f-]+/\\w+",
 							boost::regex::perl|boost::regex::icase);
@@ -371,7 +372,9 @@ void LLUrlEntryAgent::callObservers(const std::string &id,
 void LLUrlEntryAgent::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
-	std::string label = av_name.getCompleteName();
+	mAvatarNameCacheConnection.disconnect();
+	
+ 	std::string label = av_name.getCompleteName();
 
 	// received the agent name from the server - tell our observers
 	callObservers(id.asString(), label, mIcon);
@@ -456,9 +459,11 @@ std::string LLUrlEntryAgent::getLabel(const std::string &url, const LLUrlLabelCa
 	}
 	else
 	{
-		LLAvatarNameCache::get(agent_id,
-			boost::bind(&LLUrlEntryAgent::onAvatarNameCache,
-				this, _1, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgent::onAvatarNameCache, this, _1, _2));
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
@@ -515,12 +520,15 @@ std::string LLUrlEntryAgent::getIcon(const std::string &url)
 // secondlife:///app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 // x-grid-location-info://lincoln.lindenlab.com/app/agent/0e346d8b-4433-4d66-a6b0-fd37083abc4c/(completename|displayname|username)
 //
-LLUrlEntryAgentName::LLUrlEntryAgentName()
+LLUrlEntryAgentName::LLUrlEntryAgentName() :
+	mAvatarNameCacheConnection()
 {}
 
 void LLUrlEntryAgentName::onAvatarNameCache(const LLUUID& id,
 										const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	std::string label = getName(av_name);
 	// received the agent name from the server - tell our observers
 	callObservers(id.asString(), label, mIcon);
@@ -554,9 +562,11 @@ std::string LLUrlEntryAgentName::getLabel(const std::string &url, const LLUrlLab
 	}
 	else
 	{
-		LLAvatarNameCache::get(agent_id,
-			boost::bind(&LLUrlEntryAgentCompleteName::onAvatarNameCache,
-				this, _1, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_id, boost::bind(&LLUrlEntryAgentName::onAvatarNameCache, this, _1, _2));
 		addObserver(agent_id_string, url, cb);
 		return LLTrans::getString("LoadingData");
 	}
@@ -597,7 +607,7 @@ LLUrlEntryAgentDisplayName::LLUrlEntryAgentDisplayName()
 
 std::string LLUrlEntryAgentDisplayName::getName(const LLAvatarName& avatar_name)
 {
-	return avatar_name.mDisplayName;
+	return avatar_name.getDisplayName();
 }
 
 //
@@ -613,7 +623,7 @@ LLUrlEntryAgentUserName::LLUrlEntryAgentUserName()
 
 std::string LLUrlEntryAgentUserName::getName(const LLAvatarName& avatar_name)
 {
-	return avatar_name.mUsername.empty() ? avatar_name.getLegacyName() : avatar_name.mUsername;
+	return avatar_name.getAccountName();
 }
 
 //
diff --git a/indra/llui/llurlentry.h b/indra/llui/llurlentry.h
index 5f82721c0fdf9067383f1d974a052242c4c8a2a3..8c6c32178af66856990ff00967c639d6560afeb4 100644
--- a/indra/llui/llurlentry.h
+++ b/indra/llui/llurlentry.h
@@ -171,6 +171,13 @@ class LLUrlEntryAgent : public LLUrlEntryBase
 {
 public:
 	LLUrlEntryAgent();
+	~LLUrlEntryAgent()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ std::string getIcon(const std::string &url);
 	/*virtual*/ std::string getTooltip(const std::string &string) const;
@@ -181,6 +188,7 @@ class LLUrlEntryAgent : public LLUrlEntryBase
 	/*virtual*/ void callObservers(const std::string &id, const std::string &label, const std::string& icon);
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 ///
@@ -192,6 +200,13 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
 {
 public:
 	LLUrlEntryAgentName();
+	~LLUrlEntryAgentName()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	/*virtual*/ std::string getLabel(const std::string &url, const LLUrlLabelCallback &cb);
 	/*virtual*/ LLStyle::Params getStyle() const;
 protected:
@@ -199,6 +214,7 @@ class LLUrlEntryAgentName : public LLUrlEntryBase, public boost::signals2::track
 	virtual std::string getName(const LLAvatarName& avatar_name) = 0;
 private:
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index ad9bec9f61e1e10d9b2e51de5a1c31662b5fa133..3613a40e2c6c8021fce9c8fb8997f31eef03eaf0 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -55,6 +55,8 @@
 #include "lltexteditor.h"
 #include "lltextbox.h"
 
+static const S32 LINE_HEIGHT = 15;
+
 S32		LLView::sDepth = 0;
 bool	LLView::sDebugRects = false;
 bool	LLView::sDebugRectsShowNames = true;
@@ -349,7 +351,7 @@ void LLView::removeChild(LLView* child)
 	}
 	else
 	{
-		llwarns << child->getName() << "is not a child of " << getName() << llendl;
+		llwarns << "\"" << child->getName() << "\" is not a child of " << getName() << llendl;
 	}
 	updateBoundingRect();
 }
@@ -873,13 +875,12 @@ BOOL LLView::handleToolTip(S32 x, S32 y, MASK mask)
 		// allow "scrubbing" over ui by showing next tooltip immediately
 		// if previous one was still visible
 		F32 timeout = LLToolTipMgr::instance().toolTipVisible() 
-			? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
-			: LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
+		              ? LLUI::sSettingGroups["config"]->getF32( "ToolTipFastDelay" )
+		              : LLUI::sSettingGroups["config"]->getF32( "ToolTipDelay" );
 		LLToolTipMgr::instance().show(LLToolTip::Params()
-			.message(tooltip)
-			.sticky_rect(calcScreenRect())
-			.delay_time(timeout));
-
+		                              .message(tooltip)
+		                              .sticky_rect(calcScreenRect())
+		                              .delay_time(timeout));
 		handled = TRUE;
 	}
 
@@ -1204,11 +1205,24 @@ void LLView::drawDebugRect()
 			&& preview_iter == sPreviewHighlightedElements.end()
 			&& sDebugRectsShowNames)
 		{
-			//char temp[256];
 			S32 x, y;
 			gGL.color4fv( border_color.mV );
-			x = debug_rect.getWidth()/2;
-			y = debug_rect.getHeight()/2;
+
+			x = debug_rect.getWidth() / 2;
+
+			S32 rect_height = debug_rect.getHeight();
+			S32 lines = rect_height / LINE_HEIGHT + 1;
+
+			S32 depth = 0;
+			LLView * viewp = this;
+			while (NULL != viewp)
+			{
+				viewp = viewp->getParent();
+				depth++;
+			}
+
+			y = rect_height - LINE_HEIGHT * (depth % lines + 1);
+
 			std::string debug_text = llformat("%s (%d x %d)", getName().c_str(),
 										debug_rect.getWidth(), debug_rect.getHeight());
 			LLFontGL::getFontSansSerifSmall()->renderUTF8(debug_text, 0, (F32)x, (F32)y, border_color,
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 1c353495107b1f09426693ed6aabdd76195f7661..15b85a6418fde2184c49eadc77bcbf68643aee3c 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -67,7 +67,6 @@ const BOOL	NOT_MOUSE_OPAQUE = FALSE;
 
 const U32 GL_NAME_UI_RESERVED = 2;
 
-
 // maintains render state during traversal of UI tree
 class LLViewDrawContext
 {
diff --git a/indra/llui/llxuiparser.cpp b/indra/llui/llxuiparser.cpp
index afc76024d1e0ef0f8688b8de638cbe52c29843e2..3ad5ad7d425dfeda1f2ecb9d2bc9c00dfbddb0ab 100644
--- a/indra/llui/llxuiparser.cpp
+++ b/indra/llui/llxuiparser.cpp
@@ -42,7 +42,7 @@
 #include <boost/spirit/include/classic_core.hpp>
 
 #include "lluicolor.h"
-
+#include "v3math.h"
 using namespace BOOST_SPIRIT_CLASSIC_NS;
 
 const S32 MAX_STRING_ATTRIBUTE_SIZE = 40;
@@ -79,7 +79,6 @@ struct Occurs : public LLInitParam::Block<Occurs>
 	{}
 };
 
-
 typedef enum
 {
 	USE_REQUIRED,
@@ -101,14 +100,23 @@ namespace LLInitParam
 
 struct Element;
 struct Group;
-struct Choice;
 struct Sequence;
-struct Any;
+
+struct All : public LLInitParam::Block<All, Occurs>
+{
+	Multiple< Lazy<Element, IS_A_BLOCK> > elements;
+
+	All()
+	:	elements("element")
+	{
+		maxOccurs = 1;
+	}
+};
 
 struct Attribute : public LLInitParam::Block<Attribute>
 {
-	Mandatory<std::string>	name;
-	Mandatory<std::string>	type;
+	Mandatory<std::string>	name,
+							type;
 	Mandatory<EUse>			use;
 	
 	Attribute()
@@ -127,24 +135,13 @@ struct Any : public LLInitParam::Block<Any, Occurs>
 	{}
 };
 
-struct All : public LLInitParam::Block<All, Occurs>
-{
-	Multiple< Lazy<Element> > elements;
-
-	All()
-	:	elements("element")
-	{
-		maxOccurs = 1;
-	}
-};
-
 struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 {
-	Alternative< Lazy<Element> >	element;
-	Alternative< Lazy<Group> >		group;
-	Alternative< Lazy<Choice> >		choice;
-	Alternative< Lazy<Sequence> >	sequence;
-	Alternative< Lazy<Any> >		any;
+	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
+	Alternative< Lazy<Choice, IS_A_BLOCK> >		choice;
+	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
+	Alternative< Lazy<Any> >					any;
 
 	Choice()
 	:	element("element"),
@@ -158,11 +155,11 @@ struct Choice : public LLInitParam::ChoiceBlock<Choice, Occurs>
 
 struct Sequence : public LLInitParam::ChoiceBlock<Sequence, Occurs>
 {
-	Alternative< Lazy<Element> >	element;
-	Alternative< Lazy<Group> >		group;
-	Alternative< Lazy<Choice> >		choice;
-	Alternative< Lazy<Sequence> >	sequence;
-	Alternative< Lazy<Any> >		any;
+	Alternative< Lazy<Element, IS_A_BLOCK> >	element;
+	Alternative< Lazy<Group, IS_A_BLOCK> >		group;
+	Alternative< Lazy<Choice> >					choice;
+	Alternative< Lazy<Sequence, IS_A_BLOCK> >	sequence;
+	Alternative< Lazy<Any> >					any;
 };
 
 struct GroupContents : public LLInitParam::ChoiceBlock<GroupContents, Occurs>
@@ -247,7 +244,7 @@ struct ComplexType : public LLInitParam::Block<ComplexType, ComplexTypeContents>
 	Optional<bool>					mixed;
 
 	Multiple<Attribute>				attribute;
-	Multiple< Lazy<Element> >			elements;
+	Multiple< Lazy<Element, IS_A_BLOCK > >			elements;
 
 	ComplexType()
 	:	name("name"),
@@ -313,7 +310,6 @@ struct Schema : public LLInitParam::Block<Schema>
 			setNameSpace(ns);
 		};
 	}
-
 };
 
 //
@@ -625,7 +621,7 @@ void LLXUIXSDWriter::writeXSD(const std::string& type_name, const std::string& p
 			nodep->createChild("schemaLocation", true)->setStringValue(widget_name + ".xsd");
 			
 			// add to front of schema
-			mSchemaNode->addChild(nodep, mSchemaNode);
+			mSchemaNode->addChild(nodep);
 		}
 
 		for (widget_registry_t::Registrar::registry_map_t::const_iterator it = widget_registryp->currentRegistrar().beginItems();
@@ -670,6 +666,7 @@ LLXUIParser::LLXUIParser()
 		registerParserFuncs<S32>(readS32Value, writeS32Value);
 		registerParserFuncs<F32>(readF32Value, writeF32Value);
 		registerParserFuncs<F64>(readF64Value, writeF64Value);
+		registerParserFuncs<LLVector3>(readVector3Value, writeVector3Value);
 		registerParserFuncs<LLColor4>(readColor4Value, writeColor4Value);
 		registerParserFuncs<LLUIColor>(readUIColorValue, writeUIColorValue);
 		registerParserFuncs<LLUUID>(readUUIDValue, writeUUIDValue);
@@ -880,16 +877,24 @@ LLXMLNodePtr LLXUIParser::getNode(name_stack_t& stack)
 		it = next_it)
 	{
 		++next_it;
+		bool force_new_node = false;
+
 		if (it->first.empty())
 		{
 			it->second = false;
 			continue;
 		}
 
+		if (next_it != stack.end() && next_it->first.empty() && next_it->second)
+		{
+			force_new_node = true;
+		}
+
+
 		out_nodes_t::iterator found_it = mOutNodes.find(it->first);
 
 		// node with this name not yet written
-		if (found_it == mOutNodes.end() || it->second)
+		if (found_it == mOutNodes.end() || it->second || force_new_node)
 		{
 			// make an attribute if we are the last element on the name stack
 			bool is_attribute = next_it == stack.end();
@@ -1144,6 +1149,31 @@ bool LLXUIParser::writeF64Value(Parser& parser, const void* val_ptr, name_stack_
 	return false;
 }
 
+bool LLXUIParser::readVector3Value(Parser& parser, void* val_ptr)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLVector3* vecp = (LLVector3*)val_ptr;
+	if(self.mCurReadNode->getFloatValue(3, vecp->mV) >= 3)
+	{
+		return true;
+	}
+
+	return false;
+}
+
+bool LLXUIParser::writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t& stack)
+{
+	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
+	LLXMLNodePtr node = self.getNode(stack);
+	if (node.notNull())
+	{
+		LLVector3 vector = *((LLVector3*)val_ptr);
+		node->setFloatValue(3, vector.mV);
+		return true;
+	}
+	return false;
+}
+
 bool LLXUIParser::readColor4Value(Parser& parser, void* val_ptr)
 {
 	LLXUIParser& self = static_cast<LLXUIParser&>(parser);
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index d7cd25696723dd11a104c4435dd9067a5d84bbab..e48663e5cc94fc3d4963f0637bca4b06a2f21519 100644
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -127,6 +127,7 @@ LOG_CLASS(LLXUIParser);
 	static bool readS32Value(Parser& parser, void* val_ptr);
 	static bool readF32Value(Parser& parser, void* val_ptr);
 	static bool readF64Value(Parser& parser, void* val_ptr);
+	static bool readVector3Value(Parser& parser, void* val_ptr);
 	static bool readColor4Value(Parser& parser, void* val_ptr);
 	static bool readUIColorValue(Parser& parser, void* val_ptr);
 	static bool readUUIDValue(Parser& parser, void* val_ptr);
@@ -144,6 +145,7 @@ LOG_CLASS(LLXUIParser);
 	static bool writeS32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF32Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeF64Value(Parser& parser, const void* val_ptr, name_stack_t&);
+	static bool writeVector3Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeColor4Value(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUIColorValue(Parser& parser, const void* val_ptr, name_stack_t&);
 	static bool writeUUIDValue(Parser& parser, const void* val_ptr, name_stack_t&);
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
index 74ed72ef97a9a030fd65bbf949002b5693af001f..5d3f9ac327be6352eeb877da19519ddc0dac443c 100644
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -46,11 +46,6 @@ LLAvatarNameCache::callback_connection_t LLAvatarNameCache::get(const LLUUID& ag
 	return connection;
 }
 
-bool LLAvatarNameCache::useDisplayNames()
-{
-	return false;
-}
-
 //
 // Stub implementation for LLCacheName
 //
@@ -106,14 +101,14 @@ LLStyle::Params::Params()
 
 namespace LLInitParam
 {
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color)
 	{}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock() 
+	void ParamValue<LLUIColor>::updateValueFromBlock() 
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -121,14 +116,14 @@ namespace LLInitParam
 		return false;
 	}
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp)
 	{}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -140,10 +135,10 @@ namespace LLInitParam
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
 	{}
 
 	
diff --git a/indra/llui/tests/llurlentry_test.cpp b/indra/llui/tests/llurlentry_test.cpp
index 8f0a48018fb26132f0ca1b5257a1110850dce4d3..c3f0e92cb071098476ac84d0c5ce306a1ea781d0 100644
--- a/indra/llui/tests/llurlentry_test.cpp
+++ b/indra/llui/tests/llurlentry_test.cpp
@@ -31,7 +31,7 @@
 #include "llurlentry_stub.cpp"
 #include "lltut.h"
 #include "../lluicolortable.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
 
 #include <boost/regex.hpp>
 
diff --git a/indra/llui/tests/llurlmatch_test.cpp b/indra/llui/tests/llurlmatch_test.cpp
index 963473c92ab0d2f18c7bcb47a9ff7a7f1a793cf5..55c1efefefd1c15ef9a5f06aad7a87ceb0cdeaf1 100644
--- a/indra/llui/tests/llurlmatch_test.cpp
+++ b/indra/llui/tests/llurlmatch_test.cpp
@@ -28,7 +28,7 @@
 #include "linden_common.h"
 
 #include "../llurlmatch.h"
-#include "../lluiimage.h"
+#include "../llrender/lluiimage.h"
 #include "lltut.h"
 
 // link seams
@@ -63,14 +63,14 @@ S32 LLUIImage::getHeight() const
 
 namespace LLInitParam
 {
-	ParamValue<LLUIColor, TypeValues<LLUIColor> >::ParamValue(const LLUIColor& color)
+	ParamValue<LLUIColor>::ParamValue(const LLUIColor& color)
 	:	super_t(color)
 	{}
 
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateValueFromBlock()
+	void ParamValue<LLUIColor>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIColor, TypeValues<LLUIColor> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIColor>::updateBlockFromValue(bool)
 	{}
 
 	bool ParamCompare<const LLFontGL*, false>::equals(const LLFontGL* a, const LLFontGL* b)
@@ -79,14 +79,14 @@ namespace LLInitParam
 	}
 
 
-	ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::ParamValue(const LLFontGL* fontp)
+	ParamValue<const LLFontGL*>::ParamValue(const LLFontGL* fontp)
 	:	super_t(fontp)
 	{}
 
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateValueFromBlock()
+	void ParamValue<const LLFontGL*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<const LLFontGL*, TypeValues<const LLFontGL*> >::updateBlockFromValue(bool)
+	void ParamValue<const LLFontGL*>::updateBlockFromValue(bool)
 	{}
 
 	void TypeValues<LLFontGL::HAlign>::declareValues()
@@ -98,10 +98,10 @@ namespace LLInitParam
 	void TypeValues<LLFontGL::ShadowType>::declareValues()
 	{}
 
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateValueFromBlock()
+	void ParamValue<LLUIImage*>::updateValueFromBlock()
 	{}
 	
-	void ParamValue<LLUIImage*, TypeValues<LLUIImage*> >::updateBlockFromValue(bool)
+	void ParamValue<LLUIImage*>::updateBlockFromValue(bool)
 	{}
 	
 	bool ParamCompare<LLUIImage*, false>::equals(
diff --git a/indra/llvfs/CMakeLists.txt b/indra/llvfs/CMakeLists.txt
index 3c68b279f7d8ca1cd795f53c42a378821251c532..67dce8c0737e7fda21ff4fb057451aeac2e1bc0f 100644
--- a/indra/llvfs/CMakeLists.txt
+++ b/indra/llvfs/CMakeLists.txt
@@ -8,6 +8,7 @@ include(UnixInstall)
 
 include_directories(
     ${LLCOMMON_INCLUDE_DIRS}
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
     )
 
 set(llvfs_SOURCE_FILES
@@ -44,12 +45,12 @@ if (LINUX)
   LIST(APPEND llvfs_SOURCE_FILES lldir_linux.cpp)
   LIST(APPEND llvfs_HEADER_FILES lldir_linux.h)
 
-  if (VIEWER AND INSTALL)
+  if (INSTALL)
     set_source_files_properties(lldir_linux.cpp
                                 PROPERTIES COMPILE_FLAGS
                                 "-DAPP_RO_DATA_DIR=\\\"${APP_SHARE_DIR}\\\""
                                 )
-  endif (VIEWER AND INSTALL)
+  endif (INSTALL)
 endif (LINUX)
 
 if (WINDOWS)
@@ -70,6 +71,7 @@ set(vfs_BOOST_LIBRARIES
     )
 
 target_link_libraries(llvfs
+    ${LLCOMMON_LIBRARIES}
     ${vfs_BOOST_LIBRARIES}
     )
 
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 5e5aeefba179653f1f9738b8c66fe34b66771cae..6899e9a44a3ff73702813ac8efdaa5fa0f8eec60 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -90,7 +90,8 @@ LLDir::LLDir()
 	mCAFile(""),
 	mTempDir(""),
 	mDirDelimiter("/"), // fallback to forward slash if not overridden
-	mLanguage("en")
+	mLanguage("en"),
+	mUserName("undefined")
 {
 }
 
@@ -346,6 +347,11 @@ const std::string &LLDir::getLLPluginDir() const
 	return mLLPluginDir;
 }
 
+const std::string &LLDir::getUserName() const
+{
+	return mUserName;
+}
+
 static std::string ELLPathToString(ELLPath location)
 {
 	typedef std::map<ELLPath, const char*> ELLPathMap;
@@ -814,6 +820,11 @@ void LLDir::setChatLogsDir(const std::string &path)
 	}
 }
 
+void LLDir::updatePerAccountChatLogsDir()
+{
+	mPerAccountChatLogsDir = add(getChatLogsDir(), mUserName);
+}
+
 void LLDir::setPerAccountChatLogsDir(const std::string &username)
 {
 	// if both first and last aren't set, assume we're grabbing the cached dir
@@ -824,13 +835,14 @@ void LLDir::setPerAccountChatLogsDir(const std::string &username)
 		std::string userlower(username);
 		LLStringUtil::toLower(userlower);
 		LLStringUtil::replaceChar(userlower, ' ', '_');
-		mPerAccountChatLogsDir = add(getChatLogsDir(), userlower);
+
+		mUserName = userlower;
+		updatePerAccountChatLogsDir();
 	}
 	else
 	{
 		llerrs << "NULL name for LLDir::setPerAccountChatLogsDir" << llendl;
 	}
-	
 }
 
 void LLDir::setSkinFolder(const std::string &skin_folder, const std::string& language)
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index 300ff1eef6a21bc1cce9af91c1356c291e9f207b..cc10ed5bbd02501f5da65037a4a8f735ab16404f 100644
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -104,6 +104,7 @@ class LLDir
 	const std::string &getUserSkinDir() const;		// User-specified skin folder with user modifications. e.g. c:\documents and settings\username\application data\second life\skins\curskin
 	const std::string getSkinBaseDir() const;		// folder that contains all installed skins (not user modifications). e.g. c:\program files\second life\skins
 	const std::string &getLLPluginDir() const;		// Directory containing plugins and plugin shell
+	const std::string &getUserName() const;
 
 	// Expanded filename
 	std::string getExpandedFilename(ELLPath location, const std::string &filename) const;
@@ -186,6 +187,7 @@ class LLDir
 	virtual std::string getSkinFolder() const;
 	virtual std::string getLanguage() const;
 	virtual bool setCacheDir(const std::string &path);
+	virtual void updatePerAccountChatLogsDir();
 
 	virtual void dumpCurrentDirectories();
 
@@ -243,6 +245,7 @@ class LLDir
 	std::vector<std::string> mSearchSkinDirs;
 	std::string mLanguage;              // Current viewer language
 	std::string mLLPluginDir;			// Location for plugins and plugin shell
+	std::string mUserName;				// Current user name
 };
 
 void dir_exists_or_crash(const std::string &dir_name);
diff --git a/indra/llvfs/llvfile.cpp b/indra/llvfs/llvfile.cpp
index ca749c5eafb8dbb57fe1d94d490fe4137d898007..03d2cc25e335bcd9eb75ce6c15aaf1a8a663d45f 100644
--- a/indra/llvfs/llvfile.cpp
+++ b/indra/llvfs/llvfile.cpp
@@ -32,6 +32,7 @@
 #include "llthread.h"
 #include "llstat.h"
 #include "llvfs.h"
+#include "llmemory.h"
 
 const S32 LLVFile::READ			= 0x00000001;
 const S32 LLVFile::WRITE		= 0x00000002;
@@ -134,13 +135,13 @@ U8* LLVFile::readFile(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, S
 		data = NULL;
 	}
 	else
-	{
-		data = new U8[file_size];
+	{		
+		data = (U8*) ll_aligned_malloc_16(file_size);
 		file.read(data, file_size);	/* Flawfinder: ignore */ 
 		
 		if (file.getLastBytesRead() != (S32)file_size)
 		{
-			delete[] data;
+			ll_aligned_free(data);
 			data = NULL;
 			file_size = 0;
 		}
diff --git a/indra/llwindow/CMakeLists.txt b/indra/llwindow/CMakeLists.txt
index 341bddfffdb81bc83a134ea3d7323a47feb7e6c3..ad010164eb15977f259dc2b8436f3fb1d901ba45 100644
--- a/indra/llwindow/CMakeLists.txt
+++ b/indra/llwindow/CMakeLists.txt
@@ -32,12 +32,17 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${DIRECTX_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llwindow_SOURCE_FILES
     llkeyboard.cpp
     llkeyboardheadless.cpp
     llwindowheadless.cpp
     llwindowcallbacks.cpp
+    llwindow.cpp
     )
 
 set(llwindow_HEADER_FILES
@@ -50,7 +55,6 @@ set(llwindow_HEADER_FILES
     )
 
 set(viewer_SOURCE_FILES
-    llwindow.cpp
     llmousehandler.cpp
     )
 
@@ -62,13 +66,43 @@ set(viewer_HEADER_FILES
 
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-if (LINUX AND VIEWER)
+if (LINUX)
   set(llwindow_LINK_LIBRARIES
+      ${LLCOMMON_LIBRARIES}
+      ${LLIMAGE_LIBRARIES}
+      ${LLMATH_LIBRARIES}
+      ${LLRENDER_LIBRARIES}
+      ${LLVFS_LIBRARIES}
+      ${LLWINDOW_LIBRARIES}
+      ${LLXML_LIBRARIES}
       ${UI_LIBRARIES}     # for GTK
       ${SDL_LIBRARY}
       fontconfig          # For FCInit and other FC* functions.
       )
-endif (LINUX AND VIEWER)
+
+  list(APPEND viewer_SOURCE_FILES 
+       llkeyboardsdl.cpp 
+       llwindowsdl.cpp
+       )
+  list(APPEND viewer_HEADER_FILES
+       llkeyboardsdl.h
+       llwindowsdl.h
+       )
+
+  if (BUILD_HEADLESS)
+    set(llwindowheadless_LINK_LIBRARIES
+        ${LLCOMMON_LIBRARIES}
+        ${LLIMAGE_LIBRARIES}
+        ${LLMATH_LIBRARIES}
+        ${LLRENDER_HEADLESS_LIBRARIES}
+        ${LLVFS_LIBRARIES}
+        ${LLWINDOW_HEADLESS_LIBRARIES}
+        ${LLXML_LIBRARIES}
+        fontconfig          # For FCInit and other FC* functions.
+        )
+  endif (BUILD_HEADLESS)
+
+endif (LINUX)
 
 if (DARWIN)
   list(APPEND llwindow_SOURCE_FILES
@@ -91,16 +125,6 @@ if (DARWIN)
       )
 endif (DARWIN)
 
-if (LINUX AND VIEWER)
-  list(APPEND viewer_SOURCE_FILES 
-       llkeyboardsdl.cpp 
-       llwindowsdl.cpp
-       )
-  list(APPEND viewer_HEADER_FILES
-       llkeyboardsdl.h
-       llwindowsdl.h
-       )
-endif (LINUX AND VIEWER)
 
 if (WINDOWS)
   list(APPEND llwindow_SOURCE_FILES
@@ -133,40 +157,41 @@ endif (SOLARIS)
 set_source_files_properties(${llwindow_HEADER_FILES}
                             PROPERTIES HEADER_FILE_ONLY TRUE)
 
-if (SERVER AND NOT WINDOWS AND NOT DARWIN)
-  set(server_SOURCE_FILES
+if (BUILD_HEADLESS)
+  set(llwindowheadless_SOURCE_FILES
        llwindowmesaheadless.cpp
+       llmousehandler.cpp
        )
-  set(server_HEADER_FILES
+  set(llwindowheadless_HEADER_FILES
        llwindowmesaheadless.h
+       llmousehandler.h
        )
-  copy_server_sources(
-      llwindow
-      )
-
-
-  set_source_files_properties(
-    ${server_SOURCE_FILES}
-    PROPERTIES
-    COMPILE_FLAGS "-DLL_MESA=1 -DLL_MESA_HEADLESS=1"
-    )
   add_library (llwindowheadless
     ${llwindow_SOURCE_FILES}
-    ${server_SOURCE_FILES}
+    ${llwindowheadless_SOURCE_FILES}
     )
-  target_link_libraries (llwindowheadless ${llwindow_LINK_LIBRARIES})
-endif (SERVER AND NOT WINDOWS AND NOT DARWIN)
+  set_property(TARGET llwindowheadless
+    PROPERTY COMPILE_DEFINITIONS LL_MESA=1 LL_MESA_HEADLESS=1
+    )
+  target_link_libraries (llwindowheadless ${llwindowheadless_LINK_LIBRARIES} dl)
+endif (BUILD_HEADLESS)
 
 if (llwindow_HEADER_FILES)
   list(APPEND llwindow_SOURCE_FILES ${llwindow_HEADER_FILES})
 endif (llwindow_HEADER_FILES)
-  list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
 
-if (VIEWER)
-  add_library (llwindow
-    ${llwindow_SOURCE_FILES}
-    ${viewer_SOURCE_FILES}
+list(APPEND viewer_SOURCE_FILES ${viewer_HEADER_FILES})
+
+add_library (llwindow
+  ${llwindow_SOURCE_FILES}
+  ${viewer_SOURCE_FILES}
+  )
+
+if (SDL_FOUND)
+  set_property(TARGET llwindow
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
     )
-  target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
-endif (VIEWER)
+endif (SDL_FOUND)
+
+target_link_libraries (llwindow ${llwindow_LINK_LIBRARIES})
 
diff --git a/indra/llwindow/GL/glh_extensions.h b/indra/llwindow/GL/glh_extensions.h
index d89d85930b6b6deaab89006580352cb3ed4d4123..554cb1731f27e20a4a1e4fbdc6d1e3971398f9e2 100644
--- a/indra/llwindow/GL/glh_extensions.h
+++ b/indra/llwindow/GL/glh_extensions.h
@@ -113,7 +113,7 @@ static const char* EatNonWhiteSpace(const char *str)
 int glh_init_extensions(const char *origReqExts)
 {
 	// Length of requested extensions string
-	unsigned reqExtsLen;
+	//unsigned reqExtsLen;
 	char *reqExts;
 	// Ptr for individual extensions within reqExts
 	char *reqExt;
@@ -155,8 +155,8 @@ int glh_init_extensions(const char *origReqExts)
 		return TRUE;
 	}
 	reqExts = strdup(origReqExts);
-	reqExtsLen = (S32)strlen(reqExts);
 	/*
+	reqExtsLen = (S32)strlen(reqExts);
 	if (NULL == gGLHExts.mUnsupportedExts)
 	{
 		gGLHExts.mUnsupportedExts = (char*)malloc(reqExtsLen + 1);
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index a15114cb9bc77a2fc62b2ba7be838d93e9c984a0..205466e9369255d8b0e0e29e1a73ceab07fcdc75 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -1636,35 +1636,53 @@ void check_vm_bloat()
 {
 #if LL_LINUX
 	// watch our own VM and RSS sizes, warn if we bloated rapidly
-	FILE *fp = fopen("/proc/self/stat", "r");
+	static const std::string STATS_FILE = "/proc/self/stat";
+	FILE *fp = fopen(STATS_FILE.c_str(), "r");
 	if (fp)
 	{
 		static long long last_vm_size = 0;
 		static long long last_rss_size = 0;
 		const long long significant_vm_difference = 250 * 1024*1024;
 		const long long significant_rss_difference = 50 * 1024*1024;
+		long long this_vm_size = 0;
+		long long this_rss_size = 0;
 
 		ssize_t res;
 		size_t dummy;
-		char *ptr;
+		char *ptr = NULL;
 		for (int i=0; i<22; ++i) // parse past the values we don't want
 		{
-			ptr = NULL;
 			res = getdelim(&ptr, &dummy, ' ', fp);
+			if (-1 == res)
+			{
+				llwarns << "Unable to parse " << STATS_FILE << llendl;
+				goto finally;
+			}
 			free(ptr);
+			ptr = NULL;
 		}
 		// 23rd space-delimited entry is vsize
-		ptr = NULL;
 		res = getdelim(&ptr, &dummy, ' ', fp);
 		llassert(ptr);
-		long long this_vm_size = atoll(ptr);
+		if (-1 == res)
+		{
+			llwarns << "Unable to parse " << STATS_FILE << llendl;
+			goto finally;
+		}
+		this_vm_size = atoll(ptr);
 		free(ptr);
-		// 24th space-delimited entry is RSS
 		ptr = NULL;
+		// 24th space-delimited entry is RSS
 		res = getdelim(&ptr, &dummy, ' ', fp);
 		llassert(ptr);
-		long long this_rss_size = getpagesize() * atoll(ptr);
+		if (-1 == res)
+		{
+			llwarns << "Unable to parse " << STATS_FILE << llendl;
+			goto finally;
+		}
+		this_rss_size = getpagesize() * atoll(ptr);
 		free(ptr);
+		ptr = NULL;
 
 		llinfos << "VM SIZE IS NOW " << (this_vm_size/(1024*1024)) << " MB, RSS SIZE IS NOW " << (this_rss_size/(1024*1024)) << " MB" << llendl;
 
@@ -1697,6 +1715,12 @@ void check_vm_bloat()
 		last_rss_size = this_rss_size;
 		last_vm_size = this_vm_size;
 
+finally:
+		if (NULL != ptr)
+		{
+			free(ptr);
+			ptr = NULL;
+		}
 		fclose(fp);
 	}
 #endif // LL_LINUX
diff --git a/indra/llxml/CMakeLists.txt b/indra/llxml/CMakeLists.txt
index beefcda3610204afbb05a7813ebc91af182df0b7..cf96f26a77a2c17e7b464f5591f15e46ad796770 100644
--- a/indra/llxml/CMakeLists.txt
+++ b/indra/llxml/CMakeLists.txt
@@ -13,6 +13,9 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(llxml_SOURCE_FILES
     llcontrol.cpp
@@ -39,9 +42,10 @@ list(APPEND llxml_SOURCE_FILES ${llxml_HEADER_FILES})
 add_library (llxml ${llxml_SOURCE_FILES})
 # Libraries on which this library depends, needed for Linux builds
 # Sort by high-level to low-level
-target_link_libraries( llxml
-    llvfs
-    llmath
+target_link_libraries(llxml
+    ${LLVFS_LIBRARIES}
+    ${LLMATH_LIBRARIES}
+    ${LLCOMMON_LIBRARIES}
     ${EXPAT_LIBRARIES}
     )
 
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 53d9380f4f85a6ee251e8e97b91b2adf561dc054..666c03e9fffc89295d0549544d0c3c18e9382104 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -850,12 +850,10 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		return 0;
 	}
 
-	S32 ret = LLSDSerialize::fromXML(settings, infile);
-
-	if (ret <= 0)
+	if (LLSDParser::PARSE_FAILURE == LLSDSerialize::fromXML(settings, infile))
 	{
 		infile.close();
-		llwarns << "Unable to open LLSD control file " << filename << ". Trying Legacy Method." << llendl;		
+		llwarns << "Unable to parse LLSD control file " << filename << ". Trying Legacy Method." << llendl;
 		return loadFromFileLegacy(filename, TRUE, TYPE_STRING);
 	}
 
diff --git a/indra/llxml/llxmlnode.cpp b/indra/llxml/llxmlnode.cpp
index b7752492192fd8bd4049ea1b643ba388318fc5d7..7aa2ce96067063174355c1536e1fa95191251f68 100644
--- a/indra/llxml/llxmlnode.cpp
+++ b/indra/llxml/llxmlnode.cpp
@@ -147,13 +147,15 @@ LLXMLNodePtr LLXMLNode::deepCopy()
 		for (LLXMLChildList::iterator iter = mChildren->map.begin();
 			 iter != mChildren->map.end(); ++iter)	
 		{
-			newnode->addChild(iter->second->deepCopy());
+			LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+			newnode->addChild(temp_ptr_for_gcc);
 		}
 	}
 	for (LLXMLAttribList::iterator iter = mAttributes.begin();
 		 iter != mAttributes.end(); ++iter)
 	{
-		newnode->addChild(iter->second->deepCopy());
+		LLXMLNodePtr temp_ptr_for_gcc(iter->second->deepCopy());
+		newnode->addChild(temp_ptr_for_gcc);
 	}
 
 	return newnode;
@@ -259,7 +261,7 @@ BOOL LLXMLNode::removeChild(LLXMLNode *target_child)
 	return FALSE;
 }
 
-void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
+void LLXMLNode::addChild(LLXMLNodePtr& new_child)
 {
 	if (new_child->mParent != NULL)
 	{
@@ -273,6 +275,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
 	new_child->mParent = this;
 	if (new_child->mIsAttribute)
 	{
+		LLXMLAttribList::iterator found_it = mAttributes.find(new_child->mName);
+		if (found_it != mAttributes.end())
+		{
+			removeChild(found_it->second);
+		}
 		mAttributes.insert(std::make_pair(new_child->mName, new_child));
 	}
 	else
@@ -285,49 +292,11 @@ void LLXMLNode::addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child)
 		}
 		mChildren->map.insert(std::make_pair(new_child->mName, new_child));
 
-		// if after_child is specified, it damn well better be in the list of children
-		// for this node. I'm not going to assert that, because it would be expensive,
-		// but don't specify that parameter if you didn't get the value for it from the
-		// list of children of this node!
-		if (after_child.isNull())
-		{
-			if (mChildren->tail != new_child)
-			{
-				mChildren->tail->mNext = new_child;
-				new_child->mPrev = mChildren->tail;
-				mChildren->tail = new_child;
-			}
-		}
-		// if after_child == parent, then put new_child at beginning
-		else if (after_child == this)
-		{
-			// add to front of list
-			new_child->mNext = mChildren->head;
-			if (mChildren->head)
-			{
-				mChildren->head->mPrev = new_child;
-				mChildren->head = new_child;
-			}
-			else // no children
-			{
-				mChildren->head = new_child;
-				mChildren->tail = new_child;
-			}
-		}
-		else
+		if (mChildren->tail != new_child)
 		{
-			if (after_child->mNext.notNull())
-			{
-				// if after_child was not the last item, fix up some pointers
-				after_child->mNext->mPrev = new_child;
-				new_child->mNext = after_child->mNext;
-			}
-			new_child->mPrev = after_child;
-			after_child->mNext = new_child;
-			if (mChildren->tail == after_child)
-			{
-				mChildren->tail = new_child;
-			}
+			mChildren->tail->mNext = new_child;
+			new_child->mPrev = mChildren->tail;
+			mChildren->tail = new_child;
 		}
 	}
 
@@ -343,8 +312,9 @@ LLXMLNodePtr LLXMLNode::createChild(const char* name, BOOL is_attribute)
 // virtual 
 LLXMLNodePtr LLXMLNode::createChild(LLStringTableEntry* name, BOOL is_attribute)
 {
-	LLXMLNode* ret = new LLXMLNode(name, is_attribute);
+	LLXMLNodePtr ret(new LLXMLNode(name, is_attribute));
 	ret->mID.clear();
+	
 	addChild(ret);
 	return ret;
 }
@@ -358,11 +328,12 @@ BOOL LLXMLNode::deleteChild(LLXMLNode *child)
 	return FALSE;
 }
 
-void LLXMLNode::setParent(LLXMLNodePtr new_parent)
+void LLXMLNode::setParent(LLXMLNodePtr& new_parent)
 {
 	if (new_parent.notNull())
 	{
-		new_parent->addChild(this);
+		LLXMLNodePtr this_ptr(this);
+		new_parent->addChild(this_ptr);
 	}
 	else
 	{
@@ -681,27 +652,6 @@ bool LLXMLNode::updateNode(
 	return TRUE;
 }
 
-
-// static 
-LLXMLNodePtr LLXMLNode::replaceNode(LLXMLNodePtr node, LLXMLNodePtr update_node)
-{	
-	if (!node || !update_node)
-	{
-		llwarns << "Node invalid" << llendl;
-		return node;
-	}
-	
-	LLXMLNodePtr cloned_node = update_node->deepCopy();
-	node->mParent->addChild(cloned_node, node);	// add after node
-	LLXMLNodePtr parent = node->mParent;
-	parent->removeChild(node);
-	parent->updateDefault();
-	
-	return cloned_node;
-}
-
-
-
 // static
 bool LLXMLNode::parseFile(const std::string& filename, LLXMLNodePtr& node, LLXMLNode* defaults_tree)
 {
@@ -1199,7 +1149,8 @@ void LLXMLNode::scrubToTree(LLXMLNode *tree)
 		std::vector<LLXMLNodePtr>::iterator itor3;
 		for (itor3=to_delete_list.begin(); itor3!=to_delete_list.end(); ++itor3)
 		{
-			(*itor3)->setParent(NULL);
+			LLXMLNodePtr ptr;
+			(*itor3)->setParent(ptr);
 		}
 	}
 }
@@ -2734,7 +2685,8 @@ void LLXMLNode::setName(LLStringTableEntry* name)
 	mName = name;
 	if (old_parent)
 	{
-		old_parent->addChild(this);
+		LLXMLNodePtr this_ptr(this);
+		old_parent->addChild(this_ptr);
 	}
 }
 
diff --git a/indra/llxml/llxmlnode.h b/indra/llxml/llxmlnode.h
index e3da7169e7e7e99c7463e7387095cfd6b34c20aa..ec486d7957eb8e030bb9769d5dd7cdc6f9af7f3f 100644
--- a/indra/llxml/llxmlnode.h
+++ b/indra/llxml/llxmlnode.h
@@ -127,8 +127,8 @@ class LLXMLNode : public LLThreadSafeRefCount
 	BOOL isNull();
 
 	BOOL deleteChild(LLXMLNode* child);
-    void addChild(LLXMLNodePtr new_child, LLXMLNodePtr after_child = LLXMLNodePtr(NULL)); 
-    void setParent(LLXMLNodePtr new_parent); // reparent if necessary
+    void addChild(LLXMLNodePtr& new_child); 
+    void setParent(LLXMLNodePtr& new_parent); // reparent if necessary
 
     // Serialization
 	static bool parseFile(
@@ -147,7 +147,6 @@ class LLXMLNode : public LLThreadSafeRefCount
 	static bool updateNode(
 		LLXMLNodePtr& node,
 		LLXMLNodePtr& update_node);
-	static LLXMLNodePtr replaceNode(LLXMLNodePtr node, LLXMLNodePtr replacement_node);
 	
 	static bool getLayeredXMLNode(LLXMLNodePtr& root, const std::vector<std::string>& paths);
 	
diff --git a/indra/lscript/lscript_compile/CMakeLists.txt b/indra/lscript/lscript_compile/CMakeLists.txt
index 3ed2892e0ed55ecca656b24ba15f04c22cdf7f9d..07662005b999ae39274f1ba6cd907870677244e0 100644
--- a/indra/lscript/lscript_compile/CMakeLists.txt
+++ b/indra/lscript/lscript_compile/CMakeLists.txt
@@ -45,6 +45,9 @@ include_directories(
     ${LLPRIMITIVE_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(lscript_generated_SOURCE_FILES
     indra.l.cpp
@@ -95,6 +98,7 @@ add_custom_command(
       ${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
     COMMAND ${FLEX}
     ARGS
+      -P indra_
       -o${CMAKE_CURRENT_BINARY_DIR}/indra.l.cpp
       ${CMAKE_CURRENT_SOURCE_DIR}/indra.l
     DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/indra.l
@@ -112,8 +116,10 @@ if (WINDOWS)
         ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_BINARY_DIR}/indra.y.hpp
       COMMAND ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
+      ARGS
         ${BISON} ${M4_PATH}
-        ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
+        -p indra_
+        -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/indra.y
       DEPENDS
         ${CMAKE_CURRENT_SOURCE_DIR}/bison.bat
@@ -128,6 +134,7 @@ else (WINDOWS)
       COMMAND
         ${BISON}
       ARGS
+        -p indra_
         -d -o ${CMAKE_CURRENT_BINARY_DIR}/indra.y.cpp
         ${CMAKE_CURRENT_SOURCE_DIR}/indra.y
       DEPENDS
diff --git a/indra/lscript/lscript_compile/bison.bat b/indra/lscript/lscript_compile/bison.bat
index 0baff4e5ef9c4bc6d98b36fd332d238542f29510..d40997225e01d8d744871d55002881587b966dbe 100644
--- a/indra/lscript/lscript_compile/bison.bat
+++ b/indra/lscript/lscript_compile/bison.bat
@@ -2,10 +2,11 @@
 @REM find m4, even if neither program is present in PATH.
 
 @set bison=%1
-set M4PATH=%2
+shift
+set M4PATH=%1
+shift
 set M4=
-@set output=%3
-@set input=%4
 
 set PATH=%M4PATH%;%PATH%
-%bison% -d -o %output% %input%
+@REM %* does not work with shift...
+%bison% %1 %2 %3 %4 %5 %6 %7 %8 %9
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 96b7e57e9781bd3cb766c96418a88547c7685667..b2c49083cb267398b1c32ce636317b40504b84a8 100644
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -56,6 +56,29 @@ void parse_string();
 
 #define ECHO do { } while (0)
 
+#define yyparse indra_parse
+#define yyerror indra_error
+#define yylval indra_lval
+#define yy_create_buffer indra__create_buffer
+#define yy_delete_buffer indra__delete_buffer
+#define yy_flex_debug indra__flex_debug
+#define yy_init_buffer indra__init_buffer
+#define yy_flush_buffer indra__flush_buffer
+#define yy_load_buffer_state indra__load_buffer_state
+#define yy_switch_to_buffer indra__switch_to_buffer
+#define yyin indra_in
+#define yyleng indra_leng
+#define yylex indra_lex
+#define yylineno indra_lineno
+#define yyout indra_out
+#define yyrestart indra_restart
+#define yytext indra_text
+#define yywrap indra_wrap
+#define yyalloc indra_alloc
+#define yyrealloc indra_realloc
+#define yyfree indra_free
+
+
 #if defined(__cplusplus)
 extern "C" { int yylex( void ); }
 extern "C" { int yyparse( void ); }
diff --git a/indra/lscript/lscript_execute/CMakeLists.txt b/indra/lscript/lscript_execute/CMakeLists.txt
index 3a16ffdc0105a5ec01dcfb3b95714604fc33f68e..49605982a825fbe7347a42944421b1b9d4243752 100644
--- a/indra/lscript/lscript_execute/CMakeLists.txt
+++ b/indra/lscript/lscript_execute/CMakeLists.txt
@@ -10,6 +10,9 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(lscript_execute_SOURCE_FILES
     llscriptresource.cpp
diff --git a/indra/lscript/lscript_execute/lscript_execute.cpp b/indra/lscript/lscript_execute/lscript_execute.cpp
index d79e9f8bde496797dd3a2a6de2073d2b90df9fae..b12d2e4a1693bf2b9dff36e9df6c3d3315ffa535 100644
--- a/indra/lscript/lscript_execute/lscript_execute.cpp
+++ b/indra/lscript/lscript_execute/lscript_execute.cpp
@@ -806,16 +806,7 @@ void LLScriptExecute::runInstructions(BOOL b_print, const LLUUID &id,
 	//  is there a fault?
 	//	if yes, print out message and exit
 	S32 value = getVersion();
-	S32 major_version = 0;
-	if (value == LSL2_VERSION1_END_NUMBER)
-	{
-		major_version = 1;
-	}
-	else if (value == LSL2_VERSION_NUMBER)
-	{
-		major_version = 2;
-	}
-	else
+	if ( (value != LSL2_VERSION1_END_NUMBER) && (value != LSL2_VERSION_NUMBER) )
 	{
 		setFault(LSRF_VERSION_MISMATCH);
 	}
diff --git a/indra/lscript/lscript_execute/lscript_readlso.cpp b/indra/lscript/lscript_execute/lscript_readlso.cpp
index 35caa41ae18be324696e53d3985ab910d9d890fa..8b41cb5a721c47eab99734e57d1363a14ce02392 100644
--- a/indra/lscript/lscript_execute/lscript_readlso.cpp
+++ b/indra/lscript/lscript_execute/lscript_readlso.cpp
@@ -123,7 +123,7 @@ void LLScriptLSOParse::printRegisters(LLFILE *fp)
 void LLScriptLSOParse::printGlobals(LLFILE *fp)
 {
 	// print out registers first
-	S32				offset, varoffset;
+	S32				varoffset;
 	S32				ivalue;
 	F32				fpvalue;
 	LLVector3		vvalue;
@@ -144,7 +144,7 @@ void LLScriptLSOParse::printGlobals(LLFILE *fp)
 
 		// get offset to skip past name
 		varoffset = global_v_offset;
-		offset = bytestream2integer(mRawData, global_v_offset);
+		bytestream2integer(mRawData, global_v_offset);
 		
 		// get typeexport
 		type = *(mRawData + global_v_offset++);
@@ -262,8 +262,6 @@ void LLScriptLSOParse::printGlobalFunctions(LLFILE *fp)
 		fprintf(fp, "[Function #%d] [0x%X] %s\n", function_number, orig_function_offset, name);
 		fprintf(fp, "\tReturn Type: %s\n", LSCRIPTTypeNames[type]);
 		type = *(mRawData + function_offset++);
-		S32 params;
-		params = 0;
 		S32 pcount = 0;
 		while (type)
 		{
@@ -347,7 +345,6 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
 				read_ahead = event_jump_table;
 
 				S32 temp_end;
-				S32 dummy;
 
 				opcode_end = worst_case_opcode_end;
 
@@ -356,7 +353,7 @@ void LLScriptLSOParse::printStates(LLFILE *fp)
 					if (event_handlers & LSCRIPTStateBitField[k])
 					{
 						temp_end = bytestream2integer(mRawData, read_ahead);
-						dummy = bytestream2integer(mRawData, read_ahead);
+						bytestream2integer(mRawData, read_ahead);
 						if (  (temp_end < opcode_end)
 							&&(temp_end > event_offset))
 						{
diff --git a/indra/lscript/lscript_library/CMakeLists.txt b/indra/lscript/lscript_library/CMakeLists.txt
index f6bc67a994a3ec83cd4309839602f4c3ba3380b4..5af850c41bc2df07b7b125fd0a5020d141cc6539 100644
--- a/indra/lscript/lscript_library/CMakeLists.txt
+++ b/indra/lscript/lscript_library/CMakeLists.txt
@@ -28,5 +28,8 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LSCRIPT_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 add_library (lscript_library ${lscript_library_SOURCE_FILES})
diff --git a/indra/mac_crash_logger/CMakeLists.txt b/indra/mac_crash_logger/CMakeLists.txt
index 3906a3bb8c802dbbc93ff4bdb9bbfc05d926fead..c59645bd70e45b7d3d9a5fdbcbea3de6a7727821 100644
--- a/indra/mac_crash_logger/CMakeLists.txt
+++ b/indra/mac_crash_logger/CMakeLists.txt
@@ -19,6 +19,10 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(mac_crash_logger_SOURCE_FILES
     mac_crash_logger.cpp
diff --git a/indra/mac_updater/CMakeLists.txt b/indra/mac_updater/CMakeLists.txt
index 00dcedecaa90560272fabefa6d52e599db9aaff9..a644984e58f2618755a362f15170ada1a9584b37 100644
--- a/indra/mac_updater/CMakeLists.txt
+++ b/indra/mac_updater/CMakeLists.txt
@@ -7,6 +7,7 @@ include(OpenSSL)
 include(CURL)
 include(CARes)
 include(LLCommon)
+include(LLMessage)
 include(LLVFS)
 include(Linking)
 
@@ -52,6 +53,7 @@ set_target_properties(mac-updater
   )
 
 target_link_libraries(mac-updater
+    ${LLMESSAGE_LIBRARIES}
     ${LLVFS_LIBRARIES}
     ${OPENSSL_LIBRARIES}
     ${CRYPTO_LIBRARIES}
diff --git a/indra/media_plugins/base/CMakeLists.txt b/indra/media_plugins/base/CMakeLists.txt
index 3ad94b0c647bf4e4fb98a40437eaa03c9b8101ec..7367b9e5e654911c75a0bf8a9fca789a1c260378 100644
--- a/indra/media_plugins/base/CMakeLists.txt
+++ b/indra/media_plugins/base/CMakeLists.txt
@@ -11,7 +11,7 @@ include(LLRender)
 include(LLWindow)
 include(Linking)
 include(PluginAPI)
-include(FindOpenGL)
+include(OpenGL)
 
 include_directories(
     ${LLPLUGIN_INCLUDE_DIRS}
@@ -21,6 +21,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_base
diff --git a/indra/media_plugins/example/CMakeLists.txt b/indra/media_plugins/example/CMakeLists.txt
index 54dc5de1ea4e38ae55b81c5432584cb297d63ec3..171645ef0467e068197fd9df71dde2745235971e 100644
--- a/indra/media_plugins/example/CMakeLists.txt
+++ b/indra/media_plugins/example/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 
 include(ExamplePlugin)
 
@@ -25,6 +25,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_example
diff --git a/indra/media_plugins/gstreamer010/CMakeLists.txt b/indra/media_plugins/gstreamer010/CMakeLists.txt
index 5786bd1e25f474601707a7e56b4f2f34daf427e7..447f6e06895ec7d5cbf69ab85bd03513664e178d 100644
--- a/indra/media_plugins/gstreamer010/CMakeLists.txt
+++ b/indra/media_plugins/gstreamer010/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 
 include(GStreamer010Plugin)
 
@@ -27,6 +27,9 @@ include_directories(
     ${GSTREAMER010_INCLUDE_DIRS}
     ${GSTREAMER010_PLUGINS_BASE_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 ### media_plugin_gstreamer010
 
diff --git a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
index cdb7f4faeb7e04380f28021037538ff44b9ac956..932aaffa1b9f79f3cc0b416c89a67bccc551894d 100644
--- a/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
+++ b/indra/media_plugins/gstreamer010/llmediaimplgstreamervidplug.cpp
@@ -278,10 +278,9 @@ gst_slvideo_set_caps (GstBaseSink * bsink, GstCaps * caps)
 static gboolean
 gst_slvideo_start (GstBaseSink * bsink)
 {
-	GstSLVideo *slvideo;
 	gboolean ret = TRUE;
 	
-	slvideo = GST_SLVIDEO(bsink);
+	GST_SLVIDEO(bsink);
 
 	return ret;
 }
diff --git a/indra/media_plugins/quicktime/CMakeLists.txt b/indra/media_plugins/quicktime/CMakeLists.txt
index f0b8f0d16706f5b491d783b45559b0cd9d8d8a31..58391007fff486a814a3ffe9fee3da1cd98e8489 100644
--- a/indra/media_plugins/quicktime/CMakeLists.txt
+++ b/indra/media_plugins/quicktime/CMakeLists.txt
@@ -12,7 +12,7 @@ include(LLWindow)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 include(QuickTimePlugin)
 
 include_directories(
@@ -24,6 +24,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/media_plugins/webkit/CMakeLists.txt b/indra/media_plugins/webkit/CMakeLists.txt
index b36291f0e8686d771c6b6edf4f40eaa7e94518b1..0c1c3d800e1646aedf25caf4ad87083beef9b71b 100644
--- a/indra/media_plugins/webkit/CMakeLists.txt
+++ b/indra/media_plugins/webkit/CMakeLists.txt
@@ -13,7 +13,7 @@ include(UI)
 include(Linking)
 include(PluginAPI)
 include(MediaPluginBase)
-include(FindOpenGL)
+include(OpenGL)
 include(PulseAudio)
 
 include(WebKitLibPlugin)
@@ -29,6 +29,9 @@ include_directories(
     ${LLWINDOW_INCLUDE_DIRS}
     ${LLQTWEBKIT_INCLUDE_DIR}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 
 ### media_plugin_webkit
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 3cea13849fa587feaa719a9c0fb0424b03de82bf..fae02c0b30187cdcb58665dfc8344da6d2b293dc 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -12,7 +12,7 @@ include(DragDrop)
 include(EXPAT)
 include(FMODEX)
 include(OPENAL)
-include(FindOpenGL)
+include(OpenGL)
 include(Hunspell)
 include(JsonCpp)
 include(LLAudio)
@@ -46,6 +46,7 @@ include(LLLogin)
 include(VisualLeakDetector)
 include(GLOD)
 include(CMakeCopyIfDifferent)
+include(LLAppearance)
 
 if (NOT HAVOK_TPV)
    # When using HAVOK_TPV, the library is precompiled, so no need for this
@@ -70,7 +71,6 @@ include_directories(
     ${LLINVENTORY_INCLUDE_DIRS}
     ${LLMATH_INCLUDE_DIRS}
     ${LLMESSAGE_INCLUDE_DIRS}
-    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     ${LLPLUGIN_INCLUDE_DIRS}
     ${LLPRIMITIVE_INCLUDE_DIRS}
     ${LLRENDER_INCLUDE_DIRS}
@@ -86,6 +86,13 @@ include_directories(
     ${LIBS_PREBUILD_DIR}/include/hunspell
     ${OPENAL_LIB_INCLUDE_DIRS}
     ${LIBS_PREBUILT_DIR}/include/collada/1.4
+    ${LLAPPEARANCE_INCLUDE_DIRS}
+    )
+
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    ${LLPHYSICSEXTENSIONS_INCLUDE_DIRS}
     )
 
 set(viewer_SOURCE_FILES
@@ -117,12 +124,13 @@ set(viewer_SOURCE_FILES
     llavatarlist.cpp
     llavatarlistitem.cpp
     llavatarpropertiesprocessor.cpp
+    llblockedlistitem.cpp
+    llblocklist.cpp
     llbox.cpp
     llbreadcrumbview.cpp
     llbrowsernotification.cpp
     llbuycurrencyhtml.cpp
     llcallbacklist.cpp
-    llcallfloater.cpp
     llcallingcard.cpp
     llcapabilitylistener.cpp
     llcaphttpsender.cpp
@@ -140,16 +148,24 @@ set(viewer_SOURCE_FILES
     llcommanddispatcherlistener.cpp
     llcommandhandler.cpp
     llcommandlineparser.cpp
+    llcommunicationchannel.cpp
     llcompilequeue.cpp
     llconfirmationmanager.cpp
+    llconversationlog.cpp
+    llconversationloglist.cpp
+    llconversationloglistitem.cpp
+    llconversationmodel.cpp
+    llconversationview.cpp
     llcurrencyuimanager.cpp
     llcylinder.cpp
     lldateutil.cpp
     lldaycyclemanager.cpp
     lldebugmessagebox.cpp
     lldebugview.cpp
+    lldeferredsounds.cpp
     lldelayedgestureerror.cpp
     lldirpicker.cpp
+    lldonotdisturbnotificationstorage.cpp
     lldndbutton.cpp
     lldrawable.cpp
     lldrawpool.cpp
@@ -163,7 +179,6 @@ set(viewer_SOURCE_FILES
     lldrawpooltree.cpp
     lldrawpoolwater.cpp
     lldrawpoolwlsky.cpp
-    lldriverparam.cpp
     lldynamictexture.cpp
     llemote.cpp
     llenvmanager.cpp
@@ -197,7 +212,10 @@ set(viewer_SOURCE_FILES
     llfloaterbuycurrencyhtml.cpp
     llfloaterbuyland.cpp
     llfloatercamera.cpp
+    llfloaterchatvoicevolume.cpp
     llfloatercolorpicker.cpp
+    llfloaterconversationlog.cpp
+    llfloaterconversationpreview.cpp
     llfloaterdeleteenvpreset.cpp
     llfloaterdestinations.cpp
     llfloaterdisplayname.cpp
@@ -265,13 +283,13 @@ set(viewer_SOURCE_FILES
     llfloateruipreview.cpp
     llfloaterurlentry.cpp
     llfloatervoiceeffect.cpp
+    llfloatervoicevolume.cpp
     llfloaterwebcontent.cpp
     llfloaterwebprofile.cpp
     llfloaterwhitelistentry.cpp
     llfloaterwindowsize.cpp
     llfloaterworldmap.cpp
-    llfolderview.cpp
-    llfolderviewitem.cpp
+    llfolderviewmodelinventory.cpp
     llfollowcam.cpp
     llfriendcard.cpp
     llgesturelistener.cpp
@@ -297,8 +315,9 @@ set(viewer_SOURCE_FILES
     llhudrender.cpp
     llhudtext.cpp
     llhudview.cpp
-    llimfloater.cpp
-    llimfloatercontainer.cpp
+    llfloaterimsessiontab.cpp
+    llfloaterimsession.cpp
+    llfloaterimcontainer.cpp
     llimhandler.cpp
     llimview.cpp
     llinspect.cpp
@@ -324,7 +343,6 @@ set(viewer_SOURCE_FILES
     lllistcontextmenu.cpp
     lllistview.cpp
     lllocalbitmaps.cpp
-    lllocaltextureobject.cpp
     lllocationhistory.cpp
     lllocationinputctrl.cpp
     lllogchat.cpp
@@ -350,10 +368,9 @@ set(viewer_SOURCE_FILES
     llnameeditor.cpp
     llnamelistctrl.cpp
     llnavigationbar.cpp
-    llnearbychat.cpp
-    llnearbychatbar.cpp
-    llnearbychathandler.cpp
-    llnearbychatbarlistener.cpp
+    llfloaterimnearbychat.cpp
+    llfloaterimnearbychathandler.cpp
+    llfloaterimnearbychatlistener.cpp
     llnetmap.cpp
     llnotificationalerthandler.cpp
     llnotificationgrouphandler.cpp
@@ -383,7 +400,6 @@ set(viewer_SOURCE_FILES
     llpanelgroupnotices.cpp
     llpanelgrouproles.cpp
     llpanelhome.cpp
-    llpanelimcontrolpanel.cpp
     llpanelland.cpp
     llpanellandaudio.cpp
     llpanellandmarkinfo.cpp
@@ -394,7 +410,6 @@ set(viewer_SOURCE_FILES
     llpanelmaininventory.cpp
     llpanelmarketplaceinbox.cpp
     llpanelmarketplaceinboxinventory.cpp
-    llpanelmarketplaceoutboxinventory.cpp
     llpanelmediasettingsgeneral.cpp
     llpanelmediasettingspermissions.cpp
     llpanelmediasettingssecurity.cpp
@@ -444,13 +459,14 @@ set(viewer_SOURCE_FILES
     llpathfindingobject.cpp
     llpathfindingobjectlist.cpp
     llpathfindingpathtool.cpp
+    llpersistentnotificationstorage.cpp
     llphysicsmotion.cpp
     llphysicsshapebuilderutil.cpp
+    llpipelinelistener.cpp
     llplacesinventorybridge.cpp
     llplacesinventorypanel.cpp
+    llplacesfolderview.cpp
     llpopupview.cpp
-    llpolymesh.cpp
-    llpolymorph.cpp
     llpostcard.cpp
     llpreview.cpp
     llpreviewanim.cpp
@@ -501,9 +517,6 @@ set(viewer_SOURCE_FILES
     llsyswellwindow.cpp
     llteleporthistory.cpp
     llteleporthistorystorage.cpp
-    lltexglobalcolor.cpp
-    lltexlayer.cpp
-    lltexlayerparams.cpp
     lltextureatlas.cpp
     lltextureatlasmanager.cpp
     lltexturecache.cpp
@@ -601,18 +614,18 @@ set(viewer_SOURCE_FILES
     llviewershadermgr.cpp
     llviewerstats.cpp
     llviewerstatsrecorder.cpp
+    llviewertexlayer.cpp
     llviewertexteditor.cpp
     llviewertexture.cpp
     llviewertextureanim.cpp
     llviewertexturelist.cpp
     llviewerthrottle.cpp
-    llviewervisualparam.cpp
+    llviewerwearable.cpp
     llviewerwindow.cpp
     llviewerwindowlistener.cpp
     llvlcomposition.cpp
     llvlmanager.cpp
     llvoavatar.cpp
-    llvoavatardefines.cpp
     llvoavatarself.cpp
     llvocache.cpp
     llvograss.cpp
@@ -633,10 +646,8 @@ set(viewer_SOURCE_FILES
     llwatchdog.cpp
     llwaterparammanager.cpp
     llwaterparamset.cpp
-    llwearable.cpp
     llwearableitemslist.cpp
     llwearablelist.cpp
-    llwearabletype.cpp
     llweb.cpp
     llwebprofile.cpp
     llwebsharing.cpp
@@ -693,11 +704,12 @@ set(viewer_HEADER_FILES
     llavatarlist.h
     llavatarlistitem.h
     llavatarpropertiesprocessor.h
+    llblockedlistitem.h
+    llblocklist.h
     llbox.h
     llbreadcrumbview.h
     llbuycurrencyhtml.h
     llcallbacklist.h
-    llcallfloater.h
     llcallingcard.h
     llcapabilitylistener.h
     llcapabilityprovider.h
@@ -716,16 +728,24 @@ set(viewer_HEADER_FILES
     llcommanddispatcherlistener.h
     llcommandhandler.h
     llcommandlineparser.h
+    llcommunicationchannel.h
     llcompilequeue.h
     llconfirmationmanager.h
+    llconversationlog.h
+    llconversationloglist.h
+    llconversationloglistitem.h
+    llconversationmodel.h
+    llconversationview.h
     llcurrencyuimanager.h
     llcylinder.h
     lldateutil.h
     lldaycyclemanager.h
     lldebugmessagebox.h
     lldebugview.h
+    lldeferredsounds.h
     lldelayedgestureerror.h
     lldirpicker.h
+    lldonotdisturbnotificationstorage.h
     lldndbutton.h
     lldrawable.h
     lldrawpool.h
@@ -739,7 +759,6 @@ set(viewer_HEADER_FILES
     lldrawpooltree.h
     lldrawpoolwater.h
     lldrawpoolwlsky.h
-    lldriverparam.h
     lldynamictexture.h
     llemote.h
     llenvmanager.h
@@ -773,7 +792,10 @@ set(viewer_HEADER_FILES
     llfloaterbuycurrencyhtml.h
     llfloaterbuyland.h
     llfloatercamera.h
+    llfloaterchatvoicevolume.h
     llfloatercolorpicker.h
+    llfloaterconversationlog.h
+    llfloaterconversationpreview.h
     llfloaterdeleteenvpreset.h
     llfloaterdestinations.h
     llfloaterdisplayname.h
@@ -841,14 +863,13 @@ set(viewer_HEADER_FILES
     llfloateruipreview.h
     llfloaterurlentry.h
     llfloatervoiceeffect.h
+    llfloatervoicevolume.h
     llfloaterwebcontent.h
     llfloaterwebprofile.h
     llfloaterwhitelistentry.h
     llfloaterwindowsize.h
     llfloaterworldmap.h
-    llfolderview.h
-    llfoldervieweventlistener.h
-    llfolderviewitem.h
+    llfolderviewmodelinventory.h
     llfollowcam.h
     llfriendcard.h
     llgesturelistener.h
@@ -873,8 +894,9 @@ set(viewer_HEADER_FILES
     llhudrender.h
     llhudtext.h
     llhudview.h
-    llimfloater.h
-    llimfloatercontainer.h
+    llfloaterimsessiontab.h
+    llfloaterimsession.h
+    llfloaterimcontainer.h
     llimview.h
     llinspect.h
     llinspectavatar.h
@@ -900,7 +922,6 @@ set(viewer_HEADER_FILES
     lllistcontextmenu.h
     lllistview.h
     lllocalbitmaps.h
-    lllocaltextureobject.h
     lllocationhistory.h
     lllocationinputctrl.h
     lllogchat.h
@@ -926,10 +947,9 @@ set(viewer_HEADER_FILES
     llnameeditor.h
     llnamelistctrl.h
     llnavigationbar.h
-    llnearbychat.h
-    llnearbychatbar.h
-    llnearbychathandler.h
-    llnearbychatbarlistener.h
+    llfloaterimnearbychat.h
+    llfloaterimnearbychathandler.h
+    llfloaterimnearbychatlistener.h
     llnetmap.h
     llnotificationhandler.h
     llnotificationmanager.h
@@ -953,7 +973,6 @@ set(viewer_HEADER_FILES
     llpanelgroupnotices.h
     llpanelgrouproles.h
     llpanelhome.h
-    llpanelimcontrolpanel.h
     llpanelland.h
     llpanellandaudio.h
     llpanellandmarkinfo.h
@@ -964,7 +983,6 @@ set(viewer_HEADER_FILES
     llpanelmaininventory.h
     llpanelmarketplaceinbox.h
     llpanelmarketplaceinboxinventory.h
-    llpanelmarketplaceoutboxinventory.h
     llpanelmediasettingsgeneral.h
     llpanelmediasettingspermissions.h
     llpanelmediasettingssecurity.h
@@ -1009,12 +1027,13 @@ set(viewer_HEADER_FILES
     llpathfindingobject.h
     llpathfindingobjectlist.h
     llpathfindingpathtool.h
+    llpersistentnotificationstorage.h
     llphysicsmotion.h
     llphysicsshapebuilderutil.h
+    llpipelinelistener.h
     llplacesinventorybridge.h
     llplacesinventorypanel.h
-    llpolymesh.h
-    llpolymorph.h
+    llplacesfolderview.h
     llpopupview.h
     llpostcard.h
     llpreview.h
@@ -1068,9 +1087,6 @@ set(viewer_HEADER_FILES
     lltable.h
     llteleporthistory.h
     llteleporthistorystorage.h
-    lltexglobalcolor.h
-    lltexlayer.h
-    lltexlayerparams.h
     lltextureatlas.h
     lltextureatlasmanager.h
     lltexturecache.h
@@ -1169,18 +1185,18 @@ set(viewer_HEADER_FILES
     llviewershadermgr.h
     llviewerstats.h
     llviewerstatsrecorder.h
+    llviewertexlayer.h
     llviewertexteditor.h
     llviewertexture.h
     llviewertextureanim.h
     llviewertexturelist.h
     llviewerthrottle.h
-    llviewervisualparam.h
+    llviewerwearable.h
     llviewerwindow.h
     llviewerwindowlistener.h
     llvlcomposition.h
     llvlmanager.h
     llvoavatar.h
-    llvoavatardefines.h
     llvoavatarself.h
     llvocache.h
     llvograss.h
@@ -1201,10 +1217,8 @@ set(viewer_HEADER_FILES
     llwatchdog.h
     llwaterparammanager.h
     llwaterparamset.h
-    llwearable.h
     llwearableitemslist.h
     llwearablelist.h
-    llwearabletype.h
     llweb.h
     llwebprofile.h
     llwebsharing.h
@@ -1542,6 +1556,12 @@ add_executable(${VIEWER_BINARY_NAME}
     ${viewer_SOURCE_FILES}
     )
 
+if (SDL_FOUND)
+  set_property(TARGET ${VIEWER_BINARY_NAME}
+    PROPERTY COMPILE_DEFINITIONS LL_SDL=1
+    )
+endif (SDL_FOUND)
+
 # add package files
 file(GLOB EVENT_HOST_SCRIPT_GLOB_LIST
      ${CMAKE_CURRENT_SOURCE_DIR}/../viewer_components/*.py)
@@ -1832,19 +1852,9 @@ target_link_libraries(${VIEWER_BINARY_NAME}
     ${LLPHYSICS_LIBRARIES}
     ${LLPHYSICSEXTENSIONS_LIBRARIES}
     ${TCMALLOC_LIBRARIES}
+    ${LLAPPEARANCE_LIBRARIES}
     )
 
-if (USE_KDU)
-    target_link_libraries(${VIEWER_BINARY_NAME}
-        ${LLKDU_LIBRARIES}
-        ${KDU_LIBRARY}
-        )
-else (USE_KDU)
-    target_link_libraries(${VIEWER_BINARY_NAME}
-        ${LLIMAGEJ2COJ_LIBRARIES}
-        )
-endif (USE_KDU)
-
 build_version(viewer)
 
 set(ARTWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR} CACHE PATH
@@ -2063,6 +2073,15 @@ if (LL_TESTS)
     llworldmipmap.cpp
   )
 
+  set_source_files_properties(
+    llworldmap.cpp
+    llworldmipmap.cpp
+    PROPERTIES
+    LL_TEST_ADDITIONAL_SOURCE_FILES 
+    tests/llviewertexture_stub.cpp
+    #llviewertexturelist.cpp
+  )
+
   set_source_files_properties(
     lltranslate.cpp
     PROPERTIES
diff --git a/indra/newview/English.lproj/InfoPlist.strings b/indra/newview/English.lproj/InfoPlist.strings
index 5c7cacedec00fd61740b972f0c2095deddaf3ece..1802e14703520d12ca79c529f217af4eb6a094c8 100644
--- a/indra/newview/English.lproj/InfoPlist.strings
+++ b/indra/newview/English.lproj/InfoPlist.strings
@@ -2,6 +2,6 @@
 
 CFBundleName = "Second Life";
 
-CFBundleShortVersionString = "Second Life version 2.1.0.13828";
-CFBundleGetInfoString = "Second Life version 2.1.0.13828, Copyright 2004-2009 Linden Research, Inc.";
+CFBundleShortVersionString = "Second Life version 3.4.1.264760";
+CFBundleGetInfoString = "Second Life version 3.4.1.264760, Copyright 2004-2009 Linden Research, Inc.";
 
diff --git a/indra/newview/Info-SecondLife.plist b/indra/newview/Info-SecondLife.plist
index f7b11b217c928cd41a89fa6826256158f9972e34..035d6cbe6cd423b0ef9e65cba74ec728dfe313e3 100644
--- a/indra/newview/Info-SecondLife.plist
+++ b/indra/newview/Info-SecondLife.plist
@@ -60,7 +60,7 @@
 		</dict>
 	</array>
 	<key>CFBundleVersion</key>
-	<string>2.1.0.13828</string>
+	<string>3.4.1.264760</string>
 	<key>CSResourcesFileMapped</key>
 	<true/>
 </dict>
diff --git a/indra/newview/app_settings/commands.xml b/indra/newview/app_settings/commands.xml
index 73df064ab29026cf8a2ef95bf0928e3157de7c58..4659673333b945cd68e064b9b63c5de1d8b3a419 100644
--- a/indra/newview/app_settings/commands.xml
+++ b/indra/newview/app_settings/commands.xml
@@ -44,13 +44,14 @@
            />
   <command name="chat"
            available_in_toybox="true"
+		   is_flashing_allowed="true"
            icon="Command_Chat_Icon"
            label_ref="Command_Chat_Label"
-           tooltip_ref="Command_Chat_Tooltip"
+           tooltip_ref="Command_Conversations_Tooltip"
            execute_function="Floater.ToggleOrBringToFront"
-           execute_parameters="chat_bar"
+           execute_parameters="im_container"
            is_running_function="Floater.IsOpen"
-           is_running_parameters="chat_bar"
+           is_running_parameters="im_container"
            />
   <command name="compass"
            available_in_toybox="false"
@@ -239,14 +240,4 @@
            is_running_function="Floater.IsOpen"
            is_running_parameters="camera"
            />
-  <command name="voice"
-           available_in_toybox="true"
-           icon="Command_Voice_Icon"
-           label_ref="Command_Voice_Label"
-           tooltip_ref="Command_Voice_Tooltip"
-           execute_function="Floater.ToggleOrBringToFront"
-           execute_parameters="voice_controls"
-           is_running_function="Floater.IsOpen"
-           is_running_parameters="voice_controls"
-           />
 </commands>
diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml
old mode 100644
new mode 100755
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
old mode 100644
new mode 100755
index 995546ab230e5b0a9295e80e52dfc078b4c731fb..3281d347a7028f8ccccf11c95f8ac1ea6c4c1afb
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -2,6 +2,28 @@
 <llsd xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:noNamespaceSchemaLocation="llsd.xsd">
 <map>
+    <key>IMShowTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable(disable) timestamp showing in the chat.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>IMShowNamesForP2PConv</key>
+    <map>
+      <key>Comment</key>
+      <string>Enable(disable) showing of a names in the chat.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
 	<key>CrashHostUrl</key>
     <map>
       <key>Comment</key>
@@ -47,7 +69,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.95</real>
+      <real>1</real>
     </map>
     <key>AdvanceSnapshot</key>
     <map>
@@ -1573,6 +1595,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>ChatLoadGroupMaxMembers</key>
+    <map>
+        <key>Comment</key>
+        <string>Max number of active members we'll show up for an unresponsive group</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>S32</string>
+        <key>Value</key>
+        <real>100</real>
+    </map>
+    <key>ChatLoadGroupTimeout</key>
+    <map>
+        <key>Comment</key>
+        <string>Time we give the server to send group participants before we hit the server for group info (seconds)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>F32</string>
+        <key>Value</key>
+        <real>10.0</real>
+    </map>
     <key>ChatOnlineNotification</key>
     <map>
       <key>Comment</key>
@@ -1606,17 +1650,6 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
-    <key>ChatWindow</key>
-    <map>
-      <key>Comment</key>
-      <string>Show chat in multiple windows(by default) or in one multi-tabbed window(requires restart)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
     <key>CheesyBeacon</key>
     <map>
       <key>Comment</key>
@@ -1639,6 +1672,61 @@
       <key>Value</key>
       <string />
     </map>
+    <key>ContextConeInAlpha</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone In Alpha</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>0.0</real>
+    </map>
+    <key>ContextConeOutAlpha</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone Out Alpha</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.0</real>
+    </map>
+    <key>ContextConeFadeTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Cone Fade Time</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>.08</real>
+    </map>
+    <key>ConversationHistoryPageSize</key>
+    <map>
+      <key>Comment</key>
+      <string>Chat history of conversation opened from call log is displayed by pages. So this is number of entries per page.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>S32</string>
+      <key>Value</key>
+      <integer>100</integer>
+    </map>
+    <key>ConversationSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort key for conversations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>131073</integer>
+    </map>
     <key>CloseChatOnReturn</key>
     <map>
       <key>Comment</key>
@@ -1926,6 +2014,39 @@
       <string>String</string>
       <key>Value</key>
       <string />
+    </map>
+  <key>DebugAvatarAppearanceMessage</key>
+  <map>
+    <key>Comment</key>
+    <string>Dump a bunch of XML files when handling appearance messages</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+  <key>DebugAvatarExperimentalServerAppearanceUpdate</key>
+  <map>
+    <key>Comment</key>
+    <string>Experiment with sending full cof_contents instead of cof_version</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+    <key>DebugAvatarAppearanceServiceURLOverride</key>
+    <map>
+      <key>Comment</key>
+      <string>URL to use for baked texture requests; overrides value returned by login server.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
     </map>
 	<key>DebugAvatarRezTime</key>
 	<map>
@@ -1948,6 +2069,17 @@
     <string>Boolean</string>
     <key>Value</key>
     <integer>1</integer>
+  </map>
+  <key>DebugAvatarCompositeBaked</key>
+  <map>
+    <key>Comment</key>
+    <string>Colorize avatar meshes based on baked/composite state.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
   </map>
     <key>DebugBeaconLineWidth</key>
     <map>
@@ -1960,6 +2092,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>DebugForceAppearanceRequestFailure</key>
+    <map>
+      <key>Comment</key>
+      <string>Request wrong cof version to test the failure path for server appearance update requests.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DebugHideEmptySystemFolders</key>
     <map>
       <key>Comment</key>
@@ -4193,6 +4336,17 @@
       <string>Boolean</string>
       <key>Value</key>
       <integer>1</integer>
+    </map>
+     <key>IMShowContentPanel</key>
+    <map>
+      <key>Comment</key>
+      <string>Show Toolbar and Body Panels</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
     </map>
     <key>IgnoreAllNotifications</key>
     <map>
@@ -4236,7 +4390,7 @@
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.65</real>
+      <real>0.95</real>
     </map>
     <key>InBandwidth</key>
     <map>
@@ -4293,6 +4447,28 @@
       <key>Value</key>
       <real>1.0</real>
     </map>
+    <key>InventoryDebugSimulateOpFailureRate</key>
+    <map>
+      <key>Comment</key>
+        <string>Rate at which we simulate failures of copy/link requests in some operations</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>F32</string>
+      <key>Value</key>
+        <real>0.0</real>
+    </map>
+    <key>InventoryDebugSimulateLateOpRate</key>
+    <map>
+      <key>Comment</key>
+        <string>Rate at which we simulate late-completing copy/link requests in some operations</string>
+      <key>Persist</key>
+        <integer>1</integer>
+      <key>Type</key>
+        <string>F32</string>
+      <key>Value</key>
+        <real>0.0</real>
+    </map>
     <key>InventoryDisplayInbox</key>
     <map>
         <key>Comment</key>
@@ -6219,6 +6395,61 @@
       <key>Value</key>
       <integer>305</integer>
     </map>
+    <key>NotificationConferenceIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Conference IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>  
+    <key>NotificationFriendIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Friend IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>
+    <key>NotificationGroupChatOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Group Chat Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>
+    <key>NotificationNearbyChatOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Nearby Chat Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>
+    <key>NotificationNonFriendIMOptions</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies how the UI responds to Non Friend IM Notifications.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>toast</string>
+    </map>  
     <key>NotificationToastLifeTime</key>
     <map>
       <key>Comment</key>
@@ -6735,6 +6966,50 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>PlaySoundIncomingVoiceCall</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have an incoming voice call.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>PlaySoundInventoryOffer</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have an inventory offer.</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>
+      <string>Plays a sound when have a new conversation.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>PlaySoundTeleportOffer</key>
+    <map>
+      <key>Comment</key>
+      <string>Plays a sound when have a teleport offer.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>PluginAttachDebuggerToPlugins</key>
     <map>
       <key>Comment</key>
@@ -8716,6 +8991,28 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>DisableAllRenderTypes</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering types.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>DisableAllRenderFeatures</key>
+    <map>
+      <key>Comment</key>
+      <string>Disables all rendering features.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RenderHUDInSnapshot</key>
     <map>
       <key>Comment</key>
@@ -9846,7 +10143,7 @@
 	<key>ShowScriptErrorsLocation</key>
     <map>
       <key>Comment</key>
-      <string>Show script error in chat or window</string>
+      <string>Show script error in chat (0) or window (1).</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -10030,6 +10327,39 @@
       <key>Value</key>
       <integer>2</integer>
     </map>
+    <key>BlockPeopleSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort order for recent people (0 = by name, 1 = by type)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>CallLogSortOrder</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies sort order for Call Log (0 = by name, 1 = by date)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>U32</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>SortFriendsFirst</key>
+    <map>
+      <key>Comment</key>
+      <string>Specifies whether friends will be sorted first in Call Log</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>ShowPGSearchAll</key>    
     <map>
       <key>Comment</key>
@@ -12395,17 +12725,6 @@
       <key>Value</key>
       <string />
     </map>
-    <key>SpeakerParticipantDefaultOrder</key>
-    <map>
-      <key>Comment</key>
-      <string>Order for displaying speakers in voice controls.  0 = alphabetical. 1 = recent.</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>U32</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>SpeakerParticipantRemoveDelay</key>
     <map>
       <key>Comment</key>
@@ -12450,6 +12769,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+  <key>UsePeopleAPI</key>
+  <map>
+    <key>Comment</key>
+    <string>Use the people API cap for avatar name fetching, use old legacy protocol if false. Requires restart.</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>1</integer>
+  </map>
     <key>UseStartScreen</key>
     <map>
       <key>Comment</key>
@@ -12944,10 +13274,10 @@
       <key>Value</key>
       <real>50.0</real>
     </map>
-    <key>WellIconFlashCount</key>
+    <key>FlashCount</key>
     <map>
       <key>Comment</key>
-      <string>Number of flashes of IM Well and Notification Well icons after which flashing buttons stay lit up. Requires restart.</string>
+      <string>Number of flashes of item. Requires restart.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
@@ -12955,16 +13285,16 @@
       <key>Value</key>
       <integer>3</integer>
     </map>
-    <key>WellIconFlashPeriod</key>
+    <key>FlashPeriod</key>
     <map>
       <key>Comment</key>
-      <string>Period at which IM Well and Notification Well icons flash (seconds). Requires restart.</string>
+      <string>Period at which item flash (seconds). Requires restart.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
       <string>F32</string>
       <key>Value</key>
-      <real>0.25</real>
+      <real>0.5</real>
     </map>
     <key>WindLightUseAtmosShaders</key>
     <map>
@@ -13120,6 +13450,28 @@
       <key>Value</key>
       <integer>-1</integer>
     </map>
+    <key>MaxFPS</key>
+    <map>
+      <key>Comment</key>
+      <string>Yield some time to the local host if we reach a threshold framerate.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
+    <key>ForcePeriodicRenderingTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Periodically enable all rendering masks for a single frame.</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <integer>-1.0</integer>
+    </map>
     <key>ZoomDirect</key>
     <map>
       <key>Comment</key>
@@ -14105,6 +14457,17 @@
     <key>Value</key>
     <integer>0</integer>
   </map>
+  <key>DisablePrecacheDelayAfterTeleporting</key>
+  <map>
+    <key>Comment</key>
+    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
   <key>FMODExProfilerEnable</key>
   <map>
     <key>Comment</key>
@@ -14138,5 +14501,16 @@
     <key>Value</key>
     <integer>7000</integer>
   </map>
+  <key>DisablePrecacheDelayAfterTeleporting</key>
+  <map>
+    <key>Comment</key>
+    <string>Disables the artificial delay in the viewer that precaches some incoming assets</string>
+    <key>Persist</key>
+    <integer>0</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
 </map>
 </llsd>
diff --git a/indra/newview/app_settings/settings_per_account.xml b/indra/newview/app_settings/settings_per_account.xml
index 143126b3345307e4d16083378d5ee539da0637d1..590f41283b68eb9d94c04af1ae5c00dae70c77a0 100644
--- a/indra/newview/app_settings/settings_per_account.xml
+++ b/indra/newview/app_settings/settings_per_account.xml
@@ -1,9 +1,9 @@
 <llsd>
     <map>
-    <key>BusyResponseChanged</key>
+    <key>DoNotDisturbResponseChanged</key>
         <map>
         <key>Comment</key>
-            <string>Does user's busy mode message differ from default?</string>
+            <string>Does user's do not disturb mode message differ from default?</string>
         <key>Persist</key>
             <integer>1</integer>
         <key>Type</key>
@@ -11,17 +11,72 @@
         <key>Value</key>
             <integer>0</integer>
         </map>
-    <key>BusyModeResponse</key>
+    <key>DoNotDisturbModeResponse</key>
         <map>
         <key>Comment</key>
-            <string>Auto response to instant messages while in busy mode.</string>
+            <string>Auto response to instant messages while in do not disturb mode.</string>
         <key>Persist</key>
             <integer>1</integer>
         <key>Type</key>
             <string>String</string>
         <key>Value</key>
-            <string>The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
+            <string>This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
         </map>
+    <key>ConversationsExpandMessagePaneFirst</key>
+    <map>
+        <key>Comment</key>
+            <string>Expand either messages or conversations list pane from Conversations compact mode.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>1</integer>
+    </map>
+    <key>ConversationsListPaneCollapsed</key>
+    <map>
+        <key>Comment</key>
+            <string>Stores the expanded/collapsed state of the conversations list pane in Conversations floater.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+    </map>
+    <key>ConversationsListPaneWidth</key>
+    <map>
+        <key>Comment</key>
+            <string>Conversations floater list pane width.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>205</integer>
+    </map>
+    <key>ConversationsMessagePaneCollapsed</key>
+    <map>
+        <key>Comment</key>
+            <string>Stores the expanded/collapsed state of Conversations floater message pane.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+    </map>
+    <key>ConversationsMessagePaneWidth</key>
+    <map>
+        <key>Comment</key>
+            <string>Conversations floater message pane width.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>412</integer>
+    </map>
     <key>InstantMessageLogPath</key>
         <map>
         <key>Comment</key>
@@ -121,17 +176,6 @@
         <key>Value</key>
             <integer>1</integer>
         </map>
-    <key>LogInstantMessages</key>
-        <map>
-        <key>Comment</key>
-            <string>Log Instant Messages</string>
-        <key>Persist</key>
-            <integer>1</integer>
-        <key>Type</key>
-            <string>Boolean</string>
-        <key>Value</key>
-            <integer>1</integer>
-        </map>
     <key>LogShowHistory</key>
         <map>
         <key>Comment</key>
@@ -215,7 +259,51 @@
         <key>Value</key>
             <integer>0</integer>
         </map>
-      <key>ShowFavoritesOnLogin</key>
+    <key>TranslatingEnabled</key>
+        <map>
+        <key>Comment</key>
+            <string>Translation prefs are set</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+        </map>
+    <key>KeepConversationLogTranscripts</key>
+    	<map>
+      	<key>Comment</key>
+      		<string>Keep a conversation log and transcripts</string>
+      	<key>Persist</key>
+      		<integer>1</integer>
+      	<key>Type</key>
+      		<string>S32</string>
+      	<key>Value</key>
+      		<integer>2</integer>
+    	</map>    
+    <key>NearbyChatIsNotTornOff</key>
+    <map>
+      <key>Comment</key>
+      <string>saving torn-off state of the nearby chat between sessions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>NearbyChatIsNotCollapsed</key>
+    <map>
+      <key>Comment</key>
+      <string>Saving expanded/collapsed state of the nearby chat between sessions</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>ShowFavoritesOnLogin</key>
         <map>
         <key>Comment</key>
              <string>Determines whether favorites of last logged in user will be saved on exit from viewer and shown on login screen</string>
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
index 99a6fe85fe8178e1f07ba0b550b12e322966b722..9c82056fd7f71dda504eeb247ace58338bc2c7ff 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterAlphaMaskF.glsl
@@ -31,7 +31,7 @@ out vec4 frag_color;
 
 uniform float minimum_alpha;
 
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
diff --git a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
index df182168f3c59baa50aa671339355b2267146a3a..d3dacf9bc4d81e65f7cd91eda199da74440a4d66 100644
--- a/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
+++ b/indra/newview/app_settings/shaders/class1/lighting/lightFullbrightWaterF.glsl
@@ -32,7 +32,7 @@ out vec4 frag_color;
 VARYING vec4 vertex_color;
 VARYING vec2 vary_texcoord0;
 
-vec4 diffuseLookup(vec2 texcoord);
+/* vec4 diffuseLookup(vec2 texcoord); */
 
 vec3 fullbrightAtmosTransport(vec3 light);
 vec4 applyWaterFog(vec4 color);
diff --git a/indra/newview/character/avatar_lad.xml b/indra/newview/character/avatar_lad.xml
index 99dbfcae51e8d94d201fee72ae01434df3e35bb4..284e9c44b286ee6b4352b2f47759395eac54aed9 100644
--- a/indra/newview/character/avatar_lad.xml
+++ b/indra/newview/character/avatar_lad.xml
@@ -1084,6 +1084,23 @@
          scale="0 0 .5" />
       </param_skeleton>
     </param>
+
+    <param
+     id="11001"
+     group="0"
+     name="Hover"
+     wearable="shape"
+     edit_group="shape_body"
+     edit_group_order="4"
+     label_min="Lower"
+     label_max="Higher"
+     value_min="-2"
+     value_max="2"
+     value_default="0"
+     camera_distance="2.5">
+      <param_skeleton />
+    </param>
+
   </skeleton>
 
   <mesh
@@ -12291,6 +12308,17 @@ render_pass="bump">
 	 <param_driver />
     </param>
 
+    <param
+     id="11000"
+     group="0"
+     name="AppearanceMessage_Version"
+     label="AppearanceMessage Version"
+     value_default="0"
+     value_min="0"
+     value_max="255">
+	 <param_driver />
+    </param>
+
   </driver_parameters>
 
   <morph_masks>
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index ef3746c90bc3e74784f3a9353f3d22a2f0d20d6f..48b883e99957774ed753165696c8abc0f560df97 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -45,6 +45,7 @@ if [ "`uname -m`" = "x86_64" ]; then
     echo '64-bit Linux detected.'
 fi
 
+
 ## Everything below this line is just for advanced troubleshooters.
 ##-------------------------------------------------------------------
 
@@ -60,7 +61,15 @@ fi
 export SDL_VIDEO_X11_DGAMOUSE=0
 
 ## - Works around a problem with misconfigured 64-bit systems not finding GL
-export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}":/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri
+I386_MULTIARCH="$(dpkg-architecture -ai386 -qDEB_HOST_MULTIARCH 2>/dev/null)"
+MULTIARCH_ERR=$?
+if [ $MULTIARCH_ERR -eq 0 ]; then
+    echo 'Multi-arch support detected.'
+    MULTIARCH_GL_DRIVERS="/usr/lib/${I386_MULTIARCH}/dri"
+    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:${MULTIARCH_GL_DRIVERS}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+else
+    export LIBGL_DRIVERS_PATH="${LIBGL_DRIVERS_PATH}:/usr/lib64/dri:/usr/lib32/dri:/usr/lib/dri"
+fi
 
 ## - The 'scim' GTK IM module widely crashes the viewer.  Avoid it.
 if [ "$GTK_IM_MODULE" = "scim" ]; then
@@ -117,18 +126,32 @@ export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
 # 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 read it without scanning, then scan that string. Break quoted words
+# First, check if we have been instructed to skip reading in gridargs.dat:
+skip_gridargs=false
+argnum=0
+for ARG in "$@"; do
+    if [ "--skip-gridargs" == "$ARG" ]; then
+        skip_gridargs=true
+    else
+        ARGS[$argnum]="$ARG"
+        argnum=$(($argnum+1))
+    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.
-eval gridargs=("$(<etc/gridargs.dat)")
+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[@]}" "$@"
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"
 LL_RUN_ERR=$?
 
 # Handle any resulting errors
diff --git a/indra/newview/llaccountingcostmanager.cpp b/indra/newview/llaccountingcostmanager.cpp
index 8767955fcb57a9821dba6e3b0fc4e246e3b2b3e6..7662a9689daa0849a6a22146c722bb27dc48a9de 100644
--- a/indra/newview/llaccountingcostmanager.cpp
+++ b/indra/newview/llaccountingcostmanager.cpp
@@ -56,9 +56,9 @@ class LLAccountingCostResponder : public LLCurl::Responder
 		}
 	}
 	
-	void error( U32 statusNum, const std::string& reason )
+	void errorWithContent( U32 statusNum, const std::string& reason, const LLSD& content )
 	{
-		llwarns	<< "Transport error "<<reason<<llendl;	
+		llwarns << "Transport error [status:" << statusNum << "]: " << content <<llendl;
 		clearPendingRequests();
 
 		LLAccountingCostObserver* observer = mObserverHandle.get();
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index b6fd7bc9c20d9b02a55a9379e9c616fb4999878a..8c42defa73f25bc7a47871ffd8911b7b54848403 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -35,12 +35,14 @@
 #include "llagentlistener.h"
 #include "llagentwearables.h"
 #include "llagentui.h"
+#include "llappearancemgr.h"
 #include "llanimationstates.h"
 #include "llcallingcard.h"
 #include "llcapabilitylistener.h"
 #include "llchannelmanager.h"
 #include "llchicletbar.h"
 #include "llconsole.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llenvmanager.h"
 #include "llfirstuse.h"
 #include "llfloatercamera.h"
@@ -54,7 +56,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h" // to show/hide navigation bar when changing mouse look state
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationsutil.h"
 #include "llpaneltopinfobar.h"
 #include "llparcel.h"
@@ -90,7 +92,7 @@
 #include "llworldmap.h"
 #include "stringize.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 extern LLMenuBarGL* gMenuBarView;
 
@@ -375,7 +377,7 @@ LLAgent::LLAgent() :
 	mShowAvatar(TRUE),
 	mFrameAgent(),
 
-	mIsBusy(FALSE),
+	mIsDoNotDisturb(false),
 
 	mControlFlags(0x00000000),
 	mbFlagsDirty(FALSE),
@@ -807,6 +809,29 @@ void LLAgent::standUp()
 }
 
 
+void LLAgent::handleServerBakeRegionTransition(const LLUUID& region_id)
+{
+	llinfos << "called" << llendl;
+
+
+	// Old-style appearance entering a server-bake region.
+	if (isAgentAvatarValid() &&
+		!gAgentAvatarp->isUsingServerBakes() &&
+		(mRegionp->getCentralBakeVersion()>0))
+	{
+		llinfos << "update requested due to region transition" << llendl;
+		LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+	}
+	// new-style appearance entering a non-bake region,
+	// need to check for existence of the baking service.
+	else if (isAgentAvatarValid() &&
+			 gAgentAvatarp->isUsingServerBakes() &&
+			 mRegionp->getCentralBakeVersion()==0)
+	{
+		gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+	}
+}
+
 //-----------------------------------------------------------------------------
 // setRegion()
 //-----------------------------------------------------------------------------
@@ -902,6 +927,19 @@ void LLAgent::setRegion(LLViewerRegion *regionp)
 	{
 		LLEnvManagerNew::instance().onRegionCrossing();
 	}
+
+	// If the newly entered region is using server bakes, and our
+	// current appearance is non-baked, request appearance update from
+	// server.
+	if (mRegionp->capabilitiesReceived())
+	{
+		handleServerBakeRegionTransition(mRegionp->getRegionID());
+	}
+	else
+	{
+		// Need to handle via callback after caps arrive.
+		mRegionp->setCapabilitiesReceivedCallback(boost::bind(&LLAgent::handleServerBakeRegionTransition,this,_1));
+	}
 }
 
 
@@ -1355,12 +1393,7 @@ void LLAgent::setAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_START);
 		setControlFlags(AGENT_CONTROL_AWAY | AGENT_CONTROL_STOP);
-		LL_INFOS("AFK") << "Setting Away" << LL_ENDL;
 		gAwayTimer.start();
-		if (gAFKMenu)
-		{
-			gAFKMenu->setLabel(LLTrans::getString("AvatarSetNotAway"));
-		}
 	}
 }
 
@@ -1379,11 +1412,6 @@ void LLAgent::clearAFK()
 	{
 		sendAnimationRequest(ANIM_AGENT_AWAY, ANIM_REQUEST_STOP);
 		clearControlFlags(AGENT_CONTROL_AWAY);
-		LL_INFOS("AFK") << "Clearing Away" << LL_ENDL;
-		if (gAFKMenu)
-		{
-			gAFKMenu->setLabel(LLTrans::getString("AvatarSetAway"));
-		}
 	}
 }
 
@@ -1396,39 +1424,26 @@ BOOL LLAgent::getAFK() const
 }
 
 //-----------------------------------------------------------------------------
-// setBusy()
+// setDoNotDisturb()
 //-----------------------------------------------------------------------------
-void LLAgent::setBusy()
+void LLAgent::setDoNotDisturb(bool pIsDoNotDisturb)
 {
-	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_START);
-	mIsBusy = TRUE;
-	if (gBusyMenu)
+	bool isDoNotDisturbSwitchedOff = (mIsDoNotDisturb && !pIsDoNotDisturb);
+	mIsDoNotDisturb = pIsDoNotDisturb;
+	sendAnimationRequest(ANIM_AGENT_DO_NOT_DISTURB, (pIsDoNotDisturb ? ANIM_REQUEST_START : ANIM_REQUEST_STOP));
+	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(pIsDoNotDisturb);
+	if (isDoNotDisturbSwitchedOff)
 	{
-		gBusyMenu->setLabel(LLTrans::getString("AvatarSetNotBusy"));
+		LLDoNotDisturbNotificationStorage::getInstance()->updateNotifications();
 	}
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(true);
 }
 
 //-----------------------------------------------------------------------------
-// clearBusy()
+// isDoNotDisturb()
 //-----------------------------------------------------------------------------
-void LLAgent::clearBusy()
+bool LLAgent::isDoNotDisturb() const
 {
-	mIsBusy = FALSE;
-	sendAnimationRequest(ANIM_AGENT_BUSY, ANIM_REQUEST_STOP);
-	if (gBusyMenu)
-	{
-		gBusyMenu->setLabel(LLTrans::getString("AvatarSetBusy"));
-	}
-	LLNotificationsUI::LLChannelManager::getInstance()->muteAllChannels(false);
-}
-
-//-----------------------------------------------------------------------------
-// getBusy()
-//-----------------------------------------------------------------------------
-BOOL LLAgent::getBusy() const
-{
-	return mIsBusy;
+	return mIsDoNotDisturb;
 }
 
 
@@ -1707,13 +1722,11 @@ void LLAgent::autoPilot(F32 *delta_yaw)
 
 		*delta_yaw = yaw;
 
-		// Compute when to start slowing down and when to stop
-		F32 stop_distance = mAutoPilotStopDistance;
+		// Compute when to start slowing down
 		F32 slow_distance;
 		if (getFlying())
 		{
 			slow_distance = llmax(6.f, mAutoPilotStopDistance + 5.f);
-			stop_distance = llmax(2.f, mAutoPilotStopDistance);
 		}
 		else
 		{
@@ -1910,7 +1923,8 @@ void LLAgent::startTyping()
 	{
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_START);
 	}
-	LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_START, FALSE);
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+			sendChatFromViewer("", CHAT_TYPE_START, FALSE);
 }
 
 //-----------------------------------------------------------------------------
@@ -1922,7 +1936,8 @@ void LLAgent::stopTyping()
 	{
 		clearRenderState(AGENT_STATE_TYPING);
 		sendAnimationRequest(ANIM_AGENT_TYPE, ANIM_REQUEST_STOP);
-		LLNearbyChatBar::getInstance()->sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
+		(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+				sendChatFromViewer("", CHAT_TYPE_STOP, FALSE);
 	}
 }
 
@@ -2297,7 +2312,7 @@ void LLAgent::setStartPosition( U32 location_id )
     if (isAgentAvatarValid())
     {
         // the z height is at the agent's feet
-        agent_pos.mV[VZ] -= 0.5f * gAgentAvatarp->mBodySize.mV[VZ];
+        agent_pos.mV[VZ] -= 0.5f * (gAgentAvatarp->mBodySize.mV[VZ] + gAgentAvatarp->mAvatarOffset.mV[VZ]);
     }
 
     agent_pos.mV[VX] = llclamp( agent_pos.mV[VX], INSET, REGION_WIDTH - INSET );
@@ -2516,7 +2531,7 @@ class LLMaturityPreferencesResponder : public LLHTTPClient::Responder
 	virtual ~LLMaturityPreferencesResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -2554,61 +2569,31 @@ void LLMaturityPreferencesResponder::result(const LLSD &pContent)
 	mAgent->handlePreferredMaturityResult(actualMaturity);
 }
 
-void LLMaturityPreferencesResponder::error(U32 pStatus, const std::string& pReason)
+void LLMaturityPreferencesResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
 	llwarns << "while attempting to change maturity preference from '" << LLViewerRegion::accessToString(mPreviousMaturity)
-		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error because '"
-		<< pReason << "' [status:" << pStatus << "]" << llendl;
+		<< "' to '" << LLViewerRegion::accessToString(mPreferredMaturity) << "', we got an error with [status:"
+		<< pStatus << "]: " << (pContent.isDefined() ? pContent : LLSD(pReason)) << llendl;
 	mAgent->handlePreferredMaturityError();
 }
 
 U8 LLMaturityPreferencesResponder::parseMaturityFromServerResponse(const LLSD &pContent)
 {
-	// stinson 05/24/2012 Pathfinding regions have re-defined the response behavior.  In the old server code,
-	// if you attempted to change the preferred maturity to the same value, the response content would be an
-	// undefined LLSD block.  In the new server code with pathfinding, the response content should always be
-	// defined.  Thus, the check for isUndefined() can be replaced with an assert after pathfinding is merged
-	// into server trunk and fully deployed.
 	U8 maturity = SIM_ACCESS_MIN;
-	if (pContent.isUndefined())
+
+	llassert(!pContent.isUndefined());
+	llassert(pContent.isMap());
+	llassert(pContent.has("access_prefs"));
+	llassert(pContent.get("access_prefs").isMap());
+	llassert(pContent.get("access_prefs").has("max"));
+	llassert(pContent.get("access_prefs").get("max").isString());
+	if (!pContent.isUndefined() && pContent.isMap() && pContent.has("access_prefs")
+		&& pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max")
+		&& pContent.get("access_prefs").get("max").isString())
 	{
-		maturity = mPreferredMaturity;
-	}
-	else
-	{
-		llassert(!pContent.isUndefined());
-		llassert(pContent.isMap());
-	
-		if (!pContent.isUndefined() && pContent.isMap())
-		{
-			// stinson 05/24/2012 Pathfinding regions have re-defined the response syntax.  The if statement catches
-			// the new syntax, and the else statement catches the old syntax.  After pathfinding is merged into
-			// server trunk and fully deployed, we can remove the else statement.
-			if (pContent.has("access_prefs"))
-			{
-				llassert(pContent.has("access_prefs"));
-				llassert(pContent.get("access_prefs").isMap());
-				llassert(pContent.get("access_prefs").has("max"));
-				llassert(pContent.get("access_prefs").get("max").isString());
-				if (pContent.get("access_prefs").isMap() && pContent.get("access_prefs").has("max") &&
-					pContent.get("access_prefs").get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-			else if (pContent.has("max"))
-			{
-				llassert(pContent.get("max").isString());
-				if (pContent.get("max").isString())
-				{
-					LLSD::String actualPreference = pContent.get("max").asString();
-					LLStringUtil::trim(actualPreference);
-					maturity = LLViewerRegion::shortStringToAccess(actualPreference);
-				}
-			}
-		}
+		LLSD::String actualPreference = pContent.get("access_prefs").get("max").asString();
+		LLStringUtil::trim(actualPreference);
+		maturity = LLViewerRegion::shortStringToAccess(actualPreference);
 	}
 
 	return maturity;
@@ -2748,7 +2733,7 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 		// If we don't have a region, report it as an error
 		if (getRegion() == NULL)
 		{
-			responderPtr->error(0U, "region is not defined");
+			responderPtr->errorWithContent(0U, "region is not defined", LLSD());
 		}
 		else
 		{
@@ -2758,7 +2743,8 @@ void LLAgent::sendMaturityPreferenceToServer(U8 pPreferredMaturity)
 			// If the capability is not defined, report it as an error
 			if (url.empty())
 			{
-				responderPtr->error(0U, "capability 'UpdateAgentInformation' is not defined for region");
+				responderPtr->errorWithContent(0U, 
+							"capability 'UpdateAgentInformation' is not defined for region", LLSD());
 			}
 			else
 			{
@@ -3626,7 +3612,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 		return;
 	}
 
-	if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+	if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
 	{
 		// ignore baked textures when in customize mode
 		return;
@@ -3650,7 +3636,7 @@ void LLAgent::processAgentCachedTextureResponse(LLMessageSystem *mesgsys, void *
 
 		if ((S32)texture_index < TEX_NUM_INDICES )
 		{	
-			const LLVOAvatarDictionary::TextureEntry *texture_entry = LLVOAvatarDictionary::instance().getTexture((ETextureIndex)texture_index);
+			const LLAvatarAppearanceDictionary::TextureEntry *texture_entry = LLAvatarAppearanceDictionary::instance().getTexture((ETextureIndex)texture_index);
 			if (texture_entry)
 			{
 				EBakedTextureIndex baked_index = texture_entry->mBakedTextureIndex;
@@ -4257,27 +4243,82 @@ void LLAgent::requestLeaveGodMode()
 	sendReliableMessage();
 }
 
+// For debugging, trace agent state at times appearance message are sent out.
+void LLAgent::dumpSentAppearance(const std::string& dump_prefix)
+{
+	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+
+	LLAPRFile outfile;
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
+	{
+		return;
+	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "dumping sent appearance message to " << fullpath << llendl;
+	}
+
+	LLVisualParam* appearance_version_param = gAgentAvatarp->getVisualParam(11000);
+	if (appearance_version_param)
+	{
+		F32 value = appearance_version_param->getWeight();
+		dump_visual_param(file, appearance_version_param, value);
+	}
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+		 ++iter)
+	{
+		const ETextureIndex index = iter->first;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
+		if (texture_dict->mIsBakedTexture)
+		{
+			LLTextureEntry* entry = gAgentAvatarp->getTE((U8) index);
+			const LLUUID& uuid = entry->getID();
+			apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", index, uuid.asString().c_str());
+		}
+	}
+}
+
 //-----------------------------------------------------------------------------
 // sendAgentSetAppearance()
 //-----------------------------------------------------------------------------
 void LLAgent::sendAgentSetAppearance()
 {
-	if (!isAgentAvatarValid()) return;
-
-	if (gAgentQueryManager.mNumPendingQueries > 0 && (isAgentAvatarValid() && gAgentAvatarp->isUsingBakedTextures())) 
+	if (gAgentQueryManager.mNumPendingQueries > 0) 
 	{
 		return;
 	}
 
-	if (!gAgentWearables.changeInProgress())
+	if (!isAgentAvatarValid() || (getRegion() && getRegion()->getCentralBakeVersion())) return;
+
+	// At this point we have a complete appearance to send and are in a non-baking region.
+	// DRANO FIXME
+	//gAgentAvatarp->setIsUsingServerBakes(FALSE);
+	S32 sb_count, host_count, both_count, neither_count;
+	gAgentAvatarp->bakedTextureOriginCounts(sb_count, host_count, both_count, neither_count);
+	if (both_count != 0 || neither_count != 0)
+	{
+		llwarns << "bad bake texture state " << sb_count << "," << host_count << "," << both_count << "," << neither_count << llendl;
+	}
+	if (sb_count != 0 && host_count == 0)
 	{
-		// Change is fully resolved, can close some open phases.
-		gAgentAvatarp->getPhases().stopPhase("process_initial_wearables_update");
-		gAgentAvatarp->getPhases().stopPhase("wear_inventory_category");
+		gAgentAvatarp->setIsUsingServerBakes(true);
+	}
+	else if (sb_count == 0 && host_count != 0)
+	{
+		gAgentAvatarp->setIsUsingServerBakes(false);
+	}
+	else if (sb_count + host_count > 0)
+	{
+		llwarns << "unclear baked texture state, not sending appearance" << llendl;
+		return;
 	}
 	
-	gAgentAvatarp->sendAppearanceChangeMetrics();
-	LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
+
+	LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sent AgentSetAppearance: " << gAgentAvatarp->getBakedStatusForPrintout() << LL_ENDL;
 	//dumpAvatarTEs( "sendAgentSetAppearance()" );
 
 	LLMessageSystem* msg = gMessageSystem;
@@ -4291,7 +4332,7 @@ void LLAgent::sendAgentSetAppearance()
 	// NOTE -- when we start correcting all of the other Havok geometry 
 	// to compensate for the COLLISION_TOLERANCE ugliness we will have 
 	// to tweak this number again
-	const LLVector3 body_size = gAgentAvatarp->mBodySize;
+	const LLVector3 body_size = gAgentAvatarp->mBodySize + gAgentAvatarp->mAvatarOffset;
 	msg->addVector3Fast(_PREHASH_Size, body_size);	
 
 	// To guard against out of order packets
@@ -4305,7 +4346,7 @@ void LLAgent::sendAgentSetAppearance()
 
 	for(U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++ )
 	{
-		const ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+		const ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
 
 		// if we're not wearing a skirt, we don't need the texture to be baked
 		if (texture_index == TEX_SKIRT_BAKED && !gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
@@ -4316,19 +4357,30 @@ void LLAgent::sendAgentSetAppearance()
 		// IMG_DEFAULT_AVATAR means not baked. 0 index should be ignored for baked textures
 		if (!gAgentAvatarp->isTextureDefined(texture_index, 0))
 		{
+			LL_DEBUGS("Avatar") << "texture not current for baked " << (S32)baked_index << " local " << (S32)texture_index << llendl;
 			textures_current = FALSE;
 			break;
 		}
 	}
 
 	// only update cache entries if we have all our baked textures
+
+	// FIXME DRANO need additional check for not in appearance editing
+	// mode, if still using local composites need to set using local
+	// composites to false, and update mesh textures.
 	if (textures_current)
 	{
-		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
+		bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+		std::string dump_prefix = gAgentAvatarp->getFullname() + "_sent_appearance";
+		if (enable_verbose_dumps)
+		{
+			dumpSentAppearance(dump_prefix);
+		}
+		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "TAT: Sending cached texture data" << LL_ENDL;
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
 			BOOL generate_valid_hash = TRUE;
-			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
+			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLAvatarAppearanceDefines::EBakedTextureIndex)baked_index))
 			{
 				generate_valid_hash = FALSE;
 				LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Not caching baked texture upload for " << (U32)baked_index << " due to being uploaded at low resolution." << LL_ENDL;
@@ -4337,7 +4389,7 @@ void LLAgent::sendAgentSetAppearance()
 			const LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
 			if (hash.notNull())
 			{
-				ETextureIndex texture_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
+				ETextureIndex texture_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex) baked_index);
 				msg->nextBlockFast(_PREHASH_WearableData);
 				msg->addUUIDFast(_PREHASH_CacheID, hash);
 				msg->addU8Fast(_PREHASH_TextureIndex, (U8)texture_index);
@@ -4373,7 +4425,7 @@ void LLAgent::sendAgentSetAppearance()
 		}
 	}
 
-//	llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
+	//llinfos << "Avatar XML num VisualParams transmitted = " << transmitted_params << llendl;
 	sendReliableMessage();
 }
 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index 99904e118c15033dd01ebd22bc0a1ef1efe79ca2..f5f26f69d806167afe0ae382c4fccc2998b723d5 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -33,7 +33,8 @@
 #include "llagentdata.h" 			// gAgentID, gAgentSessionID
 #include "llcharacter.h"
 #include "llcoordframe.h"			// for mFrameAgent
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llpermissionsflags.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
@@ -378,14 +379,13 @@ class LLAgent : public LLOldEvents::LLObservable
 	void			sitDown();
 
 	//--------------------------------------------------------------------
-	// Busy
+	// Do Not Disturb
 	//--------------------------------------------------------------------
 public:
-	void			setBusy();
-	void			clearBusy();
-	BOOL			getBusy() const;
+	void			setDoNotDisturb(bool pIsDoNotDisturb);
+	bool			isDoNotDisturb() const;
 private:
-	BOOL			mIsBusy;
+	bool			mIsDoNotDisturb;
 
 	//--------------------------------------------------------------------
 	// Grab
@@ -609,6 +609,7 @@ class LLAgent : public LLOldEvents::LLObservable
 
 	void            handleTeleportFinished();
 	void            handleTeleportFailed();
+	void			handleServerBakeRegionTransition(const LLUUID& region_id);
 
 	//--------------------------------------------------------------------
 	// Teleport State
@@ -843,6 +844,7 @@ class LLAgent : public LLOldEvents::LLObservable
 public:
 	void			sendMessage(); // Send message to this agent's region
 	void			sendReliableMessage();
+	void 			dumpSentAppearance(const std::string& dump_prefix);
 	void			sendAgentSetAppearance();
 	void 			sendAgentDataUpdateRequest();
 	void 			sendAgentUserInfoRequest();
@@ -901,7 +903,7 @@ class LLAgentQueryManager
 	S32				mNumPendingQueries;
 	S32				mWearablesCacheQueryID;
 	U32				mUpdateSerialNum;
-	S32		    	mActiveCacheQueries[LLVOAvatarDefines::BAKED_NUM_INDICES];
+	S32		    	mActiveCacheQueries[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
 };
 
 extern LLAgentQueryManager gAgentQueryManager;
diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp
index 9025c7af8be38b9bbd17ac5a73cbe478f09f3144..0896aa5972467beedf965b9318826ab5df116e99 100644
--- a/indra/newview/llagentcamera.cpp
+++ b/indra/newview/llagentcamera.cpp
@@ -50,7 +50,7 @@
 #include "llwindow.h"
 #include "llworld.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 extern LLMenuBarGL* gMenuBarView;
 
@@ -594,7 +594,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
 	abs_target_offset.abs();
 
 	LLVector3 target_offset_dir = target_offset_origin;
-	F32 object_radius = mFocusObject->getVObjRadius();
 
 	BOOL target_outside_object_extents = FALSE;
 
@@ -689,17 +688,6 @@ BOOL LLAgentCamera::calcCameraMinDistance(F32 &obj_min_distance)
 
 	LLVector3 camera_offset_object(getCameraPositionAgent() - mFocusObject->getPositionAgent());
 
-	// length projected orthogonal to target offset
-	F32 camera_offset_dist = (camera_offset_object - target_offset_dir * (camera_offset_object * target_offset_dir)).magVec();
-
-	// calculate whether the target point would be "visible" if it were outside the bounding box
-	// on the opposite of the splitting plane defined by object_split_axis;
-	BOOL exterior_target_visible = FALSE;
-	if (camera_offset_dist > object_radius)
-	{
-		// target is visible from camera, so turn off fov zoom
-		exterior_target_visible = TRUE;
-	}
 
 	F32 camera_offset_clip = camera_offset_object * object_split_axis;
 	F32 target_offset_clip = target_offset_dir * object_split_axis;
@@ -1079,8 +1067,8 @@ void LLAgentCamera::updateLookAt(const S32 mouse_x, const S32 mouse_y)
 
 	if (!isAgentAvatarValid()) return;
 
-	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot.getWorldRotation();
-	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot.getWorldRotation();
+	LLQuaternion av_inv_rot = ~gAgentAvatarp->mRoot->getWorldRotation();
+	LLVector3 root_at = LLVector3::x_axis * gAgentAvatarp->mRoot->getWorldRotation();
 
 	if 	((gViewerWindow->getMouseVelocityStat()->getCurrent() < 0.01f) &&
 		 (root_at * last_at_axis > 0.95f))
@@ -1433,7 +1421,7 @@ void LLAgentCamera::updateCamera()
 			LLVector3(0.08f, 0.f, 0.05f) * gAgentAvatarp->mHeadp->getWorldRotation() + 
 			LLVector3(0.1f, 0.f, 0.f) * gAgentAvatarp->mPelvisp->getWorldRotation();
 		LLVector3 diff = mCameraPositionAgent - head_pos;
-		diff = diff * ~gAgentAvatarp->mRoot.getWorldRotation();
+		diff = diff * ~gAgentAvatarp->mRoot->getWorldRotation();
 
 		LLJoint* torso_joint = gAgentAvatarp->mTorsop;
 		LLJoint* chest_joint = gAgentAvatarp->mChestp;
@@ -1457,7 +1445,7 @@ void LLAgentCamera::updateCamera()
 
 		gAgentAvatarp->mPelvisp->setPosition(gAgentAvatarp->mPelvisp->getPosition() + diff);
 
-		gAgentAvatarp->mRoot.updateWorldMatrixChildren();
+		gAgentAvatarp->mRoot->updateWorldMatrixChildren();
 
 		for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
 			 iter != gAgentAvatarp->mAttachmentPoints.end(); )
@@ -1658,7 +1646,6 @@ F32	LLAgentCamera::calcCameraFOVZoomFactor()
 	else if (mFocusObject.notNull() && !mFocusObject->isAvatar() && !mFocusOnAvatar)
 	{
 		// don't FOV zoom on mostly transparent objects
-		LLVector3 focus_offset = mFocusObjectOffset;
 		F32 obj_min_dist = 0.f;
 		calcCameraMinDistance(obj_min_dist);
 		F32 current_distance = llmax(0.001f, camera_offset_dir.magVec());
@@ -1685,7 +1672,7 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 	F32			camera_land_height;
 	LLVector3d	frame_center_global = !isAgentAvatarValid() ? 
 		gAgent.getPositionGlobal() :
-		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+		gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
 	
 	BOOL		isConstrained = FALSE;
 	LLVector3d	head_offset;
@@ -1820,7 +1807,6 @@ LLVector3d LLAgentCamera::calcCameraPositionTargetGlobal(BOOL *hit_limit)
 			// set the global camera position
 			LLVector3d camera_offset;
 			
-			LLVector3 av_pos = !isAgentAvatarValid() ? LLVector3::zero : gAgentAvatarp->getRenderPosition();
 			camera_offset.setVec( local_camera_offset );
 			camera_position_global = frame_center_global + head_offset + camera_offset;
 
@@ -2257,7 +2243,7 @@ void LLAgentCamera::changeCameraToThirdPerson(BOOL animate)
 //-----------------------------------------------------------------------------
 void LLAgentCamera::changeCameraToCustomizeAvatar()
 {
-	if (LLViewerJoystick::getInstance()->getOverrideCamera())
+	if (LLViewerJoystick::getInstance()->getOverrideCamera() || !isAgentAvatarValid())
 	{
 		return;
 	}
@@ -2281,29 +2267,21 @@ void LLAgentCamera::changeCameraToCustomizeAvatar()
 		gFocusMgr.setKeyboardFocus( NULL );
 		gFocusMgr.setMouseCapture( NULL );
 
-		LLVOAvatarSelf::onCustomizeStart();
+		// Remove any pitch or rotation from the avatar
+		LLVector3 at = gAgent.getAtAxis();
+		at.mV[VZ] = 0.f;
+		at.normalize();
+		gAgent.resetAxes(at);
 
-		if (isAgentAvatarValid())
-		{
-			// Remove any pitch or rotation from the avatar
-			LLVector3 at = gAgent.getAtAxis();
-			at.mV[VZ] = 0.f;
-			at.normalize();
-			gAgent.resetAxes(at);
+		gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
+		gAgent.setCustomAnim(TRUE);
+		gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
+		LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
 
-			gAgent.sendAnimationRequest(ANIM_AGENT_CUSTOMIZE, ANIM_REQUEST_START);
-			gAgent.setCustomAnim(TRUE);
-			gAgentAvatarp->startMotion(ANIM_AGENT_CUSTOMIZE);
-			LLMotion* turn_motion = gAgentAvatarp->findMotion(ANIM_AGENT_CUSTOMIZE);
-
-			if (turn_motion)
-			{
-				// delay camera animation long enough to play through turn animation
-				setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
-			}
-
-			gAgentAvatarp->invalidateAll();
-			gAgentAvatarp->updateMeshTextures();
+		if (turn_motion)
+		{
+			// delay camera animation long enough to play through turn animation
+			setAnimationDuration(turn_motion->getDuration() + CUSTOMIZE_AVATAR_CAMERA_ANIM_SLOP);
 		}
 	}
 
diff --git a/indra/newview/llagentpilot.cpp b/indra/newview/llagentpilot.cpp
index 734c502fcf69676804fd2b2328abfeb39bb3b257..c7872fc5f61e5f9ee169947061db292e48fef769 100644
--- a/indra/newview/llagentpilot.cpp
+++ b/indra/newview/llagentpilot.cpp
@@ -139,7 +139,7 @@ void LLAgentPilot::loadXML(const std::string& filename)
 
 	mActions.reset();
 	LLSD record;
-	while (!file.eof() && LLSDSerialize::fromXML(record, file))
+	while (!file.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(record, file))
 	{
 		Action action;
 		action.mTime = record["time"].asReal();
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
old mode 100644
new mode 100755
index e441f21f904374bc0530159c901b8080464dd4c2..c88694ef76b9054cfbe20543c33027a4681c0d07
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -47,7 +47,7 @@
 #include "lltooldraganddrop.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "llwearablelist.h"
 
 #include <boost/scoped_ptr.hpp>
@@ -56,24 +56,21 @@ LLAgentWearables gAgentWearables;
 
 BOOL LLAgentWearables::mInitialWearablesUpdateReceived = FALSE;
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 ///////////////////////////////////////////////////////////////////////////////
 
 // Callback to wear and start editing an item that has just been created.
-class LLWearAndEditCallback : public LLInventoryCallback
+void wear_and_edit_cb(const LLUUID& inv_item)
 {
-	void fire(const LLUUID& inv_item)
-	{
-		if (inv_item.isNull()) return;
-
-		// Request editing the item after it gets worn.
-		gAgentWearables.requestEditingWearable(inv_item);
-
-		// Wear it.
-		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
-	}
-};
+	if (inv_item.isNull()) return;
+	
+	// Request editing the item after it gets worn.
+	gAgentWearables.requestEditingWearable(inv_item);
+	
+	// Wear it.
+	LLAppearanceMgr::instance().wearItemOnAvatar(inv_item);
+}
 
 ///////////////////////////////////////////////////////////////////////////////
 
@@ -82,7 +79,7 @@ class LLWearAndEditCallback : public LLInventoryCallback
 // wearable type stored in asset is some other value.
 // Calling this function whenever a wearable is added to increase visibility if this problem
 // turns up in other inventories.
-void checkWearableAgainstInventory(LLWearable *wearable)
+void checkWearableAgainstInventory(LLViewerWearable *wearable)
 {
 	if (wearable->getItemID().isNull())
 		return;
@@ -119,7 +116,7 @@ void LLAgentWearables::dump()
 		llinfos << "Type: " << i << " count " << count << llendl;
 		for (U32 j=0; j<count; j++)
 		{
-			LLWearable* wearable = getWearable((LLWearableType::EType)i,j);
+			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)i,j);
 			if (wearable == NULL)
 			{
 				llinfos << "    " << j << " NULL wearable" << llendl;
@@ -159,6 +156,7 @@ struct LLAgentDumper
 };
 
 LLAgentWearables::LLAgentWearables() :
+	LLWearableData(),
 	mWearablesLoaded(FALSE)
 ,	mCOFChangeInProgress(false)
 {
@@ -182,12 +180,11 @@ void LLAgentWearables::initClass()
 }
 
 void LLAgentWearables::setAvatarObject(LLVOAvatarSelf *avatar)
-{ 
-	if (avatar)
-	{
-		avatar->outputRezTiming("Sending wearables request");
-		sendAgentWearablesRequest();
-	}
+{
+	llassert(avatar);
+	avatar->outputRezTiming("Sending wearables request");
+	sendAgentWearablesRequest();
+	setAvatarAppearance(avatar);
 }
 
 // wearables
@@ -213,12 +210,13 @@ LLAgentWearables::sendAgentWearablesUpdateCallback::~sendAgentWearablesUpdateCal
  * @param todo Bitmask of actions to take on completion.
  */
 LLAgentWearables::addWearableToAgentInventoryCallback::addWearableToAgentInventoryCallback(
-	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLWearable* wearable, U32 todo) :
+	LLPointer<LLRefCount> cb, LLWearableType::EType type, U32 index, LLViewerWearable* wearable, U32 todo, const std::string description) :
 	mType(type),
 	mIndex(index),	
 	mWearable(wearable),
 	mTodo(todo),
-	mCB(cb)
+	mCB(cb),
+	mDescription(description)
 {
 	llinfos << "constructor" << llendl;
 }
@@ -258,14 +256,14 @@ void LLAgentWearables::addWearableToAgentInventoryCallback::fire(const LLUUID& i
 	}
 	if (mTodo & CALL_WEARITEM)
 	{
-		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true);
+		LLAppearanceMgr::instance().addCOFItemLink(inv_item, true, NULL, mDescription);
 	}
 }
 
 void LLAgentWearables::addWearabletoAgentInventoryDone(const LLWearableType::EType type,
 													   const U32 index,
 													   const LLUUID& item_id,
-													   LLWearable* wearable)
+													   LLViewerWearable* wearable)
 {
 	llinfos << "type " << type << " index " << index << " item " << item_id.asString() << llendl;
 
@@ -312,7 +310,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 	{
 		for (U32 index=0; index < getWearableCount((LLWearableType::EType)type); ++index)
 		{
-			LLWearable* wearable = getWearable((LLWearableType::EType)type,index);
+			LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type,index);
 			if (wearable)
 			{
 				if (wearable->getItemID().isNull())
@@ -354,7 +352,7 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 		U8 type_u8 = (U8)type;
 		gMessageSystem->addU8Fast(_PREHASH_WearableType, type_u8);
 
-		LLWearable* wearable = getWearable((LLWearableType::EType)type, 0);
+		LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)type, 0);
 		if (wearable)
 		{
 			//llinfos << "Sending wearable " << wearable->getName() << llendl;
@@ -382,14 +380,14 @@ void LLAgentWearables::sendAgentWearablesUpdate()
 void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update,
 									const std::string new_name)
 {
-	LLWearable* old_wearable = getWearable(type, index);
+	LLViewerWearable* old_wearable = getViewerWearable(type, index);
 	if(!old_wearable) return;
 	bool name_changed = !new_name.empty() && (new_name != old_wearable->getName());
 	if (name_changed || old_wearable->isDirty() || old_wearable->isOldVersion())
 	{
 		LLUUID old_item_id = old_wearable->getItemID();
-		LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
-		new_wearable->setItemID(old_item_id); // should this be in LLWearable::copyDataFrom()?
+		LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+		new_wearable->setItemID(old_item_id); // should this be in LLViewerWearable::copyDataFrom()?
 		setWearable(type,index,new_wearable);
 
 		// old_wearable may still be referred to by other inventory items. Revert
@@ -458,6 +456,7 @@ void LLAgentWearables::saveWearable(const LLWearableType::EType type, const U32
 void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 									  const U32 index,
 									  const std::string& new_name,
+									  const std::string& description,
 									  BOOL save_in_lost_and_found)
 {
 	if (!isWearableCopyable(type, index))
@@ -465,7 +464,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 		llwarns << "LLAgent::saveWearableAs() not copyable." << llendl;
 		return;
 	}
-	LLWearable* old_wearable = getWearable(type, index);
+	LLViewerWearable* old_wearable = getViewerWearable(type, index);
 	if (!old_wearable)
 	{
 		llwarns << "LLAgent::saveWearableAs() no old wearable." << llendl;
@@ -480,7 +479,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 	}
 	std::string trunc_name(new_name);
 	LLStringUtil::truncate(trunc_name, DB_INV_ITEM_NAME_STR_LEN);
-	LLWearable* new_wearable = LLWearableList::instance().createCopy(
+	LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(
 		old_wearable,
 		trunc_name);
 	LLPointer<LLInventoryCallback> cb =
@@ -489,7 +488,9 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 			type,
 			index,
 			new_wearable,
-			addWearableToAgentInventoryCallback::CALL_WEARITEM);
+			addWearableToAgentInventoryCallback::CALL_WEARITEM,
+			description
+			);
 	LLUUID category_id;
 	if (save_in_lost_and_found)
 	{
@@ -518,7 +519,7 @@ void LLAgentWearables::saveWearableAs(const LLWearableType::EType type,
 
 void LLAgentWearables::revertWearable(const LLWearableType::EType type, const U32 index)
 {
-	LLWearable* wearable = getWearable(type, index);
+	LLViewerWearable* wearable = getViewerWearable(type, index);
 	llassert(wearable);
 	if (wearable)
 	{
@@ -553,13 +554,13 @@ void LLAgentWearables::setWearableName(const LLUUID& item_id, const std::string&
 			LLUUID curr_item_id = getWearableItemID((LLWearableType::EType)i,j);
 			if (curr_item_id == item_id)
 			{
-				LLWearable* old_wearable = getWearable((LLWearableType::EType)i,j);
+				LLViewerWearable* old_wearable = getViewerWearable((LLWearableType::EType)i,j);
 				llassert(old_wearable);
 				if (!old_wearable) continue;
 
 				std::string old_name = old_wearable->getName();
 				old_wearable->setName(new_name);
-				LLWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
+				LLViewerWearable* new_wearable = LLWearableList::instance().createCopy(old_wearable);
 				new_wearable->setItemID(item_id);
 				LLInventoryItem* item = gInventory.getItem(item_id);
 				if (item)
@@ -640,14 +641,14 @@ LLInventoryItem* LLAgentWearables::getWearableInventoryItem(LLWearableType::ETyp
 	return item;
 }
 
-const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
+const LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id) const
 {
 	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			const LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			const LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 			{
 				return curr_wearable;
@@ -657,14 +658,14 @@ const LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 	return NULL;
 }
 
-LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
+LLViewerWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 {
 	const LLUUID& base_item_id = gInventory.getLinkedItemID(item_id);
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getItemID() == base_item_id))
 			{
 				return curr_wearable;
@@ -674,13 +675,13 @@ LLWearable* LLAgentWearables::getWearableFromItemID(const LLUUID& item_id)
 	return NULL;
 }
 
-LLWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) 
+LLViewerWearable*	LLAgentWearables::getWearableFromAssetID(const LLUUID& asset_id) 
 {
 	for (S32 i=0; i < LLWearableType::WT_COUNT; i++)
 	{
 		for (U32 j=0; j < getWearableCount((LLWearableType::EType)i); j++)
 		{
-			LLWearable * curr_wearable = getWearable((LLWearableType::EType)i, j);
+			LLViewerWearable * curr_wearable = getViewerWearable((LLWearableType::EType)i, j);
 			if (curr_wearable && (curr_wearable->getAssetID() == asset_id))
 			{
 				return curr_wearable;
@@ -699,215 +700,55 @@ void LLAgentWearables::sendAgentWearablesRequest()
 	gAgent.sendReliableMessage();
 }
 
-// static
-BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
-{
-	return (gAgentWearables.getWearableCount(type) > 0);
-}
-
-LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index)
-{
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return NULL;
-	}
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		return NULL;
-	}
-	else
-	{
-		return wearable_vec[index];
-	}
-}
-
-void LLAgentWearables::setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable)
+LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/)
 {
-
-	LLWearable *old_wearable = getWearable(type,index);
-	if (!old_wearable)
-	{
-		pushWearable(type,wearable);
-		return;
-	}
-	
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		llwarns << "invalid type, type " << type << " index " << index << llendl; 
-		return;
-	}
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		llwarns << "invalid index, type " << type << " index " << index << llendl; 
-	}
-	else
-	{
-		wearable_vec[index] = wearable;
-		old_wearable->setLabelUpdated();
-		wearableUpdated(wearable);
-		checkWearableAgainstInventory(wearable);
-	}
+	return dynamic_cast<LLViewerWearable*> (getWearable(type, index));
 }
 
-U32 LLAgentWearables::pushWearable(const LLWearableType::EType type, LLWearable *wearable)
+const LLViewerWearable* LLAgentWearables::getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const
 {
-	if (wearable == NULL)
-	{
-		// no null wearables please!
-		llwarns << "Null wearable sent for type " << type << llendl;
-		return MAX_CLOTHING_PER_TYPE;
-	}
-	if (type < LLWearableType::WT_COUNT || mWearableDatas[type].size() < MAX_CLOTHING_PER_TYPE)
-	{
-		mWearableDatas[type].push_back(wearable);
-		wearableUpdated(wearable);
-		checkWearableAgainstInventory(wearable);
-		return mWearableDatas[type].size()-1;
-	}
-	return MAX_CLOTHING_PER_TYPE;
+	return dynamic_cast<const LLViewerWearable*> (getWearable(type, index));
 }
 
-void LLAgentWearables::wearableUpdated(LLWearable *wearable)
+// static
+BOOL LLAgentWearables::selfHasWearable(LLWearableType::EType type)
 {
-	gAgentAvatarp->wearableUpdated(wearable->getType(), FALSE);
-	wearable->refreshName();
-	wearable->setLabelUpdated();
-
-	wearable->pullCrossWearableValues();
-
-	// Hack pt 2. If the wearable we just loaded has definition version 24,
-	// then force a re-save of this wearable after slamming the version number to 22.
-	// This number was incorrectly incremented for internal builds before release, and
-	// this fix will ensure that the affected wearables are re-saved with the right version number.
-	// the versions themselves are compatible. This code can be removed before release.
-	if( wearable->getDefinitionVersion() == 24 )
-	{
-		wearable->setDefinitionVersion(22);
-		U32 index = getWearableIndex(wearable);
-		llinfos << "forcing werable type " << wearable->getType() << " to version 22 from 24" << llendl;
-		saveWearable(wearable->getType(),index,TRUE);
-	}
-
+	return (gAgentWearables.getWearableCount(type) > 0);
 }
 
-void LLAgentWearables::popWearable(LLWearable *wearable)
+// virtual
+void LLAgentWearables::wearableUpdated(LLWearable *wearable, BOOL removed)
 {
-	if (wearable == NULL)
+	if (isAgentAvatarValid())
 	{
-		// nothing to do here. move along.
-		return;
+		const BOOL upload_result = removed;
+		gAgentAvatarp->wearableUpdated(wearable->getType(), upload_result);
 	}
 
-	U32 index = getWearableIndex(wearable);
-	LLWearableType::EType type = wearable->getType();
+	LLWearableData::wearableUpdated(wearable, removed);
 
-	if (index < MAX_CLOTHING_PER_TYPE && index < getWearableCount(type))
+	if (!removed)
 	{
-		popWearable(type, index);
-	}
-}
+		LLViewerWearable* viewer_wearable = dynamic_cast<LLViewerWearable*>(wearable);
+		viewer_wearable->refreshName();
 
-void LLAgentWearables::popWearable(const LLWearableType::EType type, U32 index)
-{
-	LLWearable *wearable = getWearable(type, index);
-	if (wearable)
-	{
-		mWearableDatas[type].erase(mWearableDatas[type].begin() + index);
-		if (isAgentAvatarValid())
+		// Hack pt 2. If the wearable we just loaded has definition version 24,
+		// then force a re-save of this wearable after slamming the version number to 22.
+		// This number was incorrectly incremented for internal builds before release, and
+		// this fix will ensure that the affected wearables are re-saved with the right version number.
+		// the versions themselves are compatible. This code can be removed before release.
+		if( wearable->getDefinitionVersion() == 24 )
 		{
-		gAgentAvatarp->wearableUpdated(wearable->getType(), TRUE);
+			wearable->setDefinitionVersion(22);
+			U32 index = getWearableIndex(wearable);
+			llinfos << "forcing wearable type " << wearable->getType() << " to version 22 from 24" << llendl;
+			saveWearable(wearable->getType(),index,TRUE);
 		}
-		wearable->setLabelUpdated();
-	}
-}
 
-U32	LLAgentWearables::getWearableIndex(const LLWearable *wearable) const
-{
-	if (wearable == NULL)
-	{
-		return MAX_CLOTHING_PER_TYPE;
+		checkWearableAgainstInventory(viewer_wearable);
 	}
-
-	const LLWearableType::EType type = wearable->getType();
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		llwarns << "tried to get wearable index with an invalid type!" << llendl;
-		return MAX_CLOTHING_PER_TYPE;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	for(U32 index = 0; index < wearable_vec.size(); index++)
-	{
-		if (wearable_vec[index] == wearable)
-		{
-			return index;
-		}
-	}
-
-	return MAX_CLOTHING_PER_TYPE;
 }
 
-const LLWearable* LLAgentWearables::getWearable(const LLWearableType::EType type, U32 index) const
-{
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return NULL;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (index>=wearable_vec.size())
-	{
-		return NULL;
-	}
-	else
-	{
-		return wearable_vec[index];
-	}
-}
-
-LLWearable* LLAgentWearables::getTopWearable(const LLWearableType::EType type)
-{
-	U32 count = getWearableCount(type);
-	if ( count == 0)
-	{
-		return NULL;
-	}
-
-	return getWearable(type, count-1);
-}
-
-LLWearable* LLAgentWearables::getBottomWearable(const LLWearableType::EType type)
-{
-	if (getWearableCount(type) == 0)
-	{
-		return NULL;
-	}
-
-	return getWearable(type, 0);
-}
-
-U32 LLAgentWearables::getWearableCount(const LLWearableType::EType type) const
-{
-	wearableentry_map_t::const_iterator wearable_iter = mWearableDatas.find(type);
-	if (wearable_iter == mWearableDatas.end())
-	{
-		return 0;
-	}
-	const wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	return wearable_vec.size();
-}
-
-U32 LLAgentWearables::getWearableCount(const U32 tex_index) const
-{
-	const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((LLVOAvatarDefines::ETextureIndex)tex_index);
-	return getWearableCount(wearable_type);
-}
-
-
 BOOL LLAgentWearables::itemUpdatePending(const LLUUID& item_id) const
 {
 	return mItemsAwaitingWearableUpdate.find(item_id) != mItemsAwaitingWearableUpdate.end();
@@ -920,7 +761,7 @@ U32 LLAgentWearables::itemUpdatePendingCount() const
 
 const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32 index) const
 {
-	const LLWearable *wearable = getWearable(type,index);
+	const LLViewerWearable *wearable = getViewerWearable(type,index);
 	if (wearable)
 		return wearable->getItemID();
 	else
@@ -929,7 +770,7 @@ const LLUUID LLAgentWearables::getWearableItemID(LLWearableType::EType type, U32
 
 const LLUUID LLAgentWearables::getWearableAssetID(LLWearableType::EType type, U32 index) const
 {
-	const LLWearable *wearable = getWearable(type,index);
+	const LLViewerWearable *wearable = getViewerWearable(type,index);
 	if (wearable)
 		return wearable->getAssetID();
 	else
@@ -955,8 +796,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 
 	if (isAgentAvatarValid())
 	{
-		//gAgentAvatarp->clearPhases(); // reset phase timers for outfit loading.
-		gAgentAvatarp->getPhases().startPhase("process_initial_wearables_update");
+		gAgentAvatarp->startPhase("process_initial_wearables_update");
 		gAgentAvatarp->outputRezTiming("Received initial wearables update");
 	}
 
@@ -1012,7 +852,7 @@ void LLAgentWearables::processAgentInitialWearablesUpdate(LLMessageSystem* mesgs
 			gMessageSystem->getUUIDFast(_PREHASH_WearableData, _PREHASH_AssetID, asset_id, i);
 			if (asset_id.isNull())
 			{
-				LLWearable::removeFromAvatar(type, FALSE);
+				LLViewerWearable::removeFromAvatar(type, FALSE);
 			}
 			else
 			{
@@ -1058,7 +898,7 @@ void LLAgentWearables::recoverMissingWearable(const LLWearableType::EType type,
 	// Try to recover by replacing missing wearable with a new one.
 	LLNotificationsUtil::add("ReplacedMissingWearable");
 	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type) << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
-	LLWearable* new_wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* new_wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 
 	setWearable(type,index,new_wearable);
 	//new_wearable->writeToAvatar(TRUE);
@@ -1093,9 +933,9 @@ void LLAgentWearables::recoverMissingWearableDone()
 	}
 }
 
-void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index)
+void LLAgentWearables::addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index)
 {
-	LLWearable* wearable = getWearable((LLWearableType::EType)wearable_type, wearable_index);
+	LLViewerWearable* wearable = getViewerWearable((LLWearableType::EType)wearable_type, wearable_index);
 	if (!wearable)
 	{
 		llerrs << "Tried to add local texture object to invalid wearable with type " << wearable_type << " and index " << wearable_index << llendl;
@@ -1125,10 +965,10 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 		llinfos << "All items created" << llendl;
 		LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
 		LLAppearanceMgr::instance().linkAll(LLAppearanceMgr::instance().getCOF(),
-												mItemsToLink,
-												link_waiter);
+											mItemsToLink,
+											link_waiter);
 	}
-	void addPendingWearable(LLWearable *wearable)
+	void addPendingWearable(LLViewerWearable *wearable)
 	{
 		if (!wearable)
 		{
@@ -1163,7 +1003,7 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 			LLWearableType::EType type = item->getWearableType();
 			if (type < LLWearableType::WT_COUNT)
 			{
-				LLWearable *wearable = mWearablesAwaitingItems[type];
+				LLViewerWearable *wearable = mWearablesAwaitingItems[type];
 				if (wearable)
 					wearable->setItemID(inv_item);
 			}
@@ -1176,7 +1016,7 @@ class OnWearableItemCreatedCB: public LLInventoryCallback
 	
 private:
 	LLInventoryModel::item_array_t mItemsToLink;
-	std::vector<LLWearable*> mWearablesAwaitingItems;
+	std::vector<LLViewerWearable*> mWearablesAwaitingItems;
 };
 
 void LLAgentWearables::createStandardWearables()
@@ -1208,7 +1048,7 @@ void LLAgentWearables::createStandardWearables()
 		if (create[i])
 		{
 			llassert(getWearableCount((LLWearableType::EType)i) == 0);
-			LLWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i);
+			LLViewerWearable* wearable = LLWearableList::instance().createNewWearable((LLWearableType::EType)i, gAgentAvatarp);
 			((OnWearableItemCreatedCB*)(&(*cb)))->addPendingWearable(wearable);
 			// no need to update here...
 			LLUUID category_id = LLUUID::null;
@@ -1267,7 +1107,7 @@ void LLAgentWearables::makeNewOutfitDone(S32 type, U32 index)
 
 
 void LLAgentWearables::addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
-												   LLWearable* wearable,
+												   LLViewerWearable* wearable,
 												   const LLUUID& category_id,
 												   BOOL notify)
 {
@@ -1305,7 +1145,7 @@ void LLAgentWearables::removeWearable(const LLWearableType::EType type, bool do_
 	}
 	else
 	{
-		LLWearable* old_wearable = getWearable(type,index);
+		LLViewerWearable* old_wearable = getViewerWearable(type,index);
 		
 		if (old_wearable)
 		{
@@ -1360,10 +1200,10 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 	//LLAgentDumper dumper("removeWearable");
 	if (do_remove_all)
 	{
-		S32 max_entry = mWearableDatas[type].size()-1;
+		S32 max_entry = getWearableCount(type)-1;
 		for (S32 i=max_entry; i>=0; i--)
 		{
-			LLWearable* old_wearable = getWearable(type,i);
+			LLViewerWearable* old_wearable = getViewerWearable(type,i);
 			//queryWearableCache(); // moved below
 			if (old_wearable)
 			{
@@ -1371,11 +1211,11 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 				old_wearable->removeFromAvatar(TRUE);
 			}
 		}
-		mWearableDatas[type].clear();
+		clearWearableType(type);
 	}
 	else
 	{
-		LLWearable* old_wearable = getWearable(type, index);
+		LLViewerWearable* old_wearable = getViewerWearable(type, index);
 		//queryWearableCache(); // moved below
 
 		if (old_wearable)
@@ -1394,7 +1234,7 @@ void LLAgentWearables::removeWearableFinal(const LLWearableType::EType type, boo
 
 // Assumes existing wearables are not dirty.
 void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& items,
-										 const LLDynamicArray< LLWearable* >& wearables,
+										 const LLDynamicArray< LLViewerWearable* >& wearables,
 										 BOOL remove)
 {
 	llinfos << "setWearableOutfit() start" << llendl;
@@ -1419,7 +1259,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 	S32 i;
 	for (i = 0; i < count; i++)
 	{
-		LLWearable* new_wearable = wearables[i];
+		LLViewerWearable* new_wearable = wearables[i];
 		LLPointer<LLInventoryItem> new_item = items[i];
 
 		llassert(new_wearable);
@@ -1439,8 +1279,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 			{
 				pushWearable(type,new_wearable);
 			}
-			wearableUpdated(new_wearable);
-			checkWearableAgainstInventory(new_wearable);
+			const BOOL removed = FALSE;
+			wearableUpdated(new_wearable, removed);
 		}
 	}
 
@@ -1476,7 +1316,7 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 
 
 // User has picked "wear on avatar" from a menu.
-void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
 {
 	//LLAgentDumper dumper("setWearableItem");
 	if (isWearingItem(new_item->getUUID()))
@@ -1491,7 +1331,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
 	{
 		// Remove old wearable, if any
 		// MULTI_WEARABLE: hardwired to 0
-		LLWearable* old_wearable = getWearable(type,0);
+		LLViewerWearable* old_wearable = getViewerWearable(type,0);
 		if (old_wearable)
 		{
 			const LLUUID& old_item_id = old_wearable->getItemID();
@@ -1517,7 +1357,7 @@ void LLAgentWearables::setWearableItem(LLInventoryItem* new_item, LLWearable* ne
 }
 
 // static 
-bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable)
+bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLInventoryItem* new_item = gInventory.getItem(notification["payload"]["item_id"].asUUID());
@@ -1553,16 +1393,17 @@ bool LLAgentWearables::onSetWearableDialog(const LLSD& notification, const LLSD&
 
 // Called from setWearableItem() and onSetWearableDialog() to actually set the wearable.
 // MULTI_WEARABLE: unify code after null objects are gone.
-void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append)
+void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append)
 {
 	const LLWearableType::EType type = new_wearable->getType();
 
 	if (do_append && getWearableItemID(type,0).notNull())
 	{
 		new_wearable->setItemID(new_item->getUUID());
-		mWearableDatas[type].push_back(new_wearable);
+		const bool trigger_updated = false;
+		pushWearable(type, new_wearable, trigger_updated);
 		llinfos << "Added additional wearable for type " << type
-				<< " size is now " << mWearableDatas[type].size() << llendl;
+				<< " size is now " << getWearableCount(type) << llendl;
 		checkWearableAgainstInventory(new_wearable);
 	}
 	else
@@ -1570,7 +1411,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 		// Replace the old wearable with a new one.
 		llassert(new_item->getAssetUUID() == new_wearable->getAssetID());
 
-		LLWearable *old_wearable = getWearable(type,0);
+		LLViewerWearable *old_wearable = getViewerWearable(type,0);
 		LLUUID old_item_id;
 		if (old_wearable)
 		{
@@ -1585,7 +1426,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 			gInventory.notifyObservers();
 		}
 		llinfos << "Replaced current element 0 for type " << type
-				<< " size is now " << mWearableDatas[type].size() << llendl;
+				<< " size is now " << getWearableCount(type) << llendl;
 	}
 
 	//llinfos << "LLVOAvatar::setWearableItem()" << llendl;
@@ -1597,7 +1438,7 @@ void LLAgentWearables::setWearableFinal(LLInventoryItem* new_item, LLWearable* n
 
 void LLAgentWearables::queryWearableCache()
 {
-	if (!areWearablesLoaded())
+	if (!areWearablesLoaded() || (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion()))
 	{
 		return;
 	}
@@ -1626,7 +1467,7 @@ void LLAgentWearables::queryWearableCache()
 			num_queries++;
 			// *NOTE: make sure at least one request gets packed
 
-			ETextureIndex te_index = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
+			ETextureIndex te_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)baked_index);
 
 			//llinfos << "Requesting texture for hash " << hash << " in baked texture slot " << baked_index << llendl;
 			gMessageSystem->nextBlockFast(_PREHASH_WearableData);
@@ -1645,53 +1486,21 @@ void LLAgentWearables::queryWearableCache()
 			gAgentAvatarp->outputRezTiming("Fetching textures from cache");
 		}
 
-		LL_INFOS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
+		LL_DEBUGS("Avatar") << gAgentAvatarp->avString() << "Requesting texture cache entry for " << num_queries << " baked textures" << LL_ENDL;
 		gMessageSystem->sendReliable(gAgent.getRegion()->getHost());
 		gAgentQueryManager.mNumPendingQueries++;
 		gAgentQueryManager.mWearablesCacheQueryID++;
 	}
 }
 
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
-												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
+// virtual
+void LLAgentWearables::invalidateBakedTextureHash(LLMD5& hash) const
 {
-	LLUUID hash_id;
-	bool hash_computed = false;
-	LLMD5 hash;
-	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
-
-	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
-	{
-		const LLWearableType::EType baked_type = baked_dict->mWearables[i];
-		const U32 num_wearables = getWearableCount(baked_type);
-		for (U32 index = 0; index < num_wearables; ++index)
-		{
-			const LLWearable* wearable = getWearable(baked_type,index);
-			if (wearable)
-			{
-				LLUUID asset_id = wearable->getAssetID();
-				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
-				hash_computed = true;
-			}
-		}
-	}
-	if (hash_computed)
+	// Add some garbage into the hash so that it becomes invalid.
+	if (isAgentAvatarValid())
 	{
-		hash.update((const unsigned char*)baked_dict->mWearablesHashID.mData, UUID_BYTES);
-
-		// Add some garbage into the hash so that it becomes invalid.
-		if (!generate_valid_hash)
-		{
-			if (isAgentAvatarValid())
-			{
-				hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
-			}
-		}
-		hash.finalize();
-		hash.raw_digest(hash_id.mData);
+		hash.update((const unsigned char*)gAgentAvatarp->getID().mData, UUID_BYTES);
 	}
-
-	return hash_id;
 }
 
 // User has picked "remove from avatar" from a menu.
@@ -1715,7 +1524,7 @@ void LLAgentWearables::userRemoveWearablesOfType(const LLWearableType::EType &ty
 	}
 }
 
-// Combines userRemoveAllAttachments() and userAttachMultipleAttachments() logic to
+// Combines userRemoveMulipleAttachments() and userAttachMultipleAttachments() logic to
 // get attachments into desired state with minimal number of adds/removes.
 void LLAgentWearables::userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array)
 {
@@ -1811,31 +1620,6 @@ void LLAgentWearables::userRemoveMultipleAttachments(llvo_vec_t& objects_to_remo
 	gMessageSystem->sendReliable(gAgent.getRegionHost());
 }
 
-void LLAgentWearables::userRemoveAllAttachments()
-{
-	if (!isAgentAvatarValid()) return;
-
-	llvo_vec_t objects_to_remove;
-	
-	for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
-		 iter != gAgentAvatarp->mAttachmentPoints.end();)
-	{
-		LLVOAvatar::attachment_map_t::iterator curiter = iter++;
-		LLViewerJointAttachment* attachment = curiter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			LLViewerObject *attached_object = (*attachment_iter);
-			if (attached_object)
-			{
-				objects_to_remove.push_back(attached_object);
-			}
-		}
-	}
-	userRemoveMultipleAttachments(objects_to_remove);
-}
-
 void LLAgentWearables::userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array)
 {
 	// Build a compound message to send all the objects that need to be rezzed.
@@ -1900,7 +1684,7 @@ void LLAgentWearables::checkWearablesLoaded() const
 
 // Returns false if the given wearable is already topmost/bottommost
 // (depending on closer_to_body parameter).
-bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body)
+bool LLAgentWearables::canMoveWearable(const LLUUID& item_id, bool closer_to_body) const
 {
 	const LLWearable* wearable = getWearableFromItemID(item_id);
 	if (!wearable) return false;
@@ -1928,7 +1712,7 @@ void LLAgentWearables::updateWearablesLoaded()
 	}
 }
 
-bool LLAgentWearables::canWearableBeRemoved(const LLWearable* wearable) const
+bool LLAgentWearables::canWearableBeRemoved(const LLViewerWearable* wearable) const
 {
 	if (!wearable) return false;
 	
@@ -1943,7 +1727,7 @@ void LLAgentWearables::animateAllWearableParams(F32 delta, BOOL upload_bake)
 	{
 		for (S32 count = 0; count < (S32)getWearableCount((LLWearableType::EType)type); ++count)
 		{
-			LLWearable *wearable = getWearable((LLWearableType::EType)type,count);
+			LLViewerWearable *wearable = getViewerWearable((LLWearableType::EType)type,count);
 			llassert(wearable);
 			if (wearable)
 			{
@@ -1958,28 +1742,39 @@ bool LLAgentWearables::moveWearable(const LLViewerInventoryItem* item, bool clos
 	if (!item) return false;
 	if (!item->isWearableType()) return false;
 
-	wearableentry_map_t::iterator wearable_iter = mWearableDatas.find(item->getWearableType());
-	if (wearable_iter == mWearableDatas.end()) return false;
-
-	wearableentry_vec_t& wearable_vec = wearable_iter->second;
-	if (wearable_vec.empty()) return false;
+	LLWearableType::EType type = item->getWearableType();
+	U32 wearable_count = getWearableCount(type);
+	if (0 == wearable_count) return false;
 
 	const LLUUID& asset_id = item->getAssetUUID();
 
 	//nowhere to move if the wearable is already on any boundary (closest to the body/furthest from the body)
-	if (closer_to_body && asset_id == wearable_vec.front()->getAssetID()) return false;
-	if (!closer_to_body && asset_id == wearable_vec.back()->getAssetID()) return false;
+	if (closer_to_body)
+	{
+		LLViewerWearable* bottom_wearable = dynamic_cast<LLViewerWearable*>( getBottomWearable(type) );
+		if (bottom_wearable->getAssetID() == asset_id)
+		{
+			return false;
+		}
+	}
+	else // !closer_to_body
+	{
+		LLViewerWearable* top_wearable = dynamic_cast<LLViewerWearable*>( getTopWearable(type) );
+		if (top_wearable->getAssetID() == asset_id)
+		{
+			return false;
+		}
+	}
 
-	for (U32 i = 0; i < wearable_vec.size(); ++i)
+	for (U32 i = 0; i < wearable_count; ++i)
 	{
-		LLWearable* wearable = wearable_vec[i];
+		LLViewerWearable* wearable = getViewerWearable(type, i);
 		if (!wearable) continue;
 		if (wearable->getAssetID() != asset_id) continue;
 		
 		//swapping wearables
 		U32 swap_i = closer_to_body ? i-1 : i+1;
-		wearable_vec[i] = wearable_vec[swap_i];
-		wearable_vec[swap_i] = wearable;
+		swapWearables(type, i, swap_i);
 		return true;
 	}
 
@@ -1991,10 +1786,10 @@ void LLAgentWearables::createWearable(LLWearableType::EType type, bool wear, con
 {
 	if (type == LLWearableType::WT_INVALID || type == LLWearableType::WT_NONE) return;
 
-	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 	LLAssetType::EType asset_type = wearable->getAssetType();
 	LLInventoryType::EType inv_type = LLInventoryType::IT_WEARABLE;
-	LLPointer<LLInventoryCallback> cb = wear ? new LLWearAndEditCallback : NULL;
+	LLPointer<LLInventoryCallback> cb = wear ? new LLBoostFuncInventoryCallback(wear_and_edit_cb) : NULL;
 	LLUUID folder_id;
 
 	if (parent_id.notNull())
@@ -2024,7 +1819,7 @@ void LLAgentWearables::editWearable(const LLUUID& item_id)
 		return;
 	}
 
-	LLWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
+	LLViewerWearable* wearable = gAgentWearables.getWearableFromItemID(item_id);
 	if (!wearable)
 	{
 		llwarns << "Cannot get wearable" << llendl;
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 5932be21c639be6626ed70fdf3fcac6d55ef6888..5be4648636792a5c883750c57b635b1ea5abb46a 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -36,16 +36,16 @@
 // newview
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
+#include "llwearabledata.h"
 
 class LLInventoryItem;
 class LLVOAvatarSelf;
-class LLWearable;
+class LLViewerWearable;
 class LLInitialWearablesFetch;
 class LLViewerObject;
-class LLTexLayerTemplate;
 
-class LLAgentWearables : public LLInitClass<LLAgentWearables>
+class LLAgentWearables : public LLInitClass<LLAgentWearables>, public LLWearableData
 {
 	//--------------------------------------------------------------------
 	// Constructors / destructors / Initializers
@@ -79,10 +79,10 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	bool			isCOFChangeInProgress() const { return mCOFChangeInProgress; }
 	void			updateWearablesLoaded();
 	void			checkWearablesLoaded() const;
-	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body);
+	bool			canMoveWearable(const LLUUID& item_id, bool closer_to_body) const;
 	
 	// Note: False for shape, skin, eyes, and hair, unless you have MORE than 1.
-	bool			canWearableBeRemoved(const LLWearable* wearable) const;
+	bool			canWearableBeRemoved(const LLViewerWearable* wearable) const;
 
 	void			animateAllWearableParams(F32 delta, BOOL upload_bake);
 
@@ -92,52 +92,38 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 public:
 	const LLUUID		getWearableItemID(LLWearableType::EType type, U32 index /*= 0*/) const;
 	const LLUUID		getWearableAssetID(LLWearableType::EType type, U32 index /*= 0*/) const;
-	const LLWearable*	getWearableFromItemID(const LLUUID& item_id) const;
-	LLWearable*	getWearableFromItemID(const LLUUID& item_id);
-	LLWearable*	getWearableFromAssetID(const LLUUID& asset_id);
+	const LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id) const;
+	LLViewerWearable*	getWearableFromItemID(const LLUUID& item_id);
+	LLViewerWearable*	getWearableFromAssetID(const LLUUID& asset_id);
+	LLViewerWearable*		getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
+	const LLViewerWearable*	getViewerWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
 	LLInventoryItem*	getWearableInventoryItem(LLWearableType::EType type, U32 index /*= 0*/);
 	static BOOL			selfHasWearable(LLWearableType::EType type);
-	LLWearable*			getWearable(const LLWearableType::EType type, U32 index /*= 0*/); 
-	const LLWearable* 	getWearable(const LLWearableType::EType type, U32 index /*= 0*/) const;
-	LLWearable*		getTopWearable(const LLWearableType::EType type);
-	LLWearable*		getBottomWearable(const LLWearableType::EType type);
-	U32				getWearableCount(const LLWearableType::EType type) const;
-	U32				getWearableCount(const U32 tex_index) const;
-
-	static const U32 MAX_CLOTHING_PER_TYPE = 5; 
-
 
 	//--------------------------------------------------------------------
 	// Setters
 	//--------------------------------------------------------------------
-
 private:
-	// Low-level data structure setter - public access is via setWearableItem, etc.
-	void 			setWearable(const LLWearableType::EType type, U32 index, LLWearable *wearable);
-	U32 			pushWearable(const LLWearableType::EType type, LLWearable *wearable);
-	void			wearableUpdated(LLWearable *wearable);
-	void 			popWearable(LLWearable *wearable);
-	void			popWearable(const LLWearableType::EType type, U32 index);
-	
+	/*virtual*/void	wearableUpdated(LLWearable *wearable, BOOL removed);
 public:
-	void			setWearableItem(LLInventoryItem* new_item, LLWearable* wearable, bool do_append = false);
-	void			setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLWearable* >& wearables, BOOL remove);
+	void			setWearableItem(LLInventoryItem* new_item, LLViewerWearable* wearable, bool do_append = false);
+	void			setWearableOutfit(const LLInventoryItem::item_array_t& items, const LLDynamicArray< LLViewerWearable* >& wearables, BOOL remove);
 	void			setWearableName(const LLUUID& item_id, const std::string& new_name);
-	void			addLocalTextureObject(const LLWearableType::EType wearable_type, const LLVOAvatarDefines::ETextureIndex texture_type, U32 wearable_index);
-	U32				getWearableIndex(const LLWearable *wearable) const;
+	// *TODO: Move this into llappearance/LLWearableData ?
+	void			addLocalTextureObject(const LLWearableType::EType wearable_type, const LLAvatarAppearanceDefines::ETextureIndex texture_type, U32 wearable_index);
 
 protected:
-	void			setWearableFinal(LLInventoryItem* new_item, LLWearable* new_wearable, bool do_append = false);
-	static bool		onSetWearableDialog(const LLSD& notification, const LLSD& response, LLWearable* wearable);
+	void			setWearableFinal(LLInventoryItem* new_item, LLViewerWearable* new_wearable, bool do_append = false);
+	static bool		onSetWearableDialog(const LLSD& notification, const LLSD& response, LLViewerWearable* wearable);
 
 	void			addWearableToAgentInventory(LLPointer<LLInventoryCallback> cb,
-												LLWearable* wearable, 
+												LLViewerWearable* wearable, 
 												const LLUUID& category_id = LLUUID::null,
 												BOOL notify = TRUE);
 	void 			addWearabletoAgentInventoryDone(const LLWearableType::EType type,
 													const U32 index,
 													const LLUUID& item_id,
-													LLWearable* wearable);
+													LLViewerWearable* wearable);
 	void			recoverMissingWearable(const LLWearableType::EType type, U32 index /*= 0*/);
 	void			recoverMissingWearableDone();
 
@@ -172,15 +158,14 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 public:
 	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
 	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
-	LLUUID			computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
-											BOOL generate_valid_hash = TRUE);
 
 protected:
+	/*virtual*/ void	invalidateBakedTextureHash(LLMD5& hash) const;
 	void			sendAgentWearablesUpdate();
 	void			sendAgentWearablesRequest();
 	void			queryWearableCache();
 	void 			updateServer();
-	static void		onInitialWearableAssetArrived(LLWearable* wearable, void* userdata);
+	static void		onInitialWearableAssetArrived(LLViewerWearable* wearable, void* userdata);
 
 	//--------------------------------------------------------------------
 	// Outfits
@@ -198,7 +183,7 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	// Save Wearables
 	//--------------------------------------------------------------------
 public:	
-	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, BOOL save_in_lost_and_found);
+	void			saveWearableAs(const LLWearableType::EType type, const U32 index, const std::string& new_name, const std::string& description, BOOL save_in_lost_and_found);
 	void			saveWearable(const LLWearableType::EType type, const U32 index, BOOL send_update = TRUE,
 								 const std::string new_name = "");
 	void			saveAllWearables();
@@ -215,7 +200,6 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 
 	static void 	userUpdateAttachments(LLInventoryModel::item_array_t& obj_item_array);
 	static void		userRemoveMultipleAttachments(llvo_vec_t& llvo_array);
-	static void		userRemoveAllAttachments();
 	static void		userAttachMultipleAttachments(LLInventoryModel::item_array_t& obj_item_array);
 
 	BOOL			itemUpdatePending(const LLUUID& item_id) const;
@@ -245,10 +229,6 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 	// Member variables
 	//--------------------------------------------------------------------
 private:
-	typedef std::vector<LLWearable*> wearableentry_vec_t; // all wearables of a certain type (EG all shirts)
-	typedef std::map<LLWearableType::EType, wearableentry_vec_t> wearableentry_map_t;	// wearable "categories" arranged by wearable type
-	wearableentry_map_t mWearableDatas;
-
 	static BOOL		mInitialWearablesUpdateReceived;
 	BOOL			mWearablesLoaded;
 	std::set<LLUUID>	mItemsAwaitingWearableUpdate;
@@ -289,15 +269,17 @@ class LLAgentWearables : public LLInitClass<LLAgentWearables>
 		addWearableToAgentInventoryCallback(LLPointer<LLRefCount> cb,
 											LLWearableType::EType type,
 											U32 index,
-											LLWearable* wearable,
-											U32 todo = CALL_NONE);
+											LLViewerWearable* wearable,
+											U32 todo = CALL_NONE,
+											const std::string description = "");
 		virtual void fire(const LLUUID& inv_item);
 	private:
 		LLWearableType::EType mType;
 		U32 mIndex;
-		LLWearable* mWearable;
+		LLViewerWearable* mWearable;
 		U32 mTodo;
 		LLPointer<LLRefCount> mCB;
+		std::string mDescription;
 	};
 
 }; // LLAgentWearables
diff --git a/indra/newview/llagentwearablesfetch.cpp b/indra/newview/llagentwearablesfetch.cpp
index e2417cdddb3528d17d68897dae5e8f547744e366..2d2d730396bc9583311d0e162ef9eff44d251f2b 100644
--- a/indra/newview/llagentwearablesfetch.cpp
+++ b/indra/newview/llagentwearablesfetch.cpp
@@ -35,61 +35,52 @@
 #include "llvoavatarself.h"
 
 
-class LLOrderMyOutfitsOnDestroy: public LLInventoryCallback
+void order_my_outfits_cb()
 {
-public:
-	LLOrderMyOutfitsOnDestroy() {};
-
-	virtual ~LLOrderMyOutfitsOnDestroy()
+	if (!LLApp::isRunning())
 	{
-		if (!LLApp::isRunning())
-		{
-			llwarns << "called during shutdown, skipping" << llendl;
-			return;
-		}
+		llwarns << "called during shutdown, skipping" << llendl;
+		return;
+	}
 		
-		const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
-		if (my_outfits_id.isNull()) return;
-
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
-		if (!cats) return;
+	const LLUUID& my_outfits_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_MY_OUTFITS);
+	if (my_outfits_id.isNull()) return;
 
-		//My Outfits should at least contain saved initial outfit and one another outfit
-		if (cats->size() < 2)
-		{
-			llwarning("My Outfits category was not populated properly", 0);
-			return;
-		}
+	LLInventoryModel::cat_array_t* cats;
+	LLInventoryModel::item_array_t* items;
+	gInventory.getDirectDescendentsOf(my_outfits_id, cats, items);
+	if (!cats) return;
 
-		llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
+	//My Outfits should at least contain saved initial outfit and one another outfit
+	if (cats->size() < 2)
+	{
+		llwarning("My Outfits category was not populated properly", 0);
+		return;
+	}
 
-		for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
-			outfit_iter != cats->end(); ++outfit_iter)
-		{
-			const LLUUID& cat_id = (*outfit_iter)->getUUID();
-			if (cat_id.isNull()) continue;
+	llinfos << "Starting updating My Outfits with wearables ordering information" << llendl;
 
-			// saved initial outfit already contains wearables ordering information
-			if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
+	for (LLInventoryModel::cat_array_t::iterator outfit_iter = cats->begin();
+		 outfit_iter != cats->end(); ++outfit_iter)
+	{
+		const LLUUID& cat_id = (*outfit_iter)->getUUID();
+		if (cat_id.isNull()) continue;
 
-			LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
-		}
+		// saved initial outfit already contains wearables ordering information
+		if (cat_id == LLAppearanceMgr::getInstance()->getBaseOutfitUUID()) continue;
 
-		llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+		LLAppearanceMgr::getInstance()->updateClothingOrderingInfo(cat_id);
 	}
 
-	/* virtual */ void fire(const LLUUID& inv_item) {};
-};
-
+	llinfos << "Finished updating My Outfits with wearables ordering information" << llendl;
+}
 
 LLInitialWearablesFetch::LLInitialWearablesFetch(const LLUUID& cof_id) :
 	LLInventoryFetchDescendentsObserver(cof_id)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().startPhase("initial_wearables_fetch");
+		gAgentAvatarp->startPhase("initial_wearables_fetch");
 		gAgentAvatarp->outputRezTiming("Initial wearables fetch started");
 	}
 }
@@ -108,7 +99,7 @@ void LLInitialWearablesFetch::done()
 	doOnIdleOneTime(boost::bind(&LLInitialWearablesFetch::processContents,this));
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().stopPhase("initial_wearables_fetch");
+		gAgentAvatarp->stopPhase("initial_wearables_fetch");
 		gAgentAvatarp->outputRezTiming("Initial wearables fetch done");
 	}
 }
@@ -342,7 +333,7 @@ void LLLibraryOutfitsFetch::folderDone()
 	}
 
 	mClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING);
-	mLibraryClothingID = gInventory.findCategoryUUIDForType(LLFolderType::FT_CLOTHING, false, true);
+	mLibraryClothingID = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_CLOTHING, false);
 
 	// If Library->Clothing->Initial Outfits exists, use that.
 	LLNameCategoryCollector matchFolderFunctor("Initial Outfits");
@@ -563,7 +554,7 @@ void LLLibraryOutfitsFetch::contentsDone()
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t wearable_array;
 	
-	LLPointer<LLOrderMyOutfitsOnDestroy> order_myoutfits_on_destroy = new LLOrderMyOutfitsOnDestroy;
+	LLPointer<LLInventoryCallback> order_myoutfits_on_destroy = new LLBoostFuncInventoryCallback(no_op_inventory_func, order_my_outfits_cb);
 
 	for (uuid_vec_t::const_iterator folder_iter = mImportedClothingFolders.begin();
 		 folder_iter != mImportedClothingFolders.end();
diff --git a/indra/newview/llappearance.h b/indra/newview/llappearance.h
index a28b77b1fcc4965094e77ad3201cdc6a37461e6c..05dfac4e420550006c69714c31f836757648dc65 100644
--- a/indra/newview/llappearance.h
+++ b/indra/newview/llappearance.h
@@ -38,14 +38,14 @@ class LLAppearance
 	void	addParam( S32 id, F32 value )				{ mParamMap[id] = value; }
 	F32		getParam( S32 id, F32 defval )				{ return get_if_there(mParamMap, id, defval ); }
 
-	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLVOAvatarDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
-	const LLUUID& getTexture( S32 te )					{ return ( te < LLVOAvatarDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
+	void	addTexture( S32 te, const LLUUID& uuid )	{ if( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) mTextures[te] = uuid; }
+	const LLUUID& getTexture( S32 te )					{ return ( te < LLAvatarAppearanceDefines::TEX_NUM_INDICES ) ? mTextures[te] : LLUUID::null; }
 	
-	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLVOAvatarDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
+	void	clear()										{ mParamMap.clear(); for( S32 i=0; i<LLAvatarAppearanceDefines::TEX_NUM_INDICES; i++ ) mTextures[i].setNull(); }
 
 	typedef std::map<S32, F32> param_map_t;
 	param_map_t mParamMap;
-	LLUUID	mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+	LLUUID	mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
 };
 
 #endif  // LL_LLAPPEARANCE_H
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
old mode 100644
new mode 100755
index 06a9892c7e2f09eed17cea5e7bd91c0b15eba8aa..652f199e2835686dbe4426cd4a47ac41bbe782b4
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -26,6 +26,7 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include <boost/lexical_cast.hpp>
 #include "llaccordionctrltab.h"
 #include "llagent.h"
 #include "llagentcamera.h"
@@ -49,6 +50,13 @@
 #include "llvoavatarself.h"
 #include "llviewerregion.h"
 #include "llwearablelist.h"
+#include "llsdutil.h"
+#include "llsdserialize.h"
+
+#if LL_MSVC
+// disable boost::lexical_cast warning
+#pragma warning (disable:4702)
+#endif
 
 std::string self_av_string()
 {
@@ -155,71 +163,342 @@ LLUUID findDescendentCategoryIDByName(const LLUUID& parent_id, const std::string
 	}
 }
 
-class LLWearInventoryCategoryCallback : public LLInventoryCallback
+// We want this to be much lower (e.g. 15.0 is usually fine), bumping
+// up for now until we can diagnose some cases of very slow response
+// to requests.
+const F32 DEFAULT_RETRY_AFTER_INTERVAL = 300.0;
+
+// Given the current back-end problems, retrying is causing too many
+// duplicate items. Bump this back to 2 once they are resolved (or can
+// leave at 0 if the operations become actually reliable).
+const S32 DEFAULT_MAX_RETRIES = 0;
+
+class LLCallAfterInventoryBatchMgr: public LLEventTimer 
 {
 public:
-	LLWearInventoryCategoryCallback(const LLUUID& cat_id, bool append)
-	{
-		mCatID = cat_id;
-		mAppend = append;
+	LLCallAfterInventoryBatchMgr(const LLUUID& dst_cat_id,
+								 const std::string& phase_name,
+								 nullary_func_t on_completion_func,
+								 nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		mDstCatID(dst_cat_id),
+		mTrackingPhase(phase_name),
+		mOnCompletionFunc(on_completion_func),
+		mOnFailureFunc(on_failure_func),
+		mRetryAfter(retry_after),
+		mMaxRetries(max_retries),
+		mPendingRequests(0),
+		mFailCount(0),
+		mCompletionOrFailureCalled(false),
+		mRetryCount(0),
+		LLEventTimer(5.0)
+	{
+		if (!mTrackingPhase.empty())
+		{
+			selfStartPhase(mTrackingPhase);
+		}
+	}
+
+	void addItems(LLInventoryModel::item_array_t& src_items)
+	{
+		for (LLInventoryModel::item_array_t::const_iterator it = src_items.begin();
+			 it != src_items.end();
+			 ++it)
+		{
+			LLViewerInventoryItem* item = *it;
+			llassert(item);
+			addItem(item->getUUID());
+		}
+	}
 
-		LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+	// Request or re-request operation for specified item.
+	void addItem(const LLUUID& item_id)
+	{
+		LL_DEBUGS("Avatar") << "item_id " << item_id << llendl;
 		
-		selfStartPhase("wear_inventory_category_callback");
+		if (!requestOperation(item_id))
+		{
+			LL_DEBUGS("Avatar") << "item_id " << item_id << " requestOperation false, skipping" << llendl;
+			return;
+		}
+
+		mPendingRequests++;
+		// On a re-request, this will reset the timer.
+		mWaitTimes[item_id] = LLTimer();
+		if (mRetryCounts.find(item_id) == mRetryCounts.end())
+		{
+			mRetryCounts[item_id] = 0;
+		}
+		else
+		{
+			mRetryCounts[item_id]++;
+		}
 	}
-	void fire(const LLUUID& item_id)
+
+	virtual bool requestOperation(const LLUUID& item_id) = 0;
+
+	void onOp(const LLUUID& src_id, const LLUUID& dst_id, LLTimer timestamp)
 	{
-		/*
-		 * Do nothing.  We only care about the destructor
-		 *
-		 * The reason for this is that this callback is used in a hack where the
-		 * same callback is given to dozens of items, and the destructor is called
-		 * after the last item has fired the event and dereferenced it -- if all
-		 * the events actually fire!
-		 */
-		LL_DEBUGS("Avatar") << self_av_string() << " fired on copied item, id " << item_id << LL_ENDL;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateLateOpRate"))
+		{
+			llwarns << "Simulating late operation by punting handling to later" << llendl;
+			doAfterInterval(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,src_id,dst_id,timestamp),
+							mRetryAfter);
+			return;
+		}
+		mPendingRequests--;
+		F32 elapsed = timestamp.getElapsedTimeF32();
+		LL_DEBUGS("Avatar") << "op done, src_id " << src_id << " dst_id " << dst_id << " after " << elapsed << " seconds" << llendl;
+		if (mWaitTimes.find(src_id) == mWaitTimes.end())
+		{
+			// No longer waiting for this item - either serviced
+			// already or gave up after too many retries.
+			llwarns << "duplicate or late operation, src_id " << src_id << "dst_id " << dst_id
+					<< " elapsed " << elapsed << " after end " << (S32) mCompletionOrFailureCalled << llendl;
+		}
+		mTimeStats.push(elapsed);
+		mWaitTimes.erase(src_id);
+		if (mWaitTimes.empty() && !mCompletionOrFailureCalled)
+		{
+			onCompletionOrFailure();
+		}
 	}
 
-protected:
-	~LLWearInventoryCategoryCallback()
+	void onCompletionOrFailure()
 	{
-		LL_INFOS("Avatar") << self_av_string() << "done all inventory callbacks" << LL_ENDL;
+		assert (!mCompletionOrFailureCalled);
+		mCompletionOrFailureCalled = true;
 		
-		selfStopPhase("wear_inventory_category_callback");
-
-		// Is the destructor called by ordinary dereference, or because the app's shutting down?
-		// If the inventory callback manager goes away, we're shutting down, no longer want the callback.
-		if( LLInventoryCallbackManager::is_instantiated() )
+		// Will never call onCompletion() if any item has been flagged as
+		// a failure - otherwise could wind up with corrupted
+		// outfit, involuntary nudity, etc.
+		reportStats();
+		if (!mTrackingPhase.empty())
 		{
-			LLAppearanceMgr::instance().wearInventoryCategoryOnAvatar(gInventory.getCategory(mCatID), mAppend);
+			selfStopPhase(mTrackingPhase);
+		}
+		if (!mFailCount)
+		{
+			onCompletion();
 		}
 		else
 		{
-			llwarns << self_av_string() << "Dropping unhandled LLWearInventoryCategoryCallback" << llendl;
+			onFailure();
 		}
 	}
 
-private:
-	LLUUID mCatID;
-	bool mAppend;
-};
+	void onFailure()
+	{
+		llinfos << "failed" << llendl;
+		mOnFailureFunc();
+	}
 
+	void onCompletion()
+	{
+		llinfos << "done" << llendl;
+		mOnCompletionFunc();
+	}
+	
+	// virtual
+	// Will be deleted after returning true - only safe to do this if all callbacks have fired.
+	BOOL tick()
+	{
+		// mPendingRequests will be zero if all requests have been
+		// responded to.  mWaitTimes.empty() will be true if we have
+		// received at least one reply for each UUID.  If requests
+		// have been dropped and retried, these will not necessarily
+		// be the same.  Only safe to return true if all requests have
+		// been serviced, since it will result in this object being
+		// deleted.
+		bool all_done = (mPendingRequests==0);
 
-//Inventory callback updating "dirty" state when destroyed
-class LLUpdateDirtyState: public LLInventoryCallback
+		if (!mWaitTimes.empty())
+		{
+			llwarns << "still waiting on " << mWaitTimes.size() << " items" << llendl;
+			for (std::map<LLUUID,LLTimer>::iterator it = mWaitTimes.begin();
+				 it != mWaitTimes.end();)
+			{
+				// Use a copy of iterator because it may be erased/invalidated.
+				std::map<LLUUID,LLTimer>::iterator curr_it = it;
+				++it;
+				
+				F32 time_waited = curr_it->second.getElapsedTimeF32();
+				S32 retries = mRetryCounts[curr_it->first];
+				if (time_waited > mRetryAfter)
+				{
+					if (retries < mMaxRetries)
+					{
+						LL_DEBUGS("Avatar") << "Waited " << time_waited <<
+							" for " << curr_it->first << ", retrying" << llendl;
+						mRetryCount++;
+						addItem(curr_it->first);
+					}
+					else
+					{
+						llwarns << "Giving up on " << curr_it->first << " after too many retries" << llendl;
+						mWaitTimes.erase(curr_it);
+						mFailCount++;
+					}
+				}
+				if (mWaitTimes.empty())
+				{
+					onCompletionOrFailure();
+				}
+
+			}
+		}
+		return all_done;
+	}
+
+	void reportStats()
+	{
+		LL_DEBUGS("Avatar") << "Phase: " << mTrackingPhase << llendl;
+		LL_DEBUGS("Avatar") << "mFailCount: " << mFailCount << llendl;
+		LL_DEBUGS("Avatar") << "mRetryCount: " << mRetryCount << llendl;
+		LL_DEBUGS("Avatar") << "Times: n " << mTimeStats.getCount() << " min " << mTimeStats.getMinValue() << " max " << mTimeStats.getMaxValue() << llendl;
+		LL_DEBUGS("Avatar") << "Mean " << mTimeStats.getMean() << " stddev " << mTimeStats.getStdDev() << llendl;
+	}
+	
+	virtual ~LLCallAfterInventoryBatchMgr()
+	{
+		LL_DEBUGS("Avatar") << "deleting" << llendl;
+	}
+
+protected:
+	std::string mTrackingPhase;
+	std::map<LLUUID,LLTimer> mWaitTimes;
+	std::map<LLUUID,S32> mRetryCounts;
+	LLUUID mDstCatID;
+	nullary_func_t mOnCompletionFunc;
+	nullary_func_t mOnFailureFunc;
+	F32 mRetryAfter;
+	S32 mMaxRetries;
+	S32 mPendingRequests;
+	S32 mFailCount;
+	S32 mRetryCount;
+	bool mCompletionOrFailureCalled;
+	LLViewerStats::StatsAccumulator mTimeStats;
+};
+
+class LLCallAfterInventoryCopyMgr: public LLCallAfterInventoryBatchMgr
 {
 public:
-	LLUpdateDirtyState() {}
-	virtual ~LLUpdateDirtyState()
+	LLCallAfterInventoryCopyMgr(LLInventoryModel::item_array_t& src_items,
+								const LLUUID& dst_cat_id,
+								const std::string& phase_name,
+								nullary_func_t on_completion_func,
+								nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+	{
+		addItems(src_items);
+	}
+	
+	virtual bool requestOperation(const LLUUID& item_id)
 	{
-		if (LLAppearanceMgr::instanceExists())
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		llassert(item);
+		LL_DEBUGS("Avatar") << "copying item " << item_id << llendl;
+		if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
 		{
-			LLAppearanceMgr::getInstance()->updateIsDirty();
+			LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+			return true;
 		}
+		copy_inventory_item(
+			gAgent.getID(),
+			item->getPermissions().getOwner(),
+			item->getUUID(),
+			mDstCatID,
+			std::string(),
+			new LLBoostFuncInventoryCallback(boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer()))
+			);
+		return true;
 	}
-	virtual void fire(const LLUUID&) {}
 };
 
+class LLCallAfterInventoryLinkMgr: public LLCallAfterInventoryBatchMgr
+{
+public:
+	LLCallAfterInventoryLinkMgr(LLInventoryModel::item_array_t& src_items,
+								const LLUUID& dst_cat_id,
+								const std::string& phase_name,
+								nullary_func_t on_completion_func,
+								nullary_func_t on_failure_func = no_op,
+								 F32 retry_after = DEFAULT_RETRY_AFTER_INTERVAL,
+								 S32 max_retries = DEFAULT_MAX_RETRIES
+		):
+		LLCallAfterInventoryBatchMgr(dst_cat_id, phase_name, on_completion_func, on_failure_func, retry_after, max_retries)
+	{
+		addItems(src_items);
+	}
+	
+	virtual bool requestOperation(const LLUUID& item_id)
+	{
+		bool request_sent = false;
+		LLViewerInventoryItem *item = gInventory.getItem(item_id);
+		if (item)
+		{
+			if (item->getParentUUID() == mDstCatID)
+			{
+				LL_DEBUGS("Avatar") << "item " << item_id << " name " << item->getName() << " is already a child of " << mDstCatID << llendl;
+				return false;
+			}
+			LL_DEBUGS("Avatar") << "linking item " << item_id << " name " << item->getName() << " to " << mDstCatID << llendl;
+			// create an inventory item link.
+			if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+			{
+				LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+				return true;
+			}
+			link_inventory_item(gAgent.getID(),
+								item->getLinkedUUID(),
+								mDstCatID,
+								item->getName(),
+								item->getActualDescription(),
+								LLAssetType::AT_LINK,
+								new LLBoostFuncInventoryCallback(
+									boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+			return true;
+		}
+		else
+		{
+			// create a base outfit link if appropriate.
+			LLViewerInventoryCategory *catp = gInventory.getCategory(item_id);
+			if (!catp)
+			{
+				llwarns << "link request failed, id not found as inventory item or category " << item_id << llendl;
+				return false;
+			}
+			const LLUUID cof = LLAppearanceMgr::instance().getCOF();
+			std::string new_outfit_name = "";
+
+			LLAppearanceMgr::instance().purgeBaseOutfitLink(cof);
+
+			if (catp && catp->getPreferredType() == LLFolderType::FT_OUTFIT)
+			{
+				if (ll_frand() < gSavedSettings.getF32("InventoryDebugSimulateOpFailureRate"))
+				{
+					LL_DEBUGS("Avatar") << "simulating failure by not sending request for item " << item_id << llendl;
+					return true;
+				}
+				LL_DEBUGS("Avatar") << "linking folder " << item_id << " name " << catp->getName() << " to cof " << cof << llendl;
+				link_inventory_item(gAgent.getID(), item_id, cof, catp->getName(), "",
+									LLAssetType::AT_LINK_FOLDER, 
+									new LLBoostFuncInventoryCallback(
+										boost::bind(&LLCallAfterInventoryBatchMgr::onOp,this,item_id,_1,LLTimer())));
+				new_outfit_name = catp->getName();
+				request_sent = true;
+			}
+	
+			LLAppearanceMgr::instance().updatePanelOutfitName(new_outfit_name);
+		}
+		return request_sent;
+	}
+};
 
 LLUpdateAppearanceOnDestroy::LLUpdateAppearanceOnDestroy(bool update_base_outfit_ordering):
 	mFireCount(0),
@@ -278,7 +557,7 @@ struct LLFoundData
 	std::string mName;
 	LLAssetType::EType mAssetType;
 	LLWearableType::EType mWearableType;
-	LLWearable* mWearable;
+	LLViewerWearable* mWearable;
 	bool mIsReplacement;
 };
 
@@ -302,7 +581,7 @@ class LLWearableHoldingPattern
 	void recoverMissingWearable(LLWearableType::EType type);
 	void clearCOFLinksForMissingWearables();
 	
-	void onWearableAssetFetch(LLWearable *wearable);
+	void onWearableAssetFetch(LLViewerWearable *wearable);
 	void onAllComplete();
 
 	typedef std::list<LLFoundData> found_list_t;
@@ -328,7 +607,7 @@ class LLWearableHoldingPattern
 	typedef std::set<LLWearableHoldingPattern*> type_set_hp;
 	static type_set_hp sActiveHoldingPatterns;
 	bool mIsMostRecent;
-	std::set<LLWearable*> mLateArrivals;
+	std::set<LLViewerWearable*> mLateArrivals;
 	bool mIsAllComplete;
 };
 
@@ -559,100 +838,72 @@ bool LLWearableHoldingPattern::pollFetchCompletion()
 	return done;
 }
 
-class RecoveredItemLinkCB: public LLInventoryCallback
+void recovered_item_link_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
 {
-public:
-	RecoveredItemLinkCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
-		mHolder(holder),
-		mWearable(wearable),
-		mType(type)
+	if (!holder->isMostRecent())
 	{
+		llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
+		// runway skip here?
 	}
-	void fire(const LLUUID& item_id)
-	{
-		if (!mHolder->isMostRecent())
-		{
-			llwarns << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
-			// runway skip here?
-		}
 
-		llinfos << "Recovered item link for type " << mType << llendl;
-		mHolder->eraseTypeToLink(mType);
-		// Add wearable to FoundData for actual wearing
-		LLViewerInventoryItem *item = gInventory.getItem(item_id);
-		LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
+	llinfos << "Recovered item link for type " << type << llendl;
+	holder->eraseTypeToLink(type);
+	// Add wearable to FoundData for actual wearing
+	LLViewerInventoryItem *item = gInventory.getItem(item_id);
+	LLViewerInventoryItem *linked_item = item ? item->getLinkedItem() : NULL;
 
-		if (linked_item)
-		{
-			gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
+	if (linked_item)
+	{
+		gInventory.addChangedMask(LLInventoryObserver::LABEL, linked_item->getUUID());
 			
-			if (item)
-			{
-				LLFoundData found(linked_item->getUUID(),
-								  linked_item->getAssetUUID(),
-								  linked_item->getName(),
-								  linked_item->getType(),
-								  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
-								  true // is replacement
-					);
-				found.mWearable = mWearable;
-				mHolder->getFoundList().push_front(found);
-			}
-			else
-			{
-				llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
-			}
+		if (item)
+		{
+			LLFoundData found(linked_item->getUUID(),
+							  linked_item->getAssetUUID(),
+							  linked_item->getName(),
+							  linked_item->getType(),
+							  linked_item->isWearableType() ? linked_item->getWearableType() : LLWearableType::WT_INVALID,
+							  true // is replacement
+				);
+			found.mWearable = wearable;
+			holder->getFoundList().push_front(found);
 		}
 		else
 		{
-			llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
+			llwarns << self_av_string() << "inventory item not found for recovered wearable" << llendl;
 		}
 	}
-private:
-	LLWearableHoldingPattern* mHolder;
-	LLWearable *mWearable;
-	LLWearableType::EType mType;
-};
+	else
+	{
+		llwarns << self_av_string() << "inventory link not found for recovered wearable" << llendl;
+	}
+}
 
-class RecoveredItemCB: public LLInventoryCallback
+void recovered_item_cb(const LLUUID& item_id, LLWearableType::EType type, LLViewerWearable *wearable, LLWearableHoldingPattern* holder)
 {
-public:
-	RecoveredItemCB(LLWearableType::EType type, LLWearable *wearable, LLWearableHoldingPattern* holder):
-		mHolder(holder),
-		mWearable(wearable),
-		mType(type)
+	if (!holder->isMostRecent())
 	{
+		// runway skip here?
+		llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
 	}
-	void fire(const LLUUID& item_id)
-	{
-		if (!mHolder->isMostRecent())
-		{
-			// runway skip here?
-			llwarns << self_av_string() << "skipping because LLWearableHolding pattern is invalid (superceded by later outfit request)" << llendl;
-		}
 
-		LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << mType << LL_ENDL;
-		LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
-		mWearable->setItemID(item_id);
-		LLPointer<LLInventoryCallback> cb = new RecoveredItemLinkCB(mType,mWearable,mHolder);
-		mHolder->eraseTypeToRecover(mType);
-		llassert(itemp);
-		if (itemp)
-		{
-			link_inventory_item( gAgent.getID(),
-					     item_id,
-					     LLAppearanceMgr::instance().getCOF(),
-					     itemp->getName(),
-						 itemp->getDescription(),
-					     LLAssetType::AT_LINK,
-					     cb);
-		}
+	LL_DEBUGS("Avatar") << self_av_string() << "Recovered item for type " << type << LL_ENDL;
+	LLViewerInventoryItem *itemp = gInventory.getItem(item_id);
+	wearable->setItemID(item_id);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_link_cb,_1,type,wearable,holder));
+	holder->eraseTypeToRecover(type);
+	llassert(itemp);
+	if (itemp)
+	{
+		link_inventory_item( gAgent.getID(),
+							 item_id,
+							 LLAppearanceMgr::instance().getCOF(),
+							 itemp->getName(),
+							 itemp->getDescription(),
+							 LLAssetType::AT_LINK,
+							 cb);
 	}
-private:
-	LLWearableHoldingPattern* mHolder;
-	LLWearable *mWearable;
-	LLWearableType::EType mType;
-};
+}
 
 void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type)
 {
@@ -666,11 +917,11 @@ void LLWearableHoldingPattern::recoverMissingWearable(LLWearableType::EType type
 	LLNotificationsUtil::add("ReplacedMissingWearable");
 	lldebugs << "Wearable " << LLWearableType::getTypeLabel(type)
 			 << " could not be downloaded.  Replaced inventory item with default wearable." << llendl;
-	LLWearable* wearable = LLWearableList::instance().createNewWearable(type);
+	LLViewerWearable* wearable = LLWearableList::instance().createNewWearable(type, gAgentAvatarp);
 
 	// Add a new one in the lost and found folder.
 	const LLUUID lost_and_found_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_LOST_AND_FOUND);
-	LLPointer<LLInventoryCallback> cb = new RecoveredItemCB(type,wearable,this);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(recovered_item_cb,_1,type,wearable,this));
 
 	create_inventory_item(gAgent.getID(),
 						  gAgent.getSessionID(),
@@ -699,7 +950,7 @@ void LLWearableHoldingPattern::clearCOFLinksForMissingWearables()
 		{
 			// Wearable link that was never resolved; remove links to it from COF
 			LL_INFOS("Avatar") << self_av_string() << "removing link for unresolved item " << data.mItemID.asString() << LL_ENDL;
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
 		}
 	}
 }
@@ -773,11 +1024,11 @@ void LLWearableHoldingPattern::handleLateArrivals()
 		 iter != getFoundList().end(); ++iter)
 	{
 		LLFoundData& data = *iter;
-		for (std::set<LLWearable*>::iterator wear_it = mLateArrivals.begin();
+		for (std::set<LLViewerWearable*>::iterator wear_it = mLateArrivals.begin();
 			 wear_it != mLateArrivals.end();
 			 ++wear_it)
 		{
-			LLWearable *wearable = *wear_it;
+			LLViewerWearable *wearable = *wear_it;
 
 			if(wearable->getAssetID() == data.mAssetID)
 			{
@@ -813,7 +1064,7 @@ void LLWearableHoldingPattern::handleLateArrivals()
 		if (data.mWearable && data.mIsReplacement &&
 			replaced_types.find(data.mWearableType) != replaced_types.end())
 		{
-			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID,false);
+			LLAppearanceMgr::instance().removeCOFItemLinks(data.mItemID);
 			std::list<LLFoundData>::iterator clobber_ator = iter;
 			++iter;
 			getFoundList().erase(clobber_ator);
@@ -837,7 +1088,7 @@ void LLWearableHoldingPattern::resetTime(F32 timeout)
 	mWaitTime.setTimerExpirySec(timeout);
 }
 
-void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
+void LLWearableHoldingPattern::onWearableAssetFetch(LLViewerWearable *wearable)
 {
 	if (!isMostRecent())
 	{
@@ -888,7 +1139,7 @@ void LLWearableHoldingPattern::onWearableAssetFetch(LLWearable *wearable)
 	}
 }
 
-static void onWearableAssetFetch(LLWearable* wearable, void* data)
+static void onWearableAssetFetch(LLViewerWearable* wearable, void* data)
 {
 	LLWearableHoldingPattern* holder = (LLWearableHoldingPattern*)data;
 	holder->onWearableAssetFetch(wearable);
@@ -927,6 +1178,18 @@ const LLUUID LLAppearanceMgr::getCOF() const
 	return gInventory.findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT);
 }
 
+S32 LLAppearanceMgr::getCOFVersion() const
+{
+	LLViewerInventoryCategory *cof = gInventory.getCategory(getCOF());
+	if (cof)
+	{
+		return cof->getVersion();
+	}
+	else
+	{
+		return LLViewerInventoryCategory::VERSION_UNKNOWN;
+	}
+}
 
 const LLViewerInventoryItem* LLAppearanceMgr::getBaseOutfitLink()
 {
@@ -995,6 +1258,18 @@ const LLUUID LLAppearanceMgr::getBaseOutfitUUID()
 	return outfit_cat->getUUID();
 }
 
+void wear_on_avatar_cb(const LLUUID& inv_item, bool do_replace = false)
+{
+	if (inv_item.isNull())
+		return;
+	
+	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
+	if (item)
+	{
+		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, do_replace);
+	}
+}
+
 bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_update, bool replace, LLPointer<LLInventoryCallback> cb)
 {
 	if (item_id_to_wear.isNull()) return false;
@@ -1014,8 +1289,8 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 
 	if (gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getLibraryRootFolderID()))
 	{
-		LLPointer<LLInventoryCallback> cb = new WearOnAvatarCallback(replace);
-		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(),cb);
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(wear_on_avatar_cb,_1,replace));
+		copy_inventory_item(gAgent.getID(), item_to_wear->getPermissions().getOwner(), item_to_wear->getUUID(), LLUUID::null, std::string(), cb);
 		return false;
 	} 
 	else if (!gInventory.isObjectDescendentOf(item_to_wear->getUUID(), gInventory.getRootFolderID()))
@@ -1041,7 +1316,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 			if ((replace && wearable_count != 0) ||
 				(wearable_count >= LLAgentWearables::MAX_CLOTHING_PER_TYPE) )
 			{
-				removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1), false);
+				removeCOFItemLinks(gAgentWearables.getWearableItemID(item_to_wear->getWearableType(), wearable_count-1));
 			}
 			addCOFItemLink(item_to_wear, do_update, cb);
 		} 
@@ -1051,7 +1326,7 @@ bool LLAppearanceMgr::wearItemOnAvatar(const LLUUID& item_id_to_wear, bool do_up
 		
 		// Remove the existing wearables of the same type.
 		// Remove existing body parts anyway because we must not be able to wear e.g. two skins.
-		removeCOFLinksOfType(item_to_wear->getWearableType(), false);
+		removeCOFLinksOfType(item_to_wear->getWearableType());
 
 		addCOFItemLink(item_to_wear, do_update, cb);
 		break;
@@ -1149,11 +1424,13 @@ void LLAppearanceMgr::takeOffOutfit(const LLUUID& cat_id)
 
 	LLInventoryModel::item_array_t::const_iterator it = items.begin();
 	const LLInventoryModel::item_array_t::const_iterator it_end = items.end();
+	uuid_vec_t uuids_to_remove;
 	for( ; it_end != it; ++it)
 	{
 		LLViewerInventoryItem* item = *it;
-		removeItemFromAvatar(item->getUUID());
+		uuids_to_remove.push_back(item->getUUID());
 	}
+	removeItemsFromAvatar(uuids_to_remove);
 }
 
 // Create a copy of src_id + contents as a subfolder of dst_id.
@@ -1197,13 +1474,13 @@ void LLAppearanceMgr::shallowCopyCategoryContents(const LLUUID& src_id, const LL
 		{
 			case LLAssetType::AT_LINK:
 			{
-				//LLInventoryItem::getDescription() is used for a new description 
+				//getActualDescription() is used for a new description 
 				//to propagate ordering information saved in descriptions of links
 				link_inventory_item(gAgent.getID(),
 									item->getLinkedUUID(),
 									dst_id,
 									item->getName(),
-									item->LLInventoryItem::getDescription(),
+									item->getActualDescription(),
 									LLAssetType::AT_LINK, cb);
 				break;
 			}
@@ -1383,7 +1660,7 @@ void LLAppearanceMgr::purgeBaseOutfitLink(const LLUUID& category)
 	}
 }
 
-void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links)
+void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items)
 {
 	LLInventoryModel::cat_array_t cats;
 	LLInventoryModel::item_array_t items;
@@ -1396,8 +1673,19 @@ void LLAppearanceMgr::purgeCategory(const LLUUID& category, bool keep_outfit_lin
 			continue;
 		if (item->getIsLinkType())
 		{
+#if 0
+			if (keep_items && keep_items->find(item) != LLInventoryModel::item_array_t::FAIL)
+			{
+				llinfos << "preserved item" << llendl;
+			}
+			else
+			{
+				gInventory.purgeObject(item->getUUID());
+			}
+#else
 			gInventory.purgeObject(item->getUUID());
 		}
+#endif
 	}
 }
 
@@ -1437,7 +1725,7 @@ void LLAppearanceMgr::linkAll(const LLUUID& cat_uuid,
 							item->getLinkedUUID(),
 							cat_uuid,
 							item->getName(),
-							item->LLInventoryItem::getDescription(),
+							item->getActualDescription(),
 							LLAssetType::AT_LINK,
 							cb);
 
@@ -1508,40 +1796,31 @@ void LLAppearanceMgr::updateCOF(const LLUUID& category, bool append)
 	getDescendentsOfAssetType(category, gest_items, LLAssetType::AT_GESTURE, false);
 	removeDuplicateItems(gest_items);
 	
-	// Remove current COF contents.
-	bool keep_outfit_links = append;
-	purgeCategory(cof, keep_outfit_links);
-	gInventory.notifyObservers();
-
 	// Create links to new COF contents.
-	LL_DEBUGS("Avatar") << self_av_string() << "creating LLUpdateAppearanceOnDestroy" << LL_ENDL;
-	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy(!append);
+	LLInventoryModel::item_array_t all_items;
+	all_items += body_items;
+	all_items += wear_items;
+	all_items += obj_items;
+	all_items += gest_items;
 
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking body items" << LL_ENDL;
-#endif
-	linkAll(cof, body_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking wear items" << LL_ENDL;
-#endif
-	linkAll(cof, wear_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking obj items" << LL_ENDL;
-#endif
-	linkAll(cof, obj_items, link_waiter);
-
-#ifndef LL_RELEASE_FOR_DOWNLOAD
-	LL_DEBUGS("Avatar") << self_av_string() << "Linking gesture items" << LL_ENDL;
-#endif
-	linkAll(cof, gest_items, link_waiter);
+	// Will link all the above items.
+	LLPointer<LLInventoryCallback> link_waiter = new LLUpdateAppearanceOnDestroy;
+	linkAll(cof,all_items,link_waiter);
 
 	// Add link to outfit if category is an outfit. 
 	if (!append)
 	{
 		createBaseOutfitLink(category, link_waiter);
 	}
+
+	// Remove current COF contents.  Have to do this after creating
+	// the link_waiter so links can be followed for any items that get
+	// carried over (e.g. keeping old shape if the new outfit does not
+	// contain one)
+	bool keep_outfit_links = append;
+	purgeCategory(cof, keep_outfit_links, &all_items);
+	gInventory.notifyObservers();
+
 	LL_DEBUGS("Avatar") << self_av_string() << "waiting for LLUpdateAppearanceOnDestroy" << LL_ENDL;
 }
 
@@ -1577,7 +1856,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 {
 	lldebugs << "updateAgentWearables()" << llendl;
 	LLInventoryItem::item_array_t items;
-	LLDynamicArray< LLWearable* > wearables;
+	LLDynamicArray< LLViewerWearable* > wearables;
 
 	// For each wearable type, find the wearables of that type.
 	for( S32 i = 0; i < LLWearableType::WT_COUNT; i++ )
@@ -1586,7 +1865,7 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 			 iter != holder->getFoundList().end(); ++iter)
 		{
 			LLFoundData& data = *iter;
-			LLWearable* wearable = data.mWearable;
+			LLViewerWearable* wearable = data.mWearable;
 			if( wearable && ((S32)wearable->getType() == i) )
 			{
 				LLViewerInventoryItem* item = (LLViewerInventoryItem*)gInventory.getItem(data.mItemID);
@@ -1603,8 +1882,6 @@ void LLAppearanceMgr::updateAgentWearables(LLWearableHoldingPattern* holder, boo
 	{
 		gAgentWearables.setWearableOutfit(items, wearables, !append);
 	}
-
-//	dec_busy_count();
 }
 
 static void remove_non_link_items(LLInventoryModel::item_array_t &items)
@@ -1624,7 +1901,7 @@ static void remove_non_link_items(LLInventoryModel::item_array_t &items)
 }
 
 //a predicate for sorting inventory items by actual descriptions
-bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
+bool sort_by_actual_description(const LLInventoryItem* item1, const LLInventoryItem* item2)
 {
 	if (!item1 || !item2) 
 	{
@@ -1632,7 +1909,7 @@ bool sort_by_description(const LLInventoryItem* item1, const LLInventoryItem* it
 		return true;
 	}
 
-	return item1->LLInventoryItem::getDescription() < item2->LLInventoryItem::getDescription();
+	return item1->getActualDescription() < item2->getActualDescription();
 }
 
 void item_array_diff(LLInventoryModel::item_array_t& full_list,
@@ -1714,11 +1991,10 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 		return;
 	}
 
-	LLVOAvatar::ScopedPhaseSetter(gAgentAvatarp,"update_appearance_from_cof");
-	
 	BoolSetter setIsInUpdateAppearanceFromCOF(mIsInUpdateAppearanceFromCOF);
+	selfStartPhase("update_appearance_from_cof");
 
-	LL_INFOS("Avatar") << self_av_string() << "starting" << LL_ENDL;
+	LL_DEBUGS("Avatar") << self_av_string() << "starting" << LL_ENDL;
 
 	//checking integrity of the COF in terms of ordering of wearables, 
 	//checking and updating links' descriptions of wearables in the COF (before analyzed for "dirty" state)
@@ -1732,9 +2008,18 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 	// the saved outfit stored as a folder link
 	updateIsDirty();
 
+	// Send server request for appearance update
+	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+	{
+		requestServerAppearanceUpdate();
+	}
+	// DRANO really should wait for the appearance message to set this.
+	// verify that deleting this line doesn't break anything.
+	//gAgentAvatarp->setIsUsingServerBakes(gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion());
+	
 	//dumpCat(getCOF(),"COF, start");
 
-	bool follow_folder_links = true;
+	bool follow_folder_links = false;
 	LLUUID current_outfit_id = getCOF();
 
 	// Find all the wearables that are in the COF's subtree.
@@ -1822,6 +2107,7 @@ void LLAppearanceMgr::updateAppearanceFromCOF(bool update_base_outfit_ordering)
 		// Fetch the wearables about to be worn.
 		LLWearableList::instance().getAsset(found.mAssetID,
 											found.mName,
+											gAgentAvatarp,
 											found.mAssetType,
 											onWearableAssetFetch,
 											(void*)holder);
@@ -1956,22 +2242,15 @@ void LLAppearanceMgr::wearCategoryFinal(LLUUID& cat_id, bool copy_items, bool ap
 			pid,
 			LLFolderType::FT_NONE,
 			name);
-		LLPointer<LLInventoryCallback> cb = new LLWearInventoryCategoryCallback(new_cat_id, append);
-		it = items->begin();
-		for(; it < end; ++it)
-		{
-			item = *it;
-			if(item)
-			{
-				copy_inventory_item(
-					gAgent.getID(),
-					item->getPermissions().getOwner(),
-					item->getUUID(),
-					new_cat_id,
-					std::string(),
-					cb);
-			}
-		}
+
+		// Create a CopyMgr that will copy items, manage its own destruction
+		new LLCallAfterInventoryCopyMgr(
+			*items, new_cat_id, std::string("wear_inventory_category_callback"),
+			boost::bind(&LLAppearanceMgr::wearInventoryCategoryOnAvatar,
+						LLAppearanceMgr::getInstance(),
+						gInventory.getCategory(new_cat_id),
+						append));
+
 		// BAP fixes a lag in display of created dir.
 		gInventory.notifyObservers();
 	}
@@ -1988,7 +2267,13 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
 	// Avoid unintentionally overwriting old wearables.  We have to do
 	// this up front to avoid having to deal with the case of multiple
 	// wearables being dirty.
-	if(!category) return;
+	if (!category) return;
+
+	if ( !LLInventoryCallbackManager::is_instantiated() )
+	{
+		// shutting down, ignore.
+		return;
+	}
 
 	LL_INFOS("Avatar") << self_av_string() << "wearInventoryCategoryOnAvatar '" << category->getName()
 			 << "'" << LL_ENDL;
@@ -2005,7 +2290,6 @@ void LLAppearanceMgr::wearInventoryCategoryOnAvatar( LLInventoryCategory* catego
 void LLAppearanceMgr::wearOutfitByName(const std::string& name)
 {
 	LL_INFOS("Avatar") << self_av_string() << "Wearing category " << name << LL_ENDL;
-	//inc_busy_count();
 
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
@@ -2045,8 +2329,6 @@ void LLAppearanceMgr::wearOutfitByName(const std::string& name)
 		llwarns << "Couldn't find outfit " <<name<< " in wearOutfitByName()"
 				<< llendl;
 	}
-
-	//dec_busy_count();
 }
 
 bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventoryItem *b)
@@ -2058,10 +2340,11 @@ bool areMatchingWearables(const LLViewerInventoryItem *a, const LLViewerInventor
 class LLDeferredCOFLinkObserver: public LLInventoryObserver
 {
 public:
-	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL):
+	LLDeferredCOFLinkObserver(const LLUUID& item_id, bool do_update, LLPointer<LLInventoryCallback> cb = NULL, std::string description = ""):
 		mItemID(item_id),
 		mDoUpdate(do_update),
-		mCallback(cb)
+		mCallback(cb),
+		mDescription(description)
 	{
 	}
 
@@ -2083,28 +2366,49 @@ class LLDeferredCOFLinkObserver: public LLInventoryObserver
 private:
 	const LLUUID mItemID;
 	bool mDoUpdate;
+	std::string mDescription;
 	LLPointer<LLInventoryCallback> mCallback;
 };
 
 
 // BAP - note that this runs asynchronously if the item is not already loaded from inventory.
 // Dangerous if caller assumes link will exist after calling the function.
-void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb)
+void LLAppearanceMgr::addCOFItemLink(const LLUUID &item_id, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
 {
 	const LLInventoryItem *item = gInventory.getItem(item_id);
 	if (!item)
 	{
-		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb);
+		LLDeferredCOFLinkObserver *observer = new LLDeferredCOFLinkObserver(item_id, do_update, cb, description);
 		gInventory.addObserver(observer);
 	}
 	else
 	{
-		addCOFItemLink(item, do_update, cb);
+		addCOFItemLink(item, do_update, cb, description);
+	}
+}
+
+void modified_cof_cb(const LLUUID& inv_item)
+{
+	LLAppearanceMgr::instance().updateAppearanceFromCOF();
+
+	// Start editing the item if previously requested.
+	gAgentWearables.editWearableIfRequested(inv_item);
+
+	// TODO: camera mode may not be changed if a debug setting is tweaked
+	if( gAgentCamera.cameraCustomizeAvatar() )
+	{
+		// If we're in appearance editing mode, the current tab may need to be refreshed
+		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+		if (panel)
+		{
+			panel->showDefaultSubpart();
+		}
 	}
 }
 
-void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb)
+void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update, LLPointer<LLInventoryCallback> cb, const std::string description)
 {		
+	std::string link_description = description;
 	const LLViewerInventoryItem *vitem = dynamic_cast<const LLViewerInventoryItem*>(item);
 	if (!vitem)
 	{
@@ -2166,37 +2470,106 @@ void LLAppearanceMgr::addCOFItemLink(const LLInventoryItem *item, bool do_update
 	{
 		if(do_update && cb.isNull())
 		{
-			cb = new ModifiedCOFCallback;
+			cb = new LLBoostFuncInventoryCallback(modified_cof_cb);
+		}
+		if (vitem->getIsLinkType())
+		{
+			link_description = vitem->getActualDescription();
 		}
-		const std::string description = vitem->getIsLinkType() ? vitem->getDescription() : "";
 		link_inventory_item( gAgent.getID(),
 							 vitem->getLinkedUUID(),
 							 getCOF(),
 							 vitem->getName(),
-							 description,
+							 link_description,
 							 LLAssetType::AT_LINK,
 							 cb);
 	}
 	return;
 }
 
-// BAP remove ensemble code for 2.1?
-void LLAppearanceMgr::addEnsembleLink( LLInventoryCategory* cat, bool do_update )
+LLInventoryModel::item_array_t LLAppearanceMgr::findCOFItemLinks(const LLUUID& item_id)
 {
-#if SUPPORT_ENSEMBLES
-	// BAP add check for already in COF.
-	LLPointer<LLInventoryCallback> cb = do_update ? new ModifiedCOFCallback : 0;
-	link_inventory_item( gAgent.getID(),
-						 cat->getLinkedUUID(),
-						 getCOF(),
-						 cat->getName(),
-						 cat->getDescription(),
-						 LLAssetType::AT_LINK_FOLDER,
-						 cb);
-#endif
+
+	LLInventoryModel::item_array_t result;
+	const LLViewerInventoryItem *vitem =
+		dynamic_cast<const LLViewerInventoryItem*>(gInventory.getItem(item_id));
+
+	if (vitem)
+	{
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(LLAppearanceMgr::getCOF(),
+									  cat_array,
+									  item_array,
+									  LLInventoryModel::EXCLUDE_TRASH);
+		for (S32 i=0; i<item_array.count(); i++)
+		{
+			const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+			if (inv_item->getLinkedUUID() == vitem->getLinkedUUID())
+			{
+				result.put(item_array.get(i));
+			}
+		}
+	}
+	return result;
+}
+
+void LLAppearanceMgr::removeAllClothesFromAvatar()
+{
+	// Fetch worn clothes (i.e. the ones in COF).
+	LLInventoryModel::item_array_t clothing_items;
+	LLInventoryModel::cat_array_t dummy;
+	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
+	gInventory.collectDescendentsIf(getCOF(),
+									dummy,
+									clothing_items,
+									LLInventoryModel::EXCLUDE_TRASH,
+									is_clothing,
+									false);
+	uuid_vec_t item_ids;
+	for (LLInventoryModel::item_array_t::iterator it = clothing_items.begin();
+		it != clothing_items.end(); ++it)
+	{
+		item_ids.push_back((*it).get()->getLinkedUUID());
+	}
+
+	// Take them off by removing from COF.
+	removeItemsFromAvatar(item_ids);
+}
+
+void LLAppearanceMgr::removeAllAttachmentsFromAvatar()
+{
+	if (!isAgentAvatarValid()) return;
+
+	LLAgentWearables::llvo_vec_t objects_to_remove;
+	
+	for (LLVOAvatar::attachment_map_t::iterator iter = gAgentAvatarp->mAttachmentPoints.begin(); 
+		 iter != gAgentAvatarp->mAttachmentPoints.end();)
+	{
+		LLVOAvatar::attachment_map_t::iterator curiter = iter++;
+		LLViewerJointAttachment* attachment = curiter->second;
+		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
+			 attachment_iter != attachment->mAttachedObjects.end();
+			 ++attachment_iter)
+		{
+			LLViewerObject *attached_object = (*attachment_iter);
+			if (attached_object)
+			{
+				objects_to_remove.push_back(attached_object);
+			}
+		}
+	}
+	uuid_vec_t ids_to_remove;
+	for (LLAgentWearables::llvo_vec_t::iterator it = objects_to_remove.begin();
+		 it != objects_to_remove.end();
+		 ++it)
+	{
+		ids_to_remove.push_back((*it)->getAttachmentItemID());
+	}
+	removeItemsFromAvatar(ids_to_remove);
 }
 
-void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
+void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id)
 {
 	gInventory.addChangedMask(LLInventoryObserver::LABEL, item_id);
 
@@ -2214,13 +2587,9 @@ void LLAppearanceMgr::removeCOFItemLinks(const LLUUID& item_id, bool do_update)
 			gInventory.purgeObject(item->getUUID());
 		}
 	}
-	if (do_update)
-	{
-		LLAppearanceMgr::updateAppearanceFromCOF();
-	}
 }
 
-void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_update)
+void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type)
 {
 	LLFindWearablesOfType filter_wearables_of_type(type);
 	LLInventoryModel::cat_array_t cats;
@@ -2236,11 +2605,6 @@ void LLAppearanceMgr::removeCOFLinksOfType(LLWearableType::EType type, bool do_u
 			gInventory.purgeObject(item->getUUID());
 		}
 	}
-
-	if (do_update)
-	{
-		updateAppearanceFromCOF();
-	}
 }
 
 bool sort_by_linked_uuid(const LLViewerInventoryItem* item1, const LLViewerInventoryItem* item2)
@@ -2308,7 +2672,7 @@ void LLAppearanceMgr::updateIsDirty()
 
 			if (item1->getLinkedUUID() != item2->getLinkedUUID() || 
 				item1->getName() != item2->getName() ||
-				item1->LLInventoryItem::getDescription() != item2->LLInventoryItem::getDescription())
+				item1->getActualDescription() != item2->getActualDescription())
 			{
 				mOutfitIsDirty = true;
 				return;
@@ -2331,7 +2695,7 @@ void LLAppearanceMgr::copyLibraryGestures()
 
 	// Copy gestures
 	LLUUID lib_gesture_cat_id =
-		gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE,false,true);
+		gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_GESTURE,false);
 	if (lib_gesture_cat_id.isNull())
 	{
 		llwarns << "Unable to copy gestures, source category not found" << llendl;
@@ -2377,7 +2741,7 @@ void LLAppearanceMgr::copyLibraryGestures()
 			folder_name == COMMON_GESTURES_FOLDER ||
 			folder_name == OTHER_GESTURES_FOLDER)
 		{
-			cb = new ActivateGestureCallback;
+			cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
 		}
 
 		LLUUID cat_id = findDescendentCategoryIDByName(lib_gesture_cat_id,folder_name);
@@ -2431,6 +2795,16 @@ void LLAppearanceMgr::onFirstFullyVisible()
 	}
 }
 
+// update "dirty" state - defined outside class to allow for calling
+// after appearance mgr instance has been destroyed.
+void appearance_mgr_update_dirty_state()
+{
+	if (LLAppearanceMgr::instanceExists())
+	{
+		LLAppearanceMgr::getInstance()->updateIsDirty();
+	}
+}
+
 bool LLAppearanceMgr::updateBaseOutfit()
 {
 	if (isOutfitLocked())
@@ -2451,8 +2825,8 @@ bool LLAppearanceMgr::updateBaseOutfit()
 	// in a Base Outfit we do not remove items, only links
 	purgeCategory(base_outfit_id, false);
 
-
-	LLPointer<LLInventoryCallback> dirty_state_updater = new LLUpdateDirtyState();
+	LLPointer<LLInventoryCallback> dirty_state_updater =
+		new LLBoostFuncInventoryCallback(no_op_inventory_func, appearance_mgr_update_dirty_state);
 
 	//COF contains only links so we copy to the Base Outfit only links
 	shallowCopyCategoryContents(getCOF(), base_outfit_id, dirty_state_updater);
@@ -2509,8 +2883,8 @@ struct WearablesOrderComparator
 			return true;
 		}
 		
-		const std::string& desc1 = item1->LLInventoryItem::getDescription();
-		const std::string& desc2 = item2->LLInventoryItem::getDescription();
+		const std::string& desc1 = item1->getActualDescription();
+		const std::string& desc2 = item2->getActualDescription();
 		
 		bool item1_valid = (desc1.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc1[0]);
 		bool item2_valid = (desc2.size() == mControlSize) && (ORDER_NUMBER_SEPARATOR == desc2[0]);
@@ -2568,7 +2942,7 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
 			if (!item) continue;
 
 			std::string new_order_str = build_order_string((LLWearableType::EType)type, i);
-			if (new_order_str == item->LLInventoryItem::getDescription()) continue;
+			if (new_order_str == item->getActualDescription()) continue;
 
 			item->setDescription(new_order_str);
 			item->setComplete(TRUE);
@@ -2583,52 +2957,424 @@ void LLAppearanceMgr::updateClothingOrderingInfo(LLUUID cat_id, bool update_base
 	if (inventory_changed) gInventory.notifyObservers();
 }
 
+// This is intended for use with HTTP Clients/Responders, but is not
+// specifically coupled with those classes.
+class LLHTTPRetryPolicy: public LLThreadSafeRefCount
+{
+public:
+	LLHTTPRetryPolicy() {}
+	virtual ~LLHTTPRetryPolicy() {}
+	virtual bool shouldRetry(U32 status, F32& seconds_to_wait) = 0;
+};
 
+// Example of simplest possible policy, not necessarily recommended.
+class LLAlwaysRetryImmediatelyPolicy: public LLHTTPRetryPolicy
+{
+public:
+	LLAlwaysRetryImmediatelyPolicy() {}
+	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	{
+		seconds_to_wait = 0.0;
+		return true;
+	}
+};
 
+// Very general policy with geometric back-off after failures,
+// up to a maximum delay, and maximum number of retries.
+class LLAdaptiveRetryPolicy: public LLHTTPRetryPolicy
+{
+public:
+	LLAdaptiveRetryPolicy(F32 min_delay, F32 max_delay, F32 backoff_factor, U32 max_retries):
+		mMinDelay(min_delay),
+		mMaxDelay(max_delay),
+		mBackoffFactor(backoff_factor),
+		mMaxRetries(max_retries),
+		mDelay(min_delay),
+		mRetryCount(0)
+	{
+	}
+
+	bool shouldRetry(U32 status, F32& seconds_to_wait)
+	{
+		seconds_to_wait = mDelay;
+		mDelay = llclamp(mDelay*mBackoffFactor,mMinDelay,mMaxDelay);
+		mRetryCount++;
+		return (mRetryCount<=mMaxRetries);
+	}
+
+private:
+	F32 mMinDelay; // delay never less than this value
+	F32 mMaxDelay; // delay never exceeds this value
+	F32 mBackoffFactor; // delay increases by this factor after each retry, up to mMaxDelay.
+	U32 mMaxRetries; // maximum number of times shouldRetry will return true.
+	F32 mDelay; // current delay.
+	U32 mRetryCount; // number of times shouldRetry has been called.
+};
 
-class LLShowCreatedOutfit: public LLInventoryCallback
+class RequestAgentUpdateAppearanceResponder: public LLHTTPClient::Responder
 {
 public:
-	LLShowCreatedOutfit(LLUUID& folder_id, bool show_panel = true): mFolderID(folder_id), mShowPanel(show_panel)
-	{}
+	RequestAgentUpdateAppearanceResponder()
+	{
+		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 32.0, 2.0, 10);
+	}
 
-	virtual ~LLShowCreatedOutfit()
+	virtual ~RequestAgentUpdateAppearanceResponder()
 	{
-		if (!LLApp::isRunning())
+	}
+
+	// Successful completion.
+	/* virtual */ void result(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "content: " << ll_pretty_print_sd(content) << LL_ENDL;
+		if (content["success"].asBoolean())
 		{
-			llwarns << "called during shutdown, skipping" << llendl;
-			return;
+			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
+			if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+			{
+				dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_ok", content);
+			}
 		}
+		else
+		{
+			onFailure(200);
+		}
+	}
 
-		LLSD key;
+	// Error
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "appearance update request failed, status: " << status << " reason: " << reason << " code: " << content["code"].asInteger() << " error: \"" << content["error"].asString() << "\"" << llendl;
+		if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+		{
+			dumpContents(gAgentAvatarp->getFullname() + "_appearance_request_error", content);
+			debugCOF(content);
 		
-		//EXT-7727. For new accounts LLShowCreatedOutfit is created during login process
-		// add may be processed after login process is finished
-		if (mShowPanel)
+		}
+		onFailure(status);
+	}	
+
+	void onFailure(U32 status)
+	{
+		F32 seconds_to_wait;
+		if (mRetryPolicy->shouldRetry(status,seconds_to_wait))
 		{
-			LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
+			llinfos << "retrying" << llendl;
+			doAfterInterval(boost::bind(&LLAppearanceMgr::requestServerAppearanceUpdate,
+										LLAppearanceMgr::getInstance(),
+										LLCurl::ResponderPtr(this)),
+							seconds_to_wait);
+		}
+		else
+		{
+			llwarns << "giving up after too many retries" << llendl;
+		}
+	}	
 
+	void dumpContents(const std::string outprefix, const LLSD& content)
+	{
+		std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+		std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+		std::ofstream ofs(fullpath.c_str(), std::ios_base::out);
+		ofs << LLSDOStreamer<LLSDXMLFormatter>(content, LLSDFormatter::OPTIONS_PRETTY);
+		LL_DEBUGS("Avatar") << "results saved to: " << fullpath << LL_ENDL;
+	}
+
+	void debugCOF(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "AIS COF, version found: " << content["expected"].asInteger() << llendl;
+		std::set<LLUUID> ais_items, local_items;
+		const LLSD& cof_raw = content["cof_raw"];
+		for (LLSD::array_const_iterator it = cof_raw.beginArray();
+			 it != cof_raw.endArray(); ++it)
+		{
+			const LLSD& item = *it;
+			if (item["parent_id"].asUUID() == LLAppearanceMgr::instance().getCOF())
+			{
+				ais_items.insert(item["item_id"].asUUID());
+				if (item["type"].asInteger() == 24) // link
+				{
+					LL_DEBUGS("Avatar") << "Link: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+				}
+				else if (item["type"].asInteger() == 25) // folder link
+				{
+					LL_DEBUGS("Avatar") << "Folder link: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+					
+				}
+				else
+				{
+					LL_DEBUGS("Avatar") << "Other: item_id: " << item["item_id"].asUUID()
+										<< " linked_item_id: " << item["asset_id"].asUUID()
+										<< " name: " << item["name"].asString()
+										<< llendl; 
+				}
+			}
+		}
+		LL_DEBUGS("Avatar") << llendl;
+		LL_DEBUGS("Avatar") << "Local COF, version requested: " << content["observed"].asInteger() << llendl;
+		LLInventoryModel::cat_array_t cat_array;
+		LLInventoryModel::item_array_t item_array;
+		gInventory.collectDescendents(LLAppearanceMgr::instance().getCOF(),
+									  cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+		for (S32 i=0; i<item_array.count(); i++)
+		{
+			const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+			local_items.insert(inv_item->getUUID());
+			LL_DEBUGS("Avatar") << "item_id: " << inv_item->getUUID()
+								<< " linked_item_id: " << inv_item->getLinkedUUID()
+								<< " name: " << inv_item->getName()
+								<< llendl;
 		}
-		LLOutfitsList *outfits_list =
-			dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
-		if (outfits_list)
+		LL_DEBUGS("Avatar") << llendl;
+		for (std::set<LLUUID>::iterator it = local_items.begin(); it != local_items.end(); ++it)
 		{
-			outfits_list->setSelectedOutfitByUUID(mFolderID);
+			if (ais_items.find(*it) == ais_items.end())
+			{
+				LL_DEBUGS("Avatar") << "LOCAL ONLY: " << *it << llendl;
+			}
+		}
+		for (std::set<LLUUID>::iterator it = ais_items.begin(); it != ais_items.end(); ++it)
+		{
+			if (local_items.find(*it) == local_items.end())
+			{
+				LL_DEBUGS("Avatar") << "AIS ONLY: " << *it << llendl;
+			}
 		}
+	}
 
-		LLAppearanceMgr::getInstance()->updateIsDirty();
-		gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
-		LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
+};
+
+LLSD LLAppearanceMgr::dumpCOF() const
+{
+	LLSD links = LLSD::emptyArray();
+	LLMD5 md5;
+	
+	LLInventoryModel::cat_array_t cat_array;
+	LLInventoryModel::item_array_t item_array;
+	gInventory.collectDescendents(getCOF(),cat_array,item_array,LLInventoryModel::EXCLUDE_TRASH);
+	for (S32 i=0; i<item_array.count(); i++)
+	{
+		const LLViewerInventoryItem* inv_item = item_array.get(i).get();
+		LLSD item;
+		LLUUID item_id(inv_item->getUUID());
+		md5.update((unsigned char*)item_id.mData, 16);
+		item["description"] = inv_item->getActualDescription();
+		md5.update(inv_item->getActualDescription());
+		item["asset_type"] = inv_item->getActualType();
+		LLUUID linked_id(inv_item->getLinkedUUID());
+		item["linked_id"] = linked_id;
+		md5.update((unsigned char*)linked_id.mData, 16);
+
+		if (LLAssetType::AT_LINK == inv_item->getActualType())
+		{
+			const LLViewerInventoryItem* linked_item = inv_item->getLinkedItem();
+			if (NULL == linked_item)
+			{
+				llwarns << "Broken link for item '" << inv_item->getName()
+						<< "' (" << inv_item->getUUID()
+						<< ") during requestServerAppearanceUpdate" << llendl;
+				continue;
+			}
+			// Some assets may be 'hidden' and show up as null in the viewer.
+			//if (linked_item->getAssetUUID().isNull())
+			//{
+			//	llwarns << "Broken link (null asset) for item '" << inv_item->getName()
+			//			<< "' (" << inv_item->getUUID()
+			//			<< ") during requestServerAppearanceUpdate" << llendl;
+			//	continue;
+			//}
+			LLUUID linked_asset_id(linked_item->getAssetUUID());
+			md5.update((unsigned char*)linked_asset_id.mData, 16);
+			U32 flags = linked_item->getFlags();
+			md5.update(boost::lexical_cast<std::string>(flags));
+		}
+		else if (LLAssetType::AT_LINK_FOLDER != inv_item->getActualType())
+		{
+			llwarns << "Non-link item '" << inv_item->getName()
+					<< "' (" << inv_item->getUUID()
+					<< ") type " << (S32) inv_item->getActualType()
+					<< " during requestServerAppearanceUpdate" << llendl;
+			continue;
+		}
+		links.append(item);
 	}
+	LLSD result = LLSD::emptyMap();
+	result["cof_contents"] = links;
+	char cof_md5sum[MD5HEX_STR_SIZE];
+	md5.finalize();
+	md5.hex_digest(cof_md5sum);
+	result["cof_md5sum"] = std::string(cof_md5sum);
+	return result;
+}
 
-	virtual void fire(const LLUUID&)
-	{}
+void LLAppearanceMgr::requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr)
+{
+	if (gAgentAvatarp->isEditingAppearance()) 
+	{
+		// don't send out appearance updates if in appearance editing mode
+		return;
+	}
 
-private:
-	LLUUID mFolderID;
-	bool mShowPanel;
+	if (!gAgent.getRegion())
+	{
+		llwarns << "Region not set, cannot request server appearance update" << llendl;
+		return;
+	}
+	if (gAgent.getRegion()->getCentralBakeVersion()==0)
+	{
+		llwarns << "Region does not support baking" << llendl;
+	}
+	std::string url = gAgent.getRegion()->getCapability("UpdateAvatarAppearance");	
+	if (url.empty())
+	{
+		llwarns << "No cap for UpdateAvatarAppearance." << llendl;
+		return;
+	}
+	
+	LLSD body;
+	S32 cof_version = getCOFVersion();
+	if (gSavedSettings.getBOOL("DebugAvatarExperimentalServerAppearanceUpdate"))
+	{
+		body = dumpCOF();
+	}
+	else
+	{
+		body["cof_version"] = cof_version;
+		if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+		{
+			body["cof_version"] = cof_version+999;
+		}
+	}
+	LL_DEBUGS("Avatar") << "request url " << url << " my_cof_version " << cof_version << llendl;
+	
+	//LLCurl::ResponderPtr responder_ptr;
+	if (!responder_ptr.get())
+	{
+		responder_ptr = new RequestAgentUpdateAppearanceResponder;
+	}
+	LLHTTPClient::post(url, body, responder_ptr);
+	llassert(cof_version >= gAgentAvatarp->mLastUpdateRequestCOFVersion);
+	gAgentAvatarp->mLastUpdateRequestCOFVersion = cof_version;
+}
+
+class LLIncrementCofVersionResponder : public LLHTTPClient::Responder
+{
+public:
+	LLIncrementCofVersionResponder() : LLHTTPClient::Responder()
+	{
+		mRetryPolicy = new LLAdaptiveRetryPolicy(1.0, 16.0, 2.0, 5);
+	}
+
+	virtual ~LLIncrementCofVersionResponder()
+	{
+	}
+
+	virtual void result(const LLSD &pContent)
+	{
+		llinfos << "Successfully incremented agent's COF." << llendl;
+		S32 new_version = pContent["category"]["version"].asInteger();
+
+		// cof_version should have increased
+		llassert(new_version > gAgentAvatarp->mLastUpdateRequestCOFVersion);
+
+		gAgentAvatarp->mLastUpdateRequestCOFVersion = new_version;
+	}
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& content)
+	{
+		llwarns << "While attempting to increment the agent's cof we got an error with [status:"
+				<< pStatus << "]: " << content << llendl;
+		F32 seconds_to_wait;
+		if (mRetryPolicy->shouldRetry(pStatus,seconds_to_wait))
+		{
+			llinfos << "retrying" << llendl;
+			doAfterInterval(boost::bind(&LLAppearanceMgr::incrementCofVersion,
+										LLAppearanceMgr::getInstance(),
+										LLHTTPClient::ResponderPtr(this)),
+										seconds_to_wait);
+		}
+		else
+		{
+			llwarns << "giving up after too many retries" << llendl;
+		}
+	}
+
+	LLPointer<LLHTTPRetryPolicy> mRetryPolicy;
 };
 
+void LLAppearanceMgr::incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr)
+{
+	// If we don't have a region, report it as an error
+	if (gAgent.getRegion() == NULL)
+	{
+		llwarns << "Region not set, cannot request cof_version increment" << llendl;
+		return;
+	}
+
+	std::string url = gAgent.getRegion()->getCapability("IncrementCofVersion");
+	if (url.empty())
+	{
+		llwarns << "No cap for IncrementCofVersion." << llendl;
+		return;
+	}
+
+	llinfos << "Requesting cof_version be incremented via capability to: "
+			<< url << llendl;
+	LLSD headers;
+	LLSD body = LLSD::emptyMap();
+
+	if (!responder_ptr.get())
+	{
+		responder_ptr = LLHTTPClient::ResponderPtr(new LLIncrementCofVersionResponder());
+	}
+
+	LLHTTPClient::get(url, body, responder_ptr, headers, 30.0f);
+}
+
+std::string LLAppearanceMgr::getAppearanceServiceURL() const
+{
+	if (gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride").empty())
+	{
+		return mAppearanceServiceURL;
+	}
+	return gSavedSettings.getString("DebugAvatarAppearanceServiceURLOverride");
+}
+
+void show_created_outfit(LLUUID& folder_id, bool show_panel = true)
+{
+	if (!LLApp::isRunning())
+	{
+		llwarns << "called during shutdown, skipping" << llendl;
+		return;
+	}
+	
+	LLSD key;
+	
+	//EXT-7727. For new accounts inventory callback is created during login process
+	// and may be processed after login process is finished
+	if (show_panel)
+	{
+		LLFloaterSidePanelContainer::showPanel("appearance", "panel_outfits_inventory", key);
+		
+	}
+	LLOutfitsList *outfits_list =
+		dynamic_cast<LLOutfitsList*>(LLFloaterSidePanelContainer::getPanel("appearance", "outfitslist_tab"));
+	if (outfits_list)
+	{
+		outfits_list->setSelectedOutfitByUUID(folder_id);
+	}
+	
+	LLAppearanceMgr::getInstance()->updateIsDirty();
+	gAgentWearables.notifyLoadingFinished(); // New outfit is saved.
+	LLAppearanceMgr::getInstance()->updatePanelOutfitName("");
+}
+
 LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, bool show_panel)
 {
 	if (!isAgentAvatarValid()) return LLUUID::null;
@@ -2644,7 +3390,8 @@ LLUUID LLAppearanceMgr::makeNewOutfitLinks(const std::string& new_folder_name, b
 
 	updateClothingOrderingInfo();
 
-	LLPointer<LLInventoryCallback> cb = new LLShowCreatedOutfit(folder_id,show_panel);
+	LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(no_op_inventory_func,
+																		 boost::bind(show_created_outfit,folder_id,show_panel));
 	shallowCopyCategoryContents(getCOF(),folder_id, cb);
 	createBaseOutfitLink(folder_id, cb);
 
@@ -2661,33 +3408,26 @@ void LLAppearanceMgr::wearBaseOutfit()
 	updateCOF(base_outfit_id);
 }
 
-void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+void LLAppearanceMgr::removeItemsFromAvatar(const uuid_vec_t& ids_to_remove)
 {
-	LLViewerInventoryItem * item_to_remove = gInventory.getItem(id_to_remove);
-	if (!item_to_remove) return;
-
-	switch (item_to_remove->getType())
+	if (ids_to_remove.empty())
 	{
-		case LLAssetType::AT_CLOTHING:
-			if (get_is_item_worn(id_to_remove))
-			{
-				//*TODO move here the exact removing code from LLWearableBridge::removeItemFromAvatar in the future
-				LLWearableBridge::removeItemFromAvatar(item_to_remove);
-			}
-			break;
-		case LLAssetType::AT_OBJECT:
-			LLVOAvatarSelf::detachAttachmentIntoInventory(item_to_remove->getLinkedUUID());
-		default:
-			break;
+		llwarns << "called with empty list, nothing to do" << llendl;
+	}
+	for (uuid_vec_t::const_iterator it = ids_to_remove.begin(); it != ids_to_remove.end(); ++it)
+	{
+		const LLUUID& id_to_remove = *it;
+		const LLUUID& linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+		removeCOFItemLinks(linked_item_id);
 	}
+	updateAppearanceFromCOF();
+}
 
-	// *HACK: Force to remove garbage from COF.
-	// Unworn links or objects can't be processed by existed removing functionality
-	// since it is not designed for such cases. As example attachment object can't be removed
-	// since sever don't sends message _PREHASH_KillObject in that case.
-	// Also we can't check is link was successfully removed from COF since in case
-	// deleting attachment link removing performs asynchronously in process_kill_object callback.
-	removeCOFItemLinks(id_to_remove,false);
+void LLAppearanceMgr::removeItemFromAvatar(const LLUUID& id_to_remove)
+{
+	LLUUID linked_item_id = gInventory.getLinkedItemID(id_to_remove);
+	removeCOFItemLinks(linked_item_id);
+	updateAppearanceFromCOF();
 }
 
 bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_body)
@@ -2716,8 +3456,8 @@ bool LLAppearanceMgr::moveWearable(LLViewerInventoryItem* item, bool closer_to_b
 	closer_to_body ? --it : ++it;
 	LLViewerInventoryItem* swap_item = *it;
 	if (!swap_item) return false;
-	std::string tmp = swap_item->LLInventoryItem::getDescription();
-	swap_item->setDescription(item->LLInventoryItem::getDescription());
+	std::string tmp = swap_item->getActualDescription();
+	swap_item->setDescription(item->getActualDescription());
 	item->setDescription(tmp);
 
 
@@ -2750,7 +3490,7 @@ void LLAppearanceMgr::sortItemsByActualDescription(LLInventoryModel::item_array_
 {
 	if (items.size() < 2) return;
 
-	std::sort(items.begin(), items.end(), sort_by_description);
+	std::sort(items.begin(), items.end(), sort_by_actual_description);
 }
 
 //#define DUMP_CAT_VERBOSE
@@ -2816,7 +3556,7 @@ LLAppearanceMgr::~LLAppearanceMgr()
 
 void LLAppearanceMgr::setAttachmentInvLinkEnable(bool val)
 {
-	llinfos << "setAttachmentInvLinkEnable => " << (int) val << llendl;
+	LL_DEBUGS("Avatar") << "setAttachmentInvLinkEnable => " << (int) val << llendl;
 	mAttachmentInvLinkEnabled = val;
 }
 
@@ -2860,7 +3600,7 @@ void LLAppearanceMgr::unregisterAttachment(const LLUUID& item_id)
 
 	   if (mAttachmentInvLinkEnabled)
 	   {
-		   LLAppearanceMgr::removeCOFItemLinks(item_id, false);
+		   LLAppearanceMgr::removeCOFItemLinks(item_id);
 	   }
 	   else
 	   {
@@ -2954,9 +3694,9 @@ class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
 	}
 	virtual void done()
 	{
-		// What we do here is get the complete information on the items in
-		// the library, and set up an observer that will wait for that to
-		// happen.
+		// What we do here is get the complete information on the
+		// items in the requested category, and set up an observer
+		// that will wait for that to happen.
 		LLInventoryModel::cat_array_t cat_array;
 		LLInventoryModel::item_array_t item_array;
 		gInventory.collectDescendents(mComplete.front(),
@@ -2968,11 +3708,9 @@ class CallAfterCategoryFetchStage1: public LLInventoryFetchDescendentsObserver
 		{
 			llwarns << "Nothing fetched in category " << mComplete.front()
 					<< llendl;
-			//dec_busy_count();
 			gInventory.removeObserver(this);
+			doOnIdleOneTime(mCallable);
 
-			// lets notify observers that loading is finished.
-			gAgentWearables.notifyLoadingFinished();
 			delete this;
 			return;
 		}
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
old mode 100644
new mode 100755
index c1d561781d21f947f00b540480f7d3571add79df..46252afbde14799662de45582dbf63150c1f819d
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -35,7 +35,6 @@
 #include "llinventoryobserver.h"
 #include "llviewerinventory.h"
 
-class LLWearable;
 class LLWearableHoldingPattern;
 class LLInventoryCallback;
 class LLOutfitUnLockTimer;
@@ -93,6 +92,10 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	// Find the Current Outfit folder.
 	const LLUUID getCOF() const;
+	S32 getCOFVersion() const;
+
+	// Debugging - get truncated LLSD summary of COF contents.
+	LLSD dumpCOF() const;
 
 	// Finds the folder link to the currently worn outfit
 	const LLViewerInventoryItem *getBaseOutfitLink();
@@ -107,6 +110,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	// Update the displayed outfit name in UI.
 	void updatePanelOutfitName(const std::string& name);
 
+	void purgeBaseOutfitLink(const LLUUID& category);
 	void createBaseOutfitLink(const LLUUID& category, LLPointer<LLInventoryCallback> link_waiter);
 
 	void updateAgentWearables(LLWearableHoldingPattern* holder, bool append);
@@ -126,15 +130,17 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 				 LLPointer<LLInventoryCallback> cb);
 
 	// Add COF link to individual item.
-	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
-	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL);
+	void addCOFItemLink(const LLUUID& item_id, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
+	void addCOFItemLink(const LLInventoryItem *item, bool do_update = true, LLPointer<LLInventoryCallback> cb = NULL, const std::string description = "");
 
-	// Remove COF entries
-	void removeCOFItemLinks(const LLUUID& item_id, bool do_update = true);
-	void removeCOFLinksOfType(LLWearableType::EType type, bool do_update = true);
+	// Find COF entries referencing the given item.
+	LLInventoryModel::item_array_t findCOFItemLinks(const LLUUID& item_id);
 
-	// Add COF link to ensemble folder.
-	void addEnsembleLink(LLInventoryCategory* item, bool do_update = true);
+	// Remove COF entries
+	void removeCOFItemLinks(const LLUUID& item_id);
+	void removeCOFLinksOfType(LLWearableType::EType type);
+	void removeAllClothesFromAvatar();
+	void removeAllAttachmentsFromAvatar();
 
 	//has the current outfit changed since it was loaded?
 	bool isOutfitDirty() { return mOutfitIsDirty; }
@@ -162,6 +168,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	bool updateBaseOutfit();
 
 	//Remove clothing or detach an object from the agent (a bodypart cannot be removed)
+	void removeItemsFromAvatar(const uuid_vec_t& item_ids);
 	void removeItemFromAvatar(const LLUUID& item_id);
 
 
@@ -182,6 +189,20 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 
 	bool isInUpdateAppearanceFromCOF() { return mIsInUpdateAppearanceFromCOF; }
 
+	void requestServerAppearanceUpdate(LLCurl::ResponderPtr responder_ptr = NULL);
+
+	void incrementCofVersion(LLHTTPClient::ResponderPtr responder_ptr = NULL);
+
+	// *HACK Remove this after server side texture baking is deployed on all sims.
+	void incrementCofVersionLegacy();
+
+	void setAppearanceServiceURL(const std::string& url) { mAppearanceServiceURL = url; }
+	std::string getAppearanceServiceURL() const;
+
+private:
+	std::string		mAppearanceServiceURL;
+	
+
 protected:
 	LLAppearanceMgr();
 	~LLAppearanceMgr();
@@ -201,9 +222,7 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 								   LLInventoryModel::item_array_t& gest_items,
 								   bool follow_folder_links);
 
-	void purgeCategory(const LLUUID& category, bool keep_outfit_links);
-	void purgeBaseOutfitLink(const LLUUID& category);
-
+	void purgeCategory(const LLUUID& category, bool keep_outfit_links, LLInventoryModel::item_array_t* keep_items = NULL);
 	static void onOutfitRename(const LLSD& notification, const LLSD& response);
 
 	void setOutfitLocked(bool locked);
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 55d7a5d45dda1a135441221da87e9fa740c7bf35..97962b87053414811c6a7f194328fb0706a8a90a 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -42,6 +42,7 @@
 #include "llagentcamera.h"
 #include "llagentlanguage.h"
 #include "llagentwearables.h"
+#include "llfloaterimcontainer.h"
 #include "llwindow.h"
 #include "llviewerstats.h"
 #include "llviewerstatsrecorder.h"
@@ -59,6 +60,7 @@
 #include "llares.h" 
 #include "llcurl.h"
 #include "llcalc.h"
+#include "llconversationlog.h"
 #include "lltexturestats.h"
 #include "lltexturestats.h"
 #include "llviewerwindow.h"
@@ -93,7 +95,6 @@
 #include "llweb.h"
 #include "llsecondlifeurls.h"
 #include "llupdaterservice.h"
-#include "llcallfloater.h"
 #include "llfloatertexturefetchdebugger.h"
 #include "llspellcheck.h"
 
@@ -200,6 +201,7 @@
 #include "llviewercontrol.h"
 #include "lleventnotifier.h"
 #include "llcallbacklist.h"
+#include "lldeferredsounds.h"
 #include "pipeline.h"
 #include "llgesturemgr.h"
 #include "llsky.h"
@@ -219,7 +221,6 @@
 #include "llmachineid.h"
 #include "llmainlooprepeater.h"
 
-
 // *FIX: These extern globals should be cleaned up.
 // The globals either represent state/config/resource-storage of either 
 // this app, or another 'component' of the viewer. App globals should be 
@@ -291,6 +292,10 @@ LLTimer gLogoutTimer;
 static const F32 LOGOUT_REQUEST_TIME = 6.f;  // this will be cut short by the LogoutReply msg.
 F32 gLogoutMaxTime = LOGOUT_REQUEST_TIME;
 
+
+S32 gPendingMetricsUploads = 0;
+
+
 BOOL				gDisconnected = FALSE;
 
 // used to restore texture state after a mode switch
@@ -459,7 +464,18 @@ static void ui_audio_callback(const LLUUID& uuid)
 {
 	if (gAudiop)
 	{
-		gAudiop->triggerSound(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		gAudiop->triggerSound(soundData);
+	}
+}
+
+// A callback set in LLAppViewer::init()
+static void deferred_ui_audio_callback(const LLUUID& uuid)
+{
+	if (gAudiop)
+	{
+		SoundData soundData(uuid, gAgent.getID(), 1.0f, LLAudioEngine::AUDIO_TYPE_UI);
+		LLDeferredSounds::instance().deferSound(soundData);
 	}
 }
 
@@ -670,6 +686,15 @@ LLAppViewer::~LLAppViewer()
 	removeMarkerFile();
 }
 
+class LLUITranslationBridge : public LLTranslationBridge
+{
+public:
+	virtual std::string getString(const std::string &xml_desc)
+	{
+		return LLTrans::getString(xml_desc);
+	}
+};
+
 bool LLAppViewer::init()
 {	
 	//
@@ -681,6 +706,10 @@ bool LLAppViewer::init()
 	//
 	LLFastTimer::reset();
 
+	// initialize LLWearableType translation bridge.
+	// Memory will be cleaned up in ::cleanupClass()
+	LLWearableType::initClass(new LLUITranslationBridge());
+
 	// initialize SSE options
 	LLVector4a::initClass();
 
@@ -773,7 +802,8 @@ bool LLAppViewer::init()
 	LLUI::initClass(settings_map,
 		LLUIImageList::getInstance(),
 		ui_audio_callback,
-		&LLUI::sGLScaleFactor);
+		deferred_ui_audio_callback,
+		&LLUI::getScaleFactor());
 	LL_INFOS("InitInfo") << "UI initialized." << LL_ENDL ;
 
 	// NOW LLUI::getLanguage() should work. gDirUtilp must know the language
@@ -1217,7 +1247,7 @@ bool LLAppViewer::mainLoop()
 
 	LLVoiceChannel::initClass();
 	LLVoiceClient::getInstance()->init(gServicePump);
-	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLCallFloater::sOnCurrentChannelChanged, _1), true);
+	LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLFloaterIMContainer::onCurrentChannelChanged, _1), true);
 	LLTimer frameTimer,idleTimer;
 	LLTimer debugTime;
 	LLViewerJoystick* joystick(LLViewerJoystick::getInstance());
@@ -1750,6 +1780,8 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning up Objects" << llendflush;
 	
 	LLViewerObject::cleanupVOClasses();
+
+	LLAvatarAppearance::cleanupClass();
 	
 	LLPostProcess::cleanupClass();
 
@@ -1832,6 +1864,9 @@ bool LLAppViewer::cleanup()
 	// save mute list. gMuteList used to also be deleted here too.
 	LLMuteList::getInstance()->cache(gAgent.getID());
 
+	//save call log list
+	LLConversationLog::instance().cache();
+
 	if (mPurgeOnExit)
 	{
 		llinfos << "Purging all cache files on exit" << llendflush;
@@ -1986,6 +2021,8 @@ bool LLAppViewer::cleanup()
 	llinfos << "Cleaning up LLProxy." << llendl;
 	LLProxy::cleanupClass();
 
+	LLWearableType::cleanupClass();
+
 	LLMainLoopRepeater::instance().stop();
 
 	//release all private memory pools.
@@ -3545,6 +3582,12 @@ void LLAppViewer::requestQuit()
 
 	// Try to send metrics back to the grid
 	metricsSend(!gDisconnected);
+
+	// Try to send last batch of avatar rez metrics.
+	if (!gDisconnected && isAgentAvatarValid())
+	{
+		gAgentAvatarp->updateAvatarRezMetrics(true); // force a last packet to be sent.
+	}
 	
 	LLHUDEffectSpiral *effectp = (LLHUDEffectSpiral*)LLHUDManager::getInstance()->createViewerEffect(LLHUDObject::LL_HUD_EFFECT_POINT, TRUE);
 	effectp->setPositionGlobal(gAgent.getPositionGlobal());
@@ -4337,7 +4380,6 @@ void LLAppViewer::idle()
 			// The 5-second interval is nice for this purpose.  If the object debug
 			// bit moves or is disabled, please give this a suitable home.
 			LLViewerAssetStatsFF::record_fps_main(gFPSClamped);
-			LLViewerAssetStatsFF::record_avatar_stats();
 		}
 	}
 
@@ -4653,6 +4695,13 @@ void LLAppViewer::idleShutdown()
 		return;
 	}
 
+	if (gPendingMetricsUploads > 0
+		&& gLogoutTimer.getElapsedTimeF32() < SHUTDOWN_UPLOAD_SAVE_TIME
+		&& !logoutRequestSent())
+	{
+		return;
+	}
+
 	// All floaters are closed.  Tell server we want to quit.
 	if( !logoutRequestSent() )
 	{
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index 7563d672e3cb8d680cf14d7f69f5838674e4822f..08039100b3e7e8385f5d90d47a65197762fae974 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -342,6 +342,8 @@ extern LLFrameTimer gLoggedInTime;
 extern F32 gLogoutMaxTime;
 extern LLTimer gLogoutTimer;
 
+extern S32 gPendingMetricsUploads;
+
 extern F32 gSimLastTime; 
 extern F32 gSimFrames;
 
diff --git a/indra/newview/llappviewerwin32.cpp b/indra/newview/llappviewerwin32.cpp
index 8326be433e9db7ebf519b38e30cf6141c7d0f020..82b93b52a2a126c4858879519f753a30ece3009d 100644
--- a/indra/newview/llappviewerwin32.cpp
+++ b/indra/newview/llappviewerwin32.cpp
@@ -92,7 +92,7 @@ void nvapi_error(NvAPI_Status status)
 	llwarns << szDesc << llendl;
 
 	//should always trigger when asserts are enabled
-	llassert(status == NVAPI_OK);
+	//llassert(status == NVAPI_OK);
 }
 
 // Create app mutex creates a unique global windows object. 
diff --git a/indra/newview/llassetuploadqueue.cpp b/indra/newview/llassetuploadqueue.cpp
index f943759bb89c66fe1e27d633b60ea195ad307637..4bdb690225d6b871876ceb0e5a33de65fcf81086 100644
--- a/indra/newview/llassetuploadqueue.cpp
+++ b/indra/newview/llassetuploadqueue.cpp
@@ -69,10 +69,11 @@ class LLAssetUploadChainResponder : public LLUpdateTaskInventoryResponder
 		delete mData;
    	}
 	
-	virtual void error(U32 statusNum, const std::string& reason)
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
    	{
-		llwarns << "Error: " << reason << llendl;
-		LLUpdateTaskInventoryResponder::error(statusNum, reason);
+		llwarns << "LLAssetUploadChainResponder Error [status:" 
+				<< statusNum << "]: " << content << llendl;
+		LLUpdateTaskInventoryResponder::errorWithContent(statusNum, reason, content);
    		LLAssetUploadQueue *queue = mSupplier->get();
    		if (queue)
 		{
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 7b2c536f5add55b5a58027110a12cb2c477bd470..25648023879a9ee2e99ddd17f04df74292e4fcd7 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -48,8 +48,8 @@
 #include "llviewercontrol.h"
 #include "llviewerobjectlist.h"
 #include "llviewermenufile.h"
+#include "llviewertexlayer.h"
 #include "llviewerwindow.h"
-#include "lltexlayer.h"
 #include "lltrans.h"
 
 // library includes
@@ -225,10 +225,10 @@ LLAssetUploadResponder::~LLAssetUploadResponder()
 }
 
 // virtual
-void LLAssetUploadResponder::error(U32 statusNum, const std::string& reason)
+void LLAssetUploadResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLAssetUploadResponder::error " << statusNum 
-			<< " reason: " << reason << llendl;
+	llinfos << "LLAssetUploadResponder::error [status:" 
+			<< statusNum << "]: " << content << llendl;
 	LLSD args;
 	switch(statusNum)
 	{
@@ -340,9 +340,9 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(
 }
 
 // virtual
-void LLNewAgentInventoryResponder::error(U32 statusNum, const std::string& reason)
+void LLNewAgentInventoryResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	LLAssetUploadResponder::error(statusNum, reason);
+	LLAssetUploadResponder::errorWithContent(statusNum, reason, content);
 	//LLImportColladaAssetCache::getInstance()->assetUploaded(mVFileID, LLUUID(), FALSE);
 }
 
@@ -456,7 +456,7 @@ LLSendTexLayerResponder::LLSendTexLayerResponder(const LLSD& post_data,
 
 LLSendTexLayerResponder::~LLSendTexLayerResponder()
 {
-	// mBakedUploadData is normally deleted by calls to LLTexLayerSetBuffer::onTextureUploadComplete() below
+	// mBakedUploadData is normally deleted by calls to LLViewerTexLayerSetBuffer::onTextureUploadComplete() below
 	if (mBakedUploadData)
 	{	// ...but delete it in the case where uploadComplete() is never called
 		delete mBakedUploadData;
@@ -477,22 +477,23 @@ void LLSendTexLayerResponder::uploadComplete(const LLSD& content)
 	if (result == "complete"
 		&& mBakedUploadData != NULL)
 	{	// Invoke 
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, 0, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 	else
 	{	// Invoke the original callback with an error result
-		LLTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+		LLViewerTexLayerSetBuffer::onTextureUploadComplete(new_id, (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 		mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 	}
 }
 
-void LLSendTexLayerResponder::error(U32 statusNum, const std::string& reason)
+void LLSendTexLayerResponder::errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 {
-	llinfos << "status: " << statusNum << " reason: " << reason << llendl;
+	llinfos << "LLSendTexLayerResponder error [status:"
+			<< statusNum << "]: " << content << llendl;
 	
 	// Invoke the original callback with an error result
-	LLTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
+	LLViewerTexLayerSetBuffer::onTextureUploadComplete(LLUUID(), (void*) mBakedUploadData, -1, LL_EXSTAT_NONE);
 	mBakedUploadData = NULL;	// deleted in onTextureUploadComplete()
 }
 
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index 381b919c4a4c15587d0227d22bedfb89a167a43b..a6d1016136c6a49f86578e4077bf1acc010a822d 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -42,7 +42,7 @@ class LLAssetUploadResponder : public LLHTTPClient::Responder
 							LLAssetType::EType asset_type);
 	~LLAssetUploadResponder();
 
-    virtual void error(U32 statusNum, const std::string& reason);
+    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 	virtual void uploadUpload(const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
@@ -67,7 +67,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 		const LLSD& post_data,
 		const std::string& file_name,
 		LLAssetType::EType asset_type);
-    virtual void error(U32 statusNum, const std::string& reason);
+    virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 	virtual void uploadComplete(const LLSD& content);
 	virtual void uploadFailure(const LLSD& content);
 };
@@ -122,7 +122,7 @@ class LLSendTexLayerResponder : public LLAssetUploadResponder
 	~LLSendTexLayerResponder();
 
 	virtual void uploadComplete(const LLSD& content);
-	virtual void error(U32 statusNum, const std::string& reason);
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content);
 
 	LLBakedUploadData * mBakedUploadData;
 };
diff --git a/indra/newview/llautoreplace.cpp b/indra/newview/llautoreplace.cpp
index d71cf290d6d3fb559076b866160720b8b63ea54a..1d72397cbc1d4d22c215b29c57bee20348876659 100644
--- a/indra/newview/llautoreplace.cpp
+++ b/indra/newview/llautoreplace.cpp
@@ -30,68 +30,60 @@
 #include "llviewercontrol.h"
 #include "llnotificationsutil.h"
 
-LLAutoReplace* LLAutoReplace::sInstance;
-
 const char* LLAutoReplace::SETTINGS_FILE_NAME = "autoreplace.xml";
 
-LLAutoReplace::LLAutoReplace()
-{
-}
-
-LLAutoReplace::~LLAutoReplace()
+void LLAutoReplace::autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text)
 {
-	sInstance = NULL;
-}
+	// make sure these returned values are cleared in case there is no replacement
+	replacement_start = 0;
+	replacement_length = 0;
+	replacement_string.clear();
 
-void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
-{
 	static LLCachedControl<bool> perform_autoreplace(gSavedSettings, "AutoReplace");
-	if(perform_autoreplace)
+	if (perform_autoreplace)
 	{
-		S32 wordEnd = cursorPos-1;
-		LLWString text = inputText.getWString();
+		S32 word_end = cursor_pos - 1;
 
-		bool atSpace  = (text[wordEnd] == ' ');
-		bool haveWord = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+		bool at_space  = (input_text[word_end] == ' ');
+		bool have_word = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 
-		if (atSpace || haveWord)
+		if (at_space || have_word)
 		{
-			if (atSpace && wordEnd > 0)
+			if (at_space && word_end > 0)
 			{
 				// find out if this space immediately follows a word
-				wordEnd--;
-				haveWord  = (LLWStringUtil::isPartOfWord(text[wordEnd]));
+				word_end--;
+				have_word  = (LLWStringUtil::isPartOfWord(input_text[word_end]));
 			}
-			if (haveWord)
+			if (have_word)
 			{
-				// wordEnd points to the end of a word, now find the start of the word
+				// word_end points to the end of a word, now find the start of the word
 				std::string word;
-				S32 wordStart = wordEnd;
-				for ( S32 backOne = wordStart - 1;
-					  backOne >= 0 && LLWStringUtil::isPartOfWord(text[backOne]);
-					  backOne--
-					 )
+				S32 word_start = word_end;
+				for (S32 back_one = word_start - 1;
+					 back_one >= 0 && LLWStringUtil::isPartOfWord(input_text[back_one]);
+					 back_one--
+					)
 				{
-					wordStart--; // walk wordStart back to the beginning of the word
+					word_start--; // walk word_start back to the beginning of the word
 				}
-				LL_DEBUGS("AutoReplace")<<"wordStart: "<<wordStart<<" wordEnd: "<<wordEnd<<LL_ENDL;
-				std::string strText  = std::string(text.begin(), text.end());
-				std::string lastWord = strText.substr(wordStart, wordEnd-wordStart+1);
-				std::string replacementWord( mSettings.replaceWord( lastWord ) );
+				LL_DEBUGS("AutoReplace") << "word_start: " << word_start << " word_end: " << word_end << LL_ENDL;
+				std::string str_text  = std::string(input_text.begin(), input_text.end());
+				std::string last_word = str_text.substr(word_start, word_end - word_start + 1);
+				std::string replacement_word(mSettings.replaceWord(last_word));
 
-				if ( replacementWord != lastWord )
+				if (replacement_word != last_word)
 				{
 					// The last word is one for which we have a replacement
-					if (atSpace)
+					if (at_space)
 					{
-						// replace the last word in the input
-						LLWString strNew = utf8str_to_wstring(replacementWord);
-						LLWString strOld = utf8str_to_wstring(lastWord);
-						int size_change = strNew.size() - strOld.size();
-
-						text.replace(wordStart,lastWord.length(),strNew);
-						inputText = wstring_to_utf8str(text);
-						cursorPos+=size_change;
+						// return the replacement string
+						replacement_start = word_start;
+						replacement_length = last_word.length();
+						replacement_string = utf8str_to_wstring(replacement_word);
+						LLWString old_string = utf8str_to_wstring(last_word);
+						S32 size_change = replacement_string.size() - old_string.size();
+						cursor_pos += size_change;
 					}
 				}
 			}
@@ -99,16 +91,6 @@ void LLAutoReplace::autoreplaceCallback(LLUIString& inputText, S32& cursorPos)
 	}
 }
 
-LLAutoReplace* LLAutoReplace::getInstance()
-{
-	if(!sInstance)
-	{
-		sInstance = new LLAutoReplace();
-		sInstance->loadFromSettings();
-	}
-	return sInstance;
-}
-
 std::string LLAutoReplace::getUserSettingsFileName()
 {
 	std::string path=gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
@@ -147,6 +129,15 @@ void LLAutoReplace::setSettings(const LLAutoReplaceSettings& newSettings)
 	saveToUserSettings();
 }
 
+LLAutoReplace::LLAutoReplace()
+{
+}
+
+void LLAutoReplace::initSingleton()
+{
+    loadFromSettings();
+}
+
 void LLAutoReplace::loadFromSettings()
 {
 	std::string filename=getUserSettingsFileName();
@@ -220,7 +211,7 @@ void LLAutoReplace::saveToUserSettings()
 	std::string filename=getUserSettingsFileName();
 	llofstream file;
 	file.open(filename.c_str());
-	LLSDSerialize::toPrettyXML(mSettings.getAsLLSD(), file);
+	LLSDSerialize::toPrettyXML(mSettings.asLLSD(), file);
 	file.close();
 	LL_INFOS("AutoReplace") << "settings saved to '" << filename << "'" << LL_ENDL;
 }
@@ -801,7 +792,7 @@ LLSD LLAutoReplaceSettings::getExampleLLSD()
 	return example;
 }
 
-const LLSD& LLAutoReplaceSettings::getAsLLSD()
+const LLSD& LLAutoReplaceSettings::asLLSD()
 {
 	return mLists;
 }
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
index f720cc4edaf0a164fbc0e709f993f0b7756e6332..9eecc2d9814911608793d5195a72a7e202e1cdaf 100644
--- a/indra/newview/llautoreplace.h
+++ b/indra/newview/llautoreplace.h
@@ -132,7 +132,7 @@ class LLAutoReplaceSettings
 	LLSD getExampleLLSD();
 
 	/// Get the actual settings as LLSD
-	const LLSD& getAsLLSD();
+	const LLSD& asLLSD();
 	///< @note for use only in AutoReplace::saveToUserSettings
 	
   private:
@@ -183,49 +183,45 @@ class LLAutoReplaceSettings
  * When the end of a word is detected (defined as any punctuation character,
  * or any whitespace except newline or return), the preceding word is used
  * as a lookup key in an ordered list of maps.  If a match is found in any
- * map, the keyword is replaced by the associated value from the map.
+ * map, the replacement start index and length are returned along with the
+ * new replacement string.
  *
  * See the autoreplaceCallback method for how to add autoreplace functionality
  * to a text entry tool.
  */
 class LLAutoReplace : public LLSingleton<LLAutoReplace>
 {
-  public:
-	LLAutoReplace();
-	~LLAutoReplace();
-
-	/// @return a pointer to the active instance
-	static LLAutoReplace* getInstance();
+public:
+    /// Callback that provides the hook for use in text entry methods
+    void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
 
-	/// Callback that provides the hook for use in text entry methods
-	void autoreplaceCallback(LLUIString& inputText, S32& cursorPos);
+    /// Get a copy of the current settings
+    LLAutoReplaceSettings getSettings();
 
-	/// Get a copy of the current settings
-	LLAutoReplaceSettings getSettings();
+    /// Commit new settings after making changes
+    void setSettings(const LLAutoReplaceSettings& settings);
 
-	/// Commit new settings after making changes
-	void setSettings(const LLAutoReplaceSettings& settings);
-
-  private:
-	friend class LLSingleton<LLAutoReplace>;
-	static LLAutoReplace* sInstance; ///< the active settings instance
+private:
+    friend class LLSingleton<LLAutoReplace>;
+    LLAutoReplace();
+    /*virtual*/ void initSingleton();
 
-	LLAutoReplaceSettings mSettings; ///< configuration information
+    LLAutoReplaceSettings mSettings; ///< configuration information
 	
-	/// Read settings from persistent storage
-	void loadFromSettings();
+    /// Read settings from persistent storage
+    void loadFromSettings();
 
-	/// Make the newSettings active and write them to user storage
-	void saveToUserSettings();
+    /// Make the newSettings active and write them to user storage
+    void saveToUserSettings();
 
-	/// Compute the user settings file name
-	std::string getUserSettingsFileName();
+    /// Compute the user settings file name
+    std::string getUserSettingsFileName();
 
-	/// Compute the (read-ony) application settings file name
-	std::string getAppSettingsFileName();
+    /// Compute the (read-ony) application settings file name
+    std::string getAppSettingsFileName();
 
-	/// basename for the settings files
-	static const char* SETTINGS_FILE_NAME;
+    /// basename for the settings files
+    static const char* SETTINGS_FILE_NAME;
 };
 
 #endif /* LLAUTOREPLACE_H */
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index fdd4565e50dbc3e88c99d6786895b47222ef2dbf..b513a52ff7c56c360c3f04af6edfdd900bb16201 100755
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -42,7 +42,9 @@
 #include "llappviewer.h"		// for gLastVersionChannel
 #include "llcachename.h"
 #include "llcallingcard.h"		// for LLAvatarTracker
+#include "llconversationlog.h"
 #include "llfloateravatarpicker.h"	// for LLFloaterAvatarPicker
+#include "llfloaterconversationpreview.h"
 #include "llfloatergroupinvite.h"
 #include "llfloatergroups.h"
 #include "llfloaterreg.h"
@@ -55,6 +57,7 @@
 #include "llinventorybridge.h"
 #include "llinventorymodel.h"	// for gInventory.findCategoryUUIDForType
 #include "llinventorypanel.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"			// for gIMMgr
 #include "llmutelist.h"
 #include "llnotificationsutil.h"	// for LLNotificationsUtil
@@ -66,7 +69,6 @@
 #include "llviewerobjectlist.h"
 #include "llviewermessage.h"	// for handle_lure
 #include "llviewerregion.h"
-#include "llimfloater.h"
 #include "lltrans.h"
 #include "llcallingcard.h"
 #include "llslurl.h"			// IDEVO
@@ -93,7 +95,7 @@ void LLAvatarActions::requestFriendshipDialog(const LLUUID& id, const std::strin
 	LLRecentPeople::instance().add(id);
 }
 
-void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
+static void on_avatar_name_friendship(const LLUUID& id, const LLAvatarName av_name)
 {
 	LLAvatarActions::requestFriendshipDialog(id, av_name.getCompleteName());
 }
@@ -134,7 +136,7 @@ void LLAvatarActions::removeFriendsDialog(const uuid_vec_t& ids)
 		LLAvatarName av_name;
 		if(LLAvatarNameCache::get(agent_id, &av_name))
 		{
-			args["NAME"] = av_name.mDisplayName;
+			args["NAME"] = av_name.getDisplayName();
 		}
 
 		msgType = "RemoveFromFriends";
@@ -179,11 +181,11 @@ void LLAvatarActions::offerTeleport(const uuid_vec_t& ids)
 static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 										  const LLAvatarName& av_name)
 {
-	std::string name = av_name.getCompleteName();
+	std::string name = av_name.getDisplayName();
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		LLFloaterIMContainer::getInstance()->showConversation(session_id);
 	}
 	make_ui_sound("UISndStartIM");
 }
@@ -191,11 +193,10 @@ static void on_avatar_name_cache_start_im(const LLUUID& agent_id,
 // static
 void LLAvatarActions::startIM(const LLUUID& id)
 {
-	if (id.isNull())
+	if (id.isNull() || gAgent.getID() == id)
 		return;
 
-	LLAvatarNameCache::get(id,
-		boost::bind(&on_avatar_name_cache_start_im, _1, _2));
+	LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_im, _1, _2));
 }
 
 // static
@@ -214,7 +215,7 @@ void LLAvatarActions::endIM(const LLUUID& id)
 static void on_avatar_name_cache_start_call(const LLUUID& agent_id,
 											const LLAvatarName& av_name)
 {
-	std::string name = av_name.getCompleteName();
+	std::string name = av_name.getDisplayName();
 	LLUUID session_id = gIMMgr->addSession(name, IM_NOTHING_SPECIAL, agent_id, true);
 	if (session_id != LLUUID::null)
 	{
@@ -230,12 +231,11 @@ void LLAvatarActions::startCall(const LLUUID& id)
 	{
 		return;
 	}
-	LLAvatarNameCache::get(id,
-		boost::bind(&on_avatar_name_cache_start_call, _1, _2));
+	LLAvatarNameCache::get(id, boost::bind(&on_avatar_name_cache_start_call, _1, _2));
 }
 
 // static
-void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
+void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id)
 {
 	if (ids.size() == 0)
 	{
@@ -252,7 +252,7 @@ void LLAvatarActions::startAdhocCall(const uuid_vec_t& ids)
 	// create the new ad hoc voice session
 	const std::string title = LLTrans::getString("conference-title");
 	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START,
-										   ids[0], id_array, true);
+										   ids[0], id_array, true, floater_id);
 	if (session_id == LLUUID::null)
 	{
 		return;
@@ -285,7 +285,7 @@ bool LLAvatarActions::canCall()
 }
 
 // static
-void LLAvatarActions::startConference(const uuid_vec_t& ids)
+void LLAvatarActions::startConference(const uuid_vec_t& ids, const LLUUID& floater_id)
 {
 	// *HACK: Copy into dynamic array
 	LLDynamicArray<LLUUID> id_array;
@@ -294,11 +294,15 @@ void LLAvatarActions::startConference(const uuid_vec_t& ids)
 		id_array.push_back(*it);
 	}
 	const std::string title = LLTrans::getString("conference-title");
-	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array);
-	if (session_id != LLUUID::null)
+	LLUUID session_id = gIMMgr->addSession(title, IM_SESSION_CONFERENCE_START, ids[0], id_array, false, floater_id);
+
+	if (session_id == LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		return;
 	}
+	
+	LLFloaterIMContainer::getInstance()->showConversation(session_id);
+	
 	make_ui_sound("UISndStartIM");
 }
 
@@ -310,19 +314,11 @@ static const char* get_profile_floater_name(const LLUUID& avatar_id)
 
 static void on_avatar_name_show_profile(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
-	std::string username = av_name.mUsername;
-	if (username.empty())
-	{
-		username = LLCacheName::buildUsername(av_name.mDisplayName);
-	}
-	
-	llinfos << "opening web profile for " << username << llendl;		
-	std::string url = getProfileURL(username);
+	std::string url = getProfileURL(av_name.getAccountName());
 
 	// PROFILES: open in webkit window
 	LLFloaterWebContent::Params p;
-	p.url(url).
-		id(agent_id.asString());
+	p.url(url).id(agent_id.asString());
 	LLFloaterReg::showInstance(get_profile_floater_name(agent_id), p);
 }
 
@@ -374,19 +370,19 @@ void LLAvatarActions::showOnMap(const LLUUID& id)
 		return;
 	}
 
-	gFloaterWorldMap->trackAvatar(id, av_name.mDisplayName);
+	gFloaterWorldMap->trackAvatar(id, av_name.getDisplayName());
 	LLFloaterReg::showInstance("world_map");
 }
 
 // static
 void LLAvatarActions::pay(const LLUUID& id)
 {
-	LLNotification::Params params("BusyModePay");
+	LLNotification::Params params("DoNotDisturbModePay");
 	params.functor.function(boost::bind(&LLAvatarActions::handlePay, _1, _2, id));
 
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
-		// warn users of being in busy mode during a transaction
+		// warn users of being in do not disturb mode during a transaction
 		LLNotifications::instance().add(params);
 	}
 	else
@@ -448,6 +444,7 @@ void LLAvatarActions::share(const LLUUID& id)
 {
 	LLSD key;
 	LLFloaterSidePanelContainer::showPanel("inventory", key);
+	LLFloaterReg::showInstance("im_container");
 
 	LLUUID session_id = gIMMgr->computeSessionID(IM_NOTHING_SPECIAL,id);
 
@@ -529,23 +526,6 @@ namespace action_give_inventory
 		return acceptable;
 	}
 
-	static void build_residents_string(const std::vector<LLAvatarName> avatar_names, std::string& residents_string)
-	{
-		llassert(avatar_names.size() > 0);
-
-		const std::string& separator = LLTrans::getString("words_separator");
-		for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
-		{
-			LLAvatarName av_name = *it;
-			residents_string.append(av_name.mDisplayName);
-			if	(++it == avatar_names.end())
-			{
-				break;
-			}
-			residents_string.append(separator);
-		}
-	}
-
 	static void build_items_string(const std::set<LLUUID>& inventory_selected_uuids , std::string& items_string)
 	{
 		llassert(inventory_selected_uuids.size() > 0);
@@ -681,7 +661,7 @@ namespace action_give_inventory
 		}
 
 		std::string residents;
-		build_residents_string(avatar_names, residents);
+		LLAvatarActions::buildResidentsString(avatar_names, residents);
 
 		std::string items;
 		build_items_string(inventory_selected_uuids, items);
@@ -712,38 +692,84 @@ namespace action_give_inventory
 	}
 }
 
+// static
+void LLAvatarActions::buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string)
+{
+	llassert(avatar_names.size() > 0);
+	
+	std::sort(avatar_names.begin(), avatar_names.end());
+	const std::string& separator = LLTrans::getString("words_separator");
+	for (std::vector<LLAvatarName>::const_iterator it = avatar_names.begin(); ; )
+	{
+		residents_string.append((*it).getDisplayName());
+		if	(++it == avatar_names.end())
+		{
+			break;
+		}
+		residents_string.append(separator);
+	}
+}
 
+// static
+void LLAvatarActions::buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string)
+{
+	std::vector<LLAvatarName> avatar_names;
+	uuid_vec_t::const_iterator it = avatar_uuids.begin();
+	for (; it != avatar_uuids.end(); ++it)
+	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(*it, &av_name))
+		{
+			avatar_names.push_back(av_name);
+		}
+	}
+	
+	// We should check whether the vector is not empty to pass the assertion
+	// that avatar_names.size() > 0 in LLAvatarActions::buildResidentsString.
+	if (!avatar_names.empty())
+	{
+		LLAvatarActions::buildResidentsString(avatar_names, residents_string);
+	}
+}
 
 //static
 std::set<LLUUID> LLAvatarActions::getInventorySelectedUUIDs()
 {
-	std::set<LLUUID> inventory_selected_uuids;
+	std::set<LLFolderViewItem*> inventory_selected;
 
 	LLInventoryPanel* active_panel = action_give_inventory::get_active_inventory_panel();
 	if (active_panel)
 	{
-		inventory_selected_uuids = active_panel->getRootFolder()->getSelectionList();
+		inventory_selected= active_panel->getRootFolder()->getSelectionList();
 	}
 
-	if (inventory_selected_uuids.empty())
+	if (inventory_selected.empty())
 	{
 		LLSidepanelInventory *sidepanel_inventory = LLFloaterSidePanelContainer::getPanel<LLSidepanelInventory>("inventory");
 		if (sidepanel_inventory)
 		{
-			inventory_selected_uuids = sidepanel_inventory->getInboxSelectionList();
+			inventory_selected= sidepanel_inventory->getInboxSelectionList();
 		}
 	}
 
+	std::set<LLUUID> inventory_selected_uuids;
+	for (std::set<LLFolderViewItem*>::iterator it = inventory_selected.begin(), end_it = inventory_selected.end();
+		it != end_it;
+		++it)
+	{
+		inventory_selected_uuids.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+	}
 	return inventory_selected_uuids;
 }
 
 //static
-void LLAvatarActions::shareWithAvatars()
+void LLAvatarActions::shareWithAvatars(LLView * panel)
 {
 	using namespace action_give_inventory;
 
+    LLFloater* root_floater = gFloaterView->getParentFloater(panel);
 	LLFloaterAvatarPicker* picker =
-		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE);
+		LLFloaterAvatarPicker::show(boost::bind(give_inventory, _1, _2), TRUE, FALSE, FALSE, root_floater->getName());
 	if (!picker)
 	{
 		return;
@@ -751,6 +777,11 @@ void LLAvatarActions::shareWithAvatars()
 
 	picker->setOkBtnEnableCb(boost::bind(is_give_inventory_acceptable));
 	picker->openFriendsTab();
+    
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
 	LLNotificationsUtil::add("ShareNotification");
 }
 
@@ -769,15 +800,15 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 
 	// check selection in the panel
 	LLFolderView* root_folder = inv_panel->getRootFolder();
-	const std::set<LLUUID> inventory_selected_uuids = root_folder->getSelectionList();
-	if (inventory_selected_uuids.empty()) return false; // nothing selected
+	const std::set<LLFolderViewItem*> inventory_selected = root_folder->getSelectionList();
+	if (inventory_selected.empty()) return false; // nothing selected
 
 	bool can_share = true;
-	std::set<LLUUID>::const_iterator it = inventory_selected_uuids.begin();
-	const std::set<LLUUID>::const_iterator it_end = inventory_selected_uuids.end();
+	std::set<LLFolderViewItem*>::const_iterator it = inventory_selected.begin();
+	const std::set<LLFolderViewItem*>::const_iterator it_end = inventory_selected.end();
 	for (; it != it_end; ++it)
 	{
-		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(*it);
+		LLViewerInventoryCategory* inv_cat = gInventory.getCategory(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
 		// any category can be offered.
 		if (inv_cat)
 		{
@@ -785,9 +816,9 @@ bool LLAvatarActions::canShareSelectedItems(LLInventoryPanel* inv_panel /* = NUL
 		}
 
 		// check if inventory item can be given
-		LLFolderViewItem* item = root_folder->getItemByID(*it);
+		LLFolderViewItem* item = *it;
 		if (!item) return false;
-		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getListener());
+		LLInvFVBridge* bridge = dynamic_cast<LLInvFVBridge*>(item->getViewModelItem());
 		if (bridge && bridge->canShare())
 		{
 			continue;
@@ -819,6 +850,26 @@ void LLAvatarActions::toggleBlock(const LLUUID& id)
 	}
 }
 
+// static
+void LLAvatarActions::toggleMuteVoice(const LLUUID& id)
+{
+	std::string name;
+	gCacheName->getFullName(id, name); // needed for mute
+
+	LLMuteList* mute_list = LLMuteList::getInstance();
+	bool is_muted = mute_list->isMuted(id, LLMute::flagVoiceChat);
+
+	LLMute mute(id, name, LLMute::AGENT);
+	if (!is_muted)
+	{
+		mute_list->add(mute, LLMute::flagVoiceChat);
+	}
+	else
+	{
+		mute_list->remove(mute, LLMute::flagVoiceChat);
+	}
+}
+
 // static
 bool LLAvatarActions::canOfferTeleport(const LLUUID& id)
 {
@@ -865,6 +916,33 @@ void LLAvatarActions::inviteToGroup(const LLUUID& id)
 	}
 }
 
+// static
+void LLAvatarActions::viewChatHistory(const LLUUID& id)
+{
+	const std::vector<LLConversation>& conversations = LLConversationLog::instance().getConversations();
+	std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+	for (; iter != conversations.end(); ++iter)
+	{
+		if (iter->getParticipantID() == id)
+		{
+			LLFloaterReg::showInstance("preview_conversation", iter->getSessionID(), true);
+			return;
+		}
+	}
+
+	if (LLLogChat::isTranscriptExist(id))
+	{
+		LLAvatarName avatar_name;
+		LLSD extended_id(id);
+
+		LLAvatarNameCache::get(id, &avatar_name);
+		extended_id[LL_FCP_COMPLETE_NAME] = avatar_name.getCompleteName();
+		extended_id[LL_FCP_ACCOUNT_NAME] = avatar_name.getAccountName();
+		LLFloaterReg::showInstance("preview_conversation", extended_id, true);
+	}
+}
+
 //== private methods ========================================================================================
 
 // static
@@ -907,7 +985,7 @@ bool LLAvatarActions::handlePay(const LLSD& notification, const LLSD& response,
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	LLFloaterPayUtil::payDirectly(&give_money, avatar_id, /*is_group=*/false);
@@ -1015,7 +1093,6 @@ void LLAvatarActions::requestFriendship(const LLUUID& target_id, const std::stri
 
 	LLSD payload;
 	payload["from_id"] = target_id;
-	payload["SUPPRESS_TOAST"] = true;
 	LLNotificationsUtil::add("FriendshipOffered", args, payload);
 }
 
@@ -1033,6 +1110,12 @@ bool LLAvatarActions::isBlocked(const LLUUID& id)
 	return LLMuteList::getInstance()->isMuted(id, name);
 }
 
+// static
+bool LLAvatarActions::isVoiceMuted(const LLUUID& id)
+{
+	return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
+}
+
 // static
 bool LLAvatarActions::canBlock(const LLUUID& id)
 {
diff --git a/indra/newview/llavataractions.h b/indra/newview/llavataractions.h
index 748b7cb3d19fc583f2a88d940958e3c179e5b5eb..6e1198cd09885b89f2b3d6c268f74558b410eef4 100644
--- a/indra/newview/llavataractions.h
+++ b/indra/newview/llavataractions.h
@@ -34,8 +34,10 @@
 #include <string>
 #include <vector>
 
+class LLAvatarName;
 class LLInventoryPanel;
 class LLFloater;
+class LLView;
 
 /**
  * Friend-related actions (add, remove, offer teleport, etc)
@@ -81,14 +83,14 @@ class LLAvatarActions
 	static void startCall(const LLUUID& id);
 
 	/**
-	 * Start an ad-hoc conference voice call with multiple users
+	 * Start an ad-hoc conference voice call with multiple users in a specific IM floater.
 	 */
-	static void startAdhocCall(const uuid_vec_t& ids);
+	static void startAdhocCall(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
 
 	/**
-	 * Start conference chat with the given avatars.
+	 * Start conference chat with the given avatars in a specific IM floater.
 	 */
-	static void startConference(const uuid_vec_t& ids);
+	static void startConference(const uuid_vec_t& ids, const LLUUID& floater_id = LLUUID::null);
 
 	/**
 	 * Show avatar profile.
@@ -116,13 +118,18 @@ class LLAvatarActions
 	/**
 	 * Share items with the picked avatars.
 	 */
-	static void shareWithAvatars();
+	static void shareWithAvatars(LLView * panel);
 
 	/**
 	 * Block/unblock the avatar.
 	 */
 	static void toggleBlock(const LLUUID& id);
 
+	/**
+	 * Block/unblock the avatar voice.
+	 */
+	static void toggleMuteVoice(const LLUUID& id);
+
 	/**
 	 * Return true if avatar with "id" is a friend
 	 */
@@ -133,6 +140,11 @@ class LLAvatarActions
 	 */
 	static bool isBlocked(const LLUUID& id);
 
+	/**
+	 * @return true if the avatar voice is blocked
+	 */
+	static bool isVoiceMuted(const LLUUID& id);
+
 	/**
 	 * @return true if you can block the avatar
 	 */
@@ -198,6 +210,27 @@ class LLAvatarActions
 	 */
 	static bool canShareSelectedItems(LLInventoryPanel* inv_panel = NULL);
 
+	/**
+	 * Builds a string of residents' display names separated by "words_separator" string.
+	 *
+	 * @param avatar_names - a vector of given avatar names from which resulting string is built
+	 * @param residents_string - the resulting string
+	 */
+	static void buildResidentsString(std::vector<LLAvatarName> avatar_names, std::string& residents_string);
+
+	/**
+	 * Builds a string of residents' display names separated by "words_separator" string.
+	 *
+	 * @param avatar_uuids - a vector of given avatar uuids from which resulting string is built
+	 * @param residents_string - the resulting string
+	 */
+	static void buildResidentsString(const uuid_vec_t& avatar_uuids, std::string& residents_string);
+
+	/**
+	 * Opens the chat history for avatar
+	 */
+	static void viewChatHistory(const LLUUID& id);
+
 	static std::set<LLUUID> getInventorySelectedUUIDs();
 
 private:
diff --git a/indra/newview/llavatariconctrl.cpp b/indra/newview/llavatariconctrl.cpp
index b539ac38ed82eedf7dc83e2cd98af50e86a4d317..f34ad2376994316c71cc874fd33af9e695a542a8 100755
--- a/indra/newview/llavatariconctrl.cpp
+++ b/indra/newview/llavatariconctrl.cpp
@@ -28,6 +28,8 @@
 
 #include "llavatariconctrl.h"
 
+#include <boost/signals2.hpp>
+
 // viewer includes
 #include "llagent.h"
 #include "llavatarconstants.h"
@@ -36,7 +38,9 @@
 #include "llmenugl.h"
 #include "lluictrlfactory.h"
 #include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
+#include "llviewertexture.h"
+#include "llavatarappearancedefines.h"
 
 // library includes
 #include "llavatarnamecache.h"
@@ -148,9 +152,13 @@ LLAvatarIconCtrl::Params::Params()
 
 
 LLAvatarIconCtrl::LLAvatarIconCtrl(const LLAvatarIconCtrl::Params& p)
-:	LLIconCtrl(p),
+	: LLIconCtrl(p),
+	LLAvatarPropertiesObserver(),
+	mAvatarId(),
+	mFullName(),
 	mDrawTooltip(p.draw_tooltip),
-	mDefaultIconName(p.default_icon_name)
+	mDefaultIconName(p.default_icon_name),
+	mAvatarNameCacheConnection()
 {
 	mPriority = LLViewerFetchedTexture::BOOST_ICON;
 	
@@ -203,6 +211,11 @@ LLAvatarIconCtrl::~LLAvatarIconCtrl()
 		LLAvatarPropertiesProcessor::getInstance()->removeObserver(mAvatarId, this);
 		// Name callbacks will be automatically disconnected since LLUICtrl is trackable
 	}
+
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 //virtual
@@ -245,9 +258,19 @@ void LLAvatarIconCtrl::setValue(const LLSD& value)
 		LLIconCtrl::setValue(value);
 	}
 
-	LLAvatarNameCache::get(mAvatarId,
-		boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, 
-			this, _1, _2));
+	fetchAvatarName();
+}
+
+void LLAvatarIconCtrl::fetchAvatarName()
+{
+	if (mAvatarId.notNull())
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarId, boost::bind(&LLAvatarIconCtrl::onAvatarNameCache, this, _1, _2));
+	}
 }
 
 bool LLAvatarIconCtrl::updateFromCache()
@@ -292,11 +315,13 @@ void LLAvatarIconCtrl::processProperties(void* data, EAvatarProcessorType type)
 
 void LLAvatarIconCtrl::onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (agent_id == mAvatarId)
 	{
 		// Most avatar icon controls are next to a UI element that shows
 		// a display name, so only show username.
-		mFullName = av_name.mUsername;
+		mFullName = av_name.getUserName();
 
 		if (mDrawTooltip)
 		{
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index 7f568fc5b89314f1e9798e44fc2794cff7942b89..4929efb7d0300de292415b692026a8fa360e9056 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -27,7 +27,9 @@
 #ifndef LL_LLAVATARICONCTRL_H
 #define LL_LLAVATARICONCTRL_H
 
-#include "lliconctrl.h"
+#include <boost/signals2.hpp>
+
+#include "../llui/lliconctrl.h"
 #include "llavatarpropertiesprocessor.h"
 #include "llviewermenu.h"
 
@@ -86,20 +88,24 @@ class LLAvatarIconCtrl
 	// LLAvatarPropertiesProcessor observer trigger
 	virtual void processProperties(void* data, EAvatarProcessorType type);
 
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-
 	const LLUUID&		getAvatarId() const	{ return mAvatarId; }
 	const std::string&	getFullName() const { return mFullName; }
 
 	void setDrawTooltip(bool value) { mDrawTooltip = value;}
 
 protected:
-	LLUUID				mAvatarId;
-	std::string			mFullName;
-	bool				mDrawTooltip;
-	std::string			mDefaultIconName;
+	LLUUID                      mAvatarId;
+	std::string                 mFullName;
+	bool                        mDrawTooltip;
+	std::string                 mDefaultIconName;
 
 	bool updateFromCache();
+
+private:
+	void fetchAvatarName();
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif  // LL_LLAVATARICONCTRL_H
diff --git a/indra/newview/llavatarlist.cpp b/indra/newview/llavatarlist.cpp
index 771419f60acc303143434fcfcf001e92bf9f7ce2..9f02f301a187390dad5879bda3fe83e64e750fca 100644
--- a/indra/newview/llavatarlist.cpp
+++ b/indra/newview/llavatarlist.cpp
@@ -46,6 +46,7 @@
 #include "lluuid.h"
 #include "llvoiceclient.h"
 #include "llviewercontrol.h"	// for gSavedSettings
+#include "lltooldraganddrop.h"
 
 static LLDefaultChildRegistry::Register<LLAvatarList> r("avatar_list");
 
@@ -278,7 +279,7 @@ void LLAvatarList::refresh()
 		LLAvatarName av_name;
 		have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
 
-		if (!have_filter || findInsensitive(av_name.mDisplayName, mNameFilter))
+		if (!have_filter || findInsensitive(av_name.getDisplayName(), mNameFilter))
 		{
 			if (nadded >= ADD_LIMIT)
 			{
@@ -296,8 +297,9 @@ void LLAvatarList::refresh()
 				}
 				else
 				{
+					std::string display_name = av_name.getDisplayName();
 					addNewItem(buddy_id, 
-						av_name.mDisplayName.empty() ? waiting_str : av_name.mDisplayName, 
+						display_name.empty() ? waiting_str : display_name, 
 						LLAvatarTracker::instance().isBuddyOnline(buddy_id));
 				}
 				
@@ -325,7 +327,7 @@ void LLAvatarList::refresh()
 			const LLUUID& buddy_id = it->asUUID();
 			LLAvatarName av_name;
 			have_names &= LLAvatarNameCache::get(buddy_id, &av_name);
-			if (!findInsensitive(av_name.mDisplayName, mNameFilter))
+			if (!findInsensitive(av_name.getDisplayName(), mNameFilter))
 			{
 				removeItemByUUID(buddy_id);
 				modified = true;
@@ -398,7 +400,7 @@ bool LLAvatarList::filterHasMatches()
 		// If name has not been loaded yet we consider it as a match.
 		// When the name will be loaded the filter will be applied again(in refresh()).
 
-		if (have_name && !findInsensitive(av_name.mDisplayName, mNameFilter))
+		if (have_name && !findInsensitive(av_name.getDisplayName(), mNameFilter))
 		{
 			continue;
 		}
@@ -461,6 +463,57 @@ BOOL LLAvatarList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return handled;
 }
 
+BOOL LLAvatarList::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	gFocusMgr.setMouseCapture(this);
+
+	S32 screen_x;
+	S32 screen_y;
+	localPointToScreen(x, y, &screen_x, &screen_y);
+	LLToolDragAndDrop::getInstance()->setDragStart(screen_x, screen_y);
+
+	return LLFlatListViewEx::handleMouseDown(x, y, mask);
+}
+
+BOOL LLAvatarList::handleMouseUp( S32 x, S32 y, MASK mask )
+{
+	if(hasMouseCapture())
+	{
+		gFocusMgr.setMouseCapture(NULL);
+	}
+
+	return LLFlatListViewEx::handleMouseUp(x, y, mask);
+}
+
+BOOL LLAvatarList::handleHover(S32 x, S32 y, MASK mask)
+{
+	bool handled = hasMouseCapture();
+	if(handled)
+	{
+		S32 screen_x;
+		S32 screen_y;
+		localPointToScreen(x, y, &screen_x, &screen_y);
+
+		if(LLToolDragAndDrop::getInstance()->isOverThreshold(screen_x, screen_y))
+		{
+			// First, create the global drag and drop object
+			std::vector<EDragAndDropType> types;
+			uuid_vec_t cargo_ids;
+			getSelectedUUIDs(cargo_ids);
+			types.resize(cargo_ids.size(), DAD_PERSON);
+			LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_PEOPLE;
+			LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, src);
+		}
+	}
+
+	if(!handled)
+	{
+		handled = LLFlatListViewEx::handleHover(x, y, mask);
+	}
+
+	return handled;
+}
+
 bool LLAvatarList::isAvalineItemSelected()
 {
 	std::vector<LLPanel*> selected_items;
diff --git a/indra/newview/llavatarlist.h b/indra/newview/llavatarlist.h
index 4814a88a79770c2640239b1867659fd6519e650d..3542577ae3c3f7cfb89272fdf1968624c0bd576f 100644
--- a/indra/newview/llavatarlist.h
+++ b/indra/newview/llavatarlist.h
@@ -84,6 +84,9 @@ class LLAvatarList : public LLFlatListViewEx
 	bool getIconsVisible() const { return mShowIcons; }
 	const std::string getIconParamName() const{return mIconParamName;}
 	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 
 	// Return true if filter has at least one match.
 	bool filterHasMatches();
diff --git a/indra/newview/llavatarlistitem.cpp b/indra/newview/llavatarlistitem.cpp
index 30eecfe3231ddb2a061696a30b94e4cafbc65a92..3e6c817dd6229f718c05af53b689c9d8e045fc36 100644
--- a/indra/newview/llavatarlistitem.cpp
+++ b/indra/newview/llavatarlistitem.cpp
@@ -27,6 +27,8 @@
 
 #include "llviewerprecompiledheaders.h"
 
+#include <boost/signals2.hpp>
+
 #include "llavataractions.h"
 #include "llavatarlistitem.h"
 
@@ -38,6 +40,7 @@
 #include "llavatarnamecache.h"
 #include "llavatariconctrl.h"
 #include "lloutputmonitorctrl.h"
+#include "lltooldraganddrop.h"
 
 bool LLAvatarListItem::sStaticInitialized = false;
 S32 LLAvatarListItem::sLeftPadding = 0;
@@ -58,7 +61,8 @@ LLAvatarListItem::Params::Params()
 
 
 LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
-:	LLPanel(),
+	: LLPanel(),
+	LLFriendObserver(),
 	mAvatarIcon(NULL),
 	mAvatarName(NULL),
 	mLastInteractionTime(NULL),
@@ -73,7 +77,8 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
 	mShowInfoBtn(true),
 	mShowProfileBtn(true),
 	mShowPermissions(false),
-	mHovered(false)
+	mHovered(false),
+	mAvatarNameCacheConnection()
 {
 	if (not_from_ui_factory)
 	{
@@ -86,7 +91,14 @@ LLAvatarListItem::LLAvatarListItem(bool not_from_ui_factory/* = true*/)
 LLAvatarListItem::~LLAvatarListItem()
 {
 	if (mAvatarId.notNull())
+	{
 		LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarId, this);
+	}
+
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 BOOL  LLAvatarListItem::postBuild()
@@ -129,6 +141,29 @@ BOOL  LLAvatarListItem::postBuild()
 	return TRUE;
 }
 
+void LLAvatarListItem::handleVisibilityChange ( BOOL new_visibility )
+{
+    //Adjust positions of icons (info button etc) when 
+    //speaking indicator visibility was changed/toggled while panel was closed (not visible)
+    if(new_visibility && mSpeakingIndicator->getIndicatorToggled())
+    {
+        updateChildren();
+        mSpeakingIndicator->setIndicatorToggled(false);
+    }
+}
+
+void LLAvatarListItem::fetchAvatarName()
+{
+	if (mAvatarId.notNull())
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(getAvatarId(), boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+	}
+}
+
 S32 LLAvatarListItem::notifyParent(const LLSD& info)
 {
 	if (info.has("visibility_changed"))
@@ -259,8 +294,7 @@ void LLAvatarListItem::setAvatarId(const LLUUID& id, const LLUUID& session_id, b
 		mAvatarIcon->setValue(id);
 
 		// Set avatar name.
-		LLAvatarNameCache::get(id,
-			boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+		fetchAvatarName();
 	}
 }
 
@@ -358,8 +392,7 @@ std::string LLAvatarListItem::getAvatarToolTip() const
 
 void LLAvatarListItem::updateAvatarName()
 {
-	LLAvatarNameCache::get(getAvatarId(),
-			boost::bind(&LLAvatarListItem::onAvatarNameCache, this, _2));
+	fetchAvatarName();
 }
 
 //== PRIVATE SECITON ==========================================================
@@ -371,8 +404,10 @@ void LLAvatarListItem::setNameInternal(const std::string& name, const std::strin
 
 void LLAvatarListItem::onAvatarNameCache(const LLAvatarName& av_name)
 {
-	setAvatarName(av_name.mDisplayName);
-	setAvatarToolTip(av_name.mUsername);
+	mAvatarNameCacheConnection.disconnect();
+
+	setAvatarName(av_name.getDisplayName());
+	setAvatarToolTip(av_name.getUserName());
 
 	//requesting the list to resort
 	notifyParent(LLSD().with("sort", LLSD()));
diff --git a/indra/newview/llavatarlistitem.h b/indra/newview/llavatarlistitem.h
index c95ac3969685f5ce3dcfa43379e548204e54e8e4..7ef35a746ec9719018680cd8485663d0cd980b42 100644
--- a/indra/newview/llavatarlistitem.h
+++ b/indra/newview/llavatarlistitem.h
@@ -27,6 +27,8 @@
 #ifndef LL_LLAVATARLISTITEM_H
 #define LL_LLAVATARLISTITEM_H
 
+#include <boost/signals2.hpp>
+
 #include "llpanel.h"
 #include "lloutputmonitorctrl.h"
 #include "llbutton.h"
@@ -82,6 +84,7 @@ class LLAvatarListItem : public LLPanel, public LLFriendObserver
 	/**
 	 * Processes notification from speaker indicator to update children when indicator's visibility is changed.
 	 */
+    virtual void handleVisibilityChange ( BOOL new_visibility );
 	virtual S32	notifyParent(const LLSD& info);
 	virtual void onMouseLeave(S32 x, S32 y, MASK mask);
 	virtual void onMouseEnter(S32 x, S32 y, MASK mask);
@@ -214,6 +217,9 @@ class LLAvatarListItem : public LLPanel, public LLFriendObserver
 
 	/// true when the mouse pointer is hovering over this item
 	bool mHovered;
+	
+	void fetchAvatarName();
+	boost::signals2::connection mAvatarNameCacheConnection;
 
 	static bool	sStaticInitialized; // this variable is introduced to improve code readability
 	static S32  sLeftPadding; // padding to first left visible child (icon or name)
diff --git a/indra/newview/llblockedlistitem.cpp b/indra/newview/llblockedlistitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d9afd2b62998e7fe4fc703a520df30dfebe7ffa9
--- /dev/null
+++ b/indra/newview/llblockedlistitem.cpp
@@ -0,0 +1,114 @@
+/**
+ * @file llviewerobjectlistitem.cpp
+ * @brief viewer object list item implementation
+ *
+ * Class LLPanelInventoryListItemBase displays inventory item as an element
+ * of LLInventoryItemsList.
+ *
+ * $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 "llblockedlistitem.h"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavatariconctrl.h"
+#include "llgroupiconctrl.h"
+#include "llinventoryicon.h"
+#include "llviewerobject.h"
+
+LLBlockedListItem::LLBlockedListItem(const LLMute* item)
+:	LLPanel(),
+	mItemID(item->mID),
+	mItemName(item->mName),
+	mMuteType(item->mType)
+{
+	buildFromFile("panel_blocked_list_item.xml");
+}
+
+BOOL LLBlockedListItem::postBuild()
+{
+	mTitleCtrl = getChild<LLTextBox>("item_name");
+	mTitleCtrl->setValue(mItemName);
+
+	switch (mMuteType)
+	{
+	case LLMute::AGENT:
+	case LLMute::EXTERNAL:
+		{
+			LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+			avatar_icon->setVisible(TRUE);
+			avatar_icon->setValue(mItemID);
+		}
+		break;
+	case LLMute::GROUP:
+		{
+			LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+			group_icon->setVisible(TRUE);
+			group_icon->setValue(mItemID);
+		}
+		break;
+	case LLMute::OBJECT:
+	case LLMute::BY_NAME:
+		getChild<LLUICtrl>("object_icon")->setVisible(TRUE);
+		break;
+
+	default:
+		break;
+	}
+
+	return TRUE;
+}
+
+void LLBlockedListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLBlockedListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(false);
+	LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLBlockedListItem::setValue(const LLSD& value)
+{
+	if (!value.isMap() || !value.has("selected"))
+	{
+		return;
+	}
+
+	getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLBlockedListItem::highlightName(const std::string& highlited_text)
+{
+	LLStyle::Params params;
+	LLTextUtil::textboxSetHighlightedVal(mTitleCtrl, params, mItemName, highlited_text);
+}
diff --git a/indra/newview/llblockedlistitem.h b/indra/newview/llblockedlistitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..05409e8a3bc5c503329fafdb1b221c9679b6e2b6
--- /dev/null
+++ b/indra/newview/llblockedlistitem.h
@@ -0,0 +1,73 @@
+/**
+ * @file llviewerobjectlistitem.h
+ * @brief viewer object list item header file
+ *
+ * $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 LLVIEWEROBJECTLISTITEM_H_
+#define LLVIEWEROBJECTLISTITEM_H_
+
+#include "llmutelist.h"
+#include "llpanel.h"
+#include "llstyle.h"
+#include "lltextbox.h"
+#include "lliconctrl.h"
+
+/**
+ * This class represents items of LLBlockList, which represents
+ * contents of LLMuteList. LLMuteList "consists" of LLMute items.
+ * Each LLMute represents either blocked avatar or object and
+ * stores info about mute type (avatar or object)
+ *
+ * Each item consists if object/avatar icon and object/avatar name
+ *
+ * To create a blocked list item just need to pass LLMute pointer
+ * and appropriate block list item will be created depending on
+ * LLMute type (LLMute::EType) and other LLMute's info
+ */
+class LLBlockedListItem : public LLPanel
+{
+public:
+
+	LLBlockedListItem(const LLMute* item);
+	virtual BOOL postBuild();
+
+	void onMouseEnter(S32 x, S32 y, MASK mask);
+	void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	virtual void setValue(const LLSD& value);
+
+	void 					highlightName(const std::string& highlited_text);
+	const std::string&		getName() const { return mItemName; }
+	const LLMute::EType&	getType() const { return mMuteType; }
+	const LLUUID&			getUUID() const { return mItemID;	}
+
+private:
+
+	LLTextBox*		mTitleCtrl;
+	const LLUUID	mItemID;
+	std::string		mItemName;
+	LLMute::EType	mMuteType;
+
+};
+
+#endif /* LLVIEWEROBJECTLISTITEM_H_ */
diff --git a/indra/newview/llblocklist.cpp b/indra/newview/llblocklist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..066cb71677a810488557f1594ff32806256c66cd
--- /dev/null
+++ b/indra/newview/llblocklist.cpp
@@ -0,0 +1,284 @@
+/**
+ * @file llblocklist.cpp
+ * @brief List of the blocked avatars and objects.
+ *
+ * $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 "llblocklist.h"
+
+#include "llavataractions.h"
+#include "llblockedlistitem.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llviewermenu.h"
+
+static LLDefaultChildRegistry::Register<LLBlockList> r("block_list");
+
+static const LLBlockListNameComparator 		NAME_COMPARATOR;
+static const LLBlockListNameTypeComparator	NAME_TYPE_COMPARATOR;
+
+LLBlockList::LLBlockList(const Params& p)
+:	LLFlatListViewEx(p),
+ 	mSelectedItem(NULL),
+ 	mDirty(true)
+{
+
+	LLMuteList::getInstance()->addObserver(this);
+
+	// Set up context menu.
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+	registrar.add		("Block.Action",	boost::bind(&LLBlockList::onCustomAction,	this, _2));
+	enable_registrar.add("Block.Enable",	boost::bind(&LLBlockList::isActionEnabled,	this, _2));
+
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+									"menu_people_blocked_gear.xml",
+									gMenuHolder,
+									LLViewerMenuHolderGL::child_registry_t::instance());
+	if(context_menu)
+	{
+		mContextMenu = context_menu->getHandle();
+	}
+}
+
+LLBlockList::~LLBlockList()
+{
+	if (mContextMenu.get())
+	{
+		mContextMenu.get()->die();
+	}
+
+	LLMuteList::getInstance()->removeObserver(this);
+}
+
+BOOL LLBlockList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+	LLToggleableMenu* context_menu = mContextMenu.get();
+	if (context_menu && size())
+	{
+		context_menu->buildDrawLabels();
+		context_menu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, context_menu, x, y);
+	}
+
+	return handled;
+}
+
+void LLBlockList::setNameFilter(const std::string& filter)
+{
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
+	{
+		mNameFilter = filter_upper;
+		setDirty();
+	}
+}
+
+void LLBlockList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
+}
+
+void LLBlockList::sortByType()
+{
+	setComparator(&NAME_TYPE_COMPARATOR);
+	sort();
+}
+
+void LLBlockList::draw()
+{
+	if (mDirty)
+	{
+		refresh();
+	}
+
+	LLFlatListView::draw();
+}
+
+void LLBlockList::addNewItem(const LLMute* mute)
+{
+	LLBlockedListItem* item = new LLBlockedListItem(mute);
+	if (!mNameFilter.empty())
+	{
+		item->highlightName(mNameFilter);
+	}
+	addItem(item, item->getUUID(), ADD_BOTTOM);
+}
+
+void LLBlockList::refresh()
+{
+	bool have_filter = !mNameFilter.empty();
+
+	// save selection to restore it after list rebuilt
+	LLUUID selected = getSelectedUUID();
+
+	// calling refresh may be initiated by removing currently selected item
+	// so select next item and save the selection to restore it after list rebuilt
+	if (!selectNextItemPair(false, true))
+	{
+		selectNextItemPair(true, true);
+	}
+	LLUUID next_selected = getSelectedUUID();
+
+	clear();
+
+	std::vector<LLMute> mutes = LLMuteList::instance().getMutes();
+	std::vector<LLMute>::const_iterator mute_it = mutes.begin();
+
+	for (; mute_it != mutes.end(); ++mute_it)
+	{
+		if (have_filter && !findInsensitive(mute_it->mName, mNameFilter))
+			continue;
+
+		addNewItem(&*mute_it);
+	}
+
+	if (getItemPair(selected))
+	{
+		// restore previously selected item
+		selectItemPair(getItemPair(selected), true);
+	}
+	else if (getItemPair(next_selected))
+	{
+		// previously selected item was removed, so select next item
+		selectItemPair(getItemPair(next_selected), true);
+	}
+
+	// Sort the list.
+	sort();
+
+	setDirty(false);
+}
+
+bool LLBlockList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+    LLStringUtil::toUpper(haystack);
+    return haystack.find(needle_upper) != std::string::npos;
+}
+
+LLBlockedListItem* LLBlockList::getBlockedItem() const
+{
+	LLPanel* panel = LLFlatListView::getSelectedItem();
+	LLBlockedListItem* item = dynamic_cast<LLBlockedListItem*>(panel);
+	return item;
+}
+
+bool LLBlockList::isActionEnabled(const LLSD& userdata)
+{
+	bool action_enabled = true;
+
+	const std::string command_name = userdata.asString();
+
+	if ("profile_item" == command_name)
+	{
+		LLBlockedListItem* item = getBlockedItem();
+		action_enabled = item && (LLMute::AGENT == item->getType());
+	}
+
+	if ("unblock_item" == command_name)
+	{
+		action_enabled = getSelectedItem() != NULL;
+	}
+
+	return action_enabled;
+}
+
+void LLBlockList::onCustomAction(const LLSD& userdata)
+{
+	if (!isActionEnabled(userdata))
+	{
+		return;
+	}
+
+	LLBlockedListItem* item = getBlockedItem();
+	const std::string command_name = userdata.asString();
+
+	if ("unblock_item" == command_name)
+	{
+		LLMute mute(item->getUUID(), item->getName());
+		LLMuteList::getInstance()->remove(mute);
+	}
+	else if ("profile_item" == command_name)
+	{
+		switch(item->getType())
+		{
+
+		case LLMute::AGENT:
+			LLAvatarActions::showProfile(item->getUUID());
+			break;
+
+		default:
+			break;
+		}
+	}
+}
+
+bool LLBlockListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+	const LLBlockedListItem* blocked_item1 = dynamic_cast<const LLBlockedListItem*>(item1);
+	const LLBlockedListItem* blocked_item2 = dynamic_cast<const LLBlockedListItem*>(item2);
+
+	if (!blocked_item1 || !blocked_item2)
+	{
+		llerror("blocked_item1 and blocked_item2 cannot be null", 0);
+		return true;
+	}
+
+	return doCompare(blocked_item1, blocked_item2);
+}
+
+bool LLBlockListNameComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+	std::string name1 = blocked_item1->getName();
+	std::string name2 = blocked_item2->getName();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	return name1 < name2;
+}
+
+bool LLBlockListNameTypeComparator::doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const
+{
+	LLMute::EType type1 = blocked_item1->getType();
+	LLMute::EType type2 = blocked_item2->getType();
+
+	// if mute type is LLMute::BY_NAME or LLMute::OBJECT it means that this mute is an object
+	bool both_mutes_are_objects = (LLMute::OBJECT == type1 || LLMute::BY_NAME == type1) && (LLMute::OBJECT == type2 || LLMute::BY_NAME == type2);
+
+	// mute types may be different, but since both LLMute::BY_NAME and LLMute::OBJECT types represent objects
+	// it's needed to perform additional checking of both_mutes_are_objects variable
+	if (type1 != type2 && !both_mutes_are_objects)
+	{
+		// objects in block list go first, so return true if mute type is not an avatar
+		return LLMute::AGENT != type1;
+	}
+
+	return NAME_COMPARATOR.compare(blocked_item1, blocked_item2);
+}
diff --git a/indra/newview/llblocklist.h b/indra/newview/llblocklist.h
new file mode 100644
index 0000000000000000000000000000000000000000..1a215710f463ade3bf5d1f6edee32e808e4761dd
--- /dev/null
+++ b/indra/newview/llblocklist.h
@@ -0,0 +1,138 @@
+/**
+ * @file llblocklist.h
+ * @brief List of the blocked avatars and objects.
+ *
+ * $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 LLBLOCKLIST_H_
+#define LLBLOCKLIST_H_
+
+#include "llflatlistview.h"
+#include "lllistcontextmenu.h"
+#include "llmutelist.h"
+#include "lltoggleablemenu.h"
+
+class LLBlockedListItem;
+class LLMute;
+
+/**
+ * List of blocked avatars and objects.
+ * This list represents contents of the LLMuteList.
+ * Each change in LLMuteList leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+class LLBlockList: public LLFlatListViewEx, public LLMuteListObserver
+{
+	LOG_CLASS(LLBlockList);
+public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
+
+	LLBlockList(const Params& p);
+	virtual ~LLBlockList();
+
+	virtual BOOL 		handleRightMouseDown(S32 x, S32 y, MASK mask);
+	LLToggleableMenu*	getContextMenu() const { return mContextMenu.get(); }
+	LLBlockedListItem*	getBlockedItem() const;
+
+	virtual void onChange() { refresh(); }
+	virtual void draw();
+
+	void setNameFilter(const std::string& filter);
+	void sortByName();
+	void sortByType();
+	void refresh();
+
+private:
+
+	void addNewItem(const LLMute* mute);
+	void setDirty(bool dirty = true) { mDirty = dirty; }
+	bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+	bool isActionEnabled(const LLSD& userdata);
+	void onCustomAction (const LLSD& userdata);
+
+
+	LLHandle<LLToggleableMenu>	mContextMenu;
+
+	LLBlockedListItem*			mSelectedItem;
+	std::string 				mNameFilter;
+	bool 						mDirty;
+
+};
+
+
+/*
+ * Abstract comparator for blocked items
+ */
+class LLBlockListItemComparator : public LLFlatListView::ItemComparator
+{
+	LOG_CLASS(LLBlockListItemComparator);
+
+public:
+	LLBlockListItemComparator() {};
+	virtual ~LLBlockListItemComparator() {};
+
+	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const = 0;
+};
+
+
+/*
+ * Compares items by name
+ */
+class LLBlockListNameComparator : public LLBlockListItemComparator
+{
+	LOG_CLASS(LLBlockListNameComparator);
+
+public:
+	LLBlockListNameComparator() {};
+	virtual ~LLBlockListNameComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+/*
+ * Compares items by type and then by name within type
+ * Objects come first then avatars
+ */
+class LLBlockListNameTypeComparator : public LLBlockListItemComparator
+{
+	LOG_CLASS(LLBlockListNameTypeComparator);
+
+public:
+	LLBlockListNameTypeComparator() {};
+	virtual ~LLBlockListNameTypeComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLBlockedListItem* blocked_item1, const LLBlockedListItem* blocked_item2) const;
+};
+
+#endif /* LLBLOCKLIST_H_ */
diff --git a/indra/newview/llbrowsernotification.cpp b/indra/newview/llbrowsernotification.cpp
index 6e77d1e3363dd6ecede27859efe9f45b75eb2a44..19747757dbcc13b4af68d5f039a5470d61764784 100644
--- a/indra/newview/llbrowsernotification.cpp
+++ b/indra/newview/llbrowsernotification.cpp
@@ -35,11 +35,13 @@
 
 using namespace LLNotificationsUI;
 
-bool LLBrowserNotification::processNotification(const LLSD& notify)
+LLBrowserNotification::LLBrowserNotification()
+	: LLSystemNotificationHandler("Browser", "browser")
 {
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	if (!notification) return false;
+}
 
+bool LLBrowserNotification::processNotification(const LLNotificationPtr& notification)
+{
 	LLUUID media_id = notification->getPayload()["media_id"].asUUID();
 	LLMediaCtrl* media_instance = LLMediaCtrl::getInstance(media_id);
 	if (media_instance)
diff --git a/indra/newview/llbuycurrencyhtml.cpp b/indra/newview/llbuycurrencyhtml.cpp
index e5a9be020311da047208e1646899560ae9b92915..459123a5d8b162b9c65f15fac4bd21d69417ac76 100644
--- a/indra/newview/llbuycurrencyhtml.cpp
+++ b/indra/newview/llbuycurrencyhtml.cpp
@@ -61,6 +61,10 @@ class LLBuyCurrencyHTMLHandler :
 		if ( params.size() >= 3 )
 		{
 			result_code = params[ 2 ].asInteger();
+			if ( result_code != 0 )
+			{
+				LL_WARNS("LLBuyCurrency") << "Received nonzero result code: " << result_code << LL_ENDL ;
+			}
 		};
 
 		// open the legacy XUI based currency floater
diff --git a/indra/newview/llcallbacklist.cpp b/indra/newview/llcallbacklist.cpp
index 357a6582d162b582eef2561ca7fdc471c45d0bc0..79ec43dfe920278d25a72c4151921a32a904974c 100644
--- a/indra/newview/llcallbacklist.cpp
+++ b/indra/newview/llcallbacklist.cpp
@@ -27,6 +27,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llcallbacklist.h"
+#include "lleventtimer.h"
 
 // Library includes
 #include "llerror.h"
@@ -180,6 +181,54 @@ void doOnIdleRepeating(bool_func_t callable)
 	gIdleCallbacks.addFunction(&OnIdleCallbackRepeating::onIdle,cb_functor);
 }
 
+class NullaryFuncEventTimer: public LLEventTimer
+{
+public:
+	NullaryFuncEventTimer(nullary_func_t callable, F32 seconds):
+		LLEventTimer(seconds),
+		mCallable(callable)
+	{
+	}
+
+private:
+	BOOL tick()
+	{
+		mCallable();
+		return TRUE;
+	}
+
+	nullary_func_t mCallable;
+};
+
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds)
+{
+	new NullaryFuncEventTimer(callable, seconds);
+}
+
+class BoolFuncEventTimer: public LLEventTimer
+{
+public:
+	BoolFuncEventTimer(bool_func_t callable, F32 seconds):
+		LLEventTimer(seconds),
+		mCallable(callable)
+	{
+	}
+private:
+	BOOL tick()
+	{
+		return mCallable();
+	}
+
+	bool_func_t mCallable;
+};
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds)
+{
+	new BoolFuncEventTimer(callable, seconds);
+}
+
 #ifdef _DEBUG
 
 void test1(void *data)
diff --git a/indra/newview/llcallbacklist.h b/indra/newview/llcallbacklist.h
index 97f3bfd9ee29b6f061c76d0d4a21cb5d800da616..0516c9cdb44e663d47d123b555a7550ce0c774c3 100644
--- a/indra/newview/llcallbacklist.h
+++ b/indra/newview/llcallbacklist.h
@@ -61,6 +61,12 @@ void doOnIdleOneTime(nullary_func_t callable);
 // Repeatedly call a callable in idle loop until it returns true.
 void doOnIdleRepeating(bool_func_t callable);
 
+// Call a given callable once after specified interval.
+void doAfterInterval(nullary_func_t callable, F32 seconds);
+
+// Call a given callable every specified number of seconds, until it returns true.
+void doPeriodically(bool_func_t callable, F32 seconds);
+
 extern LLCallbackList gIdleCallbacks;
 
 #endif
diff --git a/indra/newview/llcallfloater.cpp b/indra/newview/llcallfloater.cpp
deleted file mode 100644
index f2375bfa4f7630c34faedf88a62bb1eb55014fd3..0000000000000000000000000000000000000000
--- a/indra/newview/llcallfloater.cpp
+++ /dev/null
@@ -1,821 +0,0 @@
-/** 
- * @file llcallfloater.cpp
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llcallfloater.h"
-
-#include "llnotificationsutil.h"
-#include "lltrans.h"
-
-#include "llagent.h"
-#include "llagentdata.h" // for gAgentID
-#include "llavatarnamecache.h"
-#include "llavatariconctrl.h"
-#include "llavatarlist.h"
-#include "lldraghandle.h"
-#include "llimfloater.h"
-#include "llimview.h"
-#include "llfloaterreg.h"
-#include "llparticipantlist.h"
-#include "llspeakers.h"
-#include "lltextutil.h"
-#include "lltransientfloatermgr.h"
-#include "llviewercontrol.h"
-#include "llviewerdisplayname.h"
-#include "llviewerwindow.h"
-#include "llvoicechannel.h"
-#include "llviewerparcelmgr.h"
-#include "llfirstuse.h"
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids);
-void reshape_floater(LLCallFloater* floater, S32 delta_height);
-
-class LLNonAvatarCaller : public LLAvatarListItem
-{
-public:
-	LLNonAvatarCaller() : LLAvatarListItem(false)
-	{
-
-	}
-	BOOL postBuild()
-	{
-		BOOL rv = LLAvatarListItem::postBuild();
-
-		if (rv)
-		{
-			setOnline(true);
-			showLastInteractionTime(false);
-			setShowProfileBtn(false);
-			setShowInfoBtn(false);
-			mAvatarIcon->setValue("Avaline_Icon");
-			mAvatarIcon->setToolTip(std::string(""));
-		}
-		return rv;
-	}
-
-	void setName(const std::string& name)
-	{
-		const std::string& formatted_phone = LLTextUtil::formatPhoneNumber(name);
-		LLAvatarListItem::setAvatarName(formatted_phone);
-		LLAvatarListItem::setAvatarToolTip(formatted_phone);
-	}
-
-	void setSpeakerId(const LLUUID& id) { mSpeakingIndicator->setSpeakerId(id); }
-};
-
-
-static void* create_non_avatar_caller(void*)
-{
-	return new LLNonAvatarCaller;
-}
-
-LLVoiceChannel* LLCallFloater::sCurrentVoiceChannel = NULL;
-
-LLCallFloater::LLCallFloater(const LLSD& key)
-: LLTransientDockableFloater(NULL, false, key)
-, mSpeakerManager(NULL)
-, mParticipants(NULL)
-, mAvatarList(NULL)
-, mNonAvatarCaller(NULL)
-, mVoiceType(VC_LOCAL_CHAT)
-, mAgentPanel(NULL)
-, mSpeakingIndicator(NULL)
-, mIsModeratorMutedVoice(false)
-, mInitParticipantsVoiceState(false)
-{
-	static LLUICachedControl<S32> voice_left_remove_delay ("VoiceParticipantLeftRemoveDelay", 10);
-	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLCallFloater::removeVoiceLeftParticipant, this, _1), voice_left_remove_delay);
-
-	mFactoryMap["non_avatar_caller"] = LLCallbackMap(create_non_avatar_caller, NULL);
-	LLVoiceClient::instance().addObserver(this);
-	LLTransientFloaterMgr::getInstance()->addControlView(this);
-
-	// update the agent's name if display name setting change
-	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
-	LLViewerDisplayName::addNameChangedCallback(boost::bind(&LLCallFloater::updateAgentModeratorState, this));
-
-}
-
-LLCallFloater::~LLCallFloater()
-{
-	resetVoiceRemoveTimers();
-	delete mSpeakerDelayRemover;
-
-	delete mParticipants;
-	mParticipants = NULL;
-
-	mAvatarListRefreshConnection.disconnect();
-	mVoiceChannelStateChangeConnection.disconnect();
-
-	if(LLVoiceClient::instanceExists())
-	{
-		LLVoiceClient::getInstance()->removeObserver(this);
-	}
-	LLTransientFloaterMgr::getInstance()->removeControlView(this);
-}
-
-// virtual
-BOOL LLCallFloater::postBuild()
-{
-	mAvatarList = getChild<LLAvatarList>("speakers_list");
-	mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLCallFloater::onAvatarListRefreshed, this));
-
-	childSetAction("leave_call_btn", boost::bind(&LLCallFloater::leaveCall, this));
-
-	mNonAvatarCaller = findChild<LLNonAvatarCaller>("non_avatar_caller");
-	mNonAvatarCaller->setVisible(FALSE);
-
-	initAgentData();
-
-	connectToChannel(LLVoiceChannel::getCurrentVoiceChannel());
-
-	updateTransparency(TT_ACTIVE); // force using active floater transparency (STORM-730)
-	
-	updateSession();
-	return TRUE;
-}
-
-// virtual
-void LLCallFloater::onOpen(const LLSD& /*key*/)
-{
-	LLFirstUse::speak(false);
-}
-
-// virtual
-void LLCallFloater::draw()
-{
-	// we have to refresh participants to display ones not in voice as disabled.
-	// It should be done only when she joins or leaves voice chat.
-	// But seems that LLVoiceClientParticipantObserver is not enough to satisfy this requirement.
-	// *TODO: mantipov: remove from draw()
-
-	// NOTE: it looks like calling onChange() here is not necessary,
-	// but sometime it is not called properly from the observable object.
-	// Seems this is a problem somewhere in Voice Client (LLVoiceClient::participantAddedEvent)
-//	onChange();
-
-	bool is_moderator_muted = LLVoiceClient::getInstance()->getIsModeratorMuted(gAgentID);
-
-	if (mIsModeratorMutedVoice != is_moderator_muted)
-	{
-		setModeratorMutedVoice(is_moderator_muted);
-	}
-
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (mParticipants)
-		mParticipants->update();
-
-	LLFloater::draw();
-}
-
-// virtual
-void LLCallFloater::setFocus( BOOL b )
-{
-	LLFloater::setFocus(b);
-
-	// Force using active floater transparency (STORM-730).
-	// We have to override setFocus() for LLCallFloater because selecting an item
-	// of the voice morphing combobox causes the floater to lose focus and thus become transparent.
-	updateTransparency(TT_ACTIVE);
-}
-
-// virtual
-void LLCallFloater::onParticipantsChanged()
-{
-	if (NULL == mParticipants) return;
-	updateParticipantsVoiceState();
-
-	// Add newly joined participants.
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-	for (uuid_vec_t::const_iterator it = speakers_uuids.begin(); it != speakers_uuids.end(); it++)
-	{
-		mParticipants->addAvatarIDExceptAgent(*it);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-/// PRIVATE SECTION
-//////////////////////////////////////////////////////////////////////////
-
-void LLCallFloater::leaveCall()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice_channel)
-	{
-		gIMMgr->endCall(voice_channel->getSessionID());
-	}
-}
-
-void LLCallFloater::updateSession()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice_channel)
-	{
-		LL_DEBUGS("Voice") << "Current voice channel: " << voice_channel->getSessionID() << LL_ENDL;
-
-		if (mSpeakerManager && voice_channel->getSessionID() == mSpeakerManager->getSessionID())
-		{
-			LL_DEBUGS("Voice") << "Speaker manager is already set for session: " << voice_channel->getSessionID() << LL_ENDL;
-			return;
-		}
-		else
-		{
-			mSpeakerManager = NULL;
-		}
-	}
-
-	const LLUUID& session_id = voice_channel ? voice_channel->getSessionID() : LLUUID::null;
-
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (im_session)
-	{
-		mSpeakerManager = LLIMModel::getInstance()->getSpeakerManager(session_id);
-		switch (im_session->mType)
-		{
-		case IM_NOTHING_SPECIAL:
-		case IM_SESSION_P2P_INVITE:
-			mVoiceType = VC_PEER_TO_PEER;
-
-			if (!im_session->mOtherParticipantIsAvatar)
-			{
-				mVoiceType = VC_PEER_TO_PEER_AVALINE;
-			}
-			break;
-		case IM_SESSION_CONFERENCE_START:
-		case IM_SESSION_GROUP_START:
-		case IM_SESSION_INVITE:
-			if (gAgent.isInGroup(session_id))
-			{
-				mVoiceType = VC_GROUP_CHAT;
-			}
-			else
-			{
-				mVoiceType = VC_AD_HOC_CHAT;				
-			}
-			break;
-		default:
-			llwarning("Failed to determine voice call IM type", 0);
-			mVoiceType = VC_GROUP_CHAT;
-			break;
-		}
-	}
-
-	if (NULL == mSpeakerManager)
-	{
-		// By default show nearby chat participants
-		mSpeakerManager = LLLocalSpeakerMgr::getInstance();
-		LL_DEBUGS("Voice") << "Set DEFAULT speaker manager" << LL_ENDL;
-		mVoiceType = VC_LOCAL_CHAT;
-	}
-
-	updateTitle();
-
-	// Hide "Leave Call" button for nearby chat
-	bool is_local_chat = mVoiceType == VC_LOCAL_CHAT;
-	getChildView("leave_call_btn_panel")->setVisible( !is_local_chat);
-
-	refreshParticipantList();
-	updateAgentModeratorState();
-
-	// Show floater for voice calls & only in CONNECTED to voice channel state
-	if (!is_local_chat &&
-	    voice_channel &&
-	    LLVoiceChannel::STATE_CONNECTED == voice_channel->getState())
-	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
-		bool show_me = !(im_floater && im_floater->getVisible());
-		if (show_me) 
-		{
-			setVisible(true);
-		}
-	}
-}
-
-void LLCallFloater::refreshParticipantList()
-{
-	bool non_avatar_caller = VC_PEER_TO_PEER_AVALINE == mVoiceType;
-
-	if (non_avatar_caller)
-	{
-		LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSpeakerManager->getSessionID());
-		mNonAvatarCaller->setSpeakerId(session->mOtherParticipantID);
-		mNonAvatarCaller->setName(session->mName);
-	}
-
-	mNonAvatarCaller->setVisible(non_avatar_caller);
-	mAvatarList->setVisible(!non_avatar_caller);
-
-	if (!non_avatar_caller)
-	{
-		llassert(mParticipants == NULL); // check for possible memory leak
-		mParticipants = new LLParticipantList(mSpeakerManager, mAvatarList, true, mVoiceType != VC_GROUP_CHAT && mVoiceType != VC_AD_HOC_CHAT, false);
-		mParticipants->setValidateSpeakerCallback(boost::bind(&LLCallFloater::validateSpeaker, this, _1));
-		const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-		mParticipants->setSortOrder(LLParticipantList::EParticipantSortOrder(speaker_sort_order));
-		
-		if (LLLocalSpeakerMgr::getInstance() == mSpeakerManager)
-		{
-			mAvatarList->setNoItemsCommentText(getString("no_one_near"));
-		}
-
-		// we have to made delayed initialization of voice state of participant list.
-		// it will be performed after first LLAvatarList refreshing in the onAvatarListRefreshed().
-		mInitParticipantsVoiceState = true;
-	}
-}
-
-void LLCallFloater::onAvatarListRefreshed()
-{
-	if (mInitParticipantsVoiceState)
-	{
-		initParticipantsVoiceState();
-		mInitParticipantsVoiceState = false;
-	}
-	else
-	{
-		updateParticipantsVoiceState();
-	}
-}
-
-// static
-void LLCallFloater::sOnCurrentChannelChanged(const LLUUID& /*session_id*/)
-{
-	LLVoiceChannel* channel = LLVoiceChannel::getCurrentVoiceChannel();
-
-	// *NOTE: if signal was sent for voice channel with LLVoiceChannel::STATE_NO_CHANNEL_INFO
-	// it sill be sent for the same channel again (when state is changed).
-	// So, lets ignore this call.
-	if (channel == sCurrentVoiceChannel) return;
-
-	LLCallFloater* call_floater = LLFloaterReg::getTypedInstance<LLCallFloater>("voice_controls");
-
-	call_floater->connectToChannel(channel);
-}
-
-void LLCallFloater::onAvatarNameCache(const LLUUID& agent_id,
-									  const LLAvatarName& av_name)
-{
-	LLStringUtil::format_map_t args;
-	args["[NAME]"] = av_name.getCompleteName();
-	std::string title = getString("title_peer_2_peer", args);
-	setTitle(title);
-}
-
-void LLCallFloater::updateTitle()
-{
-	LLVoiceChannel* voice_channel = LLVoiceChannel::getCurrentVoiceChannel();
-	if (mVoiceType == VC_PEER_TO_PEER)
-	{
-		LLUUID session_id = voice_channel->getSessionID();
-		LLIMModel::LLIMSession* im_session =
-			LLIMModel::getInstance()->findIMSession(session_id);
-		if (im_session)
-		{
-			LLAvatarNameCache::get(im_session->mOtherParticipantID,
-				boost::bind(&LLCallFloater::onAvatarNameCache,
-					this, _1, _2));
-			return;
-		}
-	}
-	std::string title;
-	switch (mVoiceType)
-	{
-	case VC_LOCAL_CHAT:
-		title = getString("title_nearby");
-		break;
-	case VC_PEER_TO_PEER:
-	case VC_PEER_TO_PEER_AVALINE:
-		{
-			title = voice_channel->getSessionName();
-
-			if (VC_PEER_TO_PEER_AVALINE == mVoiceType)
-			{
-				title = LLTextUtil::formatPhoneNumber(title);
-			}
-
-			LLStringUtil::format_map_t args;
-			args["[NAME]"] = title;
-			title = getString("title_peer_2_peer", args);
-		}
-		break;
-	case VC_AD_HOC_CHAT:
-		title = getString("title_adhoc");
-		break;
-	case VC_GROUP_CHAT:
-		{
-			LLStringUtil::format_map_t args;
-			args["[GROUP]"] = voice_channel->getSessionName();
-			title = getString("title_group", args);
-		}
-		break;
-	}
-
-	setTitle(title);
-}
-
-void LLCallFloater::initAgentData()
-{
-	mAgentPanel = getChild<LLPanel> ("my_panel");
-
-	if ( mAgentPanel )
-	{
-		mAgentPanel->getChild<LLUICtrl>("user_icon")->setValue(gAgentID);
-
-		// Just use display name, because it's you
-		LLAvatarName av_name;
-		LLAvatarNameCache::get( gAgentID, &av_name );
-		mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(av_name.mDisplayName);
-
-		mSpeakingIndicator = mAgentPanel->getChild<LLOutputMonitorCtrl>("speaking_indicator");
-		mSpeakingIndicator->setSpeakerId(gAgentID);
-	}
-}
-
-void LLCallFloater::setModeratorMutedVoice(bool moderator_muted)
-{
-	mIsModeratorMutedVoice = moderator_muted;
-
-	if (moderator_muted)
-	{
-		LLNotificationsUtil::add("VoiceIsMutedByModerator");
-	}
-	mSpeakingIndicator->setIsMuted(moderator_muted);
-}
-
-void LLCallFloater::onModeratorNameCache(const LLAvatarName& av_name)
-{
-	std::string name;
-	name = av_name.mDisplayName;
-
-	if(mSpeakerManager && gAgent.isInGroup(mSpeakerManager->getSessionID()))
-	{
-		// This method can be called when LLVoiceChannel.mState == STATE_NO_CHANNEL_INFO
-		// in this case there are not any speakers yet.
-		if (mSpeakerManager->findSpeaker(gAgentID))
-		{
-			// Agent is Moderator
-			if (mSpeakerManager->findSpeaker(gAgentID)->mIsModerator)
-
-			{
-				const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); 
-				name += " " + moderator_indicator;
-			}
-		}
-	}
-	mAgentPanel->getChild<LLUICtrl>("user_text")->setValue(name);
-}
-
-void LLCallFloater::updateAgentModeratorState()
-{
-	LLAvatarNameCache::get(gAgentID, boost::bind(&LLCallFloater::onModeratorNameCache, this, _2));
-}
-
-static void get_voice_participants_uuids(uuid_vec_t& speakers_uuids)
-{
-	// Get a list of participants from VoiceClient
-       std::set<LLUUID> participants;
-       LLVoiceClient::getInstance()->getParticipantList(participants);
-	
-	for (std::set<LLUUID>::const_iterator iter = participants.begin();
-		 iter != participants.end(); ++iter)
-	{
-		speakers_uuids.push_back(*iter);
-	}
-
-}
-
-void LLCallFloater::initParticipantsVoiceState()
-{
-	// Set initial status for each participant in the list.
-	std::vector<LLPanel*> items;
-	mAvatarList->getItems(items);
-	std::vector<LLPanel*>::const_iterator
-		it = items.begin(),
-		it_end = items.end();
-
-
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-
-	for(; it != it_end; ++it)
-	{
-		LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
-		
-		if (!item)	continue;
-		
-		LLUUID speaker_id = item->getAvatarId();
-
-		uuid_vec_t::const_iterator speaker_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), speaker_id);
-
-		// If an avatarID assigned to a panel is found in a speakers list
-		// obtained from VoiceClient we assign the JOINED status to the owner
-		// of this avatarID.
-		if (speaker_iter != speakers_uuids.end())
-		{
-			setState(item, STATE_JOINED);
-		}
-		else
-		{
-			LLPointer<LLSpeaker> speakerp = mSpeakerManager->findSpeaker(speaker_id);
-			// If someone has already left the call before, we create his
-			// avatar row panel with HAS_LEFT status and remove it after
-			// the timeout, otherwise we create a panel with INVITED status
-			if (speakerp.notNull() && speakerp.get()->mHasLeftCurrentCall)
-			{
-				setState(item, STATE_LEFT);
-			}
-			else
-			{
-				setState(item, STATE_INVITED);
-			}
-		}
-	}
-}
-
-void LLCallFloater::updateParticipantsVoiceState()
-{
-	uuid_vec_t speakers_list;
-
-	// Get a list of participants from VoiceClient
-	uuid_vec_t speakers_uuids;
-	get_voice_participants_uuids(speakers_uuids);
-
-	// Updating the status for each participant already in list.
-	std::vector<LLPanel*> items;
-	mAvatarList->getItems(items);
-	std::vector<LLPanel*>::const_iterator
-		it = items.begin(),
-		it_end = items.end();
-
-	for(; it != it_end; ++it)
-	{
-		LLAvatarListItem *item = dynamic_cast<LLAvatarListItem*>(*it);
-		if (!item) continue;
-
-		const LLUUID participant_id = item->getAvatarId();
-		bool found = false;
-
-		uuid_vec_t::iterator speakers_iter = std::find(speakers_uuids.begin(), speakers_uuids.end(), participant_id);
-
-		LL_DEBUGS("Voice") << "processing speaker: " << item->getAvatarName() << ", " << item->getAvatarId() << LL_ENDL;
-
-		// If an avatarID assigned to a panel is found in a speakers list
-		// obtained from VoiceClient we assign the JOINED status to the owner
-		// of this avatarID.
-		if (speakers_iter != speakers_uuids.end())
-		{
-			setState(item, STATE_JOINED);
-
-			LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
-			if (speaker.isNull())
-				continue;
-			speaker->mHasLeftCurrentCall = FALSE;
-
-			speakers_uuids.erase(speakers_iter);
-			found = true;
-		}
-
-		if (!found)
-		{
-			updateNotInVoiceParticipantState(item);
-		}
-	}
-}
-
-void LLCallFloater::updateNotInVoiceParticipantState(LLAvatarListItem* item)
-{
-	LLUUID participant_id = item->getAvatarId();
-	ESpeakerState current_state = getState(participant_id);
-
-	switch (current_state)
-	{
-	case STATE_JOINED:
-		// If an avatarID is not found in a speakers list from VoiceClient and
-		// a panel with this ID has a JOINED status this means that this person
-		// HAS LEFT the call.
-		setState(item, STATE_LEFT);
-
-		{
-			LLPointer<LLSpeaker> speaker = mSpeakerManager->findSpeaker(participant_id);
-			if (speaker.notNull())
-			{
-				speaker->mHasLeftCurrentCall = TRUE;
-			}
-		}
-		break;
-	case STATE_LEFT:
-		// nothing to do. These states should not be changed.
-		break;
-	case STATE_INVITED:
-		// If avatar was invited into group chat and went offline it is still exists in mSpeakerStateMap
-		// If it goes online it will be rendered as JOINED via LAvatarListItem.
-		// Lets update its visual representation. See EXT-6660
-	case STATE_UNKNOWN:
-		// If an avatarID is not found in a speakers list from VoiceClient and
-		// a panel with this ID has an UNKNOWN status this means that this person
-		// HAS ENTERED session but it is not in voice chat yet. So, set INVITED status
-		setState(item, STATE_INVITED);
-		break;
-	default:
-		// for possible new future states.
-		llwarns << "Unsupported (" << getState(participant_id) << ") state for: " << item->getAvatarName()  << llendl;
-		break;
-	}
-}
-
-void LLCallFloater::setState(LLAvatarListItem* item, ESpeakerState state)
-{
-	// *HACK: mantipov: sometimes such situation is possible while switching to voice channel:
-/*
-	- voice channel is switched to the one user is joining
-	- participant list is initialized with voice states: agent is in voice
-	- than such log messages were found (with agent UUID)
-			- LLVivoxProtocolParser::process_impl: parsing: <Response requestId="22" action="Session.MediaDisconnect.1"><ReturnCode>0</ReturnCode><Results><StatusCode>0</StatusCode><StatusString /></Results><InputXml><Request requestId="22" action="Session.MediaDisconnect.1"><SessionGroupHandle>9</SessionGroupHandle><SessionHandle>12</SessionHandle><Media>Audio</Media></Request></InputXml></Response>
-			- LLVoiceClient::sessionState::removeParticipant: participant "sip:x2pwNkMbpR_mK4rtB_awASA==@bhr.vivox.com" (da9c0d90-c6e9-47f9-8ae2-bb41fdac0048) removed.
-	- and than while updating participants voice states agent is marked as HAS LEFT
-	- next updating of LLVoiceClient state makes agent JOINED
-	So, lets skip HAS LEFT state for agent's avatar
-*/
-	if (STATE_LEFT == state && item->getAvatarId() == gAgentID) return;
-
-	setState(item->getAvatarId(), state);
-
-	switch (state)
-	{
-	case STATE_INVITED:
-		item->setState(LLAvatarListItem::IS_VOICE_INVITED);
-		break;
-	case STATE_JOINED:
-		removeVoiceRemoveTimer(item->getAvatarId());
-		item->setState(LLAvatarListItem::IS_VOICE_JOINED);
-		break;
-	case STATE_LEFT:
-		{
-			setVoiceRemoveTimer(item->getAvatarId());
-			item->setState(LLAvatarListItem::IS_VOICE_LEFT);
-		}
-		break;
-	default:
-		llwarns << "Unrecognized avatar panel state (" << state << ")" << llendl;
-		break;
-	}
-}
-
-void LLCallFloater::setVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
-	mSpeakerDelayRemover->setActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::removeVoiceLeftParticipant(const LLUUID& voice_speaker_id)
-{
-	uuid_vec_t& speaker_uuids = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(speaker_uuids.begin(), speaker_uuids.end(), voice_speaker_id);
-	if(pos != speaker_uuids.end())
-	{
-		speaker_uuids.erase(pos);
-		mAvatarList->setDirty();
-	}
-
-	return false;
-}
-
-
-void LLCallFloater::resetVoiceRemoveTimers()
-{
-	mSpeakerDelayRemover->removeAllTimers();
-}
-
-void LLCallFloater::removeVoiceRemoveTimer(const LLUUID& voice_speaker_id)
-{
-	mSpeakerDelayRemover->unsetActionTimer(voice_speaker_id);
-}
-
-bool LLCallFloater::validateSpeaker(const LLUUID& speaker_id)
-{
-	bool is_valid = true;
-	switch (mVoiceType)
-	{
-	case  VC_LOCAL_CHAT:
-		{
-			// A nearby chat speaker is considered valid it it's known to LLVoiceClient (i.e. has enabled voice).
-			uuid_vec_t speakers;
-			get_voice_participants_uuids(speakers);
-			is_valid = std::find(speakers.begin(), speakers.end(), speaker_id) != speakers.end();
-		}
-		break;
-	case VC_GROUP_CHAT:
-		// if participant had left this call before do not allow add her again. See EXT-4216.
-		// but if she Join she will be added into the list from the LLCallFloater::onChange()
-		is_valid = STATE_LEFT != getState(speaker_id);
-		break;
-	default:
-		// do nothing. required for Linux build
-		break;
-	}
-
-	return is_valid;
-}
-
-void LLCallFloater::connectToChannel(LLVoiceChannel* channel)
-{
-	mVoiceChannelStateChangeConnection.disconnect();
-
-	sCurrentVoiceChannel = channel;
-
-	mVoiceChannelStateChangeConnection = sCurrentVoiceChannel->setStateChangedCallback(boost::bind(&LLCallFloater::onVoiceChannelStateChanged, this, _1, _2));
-
-	updateState(channel->getState());
-}
-
-void LLCallFloater::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	// check is voice operational and if it doesn't work hide VCP (EXT-4397)
-	if(LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking())
-	{
-		updateState(new_state);
-	}
-	else
-	{
-		closeFloater();
-	}
-}
-
-void LLCallFloater::updateState(const LLVoiceChannel::EState& new_state)
-{
-	LL_DEBUGS("Voice") << "Updating state: " << new_state << ", session name: " << sCurrentVoiceChannel->getSessionName() << LL_ENDL;
-	if (LLVoiceChannel::STATE_CONNECTED == new_state)
-	{
-		updateSession();
-	}
-	else
-	{
-		reset(new_state);
-	}
-}
-
-void LLCallFloater::reset(const LLVoiceChannel::EState& new_state)
-{
-	// lets forget states from the previous session
-	// for timers...
-	resetVoiceRemoveTimers();
-
-	// ...and for speaker state
-	mSpeakerStateMap.clear();
-
-	delete mParticipants;
-	mParticipants = NULL;
-	mAvatarList->clear();
-
-	// These ifs were added instead of simply showing "loading" to make VCP work correctly in parcels
-	// with disabled voice (EXT-4648 and EXT-4649)
-	if (!LLViewerParcelMgr::getInstance()->allowAgentVoice() && LLVoiceChannel::STATE_HUNG_UP == new_state)
-	{
-		// hides "Leave Call" when call is ended in parcel with disabled voice- hiding usually happens in
-		// updateSession() which won't be called here because connect to nearby voice never happens 
-		getChildView("leave_call_btn_panel")->setVisible( false);
-		// setting title to nearby chat an "no one near..." text- because in region with disabled
-		// voice we won't have chance to really connect to nearby, so VCP is changed here manually
-		setTitle(getString("title_nearby"));
-		mAvatarList->setNoItemsCommentText(getString("no_one_near"));
-	}
-	// "loading" is shown  only when state is "ringing" to avoid showing it in nearby chat vcp
-	// of parcels with disabled voice all the time- "no_one_near" is now shown there (EXT-4648)
-	else if (new_state == LLVoiceChannel::STATE_RINGING)
-	{
-		// update floater to show Loading while waiting for data.
-		mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
-	}
-
-	mAvatarList->setVisible(TRUE);
-	mNonAvatarCaller->setVisible(FALSE);
-
-	mSpeakerManager = NULL;
-}
-
-//EOF
diff --git a/indra/newview/llcallfloater.h b/indra/newview/llcallfloater.h
deleted file mode 100644
index 00a3f76e5679d53ee2908cff0ab9776ebe04e289..0000000000000000000000000000000000000000
--- a/indra/newview/llcallfloater.h
+++ /dev/null
@@ -1,273 +0,0 @@
-/** 
- * @file llcallfloater.h
- * @author Mike Antipov
- * @brief Voice Control Panel in a Voice Chats (P2P, Group, Nearby...).
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLCALLFLOATER_H
-#define LL_LLCALLFLOATER_H
-
-#include "lltransientdockablefloater.h"
-#include "llvoicechannel.h"
-#include "llvoiceclient.h"
-
-class LLAvatarList;
-class LLAvatarListItem;
-class LLAvatarName;
-class LLNonAvatarCaller;
-class LLOutputMonitorCtrl;
-class LLParticipantList;
-class LLSpeakerMgr;
-class LLSpeakersDelayActionsStorage;
-
-/**
- * The Voice Control Panel is an ambient window summoned by clicking the flyout chevron
- * on the Speak button. It can be torn-off and freely positioned onscreen.
- *
- * When the Resident is engaged in Voice Chat, the Voice Control Panel provides control
- * over the audible volume of each of the other participants, the Resident's own Voice
- * Morphing settings (if she has subscribed to enable the feature), and Voice Recording.
- *
- * When the Resident is engaged in any chat except Nearby Chat, the Voice Control Panel
- * also provides a 'Leave Call' button to allow the Resident to leave that voice channel.
- */
-class LLCallFloater : public LLTransientDockableFloater, LLVoiceClientParticipantObserver
-{
-public:
-
-	LOG_CLASS(LLCallFloater);
-
-	LLCallFloater(const LLSD& key);
-	~LLCallFloater();
-
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-	/*virtual*/ void draw();
-	/*virtual*/ void setFocus( BOOL b );
-
-	/**
-	 * Is called by LLVoiceClient::notifyParticipantObservers when voice participant list is changed.
-	 *
-	 * Refreshes list to display participants not in voice as disabled.
-	 */
-	/*virtual*/ void onParticipantsChanged();
-
-	static void sOnCurrentChannelChanged(const LLUUID& session_id);
-
-private:
-	typedef enum e_voice_controls_type
-	{
-		VC_LOCAL_CHAT,
-		VC_GROUP_CHAT,
-		VC_AD_HOC_CHAT,
-		VC_PEER_TO_PEER,
-		VC_PEER_TO_PEER_AVALINE
-	}EVoiceControls;
-
-	typedef enum e_speaker_state
-	{
-		STATE_UNKNOWN,
-		STATE_INVITED,
-		STATE_JOINED,
-		STATE_LEFT,
-	} ESpeakerState;
-
-	typedef std::map<LLUUID, ESpeakerState> speaker_state_map_t;
-
-	void leaveCall();
-
-	/**
-	 * Updates mSpeakerManager and list according to current Voice Channel
-	 *
-	 * It compares mSpeakerManager & current Voice Channel session IDs.
-	 * If they are different gets Speaker manager related to current channel and updates channel participant list.
-	 */
-	void updateSession();
-
-	/**
-	 * Refreshes participant list according to current Voice Channel
-	 */
-	void refreshParticipantList();
-
-	/**
-	 * Handles event on avatar list is refreshed after it was marked dirty.
-	 *
-	 * It sets initial participants voice states (once after the first refreshing)
-	 * and updates voice states each time anybody is joined/left voice chat in session.
-	 */
-	void onAvatarListRefreshed();
-
-	/**
-	 * Updates window title with an avatar name
-	 */
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-	
-	void updateTitle();
-	void initAgentData();
-	void setModeratorMutedVoice(bool moderator_muted);
-	void updateAgentModeratorState();
-	void onModeratorNameCache(const LLAvatarName& av_name);
-
-	/**
-	 * Sets initial participants voice states in avatar list (Invited, Joined, Has Left).
-	 *
-	 * @see refreshParticipantList()
-	 * @see onAvatarListRefreshed()
-	 * @see mInitParticipantsVoiceState
-	 */
-	void initParticipantsVoiceState();
-
-	/**
-	 * Updates participants voice states in avatar list (Invited, Joined, Has Left).
-	 *
-	 * @see onAvatarListRefreshed()
-	 * @see onChanged()
-	 */
-	void updateParticipantsVoiceState();
-
-	/**
-	 * Updates voice state of participant not in current voice channel depend on its current state.
-	 */
-	void updateNotInVoiceParticipantState(LLAvatarListItem* item);
-	void setState(LLAvatarListItem* item, ESpeakerState state);
-	void setState(const LLUUID& speaker_id, ESpeakerState state)
-	{
-		lldebugs << "Storing state: " << speaker_id << ", " << state << llendl;
-		mSpeakerStateMap[speaker_id] = state;
-	}
-
-	ESpeakerState getState(const LLUUID& speaker_id)
-	{
-		lldebugs << "Getting state: " << speaker_id << ", " << mSpeakerStateMap[speaker_id] << llendl;
-
-		return mSpeakerStateMap[speaker_id];
-	}
-
-	/**
-	 * Instantiates new LLAvatarListItemRemoveTimer and adds it into the map if it is not already created.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list when timer expires.
-	 */
-	void setVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Removes specified by UUID Avatar List item.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item to be removed from the list.
-	 */
-	bool removeVoiceLeftParticipant(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Deletes all timers from the list to prevent started timers from ticking after destruction
-	 * and after switching on another voice channel.
-	 */
-	void resetVoiceRemoveTimers();
-
-	/**
-	 * Removes specified by UUID timer from the map.
-	 *
-	 * @param voice_speaker_id LLUUID of Avatar List item whose timer should be removed from the map.
-	 */
-	void removeVoiceRemoveTimer(const LLUUID& voice_speaker_id);
-
-	/**
-	 * Called by LLParticipantList before adding a speaker to the participant list.
-	 *
-	 * If false is returned, the speaker will not be added to the list.
-	 *
-	 * @param speaker_id Speaker to validate.
-	 * @return true if this is a valid speaker, false otherwise.
-	 */
-	bool validateSpeaker(const LLUUID& speaker_id);
-
-	/**
-	 * Connects to passed channel to be updated according to channel's voice states.
-	 */
-	void connectToChannel(LLVoiceChannel* channel);
-
-	/**
-	 * Callback to process changing of voice channel's states.
-	 */
-	void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
-	/**
-	 * Updates floater according to passed channel's voice state.
-	 */
-	void updateState(const LLVoiceChannel::EState& new_state);
-
-	/**
-	 * Resets floater to be ready to show voice participants.
-	 *
-	 * Clears all data from the latest voice session.
-	 */
-	void reset(const LLVoiceChannel::EState& new_state);
-
-private:
-	speaker_state_map_t mSpeakerStateMap;
-	LLSpeakerMgr* mSpeakerManager;
-	LLParticipantList* mParticipants;
-	LLAvatarList* mAvatarList;
-	LLNonAvatarCaller* mNonAvatarCaller;
-	EVoiceControls mVoiceType;
-	LLPanel* mAgentPanel;
-	LLOutputMonitorCtrl* mSpeakingIndicator;
-	bool mIsModeratorMutedVoice;
-
-	/**
-	 * Flag indicated that participants voice states should be initialized.
-	 *
-	 * It is used due to Avatar List has delayed refreshing after it content is changed.
-	 * Real initializing is performed when Avatar List is first time refreshed.
-	 *
-	 * @see onAvatarListRefreshed()
-	 * @see initParticipantsVoiceState()
-	 */
-	bool mInitParticipantsVoiceState;
-
-	boost::signals2::connection mAvatarListRefreshConnection;
-
-
-	/**
-	 * time out speakers when they are not part of current session
-	 */
-	LLSpeakersDelayActionsStorage* mSpeakerDelayRemover;
-
-	/**
-	 * Stores reference to current voice channel.
-	 *
-	 * Is used to ignore voice channel changed callback for the same channel.
-	 *
-	 * @see sOnCurrentChannelChanged()
-	 */
-	static LLVoiceChannel* sCurrentVoiceChannel;
-
-	/* virtual */
-	LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
-	boost::signals2::connection mVoiceChannelStateChangeConnection;
-};
-
-
-#endif //LL_LLCALLFLOATER_H
-
diff --git a/indra/newview/llcallingcard.cpp b/indra/newview/llcallingcard.cpp
index 0d55c4429af2e38700f3e567f8b24bc849a6ee14..14583e402d53551164fa2fe91161e2fd8f3d989f 100644
--- a/indra/newview/llcallingcard.cpp
+++ b/indra/newview/llcallingcard.cpp
@@ -54,6 +54,7 @@
 #include "llresmgr.h"
 #include "llslurl.h"
 #include "llimview.h"
+#include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llviewernetwork.h"
 #include "llviewerobjectlist.h"
@@ -183,7 +184,8 @@ LLVector3d LLAvatarTracker::getGlobalPos()
 		global_pos = object->getPositionGlobal();
 		// HACK - for making the tracker point above the avatar's head
 		// rather than its groin
-		global_pos.mdV[VZ] += 0.7f * ((LLVOAvatar *)object)->mBodySize.mV[VZ];
+		LLVOAvatar* av = (LLVOAvatar*)object;
+		global_pos.mdV[VZ] += 0.7f * (av->mBodySize.mV[VZ] + av->mAvatarOffset.mV[VZ]);
 
 		mTrackingData->mGlobalPositionEstimate = global_pos;
 	}
@@ -703,9 +705,7 @@ void LLAvatarTracker::processNotify(LLMessageSystem* msg, bool online)
 		if(chat_notify)
 		{
 			// Look up the name of this agent for the notification
-			LLAvatarNameCache::get(agent_id,
-				boost::bind(&on_avatar_name_cache_notify,
-					_1, _2, online, payload));
+			LLAvatarNameCache::get(agent_id,boost::bind(&on_avatar_name_cache_notify,_1, _2, online, payload));
 		}
 
 		mModifyMask |= LLFriendObserver::ONLINE;
@@ -722,13 +722,14 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
 	// Popup a notify box with online status of this agent
 	// Use display name only because this user is your friend
 	LLSD args;
-	args["NAME"] = av_name.mDisplayName;
+	args["NAME"] = av_name.getDisplayName();
+	args["STATUS"] = online ? LLTrans::getString("OnlineStatus") : LLTrans::getString("OfflineStatus");
 
 	LLNotificationPtr notification;
 	if (online)
 	{
 		notification =
-			LLNotificationsUtil::add("FriendOnline",
+			LLNotificationsUtil::add("FriendOnlineOffline",
 									 args,
 									 payload.with("respond_on_mousedown", TRUE),
 									 boost::bind(&LLAvatarActions::startIM, agent_id));
@@ -736,7 +737,7 @@ static void on_avatar_name_cache_notify(const LLUUID& agent_id,
 	else
 	{
 		notification =
-			LLNotificationsUtil::add("FriendOffline", args, payload);
+			LLNotificationsUtil::add("FriendOnlineOffline", args, payload);
 	}
 
 	// If there's an open IM session with this agent, send a notification there too.
@@ -867,7 +868,7 @@ bool LLCollectMappableBuddies::operator()(const LLUUID& buddy_id, LLRelationship
 {
 	LLAvatarName av_name;
 	LLAvatarNameCache::get( buddy_id, &av_name);
-	buddy_map_t::value_type value(av_name.mDisplayName, buddy_id);
+	buddy_map_t::value_type value(av_name.getDisplayName(), buddy_id);
 	if(buddy->isOnline() && buddy->isRightGrantedFrom(LLRelationship::GRANT_MAP_LOCATION))
 	{
 		mMappable.insert(value);
@@ -890,7 +891,7 @@ bool LLCollectAllBuddies::operator()(const LLUUID& buddy_id, LLRelationship* bud
 {
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(buddy_id, &av_name);
-	mFullName = av_name.mDisplayName;
+	mFullName = av_name.getDisplayName();
 	buddy_map_t::value_type value(mFullName, buddy_id);
 	if(buddy->isOnline())
 	{
diff --git a/indra/newview/llchannelmanager.cpp b/indra/newview/llchannelmanager.cpp
index 987651fc80435dfc493761b8ead5925b67e72b24..43757d0174f96309596896189a7ee027e00291f8 100644
--- a/indra/newview/llchannelmanager.cpp
+++ b/indra/newview/llchannelmanager.cpp
@@ -29,7 +29,8 @@
 #include "llchannelmanager.h"
 
 #include "llappviewer.h"
-#include "llnotificationstorage.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llpersistentnotificationstorage.h"
 #include "llviewercontrol.h"
 #include "llviewerwindow.h"
 #include "llrootview.h"
@@ -138,6 +139,9 @@ 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 d6095cce07d541e48297146c7c1e2164b96b6e77..7d0331757bed74a6c3887127f417d104d105d47d 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -669,47 +669,3 @@ void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
 		mGestureCombo->setFocus(FALSE);
 	}
 }
-
-
-/* Cruft - global gChatHandler declared below has been commented out,
-   so this class is never used.  See similar code in llnearbychatbar.cpp
-class LLChatHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2) 
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-				// Say mesg on channel
-		std::string mesg = tokens[1].asString();
-		send_chat_from_viewer(mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-//LLChatHandler gChatHandler;
-cruft */
diff --git a/indra/newview/llchathistory.cpp b/indra/newview/llchathistory.cpp
index 3e1fa1e49be0d66241cac49db41e7e3a41e83868..0f138873ac8cec543dbc16078ef48098af611934 100644
--- a/indra/newview/llchathistory.cpp
+++ b/indra/newview/llchathistory.cpp
@@ -28,6 +28,8 @@
 
 #include "llchathistory.h"
 
+#include <boost/signals2.hpp>
+
 #include "llavatarnamecache.h"
 #include "llinstantmessage.h"
 
@@ -56,7 +58,7 @@
 #include "llworld.h"
 #include "lluiconstants.h"
 #include "llstring.h"
-
+#include "llurlaction.h"
 #include "llviewercontrol.h"
 
 static LLDefaultChildRegistry::Register<LLChatHistory> r("chat_history");
@@ -112,7 +114,8 @@ class LLChatHistoryHeader: public LLPanel
 		mMinUserNameWidth(0),
 		mUserNameFont(NULL),
 		mUserNameTextBox(NULL),
-		mTimeBoxTextBox(NULL)
+		mTimeBoxTextBox(NULL),
+		mAvatarNameCacheConnection()
 	{}
 
 	static LLChatHistoryHeader* createInstance(const std::string& file_name)
@@ -126,6 +129,11 @@ class LLChatHistoryHeader: public LLPanel
 	{
 		// Detach the info button so that it doesn't get destroyed (EXT-8463).
 		hideInfoCtrl();
+
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
 	}
 
 	BOOL handleMouseUp(S32 x, S32 y, MASK mask)
@@ -145,8 +153,20 @@ class LLChatHistoryHeader: public LLPanel
 		{
 			LLMuteList::getInstance()->add(LLMute(getAvatarId(), mFrom, LLMute::OBJECT));
 
-			LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with("blocked_to_select", getAvatarId()));
+			LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+				LLSD().with("people_panel_tab_name", "blocked_panel").with("blocked_to_select", getAvatarId()));
+		}
+		else if (level == "map")
+		{
+			std::string url = "secondlife://" + mObjectData["slurl"].asString();
+			LLUrlAction::showLocationOnMap(url);
+		}
+		else if (level == "teleport")
+		{
+			std::string url = "secondlife://" + mObjectData["slurl"].asString();
+			LLUrlAction::teleportToLocation(url);
 		}
+
 	}
 
 	void onAvatarIconContextMenuItemClicked(const LLSD& userdata)
@@ -287,8 +307,7 @@ class LLChatHistoryHeader: public LLPanel
 			// Start with blank so sample data from XUI XML doesn't
 			// flash on the screen
 			user_name->setValue( LLSD() );
-			LLAvatarNameCache::get(mAvatarID,
-				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+			fetchAvatarName();
 		}
 		else if (chat.mChatStyle == CHAT_STYLE_HISTORY ||
 				 mSourceType == CHAT_SOURCE_AGENT)
@@ -389,16 +408,7 @@ class LLChatHistoryHeader: public LLPanel
 		S32 user_name_width = user_name_rect.getWidth();
 		S32 time_box_width = time_box->getRect().getWidth();
 
-		if (time_box->getVisible() && user_name_width <= mMinUserNameWidth)
-		{
-			time_box->setVisible(FALSE);
-
-			user_name_rect.mRight += time_box_width;
-			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
-			user_name->setRect(user_name_rect);
-		}
-
-		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth + time_box_width)
+		if (!time_box->getVisible() && user_name_width > mMinUserNameWidth)
 		{
 			user_name_rect.mRight -= time_box_width;
 			user_name->reshape(user_name_rect.getWidth(), user_name_rect.getHeight());
@@ -420,31 +430,6 @@ class LLChatHistoryHeader: public LLPanel
 		}
 	}
 
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
-	{
-		mFrom = av_name.mDisplayName;
-
-		LLTextBox* user_name = getChild<LLTextBox>("user_name");
-		user_name->setValue( LLSD(av_name.mDisplayName ) );
-		user_name->setToolTip( av_name.mUsername );
-
-		if (gSavedSettings.getBOOL("NameTagShowUsernames") && 
-			LLAvatarNameCache::useDisplayNames() &&
-			!av_name.mIsDisplayNameDefault)
-		{
-			LLStyle::Params style_params_name;
-			LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
-			style_params_name.color(userNameColor);
-			style_params_name.font.name("SansSerifSmall");
-			style_params_name.font.style("NORMAL");
-			style_params_name.readonly_color(userNameColor);
-			user_name->appendText("  - " + av_name.mUsername, FALSE, style_params_name);
-		}
-		setToolTip( av_name.mUsername );
-		// name might have changed, update width
-		updateMinUserNameWidth();
-	}
-
 protected:
 	static const S32 PADDING = 20;
 
@@ -559,6 +544,46 @@ class LLChatHistoryHeader: public LLPanel
 		user_name->reshape(user_rect.getWidth() + delta_pos_x, user_rect.getHeight());
 	}
 
+	void fetchAvatarName()
+	{
+		if (mAvatarID.notNull())
+		{
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,
+				boost::bind(&LLChatHistoryHeader::onAvatarNameCache, this, _1, _2));
+		}
+	}
+
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name)
+	{
+		mAvatarNameCacheConnection.disconnect();
+
+		mFrom = av_name.getDisplayName();
+
+		LLTextBox* user_name = getChild<LLTextBox>("user_name");
+		user_name->setValue( LLSD(av_name.getDisplayName() ) );
+		user_name->setToolTip( av_name.getUserName() );
+
+		if (gSavedSettings.getBOOL("NameTagShowUsernames") && 
+			av_name.useDisplayNames() &&
+			!av_name.isDisplayNameDefault())
+		{
+			LLStyle::Params style_params_name;
+			LLColor4 userNameColor = LLUIColorTable::instance().getColor("EmphasisColor");
+			style_params_name.color(userNameColor);
+			style_params_name.font.name("SansSerifSmall");
+			style_params_name.font.style("NORMAL");
+			style_params_name.readonly_color(userNameColor);
+			user_name->appendText("  - " + av_name.getUserName(), FALSE, style_params_name);
+		}
+		setToolTip( av_name.getUserName() );
+		// name might have changed, update width
+		updateMinUserNameWidth();
+	}
+
 protected:
 	LLHandle<LLView>	mPopupMenuHandleAvatar;
 	LLHandle<LLView>	mPopupMenuHandleObject;
@@ -575,6 +600,9 @@ class LLChatHistoryHeader: public LLPanel
 	const LLFontGL*		mUserNameFont;
 	LLTextBox*			mUserNameTextBox;
 	LLTextBox*			mTimeBoxTextBox; 
+
+private:
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 LLUICtrl* LLChatHistoryHeader::sInfoCtrl = NULL;
@@ -591,7 +619,8 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mBottomSeparatorPad(p.bottom_separator_pad),
 	mTopHeaderPad(p.top_header_pad),
 	mBottomHeaderPad(p.bottom_header_pad),
-	mIsLastMessageFromLog(false)
+	mIsLastMessageFromLog(false),
+	mNotifyAboutUnreadMsg(p.notify_unread_msg)
 {
 	LLTextEditor::Params editor_params(p);
 	editor_params.rect = getLocalRect();
@@ -601,6 +630,14 @@ LLChatHistory::LLChatHistory(const LLChatHistory::Params& p)
 	mEditor = LLUICtrlFactory::create<LLTextEditor>(editor_params, this);
 }
 
+LLSD LLChatHistory::getValue() const
+{
+  LLSD* text=new LLSD(); 
+  text->assign(mEditor->getText());
+  return *text;
+    
+}
+
 LLChatHistory::~LLChatHistory()
 {
 	this->clear();
@@ -702,6 +739,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 {
 	LLFastTimer _(FTM_APPEND_MESSAGE);
 	bool use_plain_text_chat_history = args["use_plain_text_chat_history"].asBoolean();
+	bool square_brackets = false; // square brackets necessary for a system messages
 
 	llassert(mEditor);
 	if (!mEditor)
@@ -709,9 +747,10 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		return;
 	}
 
+	bool from_me = chat.mFromID == gAgent.getID();
 	mEditor->setPlainText(use_plain_text_chat_history);
 
-	if (!mEditor->scrolledToEnd() && chat.mFromID != gAgent.getID() && !chat.mFromName.empty())
+	if (mNotifyAboutUnreadMsg && !mEditor->scrolledToEnd() && !from_me && !chat.mFromName.empty())
 	{
 		mUnreadChatSources.insert(chat.mFromName);
 		mMoreChatPanel->setVisible(TRUE);
@@ -741,16 +780,23 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	}
 
 	LLColor4 txt_color = LLUIColorTable::instance().getColor("White");
+	LLColor4 name_color(txt_color);
+
 	LLViewerChat::getChatColor(chat,txt_color);
 	LLFontGL* fontp = LLViewerChat::getChatFont();	
 	std::string font_name = LLFontGL::nameFromFont(fontp);
 	std::string font_size = LLFontGL::sizeFromFont(fontp);	
-	LLStyle::Params style_params;
-	style_params.color(txt_color);
-	style_params.readonly_color(txt_color);
-	style_params.font.name(font_name);
-	style_params.font.size(font_size);	
-	style_params.font.style(input_append_params.font.style);
+
+	LLStyle::Params body_message_params;
+	body_message_params.color(txt_color);
+	body_message_params.readonly_color(txt_color);
+	body_message_params.font.name(font_name);
+	body_message_params.font.size(font_size);
+	body_message_params.font.style(input_append_params.font.style);
+
+	LLStyle::Params name_params(body_message_params);
+	name_params.color(name_color);
+	name_params.readonly_color(name_color);
 
 	std::string prefix = chat.mText.substr(0, 4);
 
@@ -773,29 +819,60 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 	if (irc_me || chat.mChatStyle == CHAT_STYLE_IRC)
 	{
 		delimiter = LLStringUtil::null;
-		style_params.font.style = "ITALIC";
+		body_message_params.font.style = "ITALIC";
+	}
+
+	if(chat.mChatType == CHAT_TYPE_WHISPER)
+	{
+		body_message_params.font.style = "ITALIC";
+	}
+	else if(chat.mChatType == CHAT_TYPE_SHOUT)
+	{
+		body_message_params.font.style = "BOLD";
 	}
 
 	bool message_from_log = chat.mChatStyle == CHAT_STYLE_HISTORY;
 	// We graying out chat history by graying out messages that contains full date in a time string
 	if (message_from_log)
 	{
-		style_params.color(LLColor4::grey);
-		style_params.readonly_color(LLColor4::grey);
+		txt_color = LLColor4::grey;
+		body_message_params.color(txt_color);
+		body_message_params.readonly_color(txt_color);
+		name_params.color(txt_color);
+		name_params.readonly_color(txt_color);
 	}
 
+	bool prependNewLineState = mEditor->getText().size() != 0;
+
+	// compact mode: show a timestamp and name
 	if (use_plain_text_chat_history)
 	{
-		LLStyle::Params timestamp_style(style_params);
+		square_brackets = chat.mFromName == SYSTEM_FROM;
+
+		LLStyle::Params timestamp_style(body_message_params);
+
+		// out of the timestamp
+		if (args["show_time"].asBoolean())
+		{
 		if (!message_from_log)
 		{
 			LLColor4 timestamp_color = LLUIColorTable::instance().getColor("ChatTimestampColor");
 			timestamp_style.color(timestamp_color);
 			timestamp_style.readonly_color(timestamp_color);
 		}
-		mEditor->appendText("[" + chat.mTimeStr + "] ", mEditor->getLength() != 0, timestamp_style);
+			mEditor->appendText("[" + chat.mTimeStr + "] ", prependNewLineState, timestamp_style);
+			prependNewLineState = false;
+		}
+
+        // out the opening square bracket (if need)
+		if (square_brackets)
+		{
+			mEditor->appendText("[", prependNewLineState, body_message_params);
+			prependNewLineState = false;
+		}
 
-		if (utf8str_trim(chat.mFromName).size() != 0)
+		// names showing
+		if (args["show_names_for_p2p_conv"].asBoolean() && utf8str_trim(chat.mFromName).size() != 0)
 		{
 			// Don't hotlink any messages from the system (e.g. "Second Life:"), so just add those in plain text.
 			if ( chat.mSourceType == CHAT_SOURCE_OBJECT && chat.mFromID.notNull())
@@ -805,32 +882,47 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 				// set the link for the object name to be the objectim SLapp
 				// (don't let object names with hyperlinks override our objectim Url)
-				LLStyle::Params link_params(style_params);
+				LLStyle::Params link_params(body_message_params);
 				LLColor4 link_color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 				link_params.color = link_color;
 				link_params.readonly_color = link_color;
 				link_params.is_link = true;
 				link_params.link_href = url;
 
-				mEditor->appendText(chat.mFromName + delimiter,
-									false, link_params);
+				mEditor->appendText(chat.mFromName + delimiter, prependNewLineState, link_params);
+				prependNewLineState = false;
 			}
 			else if ( chat.mFromName != SYSTEM_FROM && chat.mFromID.notNull() && !message_from_log)
 			{
-				LLStyle::Params link_params(style_params);
+				LLStyle::Params link_params(body_message_params);
 				link_params.overwriteFrom(LLStyleMap::instance().lookupAgent(chat.mFromID));
 
+				if (from_me)
+				{	std::string localized_name;
+					bool is_localized = LLTrans::findString(localized_name, "AgentNameSubst");
+					mEditor->appendText((is_localized? localized_name:"(You)") + delimiter,
+							prependNewLineState, link_params);
+					prependNewLineState = false;
+				}
+				else
+				{
 				// Add link to avatar's inspector and delimiter to message.
-				mEditor->appendText(std::string(link_params.link_href) + delimiter, false, link_params);
+					mEditor->appendText(std::string(link_params.link_href) + delimiter,
+							prependNewLineState, link_params);
+					prependNewLineState = false;
+				}
 			}
 			else
 			{
-				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter, false, style_params);
+				mEditor->appendText("<nolink>" + chat.mFromName + "</nolink>" + delimiter,
+						prependNewLineState, body_message_params);
+				prependNewLineState = false;
 			}
 		}
 	}
-	else
+	else // showing timestamp and name in the expanded mode
 	{
+		prependNewLineState = false;
 		LLView* view = NULL;
 		LLInlineViewSegment::Params p;
 		p.force_newline = true;
@@ -851,7 +943,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		}
 		else
 		{
-			view = getHeader(chat, style_params, args);
+			view = getHeader(chat, name_params, args);
 			if (mEditor->getLength() == 0)
 				p.top_pad = 0;
 			else
@@ -880,41 +972,16 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 		mIsLastMessageFromLog = message_from_log;
 	}
 
+	// body of the message processing
+
+	// notify processing
 	if (chat.mNotifId.notNull())
 	{
 		LLNotificationPtr notification = LLNotificationsUtil::find(chat.mNotifId);
 		if (notification != NULL)
 		{
 			LLIMToastNotifyPanel* notify_box = new LLIMToastNotifyPanel(
-					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history);
-			//we can't set follows in xml since it broke toasts behavior
-			notify_box->setFollowsLeft();
-			notify_box->setFollowsRight();
-			notify_box->setFollowsTop();
-
-			ctrl_list_t ctrls = notify_box->getControlPanel()->getCtrlList();
-			S32 offset = 0;
-			// Children were added by addChild() which uses push_front to insert them into list,
-			// so to get buttons in correct order reverse iterator is used (EXT-5906) 
-			for (ctrl_list_t::reverse_iterator it = ctrls.rbegin(); it != ctrls.rend(); it++)
-			{
-				LLButton * button = dynamic_cast<LLButton*> (*it);
-				if (button != NULL)
-				{
-					button->setOrigin( offset,
-							button->getRect().mBottom);
-					button->setLeftHPad(2 * HPAD);
-					button->setRightHPad(2 * HPAD);
-					// set zero width before perform autoResize()
-					button->setRect(LLRect(button->getRect().mLeft,
-							button->getRect().mTop, button->getRect().mLeft,
-							button->getRect().mBottom));
-					button->setAutoResize(true);
-					button->autoResize();
-					offset += HPAD + button->getRect().getWidth();
-					button->setFollowsNone();
-				}
-			}
+					notification, chat.mSessionID, LLRect::null, !use_plain_text_chat_history, mEditor);
 
 			//Prepare the rect for the view
 			LLRect target_rect = mEditor->getDocumentView()->getRect();
@@ -931,6 +998,8 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			mEditor->appendWidget(params, "\n", false);
 		}
 	}
+
+	// usual messages showing
 	else
 	{
 		std::string message = irc_me ? chat.mText.substr(3) : chat.mText;
@@ -938,7 +1007,7 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 
 		//MESSAGE TEXT PROCESSING
 		//*HACK getting rid of redundant sender names in system notifications sent using sender name (see EXT-5010)
-		if (use_plain_text_chat_history && gAgentID != chat.mFromID && chat.mFromID.notNull())
+		if (use_plain_text_chat_history && !from_me && chat.mFromID.notNull())
 		{
 			std::string slurl_about = SLURL_APP_AGENT + chat.mFromID.asString() + SLURL_ABOUT;
 			if (message.length() > slurl_about.length() && 
@@ -953,13 +1022,19 @@ void LLChatHistory::appendMessage(const LLChat& chat, const LLSD &args, const LL
 			message = chat.mFromName + message;
 		}
 		
-		mEditor->appendText(message, FALSE, style_params);
+		if (square_brackets)
+		{
+			message += "]";
+	}
+
+		mEditor->appendText(message, prependNewLineState, body_message_params);
+		prependNewLineState = false;
 	}
 
 	mEditor->blockUndo();
 
 	// automatically scroll to end when receiving chat from myself
-	if (chat.mFromID == gAgentID)
+	if (from_me)
 	{
 		mEditor->setCursorAndScrollToEnd();
 	}
diff --git a/indra/newview/llchathistory.h b/indra/newview/llchathistory.h
index 28344e6a1028f1c1bfaa4c5ba5632a263902a345..bb6d4fb59cefc4a07434caad95c6e2dee0dd652c 100644
--- a/indra/newview/llchathistory.h
+++ b/indra/newview/llchathistory.h
@@ -60,6 +60,8 @@ class LLChatHistory : public LLUICtrl
 
 			Optional<LLTextBox::Params>	more_chat_text;
 
+			Optional<bool>			notify_unread_msg;
+
 			Params()
 			:	message_header("message_header"),
 				message_separator("message_separator"),
@@ -71,7 +73,8 @@ class LLChatHistory : public LLUICtrl
 				bottom_separator_pad("bottom_separator_pad"),
 				top_header_pad("top_header_pad"),
 				bottom_header_pad("bottom_header_pad"),
-				more_chat_text("more_chat_text")
+				more_chat_text("more_chat_text"),
+				notify_unread_msg("notify_unread_msg", true)
 			{}
 
 		};
@@ -100,7 +103,7 @@ class LLChatHistory : public LLUICtrl
 
 	public:
 		~LLChatHistory();
-
+		LLSD getValue() const;   
 		void initFromParams(const Params&);
 
 		/**
@@ -122,6 +125,7 @@ class LLChatHistory : public LLUICtrl
 		LLUUID mLastFromID;
 		LLDate mLastMessageTime;
 		bool mIsLastMessageFromLog;
+		bool mNotifyAboutUnreadMsg;
 		//std::string mLastMessageTimeStr;
 
 		std::string mMessageHeaderFilename;
diff --git a/indra/newview/llchatitemscontainerctrl.cpp b/indra/newview/llchatitemscontainerctrl.cpp
index 9a84280f258f7be30c1763d1882c88943cdec6ae..a1a9463d4363cd695f09badce3bd4b6fef7feaf0 100644
--- a/indra/newview/llchatitemscontainerctrl.cpp
+++ b/indra/newview/llchatitemscontainerctrl.cpp
@@ -35,7 +35,7 @@
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
 #include "lltrans.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 
 #include "llviewercontrol.h"
 #include "llagentdata.h"
@@ -81,23 +81,30 @@ class LLObjectHandler : public LLCommandHandler
 LLObjectHandler gObjectHandler;
 
 //*******************************************************************************************************************
-//LLNearbyChatToastPanel
+//LLFloaterIMNearbyChatToastPanel
 //*******************************************************************************************************************
 
-LLNearbyChatToastPanel* LLNearbyChatToastPanel::createInstance()
+LLFloaterIMNearbyChatToastPanel* LLFloaterIMNearbyChatToastPanel::createInstance()
 {
-	LLNearbyChatToastPanel* item = new LLNearbyChatToastPanel();
+	LLFloaterIMNearbyChatToastPanel* item = new LLFloaterIMNearbyChatToastPanel();
 	item->buildFromFile("panel_chat_item.xml");
 	item->setFollows(FOLLOWS_NONE);
 	return item;
 }
 
-void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
+void	LLFloaterIMNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_parent )
 {
 	LLPanel::reshape(width, height,called_from_parent);
 
-	LLUICtrl* msg_text = getChild<LLUICtrl>("msg_text", false);
-	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
+	// reshape() may be called from LLView::initFromParams() before the children are created.
+	// We call findChild() instead of getChild() here to avoid creating dummy controls.
+	LLUICtrl* msg_text = findChild<LLUICtrl>("msg_text", false);
+	LLUICtrl* icon = findChild<LLUICtrl>("avatar_icon", false);
+
+	if (!msg_text || !icon)
+	{
+		return;
+	}
 
 	LLRect msg_text_rect = msg_text->getRect();
 	LLRect avatar_rect = icon->getRect();
@@ -114,12 +121,12 @@ void	LLNearbyChatToastPanel::reshape		(S32 width, S32 height, BOOL called_from_p
 	msg_text->setRect(msg_text_rect);
 }
 
-BOOL LLNearbyChatToastPanel::postBuild()
+BOOL LLFloaterIMNearbyChatToastPanel::postBuild()
 {
 	return LLPanel::postBuild();
 }
 
-void LLNearbyChatToastPanel::addMessage(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::addMessage(LLSD& notification)
 {
 	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
 
@@ -171,7 +178,7 @@ void LLNearbyChatToastPanel::addMessage(LLSD& notification)
 
 }
 
-void LLNearbyChatToastPanel::init(LLSD& notification)
+void LLFloaterIMNearbyChatToastPanel::init(LLSD& notification)
 {
 	std::string		messageText = notification["message"].asString();		// UTF-8 line of text
 	std::string		fromName = notification["from"].asString();	// agent or object name
@@ -266,7 +273,7 @@ void LLNearbyChatToastPanel::init(LLSD& notification)
 	mIsDirty = true;//will set Avatar Icon in draw
 }
 
-void	LLNearbyChatToastPanel::snapToMessageHeight	()
+void	LLFloaterIMNearbyChatToastPanel::snapToMessageHeight	()
 {
 	LLChatMsgBox* text_box = getChild<LLChatMsgBox>("msg_text", false);
 	S32 new_height = llmax (text_box->getTextPixelHeight() + 2*text_box->getVPad() + 2*msg_height_pad, 25);
@@ -281,22 +288,22 @@ void	LLNearbyChatToastPanel::snapToMessageHeight	()
 
 }
 
-void LLNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseLeave			(S32 x, S32 y, MASK mask)
 {
 	
 }
-void LLNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
+void LLFloaterIMNearbyChatToastPanel::onMouseEnter				(S32 x, S32 y, MASK mask)
 {
 	if(mSourceType != CHAT_SOURCE_AGENT)
 		return;
 }
 
-BOOL	LLNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseDown	(S32 x, S32 y, MASK mask)
 {
 	return LLPanel::handleMouseDown(x,y,mask);
 }
 
-BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 {
 	/*
 	fix for request  EXT-4780
@@ -316,16 +323,16 @@ BOOL	LLNearbyChatToastPanel::handleMouseUp	(S32 x, S32 y, MASK mask)
 			return TRUE;
 		else
 		{
-			LLNearbyChatBar::getInstance()->showHistory();
+			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
 			return FALSE;
 		}
 	}
 
-	LLNearbyChatBar::getInstance()->showHistory();
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->showHistory();
 	return LLPanel::handleMouseUp(x,y,mask);
 }
 
-void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
+void	LLFloaterIMNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 {
 	LLUICtrl* icon = getChild<LLUICtrl>("avatar_icon", false);
 	if(icon)
@@ -333,7 +340,7 @@ void	LLNearbyChatToastPanel::setHeaderVisibility(EShowItemHeader e)
 
 }
 
-bool	LLNearbyChatToastPanel::canAddText	()
+bool	LLFloaterIMNearbyChatToastPanel::canAddText	()
 {
 	LLChatMsgBox* msg_text = findChild<LLChatMsgBox>("msg_text");
 	if(!msg_text)
@@ -341,7 +348,7 @@ bool	LLNearbyChatToastPanel::canAddText	()
 	return msg_text->getLineCount()<10;
 }
 
-BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
+BOOL	LLFloaterIMNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	LLUICtrl* avatar_icon = getChild<LLUICtrl>("avatar_icon", false);
 
@@ -353,8 +360,10 @@ BOOL	LLNearbyChatToastPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
 		return TRUE;
 	return LLPanel::handleRightMouseDown(x,y,mask);
 }
-void LLNearbyChatToastPanel::draw()
+void LLFloaterIMNearbyChatToastPanel::draw()
 {
+	LLPanel::draw();
+
 	if(mIsDirty)
 	{
 		LLAvatarIconCtrl* icon = getChild<LLAvatarIconCtrl>("avatar_icon", false);
@@ -372,7 +381,6 @@ void LLNearbyChatToastPanel::draw()
 		}
 		mIsDirty = false;
 	}
-	LLToastPanelBase::draw();
 }
 
 
diff --git a/indra/newview/llchatitemscontainerctrl.h b/indra/newview/llchatitemscontainerctrl.h
index 1d700dcedefd0abbfd52c421852e6b2e9f9d1485..54b6499d52ff721768d9769625608094c1157b7e 100644
--- a/indra/newview/llchatitemscontainerctrl.h
+++ b/indra/newview/llchatitemscontainerctrl.h
@@ -40,18 +40,18 @@ typedef enum e_show_item_header
 	CHATITEMHEADER_SHOW_BOTH
 } EShowItemHeader;
 
-class LLNearbyChatToastPanel: public LLToastPanelBase
+class LLFloaterIMNearbyChatToastPanel : public LLPanel
 {
 protected:
-        LLNearbyChatToastPanel()
+        LLFloaterIMNearbyChatToastPanel()
 		: 
 	mIsDirty(false),
 	mSourceType(CHAT_SOURCE_OBJECT)
 	{};
 public:
-	~LLNearbyChatToastPanel(){}
+	~LLFloaterIMNearbyChatToastPanel(){}
 	
-	static LLNearbyChatToastPanel* createInstance();
+	static LLFloaterIMNearbyChatToastPanel* createInstance();
 
 	const LLUUID& getFromID() const { return mFromID;}
 	const std::string& getFromName() const { return mFromName; }
diff --git a/indra/newview/llchiclet.cpp b/indra/newview/llchiclet.cpp
index a661808d1ff4b0ad10c8f8310a81d390716ebbbd..88884042d4d0c482f65a1c1e5c1d84d3e483c6fb 100644
--- a/indra/newview/llchiclet.cpp
+++ b/indra/newview/llchiclet.cpp
@@ -27,35 +27,17 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 #include "llchiclet.h"
 
-#include "llagent.h"
-#include "llavataractions.h"
 #include "llchicletbar.h"
-#include "lleventtimer.h"
-#include "llgroupactions.h"
-#include "lliconctrl.h"
-#include "llimfloater.h"
-#include "llimview.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
 #include "llfloaterreg.h"
 #include "lllocalcliprect.h"
-#include "llmenugl.h"
-#include "llnotifications.h"
-#include "llnotificationsutil.h"
-#include "lloutputmonitorctrl.h"
 #include "llscriptfloater.h"
-#include "llspeakers.h"
-#include "lltextbox.h"
-#include "llvoiceclient.h"
-#include "llgroupmgr.h"
-#include "llnotificationmanager.h"
-#include "lltransientfloatermgr.h"
+#include "llsingleton.h"
 #include "llsyswellwindow.h"
 
 static LLDefaultChildRegistry::Register<LLChicletPanel> t1("chiclet_panel");
-static LLDefaultChildRegistry::Register<LLIMWellChiclet> t2_0("chiclet_im_well");
 static LLDefaultChildRegistry::Register<LLNotificationChiclet> t2("chiclet_notification");
-static LLDefaultChildRegistry::Register<LLIMP2PChiclet> t3("chiclet_im_p2p");
-static LLDefaultChildRegistry::Register<LLIMGroupChiclet> t4("chiclet_im_group");
-static LLDefaultChildRegistry::Register<LLAdHocChiclet> t5("chiclet_im_adhoc");
 static LLDefaultChildRegistry::Register<LLScriptChiclet> t6("chiclet_script");
 static LLDefaultChildRegistry::Register<LLInvOfferChiclet> t7("chiclet_offer");
 
@@ -66,65 +48,10 @@ boost::signals2::signal<LLChiclet* (const LLUUID&),
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-/**
- * Updates the Well's 'Lit' state to flash it when "new messages" are come.
- *
- * It gets callback which will be called 2*N times with passed period. See EXT-3147
- */
-class LLSysWellChiclet::FlashToLitTimer : public LLEventTimer
-{
-public:
-	typedef boost::function<void()> callback_t;
-
-	/**
-	 * Constructor.
-	 *
-	 * @param count - how many times callback should be called (twice to not change original state)
-	 * @param period - how frequently callback should be called
-	 * @param cb - callback to be called each tick
-	 */
-	FlashToLitTimer(S32 count, F32 period, callback_t cb)
-		: LLEventTimer(period)
-		, mCallback(cb)
-		, mFlashCount(2 * count)
-		, mCurrentFlashCount(0)
-	{
-		mEventTimer.stop();
-	}
-
-	BOOL tick()
-	{
-		mCallback();
-
-		if (++mCurrentFlashCount == mFlashCount) mEventTimer.stop();
-		return FALSE;
-	}
-
-	void flash()
-	{
-		mCurrentFlashCount = 0;
-		mEventTimer.start();
-	}
-
-	void stopFlashing()
-	{
-		mEventTimer.stop();
-	}
-
-private:
-	callback_t		mCallback;
-
-	/**
-	 * How many times Well will blink.
-	 */
-	S32 mFlashCount;
-	S32 mCurrentFlashCount;
-};
-
 LLSysWellChiclet::Params::Params()
-: button("button")
-, unread_notifications("unread_notifications")
-, max_displayed_count("max_displayed_count", 99)
+	: button("button")
+	, unread_notifications("unread_notifications")
+	, max_displayed_count("max_displayed_count", 99)
 {
 	button.name = "button";
 	button.tab_stop = FALSE;
@@ -132,30 +59,24 @@ LLSysWellChiclet::Params::Params()
 }
 
 LLSysWellChiclet::LLSysWellChiclet(const Params& p)
-: LLChiclet(p)
-, mButton(NULL)
-, mCounter(0)
-, mMaxDisplayedCount(p.max_displayed_count)
-, mIsNewMessagesState(false)
-, mFlashToLitTimer(NULL)
-, mContextMenu(NULL)
+	: LLChiclet(p)
+	, mButton(NULL)
+	, mCounter(0)
+	, mMaxDisplayedCount(p.max_displayed_count)
+	, mIsNewMessagesState(false)
+	, mFlashToLitTimer(NULL)
+	, mContextMenu(NULL)
 {
 	LLButton::Params button_params = p.button;
 	mButton = LLUICtrlFactory::create<LLButton>(button_params);
 	addChild(mButton);
 
-	// use settings from settings.xml to be able change them via Debug settings. See EXT-5973.
-	// Due to Timer is implemented as derived class from EventTimer it is impossible to change period
-	// in runtime. So, both settings are made as required restart.
-	static S32 flash_to_lit_count = gSavedSettings.getS32("WellIconFlashCount");
-	static F32 flash_period = gSavedSettings.getF32("WellIconFlashPeriod");
-
-	mFlashToLitTimer = new FlashToLitTimer(flash_to_lit_count, flash_period, boost::bind(&LLSysWellChiclet::changeLitState, this));
+	mFlashToLitTimer = new LLFlashTimer(boost::bind(&LLSysWellChiclet::changeLitState, this, _1));
 }
 
 LLSysWellChiclet::~LLSysWellChiclet()
 {
-	delete mFlashToLitTimer;
+	mFlashToLitTimer->unset();
 }
 
 void LLSysWellChiclet::setCounter(S32 counter)
@@ -190,7 +111,7 @@ void LLSysWellChiclet::setToggleState(BOOL toggled) {
 	mButton->setToggleState(toggled);
 }
 
-void LLSysWellChiclet::changeLitState()
+void LLSysWellChiclet::changeLitState(bool blink)
 {
 	setNewMessagesState(!mIsNewMessagesState);
 }
@@ -234,137 +155,26 @@ BOOL LLSysWellChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
-/************************************************************************/
-/*               LLIMWellChiclet implementation                         */
-/************************************************************************/
-LLIMWellChiclet::LLIMWellChiclet(const Params& p)
-: LLSysWellChiclet(p)
-{
-	LLIMModel::instance().addNewMsgCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
-	LLIMModel::instance().addNoUnreadMsgsCallback(boost::bind(&LLIMWellChiclet::messageCountChanged, this, _1));
-
-	LLIMMgr::getInstance()->addSessionObserver(this);
-
-	LLIMWellWindow::getInstance()->setSysWellChiclet(this);
-}
-
-LLIMWellChiclet::~LLIMWellChiclet()
-{
-	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
-	if (im_well_window)
-	{
-		im_well_window->setSysWellChiclet(NULL);
-	}
-
-	LLIMMgr::getInstance()->removeSessionObserver(this);
-}
-
-void LLIMWellChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string action = user_data.asString();
-	if("close all" == action)
-	{
-		LLIMWellWindow::getInstance()->closeAll();
-	}
-}
-
-bool LLIMWellChiclet::enableMenuItem(const LLSD& user_data)
-{
-	std::string item = user_data.asString();
-	if (item == "can close all")
-	{
-		return !LLIMWellWindow::getInstance()->isWindowEmpty();
-	}
-	return true;
-}
-
-void LLIMWellChiclet::createMenu()
-{
-	if(mContextMenu)
-	{
-		llwarns << "Menu already exists" << llendl;
-		return;
-	}
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMWellChicletMenu.Action",
-		boost::bind(&LLIMWellChiclet::onMenuItemClicked, this, _2));
-
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	enable_registrar.add("IMWellChicletMenu.EnableItem",
-		boost::bind(&LLIMWellChiclet::enableMenuItem, this, _2));
-
-	mContextMenu = LLUICtrlFactory::getInstance()->createFromFile<LLContextMenu>
-		("menu_im_well_button.xml",
-		 LLMenuGL::sMenuContainer,
-		 LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMWellChiclet::messageCountChanged(const LLSD& session_data)
-{
-	// The singleton class LLChicletBar instance might be already deleted
-	// so don't create a new one.
-	if (!LLChicletBar::instanceExists())
-	{
-		return;
-	}
-
-	const LLUUID& session_id = session_data["session_id"];
-	const S32 counter = LLChicletBar::getInstance()->getTotalUnreadIMCount();
-	const bool im_not_visible = !LLFloaterReg::instanceVisible("im_container")
-		&& !LLFloaterReg::instanceVisible("impanel", session_id);
-
-	setNewMessagesState(counter > mCounter	&& im_not_visible);
-
-	// we have to flash to 'Lit' state each time new unread message is coming.
-	if (counter > mCounter && im_not_visible)
-	{
-		mFlashToLitTimer->flash();
-	}
-	else if (counter == 0)
-	{
-		// if notification is resolved while well is flashing it can leave in the 'Lit' state
-		// when flashing finishes itself. Let break flashing here.
-		mFlashToLitTimer->stopFlashing();
-	}
-
-	setCounter(counter);
-}
-
 /************************************************************************/
 /*               LLNotificationChiclet implementation                   */
 /************************************************************************/
 LLNotificationChiclet::LLNotificationChiclet(const Params& p)
-: LLSysWellChiclet(p)
-, mUreadSystemNotifications(0)
+:	LLSysWellChiclet(p),
+	mUreadSystemNotifications(0)
 {
-	// connect counter handlers to the signals
-	connectCounterUpdatersToSignal("notify");
-	connectCounterUpdatersToSignal("groupnotify");
-	connectCounterUpdatersToSignal("offer");
-
+	mNotificationChannel.reset(new ChicletNotificationChannel(this));
 	// ensure that notification well window exists, to synchronously
 	// handle toast add/delete events.
 	LLNotificationWellWindow::getInstance()->setSysWellChiclet(this);
 }
 
-void LLNotificationChiclet::connectCounterUpdatersToSignal(const std::string& notification_type)
-{
-	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
-	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
-	if(n_handler)
-	{
-		n_handler->setNewNotificationCallback(boost::bind(&LLNotificationChiclet::incUreadSystemNotifications, this));
-		n_handler->setDelNotification(boost::bind(&LLNotificationChiclet::decUreadSystemNotifications, this));
-	}
-}
-
 void LLNotificationChiclet::onMenuItemClicked(const LLSD& user_data)
 {
 	std::string action = user_data.asString();
 	if("close all" == action)
 	{
 		LLNotificationWellWindow::getInstance()->closeAll();
+		LLIMWellWindow::getInstance()->closeAll();
 	}
 }
 
@@ -407,6 +217,23 @@ void LLNotificationChiclet::setCounter(S32 counter)
 	updateWidget(getCounter() == 0);
 	
 }
+
+bool LLNotificationChiclet::ChicletNotificationChannel::filterNotification( LLNotificationPtr notification )
+{
+	if (notification->getName() == "ScriptDialog")
+	{
+		return false;
+	}
+
+	if( !(notification->canLogToIM() && notification->hasFormElements())
+		&& (!notification->getPayload().has("give_inventory_notification")
+			|| notification->getPayload()["give_inventory_notification"]))
+	{
+		return true;
+	}
+	return false;
+}
+
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -422,12 +249,6 @@ LLChiclet::LLChiclet(const Params& p)
 , mSessionId(LLUUID::null)
 , mShowCounter(p.show_counter)
 {
-
-}
-
-LLChiclet::~LLChiclet()
-{
-
 }
 
 boost::signals2::connection LLChiclet::setLeftButtonClickCallback(
@@ -462,7 +283,9 @@ LLSD LLChiclet::getValue() const
 void LLChiclet::setValue(const LLSD& value)
 {
 	if(value.isUUID())
+	{
 		setSessionId(value.asUUID());
+	}
 }
 
 //////////////////////////////////////////////////////////////////////////
@@ -474,12 +297,9 @@ LLIMChiclet::LLIMChiclet(const LLIMChiclet::Params& p)
 , mShowSpeaker(false)
 , mDefaultWidth(p.rect().getWidth())
 , mNewMessagesIcon(NULL)
-, mSpeakerCtrl(NULL)
-, mCounterCtrl(NULL)
 , mChicletButton(NULL)
 , mPopupMenu(NULL)
 {
-	enableCounterControl(p.enable_counter);
 }
 
 /* virtual*/
@@ -490,16 +310,6 @@ BOOL LLIMChiclet::postBuild()
 	mChicletButton->setDoubleClickCallback(boost::bind(&LLIMChiclet::onMouseDown, this));
 	return TRUE;
 }
-void LLIMChiclet::setShowSpeaker(bool show)
-{
-	bool needs_resize = getShowSpeaker() != show;
-	if(needs_resize)
-	{		
-		mShowSpeaker = show;
-	}
-
-	toggleSpeakerControl();
-}
 
 void LLIMChiclet::enableCounterControl(bool enable) 
 {
@@ -510,87 +320,13 @@ void LLIMChiclet::enableCounterControl(bool enable)
 	}
 }
 
-void LLIMChiclet::setShowCounter(bool show)
-{
-	if(!mCounterEnabled)
-	{
-		return;
-	}
-
-	bool needs_resize = getShowCounter() != show;
-	if(needs_resize)
-	{		
-		LLChiclet::setShowCounter(show);
-		toggleCounterControl();
-	}
-}
-
-void LLIMChiclet::initSpeakerControl()
-{
-	// virtual
-}
-
 void LLIMChiclet::setRequiredWidth()
 {
-	bool show_speaker = getShowSpeaker();
-	bool show_counter = getShowCounter();
 	S32 required_width = mDefaultWidth;
-
-	if (show_counter)
-	{
-		required_width += mCounterCtrl->getRect().getWidth();
-	}
-	if (show_speaker)
-	{
-		required_width += mSpeakerCtrl->getRect().getWidth();
-	} 
-
 	reshape(required_width, getRect().getHeight());
-
 	onChicletSizeChanged();
 }
 
-void LLIMChiclet::toggleSpeakerControl()
-{
-	if(getShowSpeaker())
-	{
-		// move speaker to the right of chiclet icon
-		LLRect speaker_rc = mSpeakerCtrl->getRect();
-		speaker_rc.setLeftTopAndSize(mDefaultWidth, speaker_rc.mTop, speaker_rc.getWidth(), speaker_rc.getHeight());
-		mSpeakerCtrl->setRect(speaker_rc);
-
-		if(getShowCounter())
-		{
-			// move speaker to the right of counter
-			mSpeakerCtrl->translate(mCounterCtrl->getRect().getWidth(), 0);
-		}
-
-		initSpeakerControl();		
-	}
-
-	setRequiredWidth();
-	mSpeakerCtrl->setSpeakerId(LLUUID::null);
-	mSpeakerCtrl->setVisible(getShowSpeaker());
-}
-
-void LLIMChiclet::setCounter(S32 counter)
-{
-	if (mCounterCtrl->getCounter() == counter)
-	{
-		return;
-	}
-
-	mCounterCtrl->setCounter(counter);
-	setShowCounter(counter);
-	setShowNewMessagesIcon(counter);
-}
-
-void LLIMChiclet::toggleCounterControl()
-{
-	setRequiredWidth();
-	mCounterCtrl->setVisible(getShowCounter());
-}
-
 void LLIMChiclet::setShowNewMessagesIcon(bool show)
 {
 	if(mNewMessagesIcon)
@@ -607,8 +343,7 @@ bool LLIMChiclet::getShowNewMessagesIcon()
 
 void LLIMChiclet::onMouseDown()
 {
-	LLIMFloater::toggle(getSessionId());
-	setCounter(0);
+	LLFloaterIMSession::toggle(getSessionId());
 }
 
 void LLIMChiclet::setToggleState(bool toggle)
@@ -616,52 +351,6 @@ void LLIMChiclet::setToggleState(bool toggle)
 	mChicletButton->setToggleState(toggle);
 }
 
-void LLIMChiclet::draw()
-{
-	LLUICtrl::draw();
-}
-
-// static
-LLIMChiclet::EType LLIMChiclet::getIMSessionType(const LLUUID& session_id)
-{
-	EType				type	= TYPE_UNKNOWN;
-
-	if(session_id.isNull())
-		return type;
-
-	EInstantMessage im_type = LLIMModel::getInstance()->getType(session_id);
-	if (IM_COUNT == im_type)
-	{
-		llassert_always(0 && "IM session not found"); // should never happen
-		return type;
-	}
-
-	switch(im_type)
-	{
-	case IM_NOTHING_SPECIAL:
-	case IM_SESSION_P2P_INVITE:
-		type = TYPE_IM;
-		break;
-	case IM_SESSION_GROUP_START:
-	case IM_SESSION_INVITE:
-		if (gAgent.isInGroup(session_id))
-		{
-			type = TYPE_GROUP;
-		}
-		else
-		{
-			type = TYPE_AD_HOC;
-		}
-		break;
-	case IM_SESSION_CONFERENCE_START:
-		type = TYPE_AD_HOC;
-	default:
-		break;
-	}
-
-	return type;
-}
-
 BOOL LLIMChiclet::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	if(!mPopupMenu)
@@ -693,382 +382,6 @@ bool LLIMChiclet::canCreateMenu()
 	return true;
 }
 
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLIMP2PChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMP2PChiclet::LLIMP2PChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-void LLIMP2PChiclet::initSpeakerControl()
-{
-	mSpeakerCtrl->setSpeakerId(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::setOtherParticipantId(const LLUUID& other_participant_id)
-{
-	LLIMChiclet::setOtherParticipantId(other_participant_id);
-	mChicletIconCtrl->setValue(getOtherParticipantId());
-}
-
-void LLIMP2PChiclet::updateMenuItems()
-{
-	if(!mPopupMenu)
-		return;
-	if(getSessionId().isNull())
-		return;
-
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
-	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
-	mPopupMenu->getChild<LLUICtrl>("Send IM")->setEnabled(!open_window_exists);
-	
-	bool is_friend = LLAvatarActions::isFriend(getOtherParticipantId());
-	mPopupMenu->getChild<LLUICtrl>("Add Friend")->setEnabled(!is_friend);
-}
-
-void LLIMP2PChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMP2PChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_p2p.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMP2PChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID other_participant_id = getOtherParticipantId();
-
-	if("profile" == level)
-	{
-		LLAvatarActions::showProfile(other_participant_id);
-	}
-	else if("im" == level)
-	{
-		LLAvatarActions::startIM(other_participant_id);
-	}
-	else if("add" == level)
-	{
-		LLAvatarActions::requestFriendshipDialog(other_participant_id);
-	}
-	else if("end" == level)
-	{
-		LLAvatarActions::endIM(other_participant_id);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLAdHocChiclet::Params::Params()
-: avatar_icon("avatar_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-, avatar_icon_color("avatar_icon_color", LLColor4::green)
-{
-}
-
-LLAdHocChiclet::LLAdHocChiclet(const Params& p)
-: LLIMChiclet(p)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletAvatarIconCtrl::Params avatar_params = p.avatar_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletAvatarIconCtrl>(avatar_params);
-	//Make the avatar modified
-	mChicletIconCtrl->setColor(p.avatar_icon_color);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-void LLAdHocChiclet::setSessionId(const LLUUID& session_id)
-{
-	LLChiclet::setSessionId(session_id);
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(session_id);
-	mChicletIconCtrl->setValue(im_session->mOtherParticipantID);
-}
-
-void LLAdHocChiclet::draw()
-{
-	switchToCurrentSpeaker();
-	LLIMChiclet::draw();
-}
-
-void LLAdHocChiclet::initSpeakerControl()
-{
-	switchToCurrentSpeaker();
-}
-
-void LLAdHocChiclet::switchToCurrentSpeaker()
-{
-	LLUUID speaker_id;
-	LLSpeakerMgr::speaker_list_t speaker_list;
-
-	LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			speaker_id = s->mID;
-			break;
-		}
-	}
-
-	mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLAdHocChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLAdHocChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_adhoc.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLAdHocChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID group_id = getSessionId();
-
-	if("end" == level)
-	{
-		LLGroupActions::endIM(group_id);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
-LLIMGroupChiclet::Params::Params()
-: group_icon("group_icon")
-, chiclet_button("chiclet_button")
-, unread_notifications("unread_notifications")
-, speaker("speaker")
-, new_message_icon("new_message_icon")
-, show_speaker("show_speaker")
-{
-}
-
-LLIMGroupChiclet::LLIMGroupChiclet(const Params& p)
-: LLIMChiclet(p)
-, LLGroupMgrObserver(LLUUID::null)
-, mChicletIconCtrl(NULL)
-{
-	LLButton::Params button_params = p.chiclet_button;
-	mChicletButton = LLUICtrlFactory::create<LLButton>(button_params);
-	addChild(mChicletButton);
-
-	LLIconCtrl::Params new_msg_params = p.new_message_icon;
-	mNewMessagesIcon = LLUICtrlFactory::create<LLIconCtrl>(new_msg_params);
-	addChild(mNewMessagesIcon);
-
-	LLChicletGroupIconCtrl::Params avatar_params = p.group_icon;
-	mChicletIconCtrl = LLUICtrlFactory::create<LLChicletGroupIconCtrl>(avatar_params);
-	addChild(mChicletIconCtrl);
-
-	LLChicletNotificationCounterCtrl::Params unread_params = p.unread_notifications;
-	mCounterCtrl = LLUICtrlFactory::create<LLChicletNotificationCounterCtrl>(unread_params);
-	addChild(mCounterCtrl);
-
-	setCounter(getCounter());
-	setShowCounter(getShowCounter());
-
-	LLChicletSpeakerCtrl::Params speaker_params = p.speaker;
-	mSpeakerCtrl = LLUICtrlFactory::create<LLChicletSpeakerCtrl>(speaker_params);
-	addChild(mSpeakerCtrl);
-
-	sendChildToFront(mNewMessagesIcon);
-	setShowSpeaker(p.show_speaker);
-}
-
-LLIMGroupChiclet::~LLIMGroupChiclet()
-{
-	LLGroupMgr::getInstance()->removeObserver(this);
-}
-
-void LLIMGroupChiclet::draw()
-{
-	if(getShowSpeaker())
-	{
-		switchToCurrentSpeaker();
-	}
-	LLIMChiclet::draw();
-}
-
-void LLIMGroupChiclet::initSpeakerControl()
-{
-	switchToCurrentSpeaker();
-}
-
-void LLIMGroupChiclet::switchToCurrentSpeaker()
-{
-	LLUUID speaker_id;
-	LLSpeakerMgr::speaker_list_t speaker_list;
-
-	LLIMModel::getInstance()->findIMSession(getSessionId())->mSpeakers->getSpeakerList(&speaker_list, FALSE);
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			speaker_id = s->mID;
-			break;
-		}
-	}
-
-	mSpeakerCtrl->setSpeakerId(speaker_id);
-}
-
-void LLIMGroupChiclet::setSessionId(const LLUUID& session_id)
-{
-	LLChiclet::setSessionId(session_id);
-
-	LLGroupMgr* grp_mgr = LLGroupMgr::getInstance();
-	LLGroupMgrGroupData* group_data = grp_mgr->getGroupData(session_id);
-	if (group_data && group_data->mInsigniaID.notNull())
-	{
-		mChicletIconCtrl->setValue(group_data->mInsigniaID);
-	}
-	else
-	{
-		if(getSessionId() != mID)
-		{
-			grp_mgr->removeObserver(this);
-			mID = getSessionId();
-			grp_mgr->addObserver(this);
-		}
-		grp_mgr->sendGroupPropertiesRequest(session_id);
-	}
-}
-
-void LLIMGroupChiclet::changed(LLGroupChange gc)
-{
-	if (GC_PROPERTIES == gc)
-	{
-		LLGroupMgrGroupData* group_data = LLGroupMgr::getInstance()->getGroupData(getSessionId());
-		if (group_data)
-		{
-			mChicletIconCtrl->setValue(group_data->mInsigniaID);
-		}
-	}
-}
-
-void LLIMGroupChiclet::updateMenuItems()
-{
-	if(!mPopupMenu)
-		return;
-	if(getSessionId().isNull())
-		return;
-
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(getSessionId());
-	bool open_window_exists = open_im_floater && open_im_floater->getVisible();
-	mPopupMenu->getChild<LLUICtrl>("Chat")->setEnabled(!open_window_exists);
-}
-
-void LLIMGroupChiclet::createPopupMenu()
-{
-	if(!canCreateMenu())
-		return;
-
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	registrar.add("IMChicletMenu.Action", boost::bind(&LLIMGroupChiclet::onMenuItemClicked, this, _2));
-
-	mPopupMenu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>
-		("menu_imchiclet_group.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-}
-
-void LLIMGroupChiclet::onMenuItemClicked(const LLSD& user_data)
-{
-	std::string level = user_data.asString();
-	LLUUID group_id = getSessionId();
-
-	if("group chat" == level)
-	{
-		LLGroupActions::startIM(group_id);
-	}
-	else if("info" == level)
-	{
-		LLGroupActions::show(group_id);
-	}
-	else if("end" == level)
-	{
-		LLGroupActions::endIM(group_id);
-	}
-}
-
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -1115,28 +428,15 @@ LLChicletPanel::~LLChicletPanel()
 
 void LLChicletPanel::onMessageCountChanged(const LLSD& data)
 {
-	LLUUID session_id = data["session_id"].asUUID();
-	S32 unread = data["participant_unread"].asInteger();
+    // *TODO : we either suppress this method or return a value. Right now, it servers no purpose.
+    /*
 
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
-	if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
-	{
-		unread = 0;
-	}
-
-	std::list<LLChiclet*> chiclets = LLIMChiclet::sFindChicletsSignal(session_id);
-	std::list<LLChiclet *>::iterator iter;
-	for (iter = chiclets.begin(); iter != chiclets.end(); iter++) {
-		LLChiclet* chiclet = *iter;
-		if (chiclet != NULL)
-		{
-			chiclet->setCounter(unread);
-		}
-	    else
-	    {
-	    	llwarns << "Unable to set counter for chiclet " << session_id << llendl;
-	    }
-	}
+	//LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
+	//if (im_floater && im_floater->getVisible() && im_floater->hasFocus())
+	//{
+	//	unread = 0;
+	//}
+    */
 }
 
 void LLChicletPanel::objectChicletCallback(const LLSD& data)
@@ -1151,10 +451,6 @@ void LLChicletPanel::objectChicletCallback(const LLSD& data)
 		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*iter);
 		if (chiclet != NULL)
 		{
-			if(data.has("unread"))
-			{
-				chiclet->setCounter(data["unread"]);
-			}
 			chiclet->setShowNewMessagesIcon(new_message);
 		}
 	}
@@ -1196,28 +492,13 @@ void LLChicletPanel::onCurrentVoiceChannelChanged(const LLUUID& session_id)
 		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
 		if(chiclet)
 		{
-			chiclet->setShowSpeaker(true);
 			if (gSavedSettings.getBOOL("OpenIMOnVoice"))
 			{
-				LLIMFloater::show(chiclet->getSessionId());
+				LLFloaterIMContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
 
-	if(!s_previous_active_voice_session_id.isNull() && s_previous_active_voice_session_id != session_id)
-	{
-		chiclets = LLIMChiclet::sFindChicletsSignal(s_previous_active_voice_session_id);
-
-		for(std::list<LLChiclet *>::iterator it = chiclets.begin(); it != chiclets.end(); ++it)
-		{
-			LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-			if(chiclet)
-			{
-				chiclet->setShowSpeaker(false);
-			}
-		}		
-	}
-
 	s_previous_active_voice_session_id = session_id;
 }
 
@@ -1690,7 +971,7 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 	for (chiclet_list_t::iterator it = mChicletList.begin(); it
 			!= mChicletList.end(); it++)
 	{
-		LLIMFloater* im_floater = LLFloaterReg::findTypedInstance<LLIMFloater>(
+		LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
 				"impanel", (*it)->getSessionId());
 		if (im_floater != NULL && im_floater->getVisible()
 				&& !im_floater->isMinimized() && im_floater->isDocked())
@@ -1703,89 +984,17 @@ bool LLChicletPanel::isAnyIMFloaterDoked()
 	return res;
 }
 
-S32 LLChicletPanel::getTotalUnreadIMCount()
-{
-	S32 count = 0;
-	chiclet_list_t::const_iterator it = mChicletList.begin();
-	for( ; mChicletList.end() != it; ++it)
-	{
-		LLIMChiclet* chiclet = dynamic_cast<LLIMChiclet*>(*it);
-		if(chiclet)
-		{
-			count += chiclet->getCounter();
-		}
-	}
-	return count;
-}
-
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 LLChicletNotificationCounterCtrl::Params::Params()
-: max_displayed_count("max_displayed_count", 99)
-{
-}
-
-LLChicletNotificationCounterCtrl::LLChicletNotificationCounterCtrl(const Params& p)
- : LLTextBox(p)
- , mCounter(0)
- , mInitialWidth(0)
- , mMaxDisplayedCount(p.max_displayed_count)
+	: max_displayed_count("max_displayed_count", 99)
 {
-	mInitialWidth = getRect().getWidth();
-}
-
-void LLChicletNotificationCounterCtrl::setCounter(S32 counter)
-{
-	mCounter = counter;
-
-	// note same code in LLSysWellChiclet::setCounter(S32 counter)
-	std::string s_count;
-	if(counter != 0)
-	{
-		static std::string more_messages_exist("+");
-		std::string more_messages(counter > mMaxDisplayedCount ? more_messages_exist : "");
-		s_count = llformat("%d%s"
-			, llmin(counter, mMaxDisplayedCount)
-			, more_messages.c_str()
-			);
-	}
-
-	if(mCounter != 0)
-	{
-		setText(s_count);
-	}
-	else
-	{
-		setText(std::string(""));
-	}
-}
-
-LLRect LLChicletNotificationCounterCtrl::getRequiredRect()
-{
-	LLRect rc;
-	S32 text_width = getTextPixelWidth();
-
-	rc.mRight = rc.mLeft + llmax(text_width, mInitialWidth);
-	
-	return rc;
-}
-
-void LLChicletNotificationCounterCtrl::setValue(const LLSD& value)
-{
-	if(value.isInteger())
-		setCounter(value.asInteger());
-}
-
-LLSD LLChicletNotificationCounterCtrl::getValue() const
-{
-	return LLSD(getCounter());
 }
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
-
 LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
  : LLAvatarIconCtrl(p)
 {
@@ -1795,29 +1004,6 @@ LLChicletAvatarIconCtrl::LLChicletAvatarIconCtrl(const Params& p)
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLChicletGroupIconCtrl::LLChicletGroupIconCtrl(const Params& p)
-: LLIconCtrl(p)
-, mDefaultIcon(p.default_icon)
-{
-	setValue(LLUUID::null);
-}
-
-void LLChicletGroupIconCtrl::setValue(const LLSD& value )
-{
-	if(value.asUUID().isNull())
-	{
-		LLIconCtrl::setValue(mDefaultIcon);
-	}
-	else
-	{
-		LLIconCtrl::setValue(value);
-	}
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 LLChicletInvOfferIconCtrl::LLChicletInvOfferIconCtrl(const Params& p)
 : LLChicletAvatarIconCtrl(p)
  , mDefaultIcon(p.default_icon)
@@ -1840,15 +1026,6 @@ void LLChicletInvOfferIconCtrl::setValue(const LLSD& value )
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
 
-LLChicletSpeakerCtrl::LLChicletSpeakerCtrl(const Params&p)
- : LLOutputMonitorCtrl(p)
-{
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-
 LLScriptChiclet::Params::Params()
  : icon("icon")
  , chiclet_button("chiclet_button")
@@ -1884,11 +1061,6 @@ void LLScriptChiclet::setSessionId(const LLUUID& session_id)
 	setToolTip(LLScriptFloaterManager::getObjectName(session_id));
 }
 
-void LLScriptChiclet::setCounter(S32 counter)
-{
-	setShowNewMessagesIcon( counter > 0 );
-}
-
 void LLScriptChiclet::onMouseDown()
 {
 	LLScriptFloaterManager::getInstance()->toggleScriptFloater(getSessionId());
@@ -1967,11 +1139,6 @@ void LLInvOfferChiclet::setSessionId(const LLUUID& session_id)
 	}
 }
 
-void LLInvOfferChiclet::setCounter(S32 counter)
-{
-	setShowNewMessagesIcon( counter > 0 );
-}
-
 void LLInvOfferChiclet::onMouseDown()
 {
 	LLScriptFloaterManager::instance().toggleScriptFloater(getSessionId());
diff --git a/indra/newview/llchiclet.h b/indra/newview/llchiclet.h
index 19683492c230e72968294a94ea56b989f2dd31b7..efaf03384ae3d186887c4b1eb6f29d60c6a83b5f 100644
--- a/indra/newview/llchiclet.h
+++ b/indra/newview/llchiclet.h
@@ -29,14 +29,11 @@
 
 #include "llavatariconctrl.h"
 #include "llbutton.h"
-#include "llpanel.h"
+#include "llnotifications.h"
 #include "lltextbox.h"
-#include "lloutputmonitorctrl.h"
-#include "llgroupmgr.h"
-#include "llimview.h"
 
 class LLMenuGL;
-class LLIMFloater;
+class LLFloaterIMSession;
 
 /**
  * Class for displaying amount of messages/notifications(unread).
@@ -48,11 +45,11 @@ class LLChicletNotificationCounterCtrl : public LLTextBox
 	struct Params :	public LLInitParam::Block<Params, LLTextBox::Params>
 	{
 		/**
-		* Contains maximum displayed count of unread messages. Default value is 9.
-		*
-		* If count is less than "max_unread_count" will be displayed as is.
-		* Otherwise 9+ will be shown (for default value).
-		*/
+		 * Contains maximum displayed count of unread messages. Default value is 9.
+		 *
+		 * If count is less than "max_unread_count" will be displayed as is.
+		 * Otherwise 9+ will be shown (for default value).
+		 */
 		Optional<S32> max_displayed_count;
 
 		Params();
@@ -119,35 +116,6 @@ class LLChicletAvatarIconCtrl : public LLAvatarIconCtrl
 	friend class LLUICtrlFactory;
 };
 
-/**
- * Class for displaying group's icon in Group chiclet.
- */
-class LLChicletGroupIconCtrl : public LLIconCtrl
-{
-public:
-
-	struct Params :	public LLInitParam::Block<Params, LLIconCtrl::Params>
-	{
-		Optional<std::string> default_icon;
-
-		Params()
-		:	default_icon("default_icon", "Generic_Group")
-		{}
-	};
-
-	/**
-	 * Sets icon, if value is LLUUID::null - default icon will be set.
-	 */
-	virtual void setValue(const LLSD& value );
-
-protected:
-
-	LLChicletGroupIconCtrl(const Params& p);
-	friend class LLUICtrlFactory;
-
-	std::string mDefaultIcon;
-};
-
 /**
  * Class for displaying icon in inventory offer chiclet.
  */
@@ -181,23 +149,6 @@ class LLChicletInvOfferIconCtrl : public LLChicletAvatarIconCtrl
 	std::string mDefaultIcon;
 };
 
-/**
- * Class for displaying of speaker's voice indicator 
- */
-class LLChicletSpeakerCtrl : public LLOutputMonitorCtrl
-{
-public:
-
-	struct Params : public LLInitParam::Block<Params, LLOutputMonitorCtrl::Params>
-	{
-		Params(){};
-	};
-protected:
-
-	LLChicletSpeakerCtrl(const Params&p);
-	friend class LLUICtrlFactory;
-};
-
 /**
  * Base class for all chiclets.
  */
@@ -213,7 +164,7 @@ class LLChiclet : public LLUICtrl
 		Params();
 	};
 
-	/*virtual*/ ~LLChiclet();
+	virtual ~LLChiclet() {}
 
 	/**
 	 * Associates chat session id with chiclet.
@@ -225,26 +176,11 @@ class LLChiclet : public LLUICtrl
 	 */
 	virtual const LLUUID& getSessionId() const { return mSessionId; }
 
-	/**
-	 * Sets number of unread notifications.
-	 */
-	virtual void setCounter(S32 counter) = 0;
-
-	/**
-	 * Returns number of unread notifications.
-	 */
-	virtual S32 getCounter() = 0;
-
 	/**
 	 * Sets show counter state.
 	 */
 	virtual void setShowCounter(bool show) { mShowCounter = show; }
 
-	/**
-	 * Returns show counter state.
-	 */
-	virtual bool getShowCounter() {return mShowCounter;};
-
 	/**
 	 * Connects chiclet clicked event with callback.
 	 */
@@ -322,6 +258,7 @@ class LLIMChiclet : public LLChiclet
 	 * It is used for default setting up of chicklet:click handler, etc.  
 	 */
 	BOOL postBuild();
+
 	/**
 	 * Sets IM session name. This name will be displayed in chiclet tooltip.
 	 */
@@ -334,51 +271,10 @@ class LLIMChiclet : public LLChiclet
 	virtual void setOtherParticipantId(const LLUUID& other_participant_id) { mOtherParticipantId = other_participant_id; }
 
 	/**
-	 * Gets id of person/group user is chatting with.
+	 * Enables/disables the counter control for a chiclet.
 	 */
-	virtual LLUUID getOtherParticipantId() { return mOtherParticipantId; }
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	virtual void initSpeakerControl();
-
-	/**
-	 * set status (Shows/Hide) for voice control.
-	 */
-	virtual void setShowSpeaker(bool show);
-
-	/**
-	 * Returns voice chat status control visibility.
-	 */
-	virtual bool getShowSpeaker() {return mShowSpeaker;};
-
-	/**
-	 * Shows/Hides for voice control for a chiclet.
-	 */
-	virtual void toggleSpeakerControl();
-
-	/**
-	* Sets number of unread messages. Will update chiclet's width if number text 
-	* exceeds size of counter and notify it's parent about size change.
-	*/
-	virtual void setCounter(S32);
-
-	/**
-	* Enables/disables the counter control for a chiclet.
-	*/
 	virtual void enableCounterControl(bool enable);
 
-	/**
-	* Sets show counter state.
-	*/
-	virtual void setShowCounter(bool show);
-
-	/**
-	* Shows/Hides for counter control for a chiclet.
-	*/
-	virtual void toggleCounterControl();
-
 	/**
 	* Sets required width for a chiclet according to visible controls.
 	*/
@@ -394,21 +290,6 @@ class LLIMChiclet : public LLChiclet
 	 */
 	virtual bool getShowNewMessagesIcon();
 
-	virtual void draw();
-
-	/**
-	 * Determine whether given ID refers to a group or an IM chat session.
-	 * 
-	 * This is used when we need to chose what IM chiclet (P2P/group)
-	 * class to instantiate.
-	 * 
-	 * @param session_id session ID.
-	 * @return TYPE_GROUP in case of group chat session,
-	 *         TYPE_IM in case of P2P session,
-	 *         TYPE_UNKNOWN otherwise.
-	 */
-	static EType getIMSessionType(const LLUUID& session_id);
-
 	/**
 	 * The action taken on mouse down event.
 	 * 
@@ -450,8 +331,6 @@ class LLIMChiclet : public LLChiclet
 	S32 mDefaultWidth;
 
 	LLIconCtrl* mNewMessagesIcon;
-	LLChicletNotificationCounterCtrl* mCounterCtrl;
-	LLChicletSpeakerCtrl* mSpeakerCtrl;
 	LLButton* mChicletButton;
 
 	/** the id of another participant, either an avatar id or a group id*/
@@ -479,137 +358,6 @@ class LLIMChiclet : public LLChiclet
 			sFindChicletsSignal;
 };
 
-/**
- * Implements P2P chiclet.
- */
-class LLIMP2PChiclet : public LLIMChiclet
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Params();
-	};
-
-	/* virtual */ void setOtherParticipantId(const LLUUID& other_participant_id);
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
-	LLIMP2PChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/** 
-	 * Enables/disables menus based on relationship with other participant.
-	 * Enables/disables "show session" menu item depending on visible IM floater existence.
-	 */
-	virtual void updateMenuItems();
-
-private:
-
-	LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
-
-/**
- * Implements AD-HOC chiclet.
- */
-class LLAdHocChiclet : public LLIMChiclet
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletAvatarIconCtrl::Params> avatar_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Optional<LLColor4>	avatar_icon_color;
-
-		Params();
-	};
-
-	/**
-	 * Sets session id.
-	 * Session ID for group chat is actually Group ID.
-	 */
-	/*virtual*/ void setSessionId(const LLUUID& session_id);
-
-	/**
-	 * Keep Speaker Control with actual speaker's ID
-	 */
-	/*virtual*/ void draw();
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-protected:
-	LLAdHocChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Creates chiclet popup menu. Will create AdHoc Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
-	 */
-	/*virtual*/ void switchToCurrentSpeaker();
-
-private:
-
-	LLChicletAvatarIconCtrl* mChicletIconCtrl;
-};
 
 /**
  * Chiclet for script floaters.
@@ -631,10 +379,6 @@ class LLScriptChiclet : public LLIMChiclet
 
 	/*virtual*/ void setSessionId(const LLUUID& session_id);
 
-	/*virtual*/ void setCounter(S32 counter);
-
-	/*virtual*/ S32 getCounter() { return 0; }
-
 	/**
 	 * Toggle script floater
 	 */
@@ -680,10 +424,6 @@ class LLInvOfferChiclet: public LLIMChiclet
 
 	/*virtual*/ void setSessionId(const LLUUID& session_id);
 
-	/*virtual*/ void setCounter(S32 counter);
-
-	/*virtual*/ S32 getCounter() { return 0; }
-
 	/**
 	 * Toggle script floater
 	 */
@@ -707,89 +447,6 @@ class LLInvOfferChiclet: public LLIMChiclet
 	LLChicletInvOfferIconCtrl* mChicletIconCtrl;
 };
 
-/**
- * Implements Group chat chiclet.
- */
-class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
-{
-public:
-
-	struct Params : public LLInitParam::Block<Params, LLIMChiclet::Params>
-	{
-		Optional<LLButton::Params> chiclet_button;
-
-		Optional<LLChicletGroupIconCtrl::Params> group_icon;
-
-		Optional<LLChicletNotificationCounterCtrl::Params> unread_notifications;
-
-		Optional<LLChicletSpeakerCtrl::Params> speaker;
-
-		Optional<LLIconCtrl::Params> new_message_icon;
-
-		Optional<bool>	show_speaker;
-
-		Params();
-	};
-
-	/**
-	 * Sets session id.
-	 * Session ID for group chat is actually Group ID.
-	 */
-	/*virtual*/ void setSessionId(const LLUUID& session_id);
-
-	/**
-	 * Keep Speaker Control with actual speaker's ID
-	 */
-	/*virtual*/ void draw();
-
-	/**
-	 * Callback for LLGroupMgrObserver, we get this when group data is available or changed.
-	 * Sets group icon.
-	 */
-	/*virtual*/ void changed(LLGroupChange gc);
-
-	/**
-	 * Init Speaker Control with speaker's ID
-	 */
-	/*virtual*/ void initSpeakerControl();
-
-	/**
-	 * Returns number of unread messages.
-	 */
-	/*virtual*/ S32 getCounter() { return mCounterCtrl->getCounter(); }
-
-	~LLIMGroupChiclet();
-
-protected:
-	LLIMGroupChiclet(const Params& p);
-	friend class LLUICtrlFactory;
-
-	/**
-	 * Finds a current speaker and resets the SpeakerControl with speaker's ID
-	 */
-	/*virtual*/ void switchToCurrentSpeaker();
-
-	/**
-	 * Creates chiclet popup menu. Will create P2P or Group IM Chat menu 
-	 * based on other participant's id.
-	 */
-	virtual void createPopupMenu();
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Enables/disables "show session" menu item depending on visible IM floater existence.
-	 */
-	virtual void updateMenuItems();
-
-private:
-
-	LLChicletGroupIconCtrl* mChicletIconCtrl;
-};
-
 /**
  * Implements notification chiclet. Used to display total amount of unread messages 
  * across all IM sessions, total amount of system notifications. See EXT-3147 for details
@@ -797,7 +454,7 @@ class LLIMGroupChiclet : public LLIMChiclet, public LLGroupMgrObserver
 class LLSysWellChiclet : public LLChiclet
 {
 public:
-
+		
 	struct Params : public LLInitParam::Block<Params, LLChiclet::Params>
 	{
 		Optional<LLButton::Params> button;
@@ -843,7 +500,7 @@ class LLSysWellChiclet : public LLChiclet
 	 * There is an assumption that it will be called 2*N times to do not change its start state.
 	 * @see FlashToLitTimer
 	 */
-	void changeLitState();
+	void changeLitState(bool blink);
 
 	/**
 	 * Displays menu.
@@ -859,86 +516,58 @@ class LLSysWellChiclet : public LLChiclet
 	S32 mMaxDisplayedCount;
 	bool mIsNewMessagesState;
 
-	FlashToLitTimer* mFlashToLitTimer;
+	LLFlashTimer* mFlashToLitTimer;
 	LLContextMenu* mContextMenu;
 };
 
-/**
- * Class represented a chiclet for IM Well Icon.
- *
- * It displays a count of unread messages from other participants in all IM sessions.
- */
-class LLIMWellChiclet : public LLSysWellChiclet, LLIMSessionObserver
-{
-	friend class LLUICtrlFactory;
-public:
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}
-	virtual void sessionRemoved(const LLUUID& session_id) { messageCountChanged(LLSD()); }
-	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) {}
-
-	~LLIMWellChiclet();
-protected:
-	LLIMWellChiclet(const Params& p);
-
-	/**
-	 * Processes clicks on chiclet popup menu.
-	 */
-	virtual void onMenuItemClicked(const LLSD& user_data);
-
-	/**
-	 * Enables chiclet menu items.
-	 */
-	bool enableMenuItem(const LLSD& user_data);
-
-	/**
-	 * Creates menu.
-	 */
-	/*virtual*/ void createMenu();
-
-	/**
-	 * Handles changes in a session (message was added, messages were read, etc.)
-	 *
-	 * It get total count of unread messages from a LLIMMgr in all opened sessions and display it.
-	 *
-	 * @param[in] session_data contains session related data, is not used now
-	 *		["session_id"] - id of an appropriate session
-	 *		["participant_unread"] - count of unread messages from "real" participants.
-	 *
-	 * @see LLIMMgr::getNumberOfUnreadParticipantMessages()
-	 */
-	void messageCountChanged(const LLSD& session_data);
-};
-
 class LLNotificationChiclet : public LLSysWellChiclet
 {
+	LOG_CLASS(LLNotificationChiclet);
+			
 	friend class LLUICtrlFactory;
 public:
 	struct Params : public LLInitParam::Block<Params, LLSysWellChiclet::Params>{};
-
+		
 protected:
+	struct ChicletNotificationChannel : public LLNotificationChannel
+	{
+		ChicletNotificationChannel(LLNotificationChiclet* chiclet) 
+			: LLNotificationChannel(LLNotificationChannel::Params().filter(filterNotification).name(chiclet->getSessionId().asString()))
+			, mChiclet(chiclet)
+		{
+			// connect counter handlers to the signals
+			connectToChannel("Group Notifications");
+			connectToChannel("Offer");
+			connectToChannel("Notifications");
+		}
+				
+		static bool filterNotification(LLNotificationPtr notify);
+		// connect counter updaters to the corresponding signals
+		/*virtual*/ void onAdd(LLNotificationPtr p) { mChiclet->setCounter(++mChiclet->mUreadSystemNotifications); }
+		/*virtual*/ void onDelete(LLNotificationPtr p) { mChiclet->setCounter(--mChiclet->mUreadSystemNotifications); }
+				
+		LLNotificationChiclet* const mChiclet;
+	};
+				
+	boost::scoped_ptr<ChicletNotificationChannel> mNotificationChannel;
+				
 	LLNotificationChiclet(const Params& p);
-
+				
 	/**
 	 * Processes clicks on chiclet menu.
 	 */
 	void onMenuItemClicked(const LLSD& user_data);
-
+				
 	/**
 	 * Enables chiclet menu items.
 	 */
 	bool enableMenuItem(const LLSD& user_data);
-
+				
 	/**
 	 * Creates menu.
 	 */
 	/*virtual*/ void createMenu();
 
-	// connect counter updaters to the corresponding signals
-	void connectCounterUpdatersToSignal(const std::string& notification_type);
-
-	// methods for updating a number of unread System notifications
-	void incUreadSystemNotifications() { setCounter(++mUreadSystemNotifications); }
-	void decUreadSystemNotifications() { setCounter(--mUreadSystemNotifications); }
 	/*virtual*/ void setCounter(S32 counter);
 	S32 mUreadSystemNotifications;
 };
@@ -1044,9 +673,7 @@ class LLChicletPanel : public LLPanel
 
 	S32 getMinWidth() const { return mMinWidth; }
 
-	S32 getTotalUnreadIMCount();
-
-	S32	notifyParent(const LLSD& info);
+	/*virtual*/ S32	notifyParent(const LLSD& info);
 
 	/**
 	 * Toggle chiclet by session id ON and toggle OFF all other chiclets.
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index f1bc51fbe757a060b656dd36b94d8630da3bf65f..a51c844775e0e8a1f51d6ffa4cd9ffda629d2e2f 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -25,16 +25,10 @@
  */
 
 #include "llviewerprecompiledheaders.h" // must be first include
-
 #include "llchicletbar.h"
 
-// library includes
-#include "llfloaterreg.h"
-#include "lllayoutstack.h"
-
-// newview includes
 #include "llchiclet.h"
-#include "llimfloater.h" // for LLIMFloater
+#include "lllayoutstack.h"
 #include "llpaneltopinfobar.h"
 #include "llsyswellwindow.h"
 
@@ -57,107 +51,14 @@ LLChicletBar::LLChicletBar(const LLSD&)
 :	mChicletPanel(NULL),
 	mToolbarStack(NULL)
 {
-	// Firstly add our self to IMSession observers, so we catch session events
-	// before chiclets do that.
-	LLIMMgr::getInstance()->addSessionObserver(this);
-
 	buildFromFile("panel_chiclet_bar.xml");
 }
 
-LLChicletBar::~LLChicletBar()
-{
-	if (!LLSingleton<LLIMMgr>::destroyed())
-	{
-		LLIMMgr::getInstance()->removeSessionObserver(this);
-	}
-}
-
-LLIMChiclet* LLChicletBar::createIMChiclet(const LLUUID& session_id)
-{
-	LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(session_id);
-
-	switch (im_chiclet_type)
-	{
-	case LLIMChiclet::TYPE_IM:
-		return getChicletPanel()->createChiclet<LLIMP2PChiclet>(session_id);
-	case LLIMChiclet::TYPE_GROUP:
-		return getChicletPanel()->createChiclet<LLIMGroupChiclet>(session_id);
-	case LLIMChiclet::TYPE_AD_HOC:
-		return getChicletPanel()->createChiclet<LLAdHocChiclet>(session_id);
-	case LLIMChiclet::TYPE_UNKNOWN:
-		break;
-	}
-
-	return NULL;
-}
-
-//virtual
-void LLChicletBar::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
-{
-	if (!getChicletPanel()) return;
-
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (!session) return;
-
-	// no need to spawn chiclets for participants in P2P calls called through Avaline
-	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
-	if (getChicletPanel()->findChiclet<LLChiclet>(session_id)) return;
-
-	LLIMChiclet* chiclet = createIMChiclet(session_id);
-	if(chiclet)
-	{
-		chiclet->setIMSessionName(name);
-		chiclet->setOtherParticipantId(other_participant_id);
-		
-		LLIMFloater::onIMChicletCreated(session_id);
-
-	}
-	else
-	{
-		llwarns << "Could not create chiclet" << llendl;
-	}
-}
-
-//virtual
-void LLChicletBar::sessionRemoved(const LLUUID& session_id)
-{
-	if(getChicletPanel())
-	{
-		// IM floater should be closed when session removed and associated chiclet closed
-		LLIMFloater* iMfloater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (iMfloater != NULL)
-		{
-			iMfloater->closeFloater();
-		}
-
-		getChicletPanel()->removeChiclet(session_id);
-	}
-}
-
-void LLChicletBar::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
-	//this is only needed in case of outgoing ad-hoc/group chat sessions
-	LLChicletPanel* chiclet_panel = getChicletPanel();
-	if (chiclet_panel)
-	{
-		//it should be ad-hoc im chiclet or group im chiclet
-		LLChiclet* chiclet = chiclet_panel->findChiclet<LLChiclet>(old_session_id);
-		if (chiclet) chiclet->setSessionId(new_session_id);
-	}
-}
-
-S32 LLChicletBar::getTotalUnreadIMCount()
-{
-	return getChicletPanel()->getTotalUnreadIMCount();
-}
-
 BOOL LLChicletBar::postBuild()
 {
 	mToolbarStack = getChild<LLLayoutStack>("toolbar_stack");
 	mChicletPanel = getChild<LLChicletPanel>("chiclet_list");
 
-	showWellButton("im_well", !LLIMWellWindow::getInstance()->isWindowEmpty());
 	showWellButton("notification_well", !LLNotificationWellWindow::getInstance()->isWindowEmpty());
 
 	LLPanelTopInfoBar::instance().setResizeCallback(boost::bind(&LLChicletBar::fitWithTopInfoBar, this));
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 1427bf95e0f725f6ac2c68fe508c8cd64365219e..956c82cb77026036fbd0cc486d46fc51a8833828 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -28,7 +28,6 @@
 #define LL_LLCHICLETBAR_H
 
 #include "llpanel.h"
-#include "llimview.h"
 
 class LLChicletPanel;
 class LLIMChiclet;
@@ -38,30 +37,17 @@ class LLLayoutStack;
 class LLChicletBar
 	: public LLSingleton<LLChicletBar>
 	, public LLPanel
-	, public LLIMSessionObserver
 {
 	LOG_CLASS(LLChicletBar);
 	friend class LLSingleton<LLChicletBar>;
 public:
-	~LLChicletBar();
 
 	BOOL postBuild();
 
 	LLChicletPanel*	getChicletPanel() { return mChicletPanel; }
 
-	// LLIMSessionObserver observe triggers
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	virtual void sessionRemoved(const LLUUID& session_id);
-	void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
-	S32 getTotalUnreadIMCount();
-
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent);
 
-	/**
-	 * Creates IM Chiclet based on session type (IM chat or Group chat)
-	 */
-	LLIMChiclet* createIMChiclet(const LLUUID& session_id);
 
 	/**
 	 * Shows/hides panel with specified well button (IM or Notification)
diff --git a/indra/newview/llclassifiedstatsresponder.cpp b/indra/newview/llclassifiedstatsresponder.cpp
index b4da31895fcdf2488898736ebe0e3ecad35136d9..e3cd83e174211bc4bcd997285adf96c93fedf899 100644
--- a/indra/newview/llclassifiedstatsresponder.cpp
+++ b/indra/newview/llclassifiedstatsresponder.cpp
@@ -62,8 +62,7 @@ void LLClassifiedStatsResponder::result(const LLSD& content)
 }
 
 /*virtual*/
-void LLClassifiedStatsResponder::error(U32 status, const std::string& reason)
+void LLClassifiedStatsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLClassifiedStatsResponder::error("
-		<< status << ": " << reason << ")" << llendl;
+	llinfos << "LLClassifiedStatsResponder::error [status:" << status << "]: " << content << llendl;
 }
diff --git a/indra/newview/llclassifiedstatsresponder.h b/indra/newview/llclassifiedstatsresponder.h
index 3db1868cb2860c8084ba8594e8ba80ab756c3de4..06dcb62fd055e6ad4fadf8ccdae343e01602c920 100644
--- a/indra/newview/llclassifiedstatsresponder.h
+++ b/indra/newview/llclassifiedstatsresponder.h
@@ -39,7 +39,7 @@ class LLClassifiedStatsResponder : public LLHTTPClient::Responder
 	virtual void result(const LLSD& content);
 	//If we get back an error (not found, etc...), handle it here
 	
-	virtual void error(U32 status, const std::string& reason);
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 protected:
 	LLUUID mClassifiedID;
diff --git a/indra/newview/llcofwearables.cpp b/indra/newview/llcofwearables.cpp
index e9c7a3fa0394691089d183e97a3663c4f41de137..e86d6930e89025c04ebb19a369fdb2f99758c89a 100644
--- a/indra/newview/llcofwearables.cpp
+++ b/indra/newview/llcofwearables.cpp
@@ -139,8 +139,7 @@ class CofAttachmentContextMenu : public CofContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-		registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
+		registrar.add("Attachment.Detach", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 
 		return createFromFile("menu_cof_attachment.xml");
 	}
@@ -173,9 +172,8 @@ class CofClothingContextMenu : public CofContextMenu
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 		LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
 		LLUUID selected_id = mUUIDs.back();
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
 
-		registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
+		registrar.add("Clothing.TakeOff", boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 		registrar.add("Clothing.Replace", boost::bind(replaceWearable, selected_id));
 		registrar.add("Clothing.Edit", boost::bind(LLAgentWearables::editWearable, selected_id));
 		registrar.add("Clothing.Create", boost::bind(&CofClothingContextMenu::createNew, this, selected_id));
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 5b942f283afc49c8619845e97a6bcc8c5e884771..f1f7da5fd1f7f5865b5330578588c4fee9129656 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -241,8 +241,8 @@ void LLColorSwatchCtrl::draw()
 	{
 		if (!mFallbackImageName.empty())
 		{
-			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, TRUE, 
-				LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+			LLPointer<LLViewerFetchedTexture> fallback_image = LLViewerTextureManager::getFetchedTextureFromFile(mFallbackImageName, FTT_LOCAL_FILE, TRUE, 
+				LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 			if( fallback_image->getComponents() == 4 )
 			{	
 				gl_rect_2d_checkerboard( interior );
diff --git a/indra/newview/llcommunicationchannel.cpp b/indra/newview/llcommunicationchannel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..0821510645492a4f5fcbd4cc6b1091d4f86c372f
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.cpp
@@ -0,0 +1,113 @@
+/** 
+* @file llcommunicationchannel.cpp
+* @brief Implementation of llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $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" // must be first include
+
+#include "llcommunicationchannel.h"
+
+#include <string>
+#include <map>
+
+#include "llagent.h"
+#include "lldate.h"
+#include "llnotifications.h"
+
+
+LLCommunicationChannel::LLCommunicationChannel(const std::string& pName, const std::string& pParentName)
+	: LLNotificationChannel(pName, pParentName, filterByDoNotDisturbStatus)
+	, mHistory()
+{
+}
+
+LLCommunicationChannel::~LLCommunicationChannel()
+{
+}
+
+bool LLCommunicationChannel::filterByDoNotDisturbStatus(LLNotificationPtr)
+{
+	return !gAgent.isDoNotDisturb();
+}
+
+S32 LLCommunicationChannel::getHistorySize() const
+{
+    return mHistory.size();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::beginHistory() const
+{
+	return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::const_iterator LLCommunicationChannel::endHistory() const
+{
+	return mHistory.end();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::beginHistory()
+{
+    return mHistory.begin();
+}
+
+LLCommunicationChannel::history_list_t::iterator LLCommunicationChannel::endHistory()
+{
+    return mHistory.end();
+}
+
+void LLCommunicationChannel::clearHistory()
+{
+	mHistory.clear();
+}
+
+void LLCommunicationChannel::removeItemFromHistory(LLNotificationPtr p)
+{
+    //Find the notification and removes it from mHistory
+    for(history_list_t::iterator it = beginHistory(); it != endHistory(); ++it)
+    {
+        if(it->second == p)
+        {
+            mHistory.erase(it);
+            break;
+        }
+    }
+}
+
+void LLCommunicationChannel::onDelete(LLNotificationPtr p) 
+{
+    removeItemFromHistory(p);
+}
+
+void LLCommunicationChannel::onFilterFail(LLNotificationPtr pNotificationPtr)
+{
+	std::string notificationType = pNotificationPtr->getType();
+	if ((notificationType == "groupnotify")
+		|| (notificationType == "offer")
+		|| (notificationType == "notifytoast")
+        && !pNotificationPtr->isCancelled())
+	{
+		mHistory.insert(std::make_pair<LLDate, LLNotificationPtr>(pNotificationPtr->getDate(), pNotificationPtr));
+	}
+}
diff --git a/indra/newview/llcommunicationchannel.h b/indra/newview/llcommunicationchannel.h
new file mode 100644
index 0000000000000000000000000000000000000000..0d8f7f4387516a084aa23971833643b0d2ee3372
--- /dev/null
+++ b/indra/newview/llcommunicationchannel.h
@@ -0,0 +1,66 @@
+/** 
+* @file   llcommunicationchannel.h
+* @brief  Header file for llcommunicationchannel
+* @author Stinson@lindenlab.com
+*
+* $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_LLCOMMUNICATIONCHANNEL_H
+#define LL_LLCOMMUNICATIONCHANNEL_H
+
+#include <string>
+#include <map>
+
+#include "lldate.h"
+#include "llerror.h"
+#include "llnotifications.h"
+
+class LLCommunicationChannel : public LLNotificationChannel
+{
+	LOG_CLASS(LLCommunicationChannel);
+public:
+	LLCommunicationChannel(const std::string& pName, const std::string& pParentName);
+	virtual ~LLCommunicationChannel();
+
+	static bool filterByDoNotDisturbStatus(LLNotificationPtr);
+
+	typedef std::multimap<LLDate, LLNotificationPtr> history_list_t;
+    S32 getHistorySize() const;	
+	history_list_t::const_iterator beginHistory() const;
+	history_list_t::const_iterator endHistory() const;
+    history_list_t::iterator beginHistory();
+    history_list_t::iterator endHistory();	
+
+	void clearHistory();
+    void removeItemFromHistory(LLNotificationPtr p);
+
+protected:
+    virtual void onDelete(LLNotificationPtr p);
+	virtual void onFilterFail(LLNotificationPtr pNotificationPtr);
+
+private:
+
+	history_list_t mHistory;
+};
+
+#endif // LL_LLCOMMUNICATIONCHANNEL_H
+
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 4f5f9e22b69ddfe6ef1256d37bd945ec07b6789b..458842447459c0a2391e6a1d21654a5e88aa87a3 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -161,18 +161,6 @@ BOOL LLFloaterScriptQueue::start()
 {
 	std::string buffer;
 
-	LLSelectMgr *mgr = LLSelectMgr::getInstance();
-	LLObjectSelectionHandle selectHandle = mgr->getSelection();
-	U32 n_objects = 0;
-	if (gSavedSettings.getBOOL("EditLinkedParts"))
-	{
-		n_objects = selectHandle->getObjectCount();
-	}
-	else
-	{
-		n_objects = selectHandle->getRootObjectCount();
-	}
-
 	LLStringUtil::format_map_t args;
 	args["[START]"] = mStartString;
 	args["[COUNT]"] = llformat ("%d", mObjectIDs.count());
diff --git a/indra/newview/llconversationlog.cpp b/indra/newview/llconversationlog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7883e4cb894c0c4eead6a694be438b2ce0d4e761
--- /dev/null
+++ b/indra/newview/llconversationlog.cpp
@@ -0,0 +1,615 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&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 "llagent.h"
+#include "llavatarnamecache.h"
+#include "llconversationlog.h"
+#include "lldiriterator.h"
+#include "llnotificationsutil.h"
+#include "lltrans.h"
+
+#include <boost/foreach.hpp>
+#include "boost/lexical_cast.hpp"
+
+const int CONVERSATION_LIFETIME = 30; // lifetime of LLConversation is 30 days by spec
+
+struct ConversationParams
+{
+	ConversationParams(time_t time)
+	:	mTime(time),
+		mTimestamp(LLConversation::createTimestamp(time))
+	{}
+
+	time_t		mTime;
+	std::string	mTimestamp;
+	SessionType	mConversationType;
+	std::string	mConversationName;
+	std::string	mHistoryFileName;
+	LLUUID		mSessionID;
+	LLUUID		mParticipantID;
+	bool		mHasOfflineIMs;
+};
+
+/************************************************************************/
+/*             LLConversation implementation                            */
+/************************************************************************/
+
+LLConversation::LLConversation(const ConversationParams& params)
+:	mTime(params.mTime),
+	mTimestamp(params.mTimestamp),
+	mConversationType(params.mConversationType),
+	mConversationName(params.mConversationName),
+	mHistoryFileName(params.mHistoryFileName),
+	mSessionID(params.mSessionID),
+	mParticipantID(params.mParticipantID),
+	mHasOfflineIMs(params.mHasOfflineIMs)
+{
+	setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLIMModel::LLIMSession& session)
+:	mTime(time_corrected()),
+	mTimestamp(createTimestamp(mTime)),
+	mConversationType(session.mSessionType),
+	mConversationName(session.mName),
+	mHistoryFileName(session.mHistoryFileName),
+	mSessionID(session.isOutgoingAdHoc() ? session.generateOutgouigAdHocHash() : session.mSessionID),
+	mParticipantID(session.mOtherParticipantID),
+	mHasOfflineIMs(session.mHasOfflineMessage)
+{
+	setListenIMFloaterOpened();
+}
+
+LLConversation::LLConversation(const LLConversation& conversation)
+{
+	mTime				= conversation.getTime();
+	mTimestamp			= conversation.getTimestamp();
+	mConversationType	= conversation.getConversationType();
+	mConversationName	= conversation.getConversationName();
+	mHistoryFileName	= conversation.getHistoryFileName();
+	mSessionID			= conversation.getSessionID();
+	mParticipantID		= conversation.getParticipantID();
+	mHasOfflineIMs		= conversation.hasOfflineMessages();
+
+	setListenIMFloaterOpened();
+}
+
+LLConversation::~LLConversation()
+{
+	mIMFloaterShowedConnection.disconnect();
+}
+
+void LLConversation::updateTimestamp()
+{
+	mTime = time_corrected();
+	mTimestamp = createTimestamp(mTime);
+}
+
+void LLConversation::onIMFloaterShown(const LLUUID& session_id)
+{
+	if (mSessionID == session_id)
+	{
+		mHasOfflineIMs = false;
+	}
+}
+
+// static
+const std::string LLConversation::createTimestamp(const time_t& utc_time)
+{
+	std::string timeStr;
+	LLSD substitution;
+	substitution["datetime"] = (S32) utc_time;
+
+	timeStr = "["+LLTrans::getString ("TimeMonth")+"]/["
+				 +LLTrans::getString ("TimeDay")+"]/["
+				 +LLTrans::getString ("TimeYear")+"] ["
+				 +LLTrans::getString ("TimeHour")+"]:["
+				 +LLTrans::getString ("TimeMin")+"]";
+
+
+	LLStringUtil::format (timeStr, substitution);
+	return timeStr;
+}
+
+bool LLConversation::isOlderThan(U32 days) const
+{
+	time_t now = time_corrected();
+	U32 age = (U32)((now - mTime) / SEC_PER_DAY); // age of conversation in days
+
+	return age > days;
+}
+
+void LLConversation::setListenIMFloaterOpened()
+{
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mSessionID);
+
+	bool offline_ims_visible = LLFloaterIMSession::isVisible(floater) && floater->hasFocus();
+
+	// we don't need to listen for im floater with this conversation is opened
+	// if floater is already opened or this conversation doesn't have unread offline messages
+	if (mHasOfflineIMs && !offline_ims_visible)
+	{
+		mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversation::onIMFloaterShown, this, _1));
+	}
+	else
+	{
+		mHasOfflineIMs = false;
+	}
+}
+
+/************************************************************************/
+/*             LLConversationLogFriendObserver implementation           */
+/************************************************************************/
+
+// Note : An LLSingleton like LLConversationLog cannot be an LLFriendObserver 
+// at the same time.
+// This is because avatar observers are deleted by the observed object which 
+// conflicts with the way LLSingleton are deleted.
+
+class LLConversationLogFriendObserver : public LLFriendObserver
+{
+public:
+	LLConversationLogFriendObserver() {}
+	virtual ~LLConversationLogFriendObserver() {}
+	virtual void changed(U32 mask);
+};
+
+void LLConversationLogFriendObserver::changed(U32 mask)
+{
+	if (mask & (LLFriendObserver::ADD | LLFriendObserver::REMOVE))
+	{
+		LLConversationLog::instance().notifyObservers();
+	}
+}
+
+/************************************************************************/
+/*             LLConversationLog implementation                         */
+/************************************************************************/
+
+LLConversationLog::LLConversationLog() :
+	mAvatarNameCacheConnection(),
+	mLoggingEnabled(false)
+{
+	if(gSavedPerAccountSettings.controlExists("KeepConversationLogTranscripts"))
+	{
+		LLControlVariable * keep_log_ctrlp = gSavedPerAccountSettings.getControl("KeepConversationLogTranscripts").get();
+		S32 log_mode = keep_log_ctrlp->getValue();
+		keep_log_ctrlp->getSignal()->connect(boost::bind(&LLConversationLog::enableLogging, this, _2));
+		if (log_mode > 0)
+		{
+			loadFromFile(getFileName());
+
+			enableLogging(log_mode);
+		}
+	}
+}
+
+void LLConversationLog::enableLogging(S32 log_mode)
+{
+	mLoggingEnabled = log_mode > 0;
+	if (log_mode > 0)
+	{
+		mConversations.clear();
+		loadFromFile(getFileName());
+		LLIMMgr::instance().addSessionObserver(this);
+		mNewMessageSignalConnection = LLIMModel::instance().addNewMsgCallback(boost::bind(&LLConversationLog::onNewMessageReceived, this, _1));
+
+		mFriendObserver = new LLConversationLogFriendObserver;
+		LLAvatarTracker::instance().addObserver(mFriendObserver);
+	}
+	else
+	{
+		saveToFile(getFileName());
+
+		LLIMMgr::instance().removeSessionObserver(this);
+		mNewMessageSignalConnection.disconnect();
+		LLAvatarTracker::instance().removeObserver(mFriendObserver);
+	}
+
+	notifyObservers();
+}
+
+void LLConversationLog::logConversation(const LLUUID& session_id, BOOL has_offline_msg)
+{
+	const LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(session_id);
+	LLConversation* conversation = findConversation(session);
+
+	if (session && session->mOtherParticipantID != gAgentID)
+	{
+    	if (conversation)
+		{
+			if(has_offline_msg)
+			{
+				updateOfflineIMs(session, has_offline_msg);
+			}
+			updateConversationTimestamp(conversation);
+		}
+		else
+		{
+			createConversation(session);
+		}
+	}
+}
+
+void LLConversationLog::createConversation(const LLIMModel::LLIMSession* session)
+{
+	if (session)
+	{
+		LLConversation conversation(*session);
+		mConversations.push_back(conversation);
+
+		if (LLIMModel::LLIMSession::P2P_SESSION == session->mSessionType)
+		{
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(session->mOtherParticipantID, boost::bind(&LLConversationLog::onAvatarNameCache, this, _1, _2, session));
+		}
+
+		notifyObservers();
+	}
+}
+
+void LLConversationLog::updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name)
+{
+	if (!session)
+	{
+		return;
+	}
+
+	LLConversation* conversation = findConversation(session);
+	if (conversation)
+	{
+		conversation->setConversationName(name);
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_NAME);
+	}
+}
+
+void LLConversationLog::updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages)
+{
+	if (!session)
+	{
+		return;
+	}
+
+	LLConversation* conversation = findConversation(session);
+	if (conversation)
+	{
+		conversation->setOfflineMessages(new_messages);
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_OfflineIMs);
+	}
+}
+
+void LLConversationLog::updateConversationTimestamp(LLConversation* conversation)
+{
+	if (conversation)
+	{
+		conversation->updateTimestamp();
+		notifyParticularConversationObservers(conversation->getSessionID(), LLConversationLogObserver::CHANGED_TIME);
+	}
+}
+
+LLConversation* LLConversationLog::findConversation(const LLIMModel::LLIMSession* session)
+{
+	if (session)
+	{
+		const LLUUID session_id = session->isOutgoingAdHoc() ? session->generateOutgouigAdHocHash() : session->mSessionID;
+
+		conversations_vec_t::iterator conv_it = mConversations.begin();
+		for(; conv_it != mConversations.end(); ++conv_it)
+		{
+			if (conv_it->getSessionID() == session_id)
+			{
+				return &*conv_it;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+void LLConversationLog::removeConversation(const LLConversation& conversation)
+{
+	conversations_vec_t::iterator conv_it = mConversations.begin();
+	for(; conv_it != mConversations.end(); ++conv_it)
+	{
+		if (conv_it->getSessionID() == conversation.getSessionID() && conv_it->getTime() == conversation.getTime())
+		{
+			mConversations.erase(conv_it);
+			notifyObservers();
+			cache();
+			return;
+		}
+	}
+}
+
+const LLConversation* LLConversationLog::getConversation(const LLUUID& session_id)
+{
+	conversations_vec_t::const_iterator conv_it = mConversations.begin();
+	for(; conv_it != mConversations.end(); ++conv_it)
+	{
+		if (conv_it->getSessionID() == session_id)
+		{
+			return &*conv_it;
+		}
+	}
+
+	return NULL;
+}
+
+void LLConversationLog::addObserver(LLConversationLogObserver* observer)
+{
+	mObservers.insert(observer);
+}
+
+void LLConversationLog::removeObserver(LLConversationLogObserver* observer)
+{
+	mObservers.erase(observer);
+}
+
+void LLConversationLog::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
+{
+	logConversation(session_id, has_offline_msg);
+}
+
+void LLConversationLog::cache()
+{
+	if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0)
+	{
+		saveToFile(getFileName());
+	}
+}
+
+void LLConversationLog::getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs)
+{
+	// get Users log directory
+	std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	dirname += gDirUtilp->getDirDelimiter();
+
+	// create search pattern
+	std::string pattern = "conversation.log.backup*";
+
+	LLDirIterator iter(dirname, pattern);
+	std::string filename;
+	while (iter.next(filename))
+	{
+		list_of_backup_logs.push_back(gDirUtilp->add(dirname, filename));
+	}
+}
+
+void LLConversationLog::deleteBackupLogs()
+{
+	std::vector<std::string> backup_logs;
+	getListOfBackupLogs(backup_logs);
+
+	BOOST_FOREACH(const std::string& fullpath, backup_logs)
+	{
+		LLFile::remove(fullpath);
+	}
+}
+
+bool LLConversationLog::moveLog(const std::string &originDirectory, const std::string &targetDirectory)
+{
+
+	std::string backupFileName;
+	unsigned backupFileCount = 0;
+
+	//Does the file exist in the current path, if it does lets move it
+	if(LLFile::isfile(originDirectory)) 
+	{
+		//The target directory contains that file already, so lets store it
+		if(LLFile::isfile(targetDirectory))
+		{
+			backupFileName = targetDirectory + ".backup";
+
+			//If needed store backup file as .backup1 etc.
+			while(LLFile::isfile(backupFileName))
+			{
+				++backupFileCount;
+				backupFileName = targetDirectory + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+			}
+
+			//Rename the file to its backup name so it is not overwritten
+			LLFile::rename(targetDirectory, backupFileName);
+		}
+
+		//Move the file from the current path to target path
+		if(LLFile::rename(originDirectory, targetDirectory) != 0)
+		{
+			return false;
+		}
+	}
+
+	return true;
+}
+
+std::string LLConversationLog::getFileName()
+{
+	std::string filename = "conversation";
+	return gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename) + ".log";
+}
+
+bool LLConversationLog::saveToFile(const std::string& filename)
+{
+	if (!filename.size())
+	{
+		llwarns << "Call log list filename is empty!" << llendl;
+		return false;
+	}
+
+	LLFILE* fp = LLFile::fopen(filename, "wb");
+	if (!fp)
+	{
+		llwarns << "Couldn't open call log list" << filename << llendl;
+		return false;
+	}
+
+	std::string participant_id;
+	std::string conversation_id;
+
+	conversations_vec_t::const_iterator conv_it = mConversations.begin();
+	for (; conv_it != mConversations.end(); ++conv_it)
+	{
+		conv_it->getSessionID().toString(conversation_id);
+		conv_it->getParticipantID().toString(participant_id);
+
+		// examples of two file entries
+		// [1343221177] 0 1 0 John Doe| 7e4ec5be-783f-49f5-71dz-16c58c64c145 4ec62a74-c246-0d25-2af6-846beac2aa55 john.doe|
+		// [1343222639] 2 0 0 Ad-hoc Conference| c3g67c89-c479-4c97-b21d-32869bcfe8rc 68f1c33e-4135-3e3e-a897-8c9b23115c09 Ad-hoc Conference hash597394a0-9982-766d-27b8-c75560213b9a|
+
+		fprintf(fp, "[%lld] %d %d %d %s| %s %s %s|\n",
+				(S64)conv_it->getTime(),
+				(S32)conv_it->getConversationType(),
+				(S32)0,
+				(S32)conv_it->hasOfflineMessages(),
+				     conv_it->getConversationName().c_str(),
+				participant_id.c_str(),
+				conversation_id.c_str(),
+				conv_it->getHistoryFileName().c_str());
+	}
+	fclose(fp);
+	return true;
+}
+bool LLConversationLog::loadFromFile(const std::string& filename)
+{
+	if(!filename.size())
+	{
+		llwarns << "Call log list filename is empty!" << llendl;
+		return false;
+	}
+
+	LLFILE* fp = LLFile::fopen(filename, "rb");
+	if (!fp)
+	{
+		llwarns << "Couldn't open call log list" << filename << llendl;
+		return false;
+	}
+
+	char buffer[MAX_STRING];
+	char conv_name_buffer[MAX_STRING];
+	char part_id_buffer[MAX_STRING];
+	char conv_id_buffer[MAX_STRING];
+	char history_file_name[MAX_STRING];
+	S32 has_offline_ims;
+	S32 stype;
+	S64 time;
+	// before CHUI-348 it was a flag of conversation voice state
+	int prereserved_unused;
+
+	while (!feof(fp) && fgets(buffer, MAX_STRING, fp))
+	{
+		conv_name_buffer[0] = '\0';
+		part_id_buffer[0]	= '\0';
+		conv_id_buffer[0]	= '\0';
+
+		sscanf(buffer, "[%lld] %d %d %d %[^|]| %s %s %[^|]|",
+				&time,
+				&stype,
+				&prereserved_unused,
+				&has_offline_ims,
+				conv_name_buffer,
+				part_id_buffer,
+				conv_id_buffer,
+				history_file_name);
+
+		ConversationParams params((time_t)time);
+		params.mConversationType = (SessionType)stype;
+		params.mHasOfflineIMs = has_offline_ims;
+		params.mConversationName = std::string(conv_name_buffer);
+		params.mParticipantID = LLUUID(part_id_buffer);
+		params.mSessionID = LLUUID(conv_id_buffer);
+		params.mHistoryFileName = std::string(history_file_name);
+
+		LLConversation conversation(params);
+
+		// CHUI-325
+		// The conversation log should be capped to the last 30 days. Conversations with the last utterance
+		// being over 30 days old should be purged from the conversation log text file on login.
+		if (conversation.isOlderThan(CONVERSATION_LIFETIME))
+		{
+			continue;
+		}
+
+		mConversations.push_back(conversation);
+	}
+	fclose(fp);
+
+	LLFile::remove(filename);
+	cache();
+
+	notifyObservers();
+	return true;
+}
+
+void LLConversationLog::notifyObservers()
+{
+	std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+	for (; iter != mObservers.end(); ++iter)
+	{
+		(*iter)->changed();
+	}
+}
+
+void LLConversationLog::notifyParticularConversationObservers(const LLUUID& session_id, U32 mask)
+{
+	std::set<LLConversationLogObserver*>::const_iterator iter = mObservers.begin();
+	for (; iter != mObservers.end(); ++iter)
+	{
+		(*iter)->changed(session_id, mask);
+	}
+}
+
+void LLConversationLog::onNewMessageReceived(const LLSD& data)
+{
+	const LLUUID session_id = data["session_id"].asUUID();
+	logConversation(session_id, false);
+}
+
+void LLConversationLog::onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session)
+{
+	mAvatarNameCacheConnection.disconnect();
+	updateConversationName(session, av_name.getCompleteName());
+}
+
+void LLConversationLog::onClearLog()
+{
+	LLNotificationsUtil::add("PreferenceChatClearLog", LLSD(), LLSD(), boost::bind(&LLConversationLog::onClearLogResponse, this, _1, _2));
+}
+
+void LLConversationLog::onClearLogResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		mConversations.clear();
+		notifyObservers();
+		cache();
+		deleteBackupLogs();
+	}
+}
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
new file mode 100644
index 0000000000000000000000000000000000000000..265b1f0ef04a0c74b492c2073acc1da315b87612
--- /dev/null
+++ b/indra/newview/llconversationlog.h
@@ -0,0 +1,216 @@
+/**
+ * @file llconversationlog.h
+ *
+ * $LicenseInfo:firstyear=2002&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 LLCONVERSATIONLOG_H_
+#define LLCONVERSATIONLOG_H_
+
+#include "llcallingcard.h"
+#include "llfloaterimsession.h"
+#include "llimview.h"
+
+class LLConversationLogObserver;
+struct ConversationParams;
+
+typedef LLIMModel::LLIMSession::SType SessionType;
+
+/*
+ * This class represents a particular session(conversation) of any type(im/voice/p2p/group/...) by storing some of session's data.
+ * Each LLConversation object has a corresponding visual representation in a form of LLConversationLogListItem.
+ */
+class LLConversation
+{
+public:
+
+	LLConversation(const ConversationParams& params);
+	LLConversation(const LLIMModel::LLIMSession& session);
+	LLConversation(const LLConversation& conversation);
+
+	~LLConversation();
+
+	const SessionType&	getConversationType()	const	{ return mConversationType; }
+	const std::string&	getConversationName()	const	{ return mConversationName; }
+	const std::string&	getHistoryFileName()	const	{ return mHistoryFileName; }
+	const LLUUID&		getSessionID()			const	{ return mSessionID; }
+	const LLUUID&		getParticipantID()		const	{ return mParticipantID; }
+	const std::string&	getTimestamp()			const	{ return mTimestamp; }
+	const time_t&		getTime()				const	{ return mTime; }
+	bool				hasOfflineMessages()	const	{ return mHasOfflineIMs; }
+
+	void setConversationName(std::string conv_name) { mConversationName = conv_name; }
+	void setOfflineMessages(bool new_messages) { mHasOfflineIMs = new_messages; }
+	bool isOlderThan(U32 days) const;
+
+	/*
+	 * updates last interaction time
+	 */
+	void updateTimestamp();
+
+	/*
+	 * Resets flag of unread offline message to false when im floater with this conversation is opened.
+	 */
+	void onIMFloaterShown(const LLUUID& session_id);
+
+	/*
+	 * returns string representation(in form of: mm/dd/yyyy hh:mm) of time when conversation was started
+	 */
+	static const std::string createTimestamp(const time_t& utc_time);
+
+private:
+
+	/*
+	 * If conversation has unread offline messages sets callback for opening LLFloaterIMSession
+	 * with this conversation.
+	 */
+	void setListenIMFloaterOpened();
+
+	boost::signals2::connection mIMFloaterShowedConnection;
+
+	time_t			mTime; // last interaction time
+	SessionType		mConversationType;
+	std::string		mConversationName;
+	std::string		mHistoryFileName;
+	LLUUID			mSessionID;
+	LLUUID			mParticipantID;
+	bool			mHasOfflineIMs;
+	std::string		mTimestamp; // last interaction time in form of: mm/dd/yyyy hh:mm
+};
+
+/**
+ * LLConversationLog stores all agent's conversations.
+ * This class is responsible for creating and storing LLConversation objects when im or voice session starts.
+ * Also this class saves/retrieves conversations to/from file.
+ *
+ * Also please note that it may be several conversations with the same sessionID stored in the conversation log.
+ * To distinguish two conversations with the same sessionID it's also needed to compare their creation date.
+ */
+
+class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver
+{
+	friend class LLSingleton<LLConversationLog>;
+public:
+
+	void removeConversation(const LLConversation& conversation);
+
+	/**
+	 * Returns first conversation with matched session_id
+	 */
+	const LLConversation*				getConversation(const LLUUID& session_id);
+	const std::vector<LLConversation>&	getConversations() { return mConversations; }
+
+	void addObserver(LLConversationLogObserver* observer);
+	void removeObserver(LLConversationLogObserver* observer);
+
+	// LLIMSessionObserver triggers
+	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
+    virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) {}; // Stub
+	virtual void sessionRemoved(const LLUUID& session_id){}											// Stub
+	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id){};								// Stub
+	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id){};	// Stub
+
+	void notifyObservers();
+
+	void onNewMessageReceived(const LLSD& data);
+
+	/**
+	 * public method which is called on viewer exit to save conversation log
+	 */
+	void cache();
+	bool moveLog(const std::string &originDirectory, const std::string &targetDirectory);
+	void getListOfBackupLogs(std::vector<std::string>& list_of_backup_logs);
+	void deleteBackupLogs();
+
+	void onClearLog();
+	void onClearLogResponse(const LLSD& notification, const LLSD& response);
+
+	bool getIsLoggingEnabled() { return mLoggingEnabled; }
+	bool isLogEmpty() { return mConversations.empty(); }
+
+	/**
+	 * constructs file name in which conversations log will be saved
+	 * file name is conversation.log
+	 */
+	std::string getFileName();
+
+private:
+
+	LLConversationLog();
+	virtual ~LLConversationLog()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
+	
+	void enableLogging(S32 log_mode);
+
+	/**
+	 * adds conversation to the conversation list and notifies observers
+	 */
+	void logConversation(const LLUUID& session_id, BOOL has_offline_msg);
+
+	void notifyParticularConversationObservers(const LLUUID& session_id, U32 mask);
+
+	bool saveToFile(const std::string& filename);
+	bool loadFromFile(const std::string& filename);
+
+	void onAvatarNameCache(const LLUUID& participant_id, const LLAvatarName& av_name, const LLIMModel::LLIMSession* session);
+
+	void createConversation(const LLIMModel::LLIMSession* session);
+	void updateConversationTimestamp(LLConversation* conversation);
+	void updateConversationName(const LLIMModel::LLIMSession* session, const std::string& name);
+	void updateOfflineIMs(const LLIMModel::LLIMSession* session, BOOL new_messages);
+
+	LLConversation* findConversation(const LLIMModel::LLIMSession* session);
+
+	typedef std::vector<LLConversation> conversations_vec_t;
+	std::vector<LLConversation>				mConversations;
+	std::set<LLConversationLogObserver*>	mObservers;
+
+	LLFriendObserver* mFriendObserver;		// Observer of the LLAvatarTracker instance
+
+	boost::signals2::connection mNewMessageSignalConnection;
+	boost::signals2::connection mAvatarNameCacheConnection;
+
+	bool mLoggingEnabled;
+};
+
+class LLConversationLogObserver
+{
+public:
+
+	enum EConversationChange
+		{
+			CHANGED_TIME = 1, // last interaction time changed
+			CHANGED_NAME = 2,  // conversation name changed
+			CHANGED_OfflineIMs = 3
+		};
+
+	virtual ~LLConversationLogObserver(){}
+	virtual void changed() = 0;
+	virtual void changed(const LLUUID& session_id, U32 mask){};
+};
+
+#endif /* LLCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llconversationloglist.cpp b/indra/newview/llconversationloglist.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..5ab108b39fbc3279120a71c3933d9bdcd2c44ca2
--- /dev/null
+++ b/indra/newview/llconversationloglist.cpp
@@ -0,0 +1,533 @@
+/**
+ * @file llconversationloglist.cpp
+ *
+ * $LicenseInfo:firstyear=2002&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 "llavataractions.h"
+#include "llagent.h"
+#include "llfloaterreg.h"
+#include "llfloaterconversationpreview.h"
+#include "llgroupactions.h"
+#include "llconversationloglist.h"
+#include "llconversationloglistitem.h"
+#include "llviewermenu.h"
+#include "lltrans.h"
+
+static LLDefaultChildRegistry::Register<LLConversationLogList> r("conversation_log_list");
+
+static LLConversationLogListNameComparator NAME_COMPARATOR;
+static LLConversationLogListDateComparator DATE_COMPARATOR;
+
+LLConversationLogList::LLConversationLogList(const Params& p)
+:	LLFlatListViewEx(p),
+	mIsDirty(true)
+{
+	LLConversationLog::instance().addObserver(this);
+
+	// Set up context menu.
+	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar check_registrar;
+	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+
+	registrar.add		("Calllog.Action",	boost::bind(&LLConversationLogList::onCustomAction,	this, _2));
+	check_registrar.add ("Calllog.Check",	boost::bind(&LLConversationLogList::isActionChecked,this, _2));
+	enable_registrar.add("Calllog.Enable",	boost::bind(&LLConversationLogList::isActionEnabled,this, _2));
+
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>(
+									"menu_conversation_log_gear.xml",
+									gMenuHolder,
+									LLViewerMenuHolderGL::child_registry_t::instance());
+	if(context_menu)
+	{
+		mContextMenu = context_menu->getHandle();
+	}
+
+	mIsFriendsOnTop = gSavedSettings.getBOOL("SortFriendsFirst");
+}
+
+LLConversationLogList::~LLConversationLogList()
+{
+	if (mContextMenu.get())
+	{
+		mContextMenu.get()->die();
+	}
+
+	LLConversationLog::instance().removeObserver(this);
+}
+
+void LLConversationLogList::draw()
+{
+	if (mIsDirty)
+	{
+		refresh();
+	}
+	LLFlatListViewEx::draw();
+}
+
+BOOL LLConversationLogList::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
+
+	LLToggleableMenu* context_menu = mContextMenu.get();
+	{
+		context_menu->buildDrawLabels();
+	if (context_menu && size())
+		context_menu->updateParent(LLMenuGL::sMenuContainer);
+		LLMenuGL::showPopup(this, context_menu, x, y);
+	}
+
+	return handled;
+}
+
+void LLConversationLogList::setNameFilter(const std::string& filter)
+{
+	std::string filter_upper = filter;
+	LLStringUtil::toUpper(filter_upper);
+	if (mNameFilter != filter_upper)
+	{
+		mNameFilter = filter_upper;
+		setDirty();
+	}
+}
+
+bool LLConversationLogList::findInsensitive(std::string haystack, const std::string& needle_upper)
+{
+    LLStringUtil::toUpper(haystack);
+    return haystack.find(needle_upper) != std::string::npos;
+}
+
+void LLConversationLogList::sortByName()
+{
+	setComparator(&NAME_COMPARATOR);
+	sort();
+}
+
+void LLConversationLogList::sortByDate()
+{
+	setComparator(&DATE_COMPARATOR);
+	sort();
+}
+
+void LLConversationLogList::toggleSortFriendsOnTop()
+{
+	mIsFriendsOnTop = !mIsFriendsOnTop;
+	gSavedSettings.setBOOL("SortFriendsFirst", mIsFriendsOnTop);
+	sort();
+}
+
+void LLConversationLogList::changed()
+{
+	refresh();
+}
+
+void LLConversationLogList::changed(const LLUUID& session_id, U32 mask)
+{
+	LLConversationLogListItem* item = getConversationLogListItem(session_id);
+
+	if (!item)
+	{
+		return;
+	}
+
+	if (mask & LLConversationLogObserver::CHANGED_TIME)
+	{
+		item->updateTimestamp();
+
+		// if list is sorted by date and a date of some item has changed,
+		// than the whole list should be rebuilt
+		if (E_SORT_BY_DATE == getSortOrder())
+		{
+			mIsDirty = true;
+		}
+	}
+	else if (mask & LLConversationLogObserver::CHANGED_NAME)
+	{
+		item->updateName();
+		// if list is sorted by name and a name of some item has changed,
+		// than the whole list should be rebuilt
+		if (E_SORT_BY_DATE == getSortOrder())
+		{
+			mIsDirty = true;
+		}
+	}
+	else if (mask & LLConversationLogObserver::CHANGED_OfflineIMs)
+	{
+		item->updateOfflineIMs();
+	}
+}
+
+void LLConversationLogList::addNewItem(const LLConversation* conversation)
+{
+	LLConversationLogListItem* item = new LLConversationLogListItem(&*conversation);
+	if (!mNameFilter.empty())
+	{
+		item->highlightNameDate(mNameFilter);
+	}
+	addItem(item, conversation->getSessionID(), ADD_TOP);
+}
+
+void LLConversationLogList::refresh()
+{
+	rebuildList();
+	sort();
+
+	mIsDirty = false;
+}
+
+void LLConversationLogList::rebuildList()
+{
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	clear();
+
+	bool have_filter = !mNameFilter.empty();
+	LLConversationLog &log_instance = LLConversationLog::instance();
+
+	const std::vector<LLConversation>& conversations = log_instance.getConversations();
+	std::vector<LLConversation>::const_iterator iter = conversations.begin();
+
+	for (; iter != conversations.end(); ++iter)
+	{
+		bool not_found = have_filter && !findInsensitive(iter->getConversationName(), mNameFilter) && !findInsensitive(iter->getTimestamp(), mNameFilter);
+		if (not_found)
+			continue;
+
+		addNewItem(&*iter);
+	}
+
+	// try to restore selection of item
+	if (NULL != selected_conversationp)
+	{
+		selectItemByUUID(selected_conversationp->getSessionID());
+	}
+
+	bool logging_enabled = log_instance.getIsLoggingEnabled();
+	bool log_empty = log_instance.isLogEmpty();
+	if (!logging_enabled && log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_empty"));
+	}
+	else if (!logging_enabled && !log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_disabled_log_not_empty"));
+	}
+	else if (logging_enabled && log_empty)
+	{
+		setNoItemsCommentText(LLTrans::getString("logging_calls_enabled_log_empty"));
+	}
+	else if (logging_enabled && !log_empty)
+	{
+		setNoItemsCommentText("");
+	}
+}
+
+void LLConversationLogList::onCustomAction(const LLSD& userdata)
+{
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp)
+	{
+		return;
+	}
+
+	const std::string command_name = userdata.asString();
+	const LLUUID& selected_conversation_participant_id = selected_conversationp->getParticipantID();
+	const LLUUID& selected_conversation_session_id = selected_conversationp->getSessionID();
+	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+
+	if ("im" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::startIM(selected_conversation_participant_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::startIM(selected_conversation_session_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("call" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::startCall(selected_conversation_participant_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::startCall(selected_conversation_session_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("view_profile" == command_name)
+	{
+		switch (stype)
+		{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+			LLAvatarActions::showProfile(selected_conversation_participant_id);
+			break;
+
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+			LLGroupActions::show(selected_conversation_session_id);
+			break;
+
+		default:
+			break;
+		}
+	}
+	else if ("chat_history" == command_name)
+	{
+		LLFloaterReg::showInstance("preview_conversation", selected_conversation_session_id, true);
+	}
+	else if ("offer_teleport" == command_name)
+	{
+		LLAvatarActions::offerTeleport(selected_conversation_participant_id);
+	}
+	else if("add_friend" == command_name)
+	{
+		if (!LLAvatarActions::isFriend(selected_conversation_participant_id))
+		{
+			LLAvatarActions::requestFriendshipDialog(selected_conversation_participant_id);
+		}
+	}
+	else if("remove_friend" == command_name)
+	{
+		if (LLAvatarActions::isFriend(selected_conversation_participant_id))
+		{
+			LLAvatarActions::removeFriendDialog(selected_conversation_participant_id);
+		}
+	}
+	else if ("invite_to_group" == command_name)
+	{
+		LLAvatarActions::inviteToGroup(selected_conversation_participant_id);
+	}
+	else if ("show_on_map" == command_name)
+	{
+		LLAvatarActions::showOnMap(selected_conversation_participant_id);
+	}
+	else if ("share" == command_name)
+	{
+		LLAvatarActions::share(selected_conversation_participant_id);
+	}
+	else if ("pay" == command_name)
+	{
+		LLAvatarActions::pay(selected_conversation_participant_id);
+	}
+	else if ("block" == command_name)
+	{
+		LLAvatarActions::toggleBlock(selected_conversation_participant_id);
+	}
+}
+
+bool LLConversationLogList::isActionEnabled(const LLSD& userdata)
+{
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp || numSelected() > 1)
+	{
+		return false;
+	}
+
+	const std::string command_name = userdata.asString();
+
+	LLIMModel::LLIMSession::SType stype = getSelectedSessionType();
+	const LLUUID& selected_id = selected_conversationp->getParticipantID();
+
+	bool is_p2p   = LLIMModel::LLIMSession::P2P_SESSION == stype;
+	bool is_group = LLIMModel::LLIMSession::GROUP_SESSION == stype;
+
+	if ("can_im" == command_name || "can_view_profile" == command_name)
+	{
+		return is_p2p || is_group;
+	}
+	else if ("can_view_chat_history" == command_name)
+	{
+		return true;
+	}
+	else if ("can_call"	== command_name)
+	{
+		return (is_p2p || is_group) && LLAvatarActions::canCall();
+	}
+	else if ("add_rem_friend"		== command_name ||
+			 "can_invite_to_group"	== command_name ||
+			 "can_share"			== command_name ||
+			 "can_block"			== command_name ||
+			 "can_pay"				== command_name)
+	{
+		return is_p2p;
+	}
+	else if("can_offer_teleport" == command_name)
+	{
+		return is_p2p && LLAvatarActions::canOfferTeleport(selected_id);
+	}
+	else if ("can_show_on_map" == command_name)
+	{
+		return is_p2p && ((LLAvatarTracker::instance().isBuddyOnline(selected_id) && is_agent_mappable(selected_id)) || gAgent.isGodlike());
+	}
+
+	return false;
+}
+
+bool LLConversationLogList::isActionChecked(const LLSD& userdata)
+{
+	const LLConversation * selected_conversationp = getSelectedConversation();
+
+	if (NULL == selected_conversationp)
+	{
+		return false;
+	}
+
+	const std::string command_name = userdata.asString();
+
+	const LLUUID& selected_id = selected_conversationp->getParticipantID();
+	bool is_p2p = LLIMModel::LLIMSession::P2P_SESSION == getSelectedSessionType();
+
+	if ("is_blocked" == command_name)
+	{
+		return is_p2p && LLAvatarActions::isBlocked(selected_id);
+	}
+	else if ("is_friend" == command_name)
+	{
+		return is_p2p && LLAvatarActions::isFriend(selected_id);
+	}
+	else if ("is_not_friend" == command_name)
+	{
+		return is_p2p && !LLAvatarActions::isFriend(selected_id);
+	}
+
+	return false;
+}
+
+LLIMModel::LLIMSession::SType LLConversationLogList::getSelectedSessionType()
+{
+	const LLConversationLogListItem* item = getSelectedConversationPanel();
+
+	if (item)
+	{
+		return item->getConversation()->getConversationType();
+	}
+
+	return LLIMModel::LLIMSession::NONE_SESSION;
+}
+
+const LLConversationLogListItem* LLConversationLogList::getSelectedConversationPanel()
+{
+	LLPanel* panel = LLFlatListViewEx::getSelectedItem();
+	LLConversationLogListItem* conv_panel = dynamic_cast<LLConversationLogListItem*>(panel);
+
+	return conv_panel;
+}
+
+const LLConversation* LLConversationLogList::getSelectedConversation()
+{
+	const LLConversationLogListItem* panel = getSelectedConversationPanel();
+
+	if (panel)
+	{
+		return panel->getConversation();
+	}
+
+	return NULL;
+}
+
+LLConversationLogListItem* LLConversationLogList::getConversationLogListItem(const LLUUID& session_id)
+{
+	std::vector<LLPanel*> panels;
+	LLFlatListViewEx::getItems(panels);
+	std::vector<LLPanel*>::iterator iter = panels.begin();
+
+	for (; iter != panels.end(); ++iter)
+	{
+		LLConversationLogListItem* item = dynamic_cast<LLConversationLogListItem*>(*iter);
+		if (item && session_id == item->getConversation()->getSessionID())
+		{
+			return item;
+		}
+	}
+
+	return NULL;
+}
+
+LLConversationLogList::ESortOrder LLConversationLogList::getSortOrder()
+{
+	return static_cast<ESortOrder>(gSavedSettings.getU32("CallLogSortOrder"));
+}
+
+bool LLConversationLogListItemComparator::compare(const LLPanel* item1, const LLPanel* item2) const
+{
+	const LLConversationLogListItem* conversation_item1 = dynamic_cast<const LLConversationLogListItem*>(item1);
+	const LLConversationLogListItem* conversation_item2 = dynamic_cast<const LLConversationLogListItem*>(item2);
+
+	if (!conversation_item1 || !conversation_item2)
+	{
+		llerror("conversation_item1 and conversation_item2 cannot be null", 0);
+		return true;
+	}
+
+	return doCompare(conversation_item1, conversation_item2);
+}
+
+bool LLConversationLogListNameComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+	std::string name1 = conversation1->getConversation()->getConversationName();
+	std::string name2 = conversation2->getConversation()->getConversationName();
+	const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+	const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+	LLStringUtil::toUpper(name1);
+	LLStringUtil::toUpper(name2);
+
+	bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+	if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+	{
+		return LLAvatarActions::isFriend(id1);
+	}
+
+	return name1 < name2;
+}
+
+bool LLConversationLogListDateComparator::doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const
+{
+	time_t date1 = conversation1->getConversation()->getTime();
+	time_t date2 = conversation2->getConversation()->getTime();
+	const LLUUID& id1 = conversation1->getConversation()->getParticipantID();
+	const LLUUID& id2 = conversation2->getConversation()->getParticipantID();
+
+	bool friends_first = gSavedSettings.getBOOL("SortFriendsFirst");
+	if (friends_first && (LLAvatarActions::isFriend(id1) ^ LLAvatarActions::isFriend(id2)))
+	{
+		return LLAvatarActions::isFriend(id1);
+	}
+
+	return date1 > date2;
+}
diff --git a/indra/newview/llconversationloglist.h b/indra/newview/llconversationloglist.h
new file mode 100644
index 0000000000000000000000000000000000000000..62ec57e09e660f5a6f9931fa9b08466730a86010
--- /dev/null
+++ b/indra/newview/llconversationloglist.h
@@ -0,0 +1,153 @@
+/**
+ * @file llconversationloglist.h
+ *
+ * $LicenseInfo:firstyear=2002&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 LLCONVERSATIONLOGLIST_H_
+#define LLCONVERSATIONLOGLIST_H_
+
+#include "llconversationlog.h"
+#include "llflatlistview.h"
+#include "lltoggleablemenu.h"
+
+class LLConversationLogListItem;
+
+/**
+ * List of all agent's conversations. I.e. history of conversations.
+ * This list represents contents of the LLConversationLog.
+ * Each change in LLConversationLog leads to rebuilding this list, so
+ * it's always in actual state.
+ */
+
+class LLConversationLogList: public LLFlatListViewEx, public LLConversationLogObserver
+{
+	LOG_CLASS(LLConversationLogList);
+public:
+
+	typedef enum e_sort_oder{
+		E_SORT_BY_NAME = 0,
+		E_SORT_BY_DATE = 1,
+	} ESortOrder;
+
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
+
+	LLConversationLogList(const Params& p);
+	virtual ~LLConversationLogList();
+
+	virtual void draw();
+
+	virtual BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
+
+	LLToggleableMenu*	getContextMenu() const { return mContextMenu.get(); }
+
+	void addNewItem(const LLConversation* conversation);
+	void setNameFilter(const std::string& filter);
+	void sortByName();
+	void sortByDate();
+	void toggleSortFriendsOnTop();
+	bool getSortFriendsOnTop() const { return mIsFriendsOnTop; }
+
+	/**
+	 * Changes from LLConversationLogObserver
+	 */
+	virtual void changed();
+	virtual void changed(const LLUUID& session_id, U32 mask);
+
+private:
+
+	void setDirty(bool dirty = true) { mIsDirty = dirty; }
+	void refresh();
+
+	/**
+	 * Clears list and re-adds items from LLConverstationLog
+	 * If filter is not empty re-adds items which match the filter
+	 */
+	void rebuildList();
+
+	bool findInsensitive(std::string haystack, const std::string& needle_upper);
+
+	void onCustomAction (const LLSD& userdata);
+	bool isActionEnabled(const LLSD& userdata);
+	bool isActionChecked(const LLSD& userdata);
+
+	LLIMModel::LLIMSession::SType getSelectedSessionType();
+	const LLConversationLogListItem* getSelectedConversationPanel();
+	const LLConversation* getSelectedConversation();
+	LLConversationLogListItem* getConversationLogListItem(const LLUUID& session_id);
+
+	ESortOrder getSortOrder();
+
+	LLHandle<LLToggleableMenu>	mContextMenu;
+	bool mIsDirty;
+	bool mIsFriendsOnTop;
+	std::string mNameFilter;
+};
+
+/**
+ * Abstract comparator for ConversationLogList items
+ */
+class LLConversationLogListItemComparator : public LLFlatListView::ItemComparator
+{
+	LOG_CLASS(LLConversationLogListItemComparator);
+
+public:
+	LLConversationLogListItemComparator() {};
+	virtual ~LLConversationLogListItemComparator() {};
+
+	virtual bool compare(const LLPanel* item1, const LLPanel* item2) const;
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const = 0;
+};
+
+class LLConversationLogListNameComparator : public LLConversationLogListItemComparator
+{
+	LOG_CLASS(LLConversationLogListNameComparator);
+
+public:
+	LLConversationLogListNameComparator() {};
+	virtual ~LLConversationLogListNameComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+class LLConversationLogListDateComparator : public LLConversationLogListItemComparator
+{
+	LOG_CLASS(LLConversationLogListDateComparator);
+
+public:
+	LLConversationLogListDateComparator() {};
+	virtual ~LLConversationLogListDateComparator() {};
+
+protected:
+
+	virtual bool doCompare(const LLConversationLogListItem* conversation1, const LLConversationLogListItem* conversation2) const;
+};
+
+#endif /* LLCONVERSATIONLOGLIST_H_ */
diff --git a/indra/newview/llconversationloglistitem.cpp b/indra/newview/llconversationloglistitem.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4e984d603b3bba67db513918b3a271f55f29adff
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.cpp
@@ -0,0 +1,184 @@
+/**
+ * @file llconversationloglistitem.cpp
+ *
+ * $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"
+
+// llui
+#include "lliconctrl.h"
+#include "lltextbox.h"
+#include "lltextutil.h"
+
+// newview
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llconversationlog.h"
+#include "llconversationloglistitem.h"
+#include "llgroupactions.h"
+#include "llgroupiconctrl.h"
+#include "llinventoryicon.h"
+
+LLConversationLogListItem::LLConversationLogListItem(const LLConversation* conversation)
+:	LLPanel(),
+	mConversation(conversation),
+	mConversationName(NULL),
+	mConversationDate(NULL)
+{
+	buildFromFile("panel_conversation_log_list_item.xml");
+
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(mConversation->getSessionID());
+
+	bool ims_are_read = LLFloaterIMSession::isVisible(floater) && floater->hasFocus();
+
+	if (mConversation->hasOfflineMessages() && !ims_are_read)
+	{
+		mIMFloaterShowedConnection = LLFloaterIMSession::setIMFloaterShowedCallback(boost::bind(&LLConversationLogListItem::onIMFloaterShown, this, _1));
+	}
+}
+
+LLConversationLogListItem::~LLConversationLogListItem()
+{
+	mIMFloaterShowedConnection.disconnect();
+}
+
+BOOL LLConversationLogListItem::postBuild()
+{
+	initIcons();
+
+	// set conversation name
+	mConversationName = getChild<LLTextBox>("conversation_name");
+	mConversationName->setValue(mConversation->getConversationName());
+
+	// set conversation date and time
+	mConversationDate = getChild<LLTextBox>("date_time");
+	mConversationDate->setValue(mConversation->getTimestamp());
+
+	getChild<LLButton>("delete_btn")->setClickedCallback(boost::bind(&LLConversationLogListItem::onRemoveBtnClicked, this));
+	setDoubleClickCallback(boost::bind(&LLConversationLogListItem::onDoubleClick, this));
+
+	return TRUE;
+}
+
+void LLConversationLogListItem::initIcons()
+{
+	switch (mConversation->getConversationType())
+	{
+		case LLIMModel::LLIMSession::P2P_SESSION:
+		case LLIMModel::LLIMSession::ADHOC_SESSION:
+		{
+			LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
+			avatar_icon->setVisible(TRUE);
+			avatar_icon->setValue(mConversation->getParticipantID());
+			break;
+		}
+		case LLIMModel::LLIMSession::GROUP_SESSION:
+		{
+			LLGroupIconCtrl* group_icon = getChild<LLGroupIconCtrl>("group_icon");
+			group_icon->setVisible(TRUE);
+			group_icon->setValue(mConversation->getSessionID());
+			break;
+		}
+		default:
+			break;
+	}
+
+	if (mConversation->hasOfflineMessages())
+	{
+			getChild<LLIconCtrl>("unread_ims_icon")->setVisible(TRUE);
+	}
+}
+
+void LLConversationLogListItem::updateTimestamp()
+{
+	mConversationDate->setValue(mConversation->getTimestamp());
+}
+
+void LLConversationLogListItem::updateName()
+{
+	mConversationName->setValue(mConversation->getConversationName());
+}
+
+void LLConversationLogListItem::updateOfflineIMs()
+{
+	getChild<LLIconCtrl>("unread_ims_icon")->setVisible(mConversation->hasOfflineMessages());
+}
+
+void LLConversationLogListItem::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(true);
+	LLPanel::onMouseEnter(x, y, mask);
+}
+
+void LLConversationLogListItem::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+	getChildView("hovered_icon")->setVisible(false);
+	LLPanel::onMouseLeave(x, y, mask);
+}
+
+void LLConversationLogListItem::setValue(const LLSD& value)
+{
+	if (!value.isMap() || !value.has("selected"))
+	{
+		return;
+	}
+
+	getChildView("selected_icon")->setVisible(value["selected"]);
+}
+
+void LLConversationLogListItem::onIMFloaterShown(const LLUUID& session_id)
+{
+	if (mConversation->getSessionID() == session_id)
+	{
+		getChild<LLIconCtrl>("unread_ims_icon")->setVisible(FALSE);
+	}
+}
+
+void LLConversationLogListItem::onRemoveBtnClicked()
+{
+	LLConversationLog::instance().removeConversation(*mConversation);
+}
+
+void LLConversationLogListItem::highlightNameDate(const std::string& highlited_text)
+{
+	LLStyle::Params params;
+	LLTextUtil::textboxSetHighlightedVal(mConversationName, params, mConversation->getConversationName(), highlited_text);
+	LLTextUtil::textboxSetHighlightedVal(mConversationDate, params, mConversation->getTimestamp(), highlited_text);
+}
+
+void LLConversationLogListItem::onDoubleClick()
+{
+	switch (mConversation->getConversationType())
+	{
+	case LLIMModel::LLIMSession::P2P_SESSION:
+		LLAvatarActions::startIM(mConversation->getParticipantID());
+		break;
+
+	case LLIMModel::LLIMSession::GROUP_SESSION:
+		LLGroupActions::startIM(mConversation->getSessionID());
+		break;
+
+	default:
+		break;
+	}
+}
diff --git a/indra/newview/llconversationloglistitem.h b/indra/newview/llconversationloglistitem.h
new file mode 100644
index 0000000000000000000000000000000000000000..ee28456bbba27df2920c58ade83c407e924eacfd
--- /dev/null
+++ b/indra/newview/llconversationloglistitem.h
@@ -0,0 +1,86 @@
+/**
+ * @file llconversationloglistitem.h
+ *
+ * $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 LLCONVERSATIONLOGLISTITEM_H_
+#define LLCONVERSATIONLOGLISTITEM_H_
+
+#include "llfloaterimsession.h"
+#include "llpanel.h"
+
+class LLTextBox;
+class LLConversation;
+
+/**
+ * This class is a visual representation of LLConversation, each of which is LLConversationLog entry.
+ * LLConversationLogList consists of these LLConversationLogListItems.
+ * LLConversationLogListItem consists of:
+ *		conversaion_type_icon
+ *		conversaion_name
+ *		conversaion_date
+ * Also LLConversationLogListItem holds pointer to its LLConversationLog.
+ */
+
+class LLConversationLogListItem : public LLPanel
+{
+public:
+	LLConversationLogListItem(const LLConversation* conversation);
+	virtual ~LLConversationLogListItem();
+
+	void onMouseEnter(S32 x, S32 y, MASK mask);
+	void onMouseLeave(S32 x, S32 y, MASK mask);
+
+	virtual void setValue(const LLSD& value);
+
+	virtual BOOL postBuild();
+
+	void onIMFloaterShown(const LLUUID& session_id);
+	void onRemoveBtnClicked();
+
+	const LLConversation* getConversation() const { return mConversation; }
+
+	void highlightNameDate(const std::string& highlited_text);
+
+	void onDoubleClick();
+
+	/**
+	 * updates string value of last interaction time from conversation
+	 */
+	void updateTimestamp();
+	void updateName();
+	void updateOfflineIMs();
+
+private:
+
+	void initIcons();
+
+	const LLConversation* mConversation;
+
+	LLTextBox*		mConversationName;
+	LLTextBox*		mConversationDate;
+
+	boost::signals2::connection mIMFloaterShowedConnection;
+};
+
+#endif /* LLCONVERSATIONLOGITEM_H_ */
diff --git a/indra/newview/llconversationmodel.cpp b/indra/newview/llconversationmodel.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c74ce24872f87d9125f7720f7f015cba4ac6c31b
--- /dev/null
+++ b/indra/newview/llconversationmodel.cpp
@@ -0,0 +1,702 @@
+/** 
+ * @file llconversationmodel.cpp
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llavatarnamecache.h"
+#include "llavataractions.h"
+#include "llevents.h"
+#include "llfloaterimsession.h"
+#include "llsdutil.h"
+#include "llconversationmodel.h"
+#include "llimview.h" //For LLIMModel
+#include "lltrans.h"
+
+#include <boost/foreach.hpp>
+
+//
+// Conversation items : common behaviors
+//
+
+LLConversationItem::LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
+	mName(display_name),
+	mUUID(uuid),
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
+	mName(""),
+	mUUID(uuid),
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::LLConversationItem(LLFolderViewModelInterface& root_view_model) :
+	LLFolderViewModelItemCommon(root_view_model),
+	mName(""),
+	mUUID(),
+	mNeedsRefresh(true),
+	mConvType(CONV_UNKNOWN),
+	mLastActiveTime(0.0),
+	mDisplayModeratorOptions(false),
+	mAvatarNameCacheConnection()
+{
+}
+
+LLConversationItem::~LLConversationItem()
+{
+	// Disconnect any previous avatar name cache connection to ensure
+	// that the callback method is not called after destruction
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+}
+
+void LLConversationItem::postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant)
+{
+	LLUUID session_id = (session ? session->getUUID() : LLUUID());
+	LLUUID participant_id = (participant ? participant->getUUID() : LLUUID());
+	LLSD event(LLSDMap("type", event_type)("session_uuid", session_id)("participant_uuid", participant_id));
+	LLEventPumps::instance().obtain("ConversationsEvents").post(event);
+}
+
+// Virtual action callbacks
+void LLConversationItem::performAction(LLInventoryModel* model, std::string action)
+{
+}
+
+void LLConversationItem::openItem( void )
+{
+}
+
+void LLConversationItem::closeItem( void )
+{
+}
+
+void LLConversationItem::previewItem( void )
+{
+}
+
+void LLConversationItem::showProperties(void)
+{
+}
+
+void LLConversationItem::buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags)
+{
+	if (flags & ITEM_IN_MULTI_SELECTION)
+	{
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("remove_friends"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		if (static_cast<LLConversationItem*>(mParent)->getType() == CONV_SESSION_NEARBY)
+			items.push_back(std::string("zoom_in"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+		items.push_back(std::string("MuteText"));
+
+		if ((getType() != CONV_SESSION_1_ON_1) && mDisplayModeratorOptions)
+		{
+			items.push_back(std::string("Moderator Options Separator"));
+			items.push_back(std::string("Moderator Options"));
+			items.push_back(std::string("AllowTextChat"));
+			items.push_back(std::string("moderate_voice_separator"));
+			items.push_back(std::string("ModerateVoiceMuteSelected"));
+			items.push_back(std::string("ModerateVoiceUnMuteSelected"));
+			items.push_back(std::string("ModerateVoiceMute"));
+			items.push_back(std::string("ModerateVoiceUnmute"));
+		}
+	}
+}
+
+// method does subscription to changes in avatar name cache for current session/participant conversation item.
+void LLConversationItem::fetchAvatarName(bool isParticipant /*= true*/)
+{
+	LLUUID item_id = getUUID();
+
+	// item should not be null for participants
+	if (isParticipant)
+	{
+		llassert(item_id.notNull());
+	}
+
+	// disconnect any previous avatar name cache connection
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	// exclude nearby chat item
+	if (item_id.notNull())
+	{
+		// for P2P session item, override it as item of called agent
+		if (CONV_SESSION_1_ON_1 == getType())
+		{
+			item_id = LLIMModel::getInstance()->getOtherParticipantID(item_id);
+		}
+
+		// subscribe on avatar name cache changes for participant and session items
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(item_id, boost::bind(&LLConversationItem::onAvatarNameCache, this, _2));
+	}
+}
+
+//
+// LLConversationItemSession
+// 
+
+LLConversationItemSession::LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(display_name,uuid,root_view_model),
+	mIsLoaded(false)
+{
+	mConvType = CONV_SESSION_UNKNOWN;
+}
+
+LLConversationItemSession::LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(uuid,root_view_model)
+{
+	mConvType = CONV_SESSION_UNKNOWN;
+}
+
+bool LLConversationItemSession::hasChildren() const
+{
+	return getChildrenCount() > 0;
+}
+
+void LLConversationItemSession::addParticipant(LLConversationItemParticipant* participant)
+{
+	addChild(participant);
+	mIsLoaded = true;
+	mNeedsRefresh = true;
+	updateName(participant);
+	postEvent("add_participant", this, participant);
+}
+
+void LLConversationItemSession::updateName(LLConversationItemParticipant* participant)
+{
+	EConversationType conversation_type = getType();
+	// We modify the session name only in the case of an ad-hoc session or P2P session, exit otherwise (nothing to do)
+	if ((conversation_type != CONV_SESSION_AD_HOC) && (conversation_type != CONV_SESSION_1_ON_1))
+	{
+		return;
+	}
+
+	// Avoid changing the default name if no participant present yet
+	if (mChildren.size() == 0)
+	{
+		return;
+	}
+
+	uuid_vec_t temp_uuids; // uuids vector for building the added participants' names string
+	if (conversation_type == CONV_SESSION_AD_HOC || conversation_type == CONV_SESSION_1_ON_1)
+	{
+		// Build a string containing the participants UUIDs (minus own agent) and check if ready for display (we don't want "(waiting)" in there)
+		// Note: we don't bind ourselves to the LLAvatarNameCache event as updateParticipantName() is called by
+		// onAvatarNameCache() which is itself attached to the same event.
+
+		// In the case of a P2P conversation, we need to grab the name of the other participant in the session instance itself
+		// as we do not create participants for such a session.
+
+		LLFolderViewModelItem * itemp;
+		BOOST_FOREACH(itemp, mChildren)
+		{
+			LLConversationItem* current_participant = dynamic_cast<LLConversationItem*>(itemp);
+			// Add the avatar uuid to the list (except if it's the own agent uuid)
+			if (current_participant->getUUID() != gAgentID)
+			{
+				LLAvatarName av_name;
+				if (LLAvatarNameCache::get(current_participant->getUUID(), &av_name))
+				{
+					temp_uuids.push_back(current_participant->getUUID());
+
+					if (conversation_type == CONV_SESSION_1_ON_1)
+					{
+						break;
+					}
+				}
+			}
+		}
+	}
+
+	if (temp_uuids.size() != 0)
+	{
+		std::string new_session_name;
+		LLAvatarActions::buildResidentsString(temp_uuids, new_session_name);
+		renameItem(new_session_name);
+		postEvent("update_session", this, NULL);
+	}
+}
+
+void LLConversationItemSession::removeParticipant(LLConversationItemParticipant* participant)
+{
+	removeChild(participant);
+	mNeedsRefresh = true;
+	updateName(participant);
+	postEvent("remove_participant", this, participant);
+}
+
+void LLConversationItemSession::removeParticipant(const LLUUID& participant_id)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		removeParticipant(participant);
+	}
+}
+
+void LLConversationItemSession::clearParticipants()
+{
+	clearChildren();
+	mIsLoaded = false;
+	mNeedsRefresh = true;
+}
+
+LLConversationItemParticipant* LLConversationItemSession::findParticipant(const LLUUID& participant_id)
+{
+	// This is *not* a general tree parsing algorithm. It assumes that a session contains only 
+	// items (LLConversationItemParticipant) that have themselve no children.
+	LLConversationItemParticipant* participant = NULL;
+	child_list_t::iterator iter;
+	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	{
+		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		if (participant->hasSameValue(participant_id))
+		{
+			break;
+		}
+	}
+	return (iter == mChildren.end() ? NULL : participant);
+}
+
+void LLConversationItemSession::setParticipantIsMuted(const LLUUID& participant_id, bool is_muted)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->muteVoice(is_muted);
+	}
+}
+
+void LLConversationItemSession::setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setIsModerator(is_moderator);
+	}
+}
+
+void LLConversationItemSession::setTimeNow(const LLUUID& participant_id)
+{
+	mLastActiveTime = LLFrameTimer::getElapsedSeconds();
+	mNeedsRefresh = true;
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setTimeNow();
+	}
+}
+
+void LLConversationItemSession::setDistance(const LLUUID& participant_id, F64 dist)
+{
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
+	{
+		participant->setDistance(dist);
+		mNeedsRefresh = true;
+	}
+}
+
+void LLConversationItemSession::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+    lldebugs << "LLConversationItemParticipant::buildContextMenu()" << llendl;
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+
+    if(this->getType() == CONV_SESSION_1_ON_1)
+    {
+        items.push_back(std::string("close_conversation"));
+        items.push_back(std::string("separator_disconnect_from_voice"));
+        buildParticipantMenuOptions(items, flags);
+    }
+    else if(this->getType() == CONV_SESSION_GROUP)
+    {
+        items.push_back(std::string("close_conversation"));
+        addVoiceOptions(items);
+        items.push_back(std::string("chat_history"));
+        items.push_back(std::string("separator_chat_history"));
+        items.push_back(std::string("group_profile"));
+        items.push_back(std::string("activate_group"));
+        items.push_back(std::string("leave_group"));
+    }
+    else if(this->getType() == CONV_SESSION_AD_HOC)
+    {
+        items.push_back(std::string("close_conversation"));
+        addVoiceOptions(items);
+        items.push_back(std::string("chat_history"));
+    }
+
+    hide_context_entries(menu, items, disabled_items);
+}
+
+void LLConversationItemSession::addVoiceOptions(menuentry_vec_t& items)
+{
+    LLVoiceChannel* voice_channel = LLIMModel::getInstance() ? LLIMModel::getInstance()->getVoiceChannel(this->getUUID()) : NULL;
+
+    if(voice_channel != LLVoiceChannel::getCurrentVoiceChannel())
+    {
+        items.push_back(std::string("open_voice_conversation"));
+    }
+    else
+    {
+        items.push_back(std::string("disconnect_from_voice"));
+    }
+}
+
+// The time of activity of a session is the time of the most recent activity, session and participants included
+const bool LLConversationItemSession::getTime(F64& time) const
+{
+	F64 most_recent_time = mLastActiveTime;
+	bool has_time = (most_recent_time > 0.1);
+	LLConversationItemParticipant* participant = NULL;
+	child_list_t::const_iterator iter;
+	for (iter = mChildren.begin(); iter != mChildren.end(); iter++)
+	{
+		participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+		F64 participant_time;
+		if (participant->getTime(participant_time))
+		{
+			has_time = true;
+			most_recent_time = llmax(most_recent_time,participant_time);
+		}
+	}
+	if (has_time)
+	{
+		time = most_recent_time;
+	}
+	return has_time;
+}
+
+void LLConversationItemSession::dumpDebugData(bool dump_children)
+{
+	// Session info
+	llinfos << "Merov debug : session " << this << ", uuid = " << mUUID << ", name = " << mName << ", is loaded = " << mIsLoaded << llendl;
+	// Children info
+	if (dump_children)
+	{
+		for (child_list_t::iterator iter = mChildren.begin(); iter != mChildren.end(); iter++)
+		{
+			LLConversationItemParticipant* participant = dynamic_cast<LLConversationItemParticipant*>(*iter);
+			if (participant)
+			{
+				participant->dumpDebugData();
+			}
+		}
+	}
+}
+
+// should be invoked only for P2P sessions
+void LLConversationItemSession::onAvatarNameCache(const LLAvatarName& av_name)
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	renameItem(av_name.getDisplayName());
+	postEvent("update_session", this, NULL);
+}
+
+//
+// LLConversationItemParticipant
+// 
+
+LLConversationItemParticipant::LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(display_name,uuid,root_view_model),
+	mIsModerator(false),
+	mDisplayModeratorLabel(false),
+	mDistToAgent(-1.0)
+{
+	mDisplayName = display_name;
+	mConvType = CONV_PARTICIPANT;
+}
+
+LLConversationItemParticipant::LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItem(uuid,root_view_model),
+	mIsModerator(false),
+	mDisplayModeratorLabel(false),
+	mDistToAgent(-1.0)
+{
+	mConvType = CONV_PARTICIPANT;
+}
+
+void LLConversationItemParticipant::updateName()
+{
+	llassert(getUUID().notNull());
+	if (getUUID().notNull())
+	{
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(getUUID(),&av_name))
+		{
+			updateName(av_name);
+		}
+	}
+}
+
+void LLConversationItemParticipant::onAvatarNameCache(const LLAvatarName& av_name)
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
+	updateName(av_name);
+}
+
+void LLConversationItemParticipant::updateName(const LLAvatarName& av_name)
+{
+	mName = av_name.getUserName();
+	mDisplayName = av_name.getDisplayName();
+	
+	if (mDisplayModeratorLabel)
+	{
+		mDisplayName += " " + LLTrans::getString("IM_moderator_label");
+	}
+	
+	renameItem(mDisplayName);
+	if (mParent != NULL)
+	{
+		LLConversationItemSession* parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+		if (parent_session != NULL)
+		{
+			parent_session->requestSort();
+			parent_session->updateName(this);
+			postEvent("update_participant", parent_session, this);
+		}
+	}
+}
+
+void LLConversationItemParticipant::buildContextMenu(LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	buildParticipantMenuOptions(items, flags);
+	
+    hide_context_entries(menu, items, disabled_items);
+}
+
+LLConversationItemSession* LLConversationItemParticipant::getParentSession()
+{
+	LLConversationItemSession* parent_session = NULL;
+	if (hasParent())
+	{
+		parent_session = dynamic_cast<LLConversationItemSession*>(mParent);
+	}
+	return parent_session;
+}
+
+void LLConversationItemParticipant::dumpDebugData()
+{
+	llinfos << "Merov debug : participant, uuid = " << mUUID << ", name = " << mName << ", display name = " << mDisplayName << ", muted = " << isVoiceMuted() << ", moderator = " << mIsModerator << llendl;
+}
+
+void LLConversationItemParticipant::setDisplayModeratorRole(bool displayRole)
+{ 
+	if (displayRole != mDisplayModeratorLabel)
+	{
+		mDisplayModeratorLabel = displayRole;
+		updateName();
+	}
+}
+
+bool LLConversationItemParticipant::isVoiceMuted()
+{
+	return LLMuteList::getInstance()->isMuted(mUUID, LLMute::flagVoiceChat);
+}
+
+void LLConversationItemParticipant::muteVoice(bool mute_voice)
+{
+	std::string name;
+	gCacheName->getFullName(mUUID, name);
+	LLMuteList * mute_listp = LLMuteList::getInstance();
+	bool voice_already_muted = mute_listp->isMuted(mUUID, name);
+
+	LLMute mute(mUUID, name, LLMute::AGENT);
+	if (voice_already_muted && !mute_voice)
+	{
+		mute_listp->remove(mute);
+	}
+	else if (!voice_already_muted && mute_voice)
+	{
+		mute_listp->add(mute);
+	}
+}
+
+//
+// LLConversationSort
+// 
+
+// Comparison operator: returns "true" is a comes before b, "false" otherwise
+bool LLConversationSort::operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const
+{
+	LLConversationItem::EConversationType type_a = a->getType();
+	LLConversationItem::EConversationType type_b = b->getType();
+
+	if ((type_a == LLConversationItem::CONV_PARTICIPANT) && (type_b == LLConversationItem::CONV_PARTICIPANT))
+	{
+		// If both items are participants
+		U32 sort_order = getSortOrderParticipants();
+		if (sort_order == LLConversationFilter::SO_DATE)
+		{
+			F64 time_a = 0.0;
+			F64 time_b = 0.0;
+			bool has_time_a = a->getTime(time_a);
+			bool has_time_b = b->getTime(time_b);
+			if (has_time_a && has_time_b)
+			{
+				// Most recent comes first
+				return (time_a > time_b);
+			}
+			else if (has_time_a || has_time_b)
+			{
+				// If we have only one time available, the element with time must come first
+				return has_time_a;
+			}
+			// If no time available, we'll default to sort by name at the end of this method
+		}
+		else if (sort_order == LLConversationFilter::SO_DISTANCE)
+		{
+			F64 dist_a = 0.0;
+			F64 dist_b = 0.0;
+			bool has_dist_a = a->getDistanceToAgent(dist_a);
+			bool has_dist_b = b->getDistanceToAgent(dist_b);
+			if (has_dist_a && has_dist_b)
+			{
+				// Closest comes first
+				return (dist_a < dist_b);
+			}
+			else if (has_dist_a || has_dist_b)
+			{
+				// If we have only one distance available, the element with it must come first
+				return has_dist_a;
+			}
+			// If no distance available, we'll default to sort by name at the end of this method
+		}
+	}
+	else if ((type_a > LLConversationItem::CONV_PARTICIPANT) && (type_b > LLConversationItem::CONV_PARTICIPANT))
+	{
+		// If both are sessions
+		U32 sort_order = getSortOrderSessions();
+
+		if (sort_order == LLConversationFilter::SO_DATE)
+		{
+			// Sort by time
+			F64 time_a = 0.0;
+			F64 time_b = 0.0;
+			bool has_time_a = a->getTime(time_a);
+			bool has_time_b = b->getTime(time_b);
+			if (has_time_a && has_time_b)
+			{
+				// Most recent comes first
+				return (time_a > time_b);
+			}
+			else if (has_time_a || has_time_b)
+			{
+				// If we have only one time available, the element with time must come first
+				return has_time_a;
+			}
+			// If no time available, we'll default to sort by name at the end of this method
+		}
+		else
+		{
+			if ((type_a == LLConversationItem::CONV_SESSION_NEARBY) || (type_b == LLConversationItem::CONV_SESSION_NEARBY))
+			{
+				// If one is the nearby session, put nearby session *always* last
+				return (type_b == LLConversationItem::CONV_SESSION_NEARBY);
+			}
+			else if (sort_order == LLConversationFilter::SO_SESSION_TYPE)
+			{
+				if (type_a != type_b)
+				{
+					// Lowest types come first. See LLConversationItem definition of types
+					return (type_a < type_b);
+				}
+			// If types are identical, we'll default to sort by name at the end of this method
+			}
+		}
+	}
+	else
+	{
+		// If one item is a participant and the other a session, the session comes before the participant
+		// so we simply compare the type
+		// Notes: as a consequence, CONV_UNKNOWN (which should never get created...) always come first
+		return (type_a > type_b);
+	}
+	// By default, in all other possible cases (including sort order type LLConversationFilter::SO_NAME of course), 
+	// we sort by name
+	S32 compare = LLStringUtil::compareDict(a->getName(), b->getName());
+	return (compare < 0);
+}
+
+//
+// LLConversationViewModel
+//
+
+void LLConversationViewModel::sort(LLFolderViewFolder* folder) 
+{
+	base_t::sort(folder);
+}
+
+// EOF
diff --git a/indra/newview/llconversationmodel.h b/indra/newview/llconversationmodel.h
new file mode 100755
index 0000000000000000000000000000000000000000..876658504946906aaa1b10747111b26672a85377
--- /dev/null
+++ b/indra/newview/llconversationmodel.h
@@ -0,0 +1,314 @@
+/** 
+ * @file llconversationmodel.h
+ * @brief Implementation of conversations list
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONVERSATIONMODEL_H
+#define LL_LLCONVERSATIONMODEL_H
+
+#include <boost/signals2.hpp>
+
+#include "llavatarname.h"
+#include "../llui/llfolderviewitem.h"
+#include "../llui/llfolderviewmodel.h"
+#include "llviewerfoldertype.h"
+
+// Implementation of conversations list
+
+class LLConversationItem;
+class LLConversationItemSession;
+class LLConversationItemParticipant;
+
+typedef std::map<LLUUID, LLConversationItem*> conversations_items_map;
+typedef std::map<LLUUID, LLFolderViewItem*> conversations_widgets_map;
+
+typedef std::vector<std::string> menuentry_vec_t;
+
+// Conversation items: we hold a list of those and create an LLFolderViewItem widget for each  
+// that we tuck into the mConversationsListPanel. 
+class LLConversationItem : public LLFolderViewModelItemCommon
+{
+public:
+	enum EConversationType
+	{
+		CONV_UNKNOWN         = 0,
+		CONV_PARTICIPANT     = 1,
+		CONV_SESSION_NEARBY  = 2,	// The order counts here as it is used to sort sessions by type
+		CONV_SESSION_1_ON_1  = 3,
+		CONV_SESSION_AD_HOC  = 4,
+		CONV_SESSION_GROUP   = 5,
+		CONV_SESSION_UNKNOWN = 6
+	};
+	
+	LLConversationItem(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItem(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItem(LLFolderViewModelInterface& root_view_model);
+	virtual ~LLConversationItem();
+
+	// Stub those things we won't really be using in this conversation context
+	virtual const std::string& getName() const { return mName; }
+	virtual const std::string& getDisplayName() const { return mName; }
+	virtual const std::string& getSearchableName() const { return mName; }
+	virtual const LLUUID& getUUID() const { return mUUID; }
+	virtual time_t getCreationDate() const { return 0; }
+	virtual LLPointer<LLUIImage> getIcon() const { return NULL; }
+	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
+	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
+	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
+	virtual BOOL isItemRenameable() const { return TRUE; }
+	virtual BOOL renameItem(const std::string& new_name) { mName = new_name; mNeedsRefresh = true; return TRUE; }
+	virtual BOOL isItemMovable( void ) const { return FALSE; }
+	virtual BOOL isItemRemovable( void ) const { return FALSE; }
+	virtual BOOL isItemInTrash( void) const { return FALSE; }
+	virtual BOOL removeItem() { return FALSE; }
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch) { }
+	virtual void move( LLFolderViewModelItem* parent_listener ) { }
+	virtual BOOL isItemCopyable() const { return FALSE; }
+	virtual BOOL copyToClipboard() const { return FALSE; }
+	virtual BOOL cutToClipboard() const { return FALSE; }
+	virtual BOOL isClipboardPasteable() const { return FALSE; }
+	virtual void pasteFromClipboard() { }
+	virtual void pasteLinkFromClipboard() { }
+	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) { }
+	virtual BOOL isUpToDate() const { return TRUE; }
+	virtual bool hasChildren() const { return FALSE; }
+
+	virtual bool potentiallyVisible() { return true; }
+	virtual bool filter( LLFolderViewFilter& filter) { return false; }
+	virtual bool descendantsPassedFilter(S32 filter_generation = -1) { return true; }
+	virtual void setPassedFilter(bool passed, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0) { }
+	virtual bool passedFilter(S32 filter_generation = -1) { return true; }
+
+	// The action callbacks
+	virtual void performAction(LLInventoryModel* model, std::string action);
+	virtual void openItem( void );
+	virtual void closeItem( void );
+	virtual void previewItem( void );
+	virtual void selectItem(void) { } 
+	virtual void showProperties(void);
+
+	// Methods used in sorting (see LLConversationSort::operator())
+	EConversationType const getType() const { return mConvType; }
+	virtual const bool getTime(F64& time) const { time = mLastActiveTime; return (time > 0.1); }
+	virtual const bool getDistanceToAgent(F64& distance) const { return false; }
+	
+	// This method will be called to determine if a drop can be
+	// performed, and will set drop to TRUE if a drop is
+	// requested. 
+	// Returns TRUE if a drop is possible/happened, FALSE otherwise.
+	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
+							EDragAndDropType cargo_type,
+							void* cargo_data,
+							std::string& tooltip_msg) { return FALSE; }
+	
+//	bool hasSameValues(std::string name, const LLUUID& uuid) { return ((name == mName) && (uuid == mUUID)); }
+	bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+	
+	void resetRefresh() { mNeedsRefresh = false; }
+	bool needsRefresh() { return mNeedsRefresh; }
+	
+	void postEvent(const std::string& event_type, LLConversationItemSession* session, LLConversationItemParticipant* participant);
+	
+    void buildParticipantMenuOptions(menuentry_vec_t& items, U32 flags);
+
+	void fetchAvatarName(bool isParticipant = true);		// fetch and update the avatar name
+
+protected:
+	virtual void onAvatarNameCache(const LLAvatarName& av_name) {}
+
+	std::string mName;	// Name of the session or the participant
+	LLUUID mUUID;		// UUID of the session or the participant
+	EConversationType mConvType;	// Type of conversation item
+	bool mNeedsRefresh;	// Flag signaling to the view that something changed for this item
+	F64  mLastActiveTime;
+	bool mDisplayModeratorOptions;
+	boost::signals2::connection mAvatarNameCacheConnection;
+};	
+
+class LLConversationItemSession : public LLConversationItem
+{
+public:
+	LLConversationItemSession(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItemSession(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	
+	/*virtual*/ bool hasChildren() const;
+    LLPointer<LLUIImage> getIcon() const { return NULL; }
+	void setSessionID(const LLUUID& session_id) { mUUID = session_id; mNeedsRefresh = true; }
+	void addParticipant(LLConversationItemParticipant* participant);
+	void updateName(LLConversationItemParticipant* participant);
+	void removeParticipant(LLConversationItemParticipant* participant);
+	void removeParticipant(const LLUUID& participant_id);
+	void clearParticipants();
+	LLConversationItemParticipant* findParticipant(const LLUUID& participant_id);
+
+	void setParticipantIsMuted(const LLUUID& participant_id, bool is_muted);
+	void setParticipantIsModerator(const LLUUID& participant_id, bool is_moderator);
+	void setTimeNow(const LLUUID& participant_id);
+	void setDistance(const LLUUID& participant_id, F64 dist);
+	
+	bool isLoaded() { return mIsLoaded; }
+	
+    void buildContextMenu(LLMenuGL& menu, U32 flags);
+    void addVoiceOptions(menuentry_vec_t& items);
+	virtual const bool getTime(F64& time) const;
+
+	void dumpDebugData(bool dump_children = false);
+
+private:
+	/*virtual*/ void onAvatarNameCache(const LLAvatarName& av_name);
+
+	bool mIsLoaded;		// true if at least one participant has been added to the session, false otherwise
+};
+
+class LLConversationItemParticipant : public LLConversationItem
+{
+public:
+	LLConversationItemParticipant(std::string display_name, const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	LLConversationItemParticipant(const LLUUID& uuid, LLFolderViewModelInterface& root_view_model);
+	
+	virtual const std::string& getDisplayName() const { return mDisplayName; }
+
+	bool isVoiceMuted();
+	bool isModerator() const { return mIsModerator; }
+	void muteVoice(bool mute_voice);
+	void setIsModerator(bool is_moderator) { mIsModerator = is_moderator; mNeedsRefresh = true; }
+	void setTimeNow() { mLastActiveTime = LLFrameTimer::getElapsedSeconds(); mNeedsRefresh = true; }
+	void setDistance(F64 dist) { mDistToAgent = dist; mNeedsRefresh = true; }
+
+    void buildContextMenu(LLMenuGL& menu, U32 flags);
+
+	virtual const bool getDistanceToAgent(F64& dist) const { dist = mDistToAgent; return (dist >= 0.0); }
+
+	void updateName();	// get from the cache (do *not* fetch) and update the avatar name
+	LLConversationItemSession* getParentSession();
+
+	void dumpDebugData();
+	void setModeratorOptionsVisible(bool visible) { mDisplayModeratorOptions = visible; }
+	void setDisplayModeratorRole(bool displayRole);
+
+private:
+	void onAvatarNameCache(const LLAvatarName& av_name);	// callback used by fetchAvatarName
+	void updateName(const LLAvatarName& av_name);
+
+	bool mIsMuted;		         // default is false
+	bool mIsModerator;	         // default is false
+	bool mDisplayModeratorLabel; // default is false
+	std::string mDisplayName;
+	F64  mDistToAgent;  // Distance to the agent. A negative (meaningless) value means the distance has not been set.
+	boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+// We don't want to ever filter conversations but we need to declare that class to create a conversation view model.
+// We just stubb everything for the moment.
+class LLConversationFilter : public LLFolderViewFilter
+{
+public:
+		
+	enum ESortOrderType
+	{
+		SO_NAME = 0,						// Sort by name
+		SO_DATE = 0x1,						// Sort by date (most recent)
+		SO_SESSION_TYPE = 0x2,				// Sort by type (valid only for sessions)
+		SO_DISTANCE = 0x3,					// Sort by distance (valid only for participants in nearby chat)
+	};
+	// Default sort order is by type for sessions and by date for participants
+	static const U32 SO_DEFAULT = (SO_SESSION_TYPE << 16) | (SO_DATE);
+	
+	LLConversationFilter() { mEmpty = ""; }
+	~LLConversationFilter() {}
+		
+	bool 				check(const LLFolderViewModelItem* item) { return true; }
+	bool				checkFolder(const LLFolderViewModelItem* folder) const { return true; }
+	void 				setEmptyLookupMessage(const std::string& message) { }
+	std::string			getEmptyLookupMessage() const { return mEmpty; }
+	bool				showAllResults() const { return true; }
+	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const { return std::string::npos; }
+	std::string::size_type getFilterStringSize() const { return 0; }
+		
+	bool 				isActive() const { return false; }
+	bool 				isModified() const { return false; }
+	void 				clearModified() { }
+	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() { }
+		
+	bool 				isDefault() const { return true; }
+	bool 				isNotDefault() const { return false; }
+	void 				markDefault() { }
+	void 				resetDefault() { }
+		
+	S32 				getCurrentGeneration() const { return 0; }
+	S32 				getFirstSuccessGeneration() const { return 0; }
+	S32 				getFirstRequiredGeneration() const { return 0; }
+private:
+	std::string mEmpty;
+};
+
+class LLConversationSort
+{
+public:
+	LLConversationSort(U32 order = LLConversationFilter::SO_DEFAULT) : mSortOrder(order) { }
+	
+	// 16 LSB bits used for participants, 16 MSB bits for sessions
+	U32 getSortOrderSessions() const { return ((mSortOrder >> 16) & 0xFFFF); }
+	U32 getSortOrderParticipants() const { return (mSortOrder & 0xFFFF); }
+	void setSortOrderSessions(LLConversationFilter::ESortOrderType session) { mSortOrder = ((session & 0xFFFF) << 16) | (mSortOrder & 0xFFFF); }
+	void setSortOrderParticipants(LLConversationFilter::ESortOrderType participant) { mSortOrder = (mSortOrder & 0xFFFF0000) | (participant & 0xFFFF); }
+
+	bool operator()(const LLConversationItem* const& a, const LLConversationItem* const& b) const;
+	operator U32() const { return mSortOrder; }
+private:
+	// Note: we're treating this value as a sort order bitmask as done in other places in the code (e.g. inventory)
+	U32  mSortOrder;
+};
+
+class LLConversationViewModel
+:	public LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter>
+{
+public:
+	typedef LLFolderViewModel<LLConversationSort, LLConversationItem, LLConversationItem, LLConversationFilter> base_t;
+	
+	void sort(LLFolderViewFolder* folder);
+	bool contentsReady() { return true; }	// *TODO : we need to check that participants names are available somewhat
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items) { return false; } // We do not allow drag of conversation items
+	
+private:
+};
+
+// Utility function to hide all entries except those in the list
+// Can be called multiple times on the same menu (e.g. if multiple items
+// are selected).  If "append" is false, then only common enabled items
+// are set as enabled.
+
+//(defined in inventorybridge.cpp)
+//TODO: Gilbert Linden - Refactor to make this function non-global
+void hide_context_entries(LLMenuGL& menu, 
+    const menuentry_vec_t &entries_to_show, 
+    const menuentry_vec_t &disabled_entries);
+
+#endif // LL_LLCONVERSATIONMODEL_H
diff --git a/indra/newview/llconversationview.cpp b/indra/newview/llconversationview.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..b6c53e5e30f6dae92d95857597dd2826003850d9
--- /dev/null
+++ b/indra/newview/llconversationview.cpp
@@ -0,0 +1,696 @@
+/** 
+ * @file llconversationview.cpp
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llconversationview.h"
+
+#include <boost/bind.hpp>
+#include "llagentdata.h"
+#include "llconversationmodel.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimsessiontab.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterreg.h"
+#include "llgroupiconctrl.h"
+#include "lluictrlfactory.h"
+#include "lltoolbarview.h"
+
+//
+// Implementation of conversations list session widgets
+//
+static LLDefaultChildRegistry::Register<LLConversationViewSession> r_conversation_view_session("conversation_view_session");
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
+class LLNearbyVoiceClientStatusObserver : public LLVoiceClientStatusObserver
+{
+public:
+
+	LLNearbyVoiceClientStatusObserver(LLConversationViewSession* conv)
+	:	conversation(conv)
+	{}
+
+	virtual void onChange(EStatusType status, const std::string &channelURI, bool proximal)
+	{
+		conversation->showVoiceIndicator(conversation
+			&& status != STATUS_JOINING
+			&& status != STATUS_LEFT_CHANNEL
+			&& LLVoiceClient::getInstance()->voiceEnabled()
+			&& LLVoiceClient::getInstance()->isVoiceWorking());
+	}
+
+private:
+	LLConversationViewSession* conversation;
+};
+
+LLConversationViewSession::Params::Params() :	
+	container()
+{}
+
+LLConversationViewSession::LLConversationViewSession(const LLConversationViewSession::Params& p):
+	LLFolderViewFolder(p),
+	mContainer(p.container),
+	mItemPanel(NULL),
+	mCallIconLayoutPanel(NULL),
+	mSessionTitle(NULL),
+	mSpeakingIndicator(NULL),
+	mVoiceClientObserver(NULL),
+	mCollapsedMode(false),
+    mHasArrow(true),
+	mIsInActiveVoiceChannel(false),
+	mFlashStateOn(false),
+	mFlashStarted(false)
+{
+	mFlashTimer = new LLFlashTimer();
+}
+
+LLConversationViewSession::~LLConversationViewSession()
+{
+	mActiveVoiceChannelConnection.disconnect();
+
+	if(LLVoiceClient::instanceExists() && mVoiceClientObserver)
+	{
+		LLVoiceClient::getInstance()->removeObserver(mVoiceClientObserver);
+	}
+
+	mFlashTimer->unset();
+}
+
+void LLConversationViewSession::setFlashState(bool flash_state)
+{
+	if (flash_state && !mFlashStateOn)
+	{
+		// flash chat toolbar button if scrolled out of sight (because flashing will not be visible)
+		if (mContainer->isScrolledOutOfSight(this))
+		{
+			gToolBarView->flashCommand(LLCommandId("chat"), true);
+		}
+	}
+
+	mFlashStateOn = flash_state;
+	mFlashStarted = false;
+	mFlashTimer->stopFlashing();
+}
+
+void LLConversationViewSession::startFlashing()
+{
+	if (isInVisibleChain() && mFlashStateOn && !mFlashStarted)
+	{
+		mFlashStarted = true;
+		mFlashTimer->startFlashing();
+	}
+}
+
+bool LLConversationViewSession::isHighlightAllowed()
+{
+	return mFlashStateOn || mIsSelected;
+}
+
+bool LLConversationViewSession::isHighlightActive()
+{
+	return (mFlashStateOn ? (mFlashTimer->isFlashingInProgress() ? mFlashTimer->isCurrentlyHighlighted() : true) : mIsCurSelection);
+}
+
+BOOL LLConversationViewSession::postBuild()
+{
+	LLFolderViewItem::postBuild();
+
+	mItemPanel = LLUICtrlFactory::getInstance()->createFromFile<LLPanel>("panel_conversation_list_item.xml", NULL, LLPanel::child_registry_t::instance());
+	addChild(mItemPanel);
+
+	mCallIconLayoutPanel = mItemPanel->getChild<LLPanel>("call_icon_panel");
+	mSessionTitle = mItemPanel->getChild<LLTextBox>("conversation_title");
+
+	mActiveVoiceChannelConnection = LLVoiceChannel::setCurrentVoiceChannelChangedCallback(boost::bind(&LLConversationViewSession::onCurrentVoiceSessionChanged, this, _1));
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	if (vmi)
+	{
+		switch(vmi->getType())
+		{
+		case LLConversationItem::CONV_PARTICIPANT:
+		case LLConversationItem::CONV_SESSION_1_ON_1:
+		{
+			LLIMModel::LLIMSession* session=  LLIMModel::instance().findIMSession(vmi->getUUID());
+			if (session)
+			{
+				LLAvatarIconCtrl* icon = mItemPanel->getChild<LLAvatarIconCtrl>("avatar_icon");
+				icon->setVisible(true);
+				icon->setValue(session->mOtherParticipantID);
+				mSpeakingIndicator->setSpeakerId(gAgentID, session->mSessionID, true);
+                mHasArrow = false;
+			}
+			break;
+		}
+		case LLConversationItem::CONV_SESSION_AD_HOC:
+		{
+			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+			icon->setVisible(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+			break;
+		}
+		case LLConversationItem::CONV_SESSION_GROUP:
+		{
+			LLGroupIconCtrl* icon = mItemPanel->getChild<LLGroupIconCtrl>("group_icon");
+			icon->setVisible(true);
+			icon->setValue(vmi->getUUID());
+			mSpeakingIndicator->setSpeakerId(gAgentID, vmi->getUUID(), true);
+			break;
+		}
+		case LLConversationItem::CONV_SESSION_NEARBY:
+		{
+			LLIconCtrl* icon = mItemPanel->getChild<LLIconCtrl>("nearby_chat_icon");
+			icon->setVisible(true);
+			mSpeakingIndicator->setSpeakerId(gAgentID, LLUUID::null, true);
+			mIsInActiveVoiceChannel = true;
+			if(LLVoiceClient::instanceExists())
+			{
+				LLNearbyVoiceClientStatusObserver* mVoiceClientObserver = new LLNearbyVoiceClientStatusObserver(this);
+				LLVoiceClient::getInstance()->addObserver(mVoiceClientObserver);
+			}
+			break;
+		}
+		default:
+			break;
+		}
+	}
+
+	refresh();
+
+	return TRUE;
+}
+
+void LLConversationViewSession::draw()
+{
+	getViewModelItem()->update();
+
+	const LLFolderViewItem::Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
+	const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+
+	// Indicate that flash can start (moot operation if already started, done or not flashing)
+	startFlashing();
+
+	// draw highlight for selected items
+	drawHighlight(show_context, true, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+
+	// Draw children if root folder, or any other folder that is open. Do not draw children when animating to closed state or you get rendering overlap.
+	bool draw_children = getRoot() == static_cast<LLFolderViewFolder*>(this) || isOpen();
+
+	for (folders_t::iterator iter = mFolders.begin();
+		iter != mFolders.end();)
+	{
+		folders_t::iterator fit = iter++;
+		(*fit)->setVisible(draw_children);
+	}
+	for (items_t::iterator iter = mItems.begin();
+		iter != mItems.end();)
+	{
+		items_t::iterator iit = iter++;
+		(*iit)->setVisible(draw_children);
+	}
+
+	// we don't draw the open folder arrow in minimized mode
+	if (mHasArrow && !mCollapsedMode)
+	{
+		// update the rotation angle of open folder arrow
+		updateLabelRotation();
+		drawOpenFolderArrow(default_params, sFgColor);
+	}
+
+	refresh();        
+
+	LLView::draw();
+}
+
+BOOL LLConversationViewSession::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	//Will try to select a child node and then itself (if a child was not selected)
+    BOOL result = LLFolderViewFolder::handleMouseDown(x, y, mask);
+
+    //This node (conversation) was selected and a child (participant) was not
+    if(result && getRoot())
+    {
+		selectConversationItem();
+    }
+
+	return result;
+}
+
+BOOL LLConversationViewSession::handleRightMouseDown( S32 x, S32 y, MASK mask )
+{
+    BOOL result = LLFolderViewFolder::handleRightMouseDown(x, y, mask);
+
+    if(result)
+    {
+		selectConversationItem();
+    }
+
+	return result;
+}
+
+void LLConversationViewSession::selectConversationItem()
+{
+	if(getRoot()->getCurSelectedItem() == this)
+	{
+		LLConversationItem* item = dynamic_cast<LLConversationItem *>(getViewModelItem());
+		LLUUID session_id = item? item->getUUID() : LLUUID();
+
+		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+		im_container->flashConversationItemWidget(session_id,false);
+		im_container->selectConversationPair(session_id, false);
+		im_container->collapseMessagesPane(false);
+	}
+}
+
+// virtual
+S32 LLConversationViewSession::arrange(S32* width, S32* height)
+{
+    //LLFolderViewFolder::arrange computes value for getIndentation() function below
+    S32 arranged = LLFolderViewFolder::arrange(width, height);
+
+    S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+	
+	LLRect rect(mCollapsedMode ? getLocalRect().mLeft : h_pad,
+				getLocalRect().mTop,
+				getLocalRect().mRight,
+				getLocalRect().mTop - getItemHeight());
+	mItemPanel->setShape(rect);
+
+	return arranged;
+}
+
+// virtual
+void LLConversationViewSession::toggleOpen()
+{
+	// conversations should not be opened while in minimized mode
+	if (!mCollapsedMode)
+	{
+		LLFolderViewFolder::toggleOpen();
+
+		// do item's selection when opened
+		if (LLFolderViewFolder::isOpen())
+		{
+			getParentFolder()->setSelection(this, true);
+		}
+		mContainer->reSelectConversation();
+	}
+}
+
+void LLConversationViewSession::toggleCollapsedMode(bool is_collapsed)
+{
+	mCollapsedMode = is_collapsed;
+
+	// hide the layout stack which contains all item's child widgets
+	// except for the icon which we display in minimized mode
+	getChild<LLView>("conversation_item_stack")->setVisible(!mCollapsedMode);
+
+    S32 h_pad = mHasArrow ? getIndentation() + mArrowSize : getIndentation();
+
+	mItemPanel->translate(mCollapsedMode ? -h_pad : h_pad, 0);
+}
+
+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())
+	{
+		session_floater->setVisible(visible);
+	}
+}
+
+LLConversationViewParticipant* LLConversationViewSession::findParticipant(const LLUUID& participant_id)
+{
+	// This is *not* a general tree parsing algorithm. We search only in the mItems list
+	// assuming there is no mFolders which makes sense for sessions (sessions don't contain
+	// sessions).
+	LLConversationViewParticipant* participant = NULL;
+	items_t::const_iterator iter;
+	for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+	{
+		participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+		if (participant->hasSameValue(participant_id))
+		{
+			break;
+		}
+	}
+	return (iter == getItemsEnd() ? NULL : participant);
+}
+
+void LLConversationViewSession::showVoiceIndicator(bool visible)
+{
+	mCallIconLayoutPanel->setVisible(visible && LLVoiceChannel::getCurrentVoiceChannel()->getSessionID().isNull());
+	requestArrange();
+}
+
+void LLConversationViewSession::refresh()
+{
+	// Refresh the session view from its model data
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+	vmi->resetRefresh();
+	
+	if (mSessionTitle)
+	{
+		mSessionTitle->setText(vmi->getDisplayName());
+	}
+
+	// Update all speaking indicators
+	LLSpeakingIndicatorManager::updateSpeakingIndicators();
+
+	// we should show indicator for specified voice session only if this is current channel. EXT-5562.
+	if (!mIsInActiveVoiceChannel)
+	{
+		if (mSpeakingIndicator)
+		{
+			mSpeakingIndicator->setVisible(false);
+		}
+		LLConversationViewParticipant* participant = NULL;
+		items_t::const_iterator iter;
+		for (iter = getItemsBegin(); iter != getItemsEnd(); iter++)
+		{
+			participant = dynamic_cast<LLConversationViewParticipant*>(*iter);
+			if (participant)
+			{
+				participant->hideSpeakingIndicator();
+			}
+		}
+	}
+	requestArrange();
+	// Do the regular upstream refresh
+	LLFolderViewFolder::refresh();
+}
+
+void LLConversationViewSession::onCurrentVoiceSessionChanged(const LLUUID& session_id)
+{
+	LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(getViewModelItem());
+
+	if (vmi)
+	{
+		mIsInActiveVoiceChannel = vmi->getUUID() == session_id;
+		mCallIconLayoutPanel->setVisible(mIsInActiveVoiceChannel);
+	}
+}
+
+//
+// Implementation of conversations list participant (avatar) widgets
+//
+
+static LLDefaultChildRegistry::Register<LLConversationViewParticipant> r("conversation_view_participant");
+bool LLConversationViewParticipant::sStaticInitialized = false;
+S32 LLConversationViewParticipant::sChildrenWidths[LLConversationViewParticipant::ALIC_COUNT];
+
+LLConversationViewParticipant::Params::Params() :	
+container(),
+participant_id(),
+avatar_icon("avatar_icon"),
+info_button("info_button"),
+output_monitor("output_monitor")
+{}
+
+LLConversationViewParticipant::LLConversationViewParticipant( const LLConversationViewParticipant::Params& p ):
+	LLFolderViewItem(p),
+    mAvatarIcon(NULL),
+    mInfoBtn(NULL),
+    mSpeakingIndicator(NULL),
+    mUUID(p.participant_id)
+{
+}
+
+LLConversationViewParticipant::~LLConversationViewParticipant()
+{
+	mActiveVoiceChannelConnection.disconnect();
+}
+
+void LLConversationViewParticipant::initFromParams(const LLConversationViewParticipant::Params& params)
+{	
+    LLAvatarIconCtrl::Params avatar_icon_params(params.avatar_icon());
+    applyXUILayout(avatar_icon_params, this);
+    LLAvatarIconCtrl * avatarIcon = LLUICtrlFactory::create<LLAvatarIconCtrl>(avatar_icon_params);
+    addChild(avatarIcon);	
+    
+	LLButton::Params info_button_params(params.info_button());
+    applyXUILayout(info_button_params, this);
+	LLButton * button = LLUICtrlFactory::create<LLButton>(info_button_params);
+	addChild(button);	
+
+    LLOutputMonitorCtrl::Params output_monitor_params(params.output_monitor());
+    applyXUILayout(output_monitor_params, this);
+    LLOutputMonitorCtrl * outputMonitor = LLUICtrlFactory::create<LLOutputMonitorCtrl>(output_monitor_params);
+    addChild(outputMonitor);
+}
+
+BOOL LLConversationViewParticipant::postBuild()
+{
+    mAvatarIcon = getChild<LLAvatarIconCtrl>("avatar_icon");
+
+	mInfoBtn = getChild<LLButton>("info_btn");
+	mInfoBtn->setClickedCallback(boost::bind(&LLConversationViewParticipant::onInfoBtnClick, this));
+	mInfoBtn->setVisible(false);
+
+	mSpeakingIndicator = getChild<LLOutputMonitorCtrl>("speaking_indicator");
+
+    if (!sStaticInitialized)
+    {
+        // Remember children widths including their padding from the next sibling,
+        // so that we can hide and show them again later.
+        initChildrenWidths(this);
+        sStaticInitialized = true;
+    }
+
+    updateChildren();
+	return LLFolderViewItem::postBuild();
+}
+
+void LLConversationViewParticipant::draw()
+{
+    static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+	static LLUIColor sFgDisabledColor = LLUIColorTable::instance().getColor("MenuItemDisabledColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+    static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
+    static LLUIColor sFlashBgColor = LLUIColorTable::instance().getColor("MenuItemFlashBgColor", DEFAULT_WHITE);
+    static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
+    static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
+
+    const BOOL show_context = (getRoot() ? getRoot()->getShowSelectionContext() : FALSE);
+
+    const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
+    F32 right_x  = 0;
+
+    F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)mTextPad;
+    F32 text_left = (F32)getLabelXPos();
+	
+	LLColor4 color;
+	LLLocalSpeakerMgr *speakerMgr = LLLocalSpeakerMgr::getInstance();
+
+	if (speakerMgr && speakerMgr->isSpeakerToBeRemoved(mUUID))
+	{
+		color = sFgDisabledColor;
+	}
+	else
+	{
+		color = mIsSelected ? sHighlightFgColor : sFgColor;
+	}
+
+    drawHighlight(show_context, mIsSelected, sHighlightBgColor, sFlashBgColor, sFocusOutlineColor, sMouseOverColor);
+    drawLabel(font, text_left, y, color, right_x);
+	refresh();
+
+    LLView::draw();
+}
+
+// virtual
+S32 LLConversationViewParticipant::arrange(S32* width, S32* height)
+{
+    //Need to call arrange first since it computes value used in getIndentation()
+    S32 arranged = LLFolderViewItem::arrange(width, height);
+
+    //Adjusts the avatar icon based upon the indentation
+    LLRect avatarRect(getIndentation(), 
+                        mAvatarIcon->getRect().mTop,
+                        getIndentation() + mAvatarIcon->getRect().getWidth(),
+                        mAvatarIcon->getRect().mBottom);
+    mAvatarIcon->setShape(avatarRect);
+
+    //Since dimensions changed, adjust the children (info button, speaker indicator)
+    updateChildren();
+
+    return arranged;
+}
+
+void LLConversationViewParticipant::addToFolder(LLFolderViewFolder* folder)
+{
+    // Add the item to the folder (conversation)
+    LLFolderViewItem::addToFolder(folder);
+	
+    // Retrieve the folder (conversation) UUID, which is also the speaker session UUID
+    LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
+    if (vmi)
+    {
+		addToSession(vmi->getUUID());
+    }
+}
+
+void LLConversationViewParticipant::addToSession(const LLUUID& session_id)
+{
+	//Allows speaking icon image to be loaded based on mUUID
+	mAvatarIcon->setValue(mUUID);
+	
+	//Allows the speaker indicator to be activated based on the user and conversation
+	mSpeakingIndicator->setSpeakerId(mUUID, session_id); 
+}
+
+void LLConversationViewParticipant::onInfoBtnClick()
+{
+	LLFloaterReg::showInstance("inspect_avatar", LLSD().with("avatar_id", mUUID));
+}
+
+BOOL LLConversationViewParticipant::handleMouseDown( S32 x, S32 y, MASK mask )
+{
+	BOOL result = LLFolderViewItem::handleMouseDown(x, y, mask);
+
+    if(result && getRoot())
+    {
+    	if(getRoot()->getCurSelectedItem() == this)
+		{
+    		LLConversationItem* vmi = getParentFolder() ? dynamic_cast<LLConversationItem*>(getParentFolder()->getViewModelItem()) : NULL;
+    		LLUUID session_id = vmi? vmi->getUUID() : LLUUID();
+
+    		LLFloaterIMContainer *im_container = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+    		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+			im_container->setSelectedSession(session_id);
+			im_container->flashConversationItemWidget(session_id,false);
+			im_container->selectFloater(session_floater);
+			im_container->collapseMessagesPane(false);
+		}
+    }
+    return result;
+}
+
+void LLConversationViewParticipant::onMouseEnter(S32 x, S32 y, MASK mask)
+{
+    mInfoBtn->setVisible(true);
+    updateChildren();
+    LLFolderViewItem::onMouseEnter(x, y, mask);
+}
+
+void LLConversationViewParticipant::onMouseLeave(S32 x, S32 y, MASK mask)
+{
+    mInfoBtn->setVisible(false);
+    updateChildren();
+    LLFolderViewItem::onMouseLeave(x, y, mask);
+}
+
+S32 LLConversationViewParticipant::getLabelXPos()
+{
+    return getIndentation() + mAvatarIcon->getRect().getWidth() + mIconPad;
+}
+
+// static
+void LLConversationViewParticipant::initChildrenWidths(LLConversationViewParticipant* self)
+{
+    //speaking indicator width + padding
+    S32 speaking_indicator_width = self->getRect().getWidth() - self->mSpeakingIndicator->getRect().mLeft;
+
+    //info btn width + padding
+    S32 info_btn_width = self->mSpeakingIndicator->getRect().mLeft - self->mInfoBtn->getRect().mLeft;
+
+    S32 index = ALIC_COUNT;
+    sChildrenWidths[--index] = info_btn_width;
+    sChildrenWidths[--index] = speaking_indicator_width;
+    llassert(index == 0);
+}
+
+void LLConversationViewParticipant::updateChildren()
+{
+    mLabelPaddingRight = DEFAULT_LABEL_PADDING_RIGHT;
+    LLView* control;
+    S32 ctrl_width;
+    LLRect controlRect;
+
+    //Cycles through controls starting from right to left
+    for (S32 i = 0; i < ALIC_COUNT; ++i)
+    {
+        control = getItemChildView((EAvatarListItemChildIndex)i);
+
+        // skip invisible views
+        if (!control->getVisible()) continue;
+
+        //Get current pos/dimensions
+        controlRect = control->getRect();
+
+        ctrl_width = sChildrenWidths[i]; // including space between current & left controls
+        // accumulate the amount of space taken by the controls
+        mLabelPaddingRight += ctrl_width;
+
+        //Reposition visible controls in case adjacent controls to the right are hidden.
+        controlRect.setLeftTopAndSize(
+            getLocalRect().getWidth() - mLabelPaddingRight,
+            controlRect.mTop,
+            controlRect.getWidth(),
+            controlRect.getHeight());
+
+        //Sets the new position
+        control->setShape(controlRect);
+    }
+}
+
+LLView* LLConversationViewParticipant::getItemChildView(EAvatarListItemChildIndex child_view_index)
+{
+    LLView* child_view = NULL;
+
+    switch (child_view_index)
+    {
+        case ALIC_SPEAKER_INDICATOR:
+            child_view = mSpeakingIndicator;
+            break;
+        case ALIC_INFO_BUTTON:
+            child_view = mInfoBtn;
+            break;
+        default:
+            LL_WARNS("AvatarItemReshape") << "Unexpected child view index is passed: " << child_view_index << LL_ENDL;
+            llassert(0);
+            break;
+            // leave child_view untouched
+    }
+
+    return child_view;
+}
+
+void LLConversationViewParticipant::hideSpeakingIndicator()
+{
+	mSpeakingIndicator->setVisible(false);
+}
+
+// EOF
+
diff --git a/indra/newview/llconversationview.h b/indra/newview/llconversationview.h
new file mode 100755
index 0000000000000000000000000000000000000000..3eb2e63792d00e8fe5bf9d977488ea5818f347d9
--- /dev/null
+++ b/indra/newview/llconversationview.h
@@ -0,0 +1,177 @@
+/** 
+ * @file llconversationview.h
+ * @brief Implementation of conversations list widgets and views
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCONVERSATIONVIEW_H
+#define LL_LLCONVERSATIONVIEW_H
+
+#include "../llui/llfolderviewitem.h"
+
+#include "llavatariconctrl.h"
+#include "../llui/llbutton.h"
+#include "lloutputmonitorctrl.h"
+
+class LLTextBox;
+class LLFloaterIMContainer;
+class LLConversationViewSession;
+class LLConversationViewParticipant;
+
+class LLVoiceClientStatusObserver;
+
+// Implementation of conversations list session widgets
+
+class LLConversationViewSession : public LLFolderViewFolder
+{
+public:
+	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+	{
+		Optional<LLFloaterIMContainer*>			container;
+
+		Params();
+	};
+		
+protected:
+	friend class LLUICtrlFactory;
+	LLConversationViewSession( const Params& p );
+
+	/*virtual*/ bool isHighlightAllowed();
+	/*virtual*/ bool isHighlightActive();
+	/*virtual*/ bool isFlashing() { return mFlashStateOn; }
+
+	LLFloaterIMContainer* mContainer;
+	
+public:
+	virtual ~LLConversationViewSession();
+
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+
+	/*virtual*/ S32 arrange(S32* width, S32* height);
+
+	/*virtual*/ void toggleOpen();
+
+	/*virtual*/	bool isCollapsed() { return mCollapsedMode; }
+
+	void toggleCollapsedMode(bool is_collapsed);
+
+	void setVisibleIfDetached(BOOL visible);
+	LLConversationViewParticipant* findParticipant(const LLUUID& participant_id);
+
+	void showVoiceIndicator(bool visible);
+
+	virtual void refresh();
+
+	/*virtual*/ void setFlashState(bool flash_state);
+
+private:
+
+	void onCurrentVoiceSessionChanged(const LLUUID& session_id);
+	void startFlashing();
+	void selectConversationItem();
+
+	LLPanel*				mItemPanel;
+	LLPanel*				mCallIconLayoutPanel;
+	LLTextBox*				mSessionTitle;
+	LLOutputMonitorCtrl*	mSpeakingIndicator;
+	LLFlashTimer*			mFlashTimer;
+	bool					mFlashStateOn;
+	bool					mFlashStarted;
+
+	bool					mCollapsedMode;
+    bool                    mHasArrow;
+
+	bool					mIsInActiveVoiceChannel;
+
+	LLVoiceClientStatusObserver* mVoiceClientObserver;
+	
+	boost::signals2::connection mActiveVoiceChannelConnection;
+};
+
+// Implementation of conversations list participant (avatar) widgets
+
+class LLConversationViewParticipant : public LLFolderViewItem
+{
+
+public:
+
+	struct Params : public LLInitParam::Block<Params, LLFolderViewItem::Params>
+	{
+        Optional<LLFloaterIMContainer*>			container;
+		Optional<LLUUID>	                    participant_id;
+        Optional<LLAvatarIconCtrl::Params>	    avatar_icon;
+		Optional<LLButton::Params>				info_button;
+        Optional<LLOutputMonitorCtrl::Params>   output_monitor;
+		
+		Params();
+	};
+	
+    virtual ~LLConversationViewParticipant( void );
+
+    bool hasSameValue(const LLUUID& uuid) { return (uuid == mUUID); }
+    void addToFolder(LLFolderViewFolder* folder);
+	void addToSession(const LLUUID& session_id);
+
+    void onMouseEnter(S32 x, S32 y, MASK mask);
+    void onMouseLeave(S32 x, S32 y, MASK mask);
+
+    /*virtual*/ S32 getLabelXPos();
+    /*virtual*/ BOOL handleMouseDown( S32 x, S32 y, MASK mask );
+	void hideSpeakingIndicator();
+
+protected:
+	friend class LLUICtrlFactory;
+	LLConversationViewParticipant( const Params& p );
+	void initFromParams(const Params& params);
+	BOOL postBuild();
+    /*virtual*/ void draw();
+    /*virtual*/ S32 arrange(S32* width, S32* height);
+	
+	void onInfoBtnClick();
+
+private:
+
+    LLAvatarIconCtrl* mAvatarIcon;
+	LLButton * mInfoBtn;
+    LLOutputMonitorCtrl* mSpeakingIndicator;
+	LLUUID mUUID;		// UUID of the participant
+
+    typedef enum e_avatar_item_child {
+        ALIC_SPEAKER_INDICATOR,
+        ALIC_INFO_BUTTON,
+        ALIC_COUNT,
+    } EAvatarListItemChildIndex;
+
+    static bool	sStaticInitialized; // this variable is introduced to improve code readability
+    static S32 sChildrenWidths[ALIC_COUNT];
+    static void initChildrenWidths(LLConversationViewParticipant* self);
+    void updateChildren();
+    LLView* getItemChildView(EAvatarListItemChildIndex child_view_index);
+	
+	boost::signals2::connection mActiveVoiceChannelConnection;
+};
+
+#endif // LL_LLCONVERSATIONVIEW_H
diff --git a/indra/newview/lldeferredsounds.cpp b/indra/newview/lldeferredsounds.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9416e7cd293a6d025f4f1c0285267e9fca6be951
--- /dev/null
+++ b/indra/newview/lldeferredsounds.cpp
@@ -0,0 +1,45 @@
+/** 
+* @file lldeferredsounds.cpp
+* @brief Implementation of lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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 "lldeferredsounds.h"
+
+#include "llaudioengine.h"
+
+void LLDeferredSounds::deferSound(SoundData& sound)
+{
+	soundVector.push_back(sound);
+}
+void LLDeferredSounds::playdeferredSounds()
+{
+	while(soundVector.size())
+	{
+		gAudiop->triggerSound(soundVector.back());
+		soundVector.pop_back();
+	}
+}
diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h
new file mode 100644
index 0000000000000000000000000000000000000000..bf1eb629570b8be297fc82325821094e8d05444b
--- /dev/null
+++ b/indra/newview/lldeferredsounds.h
@@ -0,0 +1,46 @@
+/** 
+* @file   lldeferredsounds.h
+* @brief  Header file for lldeferredsounds
+* @author Gilbert@lindenlab.com
+*
+* $LicenseInfo:firstyear=2013&license=viewerlgpl$
+* Second Life Viewer Source Code
+* Copyright (C) 2013, 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_LLDEFERREDSOUNDS_H
+#define LL_LLDEFERREDSOUNDS_H
+
+#include "llsingleton.h"
+
+struct SoundData;
+
+class LLDeferredSounds : public LLSingleton<LLDeferredSounds>
+{
+private:
+	std::vector<SoundData> soundVector;
+public:
+	//Add sounds to be played once progress bar is hidden (such as after teleport or loading screen)
+	void deferSound(SoundData& sound);
+
+	void playdeferredSounds();
+};
+
+#endif // LL_LLDEFERREDSOUNDS_H
+
diff --git a/indra/newview/lldelayedgestureerror.cpp b/indra/newview/lldelayedgestureerror.cpp
index 80e7c9f1b2df9734df8bac2f093af25c5b63a329..ef1b644ad4d7ffefa41e015b1e94d955e897cb86 100644
--- a/indra/newview/lldelayedgestureerror.cpp
+++ b/indra/newview/lldelayedgestureerror.cpp
@@ -113,9 +113,11 @@ bool LLDelayedGestureError::doDialog(const LLErrorEntry &ent, bool uuid_ok)
 		}
 	}
 	 
-
-	LLNotificationsUtil::add(ent.mNotifyName, args);
-
+	if(!LLApp::isQuitting())
+	{
+		LLNotificationsUtil::add(ent.mNotifyName, args);
+	}
+	
 	return true;
 }
 
diff --git a/indra/newview/lldirpicker.cpp b/indra/newview/lldirpicker.cpp
index 1e03582a29176f2fb11c06baebfd7bde3f3ae7c6..d7d9f8291068d8d29946fff7cb9aef7a4f91bfe7 100644
--- a/indra/newview/lldirpicker.cpp
+++ b/indra/newview/lldirpicker.cpp
@@ -327,6 +327,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
 		return FALSE;
 	}
 
+#if !LL_MESA_HEADLESS
+
 	if (mFilePicker)
 	{
 		GtkWindow* picker = mFilePicker->buildFilePicker(false, true,
@@ -340,6 +342,8 @@ BOOL LLDirPicker::getDir(std::string* filename)
 		   return (!mFilePicker->getFirstFile().empty());
 		}
 	}
+#endif // !LL_MESA_HEADLESS
+
 	return FALSE;
 }
 
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..82affcf06885211ab1385ce084de6a73333ebe0e
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -0,0 +1,350 @@
+/** 
+* @file lldonotdisturbnotificationstorage.cpp
+* @brief Implementation of lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $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 "lldonotdisturbnotificationstorage.h"
+
+#include "llcommunicationchannel.h"
+#include "lldir.h"
+#include "llerror.h"
+#include "llfloaterreg.h"
+#include "llimview.h"
+#include "llnotifications.h"
+#include "llnotificationhandler.h"
+#include "llnotificationstorage.h"
+#include "llscriptfloater.h"
+#include "llsd.h"
+#include "llsingleton.h"
+#include "lluuid.h"
+
+static const F32 DND_TIMER = 3.0;
+const char * LLDoNotDisturbNotificationStorage::toastName = "IMToast";
+const char * LLDoNotDisturbNotificationStorage::offerName = "UserGiveItem";
+
+LLDoNotDisturbNotificationStorageTimer::LLDoNotDisturbNotificationStorageTimer() : LLEventTimer(DND_TIMER)
+{
+
+}
+
+LLDoNotDisturbNotificationStorageTimer::~LLDoNotDisturbNotificationStorageTimer()
+{
+
+}
+
+BOOL LLDoNotDisturbNotificationStorageTimer::tick()
+{
+    LLDoNotDisturbNotificationStorage * doNotDisturbNotificationStorage =  LLDoNotDisturbNotificationStorage::getInstance();
+
+    if(doNotDisturbNotificationStorage
+        && doNotDisturbNotificationStorage->getDirty())
+    {
+        doNotDisturbNotificationStorage->saveNotifications();
+    }
+    return FALSE;
+}
+
+LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
+	: LLSingleton<LLDoNotDisturbNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "dnd_notifications.xml"))
+    , mDirty(false)
+{
+    nameToPayloadParameterMap[toastName] = "SESSION_ID";
+    nameToPayloadParameterMap[offerName] = "object_id";
+}
+
+LLDoNotDisturbNotificationStorage::~LLDoNotDisturbNotificationStorage()
+{
+}
+
+void LLDoNotDisturbNotificationStorage::initialize()
+{
+	getCommunicationChannel()->connectFailedFilter(boost::bind(&LLDoNotDisturbNotificationStorage::onChannelChanged, this, _1));
+}
+
+bool LLDoNotDisturbNotificationStorage::getDirty()
+{
+    return mDirty;
+}
+
+void LLDoNotDisturbNotificationStorage::resetDirty()
+{
+    mDirty = false;
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_DND_NOTIFICATIONS("Save DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_DND_NOTIFICATIONS);
+
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	const LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+	data = LLSD::emptyArray();
+
+	for (LLCommunicationChannel::history_list_t::const_iterator historyIter = commChannel->beginHistory();
+		historyIter != commChannel->endHistory(); ++historyIter)
+	{
+		LLNotificationPtr notificationPtr = historyIter->second;
+
+		if (!notificationPtr->isRespondedTo() && !notificationPtr->isCancelled() && !notificationPtr->isExpired())
+		{
+			data.append(notificationPtr->asLLSD(true));
+		}
+	}
+
+	writeNotifications(output);
+
+    resetDirty();
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_DND_NOTIFICATIONS("Load DND Notifications");
+
+void LLDoNotDisturbNotificationStorage::loadNotifications()
+{
+	LLFastTimer _(FTM_LOAD_DND_NOTIFICATIONS);
+	
+	LL_INFOS("LLDoNotDisturbNotificationStorage") << "start loading notifications" << LL_ENDL;
+
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+	
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+	
+	LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
+	bool group_ad_hoc_toast_exists = false;
+	S32 toastSessionType;
+    bool offerExists = false;
+	
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		 notification_it != data.endArray();
+		 ++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+        const LLUUID& notificationID = notification_params["id"];
+        std::string notificationName = notification_params["name"];
+        LLNotificationPtr notification = instance.find(notificationID);
+
+        if(notificationName == toastName)
+        {
+			toastSessionType = notification_params["payload"]["SESSION_TYPE"];
+			if(toastSessionType == LLIMModel::LLIMSession::P2P_SESSION)
+			{
+				imToastExists = true;
+			}
+			//Don't add group/ad-hoc messages to the notification system because
+			//this means the group/ad-hoc session has to be re-created
+			else if(toastSessionType == LLIMModel::LLIMSession::GROUP_SESSION 
+					|| toastSessionType == LLIMModel::LLIMSession::ADHOC_SESSION)
+			{
+				//Just allows opening the conversation log for group/ad-hoc messages upon startup
+				group_ad_hoc_toast_exists = true;
+				continue;
+			}
+        }
+        else if(notificationName == offerName)
+        {
+            offerExists = true;
+        }
+		
+		//Notification already exists due to persistent storage adding it first into the notification system
+		if(notification)
+		{
+			notification->setDND(true);
+			instance.update(instance.find(notificationID));
+		}
+		//New notification needs to be added
+		else
+		{
+			notification = (LLNotificationPtr) new LLNotification(notification_params.with("is_dnd", true));
+			LLNotificationResponderInterface* responder = createResponder(notification_params["responder_sd"]["responder_type"], notification_params["responder_sd"]);
+			if (responder == NULL)
+			{
+				LL_WARNS("LLDoNotDisturbNotificationStorage") << "cannot create responder for notification of type '"
+					<< notification->getType() << "'" << LL_ENDL;
+			}
+			else
+			{
+				LLNotificationResponderPtr responderPtr(responder);
+				notification->setResponseFunctor(responderPtr);
+			}
+
+			instance.add(notification);
+		}
+
+	}
+
+    if(imToastExists)
+    {
+        LLFloaterReg::showInstance("im_container");
+    }
+
+	if(group_ad_hoc_toast_exists)
+	{
+		LLFloaterReg::showInstance("conversation");
+	}
+
+    if(imToastExists || group_ad_hoc_toast_exists || offerExists)
+    {
+		make_ui_sound_deferred("UISndNewIncomingIMSession");
+    }
+
+    //writes out empty .xml file (since LLCommunicationChannel::mHistory is empty)
+	saveNotifications();
+
+	LL_INFOS("LLDoNotDisturbNotificationStorage") << "finished loading notifications" << LL_ENDL;
+}
+
+void LLDoNotDisturbNotificationStorage::updateNotifications()
+{
+
+	LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+	LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+	llassert(commChannel != NULL);
+
+    LLNotifications& instance = LLNotifications::instance();
+    bool imToastExists = false;
+    bool offerExists = false;
+  
+    for (LLCommunicationChannel::history_list_t::const_iterator it = commChannel->beginHistory();
+        it != commChannel->endHistory();
+        ++it)
+    {
+        LLNotificationPtr notification = it->second;
+        std::string notificationName = notification->getName();
+
+        if(notificationName == toastName)
+        {
+            imToastExists = true;
+        }
+        else if(notificationName == offerName)
+        {
+            offerExists = true;
+        }
+
+        //Notification already exists in notification pipeline (same instance of app running)
+        if (notification)
+        {
+            notification->setDND(true);
+            instance.update(notification);
+        }
+    }
+
+    if(imToastExists)
+    {   
+        LLFloaterReg::showInstance("im_container");
+    }
+
+    if(imToastExists || offerExists)
+    {
+        make_ui_sound("UISndNewIncomingIMSession");
+    }
+
+    //When exit DND mode, write empty notifications file
+    if(commChannel->getHistorySize())
+    {
+	    commChannel->clearHistory();
+	    saveNotifications();
+    }
+}
+
+LLNotificationChannelPtr LLDoNotDisturbNotificationStorage::getCommunicationChannel() const
+{
+	LLNotificationChannelPtr channelPtr = LLNotifications::getInstance()->getChannel("Communication");
+	llassert(channelPtr);
+	return channelPtr;
+}
+
+void LLDoNotDisturbNotificationStorage::removeNotification(const char * name, const LLUUID& id)
+{
+    LLNotifications& instance = LLNotifications::instance();
+    LLNotificationChannelPtr channelPtr = getCommunicationChannel();
+    LLCommunicationChannel *commChannel = dynamic_cast<LLCommunicationChannel*>(channelPtr.get());
+    LLNotificationPtr notification;
+    LLSD payload;
+    LLUUID notificationObjectID;
+    std::string notificationName;
+    std::string payloadVariable = nameToPayloadParameterMap[name];
+    LLCommunicationChannel::history_list_t::iterator it;
+    std::vector<LLCommunicationChannel::history_list_t::iterator> itemsToRemove;
+
+    //Find notification with the matching session id
+    for (it = commChannel->beginHistory();
+        it != commChannel->endHistory(); 
+        ++it)
+    {
+        notification = it->second;
+        payload = notification->getPayload();
+        notificationObjectID = payload[payloadVariable].asUUID();
+        notificationName = notification->getName();
+
+        if((notificationName == name)
+            && id == notificationObjectID)
+        {
+            itemsToRemove.push_back(it);
+        }
+    }
+
+
+    //Remove the notifications
+    if(itemsToRemove.size())
+    {
+        while(itemsToRemove.size())
+        {
+            it = itemsToRemove.back();
+            notification = it->second;
+            commChannel->removeItemFromHistory(notification);
+            instance.cancel(notification);
+            itemsToRemove.pop_back();
+        }
+        //Trigger saving of notifications to xml once all have been removed
+        saveNotifications();
+    }
+}
+
+
+bool LLDoNotDisturbNotificationStorage::onChannelChanged(const LLSD& pPayload)
+{
+	if (pPayload["sigtype"].asString() != "load")
+	{
+        mDirty = true;
+	}
+
+	return false;
+}
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
new file mode 100644
index 0000000000000000000000000000000000000000..6e68b0d1be1013bec70431a7f010bda5e33ddb53
--- /dev/null
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -0,0 +1,78 @@
+/** 
+* @file   lldonotdisturbnotificationstorage.h
+* @brief  Header file for lldonotdisturbnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $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_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+#define LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "lleventtimer.h"
+#include "llnotifications.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer
+{
+public:
+    LLDoNotDisturbNotificationStorageTimer();
+    ~LLDoNotDisturbNotificationStorageTimer();
+
+public:
+    BOOL tick();
+};
+
+class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLDoNotDisturbNotificationStorage);
+public:
+    static const char * toastName;
+    static const char * offerName;
+
+	LLDoNotDisturbNotificationStorage();
+	~LLDoNotDisturbNotificationStorage();
+
+	void initialize();
+    bool getDirty();
+    void resetDirty();
+	void saveNotifications();
+	void loadNotifications();
+    void updateNotifications();
+    void removeNotification(const char * name, const LLUUID& id);
+
+protected:
+
+private:
+    bool mDirty;
+    LLDoNotDisturbNotificationStorageTimer mTimer;
+
+	LLNotificationChannelPtr getCommunicationChannel() const;
+	bool                     onChannelChanged(const LLSD& pPayload);
+    std::map<std::string, std::string> nameToPayloadParameterMap;
+};
+
+#endif // LL_LLDONOTDISTURBNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp
index d041baea901b76468e2339c5d6d37662cf2f972a..bb1d263670d3504b96796793ec358ae305a8bb0e 100644
--- a/indra/newview/lldrawable.cpp
+++ b/indra/newview/lldrawable.cpp
@@ -441,7 +441,7 @@ void LLDrawable::makeActive()
 	}
 
 	llassert(isAvatar() || isRoot() || mParent->isActive());
-}
+	}
 
 
 void LLDrawable::makeStatic(BOOL warning_enabled)
@@ -455,7 +455,7 @@ void LLDrawable::makeStatic(BOOL warning_enabled)
 
 		//drawable became static with active parent, not acceptable
 		llassert(mParent.isNull() || !mParent->isActive() || !warning_enabled);
-		
+
 		LLViewerObject::const_child_list_t& child_list = mVObjp->getChildren();
 		for (LLViewerObject::child_list_t::const_iterator iter = child_list.begin();
 			 iter != child_list.end(); iter++)
@@ -511,7 +511,6 @@ F32 LLDrawable::updateXform(BOOL undamped)
 	//scaling
 	LLVector3 target_scale = mVObjp->getScale();
 	LLVector3 old_scale = mCurrentScale;
-	LLVector3 dest_scale = target_scale;
 	
 	// Damping
 	F32 dist_squared = 0.f;
@@ -577,6 +576,12 @@ F32 LLDrawable::updateXform(BOOL undamped)
 			mVObjp->dirtySpatialGroup();
 		}
 	}
+	else if (!isRoot() &&
+			((dist_vec_squared(old_pos, target_pos) > 0.f)
+			|| (1.f - dot(old_rot, target_rot)) > 0.f))
+	{ //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247
+			gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE);
+	}
 	else if (!getVOVolume() && !isAvatar())
 	{
 		movePartition();
@@ -642,20 +647,10 @@ BOOL LLDrawable::updateMove()
 	{
 		return FALSE;
 	}
-
+	
 	makeActive();
 
-	BOOL done;
-
-	if (isState(MOVE_UNDAMPED))
-	{
-		done = updateMoveUndamped();
-	}
-	else
-	{
-		done = updateMoveDamped();
-	}
-	return done;
+	return isState(MOVE_UNDAMPED) ? updateMoveUndamped() : updateMoveDamped();
 }
 
 BOOL LLDrawable::updateMoveUndamped()
@@ -1241,7 +1236,6 @@ LLCamera LLSpatialBridge::transformCamera(LLCamera& camera)
 	LLCamera ret = camera;
 	LLXformMatrix* mat = mDrawable->getXform();
 	LLVector3 center = LLVector3(0,0,0) * mat->getWorldMatrix();
-	LLQuaternion rotation = LLQuaternion(mat->getWorldMatrix());
 
 	LLVector3 delta = ret.getOrigin() - center;
 	LLQuaternion rot = ~mat->getRotation();
diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp
index 1b0b11298c302d0b95c8ed48ec56532d7c001ed1..e8d43c86312fe6658e19929daec7bbe5ad6987f4 100644
--- a/indra/newview/lldrawpoolbump.cpp
+++ b/indra/newview/lldrawpoolbump.cpp
@@ -153,7 +153,7 @@ void LLStandardBumpmap::addstandard()
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mLabel = label;
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage = 
 			LLViewerTextureManager::getFetchedTexture(LLUUID(bump_image_id));	
-		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->setLoadedCallback(LLBumpImageList::onSourceStandardLoaded, 0, TRUE, FALSE, NULL, NULL );
 		gStandardBumpmapList[LLStandardBumpmap::sStandardBumpmapCount].mImage->forceToSaveRawImage(0) ;
 		LLStandardBumpmap::sStandardBumpmapCount++;
@@ -1075,7 +1075,7 @@ LLViewerTexture* LLBumpImageList::getBrightnessDarknessImage(LLViewerFetchedText
 			src_image->getHeight() != bump->getHeight())// ||
 			//(LLPipeline::sRenderDeferred && bump->getComponents() != 4))
 		{
-			src_image->setBoostLevel(LLViewerTexture::BOOST_BUMP) ;
+			src_image->setBoostLevel(LLGLTexture::BOOST_BUMP) ;
 			src_image->setLoadedCallback( callback_func, 0, TRUE, FALSE, new LLUUID(src_image->getID()), NULL );
 			src_image->forceToSaveRawImage(0) ;
 		}
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 9bc32fddbdbd641e4b9b1cb82e4482b62fd32122..0adb42428d470ea0c717b1bcdecbeb84607eb79c 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -69,7 +69,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	sDetailScale = 1.f/gSavedSettings.getF32("RenderTerrainScale");
 	sDetailMode = gSavedSettings.getS32("RenderTerrainDetail");
 	mAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient.tga", 
-													TRUE, LLViewerTexture::BOOST_UI, 
+													FTT_LOCAL_FILE,
+													TRUE, LLGLTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
 													format, int_format,
 													LLUUID("e97cf410-8e61-7005-ec06-629eba4cd1fb"));
@@ -78,7 +79,8 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	mAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
 
 	m2DAlphaRampImagep = LLViewerTextureManager::getFetchedTextureFromFile("alpha_gradient_2d.j2c", 
-													TRUE, LLViewerTexture::BOOST_UI, 
+													FTT_LOCAL_FILE,
+													TRUE, LLGLTexture::BOOST_UI, 
 													LLViewerTexture::FETCHED_TEXTURE,
 													format, int_format,
 													LLUUID("38b86f85-2575-52a9-a531-23108d8da837"));
@@ -86,7 +88,7 @@ LLDrawPoolTerrain::LLDrawPoolTerrain(LLViewerTexture *texturep) :
 	//gGL.getTexUnit(0)->bind(m2DAlphaRampImagep.get());
 	m2DAlphaRampImagep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	
-	mTexturep->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+	mTexturep->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
 	
 	//gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 }
@@ -170,7 +172,7 @@ void LLDrawPoolTerrain::render(S32 pass)
 	LLVLComposition *compp = regionp->getComposition();
 	for (S32 i = 0; i < 4; i++)
 	{
-		compp->mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN);
+		compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN);
 		compp->mDetailTextures[i]->addTextureStats(1024.f*1024.f); // assume large pixel area
 	}
 
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4f6eaa5a5b778b099e53e65cf599ff26d088be7a..5ddc15df42769f22b08dcea0ef1b3a735c6c9f7a 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -66,11 +66,11 @@ LLVector3 LLDrawPoolWater::sLightDir;
 LLDrawPoolWater::LLDrawPoolWater() :
 	LLFacePool(POOL_WATER)
 {
-	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mHBTex[0] = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	gGL.getTexUnit(0)->bind(mHBTex[0]) ;
 	mHBTex[0]->setAddressMode(LLTexUnit::TAM_CLAMP);
 
-	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mHBTex[1] = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	gGL.getTexUnit(0)->bind(mHBTex[1]);
 	mHBTex[1]->setAddressMode(LLTexUnit::TAM_CLAMP);
 
diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp
index fa42b157a72865276280d6d98e8fe6be6a94d9e8..29ad4f34d25b2378c76772d1b5e59826273f2da1 100644
--- a/indra/newview/lldynamictexture.cpp
+++ b/indra/newview/lldynamictexture.cpp
@@ -107,7 +107,7 @@ void LLViewerDynamicTexture::generateGLTexture(LLGLint internal_format, LLGLenum
 	{
 		setExplicitFormat(internal_format, primary_format, type_format, swap_bytes);
 	}
-	createGLTexture(0, raw_image, 0, TRUE, LLViewerTexture::DYNAMIC_TEX);
+	createGLTexture(0, raw_image, 0, TRUE, LLGLTexture::DYNAMIC_TEX);
 	setAddressMode((mClamp) ? LLTexUnit::TAM_CLAMP : LLTexUnit::TAM_WRAP);
 	mGLTexturep->setGLTextureCreated(false);
 }
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index c51e7d1e1a76ff64171cdd483ffc49c5d47c1bb1..d287ae6eebab25d83da53b8aa33bc0f4bb67c140 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -72,8 +72,8 @@ class LLViewerDynamicTexture : public LLViewerTexture
 	
 	/*virtual*/ S8 getType() const ;
 
-	S32			getOriginX()	{ return mOrigin.mX; }
-	S32			getOriginY()	{ return mOrigin.mY; }
+	S32			getOriginX() const	{ return mOrigin.mX; }
+	S32			getOriginY() const	{ return mOrigin.mY; }
 	
 	S32			getSize()		{ return mFullWidth * mFullHeight * mComponents; }
 
diff --git a/indra/newview/llestateinfomodel.cpp b/indra/newview/llestateinfomodel.cpp
index 7ed22d68f6061a1a02cfc44d94bcd2f526f8f85b..2669b0340fbef96ce1b72b8114fda1c77326d13a 100644
--- a/indra/newview/llestateinfomodel.cpp
+++ b/indra/newview/llestateinfomodel.cpp
@@ -65,12 +65,12 @@ void LLEstateInfoModel::sendEstateInfo()
 	}
 }
 
-bool LLEstateInfoModel::getUseFixedSun()			const {	return mFlags & REGION_FLAGS_SUN_FIXED;				}
-bool LLEstateInfoModel::getIsExternallyVisible()	const {	return mFlags & REGION_FLAGS_EXTERNALLY_VISIBLE;	}
-bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return mFlags & REGION_FLAGS_ALLOW_DIRECT_TELEPORT;	}
-bool LLEstateInfoModel::getDenyAnonymous()			const {	return mFlags & REGION_FLAGS_DENY_ANONYMOUS; 		}
-bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return mFlags & REGION_FLAGS_DENY_AGEUNVERIFIED;	}
-bool LLEstateInfoModel::getAllowVoiceChat()			const {	return mFlags & REGION_FLAGS_ALLOW_VOICE;			}
+bool LLEstateInfoModel::getUseFixedSun()			const {	return getFlag(REGION_FLAGS_SUN_FIXED);				}
+bool LLEstateInfoModel::getIsExternallyVisible()	const {	return getFlag(REGION_FLAGS_EXTERNALLY_VISIBLE);	}
+bool LLEstateInfoModel::getAllowDirectTeleport()	const {	return getFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT);	}
+bool LLEstateInfoModel::getDenyAnonymous()			const {	return getFlag(REGION_FLAGS_DENY_ANONYMOUS); 		}
+bool LLEstateInfoModel::getDenyAgeUnverified()		const {	return getFlag(REGION_FLAGS_DENY_AGEUNVERIFIED);	}
+bool LLEstateInfoModel::getAllowVoiceChat()			const {	return getFlag(REGION_FLAGS_ALLOW_VOICE);			}
 
 void LLEstateInfoModel::setUseFixedSun(bool val)			{ setFlag(REGION_FLAGS_SUN_FIXED, 				val);	}
 void LLEstateInfoModel::setIsExternallyVisible(bool val)	{ setFlag(REGION_FLAGS_EXTERNALLY_VISIBLE,		val);	}
@@ -122,9 +122,9 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 	}
 
 	// if we get an error response
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "Failed to commit estate info (" << status << "): " << reason << llendl;
+		llwarns << "Failed to commit estate info [status:" << status << "]: " << content << llendl;
 	}
 };
 
@@ -199,18 +199,6 @@ void LLEstateInfoModel::commitEstateInfoDataserver()
 	gAgent.sendMessage();
 }
 
-void LLEstateInfoModel::setFlag(U32 flag, bool val)
-{
-	if (val)
-	{
-		mFlags |= flag;
-	}
-	else
-	{
-		mFlags &= ~flag;
-	}
-}
-
 std::string LLEstateInfoModel::getInfoDump()
 {
 	LLSD dump;
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index 56391eda912f29583a0d5b3251ad12b29049bcf9..538f2f7c756f868fb58a6746da963974e6b40592 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -85,19 +85,38 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 private:
 	bool commitEstateInfoCaps();
 	void commitEstateInfoDataserver();
-	U32  getFlags() const { return mFlags; }
-	void setFlag(U32 flag, bool val);
+	inline bool getFlag(U64 flag) const;
+	inline void setFlag(U64 flag, bool val);
+	U64  getFlags() const { return mFlags; }
 	std::string getInfoDump();
 
 	// estate info
 	std::string	mName;			/// estate name
 	LLUUID		mOwnerID;		/// estate owner id
 	U32			mID;			/// estate id
-	U32			mFlags;			/// estate flags
+	U64			mFlags;			/// estate flags
 	F32			mSunHour;		/// estate sun hour
 
 	update_signal_t mUpdateSignal; /// emitted when we receive update from sim
 	update_signal_t mCommitSignal; /// emitted when our update gets applied to sim
 };
 
+inline bool LLEstateInfoModel::getFlag(U64 flag) const
+{
+	return ((mFlags & flag) != 0);
+}
+
+inline void LLEstateInfoModel::setFlag(U64 flag, bool val)
+{
+	if (val)
+	{
+		mFlags |= flag;
+	}
+	else
+	{
+		mFlags &= ~flag;
+	}
+}
+
+
 #endif // LL_LLESTATEINFOMODEL_H
diff --git a/indra/newview/lleventpoll.cpp b/indra/newview/lleventpoll.cpp
index 2c786b7f8be8714ee90e27a76e623eddb84d71a6..e0f7223a8ce745949d1ee8c60df93da53f322f74 100644
--- a/indra/newview/lleventpoll.cpp
+++ b/indra/newview/lleventpoll.cpp
@@ -62,7 +62,7 @@ namespace
 
 		
 		void handleMessage(const LLSD& content);
-		virtual	void error(U32 status, const std::string& reason);
+		virtual	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 		virtual	void result(const LLSD&	content);
 
 		virtual void completedRaw(U32 status,
@@ -187,7 +187,7 @@ namespace
 	}
 
 	//virtual
-	void LLEventPollResponder::error(U32 status, const	std::string& reason)
+	void LLEventPollResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		if (mDone) return;
 
@@ -207,13 +207,13 @@ namespace
 										+ mErrorCount * EVENT_POLL_ERROR_RETRY_SECONDS_INC
 									, this);
 
-			llwarns << "Unexpected HTTP error.  status: " << status << ", reason: " << reason << llendl;
+			llwarns << "LLEventPollResponder error [status:" << status << "]: " << content << llendl;
 		}
 		else
 		{
-			llwarns <<	"LLEventPollResponder::error: <" << mCount << "> got "
-					<<	status << ": " << reason
-					<<	(mDone ? " -- done"	: "") << llendl;
+			llwarns << "LLEventPollResponder error <" << mCount 
+					<< "> [status:" << status << "]: " << content
+					<< (mDone ? " -- done" : "") << llendl;
 			stop();
 
 			// At this point we have given up and the viewer will not receive HTTP messages from the simulator.
diff --git a/indra/newview/llexpandabletextbox.cpp b/indra/newview/llexpandabletextbox.cpp
index 935dcb74b0f8370c8df57fb3c0db77862f5ddb76..a50184460b74f65cb04b42cc6b32553fdbf4ce21 100644
--- a/indra/newview/llexpandabletextbox.cpp
+++ b/indra/newview/llexpandabletextbox.cpp
@@ -150,7 +150,7 @@ void LLExpandableTextBox::LLTextBoxEx::showExpandText()
 		std::pair<S32, S32> visible_lines = getVisibleLines(true);
 		S32 last_line = visible_lines.second - 1;
 
-		LLStyle::Params expander_style(getDefaultStyleParams());
+		LLStyle::Params expander_style(getStyleParams());
 		expander_style.font.style = "UNDERLINE";
 		expander_style.color = LLUIColorTable::instance().getColor("HTMLLinkColor");
 		LLExpanderSegment* expanderp = new LLExpanderSegment(new LLStyle(expander_style), getLineStart(last_line), getLength() + 1, mExpanderLabel, *this);
@@ -166,7 +166,7 @@ void LLExpandableTextBox::LLTextBoxEx::hideExpandText()
 	if (mExpanderVisible)
 	{
 		// this will overwrite the expander segment and all text styling with a single style
-		LLStyleConstSP sp(new LLStyle(getDefaultStyleParams()));
+		LLStyleConstSP sp(new LLStyle(getStyleParams()));
 		LLNormalTextSegment* segmentp = new LLNormalTextSegment(sp, 0, getLength() + 1, *this);
 		insertSegment(segmentp);
 		
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index 28e4b3279303bb8771db59d5b66100a744e6d52b..281f852b0aa26cd885cc2e980ae4958418205690 100644
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -555,8 +555,8 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color)
 /* removed in lieu of raycast uv detection
 void LLFace::renderSelectedUV()
 {
-	LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLViewerTexture::BOOST_UI);
-	LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLViewerTexture::BOOST_UI);
+	LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI);
+	LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI);
 
 	LLGLSUVSelect object_select;
 
diff --git a/indra/newview/llfasttimerview.cpp b/indra/newview/llfasttimerview.cpp
index 4dfb93f1bca3359ace15787dc845598b2a710266..fbf72b1a852d5b0411f5475a011a2937f9eba6e0 100644
--- a/indra/newview/llfasttimerview.cpp
+++ b/indra/newview/llfasttimerview.cpp
@@ -368,7 +368,7 @@ void LLFastTimerView::draw()
 
 	S32 left, top, right, bottom;
 	S32 x, y, barw, barh, dx, dy;
-	S32 texth, textw;
+	S32 texth;
 	LLPointer<LLUIImage> box_imagep = LLUI::getUIImage("Rounded_Square");
 
 	// Draw the window background
@@ -399,7 +399,6 @@ void LLFastTimerView::draw()
 
 		tdesc = llformat("Full bar = %s [Click to pause/reset] [SHIFT-Click to toggle]",modedesc[mDisplayMode]);
 		LLFontGL::getFontMonospace()->renderUTF8(tdesc, 0, x, y, LLColor4::white, LLFontGL::LEFT, LLFontGL::TOP);
-		textw = LLFontGL::getFontMonospace()->getWidth(tdesc);
 
 		x = xleft, y -= (texth + 2);
 		tdesc = llformat("Justification = %s [CTRL-Click to toggle]",centerdesc[mDisplayCenter]);
@@ -526,8 +525,6 @@ void LLFastTimerView::draw()
 
 			y -= (texth + 2);
 
-			textw = dx + LLFontGL::getFontMonospace()->getWidth(idp->getName()) + 40;
-
 			if (idp->getCollapsed()) 
 			{
 				it.skipDescendants();
@@ -1073,7 +1070,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	{ //read base log into memory
 		S32 i = 0;
 		std::ifstream is(base.c_str());
-		while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 		{
 			base_data[i++] = cur;
 		}
@@ -1086,7 +1083,7 @@ void LLFastTimerView::exportCharts(const std::string& base, const std::string& t
 	{ //read current log into memory
 		S32 i = 0;
 		std::ifstream is(target.c_str());
-		while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+		while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 		{
 			cur_data[i++] = cur;
 
@@ -1377,7 +1374,7 @@ LLSD LLFastTimerView::analyzePerformanceLogDefault(std::istream& is)
 	stats_map_t time_stats;
 	stats_map_t sample_stats;
 
-	while (!is.eof() && LLSDSerialize::fromXML(cur, is))
+	while (!is.eof() && LLSDParser::PARSE_FAILURE != LLSDSerialize::fromXML(cur, is))
 	{
 		for (LLSD::map_iterator iter = cur.beginMap(); iter != cur.endMap(); ++iter)
 		{
diff --git a/indra/newview/llfavoritesbar.cpp b/indra/newview/llfavoritesbar.cpp
index 4cbc9cab4a1311628dcf1b88d9a68b3f0c0d5df9..6d90667194fd3a8bb3ad7ca9508fe9495e3a1501 100644
--- a/indra/newview/llfavoritesbar.cpp
+++ b/indra/newview/llfavoritesbar.cpp
@@ -38,6 +38,7 @@
 #include "lltooltip.h"
 
 #include "llagent.h"
+#include "llavatarnamecache.h"
 #include "llclipboard.h"
 #include "llclipboard.h"
 #include "llinventorybridge.h"
@@ -45,12 +46,14 @@
 #include "llfloatersidepanelcontainer.h"
 #include "llfloaterworldmap.h"
 #include "lllandmarkactions.h"
+#include "lllogininstance.h"
 #include "llnotificationsutil.h"
 #include "lltoggleablemenu.h"
 #include "llviewerinventory.h"
 #include "llviewermenu.h"
 #include "llviewermenu.h"
 #include "lltooldraganddrop.h"
+#include "llsdserialize.h"
 
 static LLDefaultChildRegistry::Register<LLFavoritesBarCtrl> r("favorites_bar");
 
@@ -317,7 +320,8 @@ class LLItemCopiedCallback : public LLInventoryCallback
 
 		if (item)
 		{
-			item->setSortField(mSortField);
+			LLFavoritesOrderStorage::instance().setSortIndex(item, mSortField);
+
 			item->setComplete(TRUE);
 			item->updateServer(FALSE);
 
@@ -339,8 +343,8 @@ struct LLFavoritesSort
 	// TODO - made it customizible using gSavedSettings
 	bool operator()(const LLViewerInventoryItem* const& a, const LLViewerInventoryItem* const& b)
 	{
-		S32 sortField1 = a->getSortField();
-		S32 sortField2 = b->getSortField();
+		S32 sortField1 = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+		S32 sortField2 = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
 
 		if (!(sortField1 < 0 && sortField2 < 0))
 		{
@@ -528,7 +532,7 @@ void LLFavoritesBarCtrl::handleExistingFavoriteDragAndDrop(S32 x, S32 y)
 		mItems.push_back(gInventory.getItem(mDragItemId));
 	}
 
-	gInventory.saveItemsOrder(mItems);
+	LLFavoritesOrderStorage::instance().saveItemsOrder(mItems);
 
 	LLToggleableMenu* menu = (LLToggleableMenu*) mOverflowMenuHandle.get();
 
@@ -587,7 +591,8 @@ void LLFavoritesBarCtrl::handleNewFavoriteDragAndDrop(LLInventoryItem *item, con
 		}
 		else
 		{
-			currItem->setSortField(++sortField);
+			LLFavoritesOrderStorage::instance().setSortIndex(currItem, ++sortField);
+
 			currItem->setComplete(TRUE);
 			currItem->updateServer(FALSE);
 
@@ -640,7 +645,7 @@ void LLFavoritesBarCtrl::changed(U32 mask)
 		
 		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 		{
-			(*i)->getSLURL();
+			LLFavoritesOrderStorage::instance().getSLURL((*i)->getAssetUUID());
 		}
 		updateButtons();
 	}
@@ -909,7 +914,7 @@ BOOL LLFavoritesBarCtrl::collectFavoriteItems(LLInventoryModel::item_array_t &it
 		S32 sortField = 0;
 		for (LLInventoryModel::item_array_t::iterator i = items.begin(); i != items.end(); ++i)
 		{
-			(*i)->setSortField(++sortField);
+			LLFavoritesOrderStorage::instance().setSortIndex((*i), ++sortField);
 		}
 	}
 
@@ -1355,7 +1360,7 @@ BOOL LLFavoritesBarCtrl::needToSaveItemsOrder(const LLInventoryModel::item_array
 	// if there is an item without sort order field set, we need to save items order
 	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
 	{
-		if ((*i)->getSortField() < 0)
+		if (LLFavoritesOrderStorage::instance().getSortIndex((*i)->getUUID()) < 0)
 		{
 			result = TRUE;
 			break;
@@ -1390,4 +1395,294 @@ void LLFavoritesBarCtrl::insertItem(LLInventoryModel::item_array_t& items, const
 	}
 }
 
+const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
+const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
+
+void LLFavoritesOrderStorage::setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index)
+{
+	mSortIndexes[inv_item->getUUID()] = sort_index;
+	mIsDirty = true;
+	getSLURL(inv_item->getAssetUUID());
+}
+
+S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
+{
+	sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
+	if (it != mSortIndexes.end())
+	{
+		return it->second;
+	}
+	return NO_INDEX;
+}
+
+void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
+{
+	mSortIndexes.erase(inv_item_id);
+	mIsDirty = true;
+}
+
+void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
+{
+	slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
+	if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
+
+	LLLandmark* lm = gLandmarkList.getAsset(asset_id,
+		boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
+	if (lm)
+	{
+		onLandmarkLoaded(asset_id, lm);
+	}
+}
+
+// static
+void LLFavoritesOrderStorage::destroyClass()
+{
+	LLFavoritesOrderStorage::instance().cleanup();
+	if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
+	{
+		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
+	}
+	else
+	{
+		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
+	}
+}
+
+void LLFavoritesOrderStorage::load()
+{
+	// load per-resident sorting information
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+
+	LLSD settings_llsd;
+	llifstream file;
+	file.open(filename);
+	if (file.is_open())
+	{
+		LLSDSerialize::fromXML(settings_llsd, file);
+	}
+
+	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
+		iter != settings_llsd.endMap(); ++iter)
+	{
+		mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
+	}
+}
+
+void LLFavoritesOrderStorage::saveFavoritesSLURLs()
+{
+	// Do not change the file if we are not logged in yet.
+	if (!LLLoginInstance::getInstance()->authSuccess())
+	{
+		llwarns << "Cannot save favorites: not logged in" << llendl;
+		return;
+	}
+
+	std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
+	if (user_dir.empty())
+	{
+		llwarns << "Cannot save favorites: empty user dir name" << llendl;
+		return;
+	}
+
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+	llifstream in_file;
+	in_file.open(filename);
+	LLSD fav_llsd;
+	if (in_file.is_open())
+	{
+		LLSDSerialize::fromXML(fav_llsd, in_file);
+	}
+
+	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+	LLSD user_llsd;
+	for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
+	{
+		LLSD value;
+		value["name"] = (*it)->getName();
+		value["asset_id"] = (*it)->getAssetUUID();
+
+		slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
+		if (slurl_iter != mSLURLs.end())
+		{
+			lldebugs << "Saving favorite: idx=" << LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID()) << ", SLURL=" <<  slurl_iter->second << ", value=" << value << llendl;
+			value["slurl"] = slurl_iter->second;
+			user_llsd[LLFavoritesOrderStorage::instance().getSortIndex((*it)->getUUID())] = value;
+		}
+		else
+		{
+			llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
+		}
+	}
+
+	LLAvatarName av_name;
+	LLAvatarNameCache::get( gAgentID, &av_name );
+	// Note : use the "John Doe" and not the "john.doe" version of the name 
+	// as we'll compare it with the stored credentials in the login panel.
+	lldebugs << "Saved favorites for " << av_name.getUserName() << llendl;
+	fav_llsd[av_name.getUserName()] = user_llsd;
+
+	llofstream file;
+	file.open(filename);
+	LLSDSerialize::toPrettyXML(fav_llsd, file);
+}
+
+void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
+{
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
+	LLSD fav_llsd;
+	llifstream file;
+	file.open(filename);
+	if (!file.is_open()) return;
+	LLSDSerialize::fromXML(fav_llsd, file);
+
+	LLAvatarName av_name;
+	LLAvatarNameCache::get( gAgentID, &av_name );
+	// Note : use the "John Doe" and not the "john.doe" version of the name.
+	// See saveFavoritesSLURLs() here above for the reason why.
+	lldebugs << "Removed favorites for " << av_name.getUserName() << llendl;
+	if (fav_llsd.has(av_name.getUserName()))
+	{
+		fav_llsd.erase(av_name.getUserName());
+	}
+
+	llofstream out_file;
+	out_file.open(filename);
+	LLSDSerialize::toPrettyXML(fav_llsd, out_file);
+
+}
+
+void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
+{
+	if (!landmark) return;
+
+	LLVector3d pos_global;
+	if (!landmark->getGlobalPos(pos_global))
+	{
+		// If global position was unknown on first getGlobalPos() call
+		// it should be set for the subsequent calls.
+		landmark->getGlobalPos(pos_global);
+	}
+
+	if (!pos_global.isExactlyZero())
+	{
+		LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
+			boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
+	}
+}
+
+void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
+{
+	lldebugs << "Saving landmark SLURL: " << slurl << llendl;
+	mSLURLs[asset_id] = slurl;
+}
+
+void LLFavoritesOrderStorage::save()
+{
+	// nothing to save if clean
+	if (!mIsDirty) return;
+
+	// If we quit from the login screen we will not have an SL account
+	// name.  Don't try to save, otherwise we'll dump a file in
+	// C:\Program Files\SecondLife\ or similar. JC
+	std::string user_dir = gDirUtilp->getLindenUserDir();
+	if (!user_dir.empty())
+	{
+		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
+		LLSD settings_llsd;
+
+		for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
+		{
+			settings_llsd[iter->first.asString()] = iter->second;
+		}
+
+		llofstream file;
+		file.open(filename);
+		LLSDSerialize::toPrettyXML(settings_llsd, file);
+	}
+}
+
+void LLFavoritesOrderStorage::cleanup()
+{
+	// nothing to clean
+	if (!mIsDirty) return;
+
+	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
+
+	IsNotInFavorites is_not_in_fav(items);
+
+	sort_index_map_t  aTempMap;
+	//copy unremoved values from mSortIndexes to aTempMap
+	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), 
+		inserter(aTempMap, aTempMap.begin()),
+		is_not_in_fav);
+
+	//Swap the contents of mSortIndexes and aTempMap
+	mSortIndexes.swap(aTempMap);
+}
+
+void LLFavoritesOrderStorage::saveItemsOrder( const LLInventoryModel::item_array_t& items )
+{
+	int sortField = 0;
+
+	// current order is saved by setting incremental values (1, 2, 3, ...) for the sort field
+	for (LLInventoryModel::item_array_t::const_iterator i = items.begin(); i != items.end(); ++i)
+	{
+		LLViewerInventoryItem* item = *i;
+
+		setSortIndex(item, ++sortField);
+
+		item->setComplete(TRUE);
+		item->updateServer(FALSE);
+
+		gInventory.updateItem(item);
+
+		// Tell the parent folder to refresh its sort order.
+		gInventory.addChangedMask(LLInventoryObserver::SORT, item->getParentUUID());
+	}
+
+	gInventory.notifyObservers();
+}
+// See also LLInventorySort where landmarks in the Favorites folder are sorted.
+class LLViewerInventoryItemSort
+{
+public:
+	bool operator()(const LLPointer<LLViewerInventoryItem>& a, const LLPointer<LLViewerInventoryItem>& b)
+	{
+		return LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID()) 
+			< LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+	}
+};
+
+// * @param source_item_id - LLUUID of the source item to be moved into new position
+// * @param target_item_id - LLUUID of the target item before which source item should be placed.
+void LLFavoritesOrderStorage::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
+{
+	LLInventoryModel::cat_array_t cats;
+	LLInventoryModel::item_array_t items;
+	LLIsType is_type(LLAssetType::AT_LANDMARK);
+	LLUUID favorites_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+	gInventory.collectDescendentsIf(favorites_id, cats, items, LLInventoryModel::EXCLUDE_TRASH, is_type);
+
+	// ensure items are sorted properly before changing order. EXT-3498
+	std::sort(items.begin(), items.end(), LLViewerInventoryItemSort());
+
+	// update order
+	gInventory.updateItemsOrder(items, source_item_id, target_item_id);
+
+	saveItemsOrder(items);
+}
+
+void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
+{
+	if (mTargetLandmarkId.isNull()) return;
+
+	LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
+}
 // EOF
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 447d30f1f41d299c455180780613794164df61de..f06e9b9b6459c18766d6605d26644a3b098d7dba 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -33,6 +33,7 @@
 
 #include "llinventoryobserver.h"
 #include "llinventorymodel.h"
+#include "llviewerinventory.h"
 
 class LLMenuItemCallGL;
 class LLToggleableMenu;
@@ -160,6 +161,115 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 
 	boost::signals2::connection mEndDragConnection;
 };
+/*
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
+{
+public:
+	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
+
+private:
+	void fire(const LLUUID& inv_item);
+
+	LLUUID mTargetLandmarkId;
+};
+*/
+/**
+ * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
+ * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
+ * Data are stored in user home directory.
+ */
+class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
+	, public LLDestroyClass<LLFavoritesOrderStorage>
+{
+	LOG_CLASS(LLFavoritesOrderStorage);
+public:
+	/**
+	 * Sets sort index for specified with LLUUID favorite landmark
+	 */
+	void setSortIndex(const LLViewerInventoryItem* inv_item, S32 sort_index);
+
+	/**
+	 * Gets sort index for specified with LLUUID favorite landmark
+	 */
+	S32 getSortIndex(const LLUUID& inv_item_id);
+	void removeSortIndex(const LLUUID& inv_item_id);
+
+	void getSLURL(const LLUUID& asset_id);
+
+	// Saves current order of the passed items using inventory item sort field.
+	// Resets 'items' sort fields and saves them on server.
+	// Is used to save order for Favorites folder.
+	void saveItemsOrder(const LLInventoryModel::item_array_t& items);
+
+	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+
+	/**
+	 * Implementation of LLDestroyClass. Calls cleanup() instance method.
+	 *
+	 * It is important this callback is called before gInventory is cleaned.
+	 * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
+	 * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
+	 * @see cleanup()
+	 */
+	static void destroyClass();
+
+	const static S32 NO_INDEX;
+private:
+	friend class LLSingleton<LLFavoritesOrderStorage>;
+	LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
+	~LLFavoritesOrderStorage() { save(); }
+
+	/**
+	 * Removes sort indexes for items which are not in Favorites bar for now.
+	 */
+	void cleanup();
+
+	const static std::string SORTING_DATA_FILE_NAME;
+
+	void load();
+	void save();
 
+	void saveFavoritesSLURLs();
 
+	// Remove record of current user's favorites from file on disk.
+	void removeFavoritesRecordOfUser();
+
+	void onLandmarkLoaded(const LLUUID& asset_id, class LLLandmark* landmark);
+	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
+
+	typedef std::map<LLUUID, S32> sort_index_map_t;
+	sort_index_map_t mSortIndexes;
+
+	typedef std::map<LLUUID, std::string> slurls_map_t;
+	slurls_map_t mSLURLs;
+
+	bool mIsDirty;
+
+	struct IsNotInFavorites
+	{
+		IsNotInFavorites(const LLInventoryModel::item_array_t& items)
+			: mFavoriteItems(items)
+		{
+
+		}
+
+		/**
+		 * Returns true if specified item is not found among inventory items
+		 */
+		bool operator()(const sort_index_map_t::value_type& id_index_pair) const
+		{
+			LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
+			if (item.isNull()) return true;
+
+			LLInventoryModel::item_array_t::const_iterator found_it =
+				std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
+
+			return found_it == mFavoriteItems.end();
+		}
+	private:
+		LLInventoryModel::item_array_t mFavoriteItems;
+	};
+
+};
 #endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 4bf5b26b3b0794f213ee116d17f6fae3440bfcf1..d13f85baa2ec0b2fd309dee63d6b2dcd67ffe2f9 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -1103,6 +1103,7 @@ void LLFilePicker::chooser_responder(GtkWidget *widget, gint response, gpointer
 
 GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::string context)
 {
+#ifndef LL_MESA_HEADLESS
 	if (LLWindowSDL::ll_try_gtk_init())
 	{
 		GtkWidget *win = NULL;
@@ -1174,6 +1175,9 @@ GtkWindow* LLFilePicker::buildFilePicker(bool is_save, bool is_folder, std::stri
 	{
 		return NULL;
 	}
+#else
+	return NULL;
+#endif //LL_MESA_HEADLESS
 }
 
 static void add_common_filters_to_gtkchooser(GtkFileFilter *gfilter,
@@ -1473,7 +1477,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 	return FALSE;
 }
 
-BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
+BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking )
 {
 	// if local file browsing is turned off, return without opening dialog
 	// (Even though this is a stub, I think we still should not return anything at all)
@@ -1494,7 +1498,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 	default: break;
 	}
 	mFiles.push_back(filename);
-	llinfos << "getOpenFile: Will try to open file: " << hackyfilename << llendl;
+	llinfos << "getOpenFile: Will try to open file: " << filename << llendl;
 	return TRUE;
 }
 
diff --git a/indra/newview/llfirstuse.cpp b/indra/newview/llfirstuse.cpp
index a9f52282a502763bc56d92ba684c8c4e8ba2ec2a..e2850f51818ad9830a47f438e3212fa4d9dcaf14 100644
--- a/indra/newview/llfirstuse.cpp
+++ b/indra/newview/llfirstuse.cpp
@@ -74,7 +74,7 @@ void LLFirstUse::resetFirstUse()
 // static
 void LLFirstUse::otherAvatarChatFirst(bool enable)
 {
-	firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "chat_bar").with("direction", "top_right").with("distance", 24));
+	firstUseNotification("FirstOtherChatBeforeUser", enable, "HintChat", LLSD(), LLSD().with("target", "nearby_chat").with("direction", "top_right").with("distance", 24));
 }
 
 // static
diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp
index 77a0cdffce5a1b0e376119d5bce955d716027847..caad0afec054069262a9f4672bf55018c9aae67b 100644
--- a/indra/newview/llflexibleobject.cpp
+++ b/indra/newview/llflexibleobject.cpp
@@ -270,9 +270,6 @@ void LLVolumeImplFlexible::setAttributesOfAllSections(LLVector3* inScale)
 	mSection[0].mVelocity.setVec(0,0,0);
 	mSection[0].mAxisRotation.setQuat(begin_rot,0,0,1);
 
-	LLVector3 parentSectionPosition = mSection[0].mPosition;
-	LLVector3 last_direction = mSection[0].mDirection;
-
 	remapSections(mSection, mInitializedRes, mSection, mSimulateRes);
 	mInitializedRes = mSimulateRes;
 
@@ -342,10 +339,10 @@ void LLVolumeImplFlexible::doIdleUpdate()
 	if (drawablep)
 	{
 		//LLFastTimer ftm(FTM_FLEXIBLE_UPDATE);
-		
+
 		//ensure drawable is active
 		drawablep->makeActive();
-			
+
 		if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
 		{
 			bool visible = drawablep->isVisible();
@@ -381,21 +378,31 @@ void LLVolumeImplFlexible::doIdleUpdate()
 							id = parent->getVolumeInterfaceID();
 						}
 
-						if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
-						{
+				if (mVO->isRootEdit())
+				{
+					id = mID;
+				}
+				else
+				{
+					LLVOVolume* parent = (LLVOVolume*) mVO->getParent();
+					id = parent->getVolumeInterfaceID();
+				}
+
+				if ((LLDrawable::getCurrentFrame()+id)%update_period == 0)
+				{
 							sUpdateDelay[mInstanceIndex] = (S32) update_period-1;
 
-							updateRenderRes();
+					updateRenderRes();
 
-							gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
-						}
-					}
+					gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE);
 				}
+			}
+		}
 				else
 				{
 					sUpdateDelay[mInstanceIndex] = (S32) update_period;
-				}
-			}
+	}
+}
 
 		}
 	}
@@ -420,7 +427,6 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 	if ((mSimulateRes == 0 || !mInitialized) && mVO->mDrawable->isVisible()) 
 	{
 		BOOL force_update = mSimulateRes == 0 ? TRUE : FALSE;
-
 		doIdleUpdate();
 
 		if (!force_update || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FLEXIBLE))
@@ -435,7 +441,7 @@ void LLVolumeImplFlexible::doFlexibleUpdate()
 		return ;
 	}
 
-	// stinson 11/12/2012: Need to check with davep on the following.
+	// Fix for MAINT-1894
 	// Skipping the flexible update if render res is negative.  If we were to continue with a negative value,
 	// the subsequent S32 num_render_sections = 1<<mRenderRes; code will specify a really large number of
 	// render sections which will then create a length exception in the std::vector::resize() method.
diff --git a/indra/newview/llfloaterauction.cpp b/indra/newview/llfloaterauction.cpp
index 2939d31087efdfa0466c4071bcc8b6f2adc5fd0f..3c40e2d4bccde545327912fbb3a9793c3b04eb00 100644
--- a/indra/newview/llfloaterauction.cpp
+++ b/indra/newview/llfloaterauction.cpp
@@ -38,6 +38,7 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "llassetstorage.h"
 #include "llcombobox.h"
 #include "llestateinfomodel.h"
 #include "llmimetypes.h"
diff --git a/indra/newview/llfloateravatarpicker.cpp b/indra/newview/llfloateravatarpicker.cpp
index 0290e7cdf080b6e5b9df5c1203f03f9b1d49f71d..3e0e82b579e7de0a5d3bfc856689ae061b847c28 100644
--- a/indra/newview/llfloateravatarpicker.cpp
+++ b/indra/newview/llfloateravatarpicker.cpp
@@ -49,6 +49,8 @@
 #include "llscrolllistcell.h"
 #include "lltabcontainer.h"
 #include "lluictrlfactory.h"
+#include "llfocusmgr.h"
+#include "lldraghandle.h"
 #include "message.h"
 
 //#include "llsdserialize.h"
@@ -58,11 +60,14 @@ static std::map<LLUUID, LLAvatarName> sAvatarNameMap;
 
 LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 												   BOOL allow_multiple,
-												   BOOL closeOnSelect)
+												   BOOL closeOnSelect,
+												   BOOL skip_agent,
+                                                   const std::string& name,
+                                                   LLView * frustumOrigin)
 {
 	// *TODO: Use a key to allow this not to be an effective singleton
 	LLFloaterAvatarPicker* floater = 
-		LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+		LLFloaterReg::showTypedInstance<LLFloaterAvatarPicker>("avatar_picker", LLSD(name));
 	if (!floater)
 	{
 		llwarns << "Cannot instantiate avatar picker" << llendl;
@@ -73,6 +78,7 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 	floater->setAllowMultiple(allow_multiple);
 	floater->mNearMeListComplete = FALSE;
 	floater->mCloseOnSelect = closeOnSelect;
+	floater->mExcludeAgentFromSearchResults = skip_agent;
 	
 	if (!closeOnSelect)
 	{
@@ -83,6 +89,11 @@ LLFloaterAvatarPicker* LLFloaterAvatarPicker::show(select_callback_t callback,
 		floater->getChild<LLButton>("cancel_btn")->setLabel(close_string);
 	}
 
+    if(frustumOrigin)
+    {
+        floater->mFrustumOrigin = frustumOrigin->getHandle();
+    }
+
 	return floater;
 }
 
@@ -91,9 +102,17 @@ LLFloaterAvatarPicker::LLFloaterAvatarPicker(const LLSD& key)
   : LLFloater(key),
 	mNumResultsReturned(0),
 	mNearMeListComplete(FALSE),
-	mCloseOnSelect(FALSE)
+	mCloseOnSelect(FALSE),
+    mContextConeOpacity	(0.f),
+    mContextConeInAlpha(0.f),
+    mContextConeOutAlpha(0.f),
+    mContextConeFadeTime(0.f)
 {
 	mCommitCallbackRegistrar.add("Refresh.FriendList", boost::bind(&LLFloaterAvatarPicker::populateFriend, this));
+
+    mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+    mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+    mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
 }
 
 BOOL LLFloaterAvatarPicker::postBuild()
@@ -288,9 +307,9 @@ void LLFloaterAvatarPicker::populateNearMe()
 		else
 		{
 			element["columns"][0]["column"] = "name";
-			element["columns"][0]["value"] = av_name.mDisplayName;
+			element["columns"][0]["value"] = av_name.getDisplayName();
 			element["columns"][1]["column"] = "username";
-			element["columns"][1]["value"] = av_name.mUsername;
+			element["columns"][1]["value"] = av_name.getUserName();
 
 			sAvatarNameMap[av] = av_name;
 		}
@@ -338,8 +357,67 @@ void LLFloaterAvatarPicker::populateFriend()
 	friends_scroller->sortByColumnIndex(0, TRUE);
 }
 
+void LLFloaterAvatarPicker::drawFrustum()
+{
+    if(mFrustumOrigin.get())
+    {
+        LLView * frustumOrigin = mFrustumOrigin.get();
+        LLRect origin_rect;
+        frustumOrigin->localRectToOtherView(frustumOrigin->getLocalRect(), &origin_rect, this);
+        // draw context cone connecting color picker with color swatch in parent floater
+        LLRect local_rect = getLocalRect();
+        if (hasFocus() && frustumOrigin->isInVisibleChain() && mContextConeOpacity > 0.001f)
+        {
+            gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+            LLGLEnable(GL_CULL_FACE);
+            gGL.begin(LLRender::QUADS);
+            {
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mTop);
+
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+                gGL.vertex2i(local_rect.mRight, local_rect.mTop);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mTop);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
+                gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
+                gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
+                gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
+                gGL.vertex2i(origin_rect.mRight, origin_rect.mBottom);
+                gGL.vertex2i(origin_rect.mLeft, origin_rect.mBottom);
+            }
+            gGL.end();
+        }
+
+        if (gFocusMgr.childHasMouseCapture(getDragHandle()))
+        {
+            mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+        }
+        else
+        {
+            mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
+        }
+    }
+}
+
 void LLFloaterAvatarPicker::draw()
 {
+    drawFrustum();
+
 	// sometimes it is hard to determine when Select/Ok button should be disabled (see LLAvatarActions::shareWithAvatars).
 	// lets check this via mOkButtonValidateSignal callback periodically.
 	static LLFrameTimer timer;
@@ -382,8 +460,9 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 {
 public:
 	LLUUID mQueryID;
+    std::string mName;
 
-	LLAvatarPickerResponder(const LLUUID& id) : mQueryID(id) { }
+	LLAvatarPickerResponder(const LLUUID& id, const std::string& name) : mQueryID(id), mName(name) { }
 
 	/*virtual*/ void completed(U32 status, const std::string& reason, const LLSD& content)
 	{
@@ -396,7 +475,7 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 		if (isGoodStatus(status) || status == 400)
 		{
 			LLFloaterAvatarPicker* floater =
-				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker");
+				LLFloaterReg::findTypedInstance<LLFloaterAvatarPicker>("avatar_picker", mName);
 			if (floater)
 			{
 				floater->processResponse(mQueryID, content);
@@ -404,8 +483,7 @@ class LLAvatarPickerResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			llinfos << "avatar picker failed " << status
-					<< " reason " << reason << llendl;
+			llwarns << "avatar picker failed [status:" << status << "]: " << content << llendl;
 			
 		}
 	}
@@ -426,9 +504,7 @@ void LLFloaterAvatarPicker::find()
 	LLViewerRegion* region = gAgent.getRegion();
 	url = region->getCapability("AvatarPickerSearch");
 	// Prefer use of capabilities to search on both SLID and display name
-	// but allow display name search to be manually turned off for test
-	if (!url.empty()
-		&& LLAvatarNameCache::useDisplayNames())
+	if (!url.empty())
 	{
 		// capability urls don't end in '/', but we need one to parse
 		// query parameters correctly
@@ -439,7 +515,7 @@ void LLFloaterAvatarPicker::find()
 		url += "?page_size=100&names=";
 		url += LLURI::escape(text);
 		llinfos << "avatar picker " << url << llendl;
-		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID));
+		LLHTTPClient::get(url, new LLAvatarPickerResponder(mQueryID, getKey().asString()));
 	}
 	else
 	{
@@ -581,35 +657,36 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 		msg->getUUIDFast(  _PREHASH_Data,_PREHASH_AvatarID,	avatar_id, i);
 		msg->getStringFast(_PREHASH_Data,_PREHASH_FirstName, first_name, i);
 		msg->getStringFast(_PREHASH_Data,_PREHASH_LastName,	last_name, i);
-	
-		std::string avatar_name;
-		if (avatar_id.isNull())
-		{
-			LLStringUtil::format_map_t map;
-			map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
-			avatar_name = floater->getString("not_found", map);
-			search_results->setEnabled(FALSE);
-			floater->getChildView("ok_btn")->setEnabled(FALSE);
-		}
-		else
+
+		if (avatar_id != agent_id || !floater->isExcludeAgentFromSearchResults()) // exclude agent from search results?
 		{
-			avatar_name = LLCacheName::buildFullName(first_name, last_name);
-			search_results->setEnabled(TRUE);
-			found_one = TRUE;
+			std::string avatar_name;
+			if (avatar_id.isNull())
+			{
+				LLStringUtil::format_map_t map;
+				map["[TEXT]"] = floater->getChild<LLUICtrl>("Edit")->getValue().asString();
+				avatar_name = floater->getString("not_found", map);
+				search_results->setEnabled(FALSE);
+				floater->getChildView("ok_btn")->setEnabled(FALSE);
+			}
+			else
+			{
+				avatar_name = LLCacheName::buildFullName(first_name, last_name);
+				search_results->setEnabled(TRUE);
+				found_one = TRUE;
 
-			LLAvatarName av_name;
-			av_name.mLegacyFirstName = first_name;
-			av_name.mLegacyLastName = last_name;
-			av_name.mDisplayName = avatar_name;
-			const LLUUID& agent_id = avatar_id;
-			sAvatarNameMap[agent_id] = av_name;
+				LLAvatarName av_name;
+				av_name.fromString(avatar_name);
+				const LLUUID& agent_id = avatar_id;
+				sAvatarNameMap[agent_id] = av_name;
 
+			}
+			LLSD element;
+			element["id"] = avatar_id; // value
+			element["columns"][0]["column"] = "name";
+			element["columns"][0]["value"] = avatar_name;
+			search_results->addElement(element);
 		}
-		LLSD element;
-		element["id"] = avatar_id; // value
-		element["columns"][0]["column"] = "name";
-		element["columns"][0]["value"] = avatar_name;
-		search_results->addElement(element);
 	}
 
 	if (found_one)
@@ -624,52 +701,58 @@ void LLFloaterAvatarPicker::processAvatarPickerReply(LLMessageSystem* msg, void*
 void LLFloaterAvatarPicker::processResponse(const LLUUID& query_id, const LLSD& content)
 {
 	// Check for out-of-date query
-	if (query_id != mQueryID) return;
+	if (query_id == mQueryID)
+	{
+		LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
 
-	LLScrollListCtrl* search_results = getChild<LLScrollListCtrl>("SearchResults");
+		LLSD agents = content["agents"];
+
+		// clear "Searching" label on first results
+		search_results->deleteAllItems();
 
-	LLSD agents = content["agents"];
-	if (agents.size() == 0)
-	{
-		LLStringUtil::format_map_t map;
-		map["[TEXT]"] = childGetText("Edit");
 		LLSD item;
-		item["id"] = LLUUID::null;
-		item["columns"][0]["column"] = "name";
-		item["columns"][0]["value"] = getString("not_found", map);
-		search_results->addElement(item);
-		search_results->setEnabled(false);
-		getChildView("ok_btn")->setEnabled(false);
-		return;
-	}
+		LLSD::array_const_iterator it = agents.beginArray();
+		for ( ; it != agents.endArray(); ++it)
+		{
+			const LLSD& row = *it;
+			if (row["id"].asUUID() != gAgent.getID() || !mExcludeAgentFromSearchResults)
+			{
+				item["id"] = row["id"];
+				LLSD& columns = item["columns"];
+				columns[0]["column"] = "name";
+				columns[0]["value"] = row["display_name"];
+				columns[1]["column"] = "username";
+				columns[1]["value"] = row["username"];
+				search_results->addElement(item);
+
+				// add the avatar name to our list
+				LLAvatarName avatar_name;
+				avatar_name.fromLLSD(row);
+				sAvatarNameMap[row["id"].asUUID()] = avatar_name;
+			}
+		}
 
-	// clear "Searching" label on first results
-	search_results->deleteAllItems();
-
-	LLSD item;
-	LLSD::array_const_iterator it = agents.beginArray();
-	for ( ; it != agents.endArray(); ++it)
-	{
-		const LLSD& row = *it;
-		item["id"] = row["id"];
-		LLSD& columns = item["columns"];
-		columns[0]["column"] = "name";
-		columns[0]["value"] = row["display_name"];
-		columns[1]["column"] = "username";
-		columns[1]["value"] = row["username"];
-		search_results->addElement(item);
-
-		// add the avatar name to our list
-		LLAvatarName avatar_name;
-		avatar_name.fromLLSD(row);
-		sAvatarNameMap[row["id"].asUUID()] = avatar_name;
-	}
-
-	getChildView("ok_btn")->setEnabled(true);
-	search_results->setEnabled(true);
-	search_results->selectFirstItem();
-	onList();
-	search_results->setFocus(TRUE);
+		if (search_results->isEmpty())
+		{
+			LLStringUtil::format_map_t map;
+			map["[TEXT]"] = childGetText("Edit");
+			LLSD item;
+			item["id"] = LLUUID::null;
+			item["columns"][0]["column"] = "name";
+			item["columns"][0]["value"] = getString("not_found", map);
+			search_results->addElement(item);
+			search_results->setEnabled(false);
+			getChildView("ok_btn")->setEnabled(false);
+		}
+		else
+		{
+			getChildView("ok_btn")->setEnabled(true);
+			search_results->setEnabled(true);
+			search_results->selectFirstItem();
+			onList();
+			search_results->setFocus(TRUE);
+		}
+	}
 }
 
 //static
diff --git a/indra/newview/llfloateravatarpicker.h b/indra/newview/llfloateravatarpicker.h
index 96c039443ab222454621025c6a99419232cd0d5c..ed3e51c56f163823a8dfdd6fc1c1c4132638672f 100644
--- a/indra/newview/llfloateravatarpicker.h
+++ b/indra/newview/llfloateravatarpicker.h
@@ -34,7 +34,7 @@
 class LLAvatarName;
 class LLScrollListCtrl;
 
-class LLFloaterAvatarPicker : public LLFloater
+class LLFloaterAvatarPicker :public LLFloater
 {
 public:
 	typedef boost::signals2::signal<bool(const uuid_vec_t&), boost_boolean_combiner> validate_signal_t;
@@ -45,7 +45,10 @@ class LLFloaterAvatarPicker : public LLFloater
 	// Call this to select an avatar.	
 	static LLFloaterAvatarPicker* show(select_callback_t callback, 
 									   BOOL allow_multiple = FALSE,
-									   BOOL closeOnSelect = FALSE);
+									   BOOL closeOnSelect = FALSE,
+									   BOOL skip_agent = FALSE,
+                                       const std::string& name = "",
+                                       LLView * frustumOrigin = NULL);
 
 	LLFloaterAvatarPicker(const LLSD& key);
 	virtual ~LLFloaterAvatarPicker();
@@ -63,6 +66,7 @@ class LLFloaterAvatarPicker : public LLFloater
 						   std::string& tooltip_msg);
 
 	void openFriendsTab();
+	BOOL isExcludeAgentFromSearchResults() {return mExcludeAgentFromSearchResults;}
 
 private:
 	void editKeystroke(class LLLineEditor* caller, void* user_data);
@@ -84,13 +88,20 @@ class LLFloaterAvatarPicker : public LLFloater
 	void setAllowMultiple(BOOL allow_multiple);
 	LLScrollListCtrl* getActiveList();
 
+    void drawFrustum();
 	virtual void draw();
 	virtual BOOL handleKeyHere(KEY key, MASK mask);
 
 	LLUUID				mQueryID;
-	int				mNumResultsReturned;
+	int				    mNumResultsReturned;
 	BOOL				mNearMeListComplete;
 	BOOL				mCloseOnSelect;
+	BOOL                mExcludeAgentFromSearchResults;
+    LLHandle <LLView>   mFrustumOrigin;
+    F32		            mContextConeOpacity;
+    F32                 mContextConeInAlpha;
+    F32                 mContextConeOutAlpha;
+    F32                 mContextConeFadeTime;
 
 	validate_signal_t mOkButtonValidateSignal;
 	select_callback_t mSelectionCallback;
diff --git a/indra/newview/llfloateravatartextures.cpp b/indra/newview/llfloateravatartextures.cpp
index 4e10b4fc2c0d31f6fa2e34b953aafcc427cda5fc..048837acfec375183044c66715028ca0502bf946 100644
--- a/indra/newview/llfloateravatartextures.cpp
+++ b/indra/newview/llfloateravatartextures.cpp
@@ -32,12 +32,13 @@
 
 #include "llagent.h"
 #include "llagentwearables.h"
+#include "llviewerwearable.h"
 #include "lltexturectrl.h"
 #include "lluictrlfactory.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatarself.h"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 LLFloaterAvatarTextures::LLFloaterAvatarTextures(const LLSD& id)
   : LLFloater(id),
@@ -53,7 +54,7 @@ BOOL LLFloaterAvatarTextures::postBuild()
 {
 	for (U32 i=0; i < TEX_NUM_INDICES; i++)
 	{
-		const std::string tex_name = LLVOAvatarDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
+		const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(ETextureIndex(i))->mName;
 		mTextures[i] = getChild<LLTextureCtrl>(tex_name);
 	}
 	mTitle = getTitle();
@@ -75,13 +76,13 @@ static void update_texture_ctrl(LLVOAvatar* avatarp,
 								 ETextureIndex te)
 {
 	LLUUID id = IMG_DEFAULT_AVATAR;
-	const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture(te);
+	const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
 	if (tex_entry->mIsLocalTexture)
 	{
 		if (avatarp->isSelf())
 		{
 			const LLWearableType::EType wearable_type = tex_entry->mWearableType;
-			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
 			if (wearable)
 			{
 				LLLocalTextureObject *lto = wearable->getLocalTextureObject(te);
@@ -163,17 +164,17 @@ void LLFloaterAvatarTextures::onClickDump(void* data)
 			const LLTextureEntry* te = avatarp->getTE(i);
 			if (!te) continue;
 
-			const LLVOAvatarDictionary::TextureEntry* tex_entry = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)(i));
+			const LLAvatarAppearanceDictionary::TextureEntry* tex_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)(i));
 			if (!tex_entry)
 				continue;
 
 			if (LLVOAvatar::isIndexLocalTexture((ETextureIndex)i))
 			{
 				LLUUID id = IMG_DEFAULT_AVATAR;
-				LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
+				LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType((ETextureIndex)i);
 				if (avatarp->isSelf())
 				{
-					LLWearable *wearable = gAgentWearables.getWearable(wearable_type, 0);
+					LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, 0);
 					if (wearable)
 					{
 						LLLocalTextureObject *lto = wearable->getLocalTextureObject(i);
diff --git a/indra/newview/llfloateravatartextures.h b/indra/newview/llfloateravatartextures.h
index 85ff545855ecc67e504a8bc319864feae72cc688..02474a10e15d2fc255e86f59df8d9a23eb6504d8 100644
--- a/indra/newview/llfloateravatartextures.h
+++ b/indra/newview/llfloateravatartextures.h
@@ -30,7 +30,7 @@
 #include "llfloater.h"
 #include "lluuid.h"
 #include "llstring.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 
 class LLTextureCtrl;
 
@@ -51,7 +51,7 @@ class LLFloaterAvatarTextures : public LLFloater
 private:
 	LLUUID	mID;
 	std::string mTitle;
-	LLTextureCtrl* mTextures[LLVOAvatarDefines::TEX_NUM_INDICES];
+	LLTextureCtrl* mTextures[LLAvatarAppearanceDefines::TEX_NUM_INDICES];
 };
 
 #endif
diff --git a/indra/newview/llfloaterbuycontents.cpp b/indra/newview/llfloaterbuycontents.cpp
index fffd724b221111556406b5cc80fe336e508cb855..aa6ace2a616a072d359ab934cf8d9f97e0c00d3c 100644
--- a/indra/newview/llfloaterbuycontents.cpp
+++ b/indra/newview/llfloaterbuycontents.cpp
@@ -40,6 +40,7 @@
 #include "llcheckboxctrl.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"	// for gInventory
 #include "llfirstuse.h"
 #include "llfloaterreg.h"
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index 8223e89b64752078a0d5b6442c623b4b3b8f32d9..42857b2aa21d91f2622b28e328c40edca12d3d1f 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -538,7 +538,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -551,7 +551,7 @@ void LLFloaterBuyLandUI::updateCovenantInfo()
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index 62848586cdbb1438589b502fc5312f18e2d0c8d4..f2deb6a805e5083fe78e54ffef0daa2464bfc877 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -1102,12 +1102,12 @@ BOOL	LLPreviewAnimation::render()
 
 	gGL.flush();
 
-	LLVector3 target_pos = avatarp->mRoot.getWorldPosition();
+	LLVector3 target_pos = avatarp->mRoot->getWorldPosition();
 
 	LLQuaternion camera_rot = LLQuaternion(mCameraPitch, LLVector3::y_axis) * 
 		LLQuaternion(mCameraYaw, LLVector3::z_axis);
 
-	LLQuaternion av_rot = avatarp->mRoot.getWorldRotation() * camera_rot;
+	LLQuaternion av_rot = avatarp->mRoot->getWorldRotation() * camera_rot;
 	LLViewerCamera::getInstance()->setOriginAndLookAt(
 		target_pos + ((LLVector3(mCameraDistance, 0.f, 0.f) + mCameraOffset) * av_rot),		// camera
 		LLVector3::z_axis,																	// up
diff --git a/indra/newview/llfloaterchatvoicevolume.cpp b/indra/newview/llfloaterchatvoicevolume.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3c76a3a43cdfc1627d748cbef99e5b78a99ec603
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.cpp
@@ -0,0 +1,44 @@
+/** 
+ * @file llfloaterchatvoicevolume.cpp
+ *
+ * $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 "llfloaterchatvoicevolume.h"
+
+LLFloaterChatVoiceVolume::LLFloaterChatVoiceVolume(const LLSD& key)
+: LLInspect(key)
+{
+}
+
+void LLFloaterChatVoiceVolume::onOpen(const LLSD& key)
+{
+	LLInspect::onOpen(key);
+	LLUI::positionViewNearMouse(this);
+}
+
+LLFloaterChatVoiceVolume::~LLFloaterChatVoiceVolume()
+{
+	LLTransientFloaterMgr::getInstance()->removeControlView(this);
+};
diff --git a/indra/newview/llfloaterchatvoicevolume.h b/indra/newview/llfloaterchatvoicevolume.h
new file mode 100644
index 0000000000000000000000000000000000000000..61ad92b6da4dd72a0566984bcb15f16b59123593
--- /dev/null
+++ b/indra/newview/llfloaterchatvoicevolume.h
@@ -0,0 +1,44 @@
+/** 
+ * @file llfloaterchatvoicevolume.h
+ *
+ * $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 LLFLOATERCHATVOICEVOLUME_H_
+#define LLFLOATERCHATVOICEVOLUME_H_
+
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+
+class LLFloaterChatVoiceVolume : public LLInspect, LLTransientFloater
+{
+public:
+
+	LLFloaterChatVoiceVolume(const LLSD& key);
+	virtual ~LLFloaterChatVoiceVolume();
+
+	virtual void onOpen(const LLSD& key);
+
+	/*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+};
+
+#endif /* LLFLOATERCHATVOICEVOLUME_H_ */
diff --git a/indra/newview/llfloatercolorpicker.cpp b/indra/newview/llfloatercolorpicker.cpp
index d6ebe44daadef11f8d3cecdb0f7cb8083ee0a1aa..a03425649fd058879afa709b7a732fb5052c758a 100644
--- a/indra/newview/llfloatercolorpicker.cpp
+++ b/indra/newview/llfloatercolorpicker.cpp
@@ -62,10 +62,6 @@
 #include <sstream>
 #include <iomanip>
 
-const F32 CONTEXT_CONE_IN_ALPHA = 0.0f;
-const F32 CONTEXT_CONE_OUT_ALPHA = 1.f;
-const F32 CONTEXT_FADE_TIME = 0.08f;
-
 //////////////////////////////////////////////////////////////////////////////
 //
 // Class LLFloaterColorPicker
@@ -105,7 +101,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
 	  mSwatch				( swatch ),
 	  mActive				( TRUE ),
 	  mCanApplyImmediately	( show_apply_immediate ),
-	  mContextConeOpacity	( 0.f )
+	  mContextConeOpacity	( 0.f ),
+      mContextConeInAlpha   ( 0.f ),
+      mContextConeOutAlpha   ( 0.f ),
+      mContextConeFadeTime   ( 0.f )
 {
 	buildFromFile ( "floater_color_picker.xml");
 
@@ -117,6 +116,10 @@ LLFloaterColorPicker::LLFloaterColorPicker (LLColorSwatchCtrl* swatch, BOOL show
 		mApplyImmediateCheck->setEnabled(FALSE);
 		mApplyImmediateCheck->set(FALSE);
 	}
+
+    mContextConeInAlpha = gSavedSettings.getF32("ContextConeInAlpha");
+    mContextConeOutAlpha = gSavedSettings.getF32("ContextConeOutAlpha");
+    mContextConeFadeTime = gSavedSettings.getF32("ContextConeFadeTime");
 }
 
 LLFloaterColorPicker::~LLFloaterColorPicker()
@@ -486,37 +489,37 @@ void LLFloaterColorPicker::draw()
 	mSwatch->localRectToOtherView(mSwatch->getLocalRect(), &swatch_rect, this);
 	// draw context cone connecting color picker with color swatch in parent floater
 	LLRect local_rect = getLocalRect();
-	if (gFocusMgr.childHasKeyboardFocus(this) && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
+	if (hasFocus() && mSwatch->isInVisibleChain() && mContextConeOpacity > 0.001f)
 	{
 		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		LLGLEnable(GL_CULL_FACE);
 		gGL.begin(LLRender::QUADS);
 		{
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mRight, local_rect.mTop);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mTop);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mTop);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
 			gGL.vertex2i(local_rect.mRight, local_rect.mTop);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mTop);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
 
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_OUT_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeOutAlpha * mContextConeOpacity);
 			gGL.vertex2i(local_rect.mLeft, local_rect.mBottom);
 			gGL.vertex2i(local_rect.mRight, local_rect.mBottom);
-			gGL.color4f(0.f, 0.f, 0.f, CONTEXT_CONE_IN_ALPHA * mContextConeOpacity);
+			gGL.color4f(0.f, 0.f, 0.f, mContextConeInAlpha * mContextConeOpacity);
 			gGL.vertex2i(swatch_rect.mRight, swatch_rect.mBottom);
 			gGL.vertex2i(swatch_rect.mLeft, swatch_rect.mBottom);
 		}
@@ -525,11 +528,12 @@ void LLFloaterColorPicker::draw()
 
 	if (gFocusMgr.childHasMouseCapture(getDragHandle()))
 	{
-		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+		mContextConeOpacity = lerp(mContextConeOpacity, gSavedSettings.getF32("PickerContextOpacity"), 
+                                        LLCriticalDamp::getInterpolant(mContextConeFadeTime));
 	}
 	else
 	{
-		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(CONTEXT_FADE_TIME));
+		mContextConeOpacity = lerp(mContextConeOpacity, 0.f, LLCriticalDamp::getInterpolant(mContextConeFadeTime));
 	}
 
 	mPipetteBtn->setToggleState(LLToolMgr::getInstance()->getCurrentTool() == LLToolPipette::getInstance());
diff --git a/indra/newview/llfloatercolorpicker.h b/indra/newview/llfloatercolorpicker.h
index 8e387c4f7c151295329aa5c0c2cf05d62c311d3f..bab061771260790292ef80457bee968df7ded26e 100644
--- a/indra/newview/llfloatercolorpicker.h
+++ b/indra/newview/llfloatercolorpicker.h
@@ -189,6 +189,10 @@ class LLFloaterColorPicker
 		LLButton* mPipetteBtn;
 
 		F32		  mContextConeOpacity;
+        F32       mContextConeInAlpha;
+        F32       mContextConeOutAlpha;
+        F32       mContextConeFadeTime;
+
 };
 
 #endif // LL_LLFLOATERCOLORPICKER_H
diff --git a/indra/newview/llfloaterconversationlog.cpp b/indra/newview/llfloaterconversationlog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4c910c56555ffe6535b5cb08add93c64a5ab53ae
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.cpp
@@ -0,0 +1,134 @@
+/**
+ * @file llfloaterconversationlog.cpp
+ * @brief Functionality of the "conversation log" floater
+ *
+ * $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 "llconversationloglist.h"
+#include "llfiltereditor.h"
+#include "llfloaterconversationlog.h"
+#include "llfloaterreg.h"
+#include "llmenubutton.h"
+
+LLFloaterConversationLog::LLFloaterConversationLog(const LLSD& key)
+:	LLFloater(key),
+	mConversationLogList(NULL)
+{
+	mCommitCallbackRegistrar.add("CallLog.Action",	boost::bind(&LLFloaterConversationLog::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("CallLog.Check",	boost::bind(&LLFloaterConversationLog::isActionChecked, this, _2));
+}
+
+BOOL LLFloaterConversationLog::postBuild()
+{
+	mConversationLogList = getChild<LLConversationLogList>("conversation_log_list");
+
+	switch (gSavedSettings.getU32("CallLogSortOrder"))
+	{
+	case LLConversationLogList::E_SORT_BY_NAME:
+		mConversationLogList->sortByName();
+		break;
+
+	case LLConversationLogList::E_SORT_BY_DATE:
+		mConversationLogList->sortByDate();
+		break;
+	}
+
+	// Use the context menu of the Conversation list for the Conversation tab gear menu.
+	LLToggleableMenu* conversations_gear_menu = mConversationLogList->getContextMenu();
+	if (conversations_gear_menu)
+	{
+		getChild<LLMenuButton>("conversations_gear_btn")->setMenu(conversations_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+
+	getChild<LLFilterEditor>("people_filter_input")->setCommitCallback(boost::bind(&LLFloaterConversationLog::onFilterEdit, this, _2));
+
+	return LLFloater::postBuild();
+}
+
+void LLFloaterConversationLog::draw()
+{
+	getChild<LLMenuButton>("conversations_gear_btn")->setEnabled(mConversationLogList->getSelectedItem() != NULL);
+	LLFloater::draw();
+}
+
+void LLFloaterConversationLog::onFilterEdit(const std::string& search_string)
+{
+	std::string filter = search_string;
+	LLStringUtil::trimHead(filter);
+
+	mConversationLogList->setNameFilter(filter);
+}
+
+
+void LLFloaterConversationLog::onCustomAction (const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	if ("sort_by_name" == command_name)
+	{
+		mConversationLogList->sortByName();
+		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_NAME);
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		mConversationLogList->sortByDate();
+		gSavedSettings.setU32("CallLogSortOrder", LLConversationLogList::E_SORT_BY_DATE);
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		mConversationLogList->toggleSortFriendsOnTop();
+	}
+	else if ("view_nearby_chat_history" == command_name)
+	{
+		LLFloaterReg::showInstance("preview_conversation", LLSD(LLUUID::null), true);
+	}
+}
+
+bool LLFloaterConversationLog::isActionEnabled(const LLSD& userdata)
+{
+	return true;
+}
+
+bool LLFloaterConversationLog::isActionChecked(const LLSD& userdata)
+{
+	const std::string command_name = userdata.asString();
+
+	U32 sort_order = gSavedSettings.getU32("CallLogSortOrder");
+
+	if ("sort_by_name" == command_name)
+	{
+		return sort_order == LLConversationLogList::E_SORT_BY_NAME;
+	}
+	else if ("sort_by_date" == command_name)
+	{
+		return sort_order == LLConversationLogList::E_SORT_BY_DATE;
+	}
+	else if ("sort_friends_on_top" == command_name)
+	{
+		return gSavedSettings.getBOOL("SortFriendsFirst");
+	}
+
+	return false;
+}
+
diff --git a/indra/newview/llfloaterconversationlog.h b/indra/newview/llfloaterconversationlog.h
new file mode 100644
index 0000000000000000000000000000000000000000..e971330f3d0b6efe54aa49a5cafcbb39c1b618d2
--- /dev/null
+++ b/indra/newview/llfloaterconversationlog.h
@@ -0,0 +1,56 @@
+/**
+ * @file llfloaterconversationlog.h
+ *
+ * $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_LLFLOATERCONVERSATIONLOG_H_
+#define LL_LLFLOATERCONVERSATIONLOG_H_
+
+#include "llfloater.h"
+
+class LLConversationLogList;
+
+class LLFloaterConversationLog : public LLFloater
+{
+public:
+
+	LLFloaterConversationLog(const LLSD& key);
+	virtual ~LLFloaterConversationLog(){};
+
+	virtual BOOL postBuild();
+
+	virtual void draw();
+
+	void onFilterEdit(const std::string& search_string);
+
+private:
+
+	void onCustomAction (const LLSD& userdata);
+	bool isActionEnabled(const LLSD& userdata);
+	bool isActionChecked(const LLSD& userdata);
+
+	LLConversationLogList* mConversationLogList;
+};
+
+
+#endif /* LLFLOATERCONVERSATIONLOG_H_ */
diff --git a/indra/newview/llfloaterconversationpreview.cpp b/indra/newview/llfloaterconversationpreview.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..a3d715530d0a8dd48576b21d4248c69f888ac90e
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.cpp
@@ -0,0 +1,186 @@
+/**
+ * @file llfloaterconversationpreview.cpp
+ *
+ * $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 "llconversationlog.h"
+#include "llfloaterconversationpreview.h"
+#include "llimview.h"
+#include "lllineeditor.h"
+#include "llfloaterimnearbychat.h"
+#include "llspinctrl.h"
+#include "lltrans.h"
+
+const std::string LL_FCP_COMPLETE_NAME("complete_name");
+const std::string LL_FCP_ACCOUNT_NAME("user_name");
+
+LLFloaterConversationPreview::LLFloaterConversationPreview(const LLSD& session_id)
+:	LLFloater(session_id),
+	mChatHistory(NULL),
+	mSessionID(session_id.asUUID()),
+	mCurrentPage(0),
+	mPageSize(gSavedSettings.getS32("ConversationHistoryPageSize")),
+	mAccountName(session_id[LL_FCP_ACCOUNT_NAME]),
+	mCompleteName(session_id[LL_FCP_COMPLETE_NAME])
+{
+}
+
+BOOL LLFloaterConversationPreview::postBuild()
+{
+	mChatHistory = getChild<LLChatHistory>("chat_history");
+
+	const LLConversation* conv = LLConversationLog::instance().getConversation(mSessionID);
+	std::string name;
+	std::string file;
+
+	if (mAccountName != "")
+	{
+		name = mCompleteName;
+		file = mAccountName;
+	}
+	else if (mSessionID != LLUUID::null && conv)
+	{
+		name = conv->getConversationName();
+		file = conv->getHistoryFileName();
+	}
+	else
+	{
+		name = LLTrans::getString("NearbyChatTitle");
+		file = "chat";
+	}
+
+	LLStringUtil::format_map_t args;
+	args["[NAME]"] = name;
+	std::string title = getString("Title", args);
+	setTitle(title);
+
+	LLSD load_params;
+	load_params["load_all_history"] = true;
+	load_params["cut_off_todays_date"] = false;
+
+	LLLogChat::loadChatHistory(file, mMessages, load_params);
+	mCurrentPage = mMessages.size() / mPageSize;
+
+	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);
+
+	return LLFloater::postBuild();
+}
+
+void LLFloaterConversationPreview::draw()
+{
+	LLFloater::draw();
+}
+
+void LLFloaterConversationPreview::onOpen(const LLSD& key)
+{
+	showHistory();
+}
+
+void LLFloaterConversationPreview::showHistory()
+{
+	if (!mMessages.size())
+	{
+		return;
+	}
+
+	mChatHistory->clear();
+
+	std::ostringstream message;
+	std::list<LLSD>::const_iterator iter = mMessages.begin();
+
+	int delta = 0;
+	if (mCurrentPage)
+	{
+		int remainder = mMessages.size() % mPageSize;
+		delta = (remainder == 0) ? 0 : (mPageSize - remainder);
+	}
+
+	std::advance(iter, (mCurrentPage * mPageSize) - delta);
+
+	for (int msg_num = 0; (iter != mMessages.end() && msg_num < mPageSize); ++iter, ++msg_num)
+	{
+		LLSD msg = *iter;
+
+		LLUUID from_id 		= LLUUID::null;
+		std::string time	= msg["time"].asString();
+		std::string from	= msg["from"].asString();
+		std::string message	= msg["message"].asString();
+
+		if (msg["from_id"].isDefined())
+		{
+			from_id = msg["from_id"].asUUID();
+		}
+		else
+ 		{
+			std::string legacy_name = gCacheName->buildLegacyName(from);
+ 			gCacheName->getUUID(legacy_name, from_id);
+ 		}
+
+		LLChat chat;
+		chat.mFromID = from_id;
+		chat.mSessionID = mSessionID;
+		chat.mFromName = from;
+		chat.mTimeStr = time;
+		chat.mChatStyle = CHAT_STYLE_HISTORY;
+		chat.mText = message;
+
+		if (from_id.isNull() && SYSTEM_FROM == from)
+		{
+			chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+		}
+		else if (from_id.isNull())
+		{
+			chat.mSourceType = LLFloaterIMNearbyChat::isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+		}
+
+		LLSD chat_args;
+		chat_args["use_plain_text_chat_history"] =
+						gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] = gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+		mChatHistory->appendMessage(chat,chat_args);
+	}
+
+}
+
+void LLFloaterConversationPreview::onMoreHistoryBtnClick()
+{
+	mCurrentPage = (int)(mPageSpinner->getValueF32());
+	if (--mCurrentPage < 0)
+	{
+		return;
+	}
+
+	showHistory();
+}
diff --git a/indra/newview/llfloaterconversationpreview.h b/indra/newview/llfloaterconversationpreview.h
new file mode 100644
index 0000000000000000000000000000000000000000..b17ae84b632e9fecc21a7ce5360afc2335fc484d
--- /dev/null
+++ b/indra/newview/llfloaterconversationpreview.h
@@ -0,0 +1,64 @@
+/**
+ * @file llfloaterconversationpreview.h
+ *
+ * $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 LLFLOATERCONVERSATIONPREVIEW_H_
+#define LLFLOATERCONVERSATIONPREVIEW_H_
+
+#include "llchathistory.h"
+#include "llfloater.h"
+
+extern const std::string LL_FCP_COMPLETE_NAME;	//"complete_name"
+extern const std::string LL_FCP_ACCOUNT_NAME;		//"user_name"
+
+class LLSpinCtrl;
+
+class LLFloaterConversationPreview : public LLFloater
+{
+public:
+
+	LLFloaterConversationPreview(const LLSD& session_id);
+	virtual ~LLFloaterConversationPreview(){};
+
+	virtual BOOL postBuild();
+
+	virtual void draw();
+	virtual void onOpen(const LLSD& key);
+
+private:
+	void onMoreHistoryBtnClick();
+	void showHistory();
+
+	LLSpinCtrl*		mPageSpinner;
+	LLChatHistory*	mChatHistory;
+	LLUUID			mSessionID;
+	int				mCurrentPage;
+	int				mPageSize;
+
+	std::list<LLSD> mMessages;
+	std::string		mAccountName;
+	std::string		mCompleteName;
+};
+
+#endif /* LLFLOATERCONVERSATIONPREVIEW_H_ */
diff --git a/indra/newview/llfloaterdisplayname.cpp b/indra/newview/llfloaterdisplayname.cpp
index ac8f1079280591c0fd4323a5fb36baba6b888c8e..e2cef5630b0c841e9c908c87bdddf21393a4456b 100644
--- a/indra/newview/llfloaterdisplayname.cpp
+++ b/indra/newview/llfloaterdisplayname.cpp
@@ -44,7 +44,7 @@ class LLFloaterDisplayName : public LLFloater
 {
 public:
 	LLFloaterDisplayName(const LLSD& key);
-	virtual ~LLFloaterDisplayName() {};
+	virtual ~LLFloaterDisplayName() { }
 	/*virtual*/	BOOL	postBuild();
 	void onSave();
 	void onReset();
@@ -58,8 +58,8 @@ class LLFloaterDisplayName : public LLFloater
 										  const LLSD& content);
 };
 
-LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key)
-	: LLFloater(key)
+LLFloaterDisplayName::LLFloaterDisplayName(const LLSD& key) :
+	LLFloater(key)
 {
 }
 
@@ -122,10 +122,6 @@ void LLFloaterDisplayName::onCacheSetName(bool success,
 		LLSD args;
 		args["DISPLAY_NAME"] = content["display_name"];
 		LLNotificationsUtil::add("SetDisplayNameSuccess", args);
-
-		// Re-fetch my name, as it may have been sanitized by the service
-		//LLAvatarNameCache::get(getAvatarId(),
-		//	boost::bind(&LLPanelMyProfileEdit::onNameCache, this, _1, _2));
 		return;
 	}
 
@@ -164,10 +160,9 @@ void LLFloaterDisplayName::onCancel()
 
 void LLFloaterDisplayName::onReset()
 {
-	if (LLAvatarNameCache::useDisplayNames())
+	if (LLAvatarNameCache::hasNameLookupURL())
 	{
-		LLViewerDisplayName::set("",
-			boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
+		LLViewerDisplayName::set("",boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));
 	}	
 	else
 	{
@@ -199,10 +194,9 @@ void LLFloaterDisplayName::onSave()
 		return;
 	}
 	
-	if (LLAvatarNameCache::useDisplayNames())
+	if (LLAvatarNameCache::hasNameLookupURL())
 	{
-		LLViewerDisplayName::set(display_name_utf8,
-			boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	
+		LLViewerDisplayName::set(display_name_utf8,boost::bind(&LLFloaterDisplayName::onCacheSetName, this, _1, _2, _3));	
 	}
 	else
 	{
diff --git a/indra/newview/llfloatergodtools.cpp b/indra/newview/llfloatergodtools.cpp
index fb905eae116cc672db3507463f7e2b651c3c5a30..fe6223fbf53598f804b21495d561d6430c2beec9 100644
--- a/indra/newview/llfloatergodtools.cpp
+++ b/indra/newview/llfloatergodtools.cpp
@@ -164,9 +164,9 @@ LLFloaterGodTools::~LLFloaterGodTools()
 }
 
 
-U32 LLFloaterGodTools::computeRegionFlags() const
+U64 LLFloaterGodTools::computeRegionFlags() const
 {
-	U32 flags = gAgent.getRegion()->getRegionFlags();
+	U64 flags = gAgent.getRegion()->getRegionFlags();
 	if (mPanelRegionTools) flags = mPanelRegionTools->computeRegionFlags(flags);
 	if (mPanelObjectTools) flags = mPanelObjectTools->computeRegionFlags(flags);
 	return flags;
@@ -210,7 +210,7 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	if (!msg) return;
 
 	//const S32 SIM_NAME_BUF = 256;
-	U32 region_flags;
+	U64 region_flags;
 	U8 sim_access;
 	U8 agent_limit;
 	std::string sim_name;
@@ -231,13 +231,23 @@ void LLFloaterGodTools::processRegionInfo(LLMessageSystem* msg)
 	msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, sim_name);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, estate_id);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, parent_estate_id);
-	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, region_flags);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, sim_access);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, agent_limit);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, object_bonus_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_BillableFactor, billable_factor);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_WaterHeight, water_height);
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		region_flags = flags;
+	}
+
 	if (host != gAgent.getRegionHost())
 	{
 		// Update is for a different region than the one we're in.
@@ -341,6 +351,7 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
 		LLMessageSystem *msg = gMessageSystem;
 		LLPanelRegionTools *rtool = god_tools->mPanelRegionTools;
 
+		U64 region_flags = computeRegionFlags();
 		msg->newMessage("GodUpdateRegionInfo");
 		msg->nextBlockFast(_PREHASH_AgentData);
 		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
@@ -349,11 +360,14 @@ void LLFloaterGodTools::sendGodUpdateRegionInfo()
 		msg->addStringFast(_PREHASH_SimName, rtool->getSimName());
 		msg->addU32Fast(_PREHASH_EstateID, rtool->getEstateID());
 		msg->addU32Fast(_PREHASH_ParentEstateID, rtool->getParentEstateID());
-		msg->addU32Fast(_PREHASH_RegionFlags, computeRegionFlags());
+		// Legacy flags
+		msg->addU32Fast(_PREHASH_RegionFlags, U32(region_flags));
 		msg->addF32Fast(_PREHASH_BillableFactor, rtool->getBillableFactor());
 		msg->addS32Fast(_PREHASH_PricePerMeter, rtool->getPricePerMeter());
 		msg->addS32Fast(_PREHASH_RedirectGridX, rtool->getRedirectGridX());
 		msg->addS32Fast(_PREHASH_RedirectGridY, rtool->getRedirectGridY());
+		msg->nextBlockFast(_PREHASH_RegionInfo2);
+		msg->addU64Fast(_PREHASH_RegionFlagsExtended, region_flags);
 
 		gAgent.sendReliableMessage();
 	}
@@ -434,7 +448,7 @@ LLPanelRegionTools::~LLPanelRegionTools()
 	// base class will take care of everything
 }
 
-U32 LLPanelRegionTools::computeRegionFlags(U32 flags) const
+U64 LLPanelRegionTools::computeRegionFlags(U64 flags) const
 {
 	flags &= getRegionFlagsMask();
 	flags |= getRegionFlags();
@@ -562,9 +576,9 @@ S32 LLPanelRegionTools::getGridPosY() const
 	return getChild<LLUICtrl>("gridposy")->getValue().asInteger();
 }
 
-U32 LLPanelRegionTools::getRegionFlags() const
+U64 LLPanelRegionTools::getRegionFlags() const
 {
-	U32 flags = 0x0;
+	U64 flags = 0x0;
 	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()  
 					? set_prelude_flags(flags)
 					: unset_prelude_flags(flags);
@@ -601,9 +615,9 @@ U32 LLPanelRegionTools::getRegionFlags() const
 	return flags;
 }
 
-U32 LLPanelRegionTools::getRegionFlagsMask() const
+U64 LLPanelRegionTools::getRegionFlagsMask() const
 {
-	U32 flags = 0xffffffff;
+	U64 flags = 0xFFFFFFFFFFFFFFFFULL;
 	flags = getChild<LLUICtrl>("check prelude")->getValue().asBoolean()
 				? set_prelude_flags(flags)
 				: unset_prelude_flags(flags);
@@ -684,7 +698,7 @@ void LLPanelRegionTools::setParentEstateID(U32 id)
 	getChild<LLUICtrl>("parentestate")->setValue((S32)id);
 }
 
-void LLPanelRegionTools::setCheckFlags(U32 flags)
+void LLPanelRegionTools::setCheckFlags(U64 flags)
 {
 	getChild<LLUICtrl>("check prelude")->setValue(is_prelude(flags) ? TRUE : FALSE);
 	getChild<LLUICtrl>("check fixed sun")->setValue(flags & REGION_FLAGS_SUN_FIXED ? TRUE : FALSE);
@@ -943,7 +957,7 @@ void LLPanelObjectTools::refresh()
 }
 
 
-U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
+U64 LLPanelObjectTools::computeRegionFlags(U64 flags) const
 {
 	if (getChild<LLUICtrl>("disable scripts")->getValue().asBoolean())
 	{
@@ -973,7 +987,7 @@ U32 LLPanelObjectTools::computeRegionFlags(U32 flags) const
 }
 
 
-void LLPanelObjectTools::setCheckFlags(U32 flags)
+void LLPanelObjectTools::setCheckFlags(U64 flags)
 {
 	getChild<LLUICtrl>("disable scripts")->setValue(flags & REGION_FLAGS_SKIP_SCRIPTS ? TRUE : FALSE);
 	getChild<LLUICtrl>("disable collisions")->setValue(flags & REGION_FLAGS_SKIP_COLLISIONS ? TRUE : FALSE);
@@ -1123,11 +1137,13 @@ bool LLPanelObjectTools::callbackSimWideDeletes( const LLSD& notification, const
 
 void LLPanelObjectTools::onClickSet()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2));
+    LLView * button = findChild<LLButton>("Set Target");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelObjectTools::callbackAvatarID, this, _1,_2), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	// grandparent is a floater, which can have a dependent
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
diff --git a/indra/newview/llfloatergodtools.h b/indra/newview/llfloatergodtools.h
index 1aa8b838fb70516acdcc5420e8f1424caa6a1663..cbaeee705180dbf3cdec361e1017a22e5b059d86 100644
--- a/indra/newview/llfloatergodtools.h
+++ b/indra/newview/llfloatergodtools.h
@@ -98,7 +98,7 @@ class LLFloaterGodTools
 	~LLFloaterGodTools();
 	
 protected:
-	U32 computeRegionFlags() const;
+	U64 computeRegionFlags() const;
 
 protected:
 
@@ -147,8 +147,8 @@ class LLPanelRegionTools
 	const std::string getSimName() const;
 	U32 getEstateID() const;
 	U32 getParentEstateID() const;
-	U32 getRegionFlags() const;
-	U32 getRegionFlagsMask() const;
+	U64 getRegionFlags() const;
+	U64 getRegionFlagsMask() const;
 	F32 getBillableFactor() const;
 	S32 getPricePerMeter() const;
 	S32 getGridPosX() const;
@@ -160,7 +160,7 @@ class LLPanelRegionTools
 	void setSimName(const std::string& name);
 	void setEstateID(U32 id);
 	void setParentEstateID(U32 id);
-	void setCheckFlags(U32 flags);
+	void setCheckFlags(U64 flags);
 	void setBillableFactor(F32 billable_factor);
 	void setPricePerMeter(S32 price);
 	void setGridPosX(S32 pos);
@@ -168,7 +168,7 @@ class LLPanelRegionTools
 	void setRedirectGridX(S32 pos);
 	void setRedirectGridY(S32 pos);
 
-	U32 computeRegionFlags(U32 initial_flags) const;
+	U64 computeRegionFlags(U64 initial_flags) const;
 	void clearAllWidgets();
 	void enableAllWidgets();
 
@@ -218,10 +218,10 @@ class LLPanelObjectTools
 	/*virtual*/ void refresh();
 
 	void setTargetAvatar(const LLUUID& target_id);
-	U32 computeRegionFlags(U32 initial_flags) const;
+	U64 computeRegionFlags(U64 initial_flags) const;
 	void clearAllWidgets();
 	void enableAllWidgets();
-	void setCheckFlags(U32 flags);
+	void setCheckFlags(U64 flags);
 
 	void onChangeAnything();
 	void onApplyChanges();
diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp
index 2575f6f8172d13c6e32ba39d17390208b535aa39..52e678ce248e651f40be20242586339f461f37d4 100644
--- a/indra/newview/llfloaterimagepreview.cpp
+++ b/indra/newview/llfloaterimagepreview.cpp
@@ -593,7 +593,7 @@ S8 LLImagePreviewAvatar::getType() const
 
 void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const std::string& mesh_name, LLImageRaw* imagep, F32 distance, BOOL male) 
 { 
-	mTargetJoint = mDummyAvatar->mRoot.findJoint(joint_name);
+	mTargetJoint = mDummyAvatar->mRoot->findJoint(joint_name);
 	// clear out existing test mesh
 	if (mTargetMesh)
 	{
@@ -612,9 +612,9 @@ void LLImagePreviewAvatar::setPreviewTarget(const std::string& joint_name, const
 		mDummyAvatar->updateVisualParams();
 		mDummyAvatar->updateGeometry(mDummyAvatar->mDrawable);
 	}
-	mDummyAvatar->mRoot.setVisible(FALSE, TRUE);
+	mDummyAvatar->mRoot->setVisible(FALSE, TRUE);
 
-	mTargetMesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+	mTargetMesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
 	mTargetMesh->setTestTexture(mTextureName);
 	mTargetMesh->setVisible(TRUE, FALSE);
 	mCameraDistance = distance;
@@ -631,7 +631,7 @@ void LLImagePreviewAvatar::clearPreviewTexture(const std::string& mesh_name)
 {
 	if (mDummyAvatar)
 	{
-		LLViewerJointMesh *mesh = (LLViewerJointMesh*)mDummyAvatar->mRoot.findJoint(mesh_name);
+		LLViewerJointMesh *mesh = dynamic_cast<LLViewerJointMesh*>(mDummyAvatar->mRoot->findJoint(mesh_name));
 		// clear out existing test mesh
 		if (mesh)
 		{
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..58817485fb564dac0ff0296ec12aa73c7d299de4
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -0,0 +1,2028 @@
+/** 
+ * @file llfloaterimcontainer.cpp
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
+
+#include "llfloaterreg.h"
+#include "lllayoutstack.h"
+#include "llfloaterimnearbychat.h"
+
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llavatariconctrl.h"
+#include "llavatarnamecache.h"
+#include "llcallbacklist.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llgroupactions.h"
+#include "llgroupiconctrl.h"
+#include "llflashtimer.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterpreference.h"
+#include "llimview.h"
+#include "llnotificationsutil.h"
+#include "lltransientfloatermgr.h"
+#include "llviewercontrol.h"
+#include "llconversationview.h"
+#include "llcallbacklist.h"
+#include "llworld.h"
+#include "llsdserialize.h"
+#include "llviewerobjectlist.h"
+
+//
+// LLFloaterIMContainer
+//
+LLFloaterIMContainer::LLFloaterIMContainer(const LLSD& seed, const Params& params /*= getDefaultParams()*/)
+:	LLMultiFloater(seed, params),
+	mExpandCollapseBtn(NULL),
+	mConversationsRoot(NULL),
+	mConversationsEventStream("ConversationsEvents"),
+	mInitialized(false)
+{
+    mEnableCallbackRegistrar.add("IMFloaterContainer.Check", boost::bind(&LLFloaterIMContainer::isActionChecked, this, _2));
+	mCommitCallbackRegistrar.add("IMFloaterContainer.Action", boost::bind(&LLFloaterIMContainer::onCustomAction,  this, _2));
+	
+	mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMContainer::checkContextMenuItem,	this, _2));
+	mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMContainer::enableContextMenuItem,	this, _2));
+	mEnableCallbackRegistrar.add("Avatar.VisibleItem", boost::bind(&LLFloaterIMContainer::visibleContextMenuItem,	this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelected, this, _2));
+    
+    mCommitCallbackRegistrar.add("Group.DoToSelected", boost::bind(&LLFloaterIMContainer::doToSelectedGroup, this, _2));
+
+	// Firstly add our self to IMSession observers, so we catch session events
+    LLIMMgr::getInstance()->addSessionObserver(this);
+
+	mAutoResize = FALSE;
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+}
+
+LLFloaterIMContainer::~LLFloaterIMContainer()
+{
+	mConversationsEventStream.stopListening("ConversationsRefresh");
+
+	gIdleCallbacks.deleteFunction(idle, this);
+
+	mNewMessageConnection.disconnect();
+	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+
+	if (mMicroChangedSignal.connected())
+	{
+		mMicroChangedSignal.disconnect();
+	}
+
+	gSavedPerAccountSettings.setBOOL("ConversationsListPaneCollapsed", mConversationsPane->isCollapsed());
+	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
+
+	if (!LLSingleton<LLIMMgr>::destroyed())
+	{
+		LLIMMgr::getInstance()->removeSessionObserver(this);
+	}
+}
+
+void LLFloaterIMContainer::sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg)
+{
+	addConversationListItem(session_id);
+	LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+	selectConversationPair(session_id, true);
+	collapseMessagesPane(false);
+}
+
+void LLFloaterIMContainer::sessionVoiceOrIMStarted(const LLUUID& session_id)
+{
+	addConversationListItem(session_id);
+	LLFloaterIMSessionTab::addToHost(session_id);
+}
+
+void LLFloaterIMContainer::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
+{
+	// The general strategy when a session id is modified is to delete all related objects and create them anew.
+	
+	// Note however that the LLFloaterIMSession has its session id updated through a call to sessionInitReplyReceived() 
+	// and do not need to be deleted and recreated (trying this creates loads of problems). We do need however to suppress 
+	// its related mSessions record as it's indexed with the wrong id.
+	// Grabbing the updated LLFloaterIMSession and readding it in mSessions will eventually be done by addConversationListItem().
+	mSessions.erase(old_session_id);
+
+	// Delete the model and participants related to the old session
+	bool change_focus = removeConversationListItem(old_session_id);
+
+	// Create a new conversation with the new id
+	addConversationListItem(new_session_id, change_focus);
+	LLFloaterIMSessionTab::addToHost(new_session_id);
+}
+
+void LLFloaterIMContainer::sessionRemoved(const LLUUID& session_id)
+{
+	removeConversationListItem(session_id);
+}
+
+// static
+void LLFloaterIMContainer::onCurrentChannelChanged(const LLUUID& session_id)
+{
+    if (session_id != LLUUID::null)
+    {
+    	LLFloaterIMContainer::getInstance()->showConversation(session_id);
+    }
+}
+
+BOOL LLFloaterIMContainer::postBuild()
+{
+	mOrigMinWidth = getMinWidth();
+	mOrigMinHeight = getMinHeight();
+
+	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLFloaterIMContainer::onNewMessageReceived, this, _1));
+	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
+	// mTabContainer will be initialized in LLMultiFloater::addChild()
+	
+	setTabContainer(getChild<LLTabContainer>("im_box_tab_container"));
+	mStubPanel = getChild<LLPanel>("stub_panel");
+    mStubTextBox = getChild<LLTextBox>("stub_textbox");
+    mStubTextBox->setURLClickedCallback(boost::bind(&LLFloaterIMContainer::returnFloaterToHost, this));
+
+	mConversationsStack = getChild<LLLayoutStack>("conversations_stack");
+	mConversationsPane = getChild<LLLayoutPanel>("conversations_layout_panel");
+	mMessagesPane = getChild<LLLayoutPanel>("messages_layout_panel");
+	
+	mConversationsListPanel = getChild<LLPanel>("conversations_list_panel");
+
+	// Open IM session with selected participant on double click event
+	mConversationsListPanel->setDoubleClickCallback(boost::bind(&LLFloaterIMContainer::doToSelected, this, LLSD("im")));
+
+	// The resize limits for LLFloaterIMContainer should be updated, based on current values of width of conversation and message panels
+	mConversationsPane->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMContainer::assignResizeLimits, this));
+
+	// Create the root model and view for all conversation sessions
+	LLConversationItem* base_item = new LLConversationItem(getRootViewModel());
+
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mConversationsListPanel;
+    p.tool_tip = p.name;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+
+	// Add listener to conversation model events
+	mConversationsEventStream.listen("ConversationsRefresh", boost::bind(&LLFloaterIMContainer::onConversationModelEvent, this, _1));
+
+	// a scroller for folder view
+	LLRect scroller_view_rect = mConversationsListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	scroller_params.rect(scroller_view_rect);
+
+	LLScrollContainer* scroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
+	scroller->setFollowsAll();
+	mConversationsListPanel->addChild(scroller);
+	scroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(scroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
+	addConversationListItem(LLUUID()); // manually add nearby chat
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	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));
+
+	childSetAction("add_btn", boost::bind(&LLFloaterIMContainer::onAddButtonClicked, this));
+
+	collapseMessagesPane(gSavedPerAccountSettings.getBOOL("ConversationsMessagePaneCollapsed"));
+	collapseConversationsPane(gSavedPerAccountSettings.getBOOL("ConversationsListPaneCollapsed"), false);
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
+	mMicroChangedSignal = LLVoiceClient::getInstance()->MicroChangedCallback(boost::bind(&LLFloaterIMContainer::updateSpeakBtnState, this));
+
+	if (! mMessagesPane->isCollapsed() && ! mConversationsPane->isCollapsed())
+	{
+		S32 conversations_panel_width = gSavedPerAccountSettings.getS32("ConversationsListPaneWidth");
+		LLRect conversations_panel_rect = mConversationsPane->getRect();
+		conversations_panel_rect.mRight = conversations_panel_rect.mLeft + conversations_panel_width;
+        mConversationsPane->handleReshape(conversations_panel_rect, TRUE);
+	}
+
+	// Init the sort order now that the root had been created
+	setSortOrder(LLConversationSort(gSavedSettings.getU32("ConversationSortOrder")));
+	
+	// Keep the xml set title around for when we have to overwrite it
+	mGeneralTitle = getTitle();
+	
+	mInitialized = true;
+
+	// Add callbacks:
+	// We'll take care of view updates on idle
+	gIdleCallbacks.addFunction(idle, this);
+	// When display name option change, we need to reload all participant names
+	LLAvatarNameCache::addUseDisplayNamesCallback(boost::bind(&LLFloaterIMContainer::processParticipantsStyleUpdate, this));
+
+	return TRUE;
+}
+
+void LLFloaterIMContainer::onOpen(const LLSD& key)
+{
+	LLMultiFloater::onOpen(key);
+	openNearbyChat();
+	reSelectConversation();
+	assignResizeLimits();
+}
+
+// virtual
+void LLFloaterIMContainer::addFloater(LLFloater* floaterp,
+									  BOOL select_added_floater,
+									  LLTabContainer::eInsertionPoint insertion_point)
+{
+	if(!floaterp) return;
+
+	// already here
+	if (floaterp->getHost() == this)
+	{
+		openFloater(floaterp->getKey());
+		return;
+	}
+
+	LLUUID session_id = floaterp->getKey();
+	
+	// Add the floater
+	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
+
+
+	
+	LLIconCtrl* icon = 0;
+
+	if(gAgent.isInGroup(session_id, TRUE))
+	{
+		LLGroupIconCtrl::Params icon_params;
+		icon_params.group_id = session_id;
+		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
+
+		mSessions[session_id] = floaterp;
+		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+	}
+	else
+	{   LLUUID avatar_id = session_id.notNull()?
+		    LLIMModel::getInstance()->getOtherParticipantID(session_id) : LLUUID();
+
+		LLAvatarIconCtrl::Params icon_params;
+		icon_params.avatar_id = avatar_id;
+		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
+
+		mSessions[session_id] = floaterp;
+		floaterp->mCloseSignal.connect(boost::bind(&LLFloaterIMContainer::onCloseFloater, this, session_id));
+	}
+
+	// forced resize of the floater
+	LLRect wrapper_rect = this->mTabContainer->getLocalRect();
+	floaterp->setRect(wrapper_rect);
+
+	mTabContainer->setTabImage(floaterp, icon);
+}
+
+
+void LLFloaterIMContainer::onCloseFloater(LLUUID& id)
+{
+	mSessions.erase(id);
+	setFocus(TRUE);
+}
+
+void LLFloaterIMContainer::onNewMessageReceived(const LLSD& data)
+{
+	LLUUID session_id = data["session_id"].asUUID();
+	LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
+	LLFloater* current_floater = LLMultiFloater::getActiveFloater();
+
+	if(floaterp && current_floater && floaterp != current_floater)
+	{
+		if(LLMultiFloater::isFloaterFlashing(floaterp))
+			LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
+		LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
+	}
+}
+
+void LLFloaterIMContainer::onStubCollapseButtonClicked()
+{
+	collapseMessagesPane(true);
+}
+
+void LLFloaterIMContainer::onSpeakButtonClicked()
+{
+	LLAgent::toggleMicrophone("speak");
+	updateSpeakBtnState();
+}
+void LLFloaterIMContainer::onExpandCollapseButtonClicked()
+{
+	if (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed()
+			&& gSavedPerAccountSettings.getBOOL("ConversationsExpandMessagePaneFirst"))
+	{
+		// Expand the messages pane from ultra minimized state
+		// if it was collapsed last in order.
+		collapseMessagesPane(false);
+	}
+	else
+	{
+		collapseConversationsPane(!mConversationsPane->isCollapsed());
+	}
+	reSelectConversation();
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::findInstance()
+{
+	return LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+LLFloaterIMContainer* LLFloaterIMContainer::getInstance()
+{
+	return LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+}
+
+// Update all participants in the conversation lists
+void LLFloaterIMContainer::processParticipantsStyleUpdate()
+{
+	// On each session in mConversationsItems
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		// Get the current session descriptors
+		LLConversationItem* session_model = it_session->second;
+		// Iterate through each model participant child
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = session_model->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = session_model->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			// Get the avatar name for this participant id from the cache and update the model
+			participant_model->updateName();
+			// Next participant
+			current_participant_model++;
+		}
+	}
+}
+
+// static
+void LLFloaterIMContainer::idle(void* user_data)
+{
+	LLFloaterIMContainer* self = static_cast<LLFloaterIMContainer*>(user_data);
+	
+	// Update the distance to agent in the nearby chat session if required
+	// Note: it makes no sense of course to update the distance in other session
+	if (self->mConversationViewModel.getSorter().getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE)
+	{
+		self->setNearbyDistances();
+	}
+	self->mConversationsRoot->update();
+}
+
+bool LLFloaterIMContainer::onConversationModelEvent(const LLSD& event)
+{
+	// For debug only
+	//std::ostringstream llsd_value;
+	//llsd_value << LLSDOStreamer<LLSDNotationFormatter>(event) << std::endl;
+	//llinfos << "LLFloaterIMContainer::onConversationModelEvent, event = " << llsd_value.str() << llendl;
+	// end debug
+	
+	// Note: In conversations, the model is not responsible for creating the view, which is a good thing. This means that
+	// the model could change substantially and the view could echo only a portion of this model (though currently the 
+	// conversation view does echo the conversation model 1 to 1).
+	// Consequently, the participant views need to be created either by the session view or by the container panel.
+	// For the moment, we create them here, at the container level, to conform to the pattern implemented in llinventorypanel.cpp 
+	// (see LLInventoryPanel::buildNewViews()).
+
+	std::string type = event.get("type").asString();
+	LLUUID session_id = event.get("session_uuid").asUUID();
+	LLUUID participant_id = event.get("participant_uuid").asUUID();
+
+	LLConversationViewSession* session_view = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,session_id));
+	if (!session_view)
+	{
+		// We skip events that are not associated with a session
+		return false;
+	}
+	LLConversationViewParticipant* participant_view = session_view->findParticipant(participant_id);
+    LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ?
+    		(LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))
+    		: (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+
+	if (type == "remove_participant")
+	{
+		// Remove a participant view from the hierarchical conversation list
+		if (participant_view)
+		{
+			session_view->extractItem(participant_view);
+			delete participant_view;
+			session_view->refresh();
+			mConversationsRoot->arrangeAll();
+		}
+		// Remove a participant view from the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->removeConversationViewParticipant(participant_id);
+		}
+	}
+	else if (type == "add_participant")
+	{
+		LLConversationItemSession* session_model = dynamic_cast<LLConversationItemSession*>(mConversationsItems[session_id]);
+		LLConversationItemParticipant* participant_model = (session_model ? session_model->findParticipant(participant_id) : NULL);
+		if (!participant_view && session_model && participant_model)
+		{
+			LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(session_id);
+			if (session_id.isNull() || (im_sessionp && !im_sessionp->isP2PSessionType()))
+			{
+				participant_view = createConversationViewParticipant(participant_model);
+				participant_view->addToFolder(session_view);
+				participant_view->setVisible(TRUE);
+			}
+		}
+		// Add a participant view to the conversation floater 
+		if (conversation_floater && participant_model)
+		{
+			conversation_floater->addConversationViewParticipant(participant_model);
+		}
+	}
+	else if (type == "update_participant")
+	{
+		// Update the participant view in the hierarchical conversation list
+		if (participant_view)
+		{
+			participant_view->refresh();
+		}
+		// Update the participant view in the conversation floater 
+		if (conversation_floater)
+		{
+			conversation_floater->updateConversationViewParticipant(participant_id);
+		}
+	}
+	else if (type == "update_session")
+	{
+		session_view->refresh();
+	}
+	
+	mConversationViewModel.requestSortAll();
+	mConversationsRoot->arrangeAll();
+	if (conversation_floater)
+	{
+		conversation_floater->refreshConversation();
+	}
+	
+	return false;
+}
+
+void LLFloaterIMContainer::draw()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+	
+	const LLConversationItem *current_session = getCurSelectedViewModelItem();
+	if (current_session)
+	{
+		// Update moderator options visibility
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = current_session->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = current_session->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+			participant_model->setModeratorOptionsVisible(isGroupModerator() && participant_model->getUUID() != gAgentID);
+
+			current_participant_model++;
+		}
+		// Update floater's title as required by the currently selected session or use the default title
+		LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(current_session->getUUID());
+		setTitle(conversation_floaterp && conversation_floaterp->needsTitleOverwrite() ? conversation_floaterp->getTitle() : mGeneralTitle);
+	}
+
+    // "Manually" resize of mConversationsPane: same as temporarity cancellation of the flag "auto_resize=false" for it
+	if (!mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed())
+	{
+		LLRect stack_rect = mConversationsStack->getRect();
+		mConversationsPane->reshape(stack_rect.getWidth(), stack_rect.getHeight(), true);
+	}
+
+	LLFloater::draw();
+}
+
+void LLFloaterIMContainer::tabClose()
+{
+	if (mTabContainer->getTabCount() == 0)
+	{
+		// Do not close the container when every conversation is torn off because the user
+		// still needs the conversation list. Simply collapse the message pane in that case.
+		collapseMessagesPane(true);
+	}
+}
+
+//Shows/hides the stub panel when a conversation floater is torn off
+void LLFloaterIMContainer::showStub(bool stub_is_visible)
+{
+    S32 tabCount = 0;
+    LLPanel * tabPanel = NULL;
+
+    if(stub_is_visible)
+    {
+        tabCount = mTabContainer->getTabCount();
+
+        //Hide all tabs even stub
+        for(S32 i = 0; i < tabCount; ++i)
+        {
+            tabPanel = mTabContainer->getPanelByIndex(i);
+
+            if(tabPanel)
+            {
+                tabPanel->setVisible(false);
+            }
+        }
+
+        //Set the index to the stub panel since we will be showing the stub
+        mTabContainer->setCurrentPanelIndex(0);
+    }
+
+    //Now show/hide the stub
+	mStubPanel->setVisible(stub_is_visible);
+}
+
+// listener for click on mStubTextBox2
+void LLFloaterIMContainer::returnFloaterToHost()
+{
+	LLUUID session_id = this->getSelectedSession();
+	LLFloaterIMSessionTab* floater = LLFloaterIMSessionTab::getConversation(session_id);
+	floater->onTearOffClicked();
+}
+
+void LLFloaterIMContainer::setMinimized(BOOL b)
+{
+	bool was_minimized = isMinimized();
+	LLMultiFloater::setMinimized(b);
+
+	//Switching from minimized to un-minimized
+	if(was_minimized && !b)
+	{
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+
+		if(session_floater && !session_floater->isTornOff())
+		{
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+			}
+		}
+	}
+}
+
+void LLFloaterIMContainer::setVisible(BOOL visible)
+{	LLFloaterIMNearbyChat* nearby_chat;
+	if (visible)
+	{
+		// Make sure we have the Nearby Chat present when showing the conversation container
+		nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+		if (nearby_chat == NULL)
+		{
+			// If not found, force the creation of the nearby chat conversation panel
+			// *TODO: find a way to move this to XML as a default panel or something like that
+			LLSD name("nearby_chat");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
+            selectConversationPair(LLUUID(NULL), false, false);
+		}
+		openNearbyChat();
+		flashConversationItemWidget(mSelectedSession,false);
+
+		LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(mSelectedSession);
+		if(session_floater && !session_floater->isMinimized())
+		{
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && mSelectedSession.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSelectedSession);
+			}
+		}
+	}
+
+	nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		LLFloaterIMSessionTab::addToHost(LLUUID());
+	}
+
+	// We need to show/hide all the associated conversations that have been torn off
+	// (and therefore, are not longer managed by the multifloater),
+	// so that they show/hide with the conversations manager.
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+		    widget->setVisibleIfDetached(visible);
+		}
+	}
+	
+	// Now, do the normal multifloater show/hide
+	LLMultiFloater::setVisible(visible);
+}
+
+void LLFloaterIMContainer::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+	LLMultiFloater::setVisibleAndFrontmost(take_focus, key);
+    selectConversationPair(getSelectedSession(), false, take_focus);
+}
+
+void LLFloaterIMContainer::updateResizeLimits()
+{
+	LLMultiFloater::updateResizeLimits();
+	assignResizeLimits();
+}
+
+void LLFloaterIMContainer::collapseMessagesPane(bool collapse)
+{
+	if (mMessagesPane->isCollapsed() == collapse)
+	{
+		return;
+	}
+
+	// Save current width of panels before collapsing/expanding right pane.
+	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+    S32 msg_pane_width = mMessagesPane->getRect().getWidth();
+
+	if (collapse)
+	{
+		// Save the messages pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsMessagePaneWidth", msg_pane_width);
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", mConversationsPane->isCollapsed());
+	}
+
+	mConversationsPane->setIgnoreReshape(collapse);
+
+	// Show/hide the messages pane.
+	mConversationsStack->collapsePanel(mMessagesPane, collapse);
+
+	// Make sure layout is updated before resizing conversation pane.
+	mConversationsStack->updateLayout();
+
+	reshapeFloaterAndSetResizeLimits(collapse, gSavedPerAccountSettings.getS32("ConversationsMessagePaneWidth"));
+
+	if (!collapse)
+	{
+		// Restore conversation's pane previous width after expanding messages pane.
+		mConversationsPane->setTargetDim(conv_pane_width);
+	}
+}
+
+void LLFloaterIMContainer::collapseConversationsPane(bool collapse, bool save_is_allowed /*=true*/)
+{
+	if (mConversationsPane->isCollapsed() == collapse)
+	{
+		return;
+	}
+
+	LLView* button_panel = getChild<LLView>("conversations_pane_buttons_expanded");
+	button_panel->setVisible(!collapse);
+	mExpandCollapseBtn->setImageOverlay(getString(collapse ? "expand_icon" : "collapse_icon"));
+
+	// Save current width of Conversation panel before collapsing/expanding right pane.
+	S32 conv_pane_width = mConversationsPane->getRect().getWidth();
+
+	if (collapse && save_is_allowed)
+	{
+		// Save the conversations pane width before collapsing it.
+		gSavedPerAccountSettings.setS32("ConversationsListPaneWidth", conv_pane_width);
+
+		// Save the order in which the panels are closed to reverse user's last action.
+		gSavedPerAccountSettings.setBOOL("ConversationsExpandMessagePaneFirst", !mMessagesPane->isCollapsed());
+	}
+
+	mConversationsStack->collapsePanel(mConversationsPane, collapse);
+	if (!collapse)
+	{
+		// Make sure layout is updated before resizing conversation pane.
+		mConversationsStack->updateLayout();
+		// Restore conversation's pane previous width.
+		mConversationsPane->setTargetDim(gSavedPerAccountSettings.getS32("ConversationsListPaneWidth"));
+	}
+
+	S32 delta_width =
+			gSavedPerAccountSettings.getS32("ConversationsListPaneWidth") - mConversationsPane->getMinDim();
+
+	reshapeFloaterAndSetResizeLimits(collapse, delta_width);
+
+	for (conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+			widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+		    widget->toggleCollapsedMode(collapse);
+
+		    // force closing all open conversations when collapsing to minimized state
+		    if (collapse)
+		    {
+		    	widget->setOpen(false);
+		    }
+		    widget->requestArrange();
+        }
+	}
+}
+
+void LLFloaterIMContainer::reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width)
+{
+	LLRect floater_rect = getRect();
+	floater_rect.mRight += ((collapse ? -1 : 1) * delta_width);
+
+	// Set by_user = true so that reshaped rect is saved in user_settings.
+	setShape(floater_rect, true);
+	updateResizeLimits();
+
+	bool at_least_one_panel_is_expanded =
+			! (mConversationsPane->isCollapsed() && mMessagesPane->isCollapsed());
+
+	setCanResize(at_least_one_panel_is_expanded);
+	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()
+{
+	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 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;
+
+	setResizeLimits(new_min_width, getMinHeight());
+
+	mConversationsStack->updateLayout();
+}
+
+void LLFloaterIMContainer::onAddButtonClicked()
+{
+    LLView * button = findChild<LLView>("conversations_pane_buttons_expanded")->findChild<LLButton>("add_btn");
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+    LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMContainer::onAvatarPicked, this, _1), TRUE, TRUE, TRUE, root_floater->getName(), button);
+    
+    if (picker && root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+}
+
+void LLFloaterIMContainer::onAvatarPicked(const uuid_vec_t& ids)
+{
+    if (ids.size() == 1)
+    {
+        LLAvatarActions::startIM(ids.back());
+    }
+    else
+    {
+        LLAvatarActions::startConference(ids);
+    }
+}
+
+void LLFloaterIMContainer::onCustomAction(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+
+	if ("sort_sessions_by_type" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		setSortOrderSessions(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		setSortOrderParticipants(LLConversationFilter::SO_DISTANCE);
+	}
+	if ("chat_preferences" == command)
+	{
+		LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefp)
+		{
+			floater_prefp->selectChatPanel();
+		}
+	}
+	if ("privacy_preferences" == command)
+	{
+		LLFloaterPreference * floater_prefp = LLFloaterReg::showTypedInstance<LLFloaterPreference>("preferences");
+		if (floater_prefp)
+		{
+			floater_prefp->selectPrivacyPanel();
+		}
+	}
+	if ("Translating.Toggle" == command)
+	{
+		gSavedSettings.setBOOL("TranslateChat", !gSavedSettings.getBOOL("TranslateChat"));
+	}
+}
+
+BOOL LLFloaterIMContainer::isActionChecked(const LLSD& userdata)
+{
+	LLConversationSort order = mConversationViewModel.getSorter();
+	std::string command = userdata.asString();
+	if ("sort_sessions_by_type" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_SESSION_TYPE);
+	}
+	if ("sort_sessions_by_name" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_sessions_by_recent" == command)
+	{
+		return (order.getSortOrderSessions() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_name" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_NAME);
+	}
+	if ("sort_participants_by_recent" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DATE);
+	}
+	if ("sort_participants_by_distance" == command)
+	{
+		return (order.getSortOrderParticipants() == LLConversationFilter::SO_DISTANCE);
+	}
+	if ("Translating.Enabled" == command)
+	{
+		return gSavedPerAccountSettings.getBOOL("TranslatingEnabled");
+	}
+	if ("Translating.On" == command)
+	{
+		return gSavedSettings.getBOOL("TranslateChat");
+	}
+	return FALSE;
+}
+
+void LLFloaterIMContainer::setSortOrderSessions(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderSessions())
+	{
+		old_order.setSortOrderSessions(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLFloaterIMContainer::setSortOrderParticipants(const LLConversationFilter::ESortOrderType order)
+{
+	LLConversationSort old_order = mConversationViewModel.getSorter();
+	if (order != old_order.getSortOrderParticipants())
+	{
+		old_order.setSortOrderParticipants(order);
+		setSortOrder(old_order);
+	}
+}
+
+void LLFloaterIMContainer::setSortOrder(const LLConversationSort& order)
+{
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	// try to keep selection onscreen, even if it wasn't to start with
+	mConversationsRoot->scrollToShowSelection();
+	
+	// Notify all conversation (torn off or not) of the change to the sort order
+	// Note: For the moment, the sort order is *unique* across all conversations. That might change in the future.
+	for (conversations_items_map::iterator it_session = mConversationsItems.begin(); it_session != mConversationsItems.end(); it_session++)
+	{
+		LLUUID session_id = it_session->first;
+		LLFloaterIMSessionTab *conversation_floater = (session_id.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(session_id)));
+		if (conversation_floater)
+		{
+			conversation_floater->setSortOrder(order);
+		}
+	}
+	
+	gSavedSettings.setU32("ConversationSortOrder", (U32)order);
+}
+
+void LLFloaterIMContainer::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+    const std::set<LLFolderViewItem*> selectedItems = mConversationsRoot->getSelectionList();
+
+    std::set<LLFolderViewItem*>::const_iterator it = selectedItems.begin();
+    const std::set<LLFolderViewItem*>::const_iterator it_end = selectedItems.end();
+    LLConversationItem * conversationItem;
+
+    for (; it != it_end; ++it)
+    {
+        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)
+		{
+			LLFloaterIMSession * conversation_floaterp = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+			LLUUID participant_id = conversation_floaterp->getOtherParticipantUUID();
+			selected_uuids.push_back(participant_id);
+		}
+		else
+		{
+			selected_uuids.push_back(conversationItem->getUUID());
+		}
+    }
+}
+
+const LLConversationItem * LLFloaterIMContainer::getCurSelectedViewModelItem()
+{
+    LLConversationItem * conversation_item = NULL;
+
+    if(mConversationsRoot && 
+        mConversationsRoot->getCurSelectedItem() && 
+        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+    {
+		LLFloaterIMSessionTab *selected_session_floater = LLFloaterIMSessionTab::getConversation(mSelectedSession);
+		if (selected_session_floater && !selected_session_floater->getHost() && selected_session_floater->getCurSelectedViewModelItem())
+		{
+			conversation_item = selected_session_floater->getCurSelectedViewModelItem();
+		}
+		else
+		{
+			conversation_item = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem());
+		}
+	}
+
+    return conversation_item;
+}
+
+void LLFloaterIMContainer::getParticipantUUIDs(uuid_vec_t& selected_uuids)
+{
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversation_item = getCurSelectedViewModelItem();
+
+	if (NULL == conversation_item)
+	{
+		return;
+	}
+
+	getSelectedUUIDs(selected_uuids);  
+}
+
+void LLFloaterIMContainer::doToParticipants(const std::string& command, uuid_vec_t& selectedIDS)
+{
+	if (selectedIDS.size() == 1)
+	{
+		const LLUUID& userID = selectedIDS.front();
+		if ("view_profile" == command)
+		{
+			LLAvatarActions::showProfile(userID);
+		}
+		else if ("im" == command)
+		{
+			if (gAgent.getID() != userID)
+			{
+				LLAvatarActions::startIM(userID);
+			}
+		}
+		else if ("offer_teleport" == command)
+		{
+			LLAvatarActions::offerTeleport(selectedIDS);
+		}
+		else if ("voice_call" == command)
+		{
+			LLAvatarActions::startCall(userID);
+		}
+		else if ("chat_history" == command)
+		{
+			LLAvatarActions::viewChatHistory(userID);
+		}
+		else if ("add_friend" == command)
+		{
+			LLAvatarActions::requestFriendshipDialog(userID);
+		}
+		else if ("remove_friend" == command)
+		{
+			LLAvatarActions::removeFriendDialog(userID);
+		}
+		else if ("invite_to_group" == command)
+		{
+			LLAvatarActions::inviteToGroup(userID);
+		}
+		else if ("zoom_in" == command)
+		{
+			handle_zoom_to_object(userID);
+		}
+		else if ("map" == command)
+		{
+			LLAvatarActions::showOnMap(userID);
+		}
+		else if ("share" == command)
+		{
+			LLAvatarActions::share(userID);
+		}
+		else if ("pay" == command)
+		{
+			LLAvatarActions::pay(userID);
+		}
+		else if ("block_unblock" == command)
+		{
+			toggleMute(userID, LLMute::flagVoiceChat);
+		}
+		else if ("mute_unmute" == command)
+		{
+			toggleMute(userID, LLMute::flagTextChat);
+		}
+		else if ("selected" == command || "mute_all" == command || "unmute_all" == command)
+		{
+			moderateVoice(command, userID);
+		}
+		else if ("toggle_allow_text_chat" == command)
+		{
+			toggleAllowTextChat(userID);
+		}
+	}
+	else if (selectedIDS.size() > 1)
+	{
+		if ("im" == command)
+		{
+			LLAvatarActions::startConference(selectedIDS);
+		}
+		else if ("offer_teleport" == command)
+		{
+			LLAvatarActions::offerTeleport(selectedIDS);
+		}
+		else if ("voice_call" == command)
+		{
+			LLAvatarActions::startAdhocCall(selectedIDS);
+		}
+		else if ("remove_friend" == command)
+		{
+			LLAvatarActions::removeFriendsDialog(selectedIDS);
+		}
+	}
+}
+
+void LLFloaterIMContainer::doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS)
+{
+    //Find the conversation floater associated with the selected id
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    LLFloaterIMSession *conversationFloater = LLFloaterIMSession::findInstance(conversationItem->getUUID());
+
+    if(conversationFloater)
+    {
+        //Close the selected conversation
+        if("close_conversation" == command)
+        {
+            LLFloater::onClickClose(conversationFloater);
+        }
+        else if("open_voice_conversation" == command)
+        {
+            gIMMgr->startCall(conversationItem->getUUID());
+        }
+        else if("disconnect_from_voice" == command)
+        {
+            gIMMgr->endCall(conversationItem->getUUID());
+        }
+        else if("chat_history" == command)
+        {
+			if (selectedIDS.size() > 0)
+			{
+				LLAvatarActions::viewChatHistory(selectedIDS.front());
+			}
+        }
+        else
+        {
+        	if(conversationItem->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+        	{
+        		doToParticipants(command, selectedIDS);
+        	}
+        }
+    }
+}
+
+void LLFloaterIMContainer::doToSelected(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    const LLConversationItem * conversationItem = getCurSelectedViewModelItem();
+    uuid_vec_t selected_uuids;
+
+    if(conversationItem != NULL)
+    {
+    	getParticipantUUIDs(selected_uuids);
+		
+    	if(conversationItem->getType() == LLConversationItem::CONV_PARTICIPANT)
+    	{
+    		doToParticipants(command, selected_uuids);
+    	}
+    	else
+    	{
+    		doToSelectedConversation(command, selected_uuids);
+    	}
+    }
+}
+
+void LLFloaterIMContainer::doToSelectedGroup(const LLSD& userdata)
+{
+    std::string action = userdata.asString();
+
+    if (action == "group_profile")
+    {
+        LLGroupActions::show(mSelectedSession);
+    }
+    else if (action == "activate_group")
+    {
+        LLGroupActions::activate(mSelectedSession);
+    }
+    else if (action == "leave_group")
+    {
+        LLGroupActions::leave(mSelectedSession);
+    }
+}
+
+bool LLFloaterIMContainer::enableContextMenuItem(const LLSD& userdata)
+{
+    const std::string& item = userdata.asString();
+	uuid_vec_t uuids;
+	getParticipantUUIDs(uuids);
+
+	if ("conversation_log" == item)
+	{
+		return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+	}
+
+	//Enable Chat history item for ad-hoc and group conversations
+	if ("can_chat_history" == item && uuids.size() > 0)
+	{
+		return LLLogChat::isTranscriptExist(uuids.front());
+	}
+
+	// If nothing is selected(and selected item is not group chat), everything needs to be disabled
+	if (uuids.size() <= 0)
+	{
+		if(getCurSelectedViewModelItem())
+		{
+			return getCurSelectedViewModelItem()->getType() == LLConversationItem::CONV_SESSION_GROUP;
+		}
+		return false;
+	}
+
+	if("can_activate_group" == item)
+    {
+    	LLUUID selected_group_id = getCurSelectedViewModelItem()->getUUID();
+    	return gAgent.getGroupID() != selected_group_id;
+    }
+	
+	return enableContextMenuItem(item, uuids);
+}
+
+bool LLFloaterIMContainer::enableContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+	// Extract the single select info
+	bool is_single_select = (uuids.size() == 1);
+	const LLUUID& single_id = uuids.front();
+	
+	// Handle options that are applicable to all including the user agent
+    if ("can_view_profile" == item)
+    {
+		return is_single_select;
+	}
+	
+	// Beyond that point, if only the user agent is selected, everything is disabled
+	if (is_single_select && (single_id == gAgentID))
+	{
+		return false;
+	}
+
+	// If the user agent is selected with others, everything is disabled
+	for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
+	{
+		if (gAgent.getID() == *id)
+		{
+			return false;
+		}
+	}
+
+	// Handle all other options
+	if (("can_invite" == item) || ("can_chat_history" == item) || ("can_share" == item) || ("can_pay" == item))
+	{
+		// Those menu items are enable only if a single avatar is selected
+		return is_single_select;
+	}
+    else if ("can_block" == item)
+    {
+        return (is_single_select ? LLAvatarActions::canBlock(single_id) : false);
+    }
+    else if ("can_add" == item)
+    {
+        // We can add friends if:
+        // - there is only 1 selected avatar (EXT-7389)
+        // - this avatar is not already a friend
+        return (is_single_select ? !LLAvatarActions::isFriend(single_id) : false);
+    }
+    else if ("can_delete" == item)
+    {
+        // We can remove friends if there are only friends among the selection
+        bool result = true;
+        for (uuid_vec_t::const_iterator id = uuids.begin(); id != uuids.end(); ++id)
+        {
+			result &= LLAvatarActions::isFriend(*id);
+        }
+        return result;
+    }
+    else if ("can_call" == item)
+    {
+        return LLAvatarActions::canCall();
+    }
+	else if ("can_zoom_in" == item)
+	{
+		return is_single_select && gObjectList.findObject(single_id);
+	}
+    else if ("can_show_on_map" == item)
+    {
+        return (is_single_select ? (LLAvatarTracker::instance().isBuddyOnline(single_id) && is_agent_mappable(single_id)) || gAgent.isGodlike() : false);
+    }
+    else if ("can_offer_teleport" == item)
+    {
+		return LLAvatarActions::canOfferTeleport(uuids);
+    }
+	else if (("can_moderate_voice" == item) || ("can_allow_text_chat" == item) || ("can_mute" == item) || ("can_unmute" == item))
+	{
+		// *TODO : get that out of here...
+		return enableModerateContextMenuItem(item);
+	}
+
+	// By default, options that not explicitely disabled are enabled
+    return true;
+}
+
+bool LLFloaterIMContainer::checkContextMenuItem(const LLSD& userdata)
+{
+    std::string item = userdata.asString();
+	uuid_vec_t uuids;
+	getParticipantUUIDs(uuids);
+	
+	return checkContextMenuItem(item, uuids);
+}
+
+bool LLFloaterIMContainer::checkContextMenuItem(const std::string& item, uuid_vec_t& uuids)
+{
+    if (uuids.size() == 1)
+    {
+		if ("is_blocked" == item)
+		{
+			return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagVoiceChat);
+		}
+		else if (item == "is_muted")
+		{
+		    return LLMuteList::getInstance()->isMuted(uuids.front(), LLMute::flagTextChat);
+	    }
+		else if ("is_allowed_text_chat" == item)
+		{
+			const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+
+			if (NULL != speakerp)
+			{
+				return !speakerp->mModeratorMutedText;
+			}
+		}
+    }
+
+    return false;
+}
+
+bool LLFloaterIMContainer::visibleContextMenuItem(const LLSD& userdata)
+{
+	const std::string& item = userdata.asString();
+
+	if ("show_mute" == item)
+	{
+		return !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("show_unmute" == item)
+	{
+		return isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+
+	return true;
+}
+
+void LLFloaterIMContainer::showConversation(const LLUUID& session_id)
+{
+    setVisibleAndFrontmost(false);
+    selectConversationPair(session_id, true);
+
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+    if (session_floater)
+    {
+        session_floater->restoreFloater();
+    }
+}
+
+void LLFloaterIMContainer::clearAllFlashStates()
+{
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	for (;widget_it != mConversationsWidgets.end(); ++widget_it)
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(widget_it->second);
+		if (widget)
+		{
+			widget->setFlashState(false);
+		}
+	}
+}
+
+void LLFloaterIMContainer::selectConversation(const LLUUID& session_id)
+{
+    selectConversationPair(session_id, true);
+}
+
+// Select the conversation *after* (or before if none after) the passed uuid conversation
+// Used to change the selection on key hits
+void LLFloaterIMContainer::selectNextConversationByID(const LLUUID& uuid)
+{
+	bool new_selection = false;
+	selectConversation(uuid);
+	new_selection = selectNextorPreviousConversation(true);
+	if (!new_selection)
+	{
+		selectNextorPreviousConversation(false);
+	}
+}
+
+// Synchronous select the conversation item and the conversation floater
+BOOL LLFloaterIMContainer::selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater/*=true*/)
+{
+    BOOL handled = TRUE;
+    LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::findConversation(session_id);
+	
+    /* widget processing */
+    if (select_widget && mConversationsRoot->getSelectedCount() <= 1)
+    {
+		LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,session_id);
+    	if (widget && widget->getParentFolder())
+    	{
+    		widget->getParentFolder()->setSelection(widget, FALSE, FALSE);
+    		mConversationsRoot->scrollToShowSelection();
+    	}
+    }
+
+    /* floater processing */
+
+	if (NULL != session_floater)
+	{
+		if (session_id != getSelectedSession())
+		{
+			// Store the active session
+			setSelectedSession(session_id);
+
+		
+
+			if (session_floater->getHost())
+			{
+				// Always expand the message pane if the panel is hosted by the container
+				collapseMessagesPane(false);
+				// Switch to the conversation floater that is being selected
+				selectFloater(session_floater);
+			}
+			else
+			{
+				showStub(true);
+			}
+
+			//When in DND mode, remove stored IM notifications
+			//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+			if(gAgent.isDoNotDisturb() && session_id.notNull())
+			{
+				LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, session_id);
+			}
+		}
+
+		// Set the focus on the selected floater
+		if (!session_floater->hasFocus() && !session_floater->isMinimized())
+		{
+			session_floater->setFocus(focus_floater);
+		}
+	}
+	flashConversationItemWidget(session_id,false);
+    return handled;
+}
+
+void LLFloaterIMContainer::setTimeNow(const LLUUID& session_id, const LLUUID& participant_id)
+{
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,session_id));
+	if (item)
+	{
+		item->setTimeNow(participant_id);
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
+	}
+}
+
+void LLFloaterIMContainer::setNearbyDistances()
+{
+	// Get the nearby chat session: that's the one with uuid nul
+	LLConversationItemSession* item = dynamic_cast<LLConversationItemSession*>(get_ptr_in_map(mConversationsItems,LLUUID()));
+	if (item)
+	{
+		// Get the positions of the nearby avatars and their ids
+		std::vector<LLVector3d> positions;
+		uuid_vec_t avatar_ids;
+		LLWorld::getInstance()->getAvatars(&avatar_ids, &positions, gAgent.getPositionGlobal(), gSavedSettings.getF32("NearMeRange"));
+		// Get the position of the agent
+		const LLVector3d& me_pos = gAgent.getPositionGlobal();
+		// For each nearby avatar, compute and update the distance
+		int avatar_count = positions.size();
+		for (int i = 0; i < avatar_count; i++)
+		{
+			F64 dist = dist_vec_squared(positions[i], me_pos);
+			item->setDistance(avatar_ids[i],dist);
+		}
+		// Also does it for the agent itself
+		item->setDistance(gAgent.getID(),0.0f);
+		// Request resort
+		mConversationViewModel.requestSortAll();
+		mConversationsRoot->arrangeAll();
+	}
+}
+
+LLConversationItem* LLFloaterIMContainer::addConversationListItem(const LLUUID& uuid, bool isWidgetSelected /*= false*/)
+{
+	bool is_nearby_chat = uuid.isNull();
+
+    // Stores the display name for the conversation line item
+	std::string display_name = is_nearby_chat ? LLTrans::getString("NearbyChatLabel") : LLIMModel::instance().getName(uuid);
+
+	// Check if the item is not already in the list, exit (nothing to do)
+	// Note: this happens often, when reattaching a torn off conversation for instance
+	conversations_items_map::iterator item_it = mConversationsItems.find(uuid);
+	if (item_it != mConversationsItems.end())
+	{
+		return item_it->second;
+	}
+
+	// Create a conversation session model
+	LLConversationItemSession* item = NULL;
+	LLSpeakerMgr* speaker_manager = (is_nearby_chat ? (LLSpeakerMgr*)(LLLocalSpeakerMgr::getInstance()) : LLIMModel::getInstance()->getSpeakerManager(uuid));
+	if (speaker_manager)
+	{
+		item = new LLParticipantList(speaker_manager, getRootViewModel());
+	}
+	if (!item)
+	{
+		llwarns << "Couldn't create conversation session item : " << display_name << llendl;
+		return NULL;
+	}
+	item->renameItem(display_name);
+	item->updateName(NULL);
+	
+	mConversationsItems[uuid] = item;
+
+	// Create a widget from it
+	LLConversationViewSession* widget = createConversationItemWidget(item);
+	mConversationsWidgets[uuid] = widget;
+
+	// Add a new conversation widget to the root folder of the folder view
+	widget->addToFolder(mConversationsRoot);
+	widget->requestArrange();
+
+	LLIMModel::LLIMSession * im_sessionp = LLIMModel::getInstance()->findIMSession(uuid);
+
+	// Create the participants widgets now
+	// Note: usually, we do not get an updated avatar list at that point
+	if (uuid.isNull() || im_sessionp && !im_sessionp->isP2PSessionType())
+	{
+		LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+		LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+		while (current_participant_model != end_participant_model)
+		{
+			LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+			LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+			participant_view->addToFolder(widget);
+			current_participant_model++;
+		}
+	}
+
+	if (uuid.notNull() && im_sessionp->isP2PSessionType())
+	{
+		item->fetchAvatarName(false);
+	}
+
+	// Do that too for the conversation dialog
+    LLFloaterIMSessionTab *conversation_floater = (uuid.isNull() ? (LLFloaterIMSessionTab*)(LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")) : (LLFloaterIMSessionTab*)(LLFloaterIMSession::findInstance(uuid)));
+	if (conversation_floater)
+	{
+		conversation_floater->buildConversationViewParticipant();
+	}
+
+	// set the widget to minimized mode if conversations pane is collapsed
+	widget->toggleCollapsedMode(mConversationsPane->isCollapsed());
+
+	if (isWidgetSelected || 0 == mConversationsRoot->getSelectedCount())
+	{
+		selectConversationPair(uuid, true);
+		widget->requestArrange();
+
+		// scroll to newly added item
+		mConversationsRoot->scrollToShowSelection();
+	}
+
+	return item;
+}
+
+bool LLFloaterIMContainer::removeConversationListItem(const LLUUID& uuid, bool change_focus)
+{
+	// Delete the widget and the associated conversation item
+	// Note : since the mConversationsItems is also the listener to the widget, deleting 
+	// the widget will also delete its listener
+	bool is_widget_selected = false;
+	LLFolderViewItem* new_selection = NULL;
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	if (widget)
+	{
+		is_widget_selected = widget->isSelected();
+		new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+		if (!new_selection)
+		{
+			new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+		}
+		widget->destroyView();
+	}
+	
+	// Suppress the conversation items and widgets from their respective maps
+	mConversationsItems.erase(uuid);
+	mConversationsWidgets.erase(uuid);
+	
+	// Don't let the focus fall IW, select and refocus on the first conversation in the list
+	if (change_focus)
+	{
+		setFocus(TRUE);
+		if (new_selection)
+		{
+			if (mConversationsWidgets.size() == 1)
+			{
+				// If only one widget is left, it has to be the Nearby Chat. Select it directly.
+				selectConversationPair(LLUUID(NULL), true);
+			}
+			else
+			{
+				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+				if (vmi)
+				{
+					selectConversationPair(vmi->getUUID(), true);
+				}
+			}
+		}
+	}
+	return is_widget_selected;
+}
+
+LLConversationViewSession* LLFloaterIMContainer::createConversationItemWidget(LLConversationItem* item)
+{
+	LLConversationViewSession::Params params;
+	
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.tool_tip = params.name;
+	params.container = this;
+	
+    //Indentation for aligning the p2p converstation image with the nearby chat arrow
+    if(item->getType() == LLConversationItem::CONV_SESSION_1_ON_1)
+    {
+        params.folder_indentation = 3;
+    }
+
+	return LLUICtrlFactory::create<LLConversationViewSession>(params);
+}
+
+LLConversationViewParticipant* LLFloaterIMContainer::createConversationViewParticipant(LLConversationItem* item)
+{
+	LLConversationViewParticipant::Params params;
+    LLRect panel_rect = mConversationsListPanel->getRect();
+	
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+
+    //24 is the the current hight of an item (itemHeight) loaded from conversation_view_participant.xml.
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0);
+	params.tool_tip = params.name;
+	params.participant_id = item->getUUID();
+    params.folder_indentation = 27;
+
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+bool LLFloaterIMContainer::enableModerateContextMenuItem(const std::string& userdata)
+{
+	// only group moderators can perform actions related to this "enable callback"
+	if (!isGroupModerator())
+	{
+		return false;
+	}
+
+	LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	if (NULL == speakerp)
+	{
+		return false;
+	}
+
+	bool voice_channel = speakerp->isInVoiceChannel();
+
+	if ("can_moderate_voice" == userdata)
+	{
+		return voice_channel;
+	}
+	else if ("can_mute" == userdata)
+	{
+		return voice_channel && !isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+	else if ("can_unmute" == userdata)
+	{
+		return voice_channel && isMuted(getCurSelectedViewModelItem()->getUUID());
+	}
+
+	// The last invoke is used to check whether the "can_allow_text_chat" will enabled
+	return LLVoiceClient::getInstance()->isParticipantAvatar(getCurSelectedViewModelItem()->getUUID());
+}
+
+bool LLFloaterIMContainer::isGroupModerator()
+{
+	LLSpeakerMgr * speaker_manager = getSpeakerMgrForSelectedParticipant();
+	if (NULL == speaker_manager)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return false;
+	}
+
+	// Is session a group call/chat?
+	if(gAgent.isInGroup(speaker_manager->getSessionID()))
+	{
+		LLSpeaker * speaker = speaker_manager->findSpeaker(gAgentID).get();
+
+		// Is agent a moderator?
+		return speaker && speaker->mIsModerator;
+	}
+
+	return false;
+}
+
+void LLFloaterIMContainer::moderateVoice(const std::string& command, const LLUUID& userID)
+{
+	if (!gAgent.getRegion()) return;
+
+	if (command.compare("selected"))
+	{
+		moderateVoiceAllParticipants(command.compare("mute_all"));
+	}
+	else
+	{
+		moderateVoiceParticipant(userID, isMuted(userID));
+	}
+}
+
+bool LLFloaterIMContainer::isMuted(const LLUUID& avatar_id)
+{
+	const LLSpeaker * speakerp = getSpeakerOfSelectedParticipant(getSpeakerMgrForSelectedParticipant());
+	return NULL == speakerp ? true : speakerp->mStatus == LLSpeaker::STATUS_MUTED;
+}
+
+void LLFloaterIMContainer::moderateVoiceAllParticipants(bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		if (!unmute)
+		{
+			LLSD payload;
+			payload["session_id"] = speaker_managerp->getSessionID();
+			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
+			return;
+		}
+
+		speaker_managerp->moderateVoiceAllParticipants(unmute);
+	}
+}
+
+// static
+void LLFloaterIMContainer::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	// if Cancel pressed
+	if (option == 1)
+	{
+		return;
+	}
+
+	const LLSD& payload = notification["payload"];
+	const LLUUID& session_id = payload["session_id"];
+
+	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
+		LLIMModel::getInstance()->getSpeakerManager(session_id));
+	if (speaker_manager)
+	{
+		speaker_manager->moderateVoiceAllParticipants(false);
+	}
+
+	return;
+}
+
+void LLFloaterIMContainer::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr *>(getSpeakerMgrForSelectedParticipant());
+
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->moderateVoiceParticipant(avatar_id, unmute);
+	}
+}
+
+LLSpeakerMgr * LLFloaterIMContainer::getSpeakerMgrForSelectedParticipant()
+{
+	LLFolderViewItem *selectedItem = mConversationsRoot->getCurSelectedItem();
+	if (NULL == selectedItem)
+	{
+		llwarns << "Current selected item is null" << llendl;
+		return NULL;
+	}
+
+	conversations_widgets_map::const_iterator iter = mConversationsWidgets.begin();
+	conversations_widgets_map::const_iterator end = mConversationsWidgets.end();
+	const LLUUID * conversation_uuidp = NULL;
+	while(iter != end)
+	{
+		if (iter->second == selectedItem || iter->second == selectedItem->getParentFolder())
+		{
+			conversation_uuidp = &iter->first;
+			break;
+		}
+		++iter;
+	}
+	if (NULL == conversation_uuidp)
+	{
+		llwarns << "Cannot find conversation item widget" << llendl;
+		return NULL;
+	}
+
+	return conversation_uuidp->isNull() ? (LLSpeakerMgr *)LLLocalSpeakerMgr::getInstance()
+		: LLIMModel::getInstance()->getSpeakerManager(*conversation_uuidp);
+}
+
+LLSpeaker * LLFloaterIMContainer::getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp)
+{
+	if (NULL == speaker_managerp)
+	{
+		llwarns << "Speaker manager is missing" << llendl;
+		return NULL;
+	}
+
+	const LLConversationItem * participant_itemp = getCurSelectedViewModelItem();
+	if (NULL == participant_itemp)
+	{
+		llwarns << "Cannot evaluate current selected view model item" << llendl;
+		return NULL;
+	}
+
+	return speaker_managerp->findSpeaker(participant_itemp->getUUID());
+}
+
+void LLFloaterIMContainer::toggleAllowTextChat(const LLUUID& participant_uuid)
+{
+	LLIMSpeakerMgr * speaker_managerp = dynamic_cast<LLIMSpeakerMgr*>(getSpeakerMgrForSelectedParticipant());
+	if (NULL != speaker_managerp)
+	{
+		speaker_managerp->toggleAllowTextChat(participant_uuid);
+	}
+}
+
+void LLFloaterIMContainer::toggleMute(const LLUUID& participant_id, U32 flags)
+{
+        BOOL is_muted = LLMuteList::getInstance()->isMuted(participant_id, flags);
+        std::string name;
+        gCacheName->getFullName(participant_id, name);
+        LLMute mute(participant_id, name, LLMute::AGENT);
+
+        if (!is_muted)
+        {
+                LLMuteList::getInstance()->add(mute, flags);
+        }
+        else
+        {
+                LLMuteList::getInstance()->remove(mute, flags);
+        }
+}
+
+void LLFloaterIMContainer::openNearbyChat()
+{
+	// If there's only one conversation in the container and that conversation is the nearby chat
+	//(which it should be...), open it so to make the list of participants visible. This happens to be the most common case when opening the Chat floater.
+	if((mConversationsItems.size() == 1)&&(!mConversationsPane->isCollapsed()))
+	{
+		LLConversationViewSession* nearby_chat = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,LLUUID()));
+		if (nearby_chat)
+		{
+			reSelectConversation();
+			nearby_chat->setOpen(TRUE);
+		}
+	}
+}
+
+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);
+	if (session_floater->getHost())
+	{
+		selectFloater(session_floater);
+	}
+}
+
+void LLFloaterIMContainer::updateSpeakBtnState()
+{
+	LLButton* mSpeakBtn = getChild<LLButton>("speak_btn");
+	mSpeakBtn->setToggleState(LLVoiceClient::getInstance()->getUserPTTState());
+	mSpeakBtn->setEnabled(LLAgent::isActionAllowed("speak"));
+}
+
+bool LLFloaterIMContainer::isConversationLoggingAllowed()
+{
+	return gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 0;
+}
+
+void LLFloaterIMContainer::flashConversationItemWidget(const LLUUID& session_id, bool is_flashes)
+{
+    //Finds the conversation line item to flash using the session_id
+	LLConversationViewSession * widget = dynamic_cast<LLConversationViewSession *>(get_ptr_in_map(mConversationsWidgets,session_id));
+
+	if (widget)
+	{
+		widget->setFlashState(is_flashes);
+	}
+}
+
+bool LLFloaterIMContainer::isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget)
+{
+	llassert(conversation_item_widget != NULL);
+
+	// make sure the widget is actually in the right spot first
+	mConversationsRoot->arrange(NULL, NULL);
+
+	// check whether the widget is in the visible portion of the scroll container
+	LLRect widget_rect;
+	conversation_item_widget->localRectToOtherView(conversation_item_widget->getLocalRect(), &widget_rect, mConversationsRoot);
+	return !mConversationsRoot->getVisibleRect().overlaps(widget_rect);
+}
+
+BOOL LLFloaterIMContainer::handleKeyHere(KEY key, MASK mask )
+{
+	if(mask == MASK_ALT)
+	{
+		if (KEY_RETURN == key )
+		{
+			expandConversation();
+		}
+
+		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+		{
+			selectNextorPreviousConversation(true);
+		}
+		if ((KEY_UP == key) || (KEY_LEFT == key))
+		{
+			selectNextorPreviousConversation(false);
+		}
+	}
+	return TRUE;
+}
+
+bool LLFloaterIMContainer::selectAdjacentConversation(bool focus_selected)
+{
+	bool selectedAdjacentConversation = selectNextorPreviousConversation(true, focus_selected);
+
+	if(!selectedAdjacentConversation)
+	{
+		selectedAdjacentConversation = selectNextorPreviousConversation(false, focus_selected);
+	}
+
+	return selectedAdjacentConversation;
+}
+
+bool LLFloaterIMContainer::selectNextorPreviousConversation(bool select_next, bool focus_selected)
+{
+	if (mConversationsWidgets.size() > 1)
+	{
+		LLFolderViewItem* new_selection = NULL;
+		LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,getSelectedSession());
+		if (widget)
+		{
+			if(select_next)
+			{
+				new_selection = mConversationsRoot->getNextFromChild(widget, FALSE);
+			}
+			else
+			{
+				new_selection = mConversationsRoot->getPreviousFromChild(widget, FALSE);
+			}
+			if (new_selection)
+			{
+				LLConversationItem* vmi = dynamic_cast<LLConversationItem*>(new_selection->getViewModelItem());
+				if (vmi)
+				{
+					selectConversationPair(vmi->getUUID(), true, focus_selected);
+					return true;
+				}
+			}
+		}
+	}
+	return false;
+}
+
+void LLFloaterIMContainer::expandConversation()
+{
+	if(!mConversationsPane->isCollapsed())
+	{
+		LLConversationViewSession* widget = dynamic_cast<LLConversationViewSession*>(get_ptr_in_map(mConversationsWidgets,getSelectedSession()));
+		if (widget)
+		{
+			widget->setOpen(!widget->isOpen());
+		}
+	}
+}
+
+void LLFloaterIMContainer::closeFloater(bool app_quitting/* = false*/)
+{
+	// Always unminimize before trying to close.
+	// Most of the time the user will never see this state.
+	if(isMinimized())
+	{
+		LLMultiFloater::setMinimized(FALSE);
+	}
+	
+	LLFloater::closeFloater(app_quitting);
+}
+
+// EOF
diff --git a/indra/newview/llfloaterimcontainer.h b/indra/newview/llfloaterimcontainer.h
new file mode 100644
index 0000000000000000000000000000000000000000..e39d20ec35880415da2e381efc7fb9a071f452d2
--- /dev/null
+++ b/indra/newview/llfloaterimcontainer.h
@@ -0,0 +1,211 @@
+/** 
+ * @file llfloaterimcontainer.h
+ * @brief Multifloater containing active IM sessions in separate tab container tabs
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERIMCONTAINER_H
+#define LL_LLFLOATERIMCONTAINER_H
+
+#include <map>
+#include <vector>
+
+#include "llimview.h"
+#include "llevents.h"
+#include "../llui/llfloater.h"
+#include "../llui/llmultifloater.h"
+#include "llavatarpropertiesprocessor.h"
+#include "llgroupmgr.h"
+#include "../llui/lltrans.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+
+class LLButton;
+class LLLayoutPanel;
+class LLLayoutStack;
+class LLTabContainer;
+class LLFloaterIMContainer;
+class LLSpeaker;
+class LLSpeakerMgr;
+
+class LLFloaterIMContainer
+	: public LLMultiFloater
+	, public LLIMSessionObserver
+{
+public:
+	LLFloaterIMContainer(const LLSD& seed, const Params& params = getDefaultParams());
+	virtual ~LLFloaterIMContainer();
+	
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void draw();
+	/*virtual*/ void setMinimized(BOOL b);
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
+	/*virtual*/ void updateResizeLimits();
+	void onCloseFloater(LLUUID& id);
+
+	/*virtual*/ void addFloater(LLFloater* floaterp, 
+								BOOL select_added_floater, 
+								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
+	void returnFloaterToHost();
+    void showConversation(const LLUUID& session_id);
+    void selectConversation(const LLUUID& session_id);
+	void selectNextConversationByID(const LLUUID& session_id);
+    BOOL selectConversationPair(const LLUUID& session_id, bool select_widget, bool focus_floater = true);
+    void clearAllFlashStates();
+	bool selectAdjacentConversation(bool focus_selected);
+    bool selectNextorPreviousConversation(bool select_next, bool focus_selected = true);
+    void expandConversation();
+
+	/*virtual*/ void tabClose();
+	void showStub(bool visible);
+
+	static LLFloater* getCurrentVoiceFloater();
+	static LLFloaterIMContainer* findInstance();
+	static LLFloaterIMContainer* getInstance();
+
+	static void onCurrentChannelChanged(const LLUUID& session_id);
+
+	void collapseMessagesPane(bool collapse);
+	
+	// Callbacks
+	static void idle(void* user_data);
+
+	// LLIMSessionObserver observe triggers
+	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg);
+    /*virtual*/ void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	/*virtual*/ void sessionVoiceOrIMStarted(const LLUUID& session_id);
+	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
+	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
+
+	LLConversationViewModel& getRootViewModel() { return mConversationViewModel; }
+    LLUUID getSelectedSession() { return mSelectedSession; }
+    void setSelectedSession(LLUUID sessionID) { mSelectedSession = sessionID; }
+	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);
+    bool enableContextMenuItem(const std::string& item, uuid_vec_t& selectedIDS);
+    void doToParticipants(const std::string& item, uuid_vec_t& selectedIDS);
+
+	void assignResizeLimits();
+	virtual BOOL handleKeyHere(KEY key, MASK mask );
+	/*virtual*/ void closeFloater(bool app_quitting = false);
+
+private:
+	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
+	avatarID_panel_map_t mSessions;
+	boost::signals2::connection mNewMessageConnection;
+
+	/*virtual*/ void computeResizeLimits(S32& new_min_width, S32& new_min_height) {}
+
+	void onNewMessageReceived(const LLSD& data);
+
+	void onExpandCollapseButtonClicked();
+	void onStubCollapseButtonClicked();
+	void processParticipantsStyleUpdate();
+	void onSpeakButtonClicked();
+
+	void collapseConversationsPane(bool collapse, bool save_is_allowed=true);
+
+	void reshapeFloaterAndSetResizeLimits(bool collapse, S32 delta_width);
+
+	void onAddButtonClicked();
+	void onAvatarPicked(const uuid_vec_t& ids);
+
+	BOOL isActionChecked(const LLSD& userdata);
+	void onCustomAction (const LLSD& userdata);
+	void setSortOrderSessions(const LLConversationFilter::ESortOrderType order);
+	void setSortOrderParticipants(const LLConversationFilter::ESortOrderType order);
+	void setSortOrder(const LLConversationSort& order);
+
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+    const LLConversationItem * getCurSelectedViewModelItem();
+    void getParticipantUUIDs(uuid_vec_t& selected_uuids);
+    void doToSelected(const LLSD& userdata);
+	bool checkContextMenuItem(const LLSD& userdata);
+	bool enableContextMenuItem(const LLSD& userdata);
+	bool visibleContextMenuItem(const LLSD& userdata);
+    void doToSelectedConversation(const std::string& command, uuid_vec_t& selectedIDS);
+    void doToSelectedGroup(const LLSD& userdata);
+
+	static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
+	bool enableModerateContextMenuItem(const std::string& userdata);
+	LLSpeaker * getSpeakerOfSelectedParticipant(LLSpeakerMgr * speaker_managerp);
+	LLSpeakerMgr * getSpeakerMgrForSelectedParticipant();
+	bool isGroupModerator();
+	bool isMuted(const LLUUID& avatar_id);
+	void moderateVoice(const std::string& command, const LLUUID& userID);
+	void moderateVoiceAllParticipants(bool unmute);
+	void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
+	void toggleAllowTextChat(const LLUUID& participant_uuid);
+	void toggleMute(const LLUUID& participant_id, U32 flags);
+	void openNearbyChat();
+
+	LLButton* mExpandCollapseBtn;
+	LLButton* mStubCollapseBtn;
+	LLPanel* mStubPanel;
+	LLTextBox* mStubTextBox;
+	LLLayoutPanel* mMessagesPane;
+	LLLayoutPanel* mConversationsPane;
+	LLLayoutStack* mConversationsStack;
+	
+	bool mInitialized;
+
+	LLUUID mSelectedSession;
+	std::string mGeneralTitle;
+
+	// Conversation list implementation
+public:
+	bool removeConversationListItem(const LLUUID& uuid, bool change_focus = true);
+	LLConversationItem* addConversationListItem(const LLUUID& uuid, bool isWidgetSelected = false);
+	void setTimeNow(const LLUUID& session_id, const LLUUID& participant_id);
+	void setNearbyDistances();
+	void reSelectConversation();
+	void updateSpeakBtnState();
+	static bool isConversationLoggingAllowed();
+	void flashConversationItemWidget(const LLUUID& session_id, bool is_flashes);
+	bool isScrolledOutOfSight(LLConversationViewSession* conversation_item_widget);
+	boost::signals2::connection mMicroChangedSignal;
+	S32 getConversationListItemSize() { return mConversationsWidgets.size(); }
+
+private:
+	LLConversationViewSession* createConversationItemWidget(LLConversationItem* item);
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	bool onConversationModelEvent(const LLSD& event);
+
+	// Conversation list data
+	LLPanel* mConversationsListPanel;	// This is the main widget we add conversation widget to
+	conversations_items_map mConversationsItems;
+	conversations_widgets_map mConversationsWidgets;
+	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
+	LLEventStream mConversationsEventStream; 
+};
+
+#endif // LL_LLFLOATERIMCONTAINER_H
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..49f36a2f321b1b1152a4f4eddf680fb4fff8d84a
--- /dev/null
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -0,0 +1,885 @@
+/** 
+ * @file LLFloaterIMNearbyChat.cpp
+ * @brief LLFloaterIMNearbyChat class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "message.h"
+
+#include "lliconctrl.h"
+#include "llappviewer.h"
+#include "llchatentry.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+#include "llfloaterimcontainer.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llfocusmgr.h"
+#include "lllogchat.h"
+#include "llresizebar.h"
+#include "llresizehandle.h"
+#include "lldraghandle.h"
+#include "llmenugl.h"
+#include "llviewermenu.h" // for gMenuHolder
+#include "llfloaterimnearbychathandler.h"
+#include "llchannelmanager.h"
+#include "llchathistory.h"
+#include "llstylemap.h"
+#include "llavatarnamecache.h"
+#include "llfloaterreg.h"
+#include "lltrans.h"
+
+#include "llfirstuse.h"
+#include "llfloaterimnearbychat.h"
+#include "llagent.h" // gAgent
+#include "llgesturemgr.h"
+#include "llmultigesture.h"
+#include "llkeyboard.h"
+#include "llanimationstates.h"
+#include "llviewerstats.h"
+#include "llcommandhandler.h"
+#include "llviewercontrol.h"
+#include "llnavigationbar.h"
+#include "llwindow.h"
+#include "llviewerwindow.h"
+#include "llrootview.h"
+#include "llviewerchat.h"
+#include "lltranslate.h"
+#include "llautoreplace.h"
+
+S32 LLFloaterIMNearbyChat::sLastSpecialChatChannel = 0;
+
+const S32 EXPANDED_HEIGHT = 266;
+const S32 COLLAPSED_HEIGHT = 60;
+const S32 EXPANDED_MIN_HEIGHT = 150;
+
+// legacy callback glue
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
+
+struct LLChatTypeTrigger {
+	std::string name;
+	EChatType type;
+};
+
+static LLChatTypeTrigger sChatTypeTriggers[] = {
+	{ "/whisper"	, CHAT_TYPE_WHISPER},
+	{ "/shout"	, CHAT_TYPE_SHOUT}
+};
+
+
+LLFloaterIMNearbyChat::LLFloaterIMNearbyChat(const LLSD& llsd)
+:	LLFloaterIMSessionTab(llsd),
+	//mOutputMonitor(NULL),
+	mSpeakerMgr(NULL),
+	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
+{
+    mIsP2PChat = false;
+	mIsNearbyChat = true;
+	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
+	mSessionID = LLUUID();
+}
+
+//static
+LLFloaterIMNearbyChat* LLFloaterIMNearbyChat::buildFloater(const LLSD& key)
+{
+    LLFloaterReg::getInstance("im_container");
+    return new LLFloaterIMNearbyChat(key);
+}
+
+//virtual
+BOOL LLFloaterIMNearbyChat::postBuild()
+{
+    setIsSingleInstance(TRUE);
+    BOOL result = LLFloaterIMSessionTab::postBuild();
+
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
+	mInputEditor->setCommitCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxCommit, this));
+	mInputEditor->setKeystrokeCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxKeystroke, this));
+	mInputEditor->setFocusLostCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusLost, this));
+	mInputEditor->setFocusReceivedCallback(boost::bind(&LLFloaterIMNearbyChat::onChatBoxFocusReceived, this));
+	mInputEditor->setLabel(LLTrans::getString("NearbyChatTitle"));
+
+	// Title must be defined BEFORE call to addConversationListItem() because
+	// it is used to show the item's name in the conversations list
+	setTitle(LLTrans::getString("NearbyChatTitle"));
+
+	// obsolete, but may be needed for backward compatibility?
+	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
+
+	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
+	{
+		loadHistory();
+	}
+
+	return result;
+}
+
+// virtual
+void LLFloaterIMNearbyChat::closeHostedFloater()
+{
+	// Should check how many conversations are ongoing. Close all if 1 only (the Nearby Chat), select next one otherwise
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	if (floater_container->getConversationListItemSize() == 1)
+	{
+		floater_container->closeFloater();
+	}
+	else
+	{
+		if (!getHost())
+		{
+			setVisible(FALSE);
+		}
+		floater_container->selectNextConversationByID(LLUUID());
+	}
+}
+
+// virtual
+void LLFloaterIMNearbyChat::refresh()
+{
+	displaySpeakingIndicator();
+	updateCallBtnState(LLVoiceClient::getInstance()->getUserPTTState());
+
+	// *HACK: Update transparency type depending on whether our children have focus.
+	// This is needed because this floater is chrome and thus cannot accept focus, so
+	// the transparency type setting code from LLFloater::setFocus() isn't reached.
+	if (getTransparencyType() != TT_DEFAULT)
+	{
+		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
+	}
+}
+
+void LLFloaterIMNearbyChat::reloadMessages(bool clean_messages/* = false*/)
+{
+	if (clean_messages)
+	{
+		mMessageArchive.clear();
+		loadHistory();
+	}
+
+	mChatHistory->clear();
+
+	LLSD do_not_log;
+	do_not_log["do_not_log"] = true;
+	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
+	{
+		// Update the messages without re-writing them to a log file.
+		addMessage(*it,false, do_not_log);
+	}
+}
+
+void LLFloaterIMNearbyChat::loadHistory()
+{
+	LLSD do_not_log;
+	do_not_log["do_not_log"] = true;
+
+	std::list<LLSD> history;
+	LLLogChat::loadChatHistory("chat", history);
+
+	std::list<LLSD>::const_iterator it = history.begin();
+	while (it != history.end())
+	{
+		const LLSD& msg = *it;
+
+		std::string from = msg[LL_IM_FROM];
+		LLUUID from_id;
+		if (msg[LL_IM_FROM_ID].isDefined())
+		{
+			from_id = msg[LL_IM_FROM_ID].asUUID();
+		}
+		else
+ 		{
+			std::string legacy_name = gCacheName->buildLegacyName(from);
+ 			gCacheName->getUUID(legacy_name, from_id);
+ 		}
+
+		LLChat chat;
+		chat.mFromName = from;
+		chat.mFromID = from_id;
+		chat.mText = msg[LL_IM_TEXT].asString();
+		chat.mTimeStr = msg[LL_IM_TIME].asString();
+		chat.mChatStyle = CHAT_STYLE_HISTORY;
+
+		chat.mSourceType = CHAT_SOURCE_AGENT;
+		if (from_id.isNull() && SYSTEM_FROM == from)
+		{
+			chat.mSourceType = CHAT_SOURCE_SYSTEM;
+
+		}
+		else if (from_id.isNull())
+		{
+			chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
+		}
+
+		addMessage(chat, true, do_not_log);
+
+		it++;
+	}
+}
+
+void LLFloaterIMNearbyChat::removeScreenChat()
+{
+	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
+	if(chat_channel)
+	{
+		chat_channel->removeToastsFromChannel();
+	}
+}
+
+
+void LLFloaterIMNearbyChat::setVisible(BOOL visible)
+{
+	LLFloaterIMSessionTab::setVisible(visible);
+
+	if(visible)
+	{
+		removeScreenChat();
+	}
+}
+
+
+void LLFloaterIMNearbyChat::setVisibleAndFrontmost(BOOL take_focus, const LLSD& key)
+{
+	LLFloaterIMSessionTab::setVisibleAndFrontmost(take_focus, key);
+
+	if(!isTornOff() && matchesKey(key))
+	{
+		LLFloaterIMContainer::getInstance()->selectConversationPair(mSessionID, true, take_focus);
+	}
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onTearOffClicked()
+{
+	LLFloaterIMSessionTab::onTearOffClicked();
+
+	// see CHUI-170: Save torn-off state of the nearby chat between sessions
+	BOOL in_the_multifloater = (BOOL)getHost();
+	gSavedPerAccountSettings.setBOOL("NearbyChatIsNotTornOff", in_the_multifloater);
+}
+
+
+// virtual
+void LLFloaterIMNearbyChat::onOpen(const LLSD& key)
+{
+	LLFloaterIMSessionTab::onOpen(key);
+	if(!isMessagePaneExpanded())
+	{
+		restoreFloater();
+		onCollapseToLine(this);
+	}
+	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClose(bool app_quitting)
+{
+	// Override LLFloaterIMSessionTab::onClose() so that Nearby Chat is not removed from the conversation floater
+	LLFloaterIMSessionTab::restoreFloater();
+	onClickCloseBtn();
+}
+
+// virtual
+void LLFloaterIMNearbyChat::onClickCloseBtn()
+{
+	if (!isTornOff())
+	{
+		return;
+	}
+	LLFloaterIMSessionTab::onTearOffClicked();
+	
+	LLFloaterIMContainer *im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->onNearbyChatClosed();
+	}
+}
+
+void LLFloaterIMNearbyChat::onChatFontChange(LLFontGL* fontp)
+{
+	// Update things with the new font whohoo
+	if (mInputEditor)
+	{
+		mInputEditor->setFont(fontp);
+	}
+}
+
+
+void LLFloaterIMNearbyChat::show()
+{
+		openFloater(getKey());
+}
+
+bool LLFloaterIMNearbyChat::isChatVisible() const
+{
+	bool isVisible = false;
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::getInstance();
+	// Is the IM floater container ever null?
+	llassert(im_box != NULL);
+	if (im_box != NULL)
+	{
+		isVisible =
+				isChatMultiTab() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff")?
+						im_box->getVisible() && !im_box->isMinimized() :
+						getVisible() && !isMinimized();
+	}
+
+	return isVisible;
+}
+
+void LLFloaterIMNearbyChat::showHistory()
+{
+	openFloater();
+	if(!isMessagePaneExpanded())
+	{
+		restoreFloater();
+		setFocus(true);
+	}
+	setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
+}
+
+std::string LLFloaterIMNearbyChat::getCurrentChat()
+{
+	return mInputEditor ? mInputEditor->getText() : LLStringUtil::null;
+}
+
+// virtual
+BOOL LLFloaterIMNearbyChat::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+
+	if( KEY_RETURN == key && mask == MASK_CONTROL)
+	{
+		// shout
+		sendChat(CHAT_TYPE_SHOUT);
+		handled = TRUE;
+	}
+	else if (KEY_RETURN == key && mask == MASK_SHIFT)
+	{
+		// whisper
+		sendChat(CHAT_TYPE_WHISPER);
+		handled = TRUE;
+	}
+
+
+	if((mask == MASK_ALT) && isTornOff())
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+		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 handled;
+}
+
+BOOL LLFloaterIMNearbyChat::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
+{
+	U32 in_len = in_str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	bool string_was_found = false;
+
+	for (S32 n = 0; n < cnt && !string_was_found; n++)
+	{
+		if (in_len <= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger_trunc = sChatTypeTriggers[n].name;
+			LLStringUtil::truncate(trigger_trunc, in_len);
+
+			if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
+			{
+				*out_str = sChatTypeTriggers[n].name;
+				string_was_found = true;
+			}
+		}
+	}
+
+	return string_was_found;
+}
+
+void LLFloaterIMNearbyChat::onChatBoxKeystroke()
+{
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->flashConversationItemWidget(mSessionID,false);
+	}
+
+	LLFirstUse::otherAvatarChatFirst(false);
+
+	LLWString raw_text = mInputEditor->getWText();
+
+	// Can't trim the end, because that will cause autocompletion
+	// to eat trailing spaces that might be part of a gesture.
+	LLWStringUtil::trimHead(raw_text);
+
+	S32 length = raw_text.length();
+
+	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
+	{
+		gAgent.startTyping();
+	}
+	else
+	{
+		gAgent.stopTyping();
+	}
+
+	/* Doesn't work -- can't tell the difference between a backspace
+	   that killed the selection vs. backspace at the end of line.
+	if (length > 1 
+		&& text[0] == '/'
+		&& key == KEY_BACKSPACE)
+	{
+		// the selection will already be deleted, but we need to trim
+		// off the character before
+		std::string new_text = raw_text.substr(0, length-1);
+		mInputEditor->setText( new_text );
+		mInputEditor->setCursorToEnd();
+		length = length - 1;
+	}
+	*/
+
+	KEY key = gKeyboard->currentKey();
+
+	// Ignore "special" keys, like backspace, arrows, etc.
+	if (length > 1 
+		&& raw_text[0] == '/'
+		&& key < KEY_SPECIAL)
+	{
+		// we're starting a gesture, attempt to autocomplete
+
+		std::string utf8_trigger = wstring_to_utf8str(raw_text);
+		std::string utf8_out_str(utf8_trigger);
+
+		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			if (!rest_of_match.empty())
+			{
+				mInputEditor->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
+
+				// Select to end of line, starting from the character
+				// after the last one the user typed.
+				mInputEditor->selectNext(rest_of_match, false);
+			}
+		}
+		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
+		{
+			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
+			mInputEditor->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
+			mInputEditor->endOfDoc();
+		}
+
+		//llinfos << "GESTUREDEBUG " << trigger 
+		//	<< " len " << length
+		//	<< " outlen " << out_str.getLength()
+		//	<< llendl;
+	}
+}
+
+// static
+void LLFloaterIMNearbyChat::onChatBoxFocusLost()
+{
+	// stop typing animation
+	gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::onChatBoxFocusReceived()
+{
+	mInputEditor->setEnabled(!gDisconnected);
+}
+
+EChatType LLFloaterIMNearbyChat::processChatTypeTriggers(EChatType type, std::string &str)
+{
+	U32 length = str.length();
+	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
+	
+	for (S32 n = 0; n < cnt; n++)
+	{
+		if (length >= sChatTypeTriggers[n].name.length())
+		{
+			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
+
+			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
+			{
+				U32 trigger_length = sChatTypeTriggers[n].name.length();
+
+				// It's to remove space after trigger name
+				if (length > trigger_length && str[trigger_length] == ' ')
+					trigger_length++;
+
+				str = str.substr(trigger_length, length);
+
+				if (CHAT_TYPE_NORMAL == type)
+					return sChatTypeTriggers[n].type;
+				else
+					break;
+			}
+		}
+	}
+
+	return type;
+}
+
+void LLFloaterIMNearbyChat::sendChat( EChatType type )
+{
+	if (mInputEditor)
+	{
+		LLWString text = mInputEditor->getWText();
+		LLWStringUtil::trim(text);
+		LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+		if (!text.empty())
+		{
+			// Check if this is destined for another channel
+			S32 channel = 0;
+			stripChannelNumber(text, &channel);
+			
+			std::string utf8text = wstring_to_utf8str(text);
+			// Try to trigger a gesture, if not chat to a script.
+			std::string utf8_revised_text;
+			if (0 == channel)
+			{
+				// discard returned "found" boolean
+				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
+			}
+			else
+			{
+				utf8_revised_text = utf8text;
+			}
+
+			utf8_revised_text = utf8str_trim(utf8_revised_text);
+
+			type = processChatTypeTriggers(type, utf8_revised_text);
+
+			if (!utf8_revised_text.empty())
+			{
+				// Chat with animation
+				sendChatFromViewer(utf8_revised_text, type, TRUE);
+			}
+		}
+
+		mInputEditor->setText(LLStringExplicit(""));
+	}
+
+	gAgent.stopTyping();
+
+	// If the user wants to stop chatting on hitting return, lose focus
+	// and go out of chat mode.
+	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
+	{
+		stopChat();
+	}
+}
+
+void LLFloaterIMNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
+{
+	appendMessage(chat, args);
+
+	if(archive)
+	{
+		mMessageArchive.push_back(chat);
+		if(mMessageArchive.size() > 200)
+		{
+			mMessageArchive.erase(mMessageArchive.begin());
+		}
+	}
+
+	// logging
+	if (!args["do_not_log"].asBoolean() && gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
+	{
+		std::string from_name = chat.mFromName;
+
+		if (chat.mSourceType == CHAT_SOURCE_AGENT)
+		{
+			// if the chat is coming from an agent, log the complete name
+			LLAvatarName av_name;
+			LLAvatarNameCache::get(chat.mFromID, &av_name);
+
+			if (!av_name.isDisplayNameDefault())
+			{
+				from_name = av_name.getCompleteName();
+			}
+		}
+
+		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
+	}
+}
+
+
+void LLFloaterIMNearbyChat::onChatBoxCommit()
+{
+	if (mInputEditor->getText().length() > 0)
+	{
+		sendChat(CHAT_TYPE_NORMAL);
+	}
+
+	gAgent.stopTyping();
+}
+
+void LLFloaterIMNearbyChat::displaySpeakingIndicator()
+{
+	LLSpeakerMgr::speaker_list_t speaker_list;
+	LLUUID id;
+
+	id.setNull();
+	mSpeakerMgr->update(FALSE);
+	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
+
+	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
+	{
+		LLPointer<LLSpeaker> s = *i;
+		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
+		{
+			id = s->mID;
+			break;
+		}
+	}
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
+{
+	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
+}
+
+void LLFloaterIMNearbyChat::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
+{
+	// Look for "/20 foo" channel chats.
+	S32 channel = 0;
+	LLWString out_text = stripChannelNumber(wtext, &channel);
+	std::string utf8_out_text = wstring_to_utf8str(out_text);
+	std::string utf8_text = wstring_to_utf8str(wtext);
+
+	utf8_text = utf8str_trim(utf8_text);
+	if (!utf8_text.empty())
+	{
+		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
+	}
+
+	// Don't animate for chats people can't hear (chat to scripts)
+	if (animate && (channel == 0))
+	{
+		if (type == CHAT_TYPE_WHISPER)
+		{
+			lldebugs << "You whisper " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_NORMAL)
+		{
+			lldebugs << "You say " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
+		}
+		else if (type == CHAT_TYPE_SHOUT)
+		{
+			lldebugs << "You shout " << utf8_text << llendl;
+			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
+		}
+		else
+		{
+			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
+			return;
+		}
+	}
+	else
+	{
+		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
+		{
+			lldebugs << "Channel chat: " << utf8_text << llendl;
+		}
+	}
+
+	send_chat_from_viewer(utf8_out_text, type, channel);
+}
+
+// static 
+bool LLFloaterIMNearbyChat::isWordsName(const std::string& name)
+{
+	// checking to see if it's display name plus username in parentheses
+	S32 open_paren = name.find(" (", 0);
+	S32 close_paren = name.find(')', 0);
+
+	if (open_paren != std::string::npos &&
+		close_paren == name.length()-1)
+	{
+		return true;
+	}
+	else
+	{
+		//checking for a single space
+		S32 pos = name.find(' ', 0);
+		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
+	}
+}
+
+// static 
+void LLFloaterIMNearbyChat::startChat(const char* line)
+{
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		if(!nearby_chat->isTornOff())
+		{
+			LLFloaterIMContainer::getInstance()->selectConversation(LLUUID(NULL));
+		}
+		if(nearby_chat->isMinimized())
+		{
+			nearby_chat->setMinimized(false);
+		}
+		nearby_chat->show();
+		nearby_chat->setFocus(TRUE);
+
+		if (line)
+		{
+			std::string line_string(line);
+			nearby_chat->mInputEditor->setText(line_string);
+		}
+
+		nearby_chat->mInputEditor->endOfDoc();
+	}
+}
+
+// Exit "chat mode" and do the appropriate focus changes
+// static
+void LLFloaterIMNearbyChat::stopChat()
+{
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+		nearby_chat->mInputEditor->setFocus(FALSE);
+	    gAgent.stopTyping();
+	}
+}
+
+// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
+// Otherwise returns input and channel 0.
+LLWString LLFloaterIMNearbyChat::stripChannelNumber(const LLWString &mesg, S32* channel)
+{
+	if (mesg[0] == '/'
+		&& mesg[1] == '/')
+	{
+		// This is a "repeat channel send"
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(2, mesg.length() - 2);
+	}
+	else if (mesg[0] == '/'
+			 && mesg[1]
+			 && LLStringOps::isDigit(mesg[1]))
+	{
+		// This a special "/20" speak on a channel
+		S32 pos = 0;
+
+		// Copy the channel number into a string
+		LLWString channel_string;
+		llwchar c;
+		do
+		{
+			c = mesg[pos+1];
+			channel_string.push_back(c);
+			pos++;
+		}
+		while(c && pos < 64 && LLStringOps::isDigit(c));
+		
+		// Move the pointer forward to the first non-whitespace char
+		// Check isspace before looping, so we can handle "/33foo"
+		// as well as "/33 foo"
+		while(c && iswspace(c))
+		{
+			c = mesg[pos+1];
+			pos++;
+		}
+		
+		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
+		*channel = sLastSpecialChatChannel;
+		return mesg.substr(pos, mesg.length() - pos);
+	}
+	else
+	{
+		// This is normal chat.
+		*channel = 0;
+		return mesg;
+	}
+}
+
+void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
+{
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_ChatFromViewer);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_ChatData);
+	msg->addStringFast(_PREHASH_Message, utf8_out_text);
+	msg->addU8Fast(_PREHASH_Type, type);
+	msg->addS32("Channel", channel);
+
+	gAgent.sendReliableMessage();
+
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+}
+
+class LLChatCommandHandler : public LLCommandHandler
+{
+public:
+	// not allowed from outside the app
+	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
+
+    // Your code here
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLMediaCtrl* web)
+	{
+		bool retval = false;
+		// Need at least 2 tokens to have a valid message.
+		if (tokens.size() < 2)
+		{
+			retval = false;
+		}
+		else
+		{
+		S32 channel = tokens[0].asInteger();
+			// VWR-19499 Restrict function to chat channels greater than 0.
+			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
+			{
+				retval = true;
+		// Send unescaped message, see EXT-6353.
+		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
+		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
+			}
+			else
+			{
+				retval = false;
+				// Tell us this is an unsupported SLurl.
+			}
+		}
+		return retval;
+	}
+};
+
+// Creating the object registers with the dispatcher.
+LLChatCommandHandler gChatHandler;
diff --git a/indra/newview/llnearbychatbar.h b/indra/newview/llfloaterimnearbychat.h
similarity index 59%
rename from indra/newview/llnearbychatbar.h
rename to indra/newview/llfloaterimnearbychat.h
index 662496d3383cc37ccfc05548cd954f84efef65a0..05b48cccb03657a2b3e7f646f04cdc9225eec7c9 100644
--- a/indra/newview/llnearbychatbar.h
+++ b/indra/newview/llfloaterimnearbychat.h
@@ -1,6 +1,6 @@
 /** 
- * @file llnearbychatbar.h
- * @brief LLNearbyChatBar class definition
+ * @file llfloaterimnearbychat.h
+ * @brief LLFloaterIMNearbyChat class definition
  *
  * $LicenseInfo:firstyear=2002&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,38 +24,54 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLNEARBYCHATBAR_H
-#define LL_LLNEARBYCHATBAR_H
+#ifndef LL_LLFLOATERIMNEARBYCHAT_H
+#define LL_LLFLOATERIMNEARBYCHAT_H
 
-#include "llfloater.h"
+#include "llfloaterimsessiontab.h"
 #include "llcombobox.h"
 #include "llgesturemgr.h"
 #include "llchat.h"
 #include "llvoiceclient.h"
 #include "lloutputmonitorctrl.h"
 #include "llspeakers.h"
+#include "llscrollbar.h"
+#include "llviewerchat.h"
+#include "llpanel.h"
 
-class LLNearbyChatBarListener;
+class LLResizeBar;
 
-class LLNearbyChatBar :	public LLFloater
+class LLFloaterIMNearbyChat
+	:	public LLFloaterIMSessionTab
 {
-	LOG_CLASS(LLNearbyChatBar);
-
 public:
 	// constructor for inline chat-bars (e.g. hosted in chat history window)
-	LLNearbyChatBar(const LLSD& key);
-	~LLNearbyChatBar() {}
+	LLFloaterIMNearbyChat(const LLSD& key = LLSD(LLUUID()));
+	~LLFloaterIMNearbyChat() {}
+
+	static LLFloaterIMNearbyChat* buildFloater(const LLSD& key);
 
-	virtual BOOL postBuild();
+	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onClose(bool app_quitting);
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setVisibleAndFrontmost(BOOL take_focus=TRUE, const LLSD& key = LLSD());
+	/*virtual*/ void closeHostedFloater();
 
-	static LLNearbyChatBar* getInstance();
+	void loadHistory();
+    void reloadMessages(bool clean_messages = false);
+	void removeScreenChat();
 
-	LLLineEditor* getChatBox() { return mChatBox; }
+	void show();
+	bool isChatVisible() const;
 
-	virtual void draw();
+	/** @param archive true - to save a message to the chat history log */
+	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());
+
+	LLChatEntry* getChatBox() { return mInputEditor; }
 
 	std::string getCurrentChat();
+	S32 getMessageArchiveLength() {return mMessageArchive.size();}
+
 	virtual BOOL handleKeyHere( KEY key, MASK mask );
 
 	static void startChat(const char* line);
@@ -64,24 +80,22 @@ class LLNearbyChatBar :	public LLFloater
 	static void sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate);
 	static void sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate);
 
+	static bool isWordsName(const std::string& name);
+
 	void showHistory();
-	void showTranslationCheckbox(BOOL show);
-	/*virtual*/void setMinimized(BOOL b);
 
 protected:
 	static BOOL matchChatTypeTrigger(const std::string& in_str, std::string* out_str);
-	static void onChatBoxKeystroke(LLLineEditor* caller, void* userdata);
-	static void onChatBoxFocusLost(LLFocusableElement* caller, void* userdata);
+	void onChatBoxKeystroke();
+	void onChatBoxFocusLost();
 	void onChatBoxFocusReceived();
 
 	void sendChat( EChatType type );
 	void onChatBoxCommit();
 	void onChatFontChange(LLFontGL* fontp);
 
-	/* virtual */ bool applyRectControl();
-
-	void showNearbyChatPanel(bool show);
-	void onToggleNearbyChatPanel();
+	/*virtual*/ void onTearOffClicked();
+	/*virtual*/ void onClickCloseBtn();
 
 	static LLWString stripChannelNumber(const LLWString &mesg, S32* channel);
 	EChatType processChatTypeTriggers(EChatType type, std::string &str);
@@ -91,14 +105,15 @@ class LLNearbyChatBar :	public LLFloater
 	// Which non-zero channel did we last chat on?
 	static S32 sLastSpecialChatChannel;
 
-	LLLineEditor*			mChatBox;
-	LLView*					mNearbyChat;
 	LLOutputMonitorCtrl*	mOutputMonitor;
 	LLLocalSpeakerMgr*		mSpeakerMgr;
 
 	S32 mExpandedHeight;
 
-	boost::shared_ptr<LLNearbyChatBarListener> mListener;
+private:
+	/*virtual*/ void refresh();
+
+	std::vector<LLChat> mMessageArchive;
 };
 
-#endif
+#endif // LL_LLFLOATERIMNEARBYCHAT_H
diff --git a/indra/newview/llnearbychathandler.cpp b/indra/newview/llfloaterimnearbychathandler.cpp
similarity index 70%
rename from indra/newview/llnearbychathandler.cpp
rename to indra/newview/llfloaterimnearbychathandler.cpp
index 600fd395fb02525486b9927855d9cd336cf30e37..9ce5e128977e0b889acc0b40cd24a90d97c4bdae 100644
--- a/indra/newview/llnearbychathandler.cpp
+++ b/indra/newview/llfloaterimnearbychathandler.cpp
@@ -1,6 +1,6 @@
 /** 
- * @file LLNearbyChatHandler.cpp
- * @brief Nearby chat notification managment
+ * @file LLFloaterIMNearbyChatHandler.cpp
+ * @brief Nearby chat chat managment
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -27,43 +27,46 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llagentdata.h" // for gAgentID
-#include "llnearbychathandler.h"
+#include "llfloaterimnearbychathandler.h"
 
 #include "llchatitemscontainerctrl.h"
 #include "llfirstuse.h"
 #include "llfloaterscriptdebug.h"
 #include "llhints.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llrecentpeople.h"
 
 #include "llviewercontrol.h"
 
 #include "llfloaterreg.h"//for LLFloaterReg::getTypedInstance
 #include "llviewerwindow.h"//for screen channel position
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimcontainer.h"
 #include "llrootview.h"
 #include "lllayoutstack.h"
 
-//add LLNearbyChatHandler to LLNotificationsUI namespace
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
 using namespace LLNotificationsUI;
 
-//-----------------------------------------------------------------------------------------------
-//LLNearbyChatScreenChannel
-//-----------------------------------------------------------------------------------------------	
-LLToastPanelBase* createToastPanel()
+static LLFloaterIMNearbyChatToastPanel* createToastPanel()
 {
-	LLNearbyChatToastPanel* item = LLNearbyChatToastPanel::createInstance();
+	LLFloaterIMNearbyChatToastPanel* item = LLFloaterIMNearbyChatToastPanel::createInstance();
 	return item;
 }
 
-class LLNearbyChatScreenChannel: public LLScreenChannelBase
+
+//-----------------------------------------------------------------------------------------------
+//LLFloaterIMNearbyChatScreenChannel
+//-----------------------------------------------------------------------------------------------	
+
+class LLFloaterIMNearbyChatScreenChannel: public LLScreenChannelBase
 {
-	LOG_CLASS(LLNearbyChatScreenChannel);
+	LOG_CLASS(LLFloaterIMNearbyChatScreenChannel);
 public:
 	typedef std::vector<LLHandle<LLToast> > toast_vec_t;
 	typedef std::list<LLHandle<LLToast> > toast_list_t;
 
-	LLNearbyChatScreenChannel(const Params& p)
+	LLFloaterIMNearbyChatScreenChannel(const Params& p)
 		: LLScreenChannelBase(p)
 	{
 		mStopProcessing = false;
@@ -71,20 +74,20 @@ class LLNearbyChatScreenChannel: public LLScreenChannelBase
 		LLControlVariable* ctrl = gSavedSettings.getControl("NearbyToastLifeTime").get();
 		if (ctrl)
 		{
-			ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastsLifetime, this));
+			ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime, this));
 		}
 
 		ctrl = gSavedSettings.getControl("NearbyToastFadingTime").get();
 		if (ctrl)
 		{
-			ctrl->getSignal()->connect(boost::bind(&LLNearbyChatScreenChannel::updateToastFadingTime, this));
+			ctrl->getSignal()->connect(boost::bind(&LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime, this));
 		}
 	}
 
-	void addNotification	(LLSD& notification);
+	void addChat	(LLSD& chat);
 	void arrangeToasts		();
 	
-	typedef boost::function<LLToastPanelBase* (void )> create_toast_panel_callback_t;
+	typedef boost::function<LLFloaterIMNearbyChatToastPanel* (void )> create_toast_panel_callback_t;
 	void setCreatePanelCallback(create_toast_panel_callback_t value) { m_create_toast_panel_callback_t = value;}
 
 	void onToastDestroyed	(LLToast* toast, bool app_quitting);
@@ -152,17 +155,19 @@ class LLNearbyChatScreenChannel: public LLScreenChannelBase
 	bool	mChannelRect;
 };
 
+
+
 //-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
+// LLFloaterIMNearbyChatToast
 //-----------------------------------------------------------------------------------------------
 
 // We're deriving from LLToast to be able to override onClose()
 // in order to handle closing nearby chat toasts properly.
-class LLNearbyChatToast : public LLToast
+class LLFloaterIMNearbyChatToast : public LLToast
 {
-	LOG_CLASS(LLNearbyChatToast);
+	LOG_CLASS(LLFloaterIMNearbyChatToast);
 public:
-	LLNearbyChatToast(const LLToast::Params& p, LLNearbyChatScreenChannel* nc_channelp)
+	LLFloaterIMNearbyChatToast(const LLToast::Params& p, LLFloaterIMNearbyChatScreenChannel* nc_channelp)
 	:	LLToast(p),
 	 	mNearbyChatScreenChannelp(nc_channelp)
 	{
@@ -171,14 +176,14 @@ class LLNearbyChatToast : public LLToast
 	/*virtual*/ void onClose(bool app_quitting);
 
 private:
-	LLNearbyChatScreenChannel*	mNearbyChatScreenChannelp;
+	LLFloaterIMNearbyChatScreenChannel*	mNearbyChatScreenChannelp;
 };
 
 //-----------------------------------------------------------------------------------------------
-// LLNearbyChatScreenChannel
+// LLFloaterIMNearbyChatScreenChannel
 //-----------------------------------------------------------------------------------------------
 
-void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast)
+void LLFloaterIMNearbyChatScreenChannel::deactivateToast(LLToast* toast)
 {
 	toast_vec_t::iterator pos = std::find(m_active_toasts.begin(), m_active_toasts.end(), toast->getHandle());
 
@@ -192,12 +197,12 @@ void LLNearbyChatScreenChannel::deactivateToast(LLToast* toast)
 	m_active_toasts.erase(pos);
 }
 
-void	LLNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
+void	LLFloaterIMNearbyChatScreenChannel::createOverflowToast(S32 bottom, F32 timer)
 {
 	//we don't need overflow toast in nearby chat
 }
 
-void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
+void LLFloaterIMNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitting)
 {	
 	LL_DEBUGS("NearbyChat") << "Toast destroyed (app_quitting=" << app_quitting << ")" << llendl;
 
@@ -216,7 +221,7 @@ void LLNearbyChatScreenChannel::onToastDestroyed(LLToast* toast, bool app_quitti
 	}
 }
 
-void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
+void LLFloaterIMNearbyChatScreenChannel::onToastFade(LLToast* toast)
 {	
 	LL_DEBUGS("NearbyChat") << "Toast fading" << llendl;
 
@@ -231,7 +236,7 @@ void LLNearbyChatScreenChannel::onToastFade(LLToast* toast)
 	arrangeToasts();
 }
 
-void LLNearbyChatScreenChannel::updateToastsLifetime()
+void LLFloaterIMNearbyChatScreenChannel::updateToastsLifetime()
 {
 	S32 seconds = gSavedSettings.getS32("NearbyToastLifeTime");
 	toast_list_t::iterator it;
@@ -242,7 +247,7 @@ void LLNearbyChatScreenChannel::updateToastsLifetime()
 	}
 }
 
-void LLNearbyChatScreenChannel::updateToastFadingTime()
+void LLFloaterIMNearbyChatScreenChannel::updateToastFadingTime()
 {
 	S32 seconds = gSavedSettings.getS32("NearbyToastFadingTime");
 	toast_list_t::iterator it;
@@ -253,9 +258,9 @@ void LLNearbyChatScreenChannel::updateToastFadingTime()
 	}
 }
 
-bool	LLNearbyChatScreenChannel::createPoolToast()
+bool	LLFloaterIMNearbyChatScreenChannel::createPoolToast()
 {
-	LLToastPanelBase* panel= m_create_toast_panel_callback_t();
+	LLFloaterIMNearbyChatToastPanel* panel= m_create_toast_panel_callback_t();
 	if(!panel)
 		return false;
 	
@@ -264,20 +269,20 @@ bool	LLNearbyChatScreenChannel::createPoolToast()
 	p.lifetime_secs = gSavedSettings.getS32("NearbyToastLifeTime");
 	p.fading_time_secs = gSavedSettings.getS32("NearbyToastFadingTime");
 
-	LLToast* toast = new LLNearbyChatToast(p, this);
+	LLToast* toast = new LLFloaterIMNearbyChatToast(p, this);
 	
 	
-	toast->setOnFadeCallback(boost::bind(&LLNearbyChatScreenChannel::onToastFade, this, _1));
+	toast->setOnFadeCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastFade, this, _1));
 
 	// If the toast gets somehow prematurely destroyed, deactivate it to prevent crash (STORM-1352).
-	toast->setOnToastDestroyedCallback(boost::bind(&LLNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
+	toast->setOnToastDestroyedCallback(boost::bind(&LLFloaterIMNearbyChatScreenChannel::onToastDestroyed, this, _1, false));
 
 	LL_DEBUGS("NearbyChat") << "Creating and pooling toast" << llendl;	
 	m_toast_pool.push_back(toast->getHandle());
 	return true;
 }
 
-void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
+void LLFloaterIMNearbyChatScreenChannel::addChat(LLSD& chat)
 {
 	//look in pool. if there is any message
 	if(mStopProcessing)
@@ -289,16 +294,16 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 
 	if(m_active_toasts.size())
 	{
-		LLUUID fromID = notification["from_id"].asUUID();		// agent id or object id
-		std::string from = notification["from"].asString();
+		LLUUID fromID = chat["from_id"].asUUID();		// agent id or object id
+		std::string from = chat["from"].asString();
 		LLToast* toast = m_active_toasts[0].get();
 		if (toast)
 		{
-			LLNearbyChatToastPanel* panel = dynamic_cast<LLNearbyChatToastPanel*>(toast->getPanel());
+			LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
   
 			if(panel && panel->messageID() == fromID && panel->getFromName() == from && panel->canAddText())
 			{
-				panel->addMessage(notification);
+				panel->addMessage(chat);
 				toast->reshapeToPanel();
 				toast->startTimer();
 	  
@@ -316,11 +321,11 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 		LL_DEBUGS("NearbyChat") << "Empty pool" << llendl;
 		if(!createPoolToast())//created toast will go to pool. so next call will find it
 			return;
-		addNotification(notification);
+		addChat(chat);
 		return;
 	}
 
-	int chat_type = notification["chat_type"].asInteger();
+	int chat_type = chat["chat_type"].asInteger();
 	
 	if( ((EChatType)chat_type == CHAT_TYPE_DEBUG_MSG))
 	{
@@ -339,10 +344,10 @@ void LLNearbyChatScreenChannel::addNotification(LLSD& notification)
 	m_toast_pool.pop_back();
 
 
-	LLToastPanelBase* panel = dynamic_cast<LLToastPanelBase*>(toast->getPanel());
+	LLFloaterIMNearbyChatToastPanel* panel = dynamic_cast<LLFloaterIMNearbyChatToastPanel*>(toast->getPanel());
 	if(!panel)
 		return;
-	panel->init(notification);
+	panel->init(chat);
 
 	toast->reshapeToPanel();
 	toast->startTimer();
@@ -361,7 +366,7 @@ static bool sort_toasts_predicate(LLHandle<LLToast> first, LLHandle<LLToast> sec
 	return v1 > v2;
 }
 
-void LLNearbyChatScreenChannel::arrangeToasts()
+void LLFloaterIMNearbyChatScreenChannel::arrangeToasts()
 {
 	if(mStopProcessing || isHovering())
 		return;
@@ -441,20 +446,18 @@ void LLNearbyChatScreenChannel::arrangeToasts()
 
 
 //-----------------------------------------------------------------------------------------------
-//LLNearbyChatHandler
+//LLFloaterIMNearbyChatHandler
 //-----------------------------------------------------------------------------------------------
-boost::scoped_ptr<LLEventPump> LLNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
+boost::scoped_ptr<LLEventPump> LLFloaterIMNearbyChatHandler::sChatWatcher(new LLEventStream("LLChat"));
 
-LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& id)
+LLFloaterIMNearbyChatHandler::LLFloaterIMNearbyChatHandler()
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
-	LLNearbyChatScreenChannel::Params p;
+	LLFloaterIMNearbyChatScreenChannel::Params p;
 	p.id = LLUUID(gSavedSettings.getString("NearByChatChannelUUID"));
-	LLNearbyChatScreenChannel* channel = new LLNearbyChatScreenChannel(p);
+	LLFloaterIMNearbyChatScreenChannel* channel = new LLFloaterIMNearbyChatScreenChannel(p);
 	
-	LLNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
+	LLFloaterIMNearbyChatScreenChannel::create_toast_panel_callback_t callback = createToastPanel;
 
 	channel->setCreatePanelCallback(callback);
 
@@ -463,12 +466,12 @@ LLNearbyChatHandler::LLNearbyChatHandler(e_notification_type type, const LLSD& i
 	mChannel = channel->getHandle();
 }
 
-LLNearbyChatHandler::~LLNearbyChatHandler()
+LLFloaterIMNearbyChatHandler::~LLFloaterIMNearbyChatHandler()
 {
 }
 
 
-void LLNearbyChatHandler::initChannel()
+void LLFloaterIMNearbyChatHandler::initChannel()
 {
 	//LLRect snap_rect = gFloaterView->getSnapRect();
 	//mChannel->init(snap_rect.mLeft, snap_rect.mLeft + 200);
@@ -476,7 +479,7 @@ void LLNearbyChatHandler::initChannel()
 
 
 
-void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
+void LLFloaterIMNearbyChatHandler::processChat(const LLChat& chat_msg,
 									  const LLSD &args)
 {
 	if(chat_msg.mMuted == TRUE)
@@ -485,28 +488,27 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	if(chat_msg.mText.empty())
 		return;//don't process empty messages
 
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-
-	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
+    LLFloaterReg::getInstance("im_container");
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 
 	// Build notification data 
-	LLSD notification;
-	notification["message"] = chat_msg.mText;
-	notification["from"] = chat_msg.mFromName;
-	notification["from_id"] = chat_msg.mFromID;
-	notification["time"] = chat_msg.mTime;
-	notification["source"] = (S32)chat_msg.mSourceType;
-	notification["chat_type"] = (S32)chat_msg.mChatType;
-	notification["chat_style"] = (S32)chat_msg.mChatStyle;
+	LLSD chat;
+	chat["message"] = chat_msg.mText;
+	chat["from"] = chat_msg.mFromName;
+	chat["from_id"] = chat_msg.mFromID;
+	chat["time"] = chat_msg.mTime;
+	chat["source"] = (S32)chat_msg.mSourceType;
+	chat["chat_type"] = (S32)chat_msg.mChatType;
+	chat["chat_style"] = (S32)chat_msg.mChatStyle;
 	// Pass sender info so that it can be rendered properly (STORM-1021).
-	notification["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
+	chat["sender_slurl"] = LLViewerChat::getSenderSLURL(chat_msg, args);
 
 	if (chat_msg.mChatType == CHAT_TYPE_DIRECT &&
 		chat_msg.mText.length() > 0 &&
 		chat_msg.mText[0] == '@')
 	{
 		// Send event on to LLEventStream and exit
-		sChatWatcher->post(notification);
+		sChatWatcher->post(chat);
 		return;
 	}
 
@@ -553,15 +555,16 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	}
 
 	// Send event on to LLEventStream
-	sChatWatcher->post(notification);
+	sChatWatcher->post(chat);
 
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
 
-	if( !chat_bar->isMinimized()
-		&& nearby_chat->isInVisibleChain() 
-		|| ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
+	if((  ( chat_msg.mSourceType == CHAT_SOURCE_AGENT
 			&& gSavedSettings.getBOOL("UseChatBubbles") )
 		|| mChannel.isDead()
-		|| !mChannel.get()->getShowToasts() ) // to prevent toasts in Busy mode
+		|| !mChannel.get()->getShowToasts() )
+		&& nearby_chat->isMessagePaneExpanded())
+		// to prevent toasts in Do Not Disturb mode
 		return;//no need in toast if chat is visible or if bubble chat is enabled
 
 	// arrange a channel on a screen
@@ -582,7 +585,7 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 	}
 	*/
 
-	LLNearbyChatScreenChannel* channel = dynamic_cast<LLNearbyChatScreenChannel*>(mChannel.get());
+	LLFloaterIMNearbyChatScreenChannel* channel = dynamic_cast<LLFloaterIMNearbyChatScreenChannel*>(mChannel.get());
 
 	if(channel)
 	{
@@ -601,33 +604,46 @@ void LLNearbyChatHandler::processChat(const LLChat& chat_msg,
 			toast_msg = chat_msg.mText;
 		}
 
-		// Add a nearby chat toast.
-		LLUUID id;
-		id.generate();
-		notification["id"] = id;
-		std::string r_color_name = "White";
-		F32 r_color_alpha = 1.0f; 
-		LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
-		
-		notification["text_color"] = r_color_name;
-		notification["color_alpha"] = r_color_alpha;
-		notification["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
-		notification["message"] = toast_msg;
-		channel->addNotification(notification);	
-	}
-}
+		//Don't show nearby toast, if conversation is visible and selected
+		if ((nearby_chat->hasFocus()) ||
+		    ((im_box->getSelectedSession().isNull() &&
+				((LLFloater::isVisible(im_box) && !im_box->isMinimized() && im_box->isFrontmost())
+						|| (LLFloater::isVisible(nearby_chat) && !nearby_chat->isMinimized() && nearby_chat->isFrontmost())))))
+		{
+			if(nearby_chat->isMessagePaneExpanded())
+			{
+				return;
+			}
+		}
 
-void LLNearbyChatHandler::onDeleteToast(LLToast* toast)
-{
+        //Will show toast when chat preference is set        
+        if((gSavedSettings.getString("NotificationNearbyChatOptions") == "toast") || !nearby_chat->isMessagePaneExpanded())
+        {
+            // Add a nearby chat toast.
+            LLUUID id;
+            id.generate();
+            chat["id"] = id;
+            std::string r_color_name = "White";
+            F32 r_color_alpha = 1.0f; 
+            LLViewerChat::getChatColor( chat_msg, r_color_name, r_color_alpha);
+
+            chat["text_color"] = r_color_name;
+            chat["color_alpha"] = r_color_alpha;
+            chat["font_size"] = (S32)LLViewerChat::getChatFontSize() ;
+            chat["message"] = toast_msg;
+            channel->addChat(chat);	
+        }
+
+	}
 }
 
 
 //-----------------------------------------------------------------------------------------------
-// LLNearbyChatToast
+// LLFloaterIMNearbyChatToast
 //-----------------------------------------------------------------------------------------------
 
 // virtual
-void LLNearbyChatToast::onClose(bool app_quitting)
+void LLFloaterIMNearbyChatToast::onClose(bool app_quitting)
 {
 	mNearbyChatScreenChannelp->onToastDestroyed(this, app_quitting);
 }
diff --git a/indra/newview/llnearbychathandler.h b/indra/newview/llfloaterimnearbychathandler.h
similarity index 76%
rename from indra/newview/llnearbychathandler.h
rename to indra/newview/llfloaterimnearbychathandler.h
index b0e4f62d51e5d1ab2b7e62caeddc48d952e93901..5e6f8cde305c704e1e18872d884d46f414a06a7b 100644
--- a/indra/newview/llnearbychathandler.h
+++ b/indra/newview/llfloaterimnearbychathandler.h
@@ -1,5 +1,5 @@
 /** 
- * @file llnearbychathandler.h
+ * @file llfloaterimnearbychathandler.h
  * @brief nearby chat notify
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
@@ -24,27 +24,26 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLNEARBYCHATHANDLER_H
-#define LL_LLNEARBYCHATHANDLER_H
+#ifndef LL_LLFLOATERIMNEARBYCHATHANDLER_H
+#define LL_LLFLOATERIMNEARBYCHATHANDLER_H
 
 #include "llnotificationhandler.h"
 
 class LLEventPump;
 
-//add LLNearbyChatHandler to LLNotificationsUI namespace
+//add LLFloaterIMNearbyChatHandler to LLNotificationsUI namespace
 namespace LLNotificationsUI{
 
-class LLNearbyChatHandler : public LLChatHandler
+class LLFloaterIMNearbyChatHandler : public LLChatHandler
 {
 public:
-	LLNearbyChatHandler(e_notification_type type,const LLSD& id);
-	virtual ~LLNearbyChatHandler();
+	LLFloaterIMNearbyChatHandler();
+	virtual ~LLFloaterIMNearbyChatHandler();
 
 
 	virtual void processChat(const LLChat& chat_msg, const LLSD &args);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	static boost::scoped_ptr<LLEventPump> sChatWatcher;
@@ -52,4 +51,4 @@ class LLNearbyChatHandler : public LLChatHandler
 
 }
 
-#endif /* LL_LLNEARBYCHATHANDLER_H */
+#endif /* LL_LLFLOATERIMNEARBYCHATHANDLER_H */
diff --git a/indra/newview/llnearbychatbarlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp
similarity index 85%
rename from indra/newview/llnearbychatbarlistener.cpp
rename to indra/newview/llfloaterimnearbychatlistener.cpp
index a63e1fb76e555072b0eaa3ee691d6f035f0f84bd..14a22bcd84cb2f0f7b0936796ef10037272dba98 100644
--- a/indra/newview/llnearbychatbarlistener.cpp
+++ b/indra/newview/llfloaterimnearbychatlistener.cpp
@@ -1,8 +1,8 @@
 /**
- * @file   llnearbychatbarlistener.cpp
+ * @file   llfloaterimnearbychatlistener.cpp
  * @author Dave Simmons
  * @date   2011-03-15
- * @brief  Implementation for LLNearbyChatBarListener.
+ * @brief  Implementation for LLFloaterIMNearbyChatListener.
  *
  * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -28,15 +28,15 @@
 
 #include "llviewerprecompiledheaders.h"
 
-#include "llnearbychatbarlistener.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychatlistener.h"
+#include "llfloaterimnearbychat.h"
 
 #include "llagent.h"
 #include "llchat.h"
 
 
 
-LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar)
+LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar)
   : LLEventAPI("LLChatBar",
                "LLChatBar listener to (e.g.) sendChat, etc."),
 	mChatbar(chatbar)
@@ -46,12 +46,12 @@ LLNearbyChatBarListener::LLNearbyChatBarListener(LLNearbyChatBar & chatbar)
         "[\"message\"] chat message text [required]\n"
         "[\"channel\"] chat channel number [default = 0]\n"
 		"[\"type\"] chat type \"whisper\", \"normal\", \"shout\" [default = \"normal\"]",
-        &LLNearbyChatBarListener::sendChat);
+        &LLFloaterIMNearbyChatListener::sendChat);
 }
 
 
 // "sendChat" command
-void LLNearbyChatBarListener::sendChat(LLSD const & chat_data) const
+void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const
 {
 	// Extract the data
 	std::string chat_text = chat_data["message"].asString();
diff --git a/indra/newview/llnearbychatbarlistener.h b/indra/newview/llfloaterimnearbychatlistener.h
similarity index 72%
rename from indra/newview/llnearbychatbarlistener.h
rename to indra/newview/llfloaterimnearbychatlistener.h
index 9af9bc1f7b894ff71a2afd115225ca421f8b3773..1470a6dc1e1fca47f10bd2b855802175d469240b 100644
--- a/indra/newview/llnearbychatbarlistener.h
+++ b/indra/newview/llfloaterimnearbychatlistener.h
@@ -1,8 +1,8 @@
 /**
- * @file   llnearbychatbarlistener.h
+ * @file   llfloaterimnearbychatlistener.h
  * @author Dave Simmons
  * @date   2011-03-15
- * @brief  Class definition for LLNearbyChatBarListener.
+ * @brief  Class definition for LLFloaterIMNearbyChatListener.
  *
  * $LicenseInfo:firstyear=2011&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -27,24 +27,24 @@
  */
 
 
-#ifndef LL_LLNEARBYCHATBARLISTENER_H
-#define LL_LLNEARBYCHATBARLISTENER_H
+#ifndef LL_LLFLOATERIMNEARBYCHATLISTENER_H
+#define LL_LLFLOATERIMNEARBYCHATLISTENER_H
 
 #include "lleventapi.h"
 
 class LLSD;
-class LLNearbyChatBar;
+class LLFloaterIMNearbyChat;
 
-class LLNearbyChatBarListener : public LLEventAPI
+class LLFloaterIMNearbyChatListener : public LLEventAPI
 {
 public:
-	LLNearbyChatBarListener(LLNearbyChatBar & chatbar);
+	LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar);
 
 private:
     void sendChat(LLSD const & chat_data) const;
 
-	LLNearbyChatBar & mChatbar;
+	LLFloaterIMNearbyChat & mChatbar;
 };
 
-#endif // LL_LLNEARBYCHATBARLISTENER_H
+#endif // LL_LLFLOATERIMNEARBYCHATLISTENER_H
 
diff --git a/indra/newview/llfloaterimsession.cpp b/indra/newview/llfloaterimsession.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8ec85e11602709d7791b9d95c9d08251b8152960
--- /dev/null
+++ b/indra/newview/llfloaterimsession.cpp
@@ -0,0 +1,1307 @@
+/** 
+ * @file llfloaterimsession.cpp
+ * @brief LLFloaterIMSession class definition
+ *
+ * $LicenseInfo:firstyear=2009&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterimsession.h"
+
+#include "lldraghandle.h"
+#include "llnotificationsutil.h"
+
+#include "llagent.h"
+#include "llappviewer.h"
+#include "llavataractions.h"
+#include "llavatarnamecache.h"
+#include "llbutton.h"
+#include "llchannelmanager.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "lldonotdisturbnotificationstorage.h"
+#include "llfloaterreg.h"
+#include "llfloateravatarpicker.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "llinventoryfunctions.h"
+//#include "lllayoutstack.h"
+#include "llchatentry.h"
+#include "lllogchat.h"
+#include "llscreenchannel.h"
+#include "llsyswellwindow.h"
+#include "lltrans.h"
+#include "llchathistory.h"
+#include "llnotifications.h"
+#include "llviewerwindow.h"
+#include "lltransientfloatermgr.h"
+#include "llinventorymodel.h"
+#include "llrootview.h"
+#include "llspeakers.h"
+#include "llviewerchat.h"
+#include "llnotificationmanager.h"
+#include "llautoreplace.h"
+
+floater_showed_signal_t LLFloaterIMSession::sIMFloaterShowedSignal;
+
+LLFloaterIMSession::LLFloaterIMSession(const LLUUID& session_id)
+  : LLFloaterIMSessionTab(session_id),
+	mLastMessageIndex(-1),
+	mDialog(IM_NOTHING_SPECIAL),
+	mTypingStart(),
+	mShouldSendTypingState(false),
+	mMeTyping(false),
+	mOtherTyping(false),
+	mSessionNameUpdatedForTyping(false),
+	mTypingTimer(),
+	mTypingTimeoutTimer(),
+	mPositioned(false),
+	mSessionInitialized(false)
+{
+	mIsNearbyChat = false;
+
+	initIMSession(session_id);
+		
+	setOverlapsScreenChannel(true);
+
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
+    mEnableCallbackRegistrar.add("Avatar.EnableGearItem", boost::bind(&LLFloaterIMSession::enableGearMenuItem, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.GearDoToSelected", boost::bind(&LLFloaterIMSession::GearDoToSelected, this, _2));
+    mEnableCallbackRegistrar.add("Avatar.CheckGearItem", boost::bind(&LLFloaterIMSession::checkGearMenuItem, this, _2));
+
+    setDocked(true);
+}
+
+
+// virtual
+void LLFloaterIMSession::refresh()
+{
+	if (mMeTyping)
+{
+		// Time out if user hasn't typed for a while.
+		if (mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS)
+		{
+	setTyping(false);
+		}
+	}
+}
+
+// virtual
+void LLFloaterIMSession::onTearOffClicked()
+{
+    LLFloaterIMSessionTab::onTearOffClicked();
+
+    if(mIsP2PChat)
+    {
+        if(isTornOff())
+        {
+            mSpeakingIndicator->setSpeakerId(mOtherParticipantUUID, mSessionID);
+        }
+        else
+        {
+            mSpeakingIndicator->setSpeakerId(LLUUID::null);
+        }
+    }
+}
+
+// virtual
+void LLFloaterIMSession::onClickCloseBtn()
+{
+	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(mSessionID);
+
+	if (session != NULL)
+	{
+		bool is_call_with_chat = session->isGroupSessionType()
+				|| session->isAdHocSessionType() || session->isP2PSessionType();
+
+		LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+		if (is_call_with_chat && voice_channel != NULL
+				&& voice_channel->isActive())
+		{
+			LLSD payload;
+			payload["session_id"] = mSessionID;
+			LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
+			return;
+		}
+	}
+	else
+	{
+		llwarns << "Empty session with id: " << (mSessionID.asString()) << llendl;
+		return;
+	}
+
+	LLFloaterIMSessionTab::onClickCloseBtn();
+}
+
+/* static */
+void LLFloaterIMSession::newIMCallback(const LLSD& data)
+{
+	if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
+	{
+		LLUUID session_id = data["session_id"].asUUID();
+
+		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+        // update if visible, otherwise will be updated when opened
+		if (floater && floater->isInVisibleChain())
+		{
+			floater->updateMessages();
+		}
+	}
+}
+
+void LLFloaterIMSession::onVisibilityChange(const LLSD& new_visibility)
+{
+	bool visible = new_visibility.asBoolean();
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	if (visible && voice_channel &&
+		voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
+	{
+		LLFloaterReg::showInstance("voice_call", mSessionID);
+	}
+	else
+	{
+		LLFloaterReg::hideInstance("voice_call", mSessionID);
+	}
+}
+
+void LLFloaterIMSession::onSendMsg( LLUICtrl* ctrl, void* userdata )
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+	self->sendMsgFromInputEditor();
+	self->setTyping(false);
+}
+
+bool LLFloaterIMSession::enableGearMenuItem(const LLSD& userdata)
+{
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::GearDoToSelected(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+    selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSession::checkGearMenuItem(const LLSD& userdata)
+{
+	std::string command = userdata.asString();
+	uuid_vec_t selected_uuids;
+	selected_uuids.push_back(mOtherParticipantUUID);
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSession::sendMsgFromInputEditor()
+{
+	if (gAgent.isGodlike()
+		|| (mDialog != IM_NOTHING_SPECIAL)
+		|| !mOtherParticipantUUID.isNull())
+	{
+		if (mInputEditor)
+		{
+			LLWString text = mInputEditor->getWText();
+			LLWStringUtil::trim(text);
+			LLWStringUtil::replaceChar(text,182,'\n'); // Convert paragraph symbols back into newlines.
+			if(!text.empty())
+			{
+				// Truncate and convert to UTF8 for transport
+				std::string utf8_text = wstring_to_utf8str(text);
+
+				sendMsg(utf8_text);
+
+				mInputEditor->setText(LLStringUtil::null);
+			}
+		}
+	}
+	else
+	{
+		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
+	}
+}
+
+void LLFloaterIMSession::sendMsg(const std::string& msg)
+{
+	const std::string utf8_text = utf8str_truncate(msg, MAX_MSG_BUF_SIZE - 1);
+
+	if (mSessionInitialized)
+	{
+		LLIMModel::sendMessage(utf8_text, mSessionID, mOtherParticipantUUID, mDialog);
+	}
+	else
+	{
+		//queue up the message to send once the session is initialized
+		mQueuedMsgsForInit.append(utf8_text);
+	}
+
+	updateMessages();
+}
+
+LLFloaterIMSession::~LLFloaterIMSession()
+{
+	mVoiceChannelStateChangeConnection.disconnect();
+	if(LLVoiceClient::instanceExists())
+	{
+		LLVoiceClient::getInstance()->removeObserver(this);
+	}
+
+	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
+}
+
+
+void LLFloaterIMSession::initIMSession(const LLUUID& session_id)
+{
+	// Change the floater key to bind it to a new session.
+	setKey(session_id);
+
+	mSessionID = session_id;
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	if (mSession)
+	{
+		mIsP2PChat = mSession->isP2PSessionType();
+		mSessionInitialized = mSession->mSessionInitialized;
+		mDialog = mSession->mType;
+	}
+}
+
+void LLFloaterIMSession::initIMFloater()
+{
+	const LLUUID& other_party_id =
+			LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
+	if (other_party_id.notNull())
+	{
+		mOtherParticipantUUID = other_party_id;
+	}
+
+	boundVoiceChannel();
+
+	mTypingStart = LLTrans::getString("IM_typing_start_string");
+
+	// Show control panel in torn off floaters only.
+	mParticipantListPanel->setVisible(!getHost() && gSavedSettings.getBOOL("IMShowControlPanel"));
+
+	// Disable input editor if session cannot accept text
+	if ( mSession && !mSession->mTextIMPossible )
+	{
+		mInputEditor->setEnabled(FALSE);
+		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
+	}
+
+	if (!mIsP2PChat)
+	{
+		std::string session_name(LLIMModel::instance().getName(mSessionID));
+		updateSessionName(session_name);
+	}
+}
+
+//virtual
+BOOL LLFloaterIMSession::postBuild()
+{
+	BOOL result = LLFloaterIMSessionTab::postBuild();
+
+	mInputEditor->setMaxTextLength(1023);
+	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2, _3, _4, _5));
+	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
+	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
+	mInputEditor->setKeystrokeCallback( boost::bind(onInputEditorKeystroke, _1, this) );
+	mInputEditor->setCommitCallback(boost::bind(onSendMsg, _1, this));
+
+	setDocked(true);
+
+	LLButton* add_btn = getChild<LLButton>("add_btn");
+
+	// Allow to add chat participants depending on the session type
+	add_btn->setEnabled(isInviteAllowed());
+	add_btn->setClickedCallback(boost::bind(&LLFloaterIMSession::onAddButtonClicked, this));
+
+	childSetAction("voice_call_btn", boost::bind(&LLFloaterIMSession::onCallButtonClicked, this));
+
+	LLVoiceClient::getInstance()->addObserver(this);
+	
+	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
+	//see LLFloaterIMPanel for how it is done (IB)
+
+	initIMFloater();
+
+	return result;
+}
+
+void LLFloaterIMSession::onAddButtonClicked()
+{
+    LLView * button = findChild<LLView>("toolbar_panel")->findChild<LLButton>("add_btn");
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterIMSession::addSessionParticipants, this, _1), TRUE, TRUE, FALSE, root_floater->getName(), button);
+	if (!picker)
+	{
+		return;
+	}
+
+	// Need to disable 'ok' button when selected users are already in conversation.
+	picker->setOkBtnEnableCb(boost::bind(&LLFloaterIMSession::canAddSelectedToChat, this, _1));
+	
+	if (root_floater)
+	{
+		root_floater->addDependentFloater(picker);
+	}
+}
+
+bool LLFloaterIMSession::canAddSelectedToChat(const uuid_vec_t& uuids)
+{
+	if (!mSession
+		|| mDialog == IM_SESSION_GROUP_START
+		|| mDialog == IM_SESSION_INVITE && gAgent.isInGroup(mSessionID))
+	{
+		return false;
+	}
+
+	if (mIsP2PChat)
+	{
+		// For a P2P session just check if we are not adding the other participant.
+
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			if (*id == mOtherParticipantUUID)
+			{
+				return false;
+			}
+		}
+	}
+	else
+	{
+		// For a conference session we need to check against the list from LLSpeakerMgr,
+		// because this list may change when participants join or leave the session.
+
+		LLSpeakerMgr::speaker_list_t speaker_list;
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->getSpeakerList(&speaker_list, true);
+		}
+	
+		for (uuid_vec_t::const_iterator id = uuids.begin();
+				id != uuids.end(); ++id)
+		{
+			for (LLSpeakerMgr::speaker_list_t::const_iterator it = speaker_list.begin();
+					it != speaker_list.end(); ++it)
+			{
+				const LLPointer<LLSpeaker>& speaker = *it;
+				if (*id == speaker->mID)
+				{
+					return false;
+				}
+			}
+		}
+	}
+
+	return true;
+}
+
+void LLFloaterIMSession::addSessionParticipants(const uuid_vec_t& uuids)
+{
+	if (mIsP2PChat)
+	{
+		LLSD payload;
+		LLSD args;
+
+		LLNotificationsUtil::add("ConfirmAddingChatParticipants", args, payload,
+				boost::bind(&LLFloaterIMSession::addP2PSessionParticipants, this, _1, _2, 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());
+		
+		inviteToSession(uuids);
+	}
+}
+
+void LLFloaterIMSession::addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option != 0)
+	{
+		return;
+	}
+
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+
+	// first check whether this is a voice session
+	bool is_voice_call = voice_channel != NULL && voice_channel->isActive();
+
+	uuid_vec_t temp_ids;
+
+	// Add the initial participant of a P2P session
+	temp_ids.push_back(mOtherParticipantUUID);
+	temp_ids.insert(temp_ids.end(), uuids.begin(), uuids.end());
+
+	// then we can close the current session
+	onClose(false);
+
+	// 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.
+	if (is_voice_call)
+	{
+		LLAvatarActions::startAdhocCall(temp_ids, mSessionID);
+	}
+	else
+	{
+		LLAvatarActions::startConference(temp_ids, mSessionID);
+	}
+}
+
+void LLFloaterIMSession::sendParticipantsAddedNotification(const uuid_vec_t& uuids)
+{
+	std::string names_string;
+	LLAvatarActions::buildResidentsString(uuids, names_string);
+	LLStringUtil::format_map_t args;
+	args["[NAME]"] = names_string;
+
+	sendMsg(getString(uuids.size() > 1 ? "multiple_participants_added" : "participant_added", args));
+}
+
+void LLFloaterIMSession::boundVoiceChannel()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if(voice_channel)
+	{
+		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(
+				boost::bind(&LLFloaterIMSession::onVoiceChannelStateChanged, this, _1, _2));
+
+		//call (either p2p, group or ad-hoc) can be already in started state
+		bool callIsActive = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+		updateCallBtnState(callIsActive);
+	}
+}
+
+void LLFloaterIMSession::onCallButtonClicked()
+{
+	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
+	if (voice_channel)
+	{
+		bool is_call_active = voice_channel->getState() >= LLVoiceChannel::STATE_CALL_STARTED;
+	    if (is_call_active)
+	    {
+		    gIMMgr->endCall(mSessionID);
+	    }
+	    else
+	    {
+		    gIMMgr->startCall(mSessionID);
+	    }
+	}
+}
+
+void LLFloaterIMSession::onChange(EStatusType status, const std::string &channelURI, bool proximal)
+{
+	if(status != STATUS_JOINING && status != STATUS_LEFT_CHANNEL)
+	{
+		enableDisableCallBtn();
+	}
+}
+
+void LLFloaterIMSession::onVoiceChannelStateChanged(
+		const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
+{
+	bool callIsActive = new_state >= LLVoiceChannel::STATE_CALL_STARTED;
+	updateCallBtnState(callIsActive);
+}
+
+void LLFloaterIMSession::updateSessionName(const std::string& name)
+{
+	if (!name.empty())
+	{
+		LLFloaterIMSessionTab::updateSessionName(name);
+		mTypingStart.setArg("[NAME]", name);
+		setTitle (mOtherTyping ? mTypingStart.getString() : name);
+		mSessionNameUpdatedForTyping = mOtherTyping;
+	}
+}
+
+//static
+LLFloaterIMSession* LLFloaterIMSession::show(const LLUUID& session_id)
+{
+	closeHiddenIMToasts();
+
+	if (!gIMMgr->hasSession(session_id))
+		return NULL;
+
+	// Test the existence of the floater before we try to create it
+	bool exist = findInstance(session_id);
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLFloaterIMSession* floater = getInstance(session_id);
+	if (!floater)
+		return NULL;
+
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+	// Do not add again existing floaters
+	if (!exist)
+	{
+		//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
+		// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
+		LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
+		if (floater_container)
+		{
+			floater_container->addFloater(floater, TRUE, i_pt);
+		}
+	}
+
+	floater->openFloater(floater->getKey());
+
+	floater->setVisible(TRUE);
+
+	return floater;
+}
+//static
+LLFloaterIMSession* LLFloaterIMSession::findInstance(const LLUUID& session_id)
+{
+    LLFloaterIMSession* conversation =
+    		LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+	return conversation;
+}
+
+LLFloaterIMSession* LLFloaterIMSession::getInstance(const LLUUID& session_id)
+{
+	LLFloaterIMSession* conversation =
+				LLFloaterReg::getTypedInstance<LLFloaterIMSession>("impanel", session_id);
+
+	return conversation;
+}
+
+void LLFloaterIMSession::onClose(bool app_quitting)
+{
+	setTyping(false);
+
+	// The source of much argument and design thrashing
+	// Should the window hide or the session close when the X is clicked?
+	//
+	// Last change:
+	// EXT-3516 X Button should end IM session, _ button should hide
+	gIMMgr->leaveSession(mSessionID);
+    // *TODO: Study why we need to restore the floater before we close it.
+    // Might be because we want to save some state data in some clean open state.
+	LLFloaterIMSessionTab::restoreFloater();
+	// Clean up the conversation *after* the session has been ended
+	LLFloaterIMSessionTab::onClose(app_quitting);
+}
+
+void LLFloaterIMSession::setDocked(bool docked, bool pop_on_undock)
+{
+	// update notification channel state
+	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+	
+	if(!isChatMultiTab())
+	{
+		LLTransientDockableFloater::setDocked(docked, pop_on_undock);
+	}
+
+	// update notification channel state
+	if(channel)
+	{
+		channel->updateShowToastsState();
+		channel->redrawToasts();
+	}
+}
+
+void LLFloaterIMSession::setMinimized(BOOL b)
+{
+	bool wasMinimized = isMinimized();
+	LLFloaterIMSessionTab::setMinimized(b);
+
+	//Switching from minimized state to un-minimized state
+	if(wasMinimized && !b)
+	{
+		//When in DND mode, remove stored IM notifications
+		//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+		if(gAgent.isDoNotDisturb())
+		{
+			LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+		}
+	}
+}
+
+void LLFloaterIMSession::setVisible(BOOL visible)
+{
+	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+		(LLNotificationsUI::LLChannelManager::getInstance()->
+											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	LLFloaterIMSessionTab::setVisible(visible);
+
+	// update notification channel state
+	if(channel)
+	{
+		channel->updateShowToastsState();
+		channel->redrawToasts();
+	}
+
+	if(!visible)
+	{
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(mSessionID);
+			if(NULL != chicletp)
+			{
+				chicletp->setToggleState(false);
+			}
+		}
+	}
+
+	if (visible && isInVisibleChain())
+	{
+		sIMFloaterShowedSignal(mSessionID);
+        
+	}
+
+}
+
+BOOL LLFloaterIMSession::getVisible()
+{
+	bool visible;
+
+	if(isChatMultiTab())
+	{
+		LLFloaterIMContainer* im_container =
+				LLFloaterIMContainer::getInstance();
+		
+		// Treat inactive floater as invisible.
+		bool is_active = im_container->getActiveFloater() == this;
+	
+		//torn off floater is always inactive
+		if (!is_active && getHost() != im_container)
+		{
+			visible = LLTransientDockableFloater::getVisible();
+		}
+		else
+		{
+		// getVisible() returns TRUE when Tabbed IM window is minimized.
+			visible = is_active && !im_container->isMinimized()
+						&& im_container->getVisible();
+		}
+	}
+	else
+	{
+		visible = LLTransientDockableFloater::getVisible();
+	}
+
+	return visible;
+}
+
+void LLFloaterIMSession::setFocus(BOOL focus)
+{
+	LLFloaterIMSessionTab::setFocus(focus);
+
+	//When in DND mode, remove stored IM notifications
+	//Nearby chat (Null) IMs are not stored while in DND mode, so can ignore removal
+	if(focus && gAgent.isDoNotDisturb())
+	{
+		LLDoNotDisturbNotificationStorage::getInstance()->removeNotification(LLDoNotDisturbNotificationStorage::toastName, mSessionID);
+	}
+}
+
+//static
+bool LLFloaterIMSession::toggle(const LLUUID& session_id)
+{
+	if(!isChatMultiTab())
+	{
+		LLFloaterIMSession* floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>(
+				"impanel", session_id);
+		if (floater && floater->getVisible() && floater->hasFocus())
+		{
+			// clicking on chiclet to close floater just hides it to maintain existing
+			// scroll/text entry state
+			floater->setVisible(false);
+			return false;
+		}
+		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
+		{
+			floater->setVisible(TRUE);
+			floater->setFocus(TRUE);
+			return true;
+		}
+	}
+
+	// ensure the list of messages is updated when floater is made visible
+	show(session_id);
+	return true;
+}
+
+void LLFloaterIMSession::sessionInitReplyReceived(const LLUUID& im_session_id)
+{
+	mSessionInitialized = true;
+
+	//will be different only for an ad-hoc im session
+	if (mSessionID != im_session_id)
+	{
+		initIMSession(im_session_id);
+		buildConversationViewParticipant();
+	}
+
+	initIMFloater();
+	LLFloaterIMSessionTab::updateGearBtn();
+	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
+
+	//need to send delayed messages collected while waiting for session initialization
+	if (mQueuedMsgsForInit.size())
+	{
+		LLSD::array_iterator iter;
+		for ( iter = mQueuedMsgsForInit.beginArray();
+					iter != mQueuedMsgsForInit.endArray(); ++iter)
+		{
+			LLIMModel::sendMessage(iter->asString(), mSessionID,
+				mOtherParticipantUUID, mDialog);
+		}
+
+		mQueuedMsgsForInit.clear();
+	}
+}
+
+void LLFloaterIMSession::updateMessages()
+{
+	std::list<LLSD> messages;
+
+	// we shouldn't reset unread message counters if IM floater doesn't have focus
+    LLIMModel::instance().getMessages(
+    		mSessionID, messages, mLastMessageIndex + 1, hasFocus());
+
+	if (messages.size())
+	{
+		std::ostringstream message;
+		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
+		std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
+		for (; iter != iter_end; ++iter)
+		{
+			LLSD msg = *iter;
+
+			std::string time = msg["time"].asString();
+			LLUUID from_id = msg["from_id"].asUUID();
+			std::string from = msg["from"].asString();
+			std::string message = msg["message"].asString();
+			bool is_history = msg["is_history"].asBoolean();
+
+			LLChat chat;
+			chat.mFromID = from_id;
+			chat.mSessionID = mSessionID;
+			chat.mFromName = from;
+			chat.mTimeStr = time;
+			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
+
+			// process offer notification
+			if (msg.has("notification_id"))
+			{
+				chat.mNotifId = msg["notification_id"].asUUID();
+				// if notification exists - embed it
+				if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
+				{
+					// remove embedded notification from channel
+					LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
+							(LLNotificationsUI::LLChannelManager::getInstance()->
+																findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+					if (getVisible())
+					{
+						// toast will be automatically closed since it is not storable toast
+						channel->hideToast(chat.mNotifId);
+					}
+				}
+				// if notification doesn't exist - try to use next message which should be log entry
+				else
+				{
+					continue;
+				}
+			}
+			//process text message
+			else
+			{
+				chat.mText = message;
+			}
+			
+			// Add the message to the chat log
+			appendMessage(chat);
+			mLastMessageIndex = msg["index"].asInteger();
+
+			// if it is a notification - next message is a notification history log, so skip it
+			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
+			{
+				if (++iter == iter_end)
+				{
+					break;
+				}
+				else
+				{
+					mLastMessageIndex++;
+				}
+			}
+		}
+	}
+}
+
+void LLFloaterIMSession::reloadMessages(bool clean_messages/* = false*/)
+{
+	if (clean_messages)
+	{
+		LLIMModel::LLIMSession * sessionp = LLIMModel::instance().findIMSession(mSessionID);
+
+		if (NULL != sessionp)
+		{
+			sessionp->loadHistory();
+		}
+	}
+
+	mChatHistory->clear();
+	mLastMessageIndex = -1;
+	updateMessages();
+	mInputEditor->setFont(LLViewerChat::getChatFont());
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
+{
+	LLFloaterIMSession* self= (LLFloaterIMSession*) userdata;
+
+	// Allow enabling the LLFloaterIMSession input editor only if session can accept text
+	LLIMModel::LLIMSession* im_session =
+		LLIMModel::instance().findIMSession(self->mSessionID);
+	//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
+	if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
+	{
+		//in disconnected state IM input editor should be disabled
+		self->mInputEditor->setEnabled(!gDisconnected);
+	}
+}
+
+// static
+void LLFloaterIMSession::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*) userdata;
+	self->setTyping(false);
+}
+
+// static
+void LLFloaterIMSession::onInputEditorKeystroke(LLTextEditor* caller, void* userdata)
+{
+	LLFloaterIMSession* self = (LLFloaterIMSession*)userdata;
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->flashConversationItemWidget(self->mSessionID,false);
+	}
+	std::string text = self->mInputEditor->getText();
+
+		// Deleting all text counts as stopping typing.
+	self->setTyping(!text.empty());
+}
+
+void LLFloaterIMSession::setTyping(bool typing)
+{
+	if ( typing )
+	{
+		// Started or proceeded typing, reset the typing timeout timer
+		mTypingTimeoutTimer.reset();
+	}
+
+	if ( mMeTyping != typing )
+	{
+		// Typing state is changed
+		mMeTyping = typing;
+		// So, should send current state
+		mShouldSendTypingState = true;
+		// In case typing is started, send state after some delay
+		mTypingTimer.reset();
+	}
+
+	// Don't want to send typing indicators to multiple people, potentially too
+	// much network traffic. Only send in person-to-person IMs.
+	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
+	{
+		// Still typing, send 'start typing' notification or
+		// send 'stop typing' notification immediately
+		if (!mMeTyping || mTypingTimer.getElapsedTimeF32() > 1.f)
+		{
+			LLIMModel::instance().sendTypingState(mSessionID,
+					mOtherParticipantUUID, mMeTyping);
+					mShouldSendTypingState = false;
+		}
+	}
+
+	if (!mIsNearbyChat)
+	{
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if (speaker_mgr)
+		{
+			speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
+		}
+	}
+}
+
+void LLFloaterIMSession::processIMTyping(const LLIMInfo* im_info, BOOL typing)
+{
+	if ( typing )
+	{
+		// other user started typing
+		addTypingIndicator(im_info);
+	}
+	else
+	{
+		// other user stopped typing
+		removeTypingIndicator(im_info);
+	}
+}
+
+void LLFloaterIMSession::processAgentListUpdates(const LLSD& body)
+{
+	uuid_vec_t joined_uuids;
+
+	if (body.isMap() && body.has("agent_updates") && body["agent_updates"].isMap())
+	{
+		LLSD::map_const_iterator update_it;
+		for(update_it = body["agent_updates"].beginMap();
+			update_it != body["agent_updates"].endMap();
+			++update_it)
+		{
+			LLUUID agent_id(update_it->first);
+			LLSD agent_data = update_it->second;
+
+			if (agent_data.isMap())
+			{
+				// store the new participants in joined_uuids
+				if (agent_data.has("transition") && agent_data["transition"].asString() == "ENTER")
+				{
+					joined_uuids.push_back(agent_id);
+				}
+
+				// process the moderator mutes
+				if (agent_id == gAgentID && agent_data.has("info") && agent_data["info"].has("mutes"))
+				{
+					BOOL moderator_muted_text = agent_data["info"]["mutes"]["text"].asBoolean();
+					mInputEditor->setEnabled(!moderator_muted_text);
+					std::string label;
+					if (moderator_muted_text)
+						label = LLTrans::getString("IM_muted_text_label");
+					else
+						label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
+					mInputEditor->setLabel(label);
+
+					if (moderator_muted_text)
+						LLNotificationsUtil::add("TextChatIsMutedByModerator");
+				}
+			}
+		}
+	}
+
+	// the vectors need to be sorted for computing the intersection and difference
+	std::sort(mInvitedParticipants.begin(), mInvitedParticipants.end());
+    std::sort(joined_uuids.begin(), joined_uuids.end());
+
+    uuid_vec_t intersection; // uuids of invited residents who have joined the conversation
+	std::set_intersection(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+						  joined_uuids.begin(), joined_uuids.end(),
+						  std::back_inserter(intersection));
+
+	if (intersection.size() > 0)
+	{
+		sendParticipantsAddedNotification(intersection);
+	}
+
+	// Remove all joined participants from invited array.
+	// The difference between the two vectors (the elements in mInvitedParticipants which are not in joined_uuids)
+	// is placed at the beginning of mInvitedParticipants, then all other elements are erased.
+	mInvitedParticipants.erase(std::set_difference(mInvitedParticipants.begin(), mInvitedParticipants.end(),
+												   joined_uuids.begin(), joined_uuids.end(),
+												   mInvitedParticipants.begin()),
+							   mInvitedParticipants.end());
+}
+
+void LLFloaterIMSession::processSessionUpdate(const LLSD& session_update)
+{
+	// *TODO : verify following code when moderated mode will be implemented
+	if ( false && session_update.has("moderated_mode") &&
+		 session_update["moderated_mode"].has("voice") )
+	{
+		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
+		const std::string session_label = LLIMModel::instance().getName(mSessionID);
+
+		if (voice_moderated)
+		{
+			setTitle(session_label + std::string(" ")
+							+ LLTrans::getString("IM_moderated_chat_label"));
+		}
+		else
+		{
+			setTitle(session_label);
+		}
+
+		// *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
+		//update the speakers dropdown too
+		//mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
+	}
+}
+
+// virtual
+void LLFloaterIMSession::draw()
+{
+	// add people who were added via dropPerson()
+	if (!mPendingParticipants.empty())
+	{
+		addSessionParticipants(mPendingParticipants);
+		mPendingParticipants.clear();
+	}
+
+	LLFloaterIMSessionTab::draw();
+}
+
+// virtual
+BOOL LLFloaterIMSession::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+									EDragAndDropType cargo_type,
+									void* cargo_data,
+									EAcceptance* accept,
+						   std::string& tooltip_msg)
+{
+	if (cargo_type == DAD_PERSON)
+	{
+		if (dropPerson(static_cast<LLUUID*>(cargo_data), drop))
+		{
+			*accept = ACCEPT_YES_MULTI;
+		}
+		else
+		{
+			*accept = ACCEPT_NO;
+		}
+	}
+	else if (mDialog == IM_NOTHING_SPECIAL)
+	{
+		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
+				cargo_type, cargo_data, accept);
+	}
+
+	return TRUE;
+}
+
+bool LLFloaterIMSession::dropPerson(LLUUID* person_id, bool drop)
+{
+	bool res = person_id && person_id->notNull();
+	if(res)
+	{
+		uuid_vec_t ids;
+		ids.push_back(*person_id);
+
+		res = canAddSelectedToChat(ids);
+		if(res && drop)
+		{
+			// these people will be added during the next draw() call
+			// (so they can be added all at once)
+			mPendingParticipants.push_back(*person_id);
+		}
+	}
+
+	return res;
+}
+
+BOOL LLFloaterIMSession::isInviteAllowed() const
+{
+	return ( (IM_SESSION_CONFERENCE_START == mDialog)
+			 || (IM_SESSION_INVITE == mDialog && !gAgent.isInGroup(mSessionID))
+			 || mIsP2PChat);
+}
+
+class LLSessionInviteResponder : public LLHTTPClient::Responder
+{
+public:
+	LLSessionInviteResponder(const LLUUID& session_id)
+	{
+		mSessionID = session_id;
+	}
+
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "Error inviting all agents to session [status:" 
+				<< statusNum << "]: " << content << llendl;
+		//throw something back to the viewer here?
+	}
+
+private:
+	LLUUID mSessionID;
+};
+
+BOOL LLFloaterIMSession::inviteToSession(const uuid_vec_t& ids)
+{
+	LLViewerRegion* region = gAgent.getRegion();
+	bool is_region_exist = region != NULL;
+
+	if (is_region_exist)
+	{
+		S32 count = ids.size();
+
+		if( isInviteAllowed() && (count > 0) )
+		{
+			llinfos << "LLFloaterIMSession::inviteToSession() - inviting participants" << llendl;
+
+			std::string url = region->getCapability("ChatSessionRequest");
+
+			LLSD data;
+			data["params"] = LLSD::emptyArray();
+			for (int i = 0; i < count; i++)
+			{
+				data["params"].append(ids[i]);
+			}
+			data["method"] = "invite";
+			data["session-id"] = mSessionID;
+			LLHTTPClient::post(url,	data,new LLSessionInviteResponder(mSessionID));
+		}
+		else
+		{
+			llinfos << "LLFloaterIMSession::inviteToSession -"
+					<< " no need to invite agents for "
+					<< mDialog << llendl;
+			// successful add, because everyone that needed to get added
+			// was added.
+		}
+	}
+
+	return is_region_exist;
+}
+
+void LLFloaterIMSession::addTypingIndicator(const LLIMInfo* im_info)
+{
+	// We may have lost a "stop-typing" packet, don't add it twice
+	if (im_info && !mOtherTyping)
+	{
+		mOtherTyping = true;
+
+		// Update speaker
+		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+		if ( speaker_mgr )
+		{
+			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
+		}
+	}
+}
+
+void LLFloaterIMSession::removeTypingIndicator(const LLIMInfo* im_info)
+{
+	if (mOtherTyping)
+	{
+		mOtherTyping = false;
+
+		if (im_info)
+		{
+			// Update speaker
+			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			if (speaker_mgr)
+			{
+				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
+			}
+		}
+	}
+}
+
+// static
+void LLFloaterIMSession::closeHiddenIMToasts()
+{
+	class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
+	{
+	public:
+		bool matches(const LLNotificationPtr notification) const
+		{
+			// "notifytoast" type of notifications is reserved for IM notifications
+			return "notifytoast" == notification->getType();
+		}
+	};
+
+	LLNotificationsUI::LLScreenChannel* channel =
+			LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
+	if (channel != NULL)
+	{
+		channel->closeHiddenToasts(IMToastMatcher());
+	}
+}
+// static
+void LLFloaterIMSession::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	const LLSD& payload = notification["payload"];
+	LLUUID session_id = payload["session_id"];
+
+	LLFloater* im_floater = findInstance(session_id);
+	if (option == 0 && im_floater != NULL)
+	{
+		im_floater->closeFloater();
+	}
+
+	return;
+}
+
+// static
+void LLFloaterIMSession::sRemoveTypingIndicator(const LLSD& data)
+{
+	LLUUID session_id = data["session_id"];
+	if (session_id.isNull())
+		return;
+
+	LLUUID from_id = data["from_id"];
+	if (gAgentID == from_id || LLUUID::null == from_id)
+		return;
+
+	LLFloaterIMSession* floater = LLFloaterIMSession::findInstance(session_id);
+	if (!floater)
+		return;
+
+	if (IM_NOTHING_SPECIAL != floater->mDialog)
+		return;
+
+	floater->removeTypingIndicator();
+}
+
+// static
+void LLFloaterIMSession::onIMChicletCreated( const LLUUID& session_id )
+{
+	LLFloaterIMSession::addToHost(session_id);
+}
+
+boost::signals2::connection LLFloaterIMSession::setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb)
+{
+	return LLFloaterIMSession::sIMFloaterShowedSignal.connect(cb);
+}
diff --git a/indra/newview/llimfloater.h b/indra/newview/llfloaterimsession.h
similarity index 50%
rename from indra/newview/llimfloater.h
rename to indra/newview/llfloaterimsession.h
index f7cd35b5eb28d79d85f17298880e204a84cfe7a5..a0e0171b344baa322714bc3766e6851f499e7197 100644
--- a/indra/newview/llimfloater.h
+++ b/indra/newview/llfloaterimsession.h
@@ -1,6 +1,6 @@
 /** 
- * @file llimfloater.h
- * @brief LLIMFloater class definition
+ * @file llfloaterimsession.h
+ * @brief LLFloaterIMSession class definition
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -24,62 +24,81 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_IMFLOATER_H
-#define LL_IMFLOATER_H
+#ifndef LL_FLOATERIMSESSION_H
+#define LL_FLOATERIMSESSION_H
 
+#include "llimview.h"
+#include "llfloaterimsessiontab.h"
 #include "llinstantmessage.h"
 #include "lllogchat.h"
 #include "lltooldraganddrop.h"
-#include "lltransientdockablefloater.h"
+#include "llvoicechannel.h"
+#include "llvoiceclient.h"
 
 class LLAvatarName;
-class LLLineEditor;
+class LLButton;
+class LLChatEntry;
+class LLTextEditor;
 class LLPanelChatControlPanel;
 class LLChatHistory;
 class LLInventoryItem;
 class LLInventoryCategory;
 
+typedef boost::signals2::signal<void(const LLUUID& session_id)> floater_showed_signal_t;
+
 /**
  * Individual IM window that appears at the bottom of the screen,
  * optionally "docked" to the bottom tray.
  */
-class LLIMFloater : public LLTransientDockableFloater
+class LLFloaterIMSession
+    : public LLVoiceClientStatusObserver
+    , public LLFloaterIMSessionTab
 {
-	LOG_CLASS(LLIMFloater);
+	LOG_CLASS(LLFloaterIMSession);
 public:
-	LLIMFloater(const LLUUID& session_id);
+	LLFloaterIMSession(const LLUUID& session_id);
+
+	virtual ~LLFloaterIMSession();
+
+	void initIMSession(const LLUUID& session_id);
+	void initIMFloater();
 
-	virtual ~LLIMFloater();
-	
 	// LLView overrides
 	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void setMinimized(BOOL b);
 	/*virtual*/ void setVisible(BOOL visible);
 	/*virtual*/ BOOL getVisible();
+	/*virtual*/ void setFocus(BOOL focus);
 	// Check typing timeout timer.
+
 	/*virtual*/ void draw();
+	/*virtual*/ BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
+		EDragAndDropType cargo_type,
+		void* cargo_data,
+		EAcceptance* accept,
+		std::string& tooltip_msg);
+
+	static LLFloaterIMSession* findInstance(const LLUUID& session_id);
+	static LLFloaterIMSession* getInstance(const LLUUID& session_id);
 
 	// LLFloater overrides
 	/*virtual*/ void onClose(bool app_quitting);
 	/*virtual*/ void setDocked(bool docked, bool pop_on_undock = true);
-
 	// Make IM conversion visible and update the message history
-	static LLIMFloater* show(const LLUUID& session_id);
+	static LLFloaterIMSession* show(const LLUUID& session_id);
 
 	// Toggle panel specified by session_id
 	// Returns true iff panel became visible
 	static bool toggle(const LLUUID& session_id);
 
-	static LLIMFloater* findInstance(const LLUUID& session_id);
-
-	static LLIMFloater* getInstance(const LLUUID& session_id);
-
 	void sessionInitReplyReceived(const LLUUID& im_session_id);
 
 	// get new messages from LLIMModel
-	void updateMessages();
-	void reloadMessages();
-	static void onSendMsg( LLUICtrl*, void*);
-	void sendMsg();
+	/*virtual*/ void updateMessages();
+	void reloadMessages(bool clean_messages = false);
+	static void onSendMsg(LLUICtrl*, void*);
+	void sendMsgFromInputEditor();
+	void sendMsg(const std::string& msg);
 
 	// callback for LLIMModel on new messages
 	// route to specific floater if it is visible
@@ -89,62 +108,61 @@ class LLIMFloater : public LLTransientDockableFloater
 	void setPositioned(bool b) { mPositioned = b; };
 
 	void onVisibilityChange(const LLSD& new_visibility);
-	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
-	void processAgentListUpdates(const LLSD& body);
-	void processSessionUpdate(const LLSD& session_update);
+	bool enableGearMenuItem(const LLSD& userdata);
+	void GearDoToSelected(const LLSD& userdata);
+	bool checkGearMenuItem(const LLSD& userdata);
 
-	void updateChatHistoryStyle();
-	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
+	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
+	// button when voice is available
+	void onChange(EStatusType status, const std::string &channelURI,
+			bool proximal);
 
-	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask,
-							   BOOL drop, EDragAndDropType cargo_type,
-							   void *cargo_data, EAcceptance *accept,
-							   std::string& tooltip_msg);
-
-	/**
-	 * Returns true if chat is displayed in multi tabbed floater
-	 *         false if chat is displayed in multiple windows
-	 */
-	static bool isChatMultiTab();
+	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
+	virtual void onVoiceChannelStateChanged(
+			const LLVoiceChannel::EState& old_state,
+			const LLVoiceChannel::EState& new_state);
 
-	static void initIMFloater();
+	void processIMTyping(const LLIMInfo* im_info, BOOL typing);
+	void processAgentListUpdates(const LLSD& body);
+	void processSessionUpdate(const LLSD& session_update);
 
 	//used as a callback on receiving new IM message
 	static void sRemoveTypingIndicator(const LLSD& data);
-
 	static void onIMChicletCreated(const LLUUID& session_id);
+    const LLUUID& getOtherParticipantUUID() {return mOtherParticipantUUID;}
 
-	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::IM; }
-
-protected:
-	/* virtual */
-	void	onClickCloseBtn();
+	static boost::signals2::connection setIMFloaterShowedCallback(const floater_showed_signal_t::slot_type& cb);
+	static floater_showed_signal_t sIMFloaterShowedSignal;
 
+	bool needsTitleOverwrite() { return mSessionNameUpdatedForTyping && mOtherTyping; }
+	S32 getLastChatMessageIndex() {return mLastMessageIndex;}
 private:
-	// process focus events to set a currently active session
-	/* virtual */ void onFocusLost();
-	/* virtual */ void onFocusReceived();
-
-	// Update the window title, input field help text, etc.
-	void updateSessionName(const std::string& ui_title, const std::string& ui_label);
-	
-	// For display name lookups for IM window titles
-	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-	
-	BOOL dropCallingCard(LLInventoryItem* item, BOOL drop);
-	BOOL dropCategory(LLInventoryCategory* category, BOOL drop);
+
+	/*virtual*/ void refresh();
+
+    /*virtual*/ void onTearOffClicked();
+	/*virtual*/ void onClickCloseBtn();
+
+	// Update the window title and input field help text
+	/*virtual*/ void updateSessionName(const std::string& name);
+
+	bool dropPerson(LLUUID* person_id, bool drop);
 
 	BOOL isInviteAllowed() const;
 	BOOL inviteToSession(const uuid_vec_t& agent_ids);
-	
-	static void		onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata );
-	static void		onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
-	static void		onInputEditorKeystroke(LLLineEditor* caller, void* userdata);
-	void			setTyping(bool typing);
-	void			onSlide();
-	static void*	createPanelIMControl(void* userdata);
-	static void*	createPanelGroupControl(void* userdata);
-	static void* 	createPanelAdHocControl(void* userdata);
+	static void onInputEditorFocusReceived( LLFocusableElement* caller,void* userdata );
+	static void onInputEditorFocusLost(LLFocusableElement* caller, void* userdata);
+	static void onInputEditorKeystroke(LLTextEditor* caller, void* userdata);
+	void setTyping(bool typing);
+	void onAddButtonClicked();
+	void addSessionParticipants(const uuid_vec_t& uuids);
+	void addP2PSessionParticipants(const LLSD& notification, const LLSD& response, const uuid_vec_t& uuids);
+	void sendParticipantsAddedNotification(const uuid_vec_t& uuids);
+	bool canAddSelectedToChat(const uuid_vec_t& uuids);
+
+	void onCallButtonClicked();
+
+	void boundVoiceChannel();
 
 	// Add the "User is typing..." indicator.
 	void addTypingIndicator(const LLIMInfo* im_info);
@@ -156,27 +174,28 @@ class LLIMFloater : public LLTransientDockableFloater
 
 	static void confirmLeaveCallCallback(const LLSD& notification, const LLSD& response);
 
-	LLPanelChatControlPanel* mControlPanel;
-	LLUUID mSessionID;
 	S32 mLastMessageIndex;
 
 	EInstantMessage mDialog;
 	LLUUID mOtherParticipantUUID;
-	LLChatHistory* mChatHistory;
-	LLLineEditor* mInputEditor;
 	bool mPositioned;
 
-	std::string mSavedTitle;
 	LLUIString mTypingStart;
 	bool mMeTyping;
 	bool mOtherTyping;
 	bool mShouldSendTypingState;
 	LLFrameTimer mTypingTimer;
 	LLFrameTimer mTypingTimeoutTimer;
+	bool mSessionNameUpdatedForTyping;
 
 	bool mSessionInitialized;
 	LLSD mQueuedMsgsForInit;
-};
 
+	uuid_vec_t mInvitedParticipants;
+	uuid_vec_t mPendingParticipants;
+
+	// connection to voice channel state change signal
+	boost::signals2::connection mVoiceChannelStateChangeConnection;
+};
 
-#endif  // LL_IMFLOATER_H
+#endif  // LL_FLOATERIMSESSION_H
diff --git a/indra/newview/llfloaterimsessiontab.cpp b/indra/newview/llfloaterimsessiontab.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ce6e639305b345a16fbc8e3738397144167d8957
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.cpp
@@ -0,0 +1,1103 @@
+/**
+ * @file llfloaterimsessiontab.cpp
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $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 "llfloaterimsessiontab.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llavataractions.h"
+#include "llchatentry.h"
+#include "llchathistory.h"
+#include "llchiclet.h"
+#include "llchicletbar.h"
+#include "lldraghandle.h"
+#include "llfloaterreg.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h" // to replace separate IM Floaters with multifloater container
+#include "lllayoutstack.h"
+#include "lltoolbarview.h"
+#include "llfloaterimnearbychat.h"
+
+const F32 REFRESH_INTERVAL = 1.0f;
+
+LLFloaterIMSessionTab::LLFloaterIMSessionTab(const LLSD& session_id)
+  : LLTransientDockableFloater(NULL, true, session_id)
+  ,  mIsP2PChat(false)
+  ,  mExpandCollapseBtn(NULL)
+  ,  mTearOffBtn(NULL)
+  ,  mCloseBtn(NULL)
+  ,  mSessionID(session_id.asUUID())
+  , mConversationsRoot(NULL)
+  , mScroller(NULL)
+  , mSpeakingIndicator(NULL)
+  , mChatHistory(NULL)
+  , mInputEditor(NULL)
+  , mInputEditorPad(0)
+  , mRefreshTimer(new LLTimer())
+  , mIsHostAttached(false)
+  , mHasVisibleBeenInitialized(false)
+  , mIsParticipantListExpanded(true)
+  , mChatLayoutPanel(NULL)
+  , mInputPanels(NULL)
+  , mChatLayoutPanelHeight(0)
+{
+    setAutoFocus(FALSE);
+	mSession = LLIMModel::getInstance()->findIMSession(mSessionID);
+
+	mCommitCallbackRegistrar.add("IMSession.Menu.Action",
+			boost::bind(&LLFloaterIMSessionTab::onIMSessionMenuItemClicked,  this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.CompactExpandedModes.CheckItem",
+			boost::bind(&LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck, this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.CheckItem",
+			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemCheck,   this, _2));
+	mEnableCallbackRegistrar.add("IMSession.Menu.ShowModes.Enable",
+			boost::bind(&LLFloaterIMSessionTab::onIMShowModesMenuItemEnable,  this, _2));
+
+	// Right click menu handling
+    mEnableCallbackRegistrar.add("Avatar.CheckItem",  boost::bind(&LLFloaterIMSessionTab::checkContextMenuItem,	this, _2));
+    mEnableCallbackRegistrar.add("Avatar.EnableItem", boost::bind(&LLFloaterIMSessionTab::enableContextMenuItem, this, _2));
+    mCommitCallbackRegistrar.add("Avatar.DoToSelected", boost::bind(&LLFloaterIMSessionTab::doToSelected, this, _2));
+}
+
+LLFloaterIMSessionTab::~LLFloaterIMSessionTab()
+{
+	delete mRefreshTimer;
+}
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::findConversation(const LLUUID& uuid)
+{
+	LLFloaterIMSessionTab* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::findTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+	}
+
+	return conv;
+};
+
+//static
+LLFloaterIMSessionTab* LLFloaterIMSessionTab::getConversation(const LLUUID& uuid)
+{
+	LLFloaterIMSessionTab* conv;
+
+	if (uuid.isNull())
+	{
+		conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("nearby_chat");
+	}
+	else
+	{
+		conv = LLFloaterReg::getTypedInstance<LLFloaterIMSessionTab>("impanel", LLSD(uuid));
+	}
+
+	return conv;
+};
+
+void LLFloaterIMSessionTab::setVisible(BOOL visible)
+{
+	if(visible && !mHasVisibleBeenInitialized)
+	{
+		mHasVisibleBeenInitialized = true;
+		if(!gAgentCamera.cameraMouselook())
+		{
+			LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->setVisible(true);
+		}
+		LLFloaterIMSessionTab::addToHost(mSessionID);
+		LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+
+		if (conversp && conversp->isNearbyChat() && gSavedPerAccountSettings.getBOOL("NearbyChatIsNotCollapsed"))
+		{
+			onCollapseToLine(this);
+		}
+		mInputButtonPanel->setVisible(isTornOff());
+	}
+
+	LLTransientDockableFloater::setVisible(visible);
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::setFocus(BOOL focus)
+{
+	LLTransientDockableFloater::setFocus(focus);
+
+    //Redirect focus to input editor
+    if (focus)
+	{
+    	updateMessages();
+
+        if (mInputEditor)
+        {
+    	    mInputEditor->setFocus(TRUE);
+        }
+	}
+}
+
+
+void LLFloaterIMSessionTab::addToHost(const LLUUID& session_id)
+{
+	if ((session_id.notNull() && !gIMMgr->hasSession(session_id))
+			|| !LLFloaterIMSessionTab::isChatMultiTab())
+	{
+		return;
+	}
+
+	// Get the floater: this will create the instance if it didn't exist
+	LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(session_id);
+	if (conversp)
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+
+		// Do not add again existing floaters
+		if (floater_container && !conversp->isHostAttached())
+		{
+			conversp->setHostAttached(true);
+
+			if (!conversp->isNearbyChat()
+					|| gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff"))
+			{
+				floater_container->addFloater(conversp, false, LLTabContainer::RIGHT_OF_CURRENT);
+			}
+			else
+			{
+				// setting of the "potential" host for Nearby Chat: this sequence sets
+				// LLFloater::mHostHandle = NULL (a current host), but
+				// LLFloater::mLastHostHandle = floater_container (a "future" host)
+				conversp->setHost(floater_container);
+				conversp->setHost(NULL);
+
+				conversp->forceReshape();
+			}
+			// Added floaters share some state (like sort order) with their host
+			conversp->setSortOrder(floater_container->getSortOrder());
+		}
+	}
+}
+
+void LLFloaterIMSessionTab::assignResizeLimits()
+{
+	bool is_participants_pane_collapsed = mParticipantListPanel->isCollapsed();
+
+    // disable a layoutstack's functionality when participant list panel is collapsed
+	mRightPartPanel->setIgnoreReshape(is_participants_pane_collapsed);
+
+    S32 participants_pane_target_width = is_participants_pane_collapsed?
+    		0 : (mParticipantListPanel->getRect().getWidth() + LLPANEL_BORDER_WIDTH);
+
+    S32 new_min_width = participants_pane_target_width + mRightPartPanel->getExpandedMinDim() + mFloaterExtraWidth;
+
+	setResizeLimits(new_min_width, getMinHeight());
+
+	this->mParticipantListAndHistoryStack->updateLayout();
+}
+
+BOOL LLFloaterIMSessionTab::postBuild()
+{
+	BOOL result;
+
+	mBodyStack = getChild<LLLayoutStack>("main_stack");
+    mParticipantListAndHistoryStack = getChild<LLLayoutStack>("im_panels");
+
+	mCloseBtn = getChild<LLButton>("close_btn");
+	mCloseBtn->setCommitCallback(boost::bind(&LLFloater::onClickClose, this));
+
+	mExpandCollapseBtn = getChild<LLButton>("expand_collapse_btn");
+	mExpandCollapseBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onSlide, this));
+
+	mExpandCollapseLineBtn = getChild<LLButton>("minz_btn");
+	mExpandCollapseLineBtn->setClickedCallback(boost::bind(&LLFloaterIMSessionTab::onCollapseToLine, this));
+
+	mTearOffBtn = getChild<LLButton>("tear_off_btn");
+	mTearOffBtn->setCommitCallback(boost::bind(&LLFloaterIMSessionTab::onTearOffClicked, this));
+
+	mGearBtn = getChild<LLButton>("gear_btn");
+
+	mParticipantListPanel = getChild<LLLayoutPanel>("speakers_list_panel");
+	mRightPartPanel = getChild<LLLayoutPanel>("right_part_holder");
+
+	mToolbarPanel = getChild<LLLayoutPanel>("toolbar_panel");
+	mContentPanel = getChild<LLLayoutPanel>("body_panel");
+	mInputButtonPanel = getChild<LLLayoutPanel>("input_button_layout_panel");
+	mInputButtonPanel->setVisible(false);
+	// Add a scroller for the folder (participant) view
+	LLRect scroller_view_rect = mParticipantListPanel->getRect();
+	scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
+	LLScrollContainer::Params scroller_params(LLUICtrlFactory::getDefaultParams<LLFolderViewScrollContainer>());
+	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);	
+	
+	mChatHistory = getChild<LLChatHistory>("chat_history");
+
+	mInputEditor = getChild<LLChatEntry>("chat_editor");
+
+	mChatLayoutPanel = getChild<LLLayoutPanel>("chat_layout_panel");
+	mInputPanels = getChild<LLLayoutStack>("input_panels");
+	
+	mInputEditor->setTextExpandedCallback(boost::bind(&LLFloaterIMSessionTab::reshapeChatLayoutPanel, this));
+	mInputEditor->setCommitOnFocusLost( FALSE );
+	mInputEditor->setPassDelete(TRUE);
+	mInputEditor->setFont(LLViewerChat::getChatFont());
+
+	mChatLayoutPanelHeight = mChatLayoutPanel->getRect().getHeight();
+	mInputEditorPad = mChatLayoutPanelHeight - mInputEditor->getRect().getHeight();
+
+	setOpenPositioning(LLFloaterEnums::POSITIONING_RELATIVE);
+
+	mSaveRect = isNearbyChat()
+					&&  !gSavedPerAccountSettings.getBOOL("NearbyChatIsNotTornOff");
+	initRectControl();
+
+	if (isChatMultiTab())
+	{
+		result = LLFloater::postBuild();
+	}
+	else
+	{
+		result = LLDockableFloater::postBuild();
+	}
+
+	// Create the root using an ad-hoc base item
+	LLConversationItem* base_item = new LLConversationItem(mSessionID, mConversationViewModel);
+    LLFolderView::Params p(LLUICtrlFactory::getDefaultParams<LLFolderView>());
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = mParticipantListPanel;
+    p.listener = base_item;
+    p.view_model = &mConversationViewModel;
+    p.root = NULL;
+    p.use_ellipses = true;
+    p.options_menu = "menu_conversation.xml";
+    p.name = "root";
+	mConversationsRoot = LLUICtrlFactory::create<LLFolderView>(p);
+    mConversationsRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
+	// Attach that root to the scroller
+	mScroller->addChild(mConversationsRoot);
+	mConversationsRoot->setScrollContainer(mScroller);
+	mConversationsRoot->setFollowsAll();
+	mConversationsRoot->addChild(mConversationsRoot->mStatusTextBox);
+
+	setMessagePaneExpanded(true);
+
+	buildConversationViewParticipant();
+	refreshConversation();
+
+	// Zero expiry time is set only once to allow initial update.
+	mRefreshTimer->setTimerExpirySec(0);
+	mRefreshTimer->start();
+	initBtns();
+
+	if (mIsParticipantListExpanded != (bool)gSavedSettings.getBOOL("IMShowControlPanel"))
+	{
+		LLFloaterIMSessionTab::onSlide(this);
+	}
+
+	// The resize limits for LLFloaterIMSessionTab should be updated, based on current values of width of conversation and message panels
+	mParticipantListPanel->getResizeBar()->setResizeListener(boost::bind(&LLFloaterIMSessionTab::assignResizeLimits, this));
+	mFloaterExtraWidth =
+			getRect().getWidth()
+			- mParticipantListAndHistoryStack->getRect().getWidth()
+			- (mParticipantListPanel->isCollapsed()? 0 : LLPANEL_BORDER_WIDTH);
+
+	assignResizeLimits();
+
+	return result;
+}
+
+LLParticipantList* LLFloaterIMSessionTab::getParticipantList()
+{
+	return dynamic_cast<LLParticipantList*>(LLFloaterIMContainer::getInstance()->getSessionModel(mSessionID));
+}
+
+void LLFloaterIMSessionTab::draw()
+{
+	if (mRefreshTimer->hasExpired())
+	{
+		LLParticipantList* item = getParticipantList();
+		if (item)
+		{
+			// Update all model items
+			item->update();
+			// If the model and view list diverge in count, rebuild
+			// Note: this happens sometimes right around init (add participant events fire but get dropped) and is the cause
+			// of missing participants, often, the user agent itself. As there will be no other event fired, there's
+			// no other choice but get those inconsistencies regularly (and lightly) checked and scrubbed.
+			if (item->getChildrenCount() != mConversationsWidgets.size())
+			{
+				buildConversationViewParticipant();
+			}
+			refreshConversation();
+		}
+
+		// Restart the refresh timer
+		mRefreshTimer->setTimerExpirySec(REFRESH_INTERVAL);
+	}
+
+	LLTransientDockableFloater::draw();
+}
+
+void LLFloaterIMSessionTab::enableDisableCallBtn()
+{
+    getChildView("voice_call_btn")->setEnabled(
+    		mSessionID.notNull()
+    		&& mSession
+    		&& mSession->mSessionInitialized
+    		&& LLVoiceClient::getInstance()->voiceEnabled()
+    		&& LLVoiceClient::getInstance()->isVoiceWorking()
+    		&& mSession->mCallBackEnabled);
+}
+
+void LLFloaterIMSessionTab::onFocusReceived()
+{
+	setBackgroundOpaque(true);
+
+	if (mSessionID.notNull() && isInVisibleChain())
+	{
+		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
+	}
+
+	LLTransientDockableFloater::onFocusReceived();
+}
+
+void LLFloaterIMSessionTab::onFocusLost()
+{
+	setBackgroundOpaque(false);
+	LLTransientDockableFloater::onFocusLost();
+}
+
+std::string LLFloaterIMSessionTab::appendTime()
+{
+	time_t utc_time;
+	utc_time = time_corrected();
+	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
+		+LLTrans::getString("TimeMin")+"]";
+
+	LLSD substitution;
+
+	substitution["datetime"] = (S32) utc_time;
+	LLStringUtil::format (timeStr, substitution);
+
+	return timeStr;
+}
+
+void LLFloaterIMSessionTab::appendMessage(const LLChat& chat, const LLSD &args)
+{
+
+	// Update the participant activity time
+	LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+	if (im_box)
+	{
+		im_box->setTimeNow(mSessionID,chat.mFromID);
+	}
+	
+
+	LLChat& tmp_chat = const_cast<LLChat&>(chat);
+
+	if(tmp_chat.mTimeStr.empty())
+		tmp_chat.mTimeStr = appendTime();
+
+	if (!chat.mMuted)
+	{
+		tmp_chat.mFromName = chat.mFromName;
+		LLSD chat_args;
+		if (args) chat_args = args;
+		chat_args["use_plain_text_chat_history"] =
+				gSavedSettings.getBOOL("PlainTextChatHistory");
+		chat_args["show_time"] = gSavedSettings.getBOOL("IMShowTime");
+		chat_args["show_names_for_p2p_conv"] =
+				!mIsP2PChat || gSavedSettings.getBOOL("IMShowNamesForP2PConv");
+
+		if (mChatHistory)
+		{
+			mChatHistory->appendMessage(chat, chat_args);
+		}
+	}
+}
+
+
+void LLFloaterIMSessionTab::buildConversationViewParticipant()
+{
+	// Clear the widget list since we are rebuilding afresh from the model
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		removeConversationViewParticipant(widget_it->first);
+		// Iterators are invalidated by erase so we need to pick begin again
+		widget_it = mConversationsWidgets.begin();
+	}
+	
+	// Get the model list
+	LLParticipantList* item = getParticipantList();
+	if (!item)
+	{
+		// Nothing to do if the model list is inexistent
+		return;
+	}
+	
+	// Create the participants widgets now
+	LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = item->getChildrenBegin();
+	LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = item->getChildrenEnd();
+	while (current_participant_model != end_participant_model)
+	{
+		LLConversationItem* participant_model = dynamic_cast<LLConversationItem*>(*current_participant_model);
+		addConversationViewParticipant(participant_model);
+		current_participant_model++;
+	}
+}
+
+void LLFloaterIMSessionTab::addConversationViewParticipant(LLConversationItem* participant_model)
+{
+	// Check if the model already has an associated view
+	LLUUID uuid = participant_model->getUUID();
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,uuid);
+	
+	// If not already present, create the participant view and attach it to the root, otherwise, just refresh it
+	if (widget)
+	{
+		updateConversationViewParticipant(uuid); // overkill?
+	}
+	else
+	{
+		LLConversationViewParticipant* participant_view = createConversationViewParticipant(participant_model);
+		mConversationsWidgets[uuid] = participant_view;
+		participant_view->addToFolder(mConversationsRoot);
+		participant_view->addToSession(mSessionID);
+		participant_view->setVisible(TRUE);
+	}
+}
+
+void LLFloaterIMSessionTab::removeConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		mConversationsRoot->extractItem(widget);
+		delete widget;
+		mConversationsWidgets.erase(participant_id);
+	}
+}
+
+void LLFloaterIMSessionTab::updateConversationViewParticipant(const LLUUID& participant_id)
+{
+	LLFolderViewItem* widget = get_ptr_in_map(mConversationsWidgets,participant_id);
+	if (widget)
+	{
+		widget->refresh();
+	}
+}
+
+void LLFloaterIMSessionTab::refreshConversation()
+{
+	// Note: We collect participants names to change the session name only in the case of ad-hoc conversations
+	bool is_ad_hoc = (mSession ? mSession->isAdHocSessionType() : false);
+	uuid_vec_t participants_uuids; // uuids vector for building the added participants name string
+	// For P2P chat, we still need to update the session name who may have changed (switch display name for instance)
+	if (mIsP2PChat && mSession)
+	{
+		participants_uuids.push_back(mSession->mOtherParticipantID);
+	}
+
+	conversations_widgets_map::iterator widget_it = mConversationsWidgets.begin();
+	while (widget_it != mConversationsWidgets.end())
+	{
+		// Add the participant to the list except if it's the agent itself (redundant)
+		if (is_ad_hoc && (widget_it->first != gAgentID))
+		{
+			participants_uuids.push_back(widget_it->first);
+		}
+		widget_it->second->refresh();
+		widget_it->second->setVisible(TRUE);
+		++widget_it;
+	}
+	if (is_ad_hoc || mIsP2PChat)
+	{
+		// Build the session name and update it
+		std::string session_name;
+		if (participants_uuids.size() != 0)
+		{
+			LLAvatarActions::buildResidentsString(participants_uuids, session_name);
+		}
+		else
+		{
+			session_name = LLIMModel::instance().getName(mSessionID);
+		}
+		updateSessionName(session_name);
+	}
+
+	if (mSessionID.notNull())
+	{
+		LLParticipantList* participant_list = getParticipantList();
+		if (participant_list)
+		{
+			LLFolderViewModelItemCommon::child_list_t::const_iterator current_participant_model = participant_list->getChildrenBegin();
+			LLFolderViewModelItemCommon::child_list_t::const_iterator end_participant_model = participant_list->getChildrenEnd();
+			LLIMSpeakerMgr *speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
+			while (current_participant_model != end_participant_model)
+			{
+				LLConversationItemParticipant* participant_model = dynamic_cast<LLConversationItemParticipant*>(*current_participant_model);
+				if (speaker_mgr && participant_model)
+				{
+					LLSpeaker *participant_speaker = speaker_mgr->findSpeaker(participant_model->getUUID());
+					LLSpeaker *agent_speaker = speaker_mgr->findSpeaker(gAgentID);
+					if (participant_speaker && agent_speaker)
+					{
+						participant_model->setDisplayModeratorRole(agent_speaker->mIsModerator && participant_speaker->mIsModerator);
+					}
+				}
+				current_participant_model++;
+			}
+		}
+	}
+	
+	mConversationViewModel.requestSortAll();
+	if(mConversationsRoot != NULL)
+	{
+		mConversationsRoot->arrangeAll();
+		mConversationsRoot->update();
+	}
+	updateHeaderAndToolbar();
+	refresh();
+}
+
+// Copied from LLFloaterIMContainer::createConversationViewParticipant(). Refactor opportunity!
+LLConversationViewParticipant* LLFloaterIMSessionTab::createConversationViewParticipant(LLConversationItem* item)
+{
+    LLRect panel_rect = mParticipantListPanel->getRect();
+	
+	LLConversationViewParticipant::Params params;
+	params.name = item->getDisplayName();
+	params.root = mConversationsRoot;
+	params.listener = item;
+	params.rect = LLRect (0, 24, panel_rect.getWidth(), 0); // *TODO: use conversation_view_participant.xml itemHeight value in lieu of 24
+	params.tool_tip = params.name;
+	params.participant_id = item->getUUID();
+	
+	return LLUICtrlFactory::create<LLConversationViewParticipant>(params);
+}
+
+void LLFloaterIMSessionTab::setSortOrder(const LLConversationSort& order)
+{
+	mConversationViewModel.setSorter(order);
+	mConversationsRoot->arrangeAll();
+	refreshConversation();
+}
+
+void LLFloaterIMSessionTab::onIMSessionMenuItemClicked(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+
+	if (item == "compact_view" || item == "expanded_view")
+	{
+		gSavedSettings.setBOOL("PlainTextChatHistory", item == "compact_view");
+	}
+	else
+	{
+		bool prev_value = gSavedSettings.getBOOL(item);
+		gSavedSettings.setBOOL(item, !prev_value);
+	}
+
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate();
+}
+
+bool LLFloaterIMSessionTab::onIMCompactExpandedMenuItemCheck(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool is_plain_text_mode = gSavedSettings.getBOOL("PlainTextChatHistory");
+
+	return is_plain_text_mode? item == "compact_view" : item == "expanded_view";
+}
+
+
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemCheck(const LLSD& userdata)
+{
+	return gSavedSettings.getBOOL(userdata.asString());
+}
+
+// enable/disable states for the "show time" and "show names" items of the show-modes menu
+bool LLFloaterIMSessionTab::onIMShowModesMenuItemEnable(const LLSD& userdata)
+{
+	std::string item = userdata.asString();
+	bool plain_text = gSavedSettings.getBOOL("PlainTextChatHistory");
+	bool is_not_names = (item != "IMShowNamesForP2PConv");
+	return (plain_text && (is_not_names || mIsP2PChat));
+}
+
+void LLFloaterIMSessionTab::hideOrShowTitle()
+{
+	const LLFloater::Params& default_params = LLFloater::getDefaultParams();
+	S32 floater_header_size = default_params.header_height;
+	LLView* floater_contents = getChild<LLView>("contents_view");
+
+	LLRect floater_rect = getLocalRect();
+	S32 top_border_of_contents = floater_rect.mTop - (isTornOff()? floater_header_size : 0);
+	LLRect handle_rect (0, floater_rect.mTop, floater_rect.mRight, top_border_of_contents);
+	LLRect contents_rect (0, top_border_of_contents, floater_rect.mRight, floater_rect.mBottom);
+	mDragHandle->setShape(handle_rect);
+	mDragHandle->setVisible(isTornOff());
+	floater_contents->setShape(contents_rect);
+}
+
+void LLFloaterIMSessionTab::updateSessionName(const std::string& name)
+{
+	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + name);
+}
+
+void LLFloaterIMSessionTab::hideAllStandardButtons()
+{
+	for (S32 i = 0; i < BUTTON_COUNT; i++)
+	{
+		if (mButtons[i])
+		{
+			// Hide the standard header buttons in a docked IM floater.
+			mButtons[i]->setVisible(false);
+		}
+	}
+}
+
+void LLFloaterIMSessionTab::updateHeaderAndToolbar()
+{
+	// prevent start conversation before its container
+    LLFloaterIMContainer::getInstance();
+
+	bool is_not_torn_off = !checkIfTornOff();
+	if (is_not_torn_off)
+	{
+		hideAllStandardButtons();
+	}
+
+	hideOrShowTitle();
+
+	// Participant list should be visible only in torn off floaters.
+	bool is_participant_list_visible =
+			!is_not_torn_off
+			&& mIsParticipantListExpanded
+			&& !mIsP2PChat;
+
+	mParticipantListAndHistoryStack->collapsePanel(mParticipantListPanel, !is_participant_list_visible);
+    mParticipantListPanel->setVisible(is_participant_list_visible);
+
+	// Display collapse image (<<) if the floater is hosted
+	// or if it is torn off but has an open control panel.
+	bool is_expanded = is_not_torn_off || is_participant_list_visible;
+    
+	mExpandCollapseBtn->setImageOverlay(getString(is_expanded ? "collapse_icon" : "expand_icon"));
+	mExpandCollapseBtn->setToolTip(
+			is_not_torn_off?
+				getString("expcol_button_not_tearoff_tooltip") :
+				(is_expanded?
+					getString("expcol_button_tearoff_and_expanded_tooltip") :
+					getString("expcol_button_tearoff_and_collapsed_tooltip")));
+
+	// toggle floater's drag handle and title visibility
+	if (mDragHandle)
+	{
+		mDragHandle->setTitleVisible(!is_not_torn_off);
+	}
+
+	// The button (>>) should be disabled for torn off P2P conversations.
+	mExpandCollapseBtn->setEnabled(is_not_torn_off || !mIsP2PChat);
+
+	mTearOffBtn->setImageOverlay(getString(is_not_torn_off? "tear_off_icon" : "return_icon"));
+	mTearOffBtn->setToolTip(getString(is_not_torn_off? "tooltip_to_separate_window" : "tooltip_to_main_window"));
+
+
+	mCloseBtn->setVisible(is_not_torn_off && !mIsNearbyChat);
+
+	enableDisableCallBtn();
+
+	showTranslationCheckbox();
+}
+ 
+void LLFloaterIMSessionTab::forceReshape()
+{
+    LLRect floater_rect = getRect();
+    reshape(llmax(floater_rect.getWidth(), this->getMinWidth()),
+    		llmax(floater_rect.getHeight(), this->getMinHeight()),
+    		true);
+}
+
+
+void LLFloaterIMSessionTab::reshapeChatLayoutPanel()
+{
+	mChatLayoutPanel->reshape(mChatLayoutPanel->getRect().getWidth(), mInputEditor->getRect().getHeight() + mInputEditorPad, FALSE);
+}
+
+void LLFloaterIMSessionTab::showTranslationCheckbox(BOOL show)
+{
+	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(mIsNearbyChat? show : FALSE);
+}
+
+// static
+void LLFloaterIMSessionTab::processChatHistoryStyleUpdate(bool clean_messages/* = false*/)
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+			iter != inst_list.end(); ++iter)
+	{
+		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+		if (floater)
+		{
+			floater->reloadMessages(clean_messages);
+		}
+	}
+
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
+	{
+             nearby_chat->reloadMessages(clean_messages);
+	}
+}
+
+// static
+void LLFloaterIMSessionTab::reloadEmptyFloaters()
+{
+	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
+	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
+		iter != inst_list.end(); ++iter)
+	{
+		LLFloaterIMSession* floater = dynamic_cast<LLFloaterIMSession*>(*iter);
+		if (floater && floater->getLastChatMessageIndex() == -1)
+		{
+			floater->reloadMessages(true);
+		}
+	}
+
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat && nearby_chat->getMessageArchiveLength() == 0)
+	{
+		nearby_chat->reloadMessages(true);
+	}
+}
+
+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"));
+
+	enableDisableCallBtn();
+
+}
+
+void LLFloaterIMSessionTab::onSlide(LLFloaterIMSessionTab* self)
+{
+	LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+	if (host_floater)
+	{
+		// Hide the messages pane if a floater is hosted in the Conversations
+		host_floater->collapseMessagesPane(true);
+	}
+	else ///< floater is torn off
+	{
+		if (!self->mIsP2PChat)
+		{
+            // The state must toggle the collapsed state of the panel
+            bool should_be_expanded = self->mParticipantListPanel->isCollapsed();
+
+			// Update the expand/collapse flag of the participant list panel and save it
+            gSavedSettings.setBOOL("IMShowControlPanel", should_be_expanded);
+            self->mIsParticipantListExpanded = should_be_expanded;
+            
+            // Refresh for immediate feedback
+            self->refreshConversation();
+		}
+	}
+
+	self->assignResizeLimits();
+}
+
+void LLFloaterIMSessionTab::onCollapseToLine(LLFloaterIMSessionTab* self)
+{
+	LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(self->getHost());
+	if (!host_floater)
+	{
+		bool expand = self->isMessagePaneExpanded();
+		self->mExpandCollapseLineBtn->setImageOverlay(self->getString(expand ? "collapseline_icon" : "expandline_icon"));
+		self->mContentPanel->setVisible(!expand);
+		self->mToolbarPanel->setVisible(!expand);
+		self->mInputEditor->enableSingleLineMode(expand);
+		self->reshapeFloater(expand);
+		self->setMessagePaneExpanded(!expand);
+	}
+}
+
+void LLFloaterIMSessionTab::reshapeFloater(bool collapse)
+{
+	LLRect floater_rect = getRect();
+
+	if(collapse)
+	{
+		mFloaterHeight = floater_rect.getHeight();
+		S32 height = mContentPanel->getRect().getHeight() + mToolbarPanel->getRect().getHeight()
+			+ mChatLayoutPanel->getRect().getHeight() - mChatLayoutPanelHeight + 2;
+		floater_rect.mTop -= height;
+	}
+	else
+	{
+		floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+	}
+
+	enableResizeCtrls(true, true, !collapse);
+
+	saveCollapsedState();
+	setShape(floater_rect, true);
+	mBodyStack->updateLayout();
+}
+
+void LLFloaterIMSessionTab::restoreFloater()
+{
+	if(!isMessagePaneExpanded())
+	{
+		if(isMinimized())
+		{
+			setMinimized(false);
+		}
+		mContentPanel->setVisible(true);
+		mToolbarPanel->setVisible(true);
+		LLRect floater_rect = getRect();
+		floater_rect.mTop = floater_rect.mBottom + mFloaterHeight;
+		setShape(floater_rect, true);
+		mBodyStack->updateLayout();
+		mExpandCollapseLineBtn->setImageOverlay(getString("expandline_icon"));
+		setMessagePaneExpanded(true);
+		saveCollapsedState();
+		enableResizeCtrls(true, true, true);
+	}
+}
+
+/*virtual*/
+void LLFloaterIMSessionTab::onOpen(const LLSD& key)
+{
+	if (!checkIfTornOff())
+	{
+		LLFloaterIMContainer* host_floater = dynamic_cast<LLFloaterIMContainer*>(getHost());
+		// Show the messages pane when opening a floater hosted in the Conversations
+		host_floater->collapseMessagesPane(false);
+	}
+
+	mInputButtonPanel->setVisible(isTornOff());
+}
+
+
+void LLFloaterIMSessionTab::onTearOffClicked()
+{
+	restoreFloater();
+	setFollows(isTornOff()? FOLLOWS_ALL : FOLLOWS_NONE);
+    mSaveRect = isTornOff();
+    initRectControl();
+	LLFloater::onClickTearOff(this);
+	LLFloaterIMContainer* container = LLFloaterReg::findTypedInstance<LLFloaterIMContainer>("im_container");
+
+	if (isTornOff())
+	{
+		container->selectAdjacentConversation(false);
+		forceReshape();
+	}
+	//Upon re-docking the torn off floater, select the corresponding conversation line item
+	else
+	{
+		container->selectConversation(mSessionID);
+
+	}
+	mInputButtonPanel->setVisible(isTornOff());
+
+	refreshConversation();
+	updateGearBtn();
+}
+
+void LLFloaterIMSessionTab::updateGearBtn()
+{
+
+	BOOL prevVisibility = mGearBtn->getVisible();
+	mGearBtn->setVisible(checkIfTornOff() && mIsP2PChat);
+
+
+	// Move buttons if Gear button changed visibility
+	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();
+		S32 gap_width = call_btn_rect.mLeft - add_btn_rect.mRight;
+		S32 right_shift = gear_btn_rect.getWidth() + gap_width;
+		if(mGearBtn->getVisible())
+		{
+			// Move buttons to the right to give space for Gear button
+			add_btn_rect.translate(right_shift,0);
+			call_btn_rect.translate(right_shift,0);
+		}
+		else
+		{
+			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);
+	}
+}
+
+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();
+	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);
+}
+
+// static
+bool LLFloaterIMSessionTab::isChatMultiTab()
+{
+	// Restart is required in order to change chat window type.
+	return true;
+}
+
+bool LLFloaterIMSessionTab::checkIfTornOff()
+{
+	bool isTorn = !getHost();
+	
+	if (isTorn != isTornOff())
+	{
+		setTornOff(isTorn);
+		refreshConversation();
+	}
+
+	return isTorn;
+}
+
+void LLFloaterIMSessionTab::doToSelected(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+		
+	// Perform the command (IM, profile, etc...) on the list using the general conversation container method
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	// Note: By construction, those can only be participants so we can call doToParticipants() directly
+	floater_container->doToParticipants(command, selected_uuids);
+}
+
+bool LLFloaterIMSessionTab::enableContextMenuItem(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+	
+	// Perform the item enable test on the list using the general conversation container method
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->enableContextMenuItem(command, selected_uuids);
+}
+
+bool LLFloaterIMSessionTab::checkContextMenuItem(const LLSD& userdata)
+{
+	// Get the list of selected items in the tab
+    std::string command = userdata.asString();
+    uuid_vec_t selected_uuids;
+	getSelectedUUIDs(selected_uuids);
+	
+	// Perform the item check on the list using the general conversation container method
+	LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+	return floater_container->checkContextMenuItem(command, selected_uuids);
+}
+
+void LLFloaterIMSessionTab::getSelectedUUIDs(uuid_vec_t& selected_uuids)
+{
+    const std::set<LLFolderViewItem*> selected_items = mConversationsRoot->getSelectionList();
+	
+    std::set<LLFolderViewItem*>::const_iterator it = selected_items.begin();
+    const std::set<LLFolderViewItem*>::const_iterator it_end = selected_items.end();
+	
+    for (; it != it_end; ++it)
+    {
+        LLConversationItem* conversation_item = static_cast<LLConversationItem *>((*it)->getViewModelItem());
+        selected_uuids.push_back(conversation_item->getUUID());
+    }
+}
+
+LLConversationItem* LLFloaterIMSessionTab::getCurSelectedViewModelItem()
+{
+	LLConversationItem *conversationItem = NULL;
+
+	if(mConversationsRoot && 
+        mConversationsRoot->getCurSelectedItem() && 
+        mConversationsRoot->getCurSelectedItem()->getViewModelItem())
+	{
+		conversationItem = static_cast<LLConversationItem *>(mConversationsRoot->getCurSelectedItem()->getViewModelItem()) ;
+	}
+
+	return conversationItem;
+}
+
+void LLFloaterIMSessionTab::saveCollapsedState()
+{
+	LLFloaterIMSessionTab* conversp = LLFloaterIMSessionTab::getConversation(mSessionID);
+	if(conversp->isNearbyChat())
+	{
+		gSavedPerAccountSettings.setBOOL("NearbyChatIsNotCollapsed", isMessagePaneExpanded());
+	}
+}
+BOOL LLFloaterIMSessionTab::handleKeyHere(KEY key, MASK mask )
+{
+	if(mask == MASK_ALT)
+	{
+		LLFloaterIMContainer* floater_container = LLFloaterIMContainer::getInstance();
+		if (KEY_RETURN == key && !isTornOff())
+		{
+			floater_container->expandConversation();
+		}
+		if ((KEY_UP == key) || (KEY_LEFT == key))
+		{
+			floater_container->selectNextorPreviousConversation(false);
+		}
+		if ((KEY_DOWN == key ) || (KEY_RIGHT == key))
+		{
+			floater_container->selectNextorPreviousConversation(true);
+		}
+	}
+	return TRUE;
+}
diff --git a/indra/newview/llfloaterimsessiontab.h b/indra/newview/llfloaterimsessiontab.h
new file mode 100644
index 0000000000000000000000000000000000000000..302d5a8066f5efed30be8a303a343bdffccd47be
--- /dev/null
+++ b/indra/newview/llfloaterimsessiontab.h
@@ -0,0 +1,216 @@
+/**
+ * @file llfloaterimsessiontab.h
+ * @brief LLFloaterIMSessionTab class implements the common behavior of LNearbyChatBar
+ * @brief and LLFloaterIMSession for hosting both in LLIMContainer
+ *
+ * $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_FLOATERIMSESSIONTAB_H
+#define LL_FLOATERIMSESSIONTAB_H
+
+#include "lllayoutstack.h"
+#include "llparticipantlist.h"
+#include "lltransientdockablefloater.h"
+#include "llviewercontrol.h"
+#include "lleventtimer.h"
+#include "llimview.h"
+#include "llconversationmodel.h"
+#include "llconversationview.h"
+#include "lltexteditor.h"
+
+class LLPanelChatControlPanel;
+class LLChatEntry;
+class LLChatHistory;
+
+class LLFloaterIMSessionTab
+	: public LLTransientDockableFloater
+{
+
+public:
+	LOG_CLASS(LLFloaterIMSessionTab);
+
+	LLFloaterIMSessionTab(const LLSD& session_id);
+	~LLFloaterIMSessionTab();
+
+	// reload all message with new settings of visual modes
+	static void processChatHistoryStyleUpdate(bool clean_messages = false);
+	static void reloadEmptyFloaters();
+
+	/**
+	 * Returns true if chat is displayed in multi tabbed floater
+	 *         false if chat is displayed in multiple windows
+	 */
+	static bool isChatMultiTab();
+
+	// add conversation to container
+	static void addToHost(const LLUUID& session_id);
+
+	bool isHostAttached() {return mIsHostAttached;}
+	void setHostAttached(bool is_attached) {mIsHostAttached = is_attached;}
+
+    static LLFloaterIMSessionTab* findConversation(const LLUUID& uuid);
+    static LLFloaterIMSessionTab* getConversation(const LLUUID& uuid);
+
+	// show/hide the translation check box
+	void showTranslationCheckbox(const BOOL visible = FALSE);
+
+	bool isNearbyChat() {return mIsNearbyChat;}
+
+	// LLFloater overrides
+	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ void setVisible(BOOL visible);
+	/*virtual*/ void setFocus(BOOL focus);
+	
+	// Handle the left hand participant list widgets
+	void addConversationViewParticipant(LLConversationItem* item);
+	void removeConversationViewParticipant(const LLUUID& participant_id);
+	void updateConversationViewParticipant(const LLUUID& participant_id);
+	void refreshConversation();
+	void buildConversationViewParticipant();
+
+	void setSortOrder(const LLConversationSort& order);
+	virtual void onTearOffClicked();
+	void updateGearBtn();
+	void initBtns();
+	virtual void updateMessages() {}
+	LLConversationItem* getCurSelectedViewModelItem();
+	void forceReshape();
+	virtual BOOL handleKeyHere( KEY key, MASK mask );
+	bool isMessagePaneExpanded(){return mMessagePaneExpanded;}
+	void setMessagePaneExpanded(bool expanded){mMessagePaneExpanded = expanded;}
+	void restoreFloater();
+	void saveCollapsedState();
+
+protected:
+
+	// callback for click on any items of the visual states menu
+	void onIMSessionMenuItemClicked(const LLSD& userdata);
+
+	// callback for check/uncheck of the expanded/collapse mode's switcher
+	bool onIMCompactExpandedMenuItemCheck(const LLSD& userdata);
+
+	//
+	bool onIMShowModesMenuItemCheck(const LLSD& userdata);
+	bool onIMShowModesMenuItemEnable(const LLSD& userdata);
+	static void onSlide(LLFloaterIMSessionTab *self);
+	static void onCollapseToLine(LLFloaterIMSessionTab *self);
+	void reshapeFloater(bool collapse);
+
+	// refresh a visual state of the Call button
+	void updateCallBtnState(bool callIsActive);
+
+	void hideOrShowTitle(); // toggle the floater's drag handle
+	void hideAllStandardButtons();
+
+	/// Update floater header and toolbar buttons when hosted/torn off state is toggled.
+	void updateHeaderAndToolbar();
+
+	// Update the input field help text and other places that need the session name
+	virtual void updateSessionName(const std::string& name);
+
+	// set the enable/disable state for the Call button
+	virtual void enableDisableCallBtn();
+
+	// process focus events to set a currently active session
+	/* virtual */ void onFocusLost();
+	/* virtual */ void onFocusReceived();
+
+	// prepare chat's params and out one message to chatHistory
+	void appendMessage(const LLChat& chat, const LLSD &args = 0);
+
+	std::string appendTime();
+	void assignResizeLimits();
+
+	S32  mFloaterExtraWidth;
+
+	bool mIsNearbyChat;
+	bool mIsP2PChat;
+
+	bool mMessagePaneExpanded;
+	bool mIsParticipantListExpanded;
+
+
+	LLIMModel::LLIMSession* mSession;
+
+	// Participants list: model and view
+	LLConversationViewParticipant* createConversationViewParticipant(LLConversationItem* item);
+	
+	LLUUID mSessionID; 
+	LLLayoutStack* mBodyStack;
+	LLLayoutStack* mParticipantListAndHistoryStack;
+	LLLayoutPanel* mParticipantListPanel;	// add the widgets to that see mConversationsListPanel
+	LLLayoutPanel* mRightPartPanel;
+	LLLayoutPanel* mContentPanel;
+	LLLayoutPanel* mToolbarPanel;
+	LLLayoutPanel* mInputButtonPanel;
+	LLParticipantList* getParticipantList();
+	conversations_widgets_map mConversationsWidgets;
+	LLConversationViewModel mConversationViewModel;
+	LLFolderView* mConversationsRoot;
+	LLScrollContainer* mScroller;
+
+    LLOutputMonitorCtrl* mSpeakingIndicator;
+	LLChatHistory* mChatHistory;
+	LLChatEntry* mInputEditor;
+	LLLayoutPanel * mChatLayoutPanel;
+	LLLayoutStack * mInputPanels;
+	
+	LLButton* mExpandCollapseLineBtn;
+	LLButton* mExpandCollapseBtn;
+	LLButton* mTearOffBtn;
+	LLButton* mCloseBtn;
+	LLButton* mGearBtn;
+
+private:
+	// Handling selection and contextual menu
+    void doToSelected(const LLSD& userdata);
+    bool enableContextMenuItem(const LLSD& userdata);
+    bool checkContextMenuItem(const LLSD& userdata);
+	
+    void getSelectedUUIDs(uuid_vec_t& selected_uuids);
+	
+	/// Refreshes the floater at a constant rate.
+	virtual void refresh() = 0;
+
+	/**
+	 * Adjusts chat history height to fit vertically with input chat field
+	 * and avoid overlapping, since input chat field can be vertically expanded.
+	 * Implementation: chat history bottom "follows" top+top_pad of input chat field
+	 */
+	void reshapeChatLayoutPanel();
+
+	bool checkIfTornOff();
+    bool mIsHostAttached;
+    bool mHasVisibleBeenInitialized;
+
+	LLTimer* mRefreshTimer; ///< Defines the rate at which refresh() is called.
+
+	S32 mInputEditorPad;
+	S32 mChatLayoutPanelHeight;
+	S32 mFloaterHeight;
+};
+
+
+#endif /* LL_FLOATERIMSESSIONTAB_H */
diff --git a/indra/newview/llfloaterinspect.cpp b/indra/newview/llfloaterinspect.cpp
index cece8d299cc8ed2ea715828d7732a1edea325cb3..5a1dfc99ab53b95714ac909af9de28c39e555d50 100644
--- a/indra/newview/llfloaterinspect.cpp
+++ b/indra/newview/llfloaterinspect.cpp
@@ -46,7 +46,9 @@
 
 LLFloaterInspect::LLFloaterInspect(const LLSD& key)
   : LLFloater(key),
-	mDirty(FALSE)
+	mDirty(FALSE),
+	mOwnerNameCacheConnection(),
+	mCreatorNameCacheConnection()
 {
 	mCommitCallbackRegistrar.add("Inspect.OwnerProfile",	boost::bind(&LLFloaterInspect::onClickOwnerProfile, this));
 	mCommitCallbackRegistrar.add("Inspect.CreatorProfile",	boost::bind(&LLFloaterInspect::onClickCreatorProfile, this));
@@ -67,6 +69,14 @@ BOOL LLFloaterInspect::postBuild()
 
 LLFloaterInspect::~LLFloaterInspect(void)
 {
+	if (mOwnerNameCacheConnection.connected())
+	{
+		mOwnerNameCacheConnection.disconnect();
+	}
+	if (mCreatorNameCacheConnection.connected())
+	{
+		mCreatorNameCacheConnection.disconnect();
+	}
 	if(!LLFloaterReg::instanceVisible("build"))
 	{
 		if(LLToolMgr::getInstance()->getBaseTool() == LLToolCompInspect::getInstance())
@@ -80,7 +90,6 @@ LLFloaterInspect::~LLFloaterInspect(void)
 	{
 		LLFloaterReg::showInstance("build", LLSD(), TRUE);
 	}
-	//sInstance = NULL;
 }
 
 void LLFloaterInspect::onOpen(const LLSD& key)
@@ -167,15 +176,6 @@ LLUUID LLFloaterInspect::getSelectedUUID()
 	return LLUUID::null;
 }
 
-void LLFloaterInspect::onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr)
-{
-	if (FloaterPtr)
-	{
-		LLFloaterInspect* floater = (LLFloaterInspect*)FloaterPtr;
-		floater->dirty();
-	}
-}
-
 void LLFloaterInspect::refresh()
 {
 	LLUUID creator_id;
@@ -229,7 +229,11 @@ void LLFloaterInspect::refresh()
 		else
 		{
 			owner_name = LLTrans::getString("RetrievingData");
-			LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+			if (mOwnerNameCacheConnection.connected())
+			{
+				mOwnerNameCacheConnection.disconnect();
+			}
+			mOwnerNameCacheConnection = LLAvatarNameCache::get(idOwner, boost::bind(&LLFloaterInspect::onGetOwnerNameCallback, this));
 		}
 
 		if (LLAvatarNameCache::get(idCreator, &av_name))
@@ -239,7 +243,11 @@ void LLFloaterInspect::refresh()
 		else
 		{
 			creator_name = LLTrans::getString("RetrievingData");
-			LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetAvNameCallback, _1, _2, this));
+			if (mCreatorNameCacheConnection.connected())
+			{
+				mCreatorNameCacheConnection.disconnect();
+			}
+			mCreatorNameCacheConnection = LLAvatarNameCache::get(idCreator, boost::bind(&LLFloaterInspect::onGetCreatorNameCallback, this));
 		}
 		
 		row["id"] = obj->getObject()->getID();
@@ -289,6 +297,18 @@ void LLFloaterInspect::dirty()
 	setDirty();
 }
 
+void LLFloaterInspect::onGetOwnerNameCallback()
+{
+	mOwnerNameCacheConnection.disconnect();
+	setDirty();
+}
+
+void LLFloaterInspect::onGetCreatorNameCallback()
+{
+	mCreatorNameCacheConnection.disconnect();
+	setDirty();
+}
+
 void LLFloaterInspect::draw()
 {
 	if (mDirty)
diff --git a/indra/newview/llfloaterinspect.h b/indra/newview/llfloaterinspect.h
index 7ee83ccdb47060e3c6837928a06601872da27782..44381eac96f27cf64919fcae7469ba5e9ebb2dd8 100644
--- a/indra/newview/llfloaterinspect.h
+++ b/indra/newview/llfloaterinspect.h
@@ -55,8 +55,6 @@ class LLFloaterInspect : public LLFloater
 	void onClickOwnerProfile();
 	void onSelectObject();
 
-	static void onGetAvNameCallback(const LLUUID& idCreator, const LLAvatarName& av_name, void* FloaterPtr);
-
 	LLScrollListCtrl* mObjectList;
 protected:
 	// protected members
@@ -64,13 +62,15 @@ class LLFloaterInspect : public LLFloater
 	bool mDirty;
 
 private:
+	void onGetOwnerNameCallback();
+	void onGetCreatorNameCallback();
 	
 	LLFloaterInspect(const LLSD& key);
 	virtual ~LLFloaterInspect(void);
-	// static data
-//	static LLFloaterInspect* sInstance;
 
 	LLSafeHandle<LLObjectSelection> mObjectSelection;
+	boost::signals2::connection mOwnerNameCacheConnection;
+	boost::signals2::connection mCreatorNameCacheConnection;
 };
 
 #endif //LL_LLFLOATERINSPECT_H
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index be743d57d25afc5ef8b3cc0c1d0e18879c2fd9ed..8290494c229c7d596e03e1d26e02ee5c839c01c2 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -557,7 +557,7 @@ void LLPanelLandGeneral::refresh()
 		BOOL is_leased = (LLParcel::OS_LEASED == parcel->getOwnershipStatus());
 		BOOL region_xfer = FALSE;
 		if(regionp
-		   && !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL))
+		   && !(regionp->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)))
 		{
 			region_xfer = TRUE;
 		}
@@ -1046,6 +1046,8 @@ void LLPanelLandGeneral::onCommitAny(LLUICtrl *ctrl, void *userdata)
 void LLPanelLandGeneral::onClickSellLand(void* data)
 {
 	LLViewerParcelMgr::getInstance()->startSellLand();
+	LLPanelLandGeneral *panelp = (LLPanelLandGeneral *)data;
+	panelp->refresh();
 }
 
 // static
@@ -2118,7 +2120,7 @@ void LLPanelLandOptions::refreshSearch()
 			LLViewerParcelMgr::isParcelModifiableByAgent(
 				parcel, GP_LAND_CHANGE_IDENTITY)
 			&& region
-			&& !(region->getRegionFlags() & REGION_FLAGS_BLOCK_PARCEL_SEARCH);
+			&& !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH));
 
 	// There is a bug with this panel whereby the Show Directory bit can be 
 	// slammed off by the Region based on an override.  Since this data is cached
@@ -2734,11 +2736,13 @@ void LLPanelLandAccess::onCommitAny(LLUICtrl *ctrl, void *userdata)
 
 void LLPanelLandAccess::onClickAddAccess()
 {
+    LLView * button = findChild<LLButton>("add_allowed");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-		boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1));
+		boost::bind(&LLPanelLandAccess::callbackAvatarCBAccess, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
@@ -2783,11 +2787,13 @@ void LLPanelLandAccess::onClickRemoveAccess(void* data)
 // static
 void LLPanelLandAccess::onClickAddBanned()
 {
+    LLView * button = findChild<LLButton>("add_banned");
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
 	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-		boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1));
+		boost::bind(&LLPanelLandAccess::callbackAvatarCBBanned, this, _1), FALSE, FALSE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
@@ -2867,7 +2873,7 @@ void LLPanelLandCovenant::refresh()
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -2880,7 +2886,7 @@ void LLPanelLandCovenant::refresh()
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp
index ea839e6f5a5023a3e91c5d36cccbaa73a9332c8a..100f1d580b96e0ea05ed425a62e03d799b8cc717 100755
--- a/indra/newview/llfloatermodelpreview.cpp
+++ b/indra/newview/llfloatermodelpreview.cpp
@@ -760,7 +760,6 @@ void LLFloaterModelPreview::onLODParamCommit(S32 lod, bool enforce_tri_limit)
 void LLFloaterModelPreview::draw()
 {
 	LLFloater::draw();
-	LLRect r = getRect();
 
 	mModelPreview->update();
 
@@ -1684,7 +1683,6 @@ bool LLModelLoader::doLoadModel()
 						
 						//If no skeleton, do a breadth-first search to get at specific joints
 						bool rootNode = false;
-						bool skeletonWithNoRootNode = false;
 						
 						//Need to test for a skeleton that does not have a root node
 						//This occurs when your instance controller does not have an associated scene 
@@ -1695,10 +1693,6 @@ bool LLModelLoader::doLoadModel()
 							{
 								rootNode = true;
 							}
-							else 
-							{
-								skeletonWithNoRootNode = true;
-							}
 
 						}
 						if ( !pSkeleton || !rootNode )
@@ -2502,7 +2496,7 @@ void LLModelLoader::loadTextures()
 				if(!material.mDiffuseMapFilename.empty())
 				{
 					material.mDiffuseMap = 
-						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, TRUE, LLViewerTexture::BOOST_PREVIEW);
+						LLViewerTextureManager::getFetchedTextureFromUrl("file://" + material.mDiffuseMapFilename, FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_PREVIEW);
 					material.mDiffuseMap->setLoadedCallback(LLModelPreview::textureLoadedCallback, 0, TRUE, FALSE, mPreview, NULL, FALSE);
 					material.mDiffuseMap->forceToSaveRawImage(0, F32_MAX);
 					mNumOfFetchingTextures++ ;
@@ -5020,16 +5014,9 @@ BOOL LLModelPreview::render()
 	bool upload_skin = mFMP->childGetValue("upload_skin").asBoolean();	
 	bool upload_joints = mFMP->childGetValue("upload_joints").asBoolean();
 
-	bool resetJoints = false;
 	if ( upload_joints != mLastJointUpdate )
 	{
-		if ( mLastJointUpdate )
-		{
-			resetJoints = true;
-		}
-
 		mLastJointUpdate = upload_joints;
-
 	}
 
 	for (LLModelLoader::scene::iterator iter = mScene[mPreviewLOD].begin(); iter != mScene[mPreviewLOD].end(); ++iter)
diff --git a/indra/newview/llfloaternotificationsconsole.cpp b/indra/newview/llfloaternotificationsconsole.cpp
index 2681d4b34d2964de520e8f0d8e73a8cbccc01bfa..4f35c325a872e0d5bf4b94e6c12612743ca15a05 100644
--- a/indra/newview/llfloaternotificationsconsole.cpp
+++ b/indra/newview/llfloaternotificationsconsole.cpp
@@ -44,21 +44,16 @@ class LLNotificationChannelPanel : public LLLayoutPanel
 	BOOL postBuild();
 
 private:
-	bool update(const LLSD& payload, bool passed_filter);
+	bool update(const LLSD& payload);
 	static void toggleClick(void* user_data);
 	static void onClickNotification(void* user_data);
-	static void onClickNotificationReject(void* user_data);
 	LLNotificationChannelPtr mChannelPtr;
-	LLNotificationChannelPtr mChannelRejectsPtr;
 };
 
 LLNotificationChannelPanel::LLNotificationChannelPanel(const LLNotificationChannelPanel::Params& p) 
 :	LLLayoutPanel(p)
 {
 	mChannelPtr = LLNotifications::instance().getChannel(p.name);
-	mChannelRejectsPtr = LLNotificationChannelPtr(
-		LLNotificationChannel::buildChannel(p.name() + "rejects", mChannelPtr->getParentChannelName(),
-											!boost::bind(mChannelPtr->getFilter(), _1)));
 	buildFromFile( "panel_notifications_channel.xml");
 }
 
@@ -68,15 +63,11 @@ BOOL LLNotificationChannelPanel::postBuild()
 	header_button->setLabel(mChannelPtr->getName());
 	header_button->setClickedCallback(toggleClick, this);
 
-	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, true));
-	mChannelRejectsPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1, false));
+	mChannelPtr->connectChanged(boost::bind(&LLNotificationChannelPanel::update, this, _1));
 
 	LLScrollListCtrl* scroll = getChild<LLScrollListCtrl>("notifications_list");
 	scroll->setDoubleClickCallback(onClickNotification, this);
 	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
-	scroll = getChild<LLScrollListCtrl>("notification_rejects_list");
-	scroll->setDoubleClickCallback(onClickNotificationReject, this);
-	scroll->setRect(LLRect( getRect().mLeft, getRect().mTop, getRect().mRight, 0));
 	return TRUE;
 }
 
@@ -97,8 +88,6 @@ void LLNotificationChannelPanel::toggleClick(void *user_data)
 	// turn off tab stop for collapsed panel
 	self->getChild<LLScrollListCtrl>("notifications_list")->setTabStop(!header_button->getToggleState());
 	self->getChild<LLScrollListCtrl>("notifications_list")->setVisible(!header_button->getToggleState());
-	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setTabStop(!header_button->getToggleState());
-	self->getChild<LLScrollListCtrl>("notification_rejects_list")->setVisible(!header_button->getToggleState());
 }
 
 /*static*/
@@ -118,24 +107,7 @@ void LLNotificationChannelPanel::onClickNotification(void* user_data)
 	}
 }
 
-/*static*/
-void LLNotificationChannelPanel::onClickNotificationReject(void* user_data)
-{
-	LLNotificationChannelPanel* self = (LLNotificationChannelPanel*)user_data;
-	if (!self) return;
-	LLScrollListItem* firstselected = self->getChild<LLScrollListCtrl>("notification_rejects_list")->getFirstSelected();
-	llassert(firstselected);
-	if (firstselected)
-	{
-		void* data = firstselected->getUserdata();
-		if (data)
-		{
-			gFloaterView->getParentFloater(self)->addDependentFloater(new LLFloaterNotification((LLNotification*)data), TRUE);
-		}
-	}
-}
-
-bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
+bool LLNotificationChannelPanel::update(const LLSD& payload)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(payload["id"].asUUID());
 	if (notification)
@@ -151,9 +123,7 @@ bool LLNotificationChannelPanel::update(const LLSD& payload, bool passed_filter)
 		row["columns"][2]["column"] = "date";
 		row["columns"][2]["type"] = "date";
 
-		LLScrollListItem* sli = passed_filter ? 
-			getChild<LLScrollListCtrl>("notifications_list")->addElement(row) :
-			getChild<LLScrollListCtrl>("notification_rejects_list")->addElement(row);
+		LLScrollListItem* sli = getChild<LLScrollListCtrl>("notifications_list")->addElement(row);
 		sli->setUserdata(&(*notification));
 	}
 
diff --git a/indra/newview/llfloateroutbox.cpp b/indra/newview/llfloateroutbox.cpp
index 540f977305f08c1d9023c8304602009ce117bbca..29a3e6ac3a020bfa16283167ecd85eeef5ba897c 100644
--- a/indra/newview/llfloateroutbox.cpp
+++ b/indra/newview/llfloateroutbox.cpp
@@ -44,14 +44,17 @@
 #include "llviewernetwork.h"
 #include "llwindowshade.h"
 
-#define USE_WINDOWSHADE_DIALOGS	0
-
 
 ///----------------------------------------------------------------------------
 /// LLOutboxNotification class
 ///----------------------------------------------------------------------------
 
-bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& notify)
+LLNotificationsUI::LLOutboxNotification::LLOutboxNotification()
+	: LLSystemNotificationHandler("Outbox", "outbox")
+{
+}
+
+bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLNotificationPtr& notify)
 {
 	LLFloaterOutbox* outbox_floater = LLFloaterReg::getTypedInstance<LLFloaterOutbox>("outbox");
 	
@@ -60,6 +63,14 @@ bool LLNotificationsUI::LLOutboxNotification::processNotification(const LLSD& no
 	return false;
 }
 
+void LLNotificationsUI::LLOutboxNotification::onDelete(LLNotificationPtr p)
+{
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	if (notification_handler)
+	{
+		notification_handler->onDelete(p);
+	}
+}
 
 ///----------------------------------------------------------------------------
 /// LLOutboxAddedObserver helper class
@@ -168,9 +179,8 @@ void LLFloaterOutbox::onOpen(const LLSD& key)
 	if (mOutboxId.isNull())
 	{
 		const bool do_not_create_folder = false;
-		const bool do_not_find_in_library = false;
 		
-		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder, do_not_find_in_library);
+		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, do_not_create_folder);
 		
 		if (outbox_id.isNull())
 		{
@@ -244,8 +254,9 @@ void LLFloaterOutbox::setupOutbox(const LLUUID& outboxId)
 	mOutboxInventoryPanel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	mOutboxInventoryPanel->setSortOrder(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
-	mOutboxInventoryPanel->getFilter()->markDefault();
+
+	mOutboxInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_FOLDERS_BY_NAME);	
+	mOutboxInventoryPanel->getFilter().markDefault();
 	
 	fetchOutboxContents();
 	
@@ -380,7 +391,7 @@ BOOL LLFloaterOutbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 	// Determine if the mouse is inside the inventory panel itself or just within the floater
 	bool pointInInventoryPanel = false;
 	bool pointInInventoryPanelChild = false;
-	LLFolderView * root_folder = mOutboxInventoryPanel->getRootFolder();
+	LLFolderView* root_folder = mOutboxInventoryPanel->getRootFolder();
 	if (mOutboxInventoryPanel->getVisible())
 	{
 		S32 inv_x, inv_y;
@@ -437,10 +448,10 @@ void LLFloaterOutbox::onOutboxChanged()
 {
 	llassert(!mOutboxId.isNull());
 	
-	if (mOutboxInventoryPanel)
-	{
-		mOutboxInventoryPanel->requestSort();
-	}
+	//if (mOutboxInventoryPanel)
+	//{
+	//	mOutboxInventoryPanel->requestSort();
+	//}
 
 	fetchOutboxContents();
 
@@ -516,52 +527,11 @@ void LLFloaterOutbox::initializationReportError(U32 status, const LLSD& content)
 	updateView();
 }
 
-void LLFloaterOutbox::showNotification(const LLSD& notify)
+void LLFloaterOutbox::showNotification(const LLNotificationPtr& notification)
 {
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	
-	if (!notification)
-	{
-		llerrs << "Unable to find outbox notification!" << notify.asString() << llendl;
-		
-		return;
-	}
-
-#if USE_WINDOWSHADE_DIALOGS
-
-	if (mWindowShade)
-	{
-		delete mWindowShade;
-	}
-	
-	LLRect floater_rect = getLocalRect();
-	floater_rect.mTop -= getHeaderHeight();
-	floater_rect.stretch(-5, 0);
-	
-	LLWindowShade::Params params;
-	params.name = "notification_shade";
-	params.rect = floater_rect;
-	params.follows.flags = FOLLOWS_ALL;
-	params.modal = true;
-	params.can_close = false;
-	params.shade_color = LLColor4::white % 0.25f;
-	params.text_color = LLColor4::white;
-	
-	mWindowShade = LLUICtrlFactory::create<LLWindowShade>(params);
-	
-	addChild(mWindowShade);
-	mWindowShade->show(notification);
-	
-#else
-	
-	LLNotificationsUI::LLEventHandler * handler =
-		LLNotificationsUI::LLNotificationManager::instance().getHandlerForNotification("alertmodal");
-	
-	LLNotificationsUI::LLSysHandler * sys_handler = dynamic_cast<LLNotificationsUI::LLSysHandler *>(handler);
-	llassert(sys_handler);
-	
-	sys_handler->processNotification(notify);
+	LLNotificationsUI::LLNotificationHandler * notification_handler = dynamic_cast<LLNotificationsUI::LLNotificationHandler*>(LLNotifications::instance().getChannel("AlertModal").get());
+	llassert(notification_handler);
 	
-#endif
+	notification_handler->processNotification(notification);
 }
 
diff --git a/indra/newview/llfloateroutbox.h b/indra/newview/llfloateroutbox.h
index 18baccf1c95e75ae3c74dacdf3675fcb8cba4734..a91d8c113991be8e657b560791bc6289f164e819 100644
--- a/indra/newview/llfloateroutbox.h
+++ b/indra/newview/llfloateroutbox.h
@@ -64,7 +64,7 @@ class LLFloaterOutbox : public LLFloater
 						   EAcceptance* accept,
 						   std::string& tooltip_msg);
 	
-	void showNotification(const LLSD& notify);
+	void showNotification(const LLNotificationPtr& notification);
 
 	BOOL handleHover(S32 x, S32 y, MASK mask);
 	void onMouseLeave(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 542e96cf169cb6eb575d6aaf62b8fc4a7909fc71..bbf88060c1963c0601e1218d31312bd786cca8bb 100755
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -51,11 +51,11 @@
 #include "llfloaterabout.h"
 #include "llfloaterhardwaresettings.h"
 #include "llfloatersidepanelcontainer.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llkeyboard.h"
 #include "llmodaldialog.h"
 #include "llnavigationbar.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llnotificationtemplate.h"
@@ -306,7 +306,8 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mAvatarDataInitialized(false),
 	mClickActionDirty(false)
 {
-	
+	LLConversationLog::instance().addObserver(this);
+
 	//Build Floater is now Called from 	LLFloaterReg::add("preferences", "floater_preferences.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterPreference>);
 	
 	static bool registered_dialog = false;
@@ -329,8 +330,6 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 	mCommitCallbackRegistrar.add("Pref.VoiceSetKey",			boost::bind(&LLFloaterPreference::onClickSetKey, this));
 	mCommitCallbackRegistrar.add("Pref.VoiceSetMiddleMouse",	boost::bind(&LLFloaterPreference::onClickSetMiddleMouse, this));
 	mCommitCallbackRegistrar.add("Pref.SetSounds",				boost::bind(&LLFloaterPreference::onClickSetSounds, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickSkipDialogs",		boost::bind(&LLFloaterPreference::onClickSkipDialogs, this));
-//	mCommitCallbackRegistrar.add("Pref.ClickResetDialogs",		boost::bind(&LLFloaterPreference::onClickResetDialogs, this));
 	mCommitCallbackRegistrar.add("Pref.ClickEnablePopup",		boost::bind(&LLFloaterPreference::onClickEnablePopup, this));
 	mCommitCallbackRegistrar.add("Pref.ClickDisablePopup",		boost::bind(&LLFloaterPreference::onClickDisablePopup, this));	
 	mCommitCallbackRegistrar.add("Pref.LogPath",				boost::bind(&LLFloaterPreference::onClickLogPath, this));
@@ -351,13 +350,16 @@ LLFloaterPreference::LLFloaterPreference(const LLSD& key)
 
 	sSkin = gSavedSettings.getString("SkinCurrent");
 
-	mCommitCallbackRegistrar.add("Pref.ClickActionChange",				boost::bind(&LLFloaterPreference::onClickActionChange, this));
+	mCommitCallbackRegistrar.add("Pref.ClickActionChange",		boost::bind(&LLFloaterPreference::onClickActionChange, this));
 
 	gSavedSettings.getControl("NameTagShowUsernames")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("NameTagShowFriends")->getCommitSignal()->connect(boost::bind(&handleNameTagOptionChanged,  _2));	
 	gSavedSettings.getControl("UseDisplayNames")->getCommitSignal()->connect(boost::bind(&handleDisplayNamesOptionChanged,  _2));
 	
 	LLAvatarPropertiesProcessor::getInstance()->addObserver( gAgent.getID(), this );
+
+	mCommitCallbackRegistrar.add("Pref.ClearLog",				boost::bind(&LLConversationLog::onClearLog, &LLConversationLog::instance()));
+	mCommitCallbackRegistrar.add("Pref.DeleteTranscripts",      boost::bind(&LLFloaterPreference::onDeleteTranscripts, this));
 }
 
 void LLFloaterPreference::processProperties( void* pData, EAvatarProcessorType type )
@@ -425,13 +427,7 @@ void LLFloaterPreference::saveAvatarProperties( void )
 
 BOOL LLFloaterPreference::postBuild()
 {
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
-
-	gSavedSettings.getControl("PlainTextChatHistory")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLIMFloater::processChatHistoryStyleUpdate, _2));
-
-	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLNearbyChat::processChatHistoryStyleUpdate, _2));
+	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLFloaterIMSessionTab::processChatHistoryStyleUpdate, false));
 
 	gSavedSettings.getControl("ChatFontSize")->getSignal()->connect(boost::bind(&LLViewerChat::signalChatFontChanged));
 
@@ -447,28 +443,45 @@ BOOL LLFloaterPreference::postBuild()
 	std::string cache_location = gDirUtilp->getExpandedFilename(LL_PATH_CACHE, "");
 	setCacheLocation(cache_location);
 
+	getChild<LLUICtrl>("log_path_string")->setEnabled(FALSE); // make it read-only but selectable
+
 	getChild<LLComboBox>("language_combobox")->setCommitCallback(boost::bind(&LLFloaterPreference::onLanguageChange, this));
 
-	// if floater is opened before login set default localized busy message
+	getChild<LLComboBox>("FriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"FriendIMOptions"));
+	getChild<LLComboBox>("NonFriendIMOptions")->setCommitCallback(boost::bind(&LLFloaterPreference::onNotificationsChange, this,"NonFriendIMOptions"));
+	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"));
+
+	// if floater is opened before login set default localized do not disturb message
 	if (LLStartUp::getStartupState() < STATE_STARTED)
 	{
-		gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+		gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 	}
 
+	// set 'enable' property for 'Clear log...' button
+	changed();
+
+	LLLogChat::setSaveHistorySignal(boost::bind(&LLFloaterPreference::onLogChatHistorySaved, this));
+
 	return TRUE;
 }
 
-void LLFloaterPreference::onBusyResponseChanged()
+void LLFloaterPreference::updateDeleteTranscriptsButton()
 {
-	// set "BusyResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
-	if (LLTrans::getString("BusyModeResponseDefault") != getChild<LLUICtrl>("busy_response")->getValue().asString())
-	{
-		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", TRUE );
-	}
-	else
-	{
-		gSavedPerAccountSettings.setBOOL("BusyResponseChanged", FALSE );
-	}
+	std::vector<std::string> list_of_transcriptions_file_names;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions_file_names);
+	getChild<LLButton>("delete_transcripts")->setEnabled(list_of_transcriptions_file_names.size() > 0);
+}
+
+void LLFloaterPreference::onDoNotDisturbResponseChanged()
+{
+	// set "DoNotDisturbResponseChanged" TRUE if user edited message differs from default, FALSE otherwise
+	bool response_changed_flag =
+			LLTrans::getString("DoNotDisturbModeResponseDefault")
+					!= getChild<LLUICtrl>("do_not_disturb_response")->getValue().asString();
+
+	gSavedPerAccountSettings.setBOOL("DoNotDisturbResponseChanged", response_changed_flag );
 }
 
 LLFloaterPreference::~LLFloaterPreference()
@@ -479,6 +492,8 @@ LLFloaterPreference::~LLFloaterPreference()
 	{
 		ctrl_window_size->setCurrentByIndex(i);
 	}
+
+	LLConversationLog::instance().removeObserver(this);
 }
 
 void LLFloaterPreference::draw()
@@ -543,7 +558,7 @@ void LLFloaterPreference::apply()
 	
 	LLViewerMedia::setCookiesEnabled(getChild<LLUICtrl>("cookies_enabled")->getValue());
 	
-	if (hasChild("web_proxy_enabled") &&hasChild("web_proxy_editor") && hasChild("web_proxy_port"))
+	if (hasChild("web_proxy_enabled", TRUE) &&hasChild("web_proxy_editor", TRUE) && hasChild("web_proxy_port", TRUE))
 	{
 		bool proxy_enable = getChild<LLUICtrl>("web_proxy_enabled")->getValue();
 		std::string proxy_address = getChild<LLUICtrl>("web_proxy_editor")->getValue();
@@ -551,14 +566,8 @@ void LLFloaterPreference::apply()
 		LLViewerMedia::setProxyConfig(proxy_enable, proxy_address, proxy_port);
 	}
 	
-//	LLWString busy_response = utf8str_to_wstring(getChild<LLUICtrl>("busy_response")->getValue().asString());
-//	LLWStringUtil::replaceTabsWithSpaces(busy_response, 4);
-
-	gSavedSettings.setBOOL("PlainTextChatHistory", getChild<LLUICtrl>("plain_text_chat_history")->getValue().asBoolean());
-	
 	if (mGotPersonalInfo)
 	{ 
-//		gSavedSettings.setString("BusyModeResponse2", std::string(wstring_to_utf8str(busy_response)));
 		bool new_im_via_email = getChild<LLUICtrl>("send_im_to_email")->getValue().asBoolean();
 		bool new_hide_online = getChild<LLUICtrl>("online_visibility")->getValue().asBoolean();		
 	
@@ -644,21 +653,21 @@ void LLFloaterPreference::cancel()
 void LLFloaterPreference::onOpen(const LLSD& key)
 {
 	
-	// this variable and if that follows it are used to properly handle busy mode response message
+	// this variable and if that follows it are used to properly handle do not disturb mode response message
 	static bool initialized = FALSE;
-	// if user is logged in and we haven't initialized busy_response yet, do it
+	// if user is logged in and we haven't initialized do not disturb mode response yet, do it
 	if (!initialized && LLStartUp::getStartupState() == STATE_STARTED)
 	{
-		// Special approach is used for busy response localization, because "BusyModeResponse" is
+		// Special approach is used for do not disturb response localization, because "DoNotDisturbModeResponse" is
 		// in non-localizable xml, and also because it may be changed by user and in this case it shouldn't be localized.
-		// To keep track of whether busy response is default or changed by user additional setting BusyResponseChanged
+		// To keep track of whether do not disturb response is default or changed by user additional setting DoNotDisturbResponseChanged
 		// was added into per account settings.
 
 		// initialization should happen once,so setting variable to TRUE
 		initialized = TRUE;
-		// this connection is needed to properly set "BusyResponseChanged" setting when user makes changes in
-		// busy response message.
-		gSavedPerAccountSettings.getControl("BusyModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onBusyResponseChanged, this));
+		// this connection is needed to properly set "DoNotDisturbResponseChanged" setting when user makes changes in
+		// do not disturb response message.
+		gSavedPerAccountSettings.getControl("DoNotDisturbModeResponse")->getSignal()->connect(boost::bind(&LLFloaterPreference::onDoNotDisturbResponseChanged, this));
 	}
 	gAgent.sendAgentUserInfoRequest();
 
@@ -705,6 +714,14 @@ void LLFloaterPreference::onOpen(const LLSD& key)
 	// while preferences floater was closed.
 	buildPopupLists();
 
+
+	//get the options that were checked
+	onNotificationsChange("FriendIMOptions");
+	onNotificationsChange("NonFriendIMOptions");
+	onNotificationsChange("ConferenceIMOptions");
+	onNotificationsChange("GroupChatOptions");
+	onNotificationsChange("NearbyChatOptions");
+
 	LLPanelLogin::setAlwaysRefresh(true);
 	refresh();
 	
@@ -720,12 +737,12 @@ void LLFloaterPreference::onVertexShaderEnable()
 }
 
 //static
-void LLFloaterPreference::initBusyResponse()
+void LLFloaterPreference::initDoNotDisturbResponse()
 	{
-		if (!gSavedPerAccountSettings.getBOOL("BusyResponseChanged"))
+		if (!gSavedPerAccountSettings.getBOOL("DoNotDisturbResponseChanged"))
 		{
-			//LLTrans::getString("BusyModeResponseDefault") is used here for localization (EXT-5885)
-			gSavedPerAccountSettings.setString("BusyModeResponse", LLTrans::getString("BusyModeResponseDefault"));
+			//LLTrans::getString("DoNotDisturbModeResponseDefault") is used here for localization (EXT-5885)
+			gSavedPerAccountSettings.setString("DoNotDisturbModeResponse", LLTrans::getString("DoNotDisturbModeResponseDefault"));
 		}
 	}
 
@@ -780,8 +797,31 @@ void LLFloaterPreference::onBtnOK()
 		apply();
 		closeFloater(false);
 
+		//Conversation transcript and log path changed so reload conversations based on new location
+		if(mPriorInstantMessageLogPath.length())
+		{
+			if(moveTranscriptsAndLog())
+			{
+				//When floaters are empty but have a chat history files, reload chat history into them
+				LLFloaterIMSessionTab::reloadEmptyFloaters();
+			}
+			//Couldn't move files so restore the old path and show a notification
+			else
+			{
+				gSavedPerAccountSettings.setString("InstantMessageLogPath", mPriorInstantMessageLogPath);
+				LLNotificationsUtil::add("PreferenceChatPathChanged");
+			}
+			mPriorInstantMessageLogPath.clear();
+		}
+
 		LLUIColorTable::instance().saveUserSettings();
 		gSavedSettings.saveToFile(gSavedSettings.getString("ClientSettingsFile"), TRUE);
+		
+		//Only save once logged in and loaded per account settings
+		if(mGotPersonalInfo)
+		{
+			gSavedPerAccountSettings.saveToFile(gSavedSettings.getString("PerAccountSettingsFile"), TRUE);
+	}
 	}
 	else
 	{
@@ -834,12 +874,12 @@ void LLFloaterPreference::onBtnCancel()
 }
 
 // static 
-void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::updateUserInfo(const std::string& visibility, bool im_via_email)
 {
 	LLFloaterPreference* instance = LLFloaterReg::findTypedInstance<LLFloaterPreference>("preferences");
 	if (instance)
 	{
-		instance->setPersonalInfo(visibility, im_via_email, email);	
+		instance->setPersonalInfo(visibility, im_via_email);	
 	}
 }
 
@@ -881,6 +921,23 @@ void LLFloaterPreference::onLanguageChange()
 	}
 }
 
+void LLFloaterPreference::onNotificationsChange(const std::string& OptionName)
+{
+	mNotificationOptions[OptionName] = getChild<LLComboBox>(OptionName)->getSelectedItemLabel();
+
+	bool show_notifications_alert = true;
+	for (notifications_map::iterator it_notification = mNotificationOptions.begin(); it_notification != mNotificationOptions.end(); it_notification++)
+	{
+		if(it_notification->second != "None")
+		{
+			show_notifications_alert = false;
+			break;
+		}
+	}
+
+	getChild<LLTextBox>("notifications_alert")->setVisible(show_notifications_alert);
+}
+
 void LLFloaterPreference::onNameTagOpacityChange(const LLSD& newvalue)
 {
 	LLColorSwatchCtrl* color_swatch = findChild<LLColorSwatchCtrl>("background");
@@ -1402,17 +1459,94 @@ void LLFloaterPreference::setAllIgnored()
 void LLFloaterPreference::onClickLogPath()
 {
 	std::string proposed_name(gSavedPerAccountSettings.getString("InstantMessageLogPath"));	 
+	mPriorInstantMessageLogPath.clear();
 	
 	LLDirPicker& picker = LLDirPicker::instance();
+	//Launches a directory picker and waits for feedback
 	if (!picker.getDir(&proposed_name ) )
 	{
 		return; //Canceled!
 	}
 
-	gSavedPerAccountSettings.setString("InstantMessageLogPath", picker.getDirName());
+	//Gets the path from the directory picker
+	std::string dir_name = picker.getDirName();
+
+	//Path changed
+	if(proposed_name != dir_name)
+	{
+	gSavedPerAccountSettings.setString("InstantMessageLogPath", dir_name);
+		mPriorInstantMessageLogPath = proposed_name;
+	
+	// enable/disable 'Delete transcripts button
+	updateDeleteTranscriptsButton();
+}
+}
+
+bool LLFloaterPreference::moveTranscriptsAndLog()
+{
+	std::string instantMessageLogPath(gSavedPerAccountSettings.getString("InstantMessageLogPath"));
+	std::string chatLogPath = gDirUtilp->add(instantMessageLogPath, gDirUtilp->getUserName());
+
+	bool madeDirectory = false;
+
+	//Does the directory really exist, if not then make it
+	if(!LLFile::isdir(chatLogPath))
+	{
+		//mkdir success is defined as zero
+		if(LLFile::mkdir(chatLogPath) != 0)
+		{
+			return false;
+		}
+		madeDirectory = true;
+	}
+	
+	std::string originalConversationLogDir = LLConversationLog::instance().getFileName();
+	std::string targetConversationLogDir = gDirUtilp->add(chatLogPath, "conversation.log");
+	//Try to move the conversation log
+	if(!LLConversationLog::instance().moveLog(originalConversationLogDir, targetConversationLogDir))
+	{
+		//Couldn't move the log and created a new directory so remove the new directory
+		if(madeDirectory)
+		{
+			LLFile::rmdir(chatLogPath);
+		}
+		return false;
+	}
+
+	//Attempt to move transcripts
+	std::vector<std::string> listOfTranscripts;
+	std::vector<std::string> listOfFilesMoved;
+
+	LLLogChat::getListOfTranscriptFiles(listOfTranscripts);
+
+	if(!LLLogChat::moveTranscripts(gDirUtilp->getChatLogsDir(), 
+									instantMessageLogPath, 
+									listOfTranscripts,
+									listOfFilesMoved))
+	{
+		//Couldn't move all the transcripts so restore those that moved back to their old location
+		LLLogChat::moveTranscripts(instantMessageLogPath, 
+			gDirUtilp->getChatLogsDir(), 
+			listOfFilesMoved);
+
+		//Move the conversation log back
+		LLConversationLog::instance().moveLog(targetConversationLogDir, originalConversationLogDir);
+
+		if(madeDirectory)
+		{
+			LLFile::rmdir(chatLogPath);
+		}
+
+		return false;
+	}
+
+	gDirUtilp->setChatLogsDir(instantMessageLogPath);
+	gDirUtilp->updatePerAccountChatLogsDir();
+
+	return true;
 }
 
-void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email)
+void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im_via_email)
 {
 	mGotPersonalInfo = true;
 	mOriginalIMViaEmail = im_via_email;
@@ -1434,44 +1568,21 @@ void LLFloaterPreference::setPersonalInfo(const std::string& visibility, bool im
 	}
 	
 	getChild<LLUICtrl>("online_searchresults")->setEnabled(TRUE);
-
-	getChildView("include_im_in_chat_history")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
 	getChildView("friends_online_notify_checkbox")->setEnabled(TRUE);
-	
 	getChild<LLUICtrl>("online_visibility")->setValue(mOriginalHideOnlineStatus); 	 
 	getChild<LLUICtrl>("online_visibility")->setLabelArg("[DIR_VIS]", mDirectoryVisibility);
 	getChildView("send_im_to_email")->setEnabled(TRUE);
 	getChild<LLUICtrl>("send_im_to_email")->setValue(im_via_email);
-	getChildView("plain_text_chat_history")->setEnabled(TRUE);
-	getChild<LLUICtrl>("plain_text_chat_history")->setValue(gSavedSettings.getBOOL("PlainTextChatHistory"));
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-//	getChildView("log_chat")->setEnabled(TRUE);
-//	getChildView("busy_response")->setEnabled(TRUE);
-//	getChildView("log_instant_messages_timestamp")->setEnabled(TRUE);
-//	getChildView("log_chat_timestamp")->setEnabled(TRUE);
-	getChildView("log_chat_IM")->setEnabled(TRUE);
-	getChildView("log_date_timestamp")->setEnabled(TRUE);
-	
-//	getChild<LLUICtrl>("busy_response")->setValue(gSavedSettings.getString("BusyModeResponse2"));
-	
 	getChildView("favorites_on_login_check")->setEnabled(TRUE);
-	getChildView("log_nearby_chat")->setEnabled(TRUE);
-	getChildView("log_instant_messages")->setEnabled(TRUE);
-	getChildView("show_timestamps_check_im")->setEnabled(TRUE);
-	getChildView("log_path_string")->setEnabled(FALSE);// LineEditor becomes readonly in this case.
 	getChildView("log_path_button")->setEnabled(TRUE);
-	childEnable("logfile_name_datestamp");	
-	std::string display_email(email);
-	getChild<LLUICtrl>("email_address")->setValue(display_email);
-
+	getChildView("chat_font_size")->setEnabled(TRUE);
 }
 
 void LLFloaterPreference::onUpdateSliderText(LLUICtrl* ctrl, const LLSD& name)
 {
 	std::string ctrl_name = name.asString();
 	
-	if ((ctrl_name =="" )|| !hasChild(ctrl_name, true))
+	if ((ctrl_name =="" )|| !hasChild(ctrl_name, TRUE))
 		return;
 	
 	LLTextBox* text_box = getChild<LLTextBox>(name.asString());
@@ -1526,7 +1637,8 @@ void LLFloaterPreference::onChangeMaturity()
 // but the UI for this will still be enabled
 void LLFloaterPreference::onClickBlockList()
 {
-	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
+	LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+		LLSD().with("people_panel_tab_name", "blocked_panel"));
 }
 
 void LLFloaterPreference::onClickProxySettings()
@@ -1554,6 +1666,33 @@ void LLFloaterPreference::onClickActionChange()
 	mClickActionDirty = true;
 }
 
+void LLFloaterPreference::onDeleteTranscripts()
+{
+	LLSD args;
+	args["FOLDER"] = gDirUtilp->getUserName();
+
+	LLNotificationsUtil::add("PreferenceChatDeleteTranscripts", args, LLSD(), boost::bind(&LLFloaterPreference::onDeleteTranscriptsResponse, this, _1, _2));
+}
+
+void LLFloaterPreference::onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response)
+{
+	if (0 == LLNotificationsUtil::getSelectedOption(notification, response))
+	{
+		LLLogChat::deleteTranscripts();
+		updateDeleteTranscriptsButton();
+	}
+}
+
+void LLFloaterPreference::onLogChatHistorySaved()
+{
+	LLButton * delete_transcripts_buttonp = getChild<LLButton>("delete_transcripts");
+
+	if (!delete_transcripts_buttonp->getEnabled())
+	{
+		delete_transcripts_buttonp->setEnabled(true);
+	}
+}
+
 void LLFloaterPreference::updateClickActionSettings()
 {
 	const int single_clk_action = getChild<LLComboBox>("single_click_action_combo")->getValue().asInteger();
@@ -1592,6 +1731,35 @@ void LLFloaterPreference::setCacheLocation(const LLStringExplicit& location)
 	cache_location_editor->setToolTip(location);
 }
 
+void LLFloaterPreference::selectPanel(const LLSD& name)
+{
+	LLTabContainer * tab_containerp = getChild<LLTabContainer>("pref core");
+	LLPanel * panel = tab_containerp->getPanelByName(name);
+	if (NULL != panel)
+	{
+		tab_containerp->selectTabPanel(panel);
+	}
+}
+
+void LLFloaterPreference::selectPrivacyPanel()
+{
+	selectPanel("im");
+}
+
+void LLFloaterPreference::selectChatPanel()
+{
+	selectPanel("chat");
+}
+
+void LLFloaterPreference::changed()
+{
+	getChild<LLButton>("clear_log")->setEnabled(LLConversationLog::instance().getConversations().size() > 0);
+
+	// set 'enable' property for 'Delete transcripts...' button
+	updateDeleteTranscriptsButton();
+
+}
+
 //------------------------------Updater---------------------------------------
 
 static bool handleBandwidthChanged(const LLSD& newvalue)
@@ -1650,9 +1818,20 @@ LLPanelPreference::LLPanelPreference()
 //virtual
 BOOL LLPanelPreference::postBuild()
 {
+	////////////////////// PanelGeneral ///////////////////
+	if (hasChild("display_names_check", TRUE))
+	{
+		BOOL use_people_api = gSavedSettings.getBOOL("UsePeopleAPI");
+		LLCheckBoxCtrl* ctrl_display_name = getChild<LLCheckBoxCtrl>("display_names_check");
+		ctrl_display_name->setEnabled(use_people_api);
+		if (!use_people_api)
+		{
+			ctrl_display_name->setValue(FALSE);
+		}
+	}
 
 	////////////////////// PanelVoice ///////////////////
-	if (hasChild("voice_unavailable"))
+	if (hasChild("voice_unavailable", TRUE))
 	{
 		BOOL voice_disabled = gSavedSettings.getBOOL("CmdLineDisableVoice");
 		getChildView("voice_unavailable")->setVisible( voice_disabled);
@@ -1661,7 +1840,7 @@ BOOL LLPanelPreference::postBuild()
 	
 	//////////////////////PanelSkins ///////////////////
 	
-	if (hasChild("skin_selection"))
+	if (hasChild("skin_selection", TRUE))
 	{
 		LLFloaterPreference::refreshSkin(this);
 
@@ -1674,35 +1853,29 @@ BOOL LLPanelPreference::postBuild()
 
 	}
 
-	if (hasChild("online_visibility") && hasChild("send_im_to_email"))
-	{
-		getChild<LLUICtrl>("email_address")->setValue(getString("log_in_to_change") );
-//		getChild<LLUICtrl>("busy_response")->setValue(getString("log_in_to_change"));		
-	}
-	
 	//////////////////////PanelPrivacy ///////////////////
-	if (hasChild("media_enabled"))
+	if (hasChild("media_enabled", TRUE))
 	{
 		bool media_enabled = gSavedSettings.getBOOL("AudioStreamingMedia");
 		
 		getChild<LLCheckBoxCtrl>("media_enabled")->set(media_enabled);
 		getChild<LLCheckBoxCtrl>("autoplay_enabled")->setEnabled(media_enabled);
 	}
-	if (hasChild("music_enabled"))
+	if (hasChild("music_enabled", TRUE))
 	{
 		getChild<LLCheckBoxCtrl>("music_enabled")->set(gSavedSettings.getBOOL("AudioStreamingMusic"));
 	}
-	if (hasChild("voice_call_friends_only_check"))
+	if (hasChild("voice_call_friends_only_check", TRUE))
 	{
 		getChild<LLCheckBoxCtrl>("voice_call_friends_only_check")->setCommitCallback(boost::bind(&showFriendsOnlyWarning, _1, _2));
 	}
-	if (hasChild("favorites_on_login_check"))
+	if (hasChild("favorites_on_login_check", TRUE))
 	{
 		getChild<LLCheckBoxCtrl>("favorites_on_login_check")->setCommitCallback(boost::bind(&showFavoritesOnLoginWarning, _1, _2));
 	}
 
-	// Panel Advanced
-	if (hasChild("modifier_combo"))
+	//////////////////////PanelAdvanced ///////////////////
+	if (hasChild("modifier_combo", TRUE))
 	{
 		//localizing if push2talk button is set to middle mouse
 		if (MIDDLE_MOUSE_CV == getChild<LLUICtrl>("modifier_combo")->getValue().asString())
@@ -1712,7 +1885,7 @@ BOOL LLPanelPreference::postBuild()
 	}
 
 	//////////////////////PanelSetup ///////////////////
-	if (hasChild("max_bandwidth"))
+	if (hasChild("max_bandwidth"), TRUE)
 	{
 		mBandWidthUpdater = new LLPanelPreference::Updater(boost::bind(&handleBandwidthChanged, _1), BANDWIDTH_UPDATER_TIMEOUT);
 		gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&LLPanelPreference::Updater::update, mBandWidthUpdater, _2));
@@ -1856,7 +2029,7 @@ class LLPanelPreferencePrivacy : public LLPanelPreference
 			for (control_values_map_t::iterator it = mSavedValues.begin(); it != mSavedValues.end(); )
 			{
 				const std::string setting = it->first->getName();
-				if (std::find(mAccountIndependentSettings.begin(),
+				if (find(mAccountIndependentSettings.begin(),
 					mAccountIndependentSettings.end(), setting) == mAccountIndependentSettings.end())
 				{
 					mSavedValues.erase(it++);
@@ -2145,4 +2318,4 @@ void LLFloaterPreferenceProxy::onChangeSocksSettings()
 		otherHttpProxy->selectFirstItem();
 	}
 
-};
+}
diff --git a/indra/newview/llfloaterpreference.h b/indra/newview/llfloaterpreference.h
index b71f7c647b180951ff144f4a8dc490ea13033eba..22e80a21cbc1019408be129b0b1d8efbecc6eb32 100644
--- a/indra/newview/llfloaterpreference.h
+++ b/indra/newview/llfloaterpreference.h
@@ -35,7 +35,9 @@
 
 #include "llfloater.h"
 #include "llavatarpropertiesprocessor.h"
+#include "llconversationlog.h"
 
+class LLConversationLogObserver;
 class LLPanelPreference;
 class LLPanelLCD;
 class LLPanelDebug;
@@ -45,6 +47,8 @@ class LLSliderCtrl;
 class LLSD;
 class LLTextBox;
 
+typedef std::map<std::string, std::string> notifications_map;
+
 typedef enum
 	{
 		GS_LOW_GRAPHICS,
@@ -56,7 +60,7 @@ typedef enum
 
 
 // Floater to control preferences (display, audio, bandwidth, general.
-class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
+class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver, public LLConversationLogObserver
 {
 public: 
 	LLFloaterPreference(const LLSD& key);
@@ -68,20 +72,24 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 	/*virtual*/	void onClose(bool app_quitting);
+	/*virtual*/ void changed();
+	/*virtual*/ void changed(const LLUUID& session_id, U32 mask) {};
 
 	// static data update, called from message handler
-	static void updateUserInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	static void updateUserInfo(const std::string& visibility, bool im_via_email);
 
 	// refresh all the graphics preferences menus
 	static void refreshEnabledGraphics();
 	
-	// translate user's busy response message according to current locale if message is default, otherwise do nothing
-	static void initBusyResponse();
+	// translate user's do not disturb response message according to current locale if message is default, otherwise do nothing
+	static void initDoNotDisturbResponse();
 
 	void processProperties( void* pData, EAvatarProcessorType type );
 	void processProfileProperties(const LLAvatarData* pAvatarData );
 	void storeAvatarProperties( const LLAvatarData* pAvatarData );
 	void saveAvatarProperties( void );
+	void selectPrivacyPanel();
+	void selectChatPanel();
 
 protected:	
 	void		onBtnOK();
@@ -91,11 +99,12 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void		onClickClearCache();			// Clear viewer texture cache, vfs, and VO cache on next startup
 	void		onClickBrowserClearCache();		// Clear web history and caches as well as viewer caches above
 	void		onLanguageChange();
+	void		onNotificationsChange(const std::string& OptionName);
 	void		onNameTagOpacityChange(const LLSD& newvalue);
 
-	// set value of "BusyResponseChanged" in account settings depending on whether busy response
+	// set value of "DoNotDisturbResponseChanged" in account settings depending on whether do not disturb response
 	// string differs from default after user changes.
-	void onBusyResponseChanged();
+	void onDoNotDisturbResponseChanged();
 	// if the custom settings box is clicked
 	void onChangeCustom();
 	void updateMeterText(LLUICtrl* ctrl);
@@ -129,15 +138,14 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void setKey(KEY key);
 	void onClickSetMiddleMouse();
 	void onClickSetSounds();
-//	void onClickSkipDialogs();
-//	void onClickResetDialogs();
 	void onClickEnablePopup();
 	void onClickDisablePopup();	
 	void resetAllIgnored();
 	void setAllIgnored();
-	void onClickLogPath();	
+	void onClickLogPath();
+	bool moveTranscriptsAndLog();
 	void enableHistory();
-	void setPersonalInfo(const std::string& visibility, bool im_via_email, const std::string& email);
+	void setPersonalInfo(const std::string& visibility, bool im_via_email);
 	void refreshEnabledState();
 	void disableUnavailableSettings();
 	void onCommitWindowedMode();
@@ -161,16 +169,25 @@ class LLFloaterPreference : public LLFloater, public LLAvatarPropertiesObserver
 	void onClickSpellChecker();
 	void applyUIColor(LLUICtrl* ctrl, const LLSD& param);
 	void getUIColor(LLUICtrl* ctrl, const LLSD& param);
-	
+	void onLogChatHistorySaved();	
 	void buildPopupLists();
 	static void refreshSkin(void* data);
+	void selectPanel(const LLSD& name);
+
 private:
+
+	void onDeleteTranscripts();
+	void onDeleteTranscriptsResponse(const LLSD& notification, const LLSD& response);
+	void updateDeleteTranscriptsButton();
+
 	static std::string sSkin;
+	notifications_map mNotificationOptions;
 	bool mClickActionDirty; ///< Set to true when the click/double-click options get changed by user.
 	bool mGotPersonalInfo;
 	bool mOriginalIMViaEmail;
 	bool mLanguageChanged;
 	bool mAvatarDataInitialized;
+	std::string mPriorInstantMessageLogPath;
 	
 	bool mOriginalHideOnlineStatus;
 	std::string mDirectoryVisibility;
diff --git a/indra/newview/llfloaterregiondebugconsole.cpp b/indra/newview/llfloaterregiondebugconsole.cpp
index c7fab2573f29dfffaa97471fbad3059ec4b18e93..3a7ca17b73d34d3d71c34bcf090c2e57b87f52d9 100644
--- a/indra/newview/llfloaterregiondebugconsole.cpp
+++ b/indra/newview/llfloaterregiondebugconsole.cpp
@@ -75,7 +75,7 @@ namespace
 	{
 	public:
 		/* virtual */
-		void error(U32 status, const std::string& reason)
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 		{
 			sConsoleReplySignal(UNABLE_TO_SEND_COMMAND);
 		}
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index fe29bb38c73b67061731273bf1fa08f84cf77f96..50c013a49dfa3b479cf8adffada194f5b1a1a2b3 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -318,7 +318,7 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	// extract message
 	std::string sim_name;
 	std::string sim_type = LLTrans::getString("land_type_unknown");
-	U32 region_flags;
+	U64 region_flags;
 	U8 agent_limit;
 	F32 object_bonus_factor;
 	U8 sim_access;
@@ -328,7 +328,6 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	BOOL use_estate_sun;
 	F32 sun_hour;
 	msg->getString("RegionInfo", "SimName", sim_name);
-	msg->getU32("RegionInfo", "RegionFlags", region_flags);
 	msg->getU8("RegionInfo", "MaxAgents", agent_limit);
 	msg->getF32("RegionInfo", "ObjectBonusFactor", object_bonus_factor);
 	msg->getU8("RegionInfo", "SimAccess", sim_access);
@@ -347,6 +346,17 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 		LLTrans::findString(sim_type, sim_type); // try localizing sim product name
 	}
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64("RegionInfo3", "RegionFlagsExtended", region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32("RegionInfo", "RegionFlags", flags);
+		region_flags = flags;
+	}
+
 	// GENERAL PANEL
 	panel = tab->getChild<LLPanel>("General");
 	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name));
@@ -378,9 +388,9 @@ void LLFloaterRegionInfo::processRegionInfo(LLMessageSystem* msg)
 	panel = tab->getChild<LLPanel>("Debug");
 
 	panel->getChild<LLUICtrl>("region_text")->setValue(LLSD(sim_name) );
-	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_SCRIPTS)) );
-	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_COLLISIONS)) );
-	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)(region_flags & REGION_FLAGS_SKIP_PHYSICS)) );
+	panel->getChild<LLUICtrl>("disable_scripts_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_SCRIPTS) ? TRUE : FALSE )) );
+	panel->getChild<LLUICtrl>("disable_collisions_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_COLLISIONS) ? TRUE : FALSE )) );
+	panel->getChild<LLUICtrl>("disable_physics_check")->setValue(LLSD((BOOL)((region_flags & REGION_FLAGS_SKIP_PHYSICS) ? TRUE : FALSE )) );
 	panel->setCtrlsEnabled(allow_modify);
 
 	// TERRAIN PANEL
@@ -647,8 +657,10 @@ void LLPanelRegionGeneralInfo::onClickKick()
 
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
+    LLView * button = findChild<LLButton>("kick_btn");
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), FALSE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionGeneralInfo::onKickCommit, this, _1), 
+                                                                                FALSE, TRUE, FALSE, parent_floater->getName(), button);
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -746,9 +758,10 @@ class ConsoleRequestResponder : public LLHTTPClient::Responder
 {
 public:
 	/*virtual*/
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "requesting mesh_rez_enabled failed" << llendl;
+		llwarns << "ConsoleRequestResponder error requesting mesh_rez_enabled [status:"
+				<< status << "]: " << content << llendl;
 	}
 };
 
@@ -758,9 +771,10 @@ class ConsoleUpdateResponder : public LLHTTPClient::Responder
 {
 public:
 	/* virtual */
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "Updating mesh enabled region setting failed" << llendl;
+		llwarns << "ConsoleRequestResponder error updating mesh enabled region setting [status:"
+				<< status << "]: " << content << llendl;
 	}
 };
 
@@ -924,7 +938,14 @@ BOOL LLPanelRegionDebugInfo::sendUpdate()
 
 void LLPanelRegionDebugInfo::onClickChooseAvatar()
 {
-	LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), FALSE, TRUE);
+    LLView * button = findChild<LLButton>("choose_avatar_btn");
+    LLFloater* parent_floater = gFloaterView->getParentFloater(this);
+	LLFloater * child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelRegionDebugInfo::callbackAvatarID, this, _1, _2), 
+                                                                                    FALSE, TRUE, FALSE, parent_floater->getName(), button);
+	if (child_floater)
+	{
+		parent_floater->addDependentFloater(child_floater);
+	}
 }
 
 
@@ -1470,8 +1491,10 @@ void LLPanelEstateInfo::onClickKickUser()
 {
 	// this depends on the grandparent view being a floater
 	// in order to set up floater dependency
+    LLView * button = findChild<LLButton>("kick_user_from_estate_btn");
 	LLFloater* parent_floater = gFloaterView->getParentFloater(this);
-	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), FALSE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::onKickUserCommit, this, _1), 
+                                                                        FALSE, TRUE, FALSE, parent_floater->getName(), button);
 	if (child_floater)
 	{
 		parent_floater->addDependentFloater(child_floater);
@@ -1646,8 +1669,39 @@ bool LLPanelEstateInfo::accessAddCore2(const LLSD& notification, const LLSD& res
 	}
 
 	LLEstateAccessChangeInfo* change_info = new LLEstateAccessChangeInfo(notification["payload"]);
+    //Get parent floater name
+    LLPanelEstateInfo* panel = LLFloaterRegionInfo::getPanelEstate();
+    LLFloater* parent_floater = panel ? gFloaterView->getParentFloater(panel) : NULL;
+    const std::string& parent_floater_name = parent_floater ? parent_floater->getName() : "";
+    
+    //Determine the button that triggered opening of the avatar picker 
+    //(so that a shadow frustum from the button to the avatar picker can be created)
+    LLView * button = NULL;
+    switch(change_info->mOperationFlag)
+    {
+        case ESTATE_ACCESS_ALLOWED_AGENT_ADD:
+            button = panel->findChild<LLButton>("add_allowed_avatar_btn");
+            break;
+            
+        case ESTATE_ACCESS_BANNED_AGENT_ADD:
+            button = panel->findChild<LLButton>("add_banned_avatar_btn");
+            break;
+            
+        case ESTATE_ACCESS_MANAGER_ADD:
+            button = panel->findChild<LLButton>("add_estate_manager_btn");
+            break;
+    }
+
 	// avatar picker yes multi-select, yes close-on-select
-	LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), TRUE, TRUE);
+	LLFloater* child_floater = LLFloaterAvatarPicker::show(boost::bind(&LLPanelEstateInfo::accessAddCore3, _1, (void*)change_info), 
+                                                    TRUE, TRUE, FALSE, parent_floater_name, button);
+
+    //Allows the closed parent floater to close the child floater (avatar picker)
+    if (child_floater)
+    {
+        parent_floater->addDependentFloater(child_floater);
+    }
+
 	return false;
 }
 
@@ -2197,10 +2251,10 @@ class LLEstateChangeInfoResponder : public LLHTTPClient::Responder
 	}
 	
 	// if we get an error response
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llinfos << "LLEstateChangeInfoResponder::error "
-			<< status << ": " << reason << llendl;
+		llinfos << "LLEstateChangeInfoResponder::error [status:"
+			<< status << "]: " << content << llendl;
 	}
 private:
 	LLHandle<LLPanel> mpPanel;
@@ -2276,7 +2330,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
 	LLTextBox* resellable_clause = getChild<LLTextBox>("resellable_clause");
 	if (resellable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			resellable_clause->setText(getString("can_not_resell"));
 		}
@@ -2289,7 +2343,7 @@ bool LLPanelEstateCovenant::refreshFromRegion(LLViewerRegion* region)
 	LLTextBox* changeable_clause = getChild<LLTextBox>("changeable_clause");
 	if (changeable_clause)
 	{
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			changeable_clause->setText(getString("can_change"));
 		}
diff --git a/indra/newview/llfloaterreporter.cpp b/indra/newview/llfloaterreporter.cpp
index 3ec1e372eb1bd2eae68d599bdc52f9a08763f36e..35b63c54803fde1765942cd98b507c7cf9962daa 100644
--- a/indra/newview/llfloaterreporter.cpp
+++ b/indra/newview/llfloaterreporter.cpp
@@ -103,16 +103,14 @@ LLFloaterReporter::LLFloaterReporter(const LLSD& key)
 	mPicking( FALSE), 
 	mPosition(),
 	mCopyrightWarningSeen( FALSE ),
-	mResourceDatap(new LLResourceData())
+	mResourceDatap(new LLResourceData()),
+	mAvatarNameCacheConnection()
 {
 }
 
 // static
 void LLFloaterReporter::processRegionInfo(LLMessageSystem* msg)
 {
-	U32 region_flags;
-	msg->getU32("RegionInfo", "RegionFlags", region_flags);
-	
 	if ( LLFloaterReg::instanceVisible("reporter") )
 	{
 		LLNotificationsUtil::add("HelpReportAbuseEmailLL");
@@ -187,6 +185,11 @@ BOOL LLFloaterReporter::postBuild()
 // virtual
 LLFloaterReporter::~LLFloaterReporter()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
 	// child views automatically deleted
 	mObjectID 		= LLUUID::null;
 
@@ -285,10 +288,13 @@ void LLFloaterReporter::getObjectInfo(const LLUUID& object_id)
 
 void LLFloaterReporter::onClickSelectAbuser()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE );
+    LLView * button = findChild<LLButton>("select_abuser", TRUE);
+
+    LLFloater * root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterReporter::callbackAvatarID, this, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
 	if (picker)
 	{
-		gFloaterView->getParentFloater(this)->addDependentFloater(picker);
+		root_floater->addDependentFloater(picker);
 	}
 }
 
@@ -310,11 +316,17 @@ void LLFloaterReporter::setFromAvatarID(const LLUUID& avatar_id)
 	std::string avatar_link = LLSLURL("agent", mObjectID, "inspect").getSLURLString();
 	getChild<LLUICtrl>("owner_name")->setValue(avatar_link);
 
-	LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(avatar_id, boost::bind(&LLFloaterReporter::onAvatarNameCache, this, _1, _2));
 }
 
 void LLFloaterReporter::onAvatarNameCache(const LLUUID& avatar_id, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (mObjectID == avatar_id)
 	{
 		mOwnerName = av_name.getCompleteName();
@@ -698,7 +710,7 @@ class LLUserReportResponder : public LLHTTPClient::Responder
 public:
 	LLUserReportResponder(): LLHTTPClient::Responder()  {}
 
-	void error(U32 status, const std::string& reason)
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		// *TODO do some user messaging here
 		LLUploadDialog::modalUploadFinished();
@@ -768,8 +780,8 @@ void LLFloaterReporter::takeScreenshot()
 
 	// store in the image list so it doesn't try to fetch from the server
 	LLPointer<LLViewerFetchedTexture> image_in_list = 
-		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::FETCHED_TEXTURE);
-	image_in_list->createGLTexture(0, raw, 0, TRUE, LLViewerTexture::OTHER);
+		LLViewerTextureManager::getFetchedTexture(mResourceDatap->mAssetInfo.mUuid);
+	image_in_list->createGLTexture(0, raw, 0, TRUE, LLGLTexture::OTHER);
 	
 	// the texture picker then uses that texture
 	LLTexturePicker* texture = getChild<LLTextureCtrl>("screenshot");
@@ -816,12 +828,7 @@ void LLFloaterReporter::uploadDoneCallback(const LLUUID &uuid, void *user_data,
 		return;
 	}
 
-	EReportType report_type = UNKNOWN_REPORT;
-	if (data->mPreferredLocation == LLResourceData::INVALID_LOCATION)
-	{
-		report_type = COMPLAINT_REPORT;
-	}
-	else 
+	if (data->mPreferredLocation != LLResourceData::INVALID_LOCATION)
 	{
 		llwarns << "Unknown report type : " << data->mPreferredLocation << llendl;
 	}
diff --git a/indra/newview/llfloaterreporter.h b/indra/newview/llfloaterreporter.h
index 7d684317103d4e747e17ee02fde1fdc8dc868085..d54e7f6ab0cd95bc55ee6dc24213aaf4db445778 100644
--- a/indra/newview/llfloaterreporter.h
+++ b/indra/newview/llfloaterreporter.h
@@ -137,6 +137,7 @@ class LLFloaterReporter
 	std::list<LLMeanCollisionData*> mMCDList;
 	std::string		mDefaultSummary;
 	LLResourceData* mResourceDatap;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif
diff --git a/indra/newview/llfloaterscriptdebug.cpp b/indra/newview/llfloaterscriptdebug.cpp
index b691db1049f04756867a7a3cf3b1791207a3ee15..6c17f62c1e862729d5d416781857c1c679244731 100644
--- a/indra/newview/llfloaterscriptdebug.cpp
+++ b/indra/newview/llfloaterscriptdebug.cpp
@@ -105,7 +105,7 @@ void LLFloaterScriptDebug::addScriptLine(const std::string &utf8mesg, const std:
 
 	if (objectp)
 	{
-		objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", TRUE, LLViewerTexture::BOOST_UI));
+		objectp->setIcon(LLViewerTextureManager::getFetchedTextureFromFile("script_error.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
 		floater_label = llformat("%s(%.0f, %.0f, %.0f)",
 						user_name.c_str(),
 						objectp->getPositionRegion().mV[VX],
diff --git a/indra/newview/llfloaterscriptlimits.cpp b/indra/newview/llfloaterscriptlimits.cpp
index a50907601c54599bad4a9e2f17f7dfcb7cf72052..13cb3c2eb00256ad87432ae0710d8a23a71ff251 100644
--- a/indra/newview/llfloaterscriptlimits.cpp
+++ b/indra/newview/llfloaterscriptlimits.cpp
@@ -221,9 +221,9 @@ void fetchScriptLimitsRegionInfoResponder::result(const LLSD& content)
 	}
 }
 
-void fetchScriptLimitsRegionInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionInfoResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
@@ -308,9 +308,9 @@ void fetchScriptLimitsRegionSummaryResponder::result(const LLSD& content_ref)
 	}
 }
 
-void fetchScriptLimitsRegionSummaryResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionSummaryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionSummaryResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsRegionDetailsResponder::result(const LLSD& content_ref)
@@ -417,9 +417,9 @@ result (map)
 	}
 }
 
-void fetchScriptLimitsRegionDetailsResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsRegionDetailsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsRegionDetailsResponder error [status:" << status << "]: " << content << llendl;
 }
 
 void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
@@ -513,9 +513,9 @@ void fetchScriptLimitsAttachmentInfoResponder::result(const LLSD& content_ref)
 	}
 }
 
-void fetchScriptLimitsAttachmentInfoResponder::error(U32 status, const std::string& reason)
+void fetchScriptLimitsAttachmentInfoResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "Error from responder " << reason << llendl;
+	llwarns << "fetchScriptLimitsAttachmentInfoResponder error [status:" << status << "]: " << content << llendl;
 }
 
 ///----------------------------------------------------------------------------
@@ -602,15 +602,7 @@ void LLPanelScriptLimitsRegionMemory::onNameCache(
 		return;
 	}
 	
-	std::string name;
-	if (LLAvatarNameCache::useDisplayNames())
-	{
-		name = LLCacheName::buildUsername(full_name);
-	}
-	else
-	{
-		name = full_name;
-	}
+	std::string name = LLCacheName::buildUsername(full_name);
 
 	std::vector<LLSD>::iterator id_itor;
 	for (id_itor = mObjectListItems.begin(); id_itor != mObjectListItems.end(); ++id_itor)
@@ -713,10 +705,7 @@ void LLPanelScriptLimitsRegionMemory::setRegionDetails(LLSD content)
 				else
 				{
 					name_is_cached = gCacheName->getFullName(owner_id, owner_buf);  // username
-					if (LLAvatarNameCache::useDisplayNames())
-					{
-						owner_buf = LLCacheName::buildUsername(owner_buf);
-					}
+					owner_buf = LLCacheName::buildUsername(owner_buf);
 				}
 				if(!name_is_cached)
 				{
diff --git a/indra/newview/llfloaterscriptlimits.h b/indra/newview/llfloaterscriptlimits.h
index 9bcfa5fe1426ad3aad34d9986306be6c9d3526c4..f8732ef94bb02f14db6c46cf0b2661e24953eb50 100644
--- a/indra/newview/llfloaterscriptlimits.h
+++ b/indra/newview/llfloaterscriptlimits.h
@@ -89,7 +89,7 @@ class fetchScriptLimitsRegionInfoResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionInfoResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -101,7 +101,7 @@ class fetchScriptLimitsRegionSummaryResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionSummaryResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -113,7 +113,7 @@ class fetchScriptLimitsRegionDetailsResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsRegionDetailsResponder(const LLSD& info) : mInfo(info) {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 		LLSD mInfo;
@@ -125,7 +125,7 @@ class fetchScriptLimitsAttachmentInfoResponder: public LLHTTPClient::Responder
 		fetchScriptLimitsAttachmentInfoResponder() {};
 
 		void result(const LLSD& content);
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	public:
 	protected:
 };
diff --git a/indra/newview/llfloatersellland.cpp b/indra/newview/llfloatersellland.cpp
index 64c0dfa0236b7ed1fe48bc4bc01e173fb1aaa42d..0cb37dabe7ccb8cd0005198156afc795b1cab3fe 100644
--- a/indra/newview/llfloatersellland.cpp
+++ b/indra/newview/llfloatersellland.cpp
@@ -81,6 +81,7 @@ class LLFloaterSellLandUI
 	LLUUID					mAuthorizedBuyer;
 	bool					mParcelSoldWithObjects;
 	SelectionObserver 		mParcelSelectionObserver;
+	boost::signals2::connection mAvatarNameCacheConnection;
 	
 	void updateParcelInfo();
 	void refreshUI();
@@ -129,13 +130,18 @@ LLFloater* LLFloaterSellLand::buildFloater(const LLSD& key)
 LLFloaterSellLandUI::LLFloaterSellLandUI(const LLSD& key)
 :	LLFloater(key),
 	mParcelSelectionObserver(this),
-	mRegion(0)
+	mRegion(0),
+	mAvatarNameCacheConnection()
 {
 	LLViewerParcelMgr::getInstance()->addObserver(&mParcelSelectionObserver);
 }
 
 LLFloaterSellLandUI::~LLFloaterSellLandUI()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	LLViewerParcelMgr::getInstance()->removeObserver(&mParcelSelectionObserver);
 }
 
@@ -230,15 +236,20 @@ void LLFloaterSellLandUI::updateParcelInfo()
 
 	if(mSellToBuyer)
 	{
-		LLAvatarNameCache::get(mAuthorizedBuyer, 
-			boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mAuthorizedBuyer, boost::bind(&LLFloaterSellLandUI::onBuyerNameCache, this, _2));
 	}
 }
 
 void LLFloaterSellLandUI::onBuyerNameCache(const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	getChild<LLUICtrl>("sell_to_agent")->setValue(av_name.getCompleteName());
-	getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.mUsername);
+	getChild<LLUICtrl>("sell_to_agent")->setToolTip(av_name.getUserName());
 }
 
 void LLFloaterSellLandUI::setBadge(const char* id, Badge badge)
@@ -392,7 +403,8 @@ void LLFloaterSellLandUI::onChangeValue(LLUICtrl *ctrl, void *userdata)
 
 void LLFloaterSellLandUI::doSelectAgent()
 {
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE);
+    LLView * button = findChild<LLView>("sell_to_select_agent");
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLFloaterSellLandUI::callbackAvatarPick, this, _1, _2), FALSE, TRUE, FALSE, this->getName(), button);
 	// grandparent is a floater, in order to set up dependency
 	if (picker)
 	{
diff --git a/indra/newview/llfloatersidepanelcontainer.cpp b/indra/newview/llfloatersidepanelcontainer.cpp
index 5385977d95d23071be0d24e440fe7a0abae19ba9..5f9556a870d66810af487f69807501b362bf54c9 100644
--- a/indra/newview/llfloatersidepanelcontainer.cpp
+++ b/indra/newview/llfloatersidepanelcontainer.cpp
@@ -28,10 +28,13 @@
 
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
+#include "llpaneleditwearable.h"
 
 // newview includes
 #include "llsidetraypanelcontainer.h"
 #include "lltransientfloatermgr.h"
+#include "llpaneloutfitedit.h"
+#include "llsidepanelappearance.h"
 
 //static
 const std::string LLFloaterSidePanelContainer::sMainPanelName("main_panel");
@@ -54,6 +57,27 @@ void LLFloaterSidePanelContainer::onOpen(const LLSD& key)
 	getChild<LLPanel>(sMainPanelName)->onOpen(key);
 }
 
+void LLFloaterSidePanelContainer::onClickCloseBtn()
+{
+	LLPanelOutfitEdit* panel_outfit_edit =
+		dynamic_cast<LLPanelOutfitEdit*>(LLFloaterSidePanelContainer::getPanel("appearance", "panel_outfit_edit"));
+	if (panel_outfit_edit)
+	{
+		LLFloater *parent = gFloaterView->getParentFloater(panel_outfit_edit);
+		if (parent == this )
+		{
+			LLSidepanelAppearance* panel_appearance = dynamic_cast<LLSidepanelAppearance*>(getPanel("appearance"));
+			if ( panel_appearance )
+			{
+				panel_appearance->getWearable()->onClose();
+				panel_appearance->showOutfitsInventoryPanel();
+			}
+		}
+	}
+	
+	LLFloater::onClickCloseBtn();
+}
+
 LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_name, const LLSD& params)
 {
 	LLView* view = findChildView(panel_name, true);
@@ -61,7 +85,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
 
 	if (!getVisible())
 	{
-		openFloater();
+	openFloater();
 	}
 
 	LLPanel* panel = NULL;
@@ -69,10 +93,7 @@ LLPanel* LLFloaterSidePanelContainer::openChildPanel(const std::string& panel_na
 	LLSideTrayPanelContainer* container = dynamic_cast<LLSideTrayPanelContainer*>(view->getParent());
 	if (container)
 	{
-		LLSD new_params = params;
-		new_params[LLSideTrayPanelContainer::PARAM_SUB_PANEL_NAME] = panel_name;
-		container->onOpen(new_params);
-
+		container->openPanel(panel_name, params);
 		panel = container->getCurrentPanel();
 	}
 	else if ((panel = dynamic_cast<LLPanel*>(view)) != NULL)
diff --git a/indra/newview/llfloatersidepanelcontainer.h b/indra/newview/llfloatersidepanelcontainer.h
index 10d85867ce5807e7fa0ab2ef5e09de5d3d7fc039..491723471fb1109211764fe9b6757234071b9cf4 100644
--- a/indra/newview/llfloatersidepanelcontainer.h
+++ b/indra/newview/llfloatersidepanelcontainer.h
@@ -51,6 +51,8 @@ class LLFloaterSidePanelContainer : public LLFloater
 
 	/*virtual*/ void onOpen(const LLSD& key);
 
+	/*virtual*/ void onClickCloseBtn();
+
 	LLPanel* openChildPanel(const std::string& panel_name, const LLSD& params);
 
 	static void showPanel(const std::string& floater_name, const LLSD& key);
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 1eb7f4469a142e2bb1f9cd2f5f692b5531c28d1f..14923eec3c8c10880ca269c71966d94f3ec807b0 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -657,8 +657,8 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 
 	mBtnEdit	->setToggleState( edit_visible );
 	mRadioGroupEdit->setVisible( edit_visible );
-	bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
-	getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
+	//bool linked_parts = gSavedSettings.getBOOL("EditLinkedParts");
+	//getChildView("RenderingCost")->setVisible( !linked_parts && (edit_visible || focus_visible || move_visible) && sShowObjectCost);
 
 	mBtnLink->setVisible(edit_visible);
 	mBtnUnlink->setVisible(edit_visible);
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 2d91a61b545f828cef24151d07d38bc683646c0f..7530c72dd24833e1b4229621c412e7431de7b5d4 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -199,17 +199,9 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		// Owner names can have trailing spaces sent from server
 		LLStringUtil::trim(owner_buf);
 		
-		if (LLAvatarNameCache::useDisplayNames())
-		{
-			// ...convert hard-coded name from server to a username
-			// *TODO: Send owner_id from server and look up display name
-			owner_buf = LLCacheName::buildUsername(owner_buf);
-		}
-		else
-		{
-			// ...just strip out legacy "Resident" name
-			owner_buf = LLCacheName::cleanFullName(owner_buf);
-		}
+		// *TODO: Send owner_id from server and look up display name
+		owner_buf = LLCacheName::buildUsername(owner_buf);
+
 		columns[column_num]["column"] = "owner";
 		columns[column_num]["value"] = owner_buf;
 		columns[column_num++]["font"] = "SANSSERIF";
diff --git a/indra/newview/llfloatertranslationsettings.cpp b/indra/newview/llfloatertranslationsettings.cpp
index 1a17183efdd39b0f2903c626601bd5e508a20e2a..33f2c352398ee31e7546632001c6ad2809583658 100644
--- a/indra/newview/llfloatertranslationsettings.cpp
+++ b/indra/newview/llfloatertranslationsettings.cpp
@@ -29,7 +29,7 @@
 #include "llfloatertranslationsettings.h"
 
 // Viewer includes
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 #include "lltranslate.h"
 #include "llviewercontrol.h" // for gSavedSettings
 
@@ -225,11 +225,10 @@ void LLFloaterTranslationSettings::updateControlsEnabledState()
 	mGoogleVerifyBtn->setEnabled(on && google_selected &&
 		!mGoogleKeyVerified && !getEnteredGoogleKey().empty());
 
-	mOKBtn->setEnabled(
-		!on || (
-		(bing_selected && mBingKeyVerified) ||
-		(google_selected && mGoogleKeyVerified)
-	));
+	bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+	gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
+
+	mOKBtn->setEnabled(!on || service_verified);
 }
 
 void LLFloaterTranslationSettings::verifyKey(int service, const std::string& key, bool alert)
@@ -285,7 +284,16 @@ void LLFloaterTranslationSettings::onBtnGoogleVerify()
 		verifyKey(LLTranslate::SERVICE_GOOGLE, key);
 	}
 }
+void LLFloaterTranslationSettings::onClose(bool app_quitting)
+{
+	std::string service = gSavedSettings.getString("TranslationService");
+	bool bing_selected = service == "bing";
+	bool google_selected = service == "google";
+
+	bool service_verified = (bing_selected && mBingKeyVerified) || (google_selected && mGoogleKeyVerified);
+	gSavedPerAccountSettings.setBOOL("TranslatingEnabled", service_verified);
 
+}
 void LLFloaterTranslationSettings::onBtnOK()
 {
 	gSavedSettings.setBOOL("TranslateChat", mMachineTranslationCB->getValue().asBoolean());
@@ -293,6 +301,7 @@ void LLFloaterTranslationSettings::onBtnOK()
 	gSavedSettings.setString("TranslationService", getSelectedService());
 	gSavedSettings.setString("BingTranslateAPIKey", getEnteredBingKey());
 	gSavedSettings.setString("GoogleTranslateAPIKey", getEnteredGoogleKey());
-	LLNearbyChatBar::getInstance()->showTranslationCheckbox(LLTranslate::isTranslationConfigured());
+	(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+			showTranslationCheckbox(LLTranslate::isTranslationConfigured());
 	closeFloater(false);
 }
diff --git a/indra/newview/llfloatertranslationsettings.h b/indra/newview/llfloatertranslationsettings.h
index 9b47ad72ed20bc16b7300c4c999bd982768f63fc..b9bfd6265aff8f61845fd95ef8fe6dafca28f2c1 100644
--- a/indra/newview/llfloatertranslationsettings.h
+++ b/indra/newview/llfloatertranslationsettings.h
@@ -44,6 +44,7 @@ class LLFloaterTranslationSettings : public LLFloater
 
 	void setBingVerified(bool ok, bool alert);
 	void setGoogleVerified(bool ok, bool alert);
+	void onClose(bool app_quitting);
 
 private:
 	std::string getSelectedService() const;
diff --git a/indra/newview/llfloateruipreview.cpp b/indra/newview/llfloateruipreview.cpp
index 15e0b89f6ccb970cd37e91133cd2c1bc3baa5ae9..0106a1615d3b31aee80b08e693b41e0af2825fa6 100644
--- a/indra/newview/llfloateruipreview.cpp
+++ b/indra/newview/llfloateruipreview.cpp
@@ -855,7 +855,6 @@ void LLFloaterUIPreview::displayFloater(BOOL click, S32 ID)
 		LLPanel* panel = LLUICtrlFactory::create<LLPanel>(panel_params);	// create a new panel
 
 		panel->buildFromFile(path);										// build it
-		LLRect new_size = panel->getRect();								// get its rectangle
 		panel->setOrigin(2,2);											// reset its origin point so it's not offset by -left or other XUI attributes
 		(*floaterp)->setTitle(path);									// use the file name as its title, since panels have no guaranteed meaningful name attribute
 		panel->setUseBoundingRect(TRUE);								// enable the use of its outer bounding rect (normally disabled because it's O(n) on the number of sub-elements)
diff --git a/indra/newview/llfloatervoicevolume.cpp b/indra/newview/llfloatervoicevolume.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..38446e46df8979e73f8ce826ce476f4fe37dfdb7
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.cpp
@@ -0,0 +1,220 @@
+/** 
+ * @file llfloatervoicevolume.cpp
+ *
+ * $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 "llfloatervoicevolume.h"
+
+// Linden libraries
+#include "llavatarname.h"
+#include "llavatarnamecache.h"
+#include "llfloater.h"
+#include "llfloaterreg.h"
+#include "lltextbox.h"
+
+// viewer files
+#include "llagent.h"
+#include "llavataractions.h"
+#include "llinspect.h"
+#include "lltransientfloatermgr.h"
+#include "llvoiceclient.h"
+
+class LLAvatarName;
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolume
+//////////////////////////////////////////////////////////////////////////////
+
+// Avatar Inspector, a small information window used when clicking
+// on avatar names in the 2D UI and in the ambient inspector widget for
+// the 3D world.
+class LLFloaterVoiceVolume : public LLInspect, LLTransientFloater
+{
+	friend class LLFloaterReg;
+	
+public:
+	// avatar_id - Avatar ID for which to show information
+	// Inspector will be positioned relative to current mouse position
+	LLFloaterVoiceVolume(const LLSD& avatar_id);
+	virtual ~LLFloaterVoiceVolume();
+	
+	/*virtual*/ BOOL postBuild(void);
+	
+	// Because floater is single instance, need to re-parse data on each spawn
+	// (for example, inspector about same avatar but in different position)
+	/*virtual*/ void onOpen(const LLSD& avatar_id);
+
+	/*virtual*/ LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
+
+private:
+	// Set the volume slider to this user's current client-side volume setting,
+	// hiding/disabling if the user is not nearby.
+	void updateVolumeControls();
+
+	void onClickMuteVolume();
+	void onVolumeChange(const LLSD& data);
+	void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
+	
+private:
+	LLUUID				mAvatarID;
+	// Need avatar name information to spawn friend add request
+	LLAvatarName		mAvatarName;
+	boost::signals2::connection mAvatarNameCacheConnection;
+};
+
+LLFloaterVoiceVolume::LLFloaterVoiceVolume(const LLSD& sd)
+:	LLInspect(LLSD())		// single_instance, doesn't really need key
+,	mAvatarID()				// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec*
+,	mAvatarName()
+,   mAvatarNameCacheConnection()
+{
+	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
+	LLTransientFloater::init(this);
+}
+
+LLFloaterVoiceVolume::~LLFloaterVoiceVolume()
+{
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	LLTransientFloaterMgr::getInstance()->removeControlView(this);
+}
+
+/*virtual*/
+BOOL LLFloaterVoiceVolume::postBuild(void)
+{
+	getChild<LLUICtrl>("mute_btn")->setCommitCallback(
+		boost::bind(&LLFloaterVoiceVolume::onClickMuteVolume, this) );
+
+	getChild<LLUICtrl>("volume_slider")->setCommitCallback(
+		boost::bind(&LLFloaterVoiceVolume::onVolumeChange, this, _2));
+
+	return TRUE;
+}
+
+
+// Multiple calls to showInstance("floater_voice_volume", foo) will provide different
+// LLSD for foo, which we will catch here.
+//virtual
+void LLFloaterVoiceVolume::onOpen(const LLSD& data)
+{
+	// Start open animation
+	LLInspect::onOpen(data);
+
+	// Extract appropriate avatar id
+	mAvatarID = data["avatar_id"];
+
+	LLUI::positionViewNearMouse(this);
+
+	getChild<LLUICtrl>("avatar_name")->setValue("");
+	updateVolumeControls();
+
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID, boost::bind(&LLFloaterVoiceVolume::onAvatarNameCache, this, _1, _2));
+}
+
+void LLFloaterVoiceVolume::updateVolumeControls()
+{
+	bool voice_enabled = LLVoiceClient::getInstance()->getVoiceEnabled(mAvatarID);
+
+	LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
+	LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
+
+	// Do not display volume slider and mute button if it 
+	// is ourself or we are not in a voice channel together
+	if (!voice_enabled || (mAvatarID == gAgent.getID()))
+	{
+		mute_btn->setVisible(false);
+		volume_slider->setVisible(false);
+	}
+	else 
+	{
+		mute_btn->setVisible(true);
+		volume_slider->setVisible(true);
+
+		// By convention, we only display and toggle voice mutes, not all mutes
+		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
+		bool is_linden = LLStringUtil::endsWith(mAvatarName.getUserName(), " Linden");
+
+		mute_btn->setEnabled(!is_linden);
+		mute_btn->setValue(is_muted);
+
+		volume_slider->setEnabled(!is_muted);
+
+		F32 volume;
+		if (is_muted)
+		{
+			// it's clearer to display their volume as zero
+			volume = 0.f;
+		}
+		else
+		{
+			// actual volume
+			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
+		}
+		volume_slider->setValue((F64)volume);
+	}
+
+}
+
+void LLFloaterVoiceVolume::onClickMuteVolume()
+{
+	LLAvatarActions::toggleMuteVoice(mAvatarID);
+	updateVolumeControls();
+}
+
+void LLFloaterVoiceVolume::onVolumeChange(const LLSD& data)
+{
+	F32 volume = (F32)data.asReal();
+	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
+}
+
+void LLFloaterVoiceVolume::onAvatarNameCache(
+		const LLUUID& agent_id,
+		const LLAvatarName& av_name)
+{
+	mAvatarNameCacheConnection.disconnect();
+
+	if (agent_id != mAvatarID)
+	{
+		return;
+	}
+
+	getChild<LLUICtrl>("avatar_name")->setValue(av_name.getCompleteName());
+	mAvatarName = av_name;
+}
+
+//////////////////////////////////////////////////////////////////////////////
+// LLFloaterVoiceVolumeUtil
+//////////////////////////////////////////////////////////////////////////////
+void LLFloaterVoiceVolumeUtil::registerFloater()
+{
+	LLFloaterReg::add("floater_voice_volume", "floater_voice_volume.xml",
+					  &LLFloaterReg::build<LLFloaterVoiceVolume>);
+}
diff --git a/indra/newview/llfloatervoicevolume.h b/indra/newview/llfloatervoicevolume.h
new file mode 100644
index 0000000000000000000000000000000000000000..8fcf7f250b71abec786cf732e2ef7ed812051ac7
--- /dev/null
+++ b/indra/newview/llfloatervoicevolume.h
@@ -0,0 +1,35 @@
+/** 
+ * @file llfloatervoicevolume.h
+ *
+ * $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_LLFLOATERVOICEVOLUME_H
+#define LL_LLFLOATERVOICEVOLUME_H
+
+namespace LLFloaterVoiceVolumeUtil
+{
+	// Register with LLFloaterReg
+	void registerFloater();
+}
+
+#endif // LL_LLFLOATERVOICEVOLUME_H
diff --git a/indra/newview/llfoldervieweventlistener.h b/indra/newview/llfoldervieweventlistener.h
deleted file mode 100644
index 06682dcbf1f9d8058e9449e146027f4ae80f38a0..0000000000000000000000000000000000000000
--- a/indra/newview/llfoldervieweventlistener.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/** 
- * @file llfoldervieweventlistener.h
- *
- * $LicenseInfo:firstyear=2001&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-#ifndef LLFOLDERVIEWEVENTLISTENER_H
-#define LLFOLDERVIEWEVENTLISTENER_H
-
-#include "lldarray.h"	// *TODO: convert to std::vector
-#include "llfoldertype.h"
-#include "llfontgl.h"	// just for StyleFlags enum
-#include "llinventorytype.h"
-#include "llpermissionsflags.h"
-#include "llpointer.h"
-#include "llwearabletype.h"
-
-
-class LLFolderViewItem;
-class LLFolderView;
-class LLFontGL;
-class LLInventoryModel;
-class LLMenuGL;
-class LLScrollContainer;
-class LLUIImage;
-class LLUUID;
-
-// This is an abstract base class that users of the folderview classes
-// would use to catch the useful events emitted from the folder
-// views.
-class LLFolderViewEventListener
-{
-public:
-	virtual ~LLFolderViewEventListener( void ) {}
-	virtual const std::string& getName() const = 0;
-	virtual const std::string& getDisplayName() const = 0;
-	virtual const LLUUID& getUUID() const = 0;
-	virtual time_t getCreationDate() const = 0;	// UTC seconds
-	virtual PermissionMask getPermissionMask() const = 0;
-	virtual LLFolderType::EType getPreferredType() const = 0;
-	virtual LLPointer<LLUIImage> getIcon() const = 0;
-	virtual LLPointer<LLUIImage> getOpenIcon() const { return getIcon(); }
-	virtual LLFontGL::StyleFlags getLabelStyle() const = 0;
-	virtual std::string getLabelSuffix() const = 0;
-	virtual void openItem( void ) = 0;
-	virtual void closeItem( void ) = 0;
-	virtual void previewItem( void ) = 0;
-	virtual void selectItem(void) = 0;
-	virtual void showProperties(void) = 0;
-	virtual BOOL isItemRenameable() const = 0;
-	virtual BOOL renameItem(const std::string& new_name) = 0;
-	virtual BOOL isItemMovable( void ) const = 0;		// Can be moved to another folder
-	virtual BOOL isItemRemovable( void ) const = 0;		// Can be destroyed
-	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make into pure virtual.
-	virtual BOOL removeItem() = 0;
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch) = 0;
-	virtual void move( LLFolderViewEventListener* parent_listener ) = 0;
-	virtual BOOL isItemCopyable() const = 0;
-	virtual BOOL copyToClipboard() const = 0;
-	virtual BOOL cutToClipboard() const = 0;
-	virtual BOOL isClipboardPasteable() const = 0;
-	virtual void pasteFromClipboard() = 0;
-	virtual void pasteLinkFromClipboard() = 0;
-	virtual void buildContextMenu(LLMenuGL& menu, U32 flags) = 0;
-	virtual BOOL isUpToDate() const = 0;
-	virtual BOOL hasChildren() const = 0;
-	virtual LLInventoryType::EType getInventoryType() const = 0;
-	virtual void performAction(LLInventoryModel* model, std::string action) = 0;
-	virtual LLWearableType::EType getWearableType() const = 0;
-	
-	// This method should be called when a drag begins. returns TRUE
-	// if the drag can begin, otherwise FALSE.
-	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
-	
-	// This method will be called to determine if a drop can be
-	// performed, and will set drop to TRUE if a drop is
-	// requested. Returns TRUE if a drop is possible/happened,
-	// otherwise FALSE.
-	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
-							EDragAndDropType cargo_type,
-							void* cargo_data,
-							std::string& tooltip_msg) = 0;
-};
-
-#endif
diff --git a/indra/newview/llfolderviewitem.cpp b/indra/newview/llfolderviewitem.cpp
deleted file mode 100644
index 3aa16b4413453ce5690e5ff39a492ff9cf9ac836..0000000000000000000000000000000000000000
--- a/indra/newview/llfolderviewitem.cpp
+++ /dev/null
@@ -1,2901 +0,0 @@
-/** 
-* @file llfolderviewitem.cpp
-* @brief Items and folders that can appear in a hierarchical folder view
-*
-* $LicenseInfo:firstyear=2001&license=viewerlgpl$
-* Second Life Viewer Source Code
-* Copyright (C) 2010, Linden Research, Inc.
-* 
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU Lesser General Public
-* License as published by the Free Software Foundation;
-* version 2.1 of the License only.
-* 
-* This library is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-* Lesser General Public License for more details.
-* 
-* You should have received a copy of the GNU Lesser General Public
-* License along with this library; if not, write to the Free Software
-* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
-* 
-* Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
-* $/LicenseInfo$
-*/
-#include "llviewerprecompiledheaders.h"
-
-#include "llfolderviewitem.h"
-
-// viewer includes
-#include "llfolderview.h"		// Items depend extensively on LLFolderViews
-#include "llfoldervieweventlistener.h"
-#include "llviewerfoldertype.h"
-#include "llinventorybridge.h"	// for LLItemBridge in LLInventorySort::operator()
-#include "llinventoryfilter.h"
-#include "llinventoryfunctions.h"
-#include "llinventorymodelbackgroundfetch.h"
-#include "llpanel.h"
-#include "llviewercontrol.h"	// gSavedSettings
-#include "llviewerwindow.h"		// Argh, only for setCursor()
-
-// linden library includes
-#include "llclipboard.h"
-#include "llfocusmgr.h"		// gFocusMgr
-#include "lltrans.h"
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewItem
-///----------------------------------------------------------------------------
-
-static LLDefaultChildRegistry::Register<LLFolderViewItem> r("folder_view_item");
-
-// statics 
-std::map<U8, LLFontGL*> LLFolderViewItem::sFonts; // map of styles to fonts
-
-// only integers can be initialized in header
-const F32 LLFolderViewItem::FOLDER_CLOSE_TIME_CONSTANT = 0.02f;
-const F32 LLFolderViewItem::FOLDER_OPEN_TIME_CONSTANT = 0.03f;
-
-const LLColor4U DEFAULT_WHITE(255, 255, 255);
-
-
-//static
-LLFontGL* LLFolderViewItem::getLabelFontForStyle(U8 style)
-{
-	LLFontGL* rtn = sFonts[style];
-	if (!rtn) // grab label font with this style, lazily
-	{
-		LLFontDescriptor labelfontdesc("SansSerif", "Small", style);
-		rtn = LLFontGL::getFont(labelfontdesc);
-		if (!rtn)
-		{
-			rtn = LLFontGL::getFontDefault();
-		}
-		sFonts[style] = rtn;
-	}
-	return rtn;
-}
-
-//static
-void LLFolderViewItem::initClass()
-{
-}
-
-//static
-void LLFolderViewItem::cleanupClass()
-{
-	sFonts.clear();
-}
-
-
-// NOTE: Optimize this, we call it a *lot* when opening a large inventory
-LLFolderViewItem::Params::Params()
-:	icon(),
-	icon_open(),
-	icon_overlay(),
-	root(),
-	listener(),
-	folder_arrow_image("folder_arrow_image"),
-	folder_indentation("folder_indentation"),
-	selection_image("selection_image"),
-	item_height("item_height"),
-	item_top_pad("item_top_pad"),
-	creation_date()
-{}
-
-// Default constructor
-LLFolderViewItem::LLFolderViewItem(const LLFolderViewItem::Params& p)
-:	LLView(p),
-	mLabelWidth(0),
-	mLabelWidthDirty(false),
-	mParentFolder( NULL ),
-	mIsSelected( FALSE ),
-	mIsCurSelection( FALSE ),
-	mSelectPending(FALSE),
-	mLabelStyle( LLFontGL::NORMAL ),
-	mHasVisibleChildren(FALSE),
-	mIndentation(0),
-	mItemHeight(p.item_height),
-	mPassedFilter(FALSE),
-	mLastFilterGeneration(-1),
-	mStringMatchOffset(std::string::npos),
-	mControlLabelRotation(0.f),
-	mDragAndDropTarget(FALSE),
-	mIsLoading(FALSE),
-	mLabel(p.name),
-	mRoot(p.root),
-	mCreationDate(p.creation_date),
-	mIcon(p.icon),
-	mIconOpen(p.icon_open),
-	mIconOverlay(p.icon_overlay),
-	mListener(p.listener),
-	mShowLoadStatus(false),
-	mIsMouseOverTitle(false)
-{
-}
-
-BOOL LLFolderViewItem::postBuild()
-{
-	refresh();
-	return TRUE;
-}
-
-// Destroys the object
-LLFolderViewItem::~LLFolderViewItem( void )
-{
-	delete mListener;
-	mListener = NULL;
-}
-
-LLFolderView* LLFolderViewItem::getRoot()
-{
-	return mRoot;
-}
-
-// Returns true if this object is a child (or grandchild, etc.) of potential_ancestor.
-BOOL LLFolderViewItem::isDescendantOf( const LLFolderViewFolder* potential_ancestor )
-{
-	LLFolderViewItem* root = this;
-	while( root->mParentFolder )
-	{
-		if( root->mParentFolder == potential_ancestor )
-		{
-			return TRUE;
-		}
-		root = root->mParentFolder;
-	}
-	return FALSE;
-}
-
-LLFolderViewItem* LLFolderViewItem::getNextOpenNode(BOOL include_children)
-{
-	if (!mParentFolder)
-	{
-		return NULL;
-	}
-
-	LLFolderViewItem* itemp = mParentFolder->getNextFromChild( this, include_children );
-	while(itemp && !itemp->getVisible())
-	{
-		LLFolderViewItem* next_itemp = itemp->mParentFolder->getNextFromChild( itemp, include_children );
-		if (itemp == next_itemp) 
-		{
-			// hit last item
-			return itemp->getVisible() ? itemp : this;
-		}
-		itemp = next_itemp;
-	}
-
-	return itemp;
-}
-
-LLFolderViewItem* LLFolderViewItem::getPreviousOpenNode(BOOL include_children)
-{
-	if (!mParentFolder)
-	{
-		return NULL;
-	}
-
-	LLFolderViewItem* itemp = mParentFolder->getPreviousFromChild( this, include_children );
-
-	// Skip over items that are invisible or are hidden from the UI.
-	while(itemp && !itemp->getVisible())
-	{
-		LLFolderViewItem* next_itemp = itemp->mParentFolder->getPreviousFromChild( itemp, include_children );
-		if (itemp == next_itemp) 
-		{
-			// hit first item
-			return itemp->getVisible() ? itemp : this;
-		}
-		itemp = next_itemp;
-	}
-
-	return itemp;
-}
-
-// is this item something we think we should be showing?
-// for example, if we haven't gotten around to filtering it yet, then the answer is yes
-// until we find out otherwise
-BOOL LLFolderViewItem::potentiallyVisible()
-{
-	// we haven't been checked against min required filter
-	// or we have and we passed
-	return potentiallyFiltered();
-}
-
-BOOL LLFolderViewItem::potentiallyFiltered()
-{
-	return getLastFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration() || getFiltered();
-}
-
-BOOL LLFolderViewItem::getFiltered() 
-{ 
-	return mPassedFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration(); 
-}
-
-BOOL LLFolderViewItem::getFiltered(S32 filter_generation) 
-{
-	return mPassedFilter && mLastFilterGeneration >= filter_generation;
-}
-
-void LLFolderViewItem::setFiltered(BOOL filtered, S32 filter_generation)
-{
-	mPassedFilter = filtered;
-	mLastFilterGeneration = filter_generation;
-}
-
-void LLFolderViewItem::setIcon(LLUIImagePtr icon)
-{
-	mIcon = icon;
-}
-
-// refresh information from the listener
-void LLFolderViewItem::refreshFromListener()
-{
-	if(mListener)
-	{
-		mLabel = mListener->getDisplayName();
-		LLFolderType::EType preferred_type = mListener->getPreferredType();
-
-		// *TODO: to be removed when database supports multi language. This is a
-		// temporary attempt to display the inventory folder in the user locale.
-		// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
-		//		it uses the same way to find localized string
-
-		// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
-		// Translation of Accessories folder in Library inventory folder
-		bool accessories = false;
-		if(mLabel == std::string("Accessories"))
-		{
-			//To ensure that Accessories folder is in Library we have to check its parent folder.
-			//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
-			LLInventoryCategory* cat = gInventory.getCategory(mListener->getUUID());
-			if(cat)
-			{
-				const LLUUID& parent_folder_id = cat->getParentUUID();
-				accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
-			}
-		}
-
-		//"Accessories" inventory category has folder type FT_NONE. So, this folder
-		//can not be detected as protected with LLFolderType::lookupIsProtectedType
-		if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
-		{
-			LLTrans::findString(mLabel, "InvFolder " + mLabel);
-		};
-
-		setToolTip(mLabel);
-		setIcon(mListener->getIcon());
-		time_t creation_date = mListener->getCreationDate();
-		if ((creation_date > 0) && (mCreationDate != creation_date))
-		{
-			setCreationDate(creation_date);
-			dirtyFilter();
-		}
-		if (mRoot->useLabelSuffix())
-		{
-			mLabelStyle = mListener->getLabelStyle();
-			mLabelSuffix = mListener->getLabelSuffix();
-		}
-	}
-}
-
-void LLFolderViewItem::refresh()
-{
-	refreshFromListener();
-
-	std::string searchable_label(mLabel);
-	searchable_label.append(mLabelSuffix);
-	LLStringUtil::toUpper(searchable_label);
-
-	if (mSearchableLabel.compare(searchable_label))
-	{
-		mSearchableLabel.assign(searchable_label);
-		dirtyFilter();
-		// some part of label has changed, so overall width has potentially changed, and sort order too
-		if (mParentFolder)
-		{
-			mParentFolder->requestSort();
-			mParentFolder->requestArrange();
-		}
-	}
-
-	mLabelWidthDirty = true;
-}
-
-void LLFolderViewItem::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
-	functor(mListener);
-}
-
-// This function is called when items are added or view filters change. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::filterFromRoot( void )
-{
-	LLFolderViewItem* root = getRoot();
-
-	root->filter(*((LLFolderView*)root)->getFilter());
-}
-
-// This function is called when the folder view is dirty. It's
-// implemented here but called by derived classes when folding the
-// views.
-void LLFolderViewItem::arrangeFromRoot()
-{
-	LLFolderViewItem* root = getRoot();
-
-	S32 height = 0;
-	S32 width = 0;
-	S32 total_height = root->arrange( &width, &height, 0 );
-
-	LLSD params;
-	params["action"] = "size_changes";
-	params["height"] = total_height;
-	getParent()->notifyParent(params);
-}
-
-// Utility function for LLFolderView
-void LLFolderViewItem::arrangeAndSet(BOOL set_selection,
-									 BOOL take_keyboard_focus)
-{
-	LLFolderView* root = getRoot();
-	if (getParentFolder())
-	{
-	getParentFolder()->requestArrange();
-	}
-	if(set_selection)
-	{
-		setSelectionFromRoot(this, TRUE, take_keyboard_focus);
-		if(root)
-		{
-			root->scrollToShowSelection();
-		}
-	}		
-}
-
-// This function clears the currently selected item, and records the
-// specified selected item appropriately for display and use in the
-// UI. If open is TRUE, then folders are opened up along the way to
-// the selection.
-void LLFolderViewItem::setSelectionFromRoot(LLFolderViewItem* selection,
-											BOOL openitem,
-											BOOL take_keyboard_focus)
-{
-	getRoot()->setSelection(selection, openitem, take_keyboard_focus);
-}
-
-// helper function to change the selection from the root.
-void LLFolderViewItem::changeSelectionFromRoot(LLFolderViewItem* selection, BOOL selected)
-{
-	getRoot()->changeSelection(selection, selected);
-}
-
-std::set<LLUUID> LLFolderViewItem::getSelectionList() const
-{
-	std::set<LLUUID> selection;
-	return selection;
-}
-
-EInventorySortGroup LLFolderViewItem::getSortGroup()  const
-{ 
-	return SG_ITEM; 
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
-	if (!folder)
-	{
-		return FALSE;
-	}
-	mParentFolder = folder;
-	root->addItemID(getListener()->getUUID(), this);
-	return folder->addItem(this);
-}
-
-
-// Finds width and height of this object and its children.  Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewItem::arrange( S32* width, S32* height, S32 filter_generation)
-{
-	const Params& p = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	S32 indentation = p.folder_indentation();
-	// Only indent deeper items in hierarchy
-	mIndentation = (getParentFolder() 
-					&& getParentFolder()->getParentFolder() )
-		? mParentFolder->getIndentation() + indentation
-		: 0;
-	if (mLabelWidthDirty)
-	{
-		mLabelWidth = ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + getLabelFontForStyle(mLabelStyle)->getWidth(mLabel) + getLabelFontForStyle(mLabelStyle)->getWidth(mLabelSuffix) + TEXT_PAD_RIGHT; 
-		mLabelWidthDirty = false;
-	}
-
-	*width = llmax(*width, mLabelWidth + mIndentation); 
-
-	// determine if we need to use ellipses to avoid horizontal scroll. EXT-719
-	bool use_ellipses = getRoot()->getUseEllipses();
-	if (use_ellipses)
-	{
-		// limit to set rect to avoid horizontal scrollbar
-		*width = llmin(*width, getRoot()->getRect().getWidth());
-	}
-	*height = getItemHeight();
-	return *height;
-}
-
-S32 LLFolderViewItem::getItemHeight()
-{
-	return mItemHeight;
-}
-
-void LLFolderViewItem::filter( LLInventoryFilter& filter)
-{
-	const BOOL previous_passed_filter = mPassedFilter;
-	const BOOL passed_filter = filter.check(this);
-
-	// If our visibility will change as a result of this filter, then
-	// we need to be rearranged in our parent folder
-	if (mParentFolder)
-	{
-		if (getVisible() != passed_filter
-			||	previous_passed_filter != passed_filter )
-			mParentFolder->requestArrange();
-	}
-
-	setFiltered(passed_filter, filter.getCurrentGeneration());
-	mStringMatchOffset = filter.getStringMatchOffset();
-	filter.decrementFilterCount();
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-	}
-}
-
-void LLFolderViewItem::dirtyFilter()
-{
-	mLastFilterGeneration = -1;
-	// bubble up dirty flag all the way to root
-	if (getParentFolder())
-	{
-		getParentFolder()->setCompletedFilterGeneration(-1, TRUE);
-	}
-}
-
-// *TODO: This can be optimized a lot by simply recording that it is
-// selected in the appropriate places, and assuming that set selection
-// means 'deselect' for a leaf item. Do this optimization after
-// multiple selection is implemented to make sure it all plays nice
-// together.
-BOOL LLFolderViewItem::setSelection(LLFolderViewItem* selection, BOOL openitem, BOOL take_keyboard_focus)
-{
-	if (selection == this && !mIsSelected)
-	{
-		selectItem();
-	}
-	else if (mIsSelected)	// Deselect everything else.
-	{
-		deselectItem();
-	}
-	return mIsSelected;
-}
-
-BOOL LLFolderViewItem::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
-	if (selection == this)
-	{
-		if (mIsSelected)
-		{
-			deselectItem();
-		}
-		else
-		{
-			selectItem();
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-void LLFolderViewItem::deselectItem(void)
-{
-	mIsSelected = FALSE;
-}
-
-void LLFolderViewItem::selectItem(void)
-{
-	if (mIsSelected == FALSE)
-	{
-		if (mListener)
-		{
-			mListener->selectItem();
-		}
-		mIsSelected = TRUE;
-	}
-}
-
-BOOL LLFolderViewItem::isMovable()
-{
-	if( mListener )
-	{
-		return mListener->isItemMovable();
-	}
-	else
-	{
-		return TRUE;
-	}
-}
-
-BOOL LLFolderViewItem::isRemovable()
-{
-	if( mListener )
-	{
-		return mListener->isItemRemovable();
-	}
-	else
-	{
-		return TRUE;
-	}
-}
-
-void LLFolderViewItem::destroyView()
-{
-	if (mParentFolder)
-	{
-		// removeView deletes me
-		mParentFolder->removeView(this);
-	}
-}
-
-// Call through to the viewed object and return true if it can be
-// removed.
-//BOOL LLFolderViewItem::removeRecursively(BOOL single_item)
-BOOL LLFolderViewItem::remove()
-{
-	if(!isRemovable())
-	{
-		return FALSE;
-	}
-	if(mListener)
-	{
-		return mListener->removeItem();
-	}
-	return TRUE;
-}
-
-// Build an appropriate context menu for the item.
-void LLFolderViewItem::buildContextMenu(LLMenuGL& menu, U32 flags)
-{
-	if(mListener)
-	{
-		mListener->buildContextMenu(menu, flags);
-	}
-}
-
-void LLFolderViewItem::openItem( void )
-{
-	if( mListener )
-	{
-		mListener->openItem();
-	}
-}
-
-void LLFolderViewItem::preview( void )
-{
-	if (mListener)
-	{
-		mListener->previewItem();
-	}
-}
-
-void LLFolderViewItem::rename(const std::string& new_name)
-{
-	if( !new_name.empty() )
-	{
-		if( mListener )
-		{
-			mListener->renameItem(new_name);
-
-			if(mParentFolder)
-			{
-				mParentFolder->requestSort();
-			}
-		}
-	}
-}
-
-const std::string& LLFolderViewItem::getSearchableLabel() const
-{
-	return mSearchableLabel;
-}
-
-LLViewerInventoryItem * LLFolderViewItem::getInventoryItem(void)
-{
-	if (!getListener()) return NULL;
-	return gInventory.getItem(getListener()->getUUID());
-}
-
-const std::string& LLFolderViewItem::getName( void ) const
-{
-	if(mListener)
-	{
-		return mListener->getName();
-	}
-	return mLabel;
-}
-
-// LLView functionality
-BOOL LLFolderViewItem::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
-	if(!mIsSelected)
-	{
-		setSelectionFromRoot(this, FALSE);
-	}
-	make_ui_sound("UISndClick");
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	if (LLView::childrenHandleMouseDown(x, y, mask))
-	{
-		return TRUE;
-	}
-	
-	// No handler needed for focus lost since this class has no
-	// state that depends on it.
-	gFocusMgr.setMouseCapture( this );
-
-	if (!mIsSelected)
-	{
-		if(mask & MASK_CONTROL)
-		{
-			changeSelectionFromRoot(this, !mIsSelected);
-		}
-		else if (mask & MASK_SHIFT)
-		{
-			getParentFolder()->extendSelectionTo(this);
-		}
-		else
-		{
-			setSelectionFromRoot(this, FALSE);
-		}
-		make_ui_sound("UISndClick");
-	}
-	else
-	{
-		mSelectPending = TRUE;
-	}
-
-	if( isMovable() )
-	{
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y );
-		LLToolDragAndDrop::getInstance()->setDragStart( screen_x, screen_y );
-	}
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleHover( S32 x, S32 y, MASK mask )
-{
-	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
-	if( hasMouseCapture() && isMovable() )
-	{
-		S32 screen_x;
-		S32 screen_y;
-		localPointToScreen(x, y, &screen_x, &screen_y );
-		BOOL can_drag = TRUE;
-		if( LLToolDragAndDrop::getInstance()->isOverThreshold( screen_x, screen_y ) )
-		{
-			LLFolderView* root = getRoot();
-
-			if(root->getCurSelectedItem())
-			{
-				LLToolDragAndDrop::ESource src = LLToolDragAndDrop::SOURCE_WORLD;
-
-				// *TODO: push this into listener and remove
-				// dependency on llagent
-				if (mListener
-					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getRootFolderID()))
-				{
-					src = LLToolDragAndDrop::SOURCE_AGENT;
-				}
-				else if (mListener
-					&& gInventory.isObjectDescendentOf(mListener->getUUID(), gInventory.getLibraryRootFolderID()))
-				{
-					src = LLToolDragAndDrop::SOURCE_LIBRARY;
-				}
-
-				can_drag = root->startDrag(src);
-				if (can_drag)
-				{
-					// if (mListener) mListener->startDrag();
-					// RN: when starting drag and drop, clear out last auto-open
-					root->autoOpenTest(NULL);
-					root->setShowSelectionContext(TRUE);
-
-					// Release keyboard focus, so that if stuff is dropped into the
-					// world, pressing the delete key won't blow away the inventory
-					// item.
-					gFocusMgr.setKeyboardFocus(NULL);
-
-					return LLToolDragAndDrop::getInstance()->handleHover( x, y, mask );
-				}
-			}
-		}
-
-		if (can_drag)
-		{
-			gViewerWindow->setCursor(UI_CURSOR_ARROW);
-		}
-		else
-		{
-			gViewerWindow->setCursor(UI_CURSOR_NOLOCKED);
-		}
-		return TRUE;
-	}
-	else
-	{
-		getRoot()->setShowSelectionContext(FALSE);
-		gViewerWindow->setCursor(UI_CURSOR_ARROW);
-		// let parent handle this then...
-		return FALSE;
-	}
-}
-
-
-BOOL LLFolderViewItem::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
-	preview();
-	return TRUE;
-}
-
-BOOL LLFolderViewItem::handleMouseUp( S32 x, S32 y, MASK mask )
-{
-	if (LLView::childrenHandleMouseUp(x, y, mask))
-	{
-		return TRUE;
-	}
-	
-	// if mouse hasn't moved since mouse down...
-	if ( pointInView(x, y) && mSelectPending )
-	{
-		//...then select
-		if(mask & MASK_CONTROL)
-		{
-			changeSelectionFromRoot(this, !mIsSelected);
-		}
-		else if (mask & MASK_SHIFT)
-		{
-			getParentFolder()->extendSelectionTo(this);
-		}
-		else
-		{
-			setSelectionFromRoot(this, FALSE);
-		}
-	}
-
-	mSelectPending = FALSE;
-
-	if( hasMouseCapture() )
-	{
-		getRoot()->setShowSelectionContext(FALSE);
-		gFocusMgr.setMouseCapture( NULL );
-	}
-	return TRUE;
-}
-
-void LLFolderViewItem::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	mIsMouseOverTitle = false;
-}
-
-BOOL LLFolderViewItem::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
-										 EDragAndDropType cargo_type,
-										 void* cargo_data,
-										 EAcceptance* accept,
-										 std::string& tooltip_msg)
-{
-	BOOL accepted = FALSE;
-	BOOL handled = FALSE;
-	if(mListener)
-	{
-		accepted = mListener->dragOrDrop(mask,drop,cargo_type,cargo_data, tooltip_msg);
-		handled = accepted;
-		if (accepted)
-		{
-			mDragAndDropTarget = TRUE;
-			*accept = ACCEPT_YES_MULTI;
-		}
-		else
-		{
-			*accept = ACCEPT_NO;
-		}
-	}
-	if(mParentFolder && !handled)
-	{
-		// store this item to get it in LLFolderBridge::dragItemIntoFolder on drop event.
-		mRoot->setDraggingOverItem(this);
-		handled = mParentFolder->handleDragAndDropFromChild(mask,drop,cargo_type,cargo_data,accept,tooltip_msg);
-		mRoot->setDraggingOverItem(NULL);
-	}
-	if (handled)
-	{
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewItem" << llendl;
-	}
-
-	return handled;
-}
-
-void LLFolderViewItem::draw()
-{
-	static LLUIColor sFgColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightBgColor = LLUIColorTable::instance().getColor("MenuItemHighlightBgColor", DEFAULT_WHITE);
-	static LLUIColor sHighlightFgColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
-	static LLUIColor sFocusOutlineColor = LLUIColorTable::instance().getColor("InventoryFocusOutlineColor", DEFAULT_WHITE);
-	static LLUIColor sFilterBGColor = LLUIColorTable::instance().getColor("FilterBackgroundColor", DEFAULT_WHITE);
-	static LLUIColor sFilterTextColor = LLUIColorTable::instance().getColor("FilterTextColor", DEFAULT_WHITE);
-	static LLUIColor sSuffixColor = LLUIColorTable::instance().getColor("InventoryItemColor", DEFAULT_WHITE);
-	static LLUIColor sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
-	static LLUIColor sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
-	static LLUIColor sSearchStatusColor = LLUIColorTable::instance().getColor("InventorySearchStatusColor", DEFAULT_WHITE);
-	static LLUIColor sMouseOverColor = LLUIColorTable::instance().getColor("InventoryMouseOverColor", DEFAULT_WHITE);
-
-	const Params& default_params = LLUICtrlFactory::getDefaultParams<LLFolderViewItem>();
-	const S32 TOP_PAD = default_params.item_top_pad;
-	const S32 FOCUS_LEFT = 1;
-	const LLFontGL* font = getLabelFontForStyle(mLabelStyle);
-
-	const BOOL in_inventory = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getRootFolderID());
-	const BOOL in_library = getListener() && gInventory.isObjectDescendentOf(getListener()->getUUID(), gInventory.getLibraryRootFolderID());
-
-	//--------------------------------------------------------------------------------//
-	// Draw open folder arrow
-	//
-	const bool up_to_date = mListener && mListener->isUpToDate();
-	const bool possibly_has_children = ((up_to_date && hasVisibleChildren()) // we fetched our children and some of them have passed the filter...
-										|| (!up_to_date && mListener && mListener->hasChildren())); // ...or we know we have children but haven't fetched them (doesn't obey filter)
-	if (possibly_has_children)
-	{
-		LLUIImage* arrow_image = default_params.folder_arrow_image;
-		gl_draw_scaled_rotated_image(
-			mIndentation, getRect().getHeight() - ARROW_SIZE - TEXT_PAD - TOP_PAD,
-			ARROW_SIZE, ARROW_SIZE, mControlLabelRotation, arrow_image->getImage(), sFgColor);
-	}
-
-
-	//--------------------------------------------------------------------------------//
-	// Draw highlight for selected items
-	//
-	const BOOL show_context = getRoot()->getShowSelectionContext();
-	const BOOL filled = show_context || (getRoot()->getParentPanel()->hasFocus()); // If we have keyboard focus, draw selection filled
-	const S32 focus_top = getRect().getHeight();
-	const S32 focus_bottom = getRect().getHeight() - mItemHeight;
-	const bool folder_open = (getRect().getHeight() > mItemHeight + 4);
-	if (mIsSelected) // always render "current" item.  Only render other selected items if mShowSingleSelection is FALSE
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		LLColor4 bg_color = sHighlightBgColor;
-		if (!mIsCurSelection)
-		{
-			// do time-based fade of extra objects
-			F32 fade_time = getRoot()->getSelectionFadeElapsedTime();
-			if (getRoot()->getShowSingleSelection())
-			{
-				// fading out
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, bg_color.mV[VALPHA], 0.f);
-			}
-			else
-			{
-				// fading in
-				bg_color.mV[VALPHA] = clamp_rescale(fade_time, 0.f, 0.4f, 0.f, bg_color.mV[VALPHA]);
-			}
-		}
-		gl_rect_2d(FOCUS_LEFT,
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   bg_color, filled);
-		if (mIsCurSelection)
-		{
-			gl_rect_2d(FOCUS_LEFT, 
-					   focus_top, 
-					   getRect().getWidth() - 2,
-					   focus_bottom,
-					   sFocusOutlineColor, FALSE);
-		}
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sFocusOutlineColor, FALSE);
-			if (show_context)
-			{
-				gl_rect_2d(FOCUS_LEFT,
-						   focus_bottom + 1,
-						   getRect().getWidth() - 2,
-						   0,
-						   sHighlightBgColor, TRUE);
-			}
-		}
-	}
-	else if (mIsMouseOverTitle)
-	{
-		gl_rect_2d(FOCUS_LEFT,
-			focus_top, 
-			getRect().getWidth() - 2,
-			focus_bottom,
-			sMouseOverColor, FALSE);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw DragNDrop highlight
-	//
-	if (mDragAndDropTarget)
-	{
-		gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-		gl_rect_2d(FOCUS_LEFT, 
-				   focus_top, 
-				   getRect().getWidth() - 2,
-				   focus_bottom,
-				   sHighlightBgColor, FALSE);
-		if (folder_open)
-		{
-			gl_rect_2d(FOCUS_LEFT,
-					   focus_bottom + 1, // overlap with bottom edge of above rect
-					   getRect().getWidth() - 2,
-					   0,
-					   sHighlightBgColor, FALSE);
-		}
-		mDragAndDropTarget = FALSE;
-	}
-
-	const LLViewerInventoryItem *item = getInventoryItem();
-	const BOOL highlight_link = mIconOverlay && item && item->getIsLinkType();
-	//--------------------------------------------------------------------------------//
-	// Draw open icon
-	//
-	const S32 icon_x = mIndentation + ARROW_SIZE + TEXT_PAD;
-	if (!mIconOpen.isNull() && (llabs(mControlLabelRotation) > 80)) // For open folders
- 	{
-		mIconOpen->draw(icon_x, getRect().getHeight() - mIconOpen->getHeight() - TOP_PAD + 1);
-	}
-	else if (mIcon)
-	{
- 		mIcon->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
- 	}
-
-	if (highlight_link)
-	{
-		mIconOverlay->draw(icon_x, getRect().getHeight() - mIcon->getHeight() - TOP_PAD + 1);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Exit if no label to draw
-	//
-	if (mLabel.empty())
-	{
-		return;
-	}
-
-	LLColor4 color = (mIsSelected && filled) ? sHighlightFgColor : sFgColor;
-	if (highlight_link) color = sLinkColor;
-	if (in_library) color = sLibraryColor;
-	
-	F32 right_x  = 0;
-	F32 y = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-	F32 text_left = (F32)(ARROW_SIZE + TEXT_PAD + ICON_WIDTH + ICON_PAD + mIndentation);
-
-	//--------------------------------------------------------------------------------//
-	// Highlight filtered text
-	//
-	if (getRoot()->getDebugFilters())
-	{
-		if (!getFiltered() && !possibly_has_children)
-		{
-			color.mV[VALPHA] *= 0.5f;
-		}
-		LLColor4 filter_color = mLastFilterGeneration >= getRoot()->getFilter()->getCurrentGeneration() ? 
-			LLColor4(0.5f, 0.8f, 0.5f, 1.f) : 
-			LLColor4(0.8f, 0.5f, 0.5f, 1.f);
-		LLFontGL::getFontMonospace()->renderUTF8(mStatusText, 0, text_left, y, filter_color,
-												 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-												 S32_MAX, S32_MAX, &right_x, FALSE );
-		text_left = right_x;
-	}
-	//--------------------------------------------------------------------------------//
-	// Draw the actual label text
-	//
-	font->renderUTF8(mLabel, 0, text_left, y, color,
-					 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-					 S32_MAX, getRect().getWidth() - (S32) text_left, &right_x, TRUE);
-
-	//--------------------------------------------------------------------------------//
-	// Draw "Loading..." text
-	//
-	bool root_is_loading = false;
-	if (in_inventory)
-	{
-		root_is_loading = LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress(); 
-	}
-	if (in_library)
-	{
-		root_is_loading = LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
-	}
-	if ((mIsLoading
-		&&	mTimeSinceRequestStart.getElapsedTimeF32() >= gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
-			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive()
-				&&	root_is_loading
-				&&	mShowLoadStatus))
-	{
-		std::string load_string = " ( " + LLTrans::getString("LoadingData") + " ) ";
-		font->renderUTF8(load_string, 0, right_x, y, sSearchStatusColor,
-						 LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW, 
-						 S32_MAX, S32_MAX, &right_x, FALSE);
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Draw label suffix
-	//
-	if (!mLabelSuffix.empty())
-	{
-		font->renderUTF8( mLabelSuffix, 0, right_x, y, sSuffixColor,
-						  LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-						  S32_MAX, S32_MAX, &right_x, FALSE );
-	}
-
-	//--------------------------------------------------------------------------------//
-	// Highlight string match
-	//
-	if (mStringMatchOffset != std::string::npos)
-	{
-		// don't draw backgrounds for zero-length strings
-		S32 filter_string_length = getRoot()->getFilterSubString().size();
-		if (filter_string_length > 0)
-		{
-			std::string combined_string = mLabel + mLabelSuffix;
-			S32 left = llround(text_left) + font->getWidth(combined_string, 0, mStringMatchOffset) - 1;
-			S32 right = left + font->getWidth(combined_string, mStringMatchOffset, filter_string_length) + 2;
-			S32 bottom = llfloor(getRect().getHeight() - font->getLineHeight() - 3 - TOP_PAD);
-			S32 top = getRect().getHeight() - TOP_PAD;
-		
-			LLUIImage* box_image = default_params.selection_image;
-			LLRect box_rect(left, top, right, bottom);
-			box_image->draw(box_rect, sFilterBGColor);
-			F32 match_string_left = text_left + font->getWidthF32(combined_string, 0, mStringMatchOffset);
-			F32 yy = (F32)getRect().getHeight() - font->getLineHeight() - (F32)TEXT_PAD - (F32)TOP_PAD;
-			font->renderUTF8( combined_string, mStringMatchOffset, match_string_left, yy,
-							  sFilterTextColor, LLFontGL::LEFT, LLFontGL::BOTTOM, LLFontGL::NORMAL, LLFontGL::NO_SHADOW,
-							  filter_string_length, S32_MAX, &right_x, FALSE );
-		}
-	}
-}
-
-bool LLFolderViewItem::isInSelection() const
-{
-	return mIsSelected || (mParentFolder && mParentFolder->isInSelection());
-}
-
-///----------------------------------------------------------------------------
-/// Class LLFolderViewFolder
-///----------------------------------------------------------------------------
-
-LLFolderViewFolder::LLFolderViewFolder( const LLFolderViewItem::Params& p ): 
-	LLFolderViewItem( p ),	// 0 = no create time
-	mIsOpen(FALSE),
-	mExpanderHighlighted(FALSE),
-	mCurHeight(0.f),
-	mTargetHeight(0.f),
-	mAutoOpenCountdown(0.f),
-	mSubtreeCreationDate(0),
-	mAmTrash(LLFolderViewFolder::UNKNOWN),
-	mLastArrangeGeneration( -1 ),
-	mLastCalculatedWidth(0),
-	mCompletedFilterGeneration(-1),
-	mMostFilteredDescendantGeneration(-1),
-	mNeedsSort(false),
-	mPassedFolderFilter(FALSE)
-{
-}
-
-// Destroys the object
-LLFolderViewFolder::~LLFolderViewFolder( void )
-{
-	// The LLView base class takes care of object destruction. make sure that we
-	// don't have mouse or keyboard focus
-	gFocusMgr.releaseFocusIfNeeded( this ); // calls onCommit()
-}
-
-void LLFolderViewFolder::setFilteredFolder(bool filtered, S32 filter_generation)
-{
-	mPassedFolderFilter = filtered;
-	mLastFilterGeneration = filter_generation;
-}
-
-bool LLFolderViewFolder::getFilteredFolder(S32 filter_generation)
-{
-	return mPassedFolderFilter && mLastFilterGeneration >= getRoot()->getFilter()->getMinRequiredGeneration();
-}
-
-// addToFolder() returns TRUE if it succeeds. FALSE otherwise
-BOOL LLFolderViewFolder::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
-{
-	if (!folder)
-	{
-		return FALSE;
-	}
-	mParentFolder = folder;
-	root->addItemID(getListener()->getUUID(), this);
-	return folder->addFolder(this);
-}
-
-// Finds width and height of this object and its children. Also
-// makes sure that this view and its children are the right size.
-S32 LLFolderViewFolder::arrange( S32* width, S32* height, S32 filter_generation)
-{
-	// sort before laying out contents
-	if (mNeedsSort)
-	{
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-		mNeedsSort = false;
-	}
-
-	// evaluate mHasVisibleChildren
-	mHasVisibleChildren = false;
-	if (hasFilteredDescendants(filter_generation))
-	{
-		// We have to verify that there's at least one child that's not filtered out
-		bool found = false;
-		// Try the items first
-		for (items_t::iterator iit = mItems.begin(); iit != mItems.end(); ++iit)
-		{
-			LLFolderViewItem* itemp = (*iit);
-			found = (itemp->getFiltered(filter_generation));
-			if (found)
-				break;
-		}
-		if (!found)
-		{
-			// If no item found, try the folders
-			for (folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
-			{
-				LLFolderViewFolder* folderp = (*fit);
-				found = ( folderp->getListener()
-								&&	(folderp->getFiltered(filter_generation)
-									 ||	(folderp->getFilteredFolder(filter_generation) 
-										 && folderp->hasFilteredDescendants(filter_generation))));
-				if (found)
-					break;
-			}
-		}
-
-		mHasVisibleChildren = found;
-	}
-
-	// calculate height as a single item (without any children), and reshapes rectangle to match
-	LLFolderViewItem::arrange( width, height, filter_generation );
-
-	// clamp existing animated height so as to never get smaller than a single item
-	mCurHeight = llmax((F32)*height, mCurHeight);
-
-	// initialize running height value as height of single item in case we have no children
-	*height = getItemHeight();
-	F32 running_height = (F32)*height;
-	F32 target_height = (F32)*height;
-
-	// are my children visible?
-	if (needsArrange())
-	{
-		// set last arrange generation first, in case children are animating
-		// and need to be arranged again
-		mLastArrangeGeneration = getRoot()->getArrangeGeneration();
-		if (mIsOpen)
-		{
-			// Add sizes of children
-			S32 parent_item_height = getRect().getHeight();
-
-			for(folders_t::iterator fit = mFolders.begin(); fit != mFolders.end(); ++fit)
-			{
-				LLFolderViewFolder* folderp = (*fit);
-				if (getRoot()->getDebugFilters())
-				{
-					folderp->setVisible(TRUE);
-				}
-				else
-				{
-					folderp->setVisible( folderp->getListener()
-										&&	(folderp->getFiltered(filter_generation)
-											||	(folderp->getFilteredFolder(filter_generation) 
-												&& folderp->hasFilteredDescendants(filter_generation)))); // passed filter or has descendants that passed filter
-				}
-
-				if (folderp->getVisible())
-				{
-					S32 child_width = *width;
-					S32 child_height = 0;
-					S32 child_top = parent_item_height - llround(running_height);
-
-					target_height += folderp->arrange( &child_width, &child_height, filter_generation );
-
-					running_height += (F32)child_height;
-					*width = llmax(*width, child_width);
-					folderp->setOrigin( 0, child_top - folderp->getRect().getHeight() );
-				}
-			}
-			for(items_t::iterator iit = mItems.begin();
-				iit != mItems.end(); ++iit)
-			{
-				LLFolderViewItem* itemp = (*iit);
-				if (getRoot()->getDebugFilters())
-				{
-					itemp->setVisible(TRUE);
-				}
-				else
-				{
-					itemp->setVisible(itemp->getFiltered(filter_generation));
-				}
-
-				if (itemp->getVisible())
-				{
-					S32 child_width = *width;
-					S32 child_height = 0;
-					S32 child_top = parent_item_height - llround(running_height);
-
-					target_height += itemp->arrange( &child_width, &child_height, filter_generation );
-					// don't change width, as this item is as wide as its parent folder by construction
-					itemp->reshape( itemp->getRect().getWidth(), child_height);
-
-					running_height += (F32)child_height;
-					*width = llmax(*width, child_width);
-					itemp->setOrigin( 0, child_top - itemp->getRect().getHeight() );
-				}
-			}
-		}
-
-		mTargetHeight = target_height;
-		// cache this width so next time we can just return it
-		mLastCalculatedWidth = *width;
-	}
-	else
-	{
-		// just use existing width
-		*width = mLastCalculatedWidth;
-	}
-
-	// animate current height towards target height
-	if (llabs(mCurHeight - mTargetHeight) > 1.f)
-	{
-		mCurHeight = lerp(mCurHeight, mTargetHeight, LLCriticalDamp::getInterpolant(mIsOpen ? FOLDER_OPEN_TIME_CONSTANT : FOLDER_CLOSE_TIME_CONSTANT));
-
-		requestArrange();
-
-		// hide child elements that fall out of current animated height
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			// number of pixels that bottom of folder label is from top of parent folder
-			if (getRect().getHeight() - (*fit)->getRect().mTop + (*fit)->getItemHeight() 
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
-			{
-				// hide if beyond current folder height
-				(*fit)->setVisible(FALSE);
-			}
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			// number of pixels that bottom of item label is from top of parent folder
-			if (getRect().getHeight() - (*iit)->getRect().mBottom
-				> llround(mCurHeight) + MAX_FOLDER_ITEM_OVERLAP)
-			{
-				(*iit)->setVisible(FALSE);
-			}
-		}
-	}
-	else
-	{
-		mCurHeight = mTargetHeight;
-	}
-
-	// don't change width as this item is already as wide as its parent folder
-	reshape(getRect().getWidth(),llround(mCurHeight));
-
-	// pass current height value back to parent
-	*height = llround(mCurHeight);
-
-	return llround(mTargetHeight);
-}
-
-BOOL LLFolderViewFolder::needsArrange()
-{
-	return mLastArrangeGeneration < getRoot()->getArrangeGeneration(); 
-}
-
-void LLFolderViewFolder::requestSort()
-{
-	mNeedsSort = true;
-	// whenever item order changes, we need to lay things out again
-	requestArrange();
-}
-
-void LLFolderViewFolder::setCompletedFilterGeneration(S32 generation, BOOL recurse_up)
-{
-	//mMostFilteredDescendantGeneration = llmin(mMostFilteredDescendantGeneration, generation);
-	mCompletedFilterGeneration = generation;
-	// only aggregate up if we are a lower (older) value
-	if (recurse_up
-		&& mParentFolder
-		&& generation < mParentFolder->getCompletedFilterGeneration())
-	{
-		mParentFolder->setCompletedFilterGeneration(generation, TRUE);
-	}
-}
-
-void LLFolderViewFolder::filter( LLInventoryFilter& filter)
-{
-	S32 filter_generation = filter.getCurrentGeneration();
-	// if failed to pass filter newer than must_pass_generation
-	// you will automatically fail this time, so we only
-	// check against items that have passed the filter
-	S32 must_pass_generation = filter.getMustPassGeneration();
-	
-	bool autoopen_folders = (filter.hasFilterString());
-
-	// if we have already been filtered against this generation, skip out
-	if (getCompletedFilterGeneration() >= filter_generation)
-	{
-		return;
-	}
-
-	// filter folder itself
-	if (getLastFilterGeneration() < filter_generation)
-	{
-		if (getLastFilterGeneration() >= must_pass_generation	// folder has been compared to a valid precursor filter
-			&& !mPassedFilter)									// and did not pass the filter
-		{
-			// go ahead and flag this folder as done
-			mLastFilterGeneration = filter_generation;
-			mStringMatchOffset = std::string::npos;
-		}
-		else // filter self only on first pass through
-		{
-			// filter against folder rules
-			filterFolder(filter);
-			// and then item rules
-			LLFolderViewItem::filter( filter );
-		}
-	}
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-		mStatusText += llformat("(%d)", mCompletedFilterGeneration);
-		mStatusText += llformat("+%d", mMostFilteredDescendantGeneration);
-	}
-
-	// all descendants have been filtered later than must pass generation
-	// but none passed
-	if(getCompletedFilterGeneration() >= must_pass_generation && !hasFilteredDescendants(must_pass_generation))
-	{
-		// don't traverse children if we've already filtered them since must_pass_generation
-		// and came back with nothing
-		return;
-	}
-
-	// we entered here with at least one filter iteration left
-	// check to see if we have any more before continuing on to children
-	if (filter.getFilterCount() < 0)
-	{
-		return;
-	}
-
-	// when applying a filter, matching folders get their contents downloaded first
-	if (filter.isNotDefault()
-		&& getFiltered(filter.getMinRequiredGeneration())
-		&&	(mListener
-			&& !gInventory.isCategoryComplete(mListener->getUUID())))
-	{
-		LLInventoryModelBackgroundFetch::instance().start(mListener->getUUID());
-	}
-
-	// now query children
-	for (folders_t::iterator iter = mFolders.begin();
-		 iter != mFolders.end();
-		 ++iter)
-	{
-		LLFolderViewFolder* folder = (*iter);
-		// have we run out of iterations this frame?
-		if (filter.getFilterCount() < 0)
-		{
-			break;
-		}
-
-		// mMostFilteredDescendantGeneration might have been reset
-		// in which case we need to update it even for folders that
-		// don't need to be filtered anymore
-		if (folder->getCompletedFilterGeneration() >= filter_generation)
-		{
-			// track latest generation to pass any child items
-			if (folder->getFiltered() || folder->hasFilteredDescendants(filter.getMinRequiredGeneration()))
-			{
-				mMostFilteredDescendantGeneration = filter_generation;
-				requestArrange();
-			}
-			// just skip it, it has already been filtered
-			continue;
-		}
-
-		// update this folders filter status (and children)
-		folder->filter( filter );
-
-		// track latest generation to pass any child items
-		if (folder->getFiltered() || folder->hasFilteredDescendants(filter_generation))
-		{
-			mMostFilteredDescendantGeneration = filter_generation;
-			requestArrange();
-			if (getRoot()->needsAutoSelect() && autoopen_folders)
-			{
-				folder->setOpenArrangeRecursively(TRUE);
-			}
-		}
-	}
-
-	for (items_t::iterator iter = mItems.begin();
-		 iter != mItems.end();
-		 ++iter)
-	{
-		LLFolderViewItem* item = (*iter);
-		if (filter.getFilterCount() < 0)
-		{
-			break;
-		}
-		if (item->getLastFilterGeneration() >= filter_generation)
-		{
-			if (item->getFiltered())
-			{
-				mMostFilteredDescendantGeneration = filter_generation;
-				requestArrange();
-			}
-			continue;
-		}
-
-		if (item->getLastFilterGeneration() >= must_pass_generation && 
-			!item->getFiltered(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
-			item->setFiltered(FALSE, filter_generation);
-			continue;
-		}
-
-		item->filter( filter );
-
-		if (item->getFiltered(filter.getMinRequiredGeneration()))
-		{
-			mMostFilteredDescendantGeneration = filter_generation;
-			requestArrange();
-		}
-	}
-
-	// if we didn't use all filter iterations
-	// that means we filtered all of our descendants
-	// instead of exhausting the filter count for this frame
-	if (filter.getFilterCount() > 0)
-	{
-		// flag this folder as having completed filter pass for all descendants
-		setCompletedFilterGeneration(filter_generation, FALSE/*dont recurse up to root*/);
-	}
-}
-
-void LLFolderViewFolder::filterFolder(LLInventoryFilter& filter)
-{
-	const BOOL previous_passed_filter = mPassedFolderFilter;
-	const BOOL passed_filter = filter.checkFolder(this);
-
-	// If our visibility will change as a result of this filter, then
-	// we need to be rearranged in our parent folder
-	if (mParentFolder)
-	{
-		if (getVisible() != passed_filter
-			|| previous_passed_filter != passed_filter )
-		{
-			mParentFolder->requestArrange();
-		}
-	}
-
-	setFilteredFolder(passed_filter, filter.getCurrentGeneration());
-	filter.decrementFilterCount();
-
-	if (getRoot()->getDebugFilters())
-	{
-		mStatusText = llformat("%d", mLastFilterGeneration);
-	}
-}
-
-void LLFolderViewFolder::setFiltered(BOOL filtered, S32 filter_generation)
-{
-	// if this folder is now filtered, but wasn't before
-	// (it just passed)
-	if (filtered && !mPassedFilter)
-	{
-		// reset current height, because last time we drew it
-		// it might have had more visible items than now
-		mCurHeight = 0.f;
-	}
-
-	LLFolderViewItem::setFiltered(filtered, filter_generation);
-}
-
-void LLFolderViewFolder::dirtyFilter()
-{
-	// we're a folder, so invalidate our completed generation
-	setCompletedFilterGeneration(-1, FALSE);
-	LLFolderViewItem::dirtyFilter();
-}
-
-BOOL LLFolderViewFolder::getFiltered() 
-{ 
-	return getFilteredFolder(getRoot()->getFilter()->getMinRequiredGeneration()) 
-		&& LLFolderViewItem::getFiltered(); 
-}
-
-BOOL LLFolderViewFolder::getFiltered(S32 filter_generation) 
-{
-	return getFilteredFolder(filter_generation) && LLFolderViewItem::getFiltered(filter_generation);
-}
-
-BOOL LLFolderViewFolder::hasFilteredDescendants(S32 filter_generation)
-{ 
-	return mMostFilteredDescendantGeneration >= filter_generation; 
-}
-
-
-BOOL LLFolderViewFolder::hasFilteredDescendants()
-{
-	return mMostFilteredDescendantGeneration >= getRoot()->getFilter()->getCurrentGeneration();
-}
-
-// Passes selection information on to children and record selection
-// information if necessary.
-BOOL LLFolderViewFolder::setSelection(LLFolderViewItem* selection, BOOL openitem,
-                                      BOOL take_keyboard_focus)
-{
-	BOOL rv = FALSE;
-	if (selection == this)
-	{
-		if (!isSelected())
-		{
-			selectItem();
-		}
-		rv = TRUE;
-	}
-	else
-	{
-		if (isSelected())
-		{
-			deselectItem();
-		}
-		rv = FALSE;
-	}
-	BOOL child_selected = FALSE;
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		if((*fit)->setSelection(selection, openitem, take_keyboard_focus))
-		{
-			rv = TRUE;
-			child_selected = TRUE;
-		}
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		if((*iit)->setSelection(selection, openitem, take_keyboard_focus))
-		{
-			rv = TRUE;
-			child_selected = TRUE;
-		}
-	}
-	if(openitem && child_selected)
-	{
-		setOpenArrangeRecursively(TRUE);
-	}
-	return rv;
-}
-
-// This method is used to change the selection of an item.
-// Recursively traverse all children; if 'selection' is 'this' then change
-// the select status if necessary.
-// Returns TRUE if the selection state of this folder, or of a child, was changed.
-BOOL LLFolderViewFolder::changeSelection(LLFolderViewItem* selection, BOOL selected)
-{
-	BOOL rv = FALSE;
-	if(selection == this)
-	{
-		if (isSelected() != selected)
-		{
-			rv = TRUE;
-			if (selected)
-			{
-				selectItem();
-			}
-			else
-			{
-				deselectItem();
-			}
-		}
-	}
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		if((*fit)->changeSelection(selection, selected))
-		{
-			rv = TRUE;
-		}
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		if((*iit)->changeSelection(selection, selected))
-		{
-			rv = TRUE;
-		}
-	}
-	return rv;
-}
-
-LLFolderViewFolder* LLFolderViewFolder::getCommonAncestor(LLFolderViewItem* item_a, LLFolderViewItem* item_b, bool& reverse)
-{
-	if (!item_a->getParentFolder() || !item_b->getParentFolder()) return NULL;
-
-	std::deque<LLFolderViewFolder*> item_a_ancestors;
-
-	LLFolderViewFolder* parent = item_a->getParentFolder();
-	while(parent)
-	{
-		item_a_ancestors.push_back(parent);
-		parent = parent->getParentFolder();
-	}
-
-	std::deque<LLFolderViewFolder*> item_b_ancestors;
-	
-	parent = item_b->getParentFolder();
-	while(parent)
-	{
-		item_b_ancestors.push_back(parent);
-		parent = parent->getParentFolder();
-	}
-
-	LLFolderViewFolder* common_ancestor = item_a->getRoot();
-
-	while(item_a_ancestors.size() > item_b_ancestors.size())
-	{
-		item_a = item_a_ancestors.front();
-		item_a_ancestors.pop_front();
-	}
-
-	while(item_b_ancestors.size() > item_a_ancestors.size())
-	{
-		item_b = item_b_ancestors.front();
-		item_b_ancestors.pop_front();
-	}
-
-	while(item_a_ancestors.size())
-	{
-		common_ancestor = item_a_ancestors.front();
-
-		if (item_a_ancestors.front() == item_b_ancestors.front())
-		{
-			// which came first, sibling a or sibling b?
-			for (folders_t::iterator it = common_ancestor->mFolders.begin(), end_it = common_ancestor->mFolders.end();
-				it != end_it;
-				++it)
-			{
-				LLFolderViewItem* item = *it;
-
-				if (item == item_a)
-				{
-					reverse = false;
-					return common_ancestor;
-				}
-				if (item == item_b)
-				{
-					reverse = true;
-					return common_ancestor;
-				}
-			}
-
-			for (items_t::iterator it = common_ancestor->mItems.begin(), end_it = common_ancestor->mItems.end();
-				it != end_it;
-				++it)
-			{
-				LLFolderViewItem* item = *it;
-
-				if (item == item_a)
-				{
-					reverse = false;
-					return common_ancestor;
-				}
-				if (item == item_b)
-				{
-					reverse = true;
-					return common_ancestor;
-				}
-			}
-			break;
-		}
-
-		item_a = item_a_ancestors.front();
-		item_a_ancestors.pop_front();
-		item_b = item_b_ancestors.front();
-		item_b_ancestors.pop_front();
-	}
-
-	return NULL;
-}
-
-void LLFolderViewFolder::gatherChildRangeExclusive(LLFolderViewItem* start, LLFolderViewItem* end, bool reverse, std::vector<LLFolderViewItem*>& items)
-{
-	bool selecting = start == NULL;
-	if (reverse)
-	{
-		for (items_t::reverse_iterator it = mItems.rbegin(), end_it = mItems.rend();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-		for (folders_t::reverse_iterator it = mFolders.rbegin(), end_it = mFolders.rend();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-	}
-	else
-	{
-		for (folders_t::iterator it = mFolders.begin(), end_it = mFolders.end();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-		for (items_t::iterator it = mItems.begin(), end_it = mItems.end();
-			it != end_it;
-			++it)
-		{
-			if (*it == end)
-			{
-				return;
-			}
-
-			if (selecting)
-			{
-				items.push_back(*it);
-			}
-
-			if (*it == start)
-			{
-				selecting = true;
-			}
-		}
-	}
-}
-
-void LLFolderViewFolder::extendSelectionTo(LLFolderViewItem* new_selection)
-{
-	if (getRoot()->getAllowMultiSelect() == FALSE) return;
-
-	LLFolderViewItem* cur_selected_item = getRoot()->getCurSelectedItem();
-	if (cur_selected_item == NULL)
-	{
-		cur_selected_item = new_selection;
-	}
-
-
-	bool reverse = false;
-	LLFolderViewFolder* common_ancestor = getCommonAncestor(cur_selected_item, new_selection, reverse);
-	if (!common_ancestor) return;
-
-	LLFolderViewItem* last_selected_item_from_cur = cur_selected_item;
-	LLFolderViewFolder* cur_folder = cur_selected_item->getParentFolder();
-
-	std::vector<LLFolderViewItem*> items_to_select_forward;
-
-	while(cur_folder != common_ancestor)
-	{
-		cur_folder->gatherChildRangeExclusive(last_selected_item_from_cur, NULL, reverse, items_to_select_forward);
-			
-		last_selected_item_from_cur = cur_folder;
-		cur_folder = cur_folder->getParentFolder();
-	}
-
-	std::vector<LLFolderViewItem*> items_to_select_reverse;
-
-	LLFolderViewItem* last_selected_item_from_new = new_selection;
-	cur_folder = new_selection->getParentFolder();
-	while(cur_folder != common_ancestor)
-	{
-		cur_folder->gatherChildRangeExclusive(last_selected_item_from_new, NULL, !reverse, items_to_select_reverse);
-
-		last_selected_item_from_new = cur_folder;
-		cur_folder = cur_folder->getParentFolder();
-	}
-
-	common_ancestor->gatherChildRangeExclusive(last_selected_item_from_cur, last_selected_item_from_new, reverse, items_to_select_forward);
-
-	for (std::vector<LLFolderViewItem*>::reverse_iterator it = items_to_select_reverse.rbegin(), end_it = items_to_select_reverse.rend();
-		it != end_it;
-		++it)
-	{
-		items_to_select_forward.push_back(*it);
-	}
-
-	LLFolderView* root = getRoot();
-
-	for (std::vector<LLFolderViewItem*>::iterator it = items_to_select_forward.begin(), end_it = items_to_select_forward.end();
-		it != end_it;
-		++it)
-	{
-		LLFolderViewItem* item = *it;
-		if (item->isSelected())
-		{
-			root->removeFromSelectionList(item);
-		}
-		else
-		{
-			item->selectItem();
-		}
-		root->addToSelectionList(item);
-	}
-
-	if (new_selection->isSelected())
-	{
-		root->removeFromSelectionList(new_selection);
-	}
-	else
-	{
-		new_selection->selectItem();
-	}
-	root->addToSelectionList(new_selection);
-}
-
-
-void LLFolderViewFolder::destroyView()
-{
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		LLFolderViewItem* item = (*iit);
-		getRoot()->removeItemID(item->getListener()->getUUID());
-	}
-
-	std::for_each(mItems.begin(), mItems.end(), DeletePointer());
-	mItems.clear();
-
-	while (!mFolders.empty())
-	{
-		LLFolderViewFolder *folderp = mFolders.back();
-		folderp->destroyView(); // removes entry from mFolders
-	}
-
-	//deleteAllChildren();
-
-	if (mParentFolder)
-	{
-		mParentFolder->removeView(this);
-	}
-}
-
-// remove the specified item (and any children) if possible. Return
-// TRUE if the item was deleted.
-BOOL LLFolderViewFolder::removeItem(LLFolderViewItem* item)
-{
-	if(item->remove())
-	{
-		return TRUE;
-	}
-	return FALSE;
-}
-
-// simply remove the view (and any children) Don't bother telling the
-// listeners.
-void LLFolderViewFolder::removeView(LLFolderViewItem* item)
-{
-	if (!item || item->getParentFolder() != this)
-	{
-		return;
-	}
-	// deselect without traversing hierarchy
-	if (item->isSelected())
-	{
-		item->deselectItem();
-	}
-	getRoot()->removeFromSelectionList(item);
-	extractItem(item);
-	delete item;
-}
-
-// extractItem() removes the specified item from the folder, but
-// doesn't delete it.
-void LLFolderViewFolder::extractItem( LLFolderViewItem* item )
-{
-	items_t::iterator it = std::find(mItems.begin(), mItems.end(), item);
-	if(it == mItems.end())
-	{
-		// This is an evil downcast. However, it's only doing
-		// pointer comparison to find if (which it should be ) the
-		// item is in the container, so it's pretty safe.
-		LLFolderViewFolder* f = static_cast<LLFolderViewFolder*>(item);
-		folders_t::iterator ft;
-		ft = std::find(mFolders.begin(), mFolders.end(), f);
-		if (ft != mFolders.end())
-		{
-			mFolders.erase(ft);
-		}
-	}
-	else
-	{
-		mItems.erase(it);
-	}
-	//item has been removed, need to update filter
-	dirtyFilter();
-	//because an item is going away regardless of filter status, force rearrange
-	requestArrange();
-	getRoot()->removeItemID(item->getListener()->getUUID());
-	removeChild(item);
-}
-
-bool LLFolderViewFolder::isTrash() const
-{
-	if (mAmTrash == LLFolderViewFolder::UNKNOWN)
-	{
-		mAmTrash = mListener->getUUID() == gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH, false) ? LLFolderViewFolder::TRASH : LLFolderViewFolder::NOT_TRASH;
-	}
-	return mAmTrash == LLFolderViewFolder::TRASH;
-}
-
-void LLFolderViewFolder::sortBy(U32 order)
-{
-	if (!mSortFunction.updateSort(order))
-	{
-		// No changes.
-		return;
-	}
-
-	// Propagate this change to sub folders
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->sortBy(order);
-	}
-
-	// Don't sort the topmost folders (My Inventory and Library)
-	if (mListener->getUUID().notNull())
-	{
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-	}
-
-	if (order & LLInventoryFilter::SO_DATE)
-	{
-		time_t latest = 0;
-
-		if (!mItems.empty())
-		{
-			LLFolderViewItem* item = *(mItems.begin());
-			latest = item->getCreationDate();
-		}
-
-		if (!mFolders.empty())
-		{
-			LLFolderViewFolder* folder = *(mFolders.begin());
-			if (folder->getCreationDate() > latest)
-			{
-				latest = folder->getCreationDate();
-			}
-		}
-		mSubtreeCreationDate = latest;
-	}
-}
-
-void LLFolderViewFolder::setItemSortOrder(U32 ordering)
-{
-	if (mSortFunction.updateSort(ordering))
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			(*fit)->setItemSortOrder(ordering);
-		}
-
-		mFolders.sort(mSortFunction);
-		mItems.sort(mSortFunction);
-	}
-}
-
-EInventorySortGroup LLFolderViewFolder::getSortGroup() const
-{
-	if (isTrash())
-	{
-		return SG_TRASH_FOLDER;
-	}
-
-	if( mListener )
-	{
-		if(LLFolderType::lookupIsProtectedType(mListener->getPreferredType()))
-		{
-			return SG_SYSTEM_FOLDER;
-		}
-	}
-
-	return SG_NORMAL_FOLDER;
-}
-
-BOOL LLFolderViewFolder::isMovable()
-{
-	if( mListener )
-	{
-		if( !(mListener->isItemMovable()) )
-		{
-			return FALSE;
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isMovable())
-			{
-				return FALSE;
-			}
-		}
-
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isMovable())
-			{
-				return FALSE;
-			}
-		}
-	}
-	return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::isRemovable()
-{
-	if( mListener )
-	{
-		if( !(mListener->isItemRemovable()) )
-		{
-			return FALSE;
-		}
-
-		for (items_t::iterator iter = mItems.begin();
-			iter != mItems.end();)
-		{
-			items_t::iterator iit = iter++;
-			if(!(*iit)->isRemovable())
-			{
-				return FALSE;
-			}
-		}
-
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			if(!(*fit)->isRemovable())
-			{
-				return FALSE;
-			}
-		}
-	}
-	return TRUE;
-}
-
-// this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addItem(LLFolderViewItem* item)
-{
-	mItems.push_back(item);
-	
-	item->setRect(LLRect(0, 0, getRect().getWidth(), 0));
-	item->setVisible(FALSE);
-	
-	addChild(item);
-	
-	item->dirtyFilter();
-
-	// Update the folder creation date if the child is newer than our current date
-	setCreationDate(llmax<time_t>(mCreationDate, item->getCreationDate()));
-
-	// Handle sorting
-	requestArrange();
-	requestSort();
-
-	// Traverse parent folders and update creation date and resort, if necessary
-	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp)
-	{
-		// Update the folder creation date if the child is newer than our current date
-		parentp->setCreationDate(llmax<time_t>(parentp->mCreationDate, item->getCreationDate()));
-
-		if (parentp->mSortFunction.isByDate())
-		{
-			// parent folder doesn't have a time stamp yet, so get it from us
-			parentp->requestSort();
-		}
-
-		parentp = parentp->getParentFolder();
-	}
-
-	return TRUE;
-}
-
-// this is an internal method used for adding items to folders. 
-BOOL LLFolderViewFolder::addFolder(LLFolderViewFolder* folder)
-{
-	mFolders.push_back(folder);
-	folder->setOrigin(0, 0);
-	folder->reshape(getRect().getWidth(), 0);
-	folder->setVisible(FALSE);
-	addChild( folder );
-	folder->dirtyFilter();
-	// rearrange all descendants too, as our indentation level might have changed
-	folder->requestArrange(TRUE);
-	requestSort();
-	LLFolderViewFolder* parentp = getParentFolder();
-	while (parentp && !parentp->mSortFunction.isByDate())
-	{
-		// parent folder doesn't have a time stamp yet, so get it from us
-		parentp->requestSort();
-		parentp = parentp->getParentFolder();
-	}
-	return TRUE;
-}
-
-void LLFolderViewFolder::requestArrange(BOOL include_descendants)	
-{ 
-	mLastArrangeGeneration = -1; 
-	// flag all items up to root
-	if (mParentFolder)
-	{
-		mParentFolder->requestArrange();
-	}
-
-	if (include_descendants)
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();
-			++iter)
-		{
-			(*iter)->requestArrange(TRUE);
-		}
-	}
-}
-
-void LLFolderViewFolder::toggleOpen()
-{
-	setOpen(!mIsOpen);
-}
-
-// Force a folder open or closed
-void LLFolderViewFolder::setOpen(BOOL openitem)
-{
-	setOpenArrangeRecursively(openitem);
-}
-
-void LLFolderViewFolder::setOpenArrangeRecursively(BOOL openitem, ERecurseType recurse)
-{
-	BOOL was_open = mIsOpen;
-	mIsOpen = openitem;
-	if (mListener)
-	{
-		if(!was_open && openitem)
-		{
-			mListener->openItem();
-		}
-		else if(was_open && !openitem)
-		{
-			mListener->closeItem();
-		}
-	}
-
-	if (recurse == RECURSE_DOWN || recurse == RECURSE_UP_DOWN)
-	{
-		for (folders_t::iterator iter = mFolders.begin();
-			iter != mFolders.end();)
-		{
-			folders_t::iterator fit = iter++;
-			(*fit)->setOpenArrangeRecursively(openitem, RECURSE_DOWN);		/* Flawfinder: ignore */
-		}
-	}
-	if (mParentFolder
-		&&	(recurse == RECURSE_UP
-			|| recurse == RECURSE_UP_DOWN))
-	{
-		mParentFolder->setOpenArrangeRecursively(openitem, RECURSE_UP);
-	}
-
-	if (was_open != mIsOpen)
-	{
-		requestArrange();
-	}
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropFromChild(MASK mask,
-													BOOL drop,
-													EDragAndDropType c_type,
-													void* cargo_data,
-													EAcceptance* accept,
-													std::string& tooltip_msg)
-{
-	BOOL accepted = mListener && mListener->dragOrDrop(mask,drop,c_type,cargo_data, tooltip_msg);
-	if (accepted) 
-	{
-		mDragAndDropTarget = TRUE;
-		*accept = ACCEPT_YES_MULTI;
-	}
-	else 
-	{
-		*accept = ACCEPT_NO;
-	}
-
-	// drag and drop to child item, so clear pending auto-opens
-	getRoot()->autoOpenTest(NULL);
-
-	return TRUE;
-}
-
-void LLFolderViewFolder::openItem( void )
-{
-	toggleOpen();
-}
-
-void LLFolderViewFolder::applyFunctorToChildren(LLFolderViewFunctor& functor)
-{
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		functor.doItem((*fit));
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		functor.doItem((*iit));
-	}
-}
-
-void LLFolderViewFolder::applyFunctorRecursively(LLFolderViewFunctor& functor)
-{
-	functor.doFolder(this);
-
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->applyFunctorRecursively(functor);
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		functor.doItem((*iit));
-	}
-}
-
-void LLFolderViewFolder::applyListenerFunctorRecursively(LLFolderViewListenerFunctor& functor)
-{
-	functor(mListener);
-	for (folders_t::iterator iter = mFolders.begin();
-		iter != mFolders.end();)
-	{
-		folders_t::iterator fit = iter++;
-		(*fit)->applyListenerFunctorRecursively(functor);
-	}
-	for (items_t::iterator iter = mItems.begin();
-		iter != mItems.end();)
-	{
-		items_t::iterator iit = iter++;
-		(*iit)->applyListenerFunctorRecursively(functor);
-	}
-}
-
-// LLView functionality
-BOOL LLFolderViewFolder::handleDragAndDrop(S32 x, S32 y, MASK mask,
-										   BOOL drop,
-										   EDragAndDropType cargo_type,
-										   void* cargo_data,
-										   EAcceptance* accept,
-										   std::string& tooltip_msg)
-{
-	BOOL handled = FALSE;
-
-	if (mIsOpen)
-	{
-		handled = (childrenHandleDragAndDrop(x, y, mask, drop, cargo_type, cargo_data, accept, tooltip_msg) != NULL);
-	}
-
-	if (!handled)
-	{
-		handleDragAndDropToThisFolder(mask, drop, cargo_type, cargo_data, accept, tooltip_msg);
-
-		lldebugst(LLERR_USER_INPUT) << "dragAndDrop handled by LLFolderViewFolder" << llendl;
-	}
-
-	return TRUE;
-}
-
-BOOL LLFolderViewFolder::handleDragAndDropToThisFolder(MASK mask,
-													   BOOL drop,
-													   EDragAndDropType cargo_type,
-													   void* cargo_data,
-													   EAcceptance* accept,
-													   std::string& tooltip_msg)
-{
-	BOOL accepted = mListener && mListener->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
-	
-	if (accepted) 
-	{
-		mDragAndDropTarget = TRUE;
-		*accept = ACCEPT_YES_MULTI;
-	}
-	else 
-	{
-		*accept = ACCEPT_NO;
-	}
-	
-	if (!drop && accepted)
-	{
-		getRoot()->autoOpenTest(this);
-	}
-	
-	return TRUE;
-}
-
-
-BOOL LLFolderViewFolder::handleRightMouseDown( S32 x, S32 y, MASK mask )
-{
-	BOOL handled = FALSE;
-	// fetch contents of this folder, as context menu can depend on contents
-	// still, user would have to open context menu again to see the changes
-	gInventory.fetchDescendentsOf(mListener->getUUID());
-
-	if( mIsOpen )
-	{
-		handled = childrenHandleRightMouseDown( x, y, mask ) != NULL;
-	}
-	if (!handled)
-	{
-		handled = LLFolderViewItem::handleRightMouseDown( x, y, mask );
-	}
-	return handled;
-}
-
-
-BOOL LLFolderViewFolder::handleHover(S32 x, S32 y, MASK mask)
-{
-	mIsMouseOverTitle = (y > (getRect().getHeight() - mItemHeight));
-
-	BOOL handled = LLView::handleHover(x, y, mask);
-
-	if (!handled)
-	{
-		// this doesn't do child processing
-		handled = LLFolderViewItem::handleHover(x, y, mask);
-	}
-
-	return handled;
-}
-
-BOOL LLFolderViewFolder::handleMouseDown( S32 x, S32 y, MASK mask )
-{
-	BOOL handled = FALSE;
-	if( mIsOpen )
-	{
-		handled = childrenHandleMouseDown(x,y,mask) != NULL;
-	}
-	if( !handled )
-	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
-		{
-			toggleOpen();
-			handled = TRUE;
-		}
-		else
-		{
-			// do normal selection logic
-			handled = LLFolderViewItem::handleMouseDown(x, y, mask);
-		}
-	}
-
-	return handled;
-}
-
-BOOL LLFolderViewFolder::handleDoubleClick( S32 x, S32 y, MASK mask )
-{
-	/* Disable outfit double click to wear
-	const LLUUID &cat_uuid = getListener()->getUUID();
-	const LLViewerInventoryCategory *cat = gInventory.getCategory(cat_uuid);
-	if (cat && cat->getPreferredType() == LLFolderType::FT_OUTFIT)
-	{
-		getListener()->performAction(NULL, NULL,"replaceoutfit");
-		return TRUE;
-	}
-	*/
-
-	BOOL handled = FALSE;
-	if( mIsOpen )
-	{
-		handled = childrenHandleDoubleClick( x, y, mask ) != NULL;
-	}
-	if( !handled )
-	{
-		if(mIndentation < x && x < mIndentation + ARROW_SIZE + TEXT_PAD)
-		{
-			// don't select when user double-clicks plus sign
-			// so as not to contradict single-click behavior
-			toggleOpen();
-		}
-		else
-		{
-			setSelectionFromRoot(this, FALSE);
-			toggleOpen();
-		}
-		handled = TRUE;
-	}
-	return handled;
-}
-
-void LLFolderViewFolder::draw()
-{
-	if (mAutoOpenCountdown != 0.f)
-	{
-		mControlLabelRotation = mAutoOpenCountdown * -90.f;
-	}
-	else if (mIsOpen)
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, -90.f, LLCriticalDamp::getInterpolant(0.04f));
-	}
-	else
-	{
-		mControlLabelRotation = lerp(mControlLabelRotation, 0.f, LLCriticalDamp::getInterpolant(0.025f));
-	}
-
-	bool possibly_has_children = false;
-	bool up_to_date = mListener && mListener->isUpToDate();
-	if(!up_to_date
-		&& mListener->hasChildren()) // we know we have children but haven't fetched them (doesn't obey filter)
-	{
-		possibly_has_children = true;
-	}
-
-
-	BOOL loading = (mIsOpen
-					&& possibly_has_children
-					&& !up_to_date );
-
-	if ( loading && !mIsLoading )
-	{
-		// Measure how long we've been in the loading state
-		mTimeSinceRequestStart.reset();
-	}
-
-	mIsLoading = loading;
-
-	LLFolderViewItem::draw();
-
-	// draw children if root folder, or any other folder that is open or animating to closed state
-	if( getRoot() == this || (mIsOpen || mCurHeight != mTargetHeight ))
-	{
-		LLView::draw();
-	}
-
-	mExpanderHighlighted = FALSE;
-}
-
-time_t LLFolderViewFolder::getCreationDate() const
-{
-	return llmax<time_t>(mCreationDate, mSubtreeCreationDate);
-}
-
-
-BOOL	LLFolderViewFolder::potentiallyVisible()
-{
-	// folder should be visible by it's own filter status
-	return LLFolderViewItem::potentiallyVisible() 	
-		// or one or more of its descendants have passed the minimum filter requirement
-		|| hasFilteredDescendants(getRoot()->getFilter()->getMinRequiredGeneration())
-		// or not all of its descendants have been checked against minimum filter requirement
-		|| getCompletedFilterGeneration() < getRoot()->getFilter()->getMinRequiredGeneration(); 
-}
-
-// this does prefix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getNextFromChild( LLFolderViewItem* item, BOOL include_children )
-{
-	BOOL found_item = FALSE;
-
-	LLFolderViewItem* result = NULL;
-	// when not starting from a given item, start at beginning
-	if(item == NULL)
-	{
-		found_item = TRUE;
-	}
-
-	// find current item among children
-	folders_t::iterator fit = mFolders.begin();
-	folders_t::iterator fend = mFolders.end();
-
-	items_t::iterator iit = mItems.begin();
-	items_t::iterator iend = mItems.end();
-
-	// if not trivially starting at the beginning, we have to find the current item
-	if (!found_item)
-	{
-		// first, look among folders, since they are always above items
-		for(; fit != fend; ++fit)
-		{
-			if(item == (*fit))
-			{
-				found_item = TRUE;
-				// if we are on downwards traversal
-				if (include_children && (*fit)->isOpen())
-				{
-					// look for first descendant
-					return (*fit)->getNextFromChild(NULL, TRUE);
-				}
-				// otherwise advance to next folder
-				++fit;
-				include_children = TRUE;
-				break;
-			}
-		}
-
-		// didn't find in folders?  Check items...
-		if (!found_item)
-		{
-			for(; iit != iend; ++iit)
-			{
-				if(item == (*iit))
-				{
-					found_item = TRUE;
-					// point to next item
-					++iit;
-					break;
-				}
-			}
-		}
-	}
-
-	if (!found_item)
-	{
-		// you should never call this method with an item that isn't a child
-		// so we should always find something
-		llassert(FALSE);
-		return NULL;
-	}
-
-	// at this point, either iit or fit point to a candidate "next" item
-	// if both are out of range, we need to punt up to our parent
-
-	// now, starting from found folder, continue through folders
-	// searching for next visible folder
-	while(fit != fend && !(*fit)->getVisible())
-	{
-		// turn on downwards traversal for next folder
-		++fit;
-	} 
-
-	if (fit != fend)
-	{
-		result = (*fit);
-	}
-	else
-	{
-		// otherwise, scan for next visible item
-		while(iit != iend && !(*iit)->getVisible())
-		{
-			++iit;
-		} 
-
-		// check to see if we have a valid item
-		if (iit != iend)
-		{
-			result = (*iit);
-		}
-	}
-
-	if( !result && mParentFolder )
-	{
-		// If there are no siblings or children to go to, recurse up one level in the tree
-		// and skip children for this folder, as we've already discounted them
-		result = mParentFolder->getNextFromChild(this, FALSE);
-	}
-
-	return result;
-}
-
-// this does postfix traversal, as folders are listed above their contents
-LLFolderViewItem* LLFolderViewFolder::getPreviousFromChild( LLFolderViewItem* item, BOOL include_children )
-{
-	BOOL found_item = FALSE;
-
-	LLFolderViewItem* result = NULL;
-	// when not starting from a given item, start at end
-	if(item == NULL)
-	{
-		found_item = TRUE;
-	}
-
-	// find current item among children
-	folders_t::reverse_iterator fit = mFolders.rbegin();
-	folders_t::reverse_iterator fend = mFolders.rend();
-
-	items_t::reverse_iterator iit = mItems.rbegin();
-	items_t::reverse_iterator iend = mItems.rend();
-
-	// if not trivially starting at the end, we have to find the current item
-	if (!found_item)
-	{
-		// first, look among items, since they are always below the folders
-		for(; iit != iend; ++iit)
-		{
-			if(item == (*iit))
-			{
-				found_item = TRUE;
-				// point to next item
-				++iit;
-				break;
-			}
-		}
-
-		// didn't find in items?  Check folders...
-		if (!found_item)
-		{
-			for(; fit != fend; ++fit)
-			{
-				if(item == (*fit))
-				{
-					found_item = TRUE;
-					// point to next folder
-					++fit;
-					break;
-				}
-			}
-		}
-	}
-
-	if (!found_item)
-	{
-		// you should never call this method with an item that isn't a child
-		// so we should always find something
-		llassert(FALSE);
-		return NULL;
-	}
-
-	// at this point, either iit or fit point to a candidate "next" item
-	// if both are out of range, we need to punt up to our parent
-
-	// now, starting from found item, continue through items
-	// searching for next visible item
-	while(iit != iend && !(*iit)->getVisible())
-	{
-		++iit;
-	} 
-
-	if (iit != iend)
-	{
-		// we found an appropriate item
-		result = (*iit);
-	}
-	else
-	{
-		// otherwise, scan for next visible folder
-		while(fit != fend && !(*fit)->getVisible())
-		{
-			++fit;
-		} 
-
-		// check to see if we have a valid folder
-		if (fit != fend)
-		{
-			// try selecting child element of this folder
-			if ((*fit)->isOpen())
-			{
-				result = (*fit)->getPreviousFromChild(NULL);
-			}
-			else
-			{
-				result = (*fit);
-			}
-		}
-	}
-
-	if( !result )
-	{
-		// If there are no siblings or children to go to, recurse up one level in the tree
-		// which gets back to this folder, which will only be visited if it is a valid, visible item
-		result = this;
-	}
-
-	return result;
-}
-
-
-bool LLInventorySort::updateSort(U32 order)
-{
-	if (order != mSortOrder)
-	{
-		mSortOrder = order;
-		mByDate = (order & LLInventoryFilter::SO_DATE);
-		mSystemToTop = (order & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
-		mFoldersByName = (order & LLInventoryFilter::SO_FOLDERS_BY_NAME);
-		return true;
-	}
-	return false;
-}
-
-bool LLInventorySort::operator()(const LLFolderViewItem* const& a, const LLFolderViewItem* const& b)
-{
-	// ignore sort order for landmarks in the Favorites folder.
-	// they should be always sorted as in Favorites bar. See EXT-719
-	if (a->getSortGroup() == SG_ITEM
-		&& b->getSortGroup() == SG_ITEM
-		&& a->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK
-		&& b->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
-	{
-
-		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-
-		LLUUID a_uuid = a->getParentFolder()->getListener()->getUUID();
-		LLUUID b_uuid = b->getParentFolder()->getListener()->getUUID();
-
-		if ((a_uuid == favorites_folder_id && b_uuid == favorites_folder_id))
-		{
-			// *TODO: mantipov: probably it is better to add an appropriate method to LLFolderViewItem
-			// or to LLInvFVBridge
-			LLViewerInventoryItem* aitem = (static_cast<const LLItemBridge*>(a->getListener()))->getItem();
-			LLViewerInventoryItem* bitem = (static_cast<const LLItemBridge*>(b->getListener()))->getItem();
-			if (!aitem || !bitem)
-				return false;
-			S32 a_sort = aitem->getSortField();
-			S32 b_sort = bitem->getSortField();
-			return a_sort < b_sort;
-		}
-	}
-
-	// We sort by name if we aren't sorting by date
-	// OR if these are folders and we are sorting folders by name.
-	bool by_name = (!mByDate 
-		|| (mFoldersByName 
-		&& (a->getSortGroup() != SG_ITEM)));
-
-	if (a->getSortGroup() != b->getSortGroup())
-	{
-		if (mSystemToTop)
-		{
-			// Group order is System Folders, Trash, Normal Folders, Items
-			return (a->getSortGroup() < b->getSortGroup());
-		}
-		else if (mByDate)
-		{
-			// Trash needs to go to the bottom if we are sorting by date
-			if ( (a->getSortGroup() == SG_TRASH_FOLDER)
-				|| (b->getSortGroup() == SG_TRASH_FOLDER))
-			{
-				return (b->getSortGroup() == SG_TRASH_FOLDER);
-			}
-		}
-	}
-
-	if (by_name)
-	{
-		S32 compare = LLStringUtil::compareDict(a->getLabel(), b->getLabel());
-		if (0 == compare)
-		{
-			return (a->getCreationDate() > b->getCreationDate());
-		}
-		else
-		{
-			return (compare < 0);
-		}
-	}
-	else
-	{
-		// BUG: This is very very slow.  The getCreationDate() is log n in number
-		// of inventory items.
-		time_t first_create = a->getCreationDate();
-		time_t second_create = b->getCreationDate();
-		if (first_create == second_create)
-		{
-			return (LLStringUtil::compareDict(a->getLabel(), b->getLabel()) < 0);
-		}
-		else
-		{
-			return (first_create > second_create);
-		}
-	}
-}
diff --git a/indra/newview/llfolderviewmodelinventory.cpp b/indra/newview/llfolderviewmodelinventory.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..586965e5a007b094dcc22e4e808f79190589f3c2
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.cpp
@@ -0,0 +1,314 @@
+/* 
+ * @file llfolderviewmodelinventory.cpp
+ * @brief Implementation of the inventory-specific view model
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfolderviewmodelinventory.h"
+#include "llinventorymodelbackgroundfetch.h"
+#include "llinventorypanel.h"
+#include "lltooldraganddrop.h"
+#include "llfavoritesbar.h"
+
+//
+// class LLFolderViewModelInventory
+//
+static LLFastTimer::DeclareTimer FTM_INVENTORY_SORT("Sort");
+
+bool LLFolderViewModelInventory::startDrag(std::vector<LLFolderViewModelItem*>& items)
+{
+	std::vector<EDragAndDropType> types;
+	uuid_vec_t cargo_ids;
+	std::vector<LLFolderViewModelItem*>::iterator item_it;
+	bool can_drag = true;
+	if (!items.empty())
+	{
+		for (item_it = items.begin(); item_it != items.end(); ++item_it)
+		{
+			EDragAndDropType type = DAD_NONE;
+			LLUUID id = LLUUID::null;
+			can_drag = can_drag && static_cast<LLFolderViewModelItemInventory*>(*item_it)->startDrag(&type, &id);
+
+			types.push_back(type);
+			cargo_ids.push_back(id);
+		}
+
+		LLToolDragAndDrop::getInstance()->beginMultiDrag(types, cargo_ids, 
+			static_cast<LLFolderViewModelItemInventory*>(items.front())->getDragSource(), mTaskID); 
+	}
+	return can_drag;
+}
+
+
+void LLFolderViewModelInventory::sort( LLFolderViewFolder* folder )
+{
+	LLFastTimer _(FTM_INVENTORY_SORT);
+
+	if (!needsSort(folder->getViewModelItem())) return;
+
+	LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem());
+	if (modelp->getUUID().isNull()) return;
+
+	for (std::list<LLFolderViewFolder*>::iterator it =   folder->getFoldersBegin(), end_it = folder->getFoldersEnd();
+		it != end_it;
+		++it)
+	{
+		LLFolderViewFolder* child_folderp = *it;
+		sort(child_folderp);
+
+		if (child_folderp->getFoldersCount() > 0)
+		{
+			time_t most_recent_folder_time =
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getFoldersBegin())->getViewModelItem())->getCreationDate();
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+			if (most_recent_folder_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_folder_time);
+			}
+		}
+		if (child_folderp->getItemsCount() > 0)			
+		{
+			time_t most_recent_item_time =
+				static_cast<LLFolderViewModelItemInventory*>((*child_folderp->getItemsBegin())->getViewModelItem())->getCreationDate();
+
+			LLFolderViewModelItemInventory* modelp =   static_cast<LLFolderViewModelItemInventory*>(child_folderp->getViewModelItem());
+			if (most_recent_item_time > modelp->getCreationDate())
+			{
+				modelp->setCreationDate(most_recent_item_time);
+			}
+		}
+	}
+	base_t::sort(folder);
+}
+
+bool LLFolderViewModelInventory::contentsReady()
+{
+	return !LLInventoryModelBackgroundFetch::instance().folderFetchActive();
+}
+
+void LLFolderViewModelItemInventory::requestSort()
+{
+	LLFolderViewModelItemCommon::requestSort();
+	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(mFolderViewItem);
+	if (folderp)
+	{
+		folderp->requestArrange();
+	}
+	if (static_cast<LLFolderViewModelInventory&>(mRootViewModel).getSorter().isByDate())
+	{
+		// sort by date potentially affects parent folders which use a date
+		// derived from newest item in them
+		if (mParent)
+		{
+			mParent->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;
+	mPrevPassedAllFilters = passedFilter(filter_generation);
+
+	if (passed_filter_before != mPrevPassedAllFilters)
+	{
+		LLFolderViewFolder* parent_folder = mFolderViewItem->getParentFolder();
+		if (parent_folder)
+		{
+			parent_folder->requestArrange();
+		}
+	}
+}
+
+bool LLFolderViewModelItemInventory::filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter )
+{
+	S32 filter_generation = filter.getCurrentGeneration();
+
+	bool continue_filtering = true;
+	if (item->getLastFilterGeneration() < filter_generation)
+	{
+		// recursive application of the filter for child items
+		continue_filtering = item->filter( filter );
+	}
+
+	// track latest generation to pass any child items, for each folder up to root
+	if (item->passedFilter())
+	{
+		LLFolderViewModelItemInventory* view_model = this;
+		
+		while(view_model && view_model->mMostFilteredDescendantGeneration < filter_generation)
+		{
+			view_model->mMostFilteredDescendantGeneration = filter_generation;
+			view_model = static_cast<LLFolderViewModelItemInventory*>(view_model->mParent);
+		}
+	}
+
+	return continue_filtering;
+}
+
+bool LLFolderViewModelItemInventory::filter( LLFolderViewFilter& filter)
+{
+	const S32 filter_generation = filter.getCurrentGeneration();
+	const S32 must_pass_generation = filter.getFirstRequiredGeneration();
+
+	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
+		setPassedFilter(false, filter_generation);
+		setPassedFolderFilter(false, 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()
+		&& (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
+	{
+		// now query children
+		for (child_list_t::iterator iter = mChildren.begin(), end_iter = mChildren.end();
+			iter != end_iter && filter.getFilterCount() > 0;
+			++iter)
+		{
+			if (!filterChildItem((*iter), filter))
+			{
+				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)
+	{
+		filter.decrementFilterCount();
+
+		const bool passed_filter = filter.check(this);
+		setPassedFilter(passed_filter, filter_generation, filter.getStringMatchOffset(this), filter.getFilterStringSize());
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
+
+LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel()
+{
+	return &mInventoryViewModel;
+}
+
+
+const LLFolderViewModelInventory* LLInventoryPanel::getFolderViewModel() const
+{
+	return &mInventoryViewModel;
+}
+
+bool LLInventorySort::operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const
+{
+	// Ignore sort order for landmarks in the Favorites folder.
+	// In that folder, landmarks should be always sorted as in the Favorites bar. See EXT-719
+	if (a->getSortGroup() == SG_ITEM
+		&& b->getSortGroup() == SG_ITEM
+		&& a->getInventoryType() == LLInventoryType::IT_LANDMARK
+		&& b->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	{
+		static const LLUUID& favorites_folder_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
+		// If both landmarks are in the Favorites folder...
+		if (gInventory.isObjectDescendentOf(a->getUUID(), favorites_folder_id) && gInventory.isObjectDescendentOf(b->getUUID(), favorites_folder_id))
+		{
+			// Get their index in that folder
+			S32 a_sort = LLFavoritesOrderStorage::instance().getSortIndex(a->getUUID());
+			S32 b_sort = LLFavoritesOrderStorage::instance().getSortIndex(b->getUUID());
+			// Note: this test is a bit overkill: since they are both in the Favorites folder, we shouldn't get negative index values...
+			if (!((a_sort < 0) && (b_sort < 0)))
+			{
+				return a_sort < b_sort;
+			}
+		}
+	}
+
+	// We sort by name if we aren't sorting by date
+	// OR if these are folders and we are sorting folders by name.
+	bool by_name = (!mByDate || (mFoldersByName && (a->getSortGroup() != SG_ITEM)));
+
+	if (a->getSortGroup() != b->getSortGroup())
+	{
+		if (mSystemToTop)
+		{
+			// Group order is System Folders, Trash, Normal Folders, Items
+			return (a->getSortGroup() < b->getSortGroup());
+		}
+		else if (mByDate)
+		{
+			// Trash needs to go to the bottom if we are sorting by date
+			if ( (a->getSortGroup() == SG_TRASH_FOLDER)
+				|| (b->getSortGroup() == SG_TRASH_FOLDER))
+			{
+				return (b->getSortGroup() == SG_TRASH_FOLDER);
+			}
+		}
+	}
+
+	if (by_name)
+	{
+		S32 compare = LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName());
+		if (0 == compare)
+		{
+			return (a->getCreationDate() > b->getCreationDate());
+		}
+		else
+		{
+			return (compare < 0);
+		}
+	}
+	else
+	{
+		time_t first_create = a->getCreationDate();
+		time_t second_create = b->getCreationDate();
+		if (first_create == second_create)
+		{
+			return (LLStringUtil::compareDict(a->getDisplayName(), b->getDisplayName()) < 0);
+		}
+		else
+		{
+			return (first_create > second_create);
+		}
+	}
+}
+
+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
new file mode 100644
index 0000000000000000000000000000000000000000..890d03d1c9cf29e48c4a20fe2a4260f5545f1857
--- /dev/null
+++ b/indra/newview/llfolderviewmodelinventory.h
@@ -0,0 +1,118 @@
+/** 
+ * @file llfolderviewmodelinventory.h
+ * @brief view model implementation specific to inventory
+ * class definition
+ *
+ * $LicenseInfo:firstyear=2001&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFOLDERVIEWMODELINVENTORY_H
+#define LL_LLFOLDERVIEWMODELINVENTORY_H
+
+#include "llinventoryfilter.h"
+#include "llinventory.h"
+#include "llwearabletype.h"
+#include "lltooldraganddrop.h"
+
+class LLFolderViewModelItemInventory
+	:	public LLFolderViewModelItemCommon
+{
+public:
+	LLFolderViewModelItemInventory(class LLFolderViewModelInventory& root_view_model);
+	virtual const LLUUID& getUUID() const = 0;
+	virtual time_t getCreationDate() const = 0;	// UTC seconds
+	virtual void setCreationDate(time_t creation_date_utc) = 0;
+	virtual PermissionMask getPermissionMask() const = 0;
+	virtual LLFolderType::EType getPreferredType() const = 0;
+	virtual void showProperties(void) = 0;
+	virtual BOOL isItemInTrash( void) const { return FALSE; } // TODO: make   into pure virtual.
+	virtual BOOL isUpToDate() const = 0;
+	virtual bool hasChildren() const = 0;
+	virtual LLInventoryType::EType getInventoryType() const = 0;
+	virtual void performAction(LLInventoryModel* model, std::string action)   = 0;
+	virtual LLWearableType::EType getWearableType() const = 0;
+	virtual EInventorySortGroup getSortGroup() const = 0;
+	virtual LLInventoryObject* getInventoryObject() const = 0;
+	virtual void requestSort();
+	virtual void setPassedFilter(bool filtered, S32 filter_generation, std::string::size_type string_offset = std::string::npos, std::string::size_type string_size = 0);
+	virtual bool filter( LLFolderViewFilter& filter);
+	virtual bool filterChildItem( LLFolderViewModelItem* item, LLFolderViewFilter& filter);
+
+	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const = 0;
+	virtual LLToolDragAndDrop::ESource getDragSource() const = 0;
+
+protected:
+	bool								mPrevPassedAllFilters;
+};
+
+class LLInventorySort
+{
+public:
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Optional<S32> order;
+
+		Params()
+		:	order("order", 0)
+		{}
+	};
+
+	LLInventorySort(S32 order = 0)
+	{
+		fromParams(Params().order(order));
+	}
+
+	bool isByDate() const { return mByDate; }
+	U32 getSortOrder() const { return mSortOrder; }
+	void toParams(Params& p) { p.order(mSortOrder);}
+	void fromParams(Params& p) 
+	{ 
+		mSortOrder = p.order; 
+		mByDate = (mSortOrder & LLInventoryFilter::SO_DATE);
+		mSystemToTop = (mSortOrder & LLInventoryFilter::SO_SYSTEM_FOLDERS_TO_TOP);
+		mFoldersByName = (mSortOrder & LLInventoryFilter::SO_FOLDERS_BY_NAME);
+	}
+
+	bool operator()(const LLFolderViewModelItemInventory* const& a, const LLFolderViewModelItemInventory* const& b) const;
+private:
+	U32  mSortOrder;
+	bool mByDate;
+	bool mSystemToTop;
+	bool mFoldersByName;
+};
+
+class LLFolderViewModelInventory
+	:	public LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter>
+{
+public:
+	typedef LLFolderViewModel<LLInventorySort,   LLFolderViewModelItemInventory, LLFolderViewModelItemInventory,   LLInventoryFilter> base_t;
+
+	void setTaskID(const LLUUID& id) {mTaskID = id;}
+
+	void sort(LLFolderViewFolder* folder);
+	bool contentsReady();
+	bool startDrag(std::vector<LLFolderViewModelItem*>& items);
+
+private:
+	LLUUID mTaskID;
+};
+#endif // LL_LLFOLDERVIEWMODELINVENTORY_H
diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp
index b670af1782a698eb37d6f5fb9c0cbe218a298d65..47612fe25c0d077e4dfdd1781de36fe801e83610 100644
--- a/indra/newview/llfollowcam.cpp
+++ b/indra/newview/llfollowcam.cpp
@@ -38,7 +38,6 @@ std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
 //-------------------------------------------------------
 // constants
 //-------------------------------------------------------
-const F32 ONE_HALF							= 0.5; 
 const F32 FOLLOW_CAM_ZOOM_FACTOR			= 0.1f;
 const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT		= 0.1f;
 const F32 DISTANCE_EPSILON					= 0.0001f;
diff --git a/indra/newview/llfriendcard.cpp b/indra/newview/llfriendcard.cpp
index 11401d6c68b82761ea85ca8030dcdfe633e3fb07..5c6ce9d311df02207c2f1edd8bb80bf293f9981a 100644
--- a/indra/newview/llfriendcard.cpp
+++ b/indra/newview/llfriendcard.cpp
@@ -47,13 +47,13 @@ static const std::string INVENTORY_STRING_FRIENDS_ALL_SUBFOLDER = "All";
 // helper functions
 
 // NOTE: For now Friends & All folders are created as protected folders of the LLFolderType::FT_CALLINGCARD type.
-// So, their names will be processed in the LLFolderViewItem::refreshFromListener() to be localized
+// So, their names will be processed in the LLFolderViewItem::refresh() to be localized
 // using "InvFolder LABEL_NAME" as LLTrans::findString argument.
 
 // We must use in this file their hard-coded names to ensure found them on different locales. EXT-5829.
 // These hard-coded names will be stored in InventoryItems but shown localized in FolderViewItems
 
-// If hack in the LLFolderViewItem::refreshFromListener() to localize protected folder is removed
+// If hack in the LLFolderViewItem::refresh() to localize protected folder is removed
 // or these folders are not protected these names should be localized in another place/way.
 inline const std::string get_friend_folder_name()
 {
@@ -521,7 +521,7 @@ class CreateFriendCardCallback : public LLInventoryCallback
 	void fire(const LLUUID& inv_item_id)
 	{
 		LLViewerInventoryItem* item = gInventory.getItem(inv_item_id);
-
+		
 		if (item)
 			LLFriendCardsManager::instance().extractAvatarID(item->getCreatorUUID());
 	}
@@ -533,7 +533,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 	bool shouldBeAdded = true;
 	LLAvatarName av_name;
 	LLAvatarNameCache::get(avatarID, &av_name);
-	const std::string& name = av_name.mUsername;
+	const std::string& name = av_name.getAccountName();
 
 	lldebugs << "Processing buddy name: " << name 
 		<< ", id: " << avatarID
@@ -557,7 +557,7 @@ void LLFriendCardsManager::addFriendCardToInventory(const LLUUID& avatarID)
 		lldebugs << "Sent create_inventory_item for " << avatarID << ", " << name << llendl;
 
 		// TODO: mantipov: Is CreateFriendCardCallback really needed? Probably not
-		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback();
+		LLPointer<LLInventoryCallback> cb = new CreateFriendCardCallback;
 
 		create_inventory_callingcard(avatarID, findFriendAllSubfolderUUIDImpl(), cb);
 	}
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ca76bfb07bdc34de04202c538f647699456c44..9aa86297fc084808db2f7eb95a3cb10fd5e887c1 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -35,6 +35,7 @@
 // library
 #include "llaudioengine.h"
 #include "lldatapacker.h"
+#include "llfloaterreg.h"
 #include "llinventory.h"
 #include "llkeyframemotion.h"
 #include "llmultigesture.h"
@@ -51,7 +52,7 @@
 #include "llviewermessage.h"
 #include "llvoavatarself.h"
 #include "llviewerstats.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 #include "llappearancemgr.h"
 #include "llgesturelistener.h"
 
@@ -337,7 +338,7 @@ void LLGestureMgr::deactivateGesture(const LLUUID& item_id)
 
 	gAgent.sendReliableMessage();
 
-	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id, false);
+	LLAppearanceMgr::instance().removeCOFItemLinks(base_item_id);
 
 	notifyObservers();
 }
@@ -997,7 +998,8 @@ void LLGestureMgr::runStep(LLMultiGesture* gesture, LLGestureStep* step)
 
 			const BOOL animate = FALSE;
 
-			LLNearbyChatBar::getInstance()->sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
+			(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+					sendChatFromViewer(chat_text, CHAT_TYPE_NORMAL, animate);
 
 			gesture->mCurrentStep++;
 			break;
diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp
index 1208c9378e9024f84582c879eed315a5b7f1c597..60fa53f491c1d94b9d6e2018a5a1e330f2eb4260 100644
--- a/indra/newview/llglsandbox.cpp
+++ b/indra/newview/llglsandbox.cpp
@@ -79,10 +79,10 @@ void LLToolSelectRect::handleRectangleSelection(S32 x, S32 y, MASK mask)
 	S32 top =	llmax(y, mDragStartY);
 	S32 bottom =llmin(y, mDragStartY);
 
-	left = llround((F32) left * LLUI::sGLScaleFactor.mV[VX]);
-	right = llround((F32) right * LLUI::sGLScaleFactor.mV[VX]);
-	top = llround((F32) top * LLUI::sGLScaleFactor.mV[VY]);
-	bottom = llround((F32) bottom * LLUI::sGLScaleFactor.mV[VY]);
+	left = llround((F32) left * LLUI::getScaleFactor().mV[VX]);
+	right = llround((F32) right * LLUI::getScaleFactor().mV[VX]);
+	top = llround((F32) top * LLUI::getScaleFactor().mV[VY]);
+	bottom = llround((F32) bottom * LLUI::getScaleFactor().mV[VY]);
 
 	F32 old_far_plane = LLViewerCamera::getInstance()->getFar();
 	F32 old_near_plane = LLViewerCamera::getInstance()->getNear();
diff --git a/indra/newview/llgroupactions.cpp b/indra/newview/llgroupactions.cpp
index 623ebb76f2b557ac852ef642fa2dafd834dec47b..a0f2918bd786338340f7b9fa606c2021ef2323b2 100644
--- a/indra/newview/llgroupactions.cpp
+++ b/indra/newview/llgroupactions.cpp
@@ -36,10 +36,10 @@
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llgroupmgr.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h" // for gIMMgr
 #include "llnotificationsutil.h"
 #include "llstatusbar.h"	// can_afford_transaction()
-#include "llimfloater.h"
 #include "groupchatlistener.h"
 
 //
@@ -335,7 +335,7 @@ LLUUID LLGroupActions::startIM(const LLUUID& group_id)
 			group_id);
 		if (session_id != LLUUID::null)
 		{
-			LLIMFloater::show(session_id);
+			LLFloaterIMContainer::getInstance()->showConversation(session_id);
 		}
 		make_ui_sound("UISndStartIM");
 		return session_id;
diff --git a/indra/newview/llgroupiconctrl.cpp b/indra/newview/llgroupiconctrl.cpp
index 2f9810775b8a3288351083cc46d4c47773bcc01d..2d0fc26c2a140e69a6210e55cd3a0470f9b6c4b1 100644
--- a/indra/newview/llgroupiconctrl.cpp
+++ b/indra/newview/llgroupiconctrl.cpp
@@ -29,6 +29,7 @@
 #include "llgroupiconctrl.h"
 
 #include "llagent.h"
+#include "llviewertexture.h"
 /*
 #include "llavatarconstants.h"
 #include "llcallingcard.h" // for LLAvatarTracker
@@ -38,7 +39,7 @@
 
 #include "llcachename.h"
 #include "llagentdata.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 */
 
 static LLDefaultChildRegistry::Register<LLGroupIconCtrl> g_i("group_icon");
diff --git a/indra/newview/llgrouplist.cpp b/indra/newview/llgrouplist.cpp
index 129cddda455f404f18b2f821560dee2ecace2384..aba3d74d878152478e2354ab87a9cb479682f8a1 100644
--- a/indra/newview/llgrouplist.cpp
+++ b/indra/newview/llgrouplist.cpp
@@ -86,7 +86,7 @@ LLGroupList::LLGroupList(const Params& p)
 	registrar.add("People.Groups.Action",			boost::bind(&LLGroupList::onContextMenuItemClick,	this, _2));
 	enable_registrar.add("People.Groups.Enable",	boost::bind(&LLGroupList::onContextMenuItemEnable,	this, _2));
 
-	LLMenuGL* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_people_groups.xml",
+	LLToggleableMenu* context_menu = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups.xml",
 			gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
 	if(context_menu)
 		mContextMenuHandle = context_menu->getHandle();
@@ -112,7 +112,7 @@ BOOL LLGroupList::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	BOOL handled = LLUICtrl::handleRightMouseDown(x, y, mask);
 
-	LLMenuGL* context_menu = (LLMenuGL*)mContextMenuHandle.get();
+	LLToggleableMenu* context_menu = mContextMenuHandle.get();
 	if (context_menu && size() > 0)
 	{
 		context_menu->buildDrawLabels();
@@ -406,7 +406,7 @@ void LLGroupListItem::setActive(bool active)
 	// *BUG: setName() overrides the style params.
 
 	// Active group should be bold.
-	LLFontDescriptor new_desc(mGroupNameBox->getDefaultFont()->getFontDesc());
+	LLFontDescriptor new_desc(mGroupNameBox->getFont()->getFontDesc());
 
 	// *NOTE dzaporozhan
 	// On Windows LLFontGL::NORMAL will not remove LLFontGL::BOLD if font 
diff --git a/indra/newview/llgrouplist.h b/indra/newview/llgrouplist.h
index 8abf14b3d031542fdd75f7d5dd55241fcc9593da..e96a7208860005e4cd341581b24712d2a97d71fe 100644
--- a/indra/newview/llgrouplist.h
+++ b/indra/newview/llgrouplist.h
@@ -28,10 +28,13 @@
 #define LL_LLGROUPLIST_H
 
 #include "llevent.h"
+#include "llpointer.h"
+
 #include "llflatlistview.h"
 #include "llpanel.h"
-#include "llpointer.h"
 #include "llstyle.h"
+#include "lltoggleablemenu.h"
+
 #include "llgroupmgr.h"
 
 /**
@@ -45,6 +48,10 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
 {
 	LOG_CLASS(LLGroupList);
 public:
+	struct Params : public LLInitParam::Block<Params, LLFlatListViewEx::Params>
+	{
+		Params(){};
+	};
 
 	LLGroupList(const Params& p);
 	virtual ~LLGroupList();
@@ -57,6 +64,8 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
 	void toggleIcons();
 	bool getIconsVisible() const { return mShowIcons; }
 
+	LLToggleableMenu* getContextMenu() const { return mContextMenuHandle.get(); }
+
 private:
 	void setDirty(bool val = true)		{ mDirty = val; }
 	void refresh();
@@ -66,7 +75,7 @@ class LLGroupList: public LLFlatListViewEx, public LLOldEvents::LLSimpleListener
 	bool onContextMenuItemClick(const LLSD& userdata);
 	bool onContextMenuItemEnable(const LLSD& userdata);
 
-	LLHandle<LLView>	mContextMenuHandle;
+	LLHandle<LLToggleableMenu>	mContextMenuHandle;
 
 	bool mShowIcons;
 	bool mDirty;
diff --git a/indra/newview/llgroupmgr.cpp b/indra/newview/llgroupmgr.cpp
index 81eb1d397e822a00bd3c7502120bd133c4d4990a..cbd844cdac07743deb4a444a3a602a5b5b44cdf3 100644
--- a/indra/newview/llgroupmgr.cpp
+++ b/indra/newview/llgroupmgr.cpp
@@ -1847,14 +1847,15 @@ class GroupMemberDataResponder : public LLHTTPClient::Responder
 		GroupMemberDataResponder() {}
 		virtual ~GroupMemberDataResponder() {}
 		virtual void result(const LLSD& pContent);
-		virtual void error(U32 pStatus, const std::string& pReason);
+		virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 private:
 		LLSD mMemberData;
 };
 
-void GroupMemberDataResponder::error(U32 pStatus, const std::string& pReason)
+void GroupMemberDataResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	LL_WARNS("GrpMgr") << "Error receiving group member data." << LL_ENDL;
+	LL_WARNS("GrpMgr") << "Error receiving group member data [status:" 
+		<< pStatus << "]: " << pContent << LL_ENDL;
 }
 
 void GroupMemberDataResponder::result(const LLSD& content)
diff --git a/indra/newview/llhomelocationresponder.cpp b/indra/newview/llhomelocationresponder.cpp
index 4850d18d994004c0599f9e6f58258579cfa95970..37428c4a44b5769885613c4ffc247f0c3b63b5a4 100644
--- a/indra/newview/llhomelocationresponder.cpp
+++ b/indra/newview/llhomelocationresponder.cpp
@@ -97,7 +97,7 @@ void LLHomeLocationResponder::result( const LLSD& content )
   }
 }
 
-void LLHomeLocationResponder::error( U32 status, const std::string& reason )
+void LLHomeLocationResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
 {
-  llinfos << "received error(" << reason  << ")" << llendl;
+	llwarns << "LLHomeLocationResponder error [status:" << status << "]: " << content << llendl;
 }
diff --git a/indra/newview/llhomelocationresponder.h b/indra/newview/llhomelocationresponder.h
index d640b9c894b4b38a89cfd6c24d14a687d78f1910..9bf4b12c4e9eef85c5e5cbd45de4b9fa220f2f35 100644
--- a/indra/newview/llhomelocationresponder.h
+++ b/indra/newview/llhomelocationresponder.h
@@ -36,7 +36,7 @@
 class LLHomeLocationResponder : public LLHTTPClient::Responder
 {
 	virtual void result( const LLSD& content );
-	virtual void error( U32 status, const std::string& reason );
+	virtual void errorWithContent( U32 status, const std::string& reason, const LLSD& content );
 };
 
 #endif
diff --git a/indra/newview/llhudeffectlookat.cpp b/indra/newview/llhudeffectlookat.cpp
index bc3b220dc098d9183782f865469c1e78251e6db0..9dde65ceb6bde7e29301a30405f3c722892de6a0 100644
--- a/indra/newview/llhudeffectlookat.cpp
+++ b/indra/newview/llhudeffectlookat.cpp
@@ -636,7 +636,7 @@ bool LLHUDEffectLookAt::calcTargetPosition()
 			}
 			else
 			{
-				target_rot = target_av->mRoot.getWorldRotation();
+				target_rot = target_av->mRoot->getWorldRotation();
 			}
 		}
 		else // target obj is not an avatar
diff --git a/indra/newview/llhudnametag.cpp b/indra/newview/llhudnametag.cpp
index 482294c8a614bf2aec9ba73251aefadd607cc684..33360979558ff345bff4dcc2b2c1254e08ee156c 100644
--- a/indra/newview/llhudnametag.cpp
+++ b/indra/newview/llhudnametag.cpp
@@ -166,7 +166,6 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 	}
 
 	// scale screen size of borders down
-	//RN: for now, text on hud objects is never occluded
 
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
@@ -187,45 +186,29 @@ BOOL LLHUDNameTag::lineSegmentIntersect(const LLVector3& start, const LLVector3&
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
 
-	//if (mUseBubble)
+	LLVector3 bg_pos = render_position
+		+ (F32)mOffsetY * y_pixel_vec
+		- (width_vec / 2.f)
+		- (height_vec);
+
+	LLVector3 v[] = 
 	{
-		LLVector3 bg_pos = render_position
-			+ (F32)mOffsetY * y_pixel_vec
-			- (width_vec / 2.f)
-			- (height_vec);
-		//LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
+		bg_pos,
+		bg_pos + width_vec,
+		bg_pos + width_vec + height_vec,
+		bg_pos + height_vec,
+	};
 
-		LLVector3 v[] = 
-		{
-			bg_pos,
-			bg_pos + width_vec,
-			bg_pos + width_vec + height_vec,
-			bg_pos + height_vec,
-		};
+	LLVector3 dir = end-start;
+	F32 a, b, t;
 
-		if (debug_render)
+	if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
+		LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
+	{
+		if (t <= 1.f)
 		{
-			gGL.begin(LLRender::LINE_STRIP);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[1].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.vertex3fv(v[3].mV);
-			gGL.vertex3fv(v[0].mV);
-			gGL.vertex3fv(v[2].mV);
-			gGL.end();
-		}
-
-		LLVector3 dir = end-start;
-		F32 a, b, t;
-
-		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a, b, t, FALSE) ||
-			LLTriangleRayIntersect(v[2], v[3], v[0], start, dir, a, b, t, FALSE) )
-		{
-			if (t <= 1.f)
-			{
-				intersection = start + dir*t;
-				return TRUE;
-			}
+			intersection = start + dir*t;
+			return TRUE;
 		}
 	}
 
@@ -241,12 +224,6 @@ void LLHUDNameTag::render()
 	}
 }
 
-void LLHUDNameTag::renderForSelect()
-{
-	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-	renderText(TRUE);
-}
-
 void LLHUDNameTag::renderText(BOOL for_select)
 {
 	if (!mVisible || mHidden)
@@ -299,24 +276,6 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	LLColor4 bg_color = LLUIColorTable::instance().getColor("NameTagBackground");
 	bg_color.setAlpha(gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
 
-	// maybe a no-op?
-	//const S32 border_height = 16;
-	//const S32 border_width = 16;
-	const S32 border_height = 8;
-	const S32 border_width = 8;
-
-	// *TODO move this into helper function
-	F32 border_scale = 1.f;
-
-	if (border_height * 2 > mHeight)
-	{
-		border_scale = (F32)mHeight / ((F32)border_height * 2.f);
-	}
-	if (border_width * 2 > mWidth)
-	{
-		border_scale = llmin(border_scale, (F32)mWidth / ((F32)border_width * 2.f));
-	}
-
 	// scale screen size of borders down
 	//RN: for now, text on hud objects is never occluded
 
@@ -325,152 +284,34 @@ void LLHUDNameTag::renderText(BOOL for_select)
 	
 	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 
-	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
 	LLVector3 width_vec = mWidth * x_pixel_vec;
 	LLVector3 height_vec = mHeight * y_pixel_vec;
-	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
-	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
 
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
 	LLCoordGL screen_pos;
 	LLViewerCamera::getInstance()->projectPosAgentToScreen(mPositionAgent, screen_pos, FALSE);
 
-	LLVector2 screen_offset;
-//	if (!mUseBubble)
-//	{
-//		screen_offset = mPositionOffset;
-//	}
-//	else
-//	{
-		screen_offset = updateScreenPos(mPositionOffset);
-//	}
+	LLVector2 screen_offset = updateScreenPos(mPositionOffset);
 
 	LLVector3 render_position = mPositionAgent  
 			+ (x_pixel_vec * screen_offset.mV[VX])
 			+ (y_pixel_vec * screen_offset.mV[VY]);
 
-//	if (mUseBubble)
+	LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
+	LLRect screen_rect;
+	screen_rect.setCenterAndSize(0, static_cast<S32>(lltrunc(-mHeight / 2 + mOffsetY)), static_cast<S32>(lltrunc(mWidth)), static_cast<S32>(lltrunc(mHeight)));
+	imagep->draw3D(render_position, x_pixel_vec, y_pixel_vec, screen_rect, bg_color);
+	if (mLabelSegments.size())
 	{
-		LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
-		LLUI::pushMatrix();
-		{
-			LLVector3 bg_pos = render_position
-				+ (F32)mOffsetY * y_pixel_vec
-				- (width_vec / 2.f)
-				- (height_vec);
-			LLUI::translate(bg_pos.mV[VX], bg_pos.mV[VY], bg_pos.mV[VZ]);
-
-			if (for_select)
-			{
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				S32 name = mSourceObject->mGLName;
-				LLColor4U coloru((U8)(name >> 16), (U8)(name >> 8), (U8)name);
-				gGL.color4ubv(coloru.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-				LLUI::popMatrix();
-				return;
-			}
-			else
-			{
-				gGL.getTexUnit(0)->bind(imagep->getImage());
-				
-				gGL.color4fv(bg_color.mV);
-				gl_segmented_rect_3d_tex(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, height_vec);
-		
-				if ( mLabelSegments.size())
-				{
-					LLUI::pushMatrix();
-					{
-						gGL.color4f(text_color.mV[VX], text_color.mV[VY], text_color.mV[VZ], gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor);
-						LLVector3 label_height = (mFontp->getLineHeight() * mLabelSegments.size() + (VERTICAL_PADDING / 3.f)) * y_pixel_vec;
-						LLVector3 label_offset = height_vec - label_height;
-						LLUI::translate(label_offset.mV[VX], label_offset.mV[VY], label_offset.mV[VZ]);
-						gl_segmented_rect_3d_tex_top(border_scale_vec, scaled_border_width, scaled_border_height, width_vec, label_height);
-					}
-					LLUI::popMatrix();
-				}
-			}
-
-			BOOL outside_width = llabs(mPositionOffset.mV[VX]) > mWidth * 0.5f;
-			BOOL outside_height = llabs(mPositionOffset.mV[VY] + (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.5f : 0.f)) > mHeight * (mVertAlignment == ALIGN_VERT_TOP ? mHeight * 0.75f : 0.5f);
+		LLUIImagePtr rect_top_image = LLUI::getUIImage("Rounded_Rect_Top");
+		LLRect label_top_rect = screen_rect;
+		const S32 label_height = llround((mFontp->getLineHeight() * (F32)mLabelSegments.size() + (VERTICAL_PADDING / 3.f)));
+		label_top_rect.mBottom = label_top_rect.mTop - label_height;
+		LLColor4 label_top_color = text_color;
+		label_top_color.mV[VALPHA] = gSavedSettings.getF32("ChatBubbleOpacity") * alpha_factor;
 
-			// draw line segments pointing to parent object
-			if (!mOffscreen && (outside_width || outside_height))
-			{
-				LLUI::pushMatrix();
-				{
-					gGL.color4fv(bg_color.mV);
-					LLVector3 target_pos = -1.f * (mPositionOffset.mV[VX] * x_pixel_vec + mPositionOffset.mV[VY] * y_pixel_vec);
-					target_pos += (width_vec / 2.f);
-					target_pos += mVertAlignment == ALIGN_VERT_CENTER ? (height_vec * 0.5f) : LLVector3::zero;
-					target_pos -= 3.f * x_pixel_vec;
-					target_pos -= 6.f * y_pixel_vec;
-					LLUI::translate(target_pos.mV[VX], target_pos.mV[VY], target_pos.mV[VZ]);
-					gl_segmented_rect_3d_tex(border_scale_vec, 3.f * x_pixel_vec, 3.f * y_pixel_vec, 6.f * x_pixel_vec, 6.f * y_pixel_vec);	
-				}
-				LLUI::popMatrix();
-
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				LLGLDepthTest gls_depth(mZCompare ? GL_TRUE : GL_FALSE, GL_FALSE);
-				
-				LLVector3 box_center_offset;
-				box_center_offset = (width_vec * 0.5f) + (height_vec * 0.5f);
-				LLUI::translate(box_center_offset.mV[VX], box_center_offset.mV[VY], box_center_offset.mV[VZ]);
-				gGL.color4fv(bg_color.mV);
-				LLUI::setLineWidth(2.0);
-				gGL.begin(LLRender::LINES);
-				{
-					if (outside_width)
-					{
-						LLVector3 vert;
-						// draw line in x then y
-						if (mPositionOffset.mV[VX] < 0.f)
-						{
-							// start at right edge
-							vert = width_vec * 0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at left edge
-							vert = width_vec * -0.5f;
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VX] * x_pixel_vec;
-						gGL.vertex3fv(vert.mV);
-						gGL.vertex3fv(vert.mV);
-						vert -= mPositionOffset.mV[VY] * y_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-					else
-					{
-						LLVector3 vert;
-						// draw line in y then x
-						if (mPositionOffset.mV[VY] < 0.f)
-						{
-							// start at top edge
-							vert = (height_vec * 0.5f) - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						else
-						{
-							// start at bottom edge
-							vert = (height_vec * -0.5f)  - (mPositionOffset.mV[VX] * x_pixel_vec);
-							gGL.vertex3fv(vert.mV);
-						}
-						vert = -mPositionOffset.mV[VY] * y_pixel_vec - mPositionOffset.mV[VX] * x_pixel_vec;
-						vert -= ((mVertAlignment == ALIGN_VERT_TOP) ? (height_vec * 0.5f) : LLVector3::zero);
-						gGL.vertex3fv(vert.mV);
-					}
-				}
-				gGL.end();
-				LLUI::setLineWidth(1.0);
-
-			}
-		}
-		LLUI::popMatrix();
+		rect_top_image->draw3D(render_position, x_pixel_vec, y_pixel_vec, label_top_rect, label_top_color);
 	}
 
 	F32 y_offset = (F32)mOffsetY;
@@ -874,29 +715,26 @@ void LLHUDNameTag::updateAll()
 	for (r_it = sVisibleTextObjects.rbegin(); r_it != sVisibleTextObjects.rend(); ++r_it)
 	{
 		LLHUDNameTag* textp = (*r_it);
-//		if (textp->mUseBubble)
-//		{
-			if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
-			{
-				textp->setLOD(3);
-			}
-			else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
-			{
-				textp->setLOD(2);
-			}
-			else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
-			{
-				textp->setLOD(1);
-			}
-			else
-			{
-				textp->setLOD(0);
-			}
-			textp->updateSize();
-			// find on-screen position and initialize collision rectangle
-			textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
-			current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
-//		}
+		if (current_screen_area / screen_area > LOD_2_SCREEN_COVERAGE)
+		{
+			textp->setLOD(3);
+		}
+		else if (current_screen_area / screen_area > LOD_1_SCREEN_COVERAGE)
+		{
+			textp->setLOD(2);
+		}
+		else if (current_screen_area / screen_area > LOD_0_SCREEN_COVERAGE)
+		{
+			textp->setLOD(1);
+		}
+		else
+		{
+			textp->setLOD(0);
+		}
+		textp->updateSize();
+		// find on-screen position and initialize collision rectangle
+		textp->mTargetPositionOffset = textp->updateScreenPos(LLVector2::zero);
+		current_screen_area += (F32)(textp->mSoftScreenRect.getWidth() * textp->mSoftScreenRect.getHeight());
 	}
 
 	LLStat* camera_vel_stat = LLViewerCamera::getInstance()->getVelocityStat();
@@ -914,20 +752,12 @@ void LLHUDNameTag::updateAll()
 		{
 			LLHUDNameTag* src_textp = (*src_it);
 
-//			if (!src_textp->mUseBubble)
-//			{
-//				continue;
-//			}
 			VisibleTextObjectIterator dst_it = src_it;
 			++dst_it;
 			for (; dst_it != sVisibleTextObjects.end(); ++dst_it)
 			{
 				LLHUDNameTag* dst_textp = (*dst_it);
 
-//				if (!dst_textp->mUseBubble)
-//				{
-//					continue;
-//				}
 				if (src_textp->mSoftScreenRect.overlaps(dst_textp->mSoftScreenRect))
 				{
 					LLRectf intersect_rect = src_textp->mSoftScreenRect;
@@ -976,10 +806,6 @@ void LLHUDNameTag::updateAll()
 	VisibleTextObjectIterator this_object_it;
 	for (this_object_it = sVisibleTextObjects.begin(); this_object_it != sVisibleTextObjects.end(); ++this_object_it)
 	{
-//		if (!(*this_object_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		(*this_object_it)->mPositionOffset = lerp((*this_object_it)->mPositionOffset, (*this_object_it)->mTargetPositionOffset, LLCriticalDamp::getInterpolant(POSITION_DAMPING_TC));
 	}
 }
@@ -1037,10 +863,6 @@ void LLHUDNameTag::addPickable(std::set<LLViewerObject*> &pick_list)
 	VisibleTextObjectIterator text_it;
 	for (text_it = sVisibleTextObjects.begin(); text_it != sVisibleTextObjects.end(); ++text_it)
 	{
-//		if (!(*text_it)->mUseBubble)
-//		{
-//			continue;
-//		}
 		pick_list.insert((*text_it)->mSourceObject);
 	}
 }
diff --git a/indra/newview/llhudnametag.h b/indra/newview/llhudnametag.h
index 3325c22def35e12a0f7cf2efa6deff48036174ff..72647d5b262dbd7c952f74f63909932f23b7d644 100644
--- a/indra/newview/llhudnametag.h
+++ b/indra/newview/llhudnametag.h
@@ -118,7 +118,6 @@ class LLHUDNameTag : public LLHUDObject
 	/*virtual*/ void markDead();
 	friend class LLHUDObject;
 	/*virtual*/ F32 getDistance() const { return mLastDistance; }
-	//void setUseBubble(BOOL use_bubble) { mUseBubble = use_bubble; }
 	S32  getLOD() { return mLOD; }
 	BOOL getVisible() { return mVisible; }
 	BOOL getHidden() const { return mHidden; }
@@ -136,7 +135,6 @@ class LLHUDNameTag : public LLHUDObject
 	LLHUDNameTag(const U8 type);
 
 	/*virtual*/ void render();
-	/*virtual*/ void renderForSelect();
 	void renderText(BOOL for_select);
 	static void updateAll();
 	void setLOD(S32 lod);
diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp
index 579b6008ae85ad769e63b2bccba042383b3fc8f0..3c6bcd982995b9a19fb34ce228bb7241f5d6d259 100644
--- a/indra/newview/llhudtext.cpp
+++ b/indra/newview/llhudtext.cpp
@@ -186,11 +186,8 @@ void LLHUDText::renderText()
 		LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
 	}
 
-	LLVector2 border_scale_vec((F32)border_width / (F32)imagep->getTextureWidth(), (F32)border_height / (F32)imagep->getTextureHeight());
 	LLVector3 width_vec = mWidth * x_pixel_vec;
 	LLVector3 height_vec = mHeight * y_pixel_vec;
-	LLVector3 scaled_border_width = (F32)llfloor(border_scale * (F32)border_width) * x_pixel_vec;
-	LLVector3 scaled_border_height = (F32)llfloor(border_scale * (F32)border_height) * y_pixel_vec;
 
 	mRadius = (width_vec + height_vec).magVec() * 0.5f;
 
@@ -440,7 +437,7 @@ LLVector2 LLHUDText::updateScreenPos(LLVector2 &offset)
 	LLVector3 x_pixel_vec;
 	LLVector3 y_pixel_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(mPositionAgent, y_pixel_vec, x_pixel_vec);
-	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
+//	LLVector3 world_pos = mPositionAgent + (offset.mV[VX] * x_pixel_vec) + (offset.mV[VY] * y_pixel_vec);
 //	if (!LLViewerCamera::getInstance()->projectPosAgentToScreen(world_pos, screen_pos, FALSE) && mVisibleOffScreen)
 //	{
 //		// bubble off-screen, so find a spot for it along screen edge
diff --git a/indra/newview/llimfloater.cpp b/indra/newview/llimfloater.cpp
deleted file mode 100644
index 63eedcdfeae4d849fcc2eaa3047c9d96c19a0cf3..0000000000000000000000000000000000000000
--- a/indra/newview/llimfloater.cpp
+++ /dev/null
@@ -1,1195 +0,0 @@
-/** 
- * @file llimfloater.cpp
- * @brief LLIMFloater class definition
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimfloater.h"
-
-#include "llnotificationsutil.h"
-
-#include "llagent.h"
-#include "llappviewer.h"
-#include "llavatarnamecache.h"
-#include "llbutton.h"
-#include "llchannelmanager.h"
-#include "llchiclet.h"
-#include "llchicletbar.h"
-#include "llfloaterreg.h"
-#include "llimfloatercontainer.h" // to replace separate IM Floaters with multifloater container
-#include "llinventoryfunctions.h"
-#include "lllayoutstack.h"
-#include "lllineeditor.h"
-#include "lllogchat.h"
-#include "llpanelimcontrolpanel.h"
-#include "llscreenchannel.h"
-#include "llsyswellwindow.h"
-#include "lltrans.h"
-#include "llchathistory.h"
-#include "llnotifications.h"
-#include "llviewerwindow.h"
-#include "llvoicechannel.h"
-#include "lltransientfloatermgr.h"
-#include "llinventorymodel.h"
-#include "llrootview.h"
-#include "llspeakers.h"
-#include "llviewerchat.h"
-#include "llautoreplace.h"
-
-LLIMFloater::LLIMFloater(const LLUUID& session_id)
-  : LLTransientDockableFloater(NULL, true, session_id),
-	mControlPanel(NULL),
-	mSessionID(session_id),
-	mLastMessageIndex(-1),
-	mDialog(IM_NOTHING_SPECIAL),
-	mChatHistory(NULL),
-	mInputEditor(NULL),
-	mSavedTitle(),
-	mTypingStart(),
-	mShouldSendTypingState(false),
-	mMeTyping(false),
-	mOtherTyping(false),
-	mTypingTimer(),
-	mTypingTimeoutTimer(),
-	mPositioned(false),
-	mSessionInitialized(false)
-{
-	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionID);
-	if (im_session)
-	{
-		mSessionInitialized = im_session->mSessionInitialized;
-		
-		mDialog = im_session->mType;
-		switch(mDialog){
-		case IM_NOTHING_SPECIAL:
-		case IM_SESSION_P2P_INVITE:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelIMControl, this);
-			break;
-		case IM_SESSION_CONFERENCE_START:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
-			break;
-		case IM_SESSION_GROUP_START:
-			mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
-			break;
-		case IM_SESSION_INVITE:		
-			if (gAgent.isInGroup(mSessionID))
-			{
-				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelGroupControl, this);
-			}
-			else
-			{
-				mFactoryMap["panel_im_control_panel"] = LLCallbackMap(createPanelAdHocControl, this);
-			}
-			break;
-		default: break;
-		}
-	}
-	setOverlapsScreenChannel(true);
-
-	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-
-	setDocked(true);
-}
-
-void LLIMFloater::onFocusLost()
-{
-	LLIMModel::getInstance()->resetActiveSessionID();
-	
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, false);
-}
-
-void LLIMFloater::onFocusReceived()
-{
-	LLIMModel::getInstance()->setActiveSessionID(mSessionID);
-
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(mSessionID, true);
-
-	if (getVisible())
-	{
-		LLIMModel::instance().sendNoUnreadMessages(mSessionID);
-	}
-}
-
-// virtual
-void LLIMFloater::onClose(bool app_quitting)
-{
-	setTyping(false);
-
-	// The source of much argument and design thrashing
-	// Should the window hide or the session close when the X is clicked?
-	//
-	// Last change:
-	// EXT-3516 X Button should end IM session, _ button should hide
-	gIMMgr->leaveSession(mSessionID);
-}
-
-/* static */
-void LLIMFloater::newIMCallback(const LLSD& data){
-	
-	if (data["num_unread"].asInteger() > 0 || data["from_id"].asUUID().isNull())
-	{
-		LLUUID session_id = data["session_id"].asUUID();
-
-		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (floater == NULL) return;
-
-        // update if visible, otherwise will be updated when opened
-		if (floater->getVisible())
-		{
-			floater->updateMessages();
-		}
-	}
-}
-
-void LLIMFloater::onVisibilityChange(const LLSD& new_visibility)
-{
-	bool visible = new_visibility.asBoolean();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (visible && voice_channel &&
-		voice_channel->getState() == LLVoiceChannel::STATE_CONNECTED)
-	{
-		LLFloaterReg::showInstance("voice_call", mSessionID);
-	}
-	else
-	{
-		LLFloaterReg::hideInstance("voice_call", mSessionID);
-	}
-}
-
-void LLIMFloater::onSendMsg( LLUICtrl* ctrl, void* userdata )
-{
-	LLIMFloater* self = (LLIMFloater*) userdata;
-	self->sendMsg();
-	self->setTyping(false);
-}
-
-void LLIMFloater::sendMsg()
-{
-	if (!gAgent.isGodlike() 
-		&& (mDialog == IM_NOTHING_SPECIAL)
-		&& mOtherParticipantUUID.isNull())
-	{
-		llinfos << "Cannot send IM to everyone unless you're a god." << llendl;
-		return;
-	}
-
-	if (mInputEditor)
-	{
-		LLWString text = mInputEditor->getConvertedText();
-		if(!text.empty())
-		{
-			// Truncate and convert to UTF8 for transport
-			std::string utf8_text = wstring_to_utf8str(text);
-			utf8_text = utf8str_truncate(utf8_text, MAX_MSG_BUF_SIZE - 1);
-			
-			if (mSessionInitialized)
-			{
-				LLIMModel::sendMessage(utf8_text, mSessionID,
-					mOtherParticipantUUID,mDialog);
-			}
-			else
-			{
-				//queue up the message to send once the session is initialized
-				mQueuedMsgsForInit.append(utf8_text);
-			}
-
-			mInputEditor->setText(LLStringUtil::null);
-
-			updateMessages();
-		}
-	}
-}
-
-
-
-LLIMFloater::~LLIMFloater()
-{
-	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-}
-
-//virtual
-BOOL LLIMFloater::postBuild()
-{
-	const LLUUID& other_party_id = LLIMModel::getInstance()->getOtherParticipantID(mSessionID);
-	if (other_party_id.notNull())
-	{
-		mOtherParticipantUUID = other_party_id;
-	}
-
-	mControlPanel->setSessionId(mSessionID);
-	mControlPanel->getParent()->setVisible(gSavedSettings.getBOOL("IMShowControlPanel"));
-
-	LLButton* slide_left = getChild<LLButton>("slide_left_btn");
-	slide_left->setVisible(mControlPanel->getParent()->getVisible());
-	slide_left->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
-	LLButton* slide_right = getChild<LLButton>("slide_right_btn");
-	slide_right->setVisible(!mControlPanel->getParent()->getVisible());
-	slide_right->setClickedCallback(boost::bind(&LLIMFloater::onSlide, this));
-
-	mInputEditor = getChild<LLLineEditor>("chat_editor");
-	mInputEditor->setMaxTextLength(1023);
-	// enable line history support for instant message bar
-	mInputEditor->setEnableLineHistory(TRUE);
-	// *TODO Establish LineEditor with autoreplace callback
-	mInputEditor->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-
-	LLFontGL* font = LLViewerChat::getChatFont();
-	mInputEditor->setFont(font);	
-	
-	mInputEditor->setFocusReceivedCallback( boost::bind(onInputEditorFocusReceived, _1, this) );
-	mInputEditor->setFocusLostCallback( boost::bind(onInputEditorFocusLost, _1, this) );
-	mInputEditor->setKeystrokeCallback( onInputEditorKeystroke, this );
-	mInputEditor->setCommitOnFocusLost( FALSE );
-	mInputEditor->setRevertOnEsc( FALSE );
-	mInputEditor->setReplaceNewlinesWithSpaces( FALSE );
-	mInputEditor->setPassDelete( TRUE );
-
-	childSetCommitCallback("chat_editor", onSendMsg, this);
-	
-	mChatHistory = getChild<LLChatHistory>("chat_history");
-
-	setDocked(true);
-
-	mTypingStart = LLTrans::getString("IM_typing_start_string");
-
-	// Disable input editor if session cannot accept text
-	LLIMModel::LLIMSession* im_session =
-		LLIMModel::instance().findIMSession(mSessionID);
-	if( im_session && !im_session->mTextIMPossible )
-	{
-		mInputEditor->setEnabled(FALSE);
-		mInputEditor->setLabel(LLTrans::getString("IM_unavailable_text_label"));
-	}
-
-	if ( im_session && im_session->isP2PSessionType())
-	{
-		// look up display name for window title
-		LLAvatarNameCache::get(im_session->mOtherParticipantID,
-							   boost::bind(&LLIMFloater::onAvatarNameCache,
-										   this, _1, _2));
-	}
-	else
-	{
-		std::string session_name(LLIMModel::instance().getName(mSessionID));
-		updateSessionName(session_name, session_name);
-	}
-	
-	//*TODO if session is not initialized yet, add some sort of a warning message like "starting session...blablabla"
-	//see LLFloaterIMPanel for how it is done (IB)
-
-	if(isChatMultiTab())
-	{
-		return LLFloater::postBuild();
-	}
-	else
-	{
-		return LLDockableFloater::postBuild();
-	}
-}
-
-void LLIMFloater::updateSessionName(const std::string& ui_title,
-									const std::string& ui_label)
-{
-	mInputEditor->setLabel(LLTrans::getString("IM_to_label") + " " + ui_label);
-	setTitle(ui_title);	
-}
-
-void LLIMFloater::onAvatarNameCache(const LLUUID& agent_id,
-									const LLAvatarName& av_name)
-{
-	// Use display name only for labels, as the extended name will be in the
-	// floater title
-	std::string ui_title = av_name.getCompleteName();
-	updateSessionName(ui_title, av_name.mDisplayName);
-	mTypingStart.setArg("[NAME]", ui_title);
-}
-
-// virtual
-void LLIMFloater::draw()
-{
-	if ( mMeTyping )
-	{
-		// Time out if user hasn't typed for a while.
-		if ( mTypingTimeoutTimer.getElapsedTimeF32() > LLAgent::TYPING_TIMEOUT_SECS )
-		{
-			setTyping(false);
-		}
-	}
-
-	LLTransientDockableFloater::draw();
-}
-
-
-// static
-void* LLIMFloater::createPanelIMControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelIMControlPanel();
-	self->mControlPanel->setXMLFilename("panel_im_control_panel.xml");
-	return self->mControlPanel;
-}
-
-
-// static
-void* LLIMFloater::createPanelGroupControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelGroupControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_group_control_panel.xml");
-	return self->mControlPanel;
-}
-
-// static
-void* LLIMFloater::createPanelAdHocControl(void* userdata)
-{
-	LLIMFloater *self = (LLIMFloater*)userdata;
-	self->mControlPanel = new LLPanelAdHocControlPanel(self->mSessionID);
-	self->mControlPanel->setXMLFilename("panel_adhoc_control_panel.xml");
-	return self->mControlPanel;
-}
-
-void LLIMFloater::onSlide()
-{
-	mControlPanel->getParent()->setVisible(!mControlPanel->getParent()->getVisible());
-
-	gSavedSettings.setBOOL("IMShowControlPanel", mControlPanel->getParent()->getVisible());
-
-	getChild<LLButton>("slide_left_btn")->setVisible(mControlPanel->getParent()->getVisible());
-	getChild<LLButton>("slide_right_btn")->setVisible(!mControlPanel->getParent()->getVisible());
-}
-
-//static
-LLIMFloater* LLIMFloater::show(const LLUUID& session_id)
-{
-	closeHiddenIMToasts();
-
-	if (!gIMMgr->hasSession(session_id)) return NULL;
-
-	if(!isChatMultiTab())
-	{
-		//hide all
-		LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-		for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-			 iter != inst_list.end(); ++iter)
-		{
-			LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-			if (floater && floater->isDocked())
-			{
-				floater->setVisible(false);
-			}
-		}
-	}
-
-	bool exist = findInstance(session_id);
-
-	LLIMFloater* floater = getInstance(session_id);
-	if (!floater) return NULL;
-
-	if(isChatMultiTab())
-	{
-		LLIMFloaterContainer* floater_container = LLIMFloaterContainer::getInstance();
-
-		// do not add existed floaters to avoid adding torn off instances
-		if (!exist)
-		{
-			//		LLTabContainer::eInsertionPoint i_pt = user_initiated ? LLTabContainer::RIGHT_OF_CURRENT : LLTabContainer::END;
-			// TODO: mantipov: use LLTabContainer::RIGHT_OF_CURRENT if it exists
-			LLTabContainer::eInsertionPoint i_pt = LLTabContainer::END;
-			
-			if (floater_container)
-			{
-				floater_container->addFloater(floater, TRUE, i_pt);
-			}
-		}
-
-		floater->openFloater(floater->getKey());
-	}
-	else
-	{
-		// Docking may move chat window, hide it before moving, or user will see how window "jumps"
-		floater->setVisible(false);
-
-		if (floater->getDockControl() == NULL)
-		{
-			LLChiclet* chiclet =
-					LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(
-							session_id);
-			if (chiclet == NULL)
-			{
-				llerror("Dock chiclet for LLIMFloater doesn't exists", 0);
-			}
-			else
-			{
-				LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
-			}
-
-			floater->setDockControl(new LLDockControl(chiclet, floater, floater->getDockTongue(),
-					LLDockControl::BOTTOM));
-		}
-
-		// window is positioned, now we can show it.
-	}
-	floater->setVisible(TRUE);
-
-	return floater;
-}
-
-void LLIMFloater::setDocked(bool docked, bool pop_on_undock)
-{
-	// update notification channel state
-	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-	
-	if(!isChatMultiTab())
-	{
-		LLTransientDockableFloater::setDocked(docked, pop_on_undock);
-	}
-
-	// update notification channel state
-	if(channel)
-	{
-		channel->updateShowToastsState();
-		channel->redrawToasts();
-	}
-}
-
-void LLIMFloater::setVisible(BOOL visible)
-{
-	LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-		(LLNotificationsUI::LLChannelManager::getInstance()->
-											findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-	LLTransientDockableFloater::setVisible(visible);
-
-	// update notification channel state
-	if(channel)
-	{
-		channel->updateShowToastsState();
-		channel->redrawToasts();
-	}
-
-	BOOL is_minimized = visible && isChatMultiTab()
-		? LLIMFloaterContainer::getInstance()->isMinimized()
-		: !visible;
-
-	if (!is_minimized && mChatHistory && mInputEditor)
-	{
-		//only if floater was construced and initialized from xml
-		updateMessages();
-		//prevent stealing focus when opening a background IM tab (EXT-5387, checking focus for EXT-6781)
-		if (!isChatMultiTab() || hasFocus())
-		{
-			mInputEditor->setFocus(TRUE);
-		}
-	}
-
-	if(!visible)
-	{
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(mSessionID);
-		if(chiclet)
-		{
-			chiclet->setToggleState(false);
-		}
-	}
-}
-
-BOOL LLIMFloater::getVisible()
-{
-	if(isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_container = LLIMFloaterContainer::getInstance();
-		
-		// Treat inactive floater as invisible.
-		bool is_active = im_container->getActiveFloater() == this;
-	
-		//torn off floater is always inactive
-		if (!is_active && getHost() != im_container)
-		{
-			return LLTransientDockableFloater::getVisible();
-		}
-
-		// getVisible() returns TRUE when Tabbed IM window is minimized.
-		return is_active && !im_container->isMinimized() && im_container->getVisible();
-	}
-	else
-	{
-		return LLTransientDockableFloater::getVisible();
-	}
-}
-
-//static
-bool LLIMFloater::toggle(const LLUUID& session_id)
-{
-	if(!isChatMultiTab())
-	{
-		LLIMFloater* floater = LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-		if (floater && floater->getVisible() && floater->hasFocus())
-		{
-			// clicking on chiclet to close floater just hides it to maintain existing
-			// scroll/text entry state
-			floater->setVisible(false);
-			return false;
-		}
-		else if(floater && (!floater->isDocked() || floater->getVisible() && !floater->hasFocus()))
-		{
-			floater->setVisible(TRUE);
-			floater->setFocus(TRUE);
-			return true;
-		}
-	}
-
-	// ensure the list of messages is updated when floater is made visible
-	show(session_id);
-	return true;
-}
-
-//static
-LLIMFloater* LLIMFloater::findInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-LLIMFloater* LLIMFloater::getInstance(const LLUUID& session_id)
-{
-	return LLFloaterReg::getTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-void LLIMFloater::sessionInitReplyReceived(const LLUUID& im_session_id)
-{
-	mSessionInitialized = true;
-
-	//will be different only for an ad-hoc im session
-	if (mSessionID != im_session_id)
-	{
-		mSessionID = im_session_id;
-		setKey(im_session_id);
-		mControlPanel->setSessionId(im_session_id);
-	}
-
-	// updating "Call" button from group control panel here to enable it without placing into draw() (EXT-4796)
-	if(gAgent.isInGroup(im_session_id))
-	{
-		mControlPanel->updateCallButton();
-	}
-	
-	//*TODO here we should remove "starting session..." warning message if we added it in postBuild() (IB)
-
-
-	//need to send delayed messaged collected while waiting for session initialization
-	if (!mQueuedMsgsForInit.size()) return;
-	LLSD::array_iterator iter;
-	for ( iter = mQueuedMsgsForInit.beginArray();
-		iter != mQueuedMsgsForInit.endArray();
-		++iter)
-	{
-		LLIMModel::sendMessage(iter->asString(), mSessionID,
-			mOtherParticipantUUID, mDialog);
-	}
-}
-
-void LLIMFloater::updateMessages()
-{
-	bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
-
-	std::list<LLSD> messages;
-
-	// we shouldn't reset unread message counters if IM floater doesn't have focus
-	if (hasFocus())
-	{
-		LLIMModel::instance().getMessages(mSessionID, messages, mLastMessageIndex+1);
-	}
-	else
-	{
-		LLIMModel::instance().getMessagesSilently(mSessionID, messages, mLastMessageIndex+1);
-	}
-
-	if (messages.size())
-	{
-		LLSD chat_args;
-		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
-
-		std::ostringstream message;
-		std::list<LLSD>::const_reverse_iterator iter = messages.rbegin();
-		std::list<LLSD>::const_reverse_iterator iter_end = messages.rend();
-		for (; iter != iter_end; ++iter)
-		{
-			LLSD msg = *iter;
-
-			std::string time = msg["time"].asString();
-			LLUUID from_id = msg["from_id"].asUUID();
-			std::string from = msg["from"].asString();
-			std::string message = msg["message"].asString();
-			bool is_history = msg["is_history"].asBoolean();
-
-			LLChat chat;
-			chat.mFromID = from_id;
-			chat.mSessionID = mSessionID;
-			chat.mFromName = from;
-			chat.mTimeStr = time;
-			chat.mChatStyle = is_history ? CHAT_STYLE_HISTORY : chat.mChatStyle;
-
-			// process offer notification
-			if (msg.has("notification_id"))
-			{
-				chat.mNotifId = msg["notification_id"].asUUID();
-				// if notification exists - embed it
-				if (LLNotificationsUtil::find(chat.mNotifId) != NULL)
-				{
-					// remove embedded notification from channel
-					LLNotificationsUI::LLScreenChannel* channel = static_cast<LLNotificationsUI::LLScreenChannel*>
-							(LLNotificationsUI::LLChannelManager::getInstance()->
-																findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-					if (getVisible())
-					{
-						// toast will be automatically closed since it is not storable toast
-						channel->hideToast(chat.mNotifId);
-					}
-				}
-				// if notification doesn't exist - try to use next message which should be log entry
-				else
-				{
-					continue;
-				}
-			}
-			//process text message
-			else
-			{
-				chat.mText = message;
-			}
-			
-			mChatHistory->appendMessage(chat, chat_args);
-			mLastMessageIndex = msg["index"].asInteger();
-
-			// if it is a notification - next message is a notification history log, so skip it
-			if (chat.mNotifId.notNull() && LLNotificationsUtil::find(chat.mNotifId) != NULL)
-			{
-				if (++iter == iter_end)
-				{
-					break;
-				}
-				else
-				{
-					mLastMessageIndex++;
-				}
-			}
-		}
-	}
-}
-
-void LLIMFloater::reloadMessages()
-{
-	mChatHistory->clear();
-	mLastMessageIndex = -1;
-	updateMessages();
-}
-
-// static
-void LLIMFloater::onInputEditorFocusReceived( LLFocusableElement* caller, void* userdata )
-{
-	LLIMFloater* self= (LLIMFloater*) userdata;
-
-	// Allow enabling the LLIMFloater input editor only if session can accept text
-	LLIMModel::LLIMSession* im_session =
-		LLIMModel::instance().findIMSession(self->mSessionID);
-	//TODO: While disabled lllineeditor can receive focus we need to check if it is enabled (EK)
-	if( im_session && im_session->mTextIMPossible && self->mInputEditor->getEnabled())
-	{
-		//in disconnected state IM input editor should be disabled
-		self->mInputEditor->setEnabled(!gDisconnected);
-	}
-}
-
-// static
-void LLIMFloater::onInputEditorFocusLost(LLFocusableElement* caller, void* userdata)
-{
-	LLIMFloater* self = (LLIMFloater*) userdata;
-	self->setTyping(false);
-}
-
-// static
-void LLIMFloater::onInputEditorKeystroke(LLLineEditor* caller, void* userdata)
-{
-	LLIMFloater* self = (LLIMFloater*)userdata;
-	std::string text = self->mInputEditor->getText();
-	if (!text.empty())
-	{
-		self->setTyping(true);
-	}
-	else
-	{
-		// Deleting all text counts as stopping typing.
-		self->setTyping(false);
-	}
-}
-
-void LLIMFloater::setTyping(bool typing)
-{
-	if ( typing )
-	{
-		// Started or proceeded typing, reset the typing timeout timer
-		mTypingTimeoutTimer.reset();
-	}
-
-	if ( mMeTyping != typing )
-	{
-		// Typing state is changed
-		mMeTyping = typing;
-		// So, should send current state
-		mShouldSendTypingState = true;
-		// In case typing is started, send state after some delay
-		mTypingTimer.reset();
-	}
-
-	// Don't want to send typing indicators to multiple people, potentially too
-	// much network traffic. Only send in person-to-person IMs.
-	if ( mShouldSendTypingState && mDialog == IM_NOTHING_SPECIAL )
-	{
-		if ( mMeTyping )
-		{
-			if ( mTypingTimer.getElapsedTimeF32() > 1.f )
-			{
-				// Still typing, send 'start typing' notification
-				LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, TRUE);
-				mShouldSendTypingState = false;
-			}
-		}
-		else
-		{
-			// Send 'stop typing' notification immediately
-			LLIMModel::instance().sendTypingState(mSessionID, mOtherParticipantUUID, FALSE);
-			mShouldSendTypingState = false;
-		}
-	}
-
-	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-	if (speaker_mgr)
-		speaker_mgr->setSpeakerTyping(gAgent.getID(), FALSE);
-
-}
-
-void LLIMFloater::processIMTyping(const LLIMInfo* im_info, BOOL typing)
-{
-	if ( typing )
-	{
-		// other user started typing
-		addTypingIndicator(im_info);
-	}
-	else
-	{
-		// other user stopped typing
-		removeTypingIndicator(im_info);
-	}
-}
-
-void LLIMFloater::processAgentListUpdates(const LLSD& body)
-{
-	if ( !body.isMap() ) return;
-
-	if ( body.has("agent_updates") && body["agent_updates"].isMap() )
-	{
-		LLSD agent_data = body["agent_updates"].get(gAgentID.asString());
-		if (agent_data.isMap() && agent_data.has("info"))
-		{
-			LLSD agent_info = agent_data["info"];
-
-			if (agent_info.has("mutes"))
-			{
-				BOOL moderator_muted_text = agent_info["mutes"]["text"].asBoolean(); 
-				mInputEditor->setEnabled(!moderator_muted_text);
-				std::string label;
-				if (moderator_muted_text)
-					label = LLTrans::getString("IM_muted_text_label");
-				else
-					label = LLTrans::getString("IM_to_label") + " " + LLIMModel::instance().getName(mSessionID);
-				mInputEditor->setLabel(label);
-
-				if (moderator_muted_text)
-					LLNotificationsUtil::add("TextChatIsMutedByModerator");
-			}
-		}
-	}
-}
-
-void LLIMFloater::updateChatHistoryStyle()
-{
-	mChatHistory->clear();
-	mLastMessageIndex = -1;
-	updateMessages();
-}
-
-void LLIMFloater::processChatHistoryStyleUpdate(const LLSD& newvalue)
-{
-	LLFontGL* font = LLViewerChat::getChatFont();
-	LLFloaterReg::const_instance_list_t& inst_list = LLFloaterReg::getFloaterList("impanel");
-	for (LLFloaterReg::const_instance_list_t::const_iterator iter = inst_list.begin();
-		 iter != inst_list.end(); ++iter)
-	{
-		LLIMFloater* floater = dynamic_cast<LLIMFloater*>(*iter);
-		if (floater)
-		{
-			floater->updateChatHistoryStyle();
-			floater->mInputEditor->setFont(font);
-		}
-	}
-
-}
-
-void LLIMFloater::processSessionUpdate(const LLSD& session_update)
-{
-	// *TODO : verify following code when moderated mode will be implemented
-	if ( false && session_update.has("moderated_mode") &&
-		 session_update["moderated_mode"].has("voice") )
-	{
-		BOOL voice_moderated = session_update["moderated_mode"]["voice"];
-		const std::string session_label = LLIMModel::instance().getName(mSessionID);
-
-		if (voice_moderated)
-		{
-			setTitle(session_label + std::string(" ") + LLTrans::getString("IM_moderated_chat_label"));
-		}
-		else
-		{
-			setTitle(session_label);
-		}
-
-		// *TODO : uncomment this when/if LLPanelActiveSpeakers panel will be added
-		//update the speakers dropdown too
-		//mSpeakerPanel->setVoiceModerationCtrlMode(voice_moderated);
-	}
-}
-
-BOOL LLIMFloater::handleDragAndDrop(S32 x, S32 y, MASK mask,
-						   BOOL drop, EDragAndDropType cargo_type,
-						   void *cargo_data, EAcceptance *accept,
-						   std::string& tooltip_msg)
-{
-
-	if (mDialog == IM_NOTHING_SPECIAL)
-	{
-		LLToolDragAndDrop::handleGiveDragAndDrop(mOtherParticipantUUID, mSessionID, drop,
-												 cargo_type, cargo_data, accept);
-	}
-
-	// handle case for dropping calling cards (and folders of calling cards) onto invitation panel for invites
-	else if (isInviteAllowed())
-	{
-		*accept = ACCEPT_NO;
-
-		if (cargo_type == DAD_CALLINGCARD)
-		{
-			if (dropCallingCard((LLInventoryItem*)cargo_data, drop))
-			{
-				*accept = ACCEPT_YES_MULTI;
-			}
-		}
-		else if (cargo_type == DAD_CATEGORY)
-		{
-			if (dropCategory((LLInventoryCategory*)cargo_data, drop))
-			{
-				*accept = ACCEPT_YES_MULTI;
-			}
-		}
-	}
-	return TRUE;
-}
-
-BOOL LLIMFloater::dropCallingCard(LLInventoryItem* item, BOOL drop)
-{
-	BOOL rv = isInviteAllowed();
-	if(rv && item && item->getCreatorUUID().notNull())
-	{
-		if(drop)
-		{
-			uuid_vec_t ids;
-			ids.push_back(item->getCreatorUUID());
-			inviteToSession(ids);
-		}
-	}
-	else
-	{
-		// set to false if creator uuid is null.
-		rv = FALSE;
-	}
-	return rv;
-}
-
-BOOL LLIMFloater::dropCategory(LLInventoryCategory* category, BOOL drop)
-{
-	BOOL rv = isInviteAllowed();
-	if(rv && category)
-	{
-		LLInventoryModel::cat_array_t cats;
-		LLInventoryModel::item_array_t items;
-		LLUniqueBuddyCollector buddies;
-		gInventory.collectDescendentsIf(category->getUUID(),
-										cats,
-										items,
-										LLInventoryModel::EXCLUDE_TRASH,
-										buddies);
-		S32 count = items.count();
-		if(count == 0)
-		{
-			rv = FALSE;
-		}
-		else if(drop)
-		{
-			uuid_vec_t ids;
-			ids.reserve(count);
-			for(S32 i = 0; i < count; ++i)
-			{
-				ids.push_back(items.get(i)->getCreatorUUID());
-			}
-			inviteToSession(ids);
-		}
-	}
-	return rv;
-}
-
-BOOL LLIMFloater::isInviteAllowed() const
-{
-
-	return ( (IM_SESSION_CONFERENCE_START == mDialog)
-			 || (IM_SESSION_INVITE == mDialog) );
-}
-
-class LLSessionInviteResponder : public LLHTTPClient::Responder
-{
-public:
-	LLSessionInviteResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-
-	void error(U32 statusNum, const std::string& reason)
-	{
-		llinfos << "Error inviting all agents to session" << llendl;
-		//throw something back to the viewer here?
-	}
-
-private:
-	LLUUID mSessionID;
-};
-
-BOOL LLIMFloater::inviteToSession(const uuid_vec_t& ids)
-{
-	LLViewerRegion* region = gAgent.getRegion();
-	if (!region)
-	{
-		return FALSE;
-	}
-
-	S32 count = ids.size();
-
-	if( isInviteAllowed() && (count > 0) )
-	{
-		llinfos << "LLIMFloater::inviteToSession() - inviting participants" << llendl;
-
-		std::string url = region->getCapability("ChatSessionRequest");
-
-		LLSD data;
-
-		data["params"] = LLSD::emptyArray();
-		for (int i = 0; i < count; i++)
-		{
-			data["params"].append(ids[i]);
-		}
-
-		data["method"] = "invite";
-		data["session-id"] = mSessionID;
-		LLHTTPClient::post(
-			url,
-			data,
-			new LLSessionInviteResponder(
-					mSessionID));
-	}
-	else
-	{
-		llinfos << "LLIMFloater::inviteToSession -"
-				<< " no need to invite agents for "
-				<< mDialog << llendl;
-		// successful add, because everyone that needed to get added
-		// was added.
-	}
-
-	return TRUE;
-}
-
-void LLIMFloater::addTypingIndicator(const LLIMInfo* im_info)
-{
-	// We may have lost a "stop-typing" packet, don't add it twice
-	if ( im_info && !mOtherTyping )
-	{
-		mOtherTyping = true;
-
-		// Save and set new title
-		mSavedTitle = getTitle();
-		setTitle (mTypingStart);
-
-		// Update speaker
-		LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-		if ( speaker_mgr )
-		{
-			speaker_mgr->setSpeakerTyping(im_info->mFromID, TRUE);
-		}
-	}
-}
-
-void LLIMFloater::removeTypingIndicator(const LLIMInfo* im_info)
-{
-	if ( mOtherTyping )
-	{
-		mOtherTyping = false;
-
-		// Revert the title to saved one
-		setTitle(mSavedTitle);
-
-		if ( im_info )
-		{
-			// Update speaker
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(mSessionID);
-			if ( speaker_mgr )
-			{
-				speaker_mgr->setSpeakerTyping(im_info->mFromID, FALSE);
-			}
-		}
-
-	}
-}
-
-// static
-void LLIMFloater::closeHiddenIMToasts()
-{
-	class IMToastMatcher: public LLNotificationsUI::LLScreenChannel::Matcher
-	{
-	public:
-		bool matches(const LLNotificationPtr notification) const
-		{
-			// "notifytoast" type of notifications is reserved for IM notifications
-			return "notifytoast" == notification->getType();
-		}
-	};
-
-	LLNotificationsUI::LLScreenChannel* channel = LLNotificationsUI::LLChannelManager::getNotificationScreenChannel();
-	if (channel != NULL)
-	{
-		channel->closeHiddenToasts(IMToastMatcher());
-	}
-}
-// static
-void LLIMFloater::confirmLeaveCallCallback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	const LLSD& payload = notification["payload"];
-	LLUUID session_id = payload["session_id"];
-
-	LLFloater* im_floater = LLFloaterReg::findInstance("impanel", session_id);
-	if (option == 0 && im_floater != NULL)
-	{
-		im_floater->closeFloater();
-	}
-
-	return;
-}
-
-// static
-bool LLIMFloater::isChatMultiTab()
-{
-	// Restart is required in order to change chat window type.
-	static bool is_single_window = gSavedSettings.getS32("ChatWindow") == 1;
-	return is_single_window;
-}
-
-// static
-void LLIMFloater::initIMFloater()
-{
-	// This is called on viewer start up
-	// init chat window type before user changed it in preferences
-	isChatMultiTab();
-}
-
-//static
-void LLIMFloater::sRemoveTypingIndicator(const LLSD& data)
-{
-	LLUUID session_id = data["session_id"];
-	if (session_id.isNull()) return;
-
-	LLUUID from_id = data["from_id"];
-	if (gAgentID == from_id || LLUUID::null == from_id) return;
-
-	LLIMFloater* floater = LLIMFloater::findInstance(session_id);
-	if (!floater) return;
-
-	if (IM_NOTHING_SPECIAL != floater->mDialog) return;
-
-	floater->removeTypingIndicator();
-}
-
-void LLIMFloater::onIMChicletCreated( const LLUUID& session_id )
-{
-
-	if (isChatMultiTab())
-	{
-		LLIMFloaterContainer* im_box = LLIMFloaterContainer::getInstance();
-		if (!im_box) return;
-
-		if (LLIMFloater::findInstance(session_id)) return;
-
-		LLIMFloater* new_tab = LLIMFloater::getInstance(session_id);
-
-		im_box->addFloater(new_tab, FALSE, LLTabContainer::END);
-	}
-
-}
-
-void	LLIMFloater::onClickCloseBtn()
-{
-
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				mSessionID);
-
-	if (session == NULL)
-	{
-		llwarns << "Empty session." << llendl;
-		return;
-	}
-
-	bool is_call_with_chat = session->isGroupSessionType()
-			|| session->isAdHocSessionType() || session->isP2PSessionType();
-
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionID);
-
-	if (is_call_with_chat && voice_channel != NULL && voice_channel->isActive())
-	{
-		LLSD payload;
-		payload["session_id"] = mSessionID;
-		LLNotificationsUtil::add("ConfirmLeaveCall", LLSD(), payload, confirmLeaveCallCallback);
-		return;
-	}
-
-	LLFloater::onClickCloseBtn();
-}
diff --git a/indra/newview/llimfloatercontainer.cpp b/indra/newview/llimfloatercontainer.cpp
deleted file mode 100644
index 0f0ae896a24c6f3c0743b8e93d34ce6f3dfaccdb..0000000000000000000000000000000000000000
--- a/indra/newview/llimfloatercontainer.cpp
+++ /dev/null
@@ -1,165 +0,0 @@
-/** 
- * @file llimfloatercontainer.cpp
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llimfloatercontainer.h"
-#include "llfloaterreg.h"
-#include "llimview.h"
-#include "llavatariconctrl.h"
-#include "llgroupiconctrl.h"
-#include "llagent.h"
-#include "lltransientfloatermgr.h"
-
-//
-// LLIMFloaterContainer
-//
-LLIMFloaterContainer::LLIMFloaterContainer(const LLSD& seed)
-:	LLMultiFloater(seed)
-{
-	mAutoResize = FALSE;
-	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::IM, this);
-}
-
-LLIMFloaterContainer::~LLIMFloaterContainer()
-{
-	mNewMessageConnection.disconnect();
-	LLTransientFloaterMgr::getInstance()->removeControlView(LLTransientFloaterMgr::IM, this);
-}
-
-BOOL LLIMFloaterContainer::postBuild()
-{
-	mNewMessageConnection = LLIMModel::instance().mNewMsgSignal.connect(boost::bind(&LLIMFloaterContainer::onNewMessageReceived, this, _1));
-	// Do not call base postBuild to not connect to mCloseSignal to not close all floaters via Close button
-	// mTabContainer will be initialized in LLMultiFloater::addChild()
-	return TRUE;
-}
-
-void LLIMFloaterContainer::onOpen(const LLSD& key)
-{
-	LLMultiFloater::onOpen(key);
-/*
-	if (key.isDefined())
-	{
-		LLIMFloater* im_floater = LLIMFloater::findInstance(key.asUUID());
-		if (im_floater)
-		{
-			im_floater->openFloater();
-		}
-	}
-*/
-}
-
-void LLIMFloaterContainer::addFloater(LLFloater* floaterp, 
-									BOOL select_added_floater, 
-									LLTabContainer::eInsertionPoint insertion_point)
-{
-	if(!floaterp) return;
-
-	// already here
-	if (floaterp->getHost() == this)
-	{
-		openFloater(floaterp->getKey());
-		return;
-	}
-
-	LLMultiFloater::addFloater(floaterp, select_added_floater, insertion_point);
-
-	LLUUID session_id = floaterp->getKey();
-
-	LLIconCtrl* icon = 0;
-
-	if(gAgent.isInGroup(session_id, TRUE))
-	{
-		LLGroupIconCtrl::Params icon_params;
-		icon_params.group_id = session_id;
-		icon = LLUICtrlFactory::instance().create<LLGroupIconCtrl>(icon_params);
-
-		mSessions[session_id] = floaterp;
-		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
-	}
-	else
-	{
-		LLUUID avatar_id = LLIMModel::getInstance()->getOtherParticipantID(session_id);
-
-		LLAvatarIconCtrl::Params icon_params;
-		icon_params.avatar_id = avatar_id;
-		icon = LLUICtrlFactory::instance().create<LLAvatarIconCtrl>(icon_params);
-
-		mSessions[session_id] = floaterp;
-		floaterp->mCloseSignal.connect(boost::bind(&LLIMFloaterContainer::onCloseFloater, this, session_id));
-	}
-	mTabContainer->setTabImage(floaterp, icon);
-}
-
-void LLIMFloaterContainer::onCloseFloater(LLUUID& id)
-{
-	mSessions.erase(id);
-	setFocus(TRUE);
-}
-
-void LLIMFloaterContainer::onNewMessageReceived(const LLSD& data)
-{
-	LLUUID session_id = data["session_id"].asUUID();
-	LLFloater* floaterp = get_ptr_in_map(mSessions, session_id);
-	LLFloater* current_floater = LLMultiFloater::getActiveFloater();
-
-	if(floaterp && current_floater && floaterp != current_floater)
-	{
-		if(LLMultiFloater::isFloaterFlashing(floaterp))
-			LLMultiFloater::setFloaterFlashing(floaterp, FALSE);
-		LLMultiFloater::setFloaterFlashing(floaterp, TRUE);
-	}
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::findInstance()
-{
-	return LLFloaterReg::findTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-LLIMFloaterContainer* LLIMFloaterContainer::getInstance()
-{
-	return LLFloaterReg::getTypedInstance<LLIMFloaterContainer>("im_container");
-}
-
-void LLIMFloaterContainer::setMinimized(BOOL b)
-{
-	if (isMinimized() == b) return;
-	
-	LLMultiFloater::setMinimized(b);
-	// Hide minimized floater (see EXT-5315)
-	setVisible(!b);
-
-	if (isMinimized()) return;
-
-	if (getActiveFloater())
-	{
-		getActiveFloater()->setVisible(TRUE);
-	}
-}
-
-// EOF
diff --git a/indra/newview/llimfloatercontainer.h b/indra/newview/llimfloatercontainer.h
deleted file mode 100644
index 892ecef48d13ad5c07e64789b02a459612ebc7f5..0000000000000000000000000000000000000000
--- a/indra/newview/llimfloatercontainer.h
+++ /dev/null
@@ -1,70 +0,0 @@
-/** 
- * @file llimfloatercontainer.h
- * @brief Multifloater containing active IM sessions in separate tab container tabs
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLIMFLOATERCONTAINER_H
-#define LL_LLIMFLOATERCONTAINER_H
-
-#include <map>
-#include <vector>
-
-#include "llfloater.h"
-#include "llmultifloater.h"
-#include "llavatarpropertiesprocessor.h"
-#include "llgroupmgr.h"
-
-class LLTabContainer;
-
-class LLIMFloaterContainer : public LLMultiFloater
-{
-public:
-	LLIMFloaterContainer(const LLSD& seed);
-	virtual ~LLIMFloaterContainer();
-	
-	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
-	void onCloseFloater(LLUUID& id);
-
-	/*virtual*/ void addFloater(LLFloater* floaterp, 
-								BOOL select_added_floater, 
-								LLTabContainer::eInsertionPoint insertion_point = LLTabContainer::END);
-
-	static LLFloater* getCurrentVoiceFloater();
-
-	static LLIMFloaterContainer* findInstance();
-
-	static LLIMFloaterContainer* getInstance();
-
-	virtual void setMinimized(BOOL b);
-
-private:
-	typedef std::map<LLUUID,LLFloater*> avatarID_panel_map_t;
-	avatarID_panel_map_t mSessions;
-	boost::signals2::connection mNewMessageConnection;
-
-	void onNewMessageReceived(const LLSD& data);
-};
-
-#endif // LL_LLIMFLOATERCONTAINER_H
diff --git a/indra/newview/llimhandler.cpp b/indra/newview/llimhandler.cpp
index 07d73c8c66f3f943f6a51b9d4aba99ae48d686a1..c2b29f36e8ab463731384da680ce6893bc0443b7 100644
--- a/indra/newview/llimhandler.cpp
+++ b/indra/newview/llimhandler.cpp
@@ -36,11 +36,12 @@
 
 using namespace LLNotificationsUI;
 
+extern void process_dnd_im(const LLSD& notification);
+
 //--------------------------------------------------------------------------
-LLIMHandler::LLIMHandler(e_notification_type type, const LLSD& id)
+LLIMHandler::LLIMHandler()
+:	LLCommunicationNotificationHandler("IM Notifications", "notifytoast")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	mChannel = LLChannelManager::getInstance()->createNotificationChannel()->getHandle();
 }
@@ -59,72 +60,57 @@ void LLIMHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLIMHandler::processNotification(const LLSD& notify)
+bool LLIMHandler::processNotification(const LLNotificationPtr& notification)
 {
-	if(mChannel.isDead())
-	{
-		return false;
-	}
-
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
-	// arrange a channel on a screen
-	if(!mChannel.get()->getVisible())
-	{
-		initChannel();
-	}
-
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
-		LLSD substitutions = notification->getSubstitutions();
-
-		// According to comments in LLIMMgr::addMessage(), if we get message
-		// from ourselves, the sender id is set to null. This fixes EXT-875.
-		LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
-		if (avatar_id.isNull())
-			avatar_id = gAgentID;
-
-		LLToastIMPanel::Params im_p;
-		im_p.notification = notification;
-		im_p.avatar_id = avatar_id;
-		im_p.from = substitutions["FROM"].asString();
-		im_p.time = substitutions["TIME"].asString();
-		im_p.message = substitutions["MESSAGE"].asString();
-		im_p.session_id = substitutions["SESSION_ID"].asUUID();
-
-		LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
-
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.session_id = im_p.session_id;
-		p.notification = notification;
-		p.panel = im_box;
-		p.can_be_stored = false;
-		p.on_delete_toast = boost::bind(&LLIMHandler::onDeleteToast, this, _1);
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
-
-		// send a signal to the counter manager;
-		mNewNotificationSignal();
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		mChannel.get()->killToastByNotificationID(notification->getID());
-	}
-	return false;
-}
+    if(notification->isDND())
+    {
+        LLSD data = notification->asLLSD(); //don't need this if retrieve needed data from notification getters
+        process_dnd_im(data);
+    }
+    else
+    {
+	    if(mChannel.isDead())
+	    {
+		    return false;
+	    }
+
+	    // arrange a channel on a screen
+	    if(!mChannel.get()->getVisible())
+	    {
+		    initChannel();
+	    }
+
+	    LLSD substitutions = notification->getSubstitutions();
+
+	    // According to comments in LLIMMgr::addMessage(), if we get message
+	    // from ourselves, the sender id is set to null. This fixes EXT-875.
+	    LLUUID avatar_id = substitutions["FROM_ID"].asUUID();
+	    if (avatar_id.isNull())
+		    avatar_id = gAgentID;
+
+	    LLToastIMPanel::Params im_p;
+	    im_p.notification = notification;
+	    im_p.avatar_id = avatar_id;
+	    im_p.from = substitutions["FROM"].asString();
+	    im_p.time = substitutions["TIME"].asString();
+	    im_p.message = substitutions["MESSAGE"].asString();
+	    im_p.session_id = substitutions["SESSION_ID"].asUUID();
+
+	    LLToastIMPanel* im_box = new LLToastIMPanel(im_p);
+
+	    LLToast::Params p;
+	    p.notif_id = notification->getID();
+	    p.session_id = im_p.session_id;
+	    p.notification = notification;
+	    p.panel = im_box;
+	    p.can_be_stored = false;
+	    LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	    if(channel)
+		    channel->addToast(p);
+    }
 
-//--------------------------------------------------------------------------
-void LLIMHandler::onDeleteToast(LLToast* toast)
-{
-	// send a signal to the counter manager
-	mDelNotificationSignal();
+	return false;
 }
 
-//--------------------------------------------------------------------------
 
 
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 0250af6a0efce2c8231f778d4e201b0beacc160b..59272d721fb6509b19f2a6210b288194357c8026 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -171,7 +171,7 @@ LLFloaterIMPanel::LLFloaterIMPanel(const std::string& session_label,
 	// enable line history support for instant message bar
 	mInputEditor->setEnableLineHistory(TRUE);
 
-	//*TODO we probably need the same "awaiting message" thing in LLIMFloater
+	//*TODO we probably need the same "awaiting message" thing in LLFloaterIMSession
 	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(mSessionUUID);
 	if (!im_session)
 	{
@@ -394,9 +394,10 @@ class LLSessionInviteResponder : public LLHTTPClient::Responder
 		mSessionID = session_id;
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
-		llinfos << "Error inviting all agents to session" << llendl;
+		llwarns << "Error inviting all agents to session [status:" 
+				<< statusNum << "]: " << content << llendl;
 		//throw something back to the viewer here?
 	}
 
diff --git a/indra/newview/llimview.cpp b/indra/newview/llimview.cpp
index 400057087218ac551d37fe023214bfbefc5e9369..2c20409381d3331018c0b099d9a45ee7c62eb435 100644
--- a/indra/newview/llimview.cpp
+++ b/indra/newview/llimview.cpp
@@ -29,6 +29,8 @@
 #include "llimview.h"
 
 #include "llavatarnamecache.h"	// IDEVO
+#include "llavataractions.h"
+#include "llfloaterconversationlog.h"
 #include "llfloaterreg.h"
 #include "llfontgl.h"
 #include "llgl.h"
@@ -41,14 +43,15 @@
 #include "lltextutil.h"
 #include "lltrans.h"
 #include "lluictrlfactory.h"
-
+#include "llfloaterimsessiontab.h"
 #include "llagent.h"
 #include "llagentui.h"
 #include "llappviewer.h"
 #include "llavatariconctrl.h"
 #include "llcallingcard.h"
 #include "llchat.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
+#include "llfloaterimcontainer.h"
 #include "llgroupiconctrl.h"
 #include "llmd5.h"
 #include "llmutelist.h"
@@ -57,12 +60,14 @@
 #include "llviewerwindow.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llspeakers.h" //for LLIMSpeakerMgr
 #include "lltextbox.h"
 #include "lltoolbarview.h"
 #include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
+#include "llconversationlog.h"
+#include "message.h"
 
 
 const static std::string ADHOC_NAME_SUFFIX(" Conference");
@@ -97,6 +102,47 @@ BOOL LLSessionTimeoutTimer::tick()
 	return TRUE;
 }
 
+
+
+void process_dnd_im(const LLSD& notification)
+{
+    LLSD data = notification["substitutions"];
+    LLUUID sessionID = data["SESSION_ID"].asUUID();
+	LLUUID fromID = data["FROM_ID"].asUUID();
+
+    //re-create the IM session if needed 
+    //(when coming out of DND mode upon app restart)
+    if(!gIMMgr->hasSession(sessionID))
+    {
+        //reconstruct session using data from the notification
+        std::string name = data["FROM"];
+        LLAvatarName av_name;
+        if (LLAvatarNameCache::get(data["FROM_ID"], &av_name))
+        {
+            name = av_name.getDisplayName();
+        }
+		
+        
+        LLIMModel::getInstance()->newSession(sessionID, 
+            name, 
+            IM_NOTHING_SPECIAL, 
+            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);
+		}
+
+    }
+}
+
+
+
+
 static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   LLSD msg)
@@ -108,77 +154,177 @@ static void on_avatar_name_cache_toast(const LLUUID& agent_id,
 	args["FROM"] = av_name.getCompleteName();
 	args["FROM_ID"] = msg["from_id"];
 	args["SESSION_ID"] = msg["session_id"];
-	LLNotificationsUtil::add("IMToast", args, LLSD(), boost::bind(&LLIMFloater::show, msg["session_id"].asUUID()));
+	args["SESSION_TYPE"] = msg["session_type"];
+	LLNotificationsUtil::add("IMToast", args, args, boost::bind(&LLFloaterIMContainer::showConversation, LLFloaterIMContainer::getInstance(), msg["session_id"].asUUID()));
 }
 
-void toast_callback(const LLSD& msg){
-	// do not show toast in busy mode or it goes from agent
-	if (gAgent.getBusy() || gAgent.getID() == msg["from_id"])
-	{
-		return;
-	}
+void on_new_message(const LLSD& 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);
 
-	// check whether incoming IM belongs to an active session or not
-	if (LLIMModel::getInstance()->getActiveSessionID().notNull()
-			&& LLIMModel::getInstance()->getActiveSessionID() == msg["session_id"])
-	{
-		return;
-	}
+    // 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;
 
-	// Skip toasting for system messages
-	if (msg["from_id"].asUUID() == LLUUID::null)
-	{
-		return;
-	}
 
-	// *NOTE Skip toasting if the user disable it in preferences/debug settings ~Alexandrea
-	LLIMModel::LLIMSession* session = LLIMModel::instance().findIMSession(
-				msg["session_id"]);
-	if (!gSavedSettings.getBOOL("EnableGroupChatPopups")
-			&& session->isGroupSessionType())
+
+    LLFloaterIMContainer* im_box = LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container");
+	LLFloaterIMSessionTab* session_floater = LLFloaterIMSessionTab::getConversation(session_id);
+
+	if (!LLFloater::isVisible(im_box) || im_box->isMinimized())
 	{
-		return;
+		conversations_floater_status = CLOSED;
 	}
-	if (!gSavedSettings.getBOOL("EnableIMChatPopups")
-			&& !session->isGroupSessionType())
+	else if (!im_box->hasFocus() &&
+			    !(session_floater && LLFloater::isVisible(session_floater)
+	            && !session_floater->isMinimized() && session_floater->hasFocus()))
 	{
-		return;
+		conversations_floater_status = NOT_ON_TOP;
 	}
-
-	// Skip toasting if we have open window of IM with this session id
-	LLIMFloater* open_im_floater = LLIMFloater::findInstance(msg["session_id"]);
-	if (open_im_floater && open_im_floater->getVisible())
+	else if (im_box->getSelectedSession() != session_id)
 	{
-		return;
-	}
-
-	LLAvatarNameCache::get(msg["from_id"].asUUID(),
-		boost::bind(&on_avatar_name_cache_toast,
-			_1, _2, msg));
-}
-
-void LLIMModel::setActiveSessionID(const LLUUID& session_id)
-{
-	// check if such an ID really exists
-	if (!findIMSession(session_id))
+		conversations_floater_status = ON_TOP;
+    }
+	else
 	{
-		llwarns << "Trying to set as active a non-existent session!" << llendl;
-		return;
-	}
-
-	mActiveSessionID = session_id;
+		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");
+    }
+
+    // actions:
+
+    // 0. nothing - exit
+    if (("none" == user_preferences ||
+    		ON_TOP_AND_ITEM_IS_SELECTED == conversations_floater_status)
+    	    && session_floater->isMessagePaneExpanded())
+    {
+    	return;
+    }
+
+    // 1. open floater and [optional] surface it
+    if ("openconversations" == user_preferences &&
+    		(CLOSED == conversations_floater_status
+    				|| NOT_ON_TOP == conversations_floater_status))
+    {
+    	if(!gAgent.isDoNotDisturb())
+        {
+			// Open conversations floater
+			LLFloaterReg::showInstance("im_container");
+			im_box->collapseMessagesPane(false);
+			if (session_floater)
+			{
+				if (session_floater->getHost())
+				{
+					if (NULL != im_box && im_box->isMinimized())
+					{
+						LLFloater::onClickMinimize(im_box);
+					}
+				}
+				else
+				{
+					if (session_floater->isMinimized())
+					{
+						LLFloater::onClickMinimize(session_floater);
+					}
+				}
+			}
+		}
+        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));
+	        }
+        }
+    }
+
+    // 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);
+    	}
+    }
+
+    // 4. Toast
+    if ((("toast" == user_preferences) &&
+    		(CLOSED == conversations_floater_status
+    		    || NOT_ON_TOP == conversations_floater_status))
+    		    || !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())
+        {
+            LLAvatarNameCache::get(participant_id, boost::bind(&on_avatar_name_cache_toast, _1, _2, msg));
+        }
+    }
 }
 
 LLIMModel::LLIMModel() 
 {
-	addNewMsgCallback(boost::bind(&LLIMFloater::newIMCallback, _1));
-	addNewMsgCallback(boost::bind(&toast_callback, _1));
+	addNewMsgCallback(boost::bind(&LLFloaterIMSession::newIMCallback, _1));
+	addNewMsgCallback(boost::bind(&on_new_message, _1));
 }
 
-LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
 :	mSessionID(session_id),
 	mName(name),
 	mType(type),
+	mHasOfflineMessage(has_offline_msg),
 	mParticipantUnreadMessageCount(0),
 	mNumUnread(0),
 	mOtherParticipantID(other_participant_id),
@@ -190,7 +336,8 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	mTextIMPossible(true),
 	mOtherParticipantIsAvatar(true),
 	mStartCallOnInitialize(false),
-	mStartedAsIMCall(voice)
+	mStartedAsIMCall(voice),
+	mAvatarNameCacheConnection()
 {
 	// set P2P type by default
 	mSessionType = P2P_SESSION;
@@ -256,30 +403,22 @@ LLIMModel::LLIMSession::LLIMSession(const LLUUID& session_id, const std::string&
 	}
 
 	buildHistoryFileName();
-
-	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
-	{
-		std::list<LLSD> chat_history;
-
-		//involves parsing of a chat history
-		LLLogChat::loadAllHistory(mHistoryFileName, chat_history);
-		addMessagesFromHistory(chat_history);
-	}
+	loadHistory();
 
 	// Localizing name of ad-hoc session. STORM-153
 	// Changing name should happen here- after the history file was created, so that
 	// history files have consistent (English) names in different locales.
 	if (isAdHocSessionType() && IM_SESSION_INVITE == mType)
 	{
-		LLAvatarNameCache::get(mOtherParticipantID,
-							   boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,
-							   this, _2));
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(mOtherParticipantID,boost::bind(&LLIMModel::LLIMSession::onAdHocNameCache,this, _2));
 	}
 }
 
 void LLIMModel::LLIMSession::onAdHocNameCache(const LLAvatarName& av_name)
 {
-	if (av_name.mIsTemporaryName)
+	mAvatarNameCacheConnection.disconnect();
+
+	if (!av_name.isValidName())
 	{
 		S32 separator_index = mName.rfind(" ");
 		std::string name = mName.substr(0, separator_index);
@@ -375,6 +514,8 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 				break;
 			}
 		}
+	default:
+		break;
 	}
 	// Update speakers list when connected
 	if (LLVoiceChannel::STATE_CONNECTED == new_state)
@@ -385,6 +526,11 @@ void LLIMModel::LLIMSession::onVoiceChannelStateChanged(const LLVoiceChannel::ES
 
 LLIMModel::LLIMSession::~LLIMSession()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+
 	delete mSpeakers;
 	mSpeakers = NULL;
 
@@ -450,11 +596,11 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
 	{
 		const LLSD& msg = *it;
 
-		std::string from = msg[IM_FROM];
+		std::string from = msg[LL_IM_FROM];
 		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
+		if (msg[LL_IM_FROM_ID].isDefined())
 		{
-			from_id = msg[IM_FROM_ID].asUUID();
+			from_id = msg[LL_IM_FROM_ID].asUUID();
 		}
 		else
 		{
@@ -463,8 +609,8 @@ void LLIMModel::LLIMSession::addMessagesFromHistory(const std::list<LLSD>& histo
  			gCacheName->getUUID(legacy_name, from_id);
 		}
 
-		std::string timestamp = msg[IM_TIME];
-		std::string text = msg[IM_TEXT];
+		std::string timestamp = msg[LL_IM_TIME];
+		std::string text = msg[LL_IM_TEXT];
 
 		addMessage(from, from_id, text, timestamp, true);
 
@@ -488,10 +634,23 @@ void LLIMModel::LLIMSession::chatFromLogFile(LLLogChat::ELogLineType type, const
 	}
 }
 
+void LLIMModel::LLIMSession::loadHistory()
+{
+	mMsgs.clear();
+
+	if ( gSavedPerAccountSettings.getBOOL("LogShowHistory") )
+	{
+		std::list<LLSD> chat_history;
+
+		//involves parsing of a chat history
+		LLLogChat::loadChatHistory(mHistoryFileName, chat_history);
+		addMessagesFromHistory(chat_history);
+	}
+}
+
 LLIMModel::LLIMSession* LLIMModel::findIMSession(const LLUUID& session_id) const
 {
-	return get_if_there(mId2SessionMap, session_id,
-		(LLIMModel::LLIMSession*) NULL);
+	return get_if_there(mId2SessionMap, session_id, (LLIMModel::LLIMSession*) NULL);
 }
 
 //*TODO consider switching to using std::set instead of std::list for holding LLUUIDs across the whole code
@@ -533,7 +692,7 @@ LLIMModel::LLIMSession* LLIMModel::findAdHocIMSession(const uuid_vec_t& ids)
 	return NULL;
 }
 
-bool LLIMModel::LLIMSession::isOutgoingAdHoc()
+bool LLIMModel::LLIMSession::isOutgoingAdHoc() const
 {
 	return IM_SESSION_CONFERENCE_START == mType;
 }
@@ -553,6 +712,19 @@ bool LLIMModel::LLIMSession::isOtherParticipantAvaline()
 	return !mOtherParticipantIsAvatar;
 }
 
+LLUUID LLIMModel::LLIMSession::generateOutgouigAdHocHash() const
+{
+	LLUUID hash = LLUUID::null;
+
+	if (mInitialTargetIDs.size())
+	{
+		std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
+		hash = generateHash(sorted_uuids);
+	}
+
+	return hash;
+}
+
 void LLIMModel::LLIMSession::buildHistoryFileName()
 {
 	mHistoryFileName = mName;
@@ -569,7 +741,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 		if (mInitialTargetIDs.size())
 		{
 			std::set<LLUUID> sorted_uuids(mInitialTargetIDs.begin(), mInitialTargetIDs.end());
-			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids);
+			mHistoryFileName = mName + " hash" + generateHash(sorted_uuids).asString();
 		}
 		else
 		{
@@ -584,15 +756,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 		// so no need for a callback in LLAvatarNameCache::get()
 		if (LLAvatarNameCache::get(mOtherParticipantID, &av_name))
 		{
-			if (av_name.mUsername.empty())
-			{
-				// Display names are off, use mDisplayName which will be the legacy name
-				mHistoryFileName = LLCacheName::buildUsername(av_name.mDisplayName);
-			}
-			else
-			{
-				mHistoryFileName =  av_name.mUsername;
-			}
+			mHistoryFileName = LLCacheName::buildUsername(av_name.getUserName());
 		}
 		else
 		{
@@ -603,7 +767,7 @@ void LLIMModel::LLIMSession::buildHistoryFileName()
 }
 
 //static
-std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
+LLUUID LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_uuids)
 {
 	LLMD5 md5_uuid;
 	
@@ -617,7 +781,7 @@ std::string LLIMModel::LLIMSession::generateHash(const std::set<LLUUID>& sorted_
 
 	LLUUID participants_md5_hash;
 	md5_uuid.raw_digest((unsigned char*) participants_md5_hash.mData);
-	return participants_md5_hash.asString();
+	return participants_md5_hash;
 }
 
 void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, const LLUUID& new_session_id)
@@ -631,16 +795,19 @@ void LLIMModel::processSessionInitializedReply(const LLUUID& old_session_id, con
 		{
 			mId2SessionMap.erase(old_session_id);
 			mId2SessionMap[new_session_id] = session;
-
-			gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
 		}
 
-		LLIMFloater* im_floater = LLIMFloater::findInstance(old_session_id);
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(old_session_id);
 		if (im_floater)
 		{
 			im_floater->sessionInitReplyReceived(new_session_id);
 		}
 
+		if (old_session_id != new_session_id)
+		{
+			gIMMgr->notifyObserverSessionIDUpdated(old_session_id, new_session_id);
+		}
+
 		// auto-start the call on session initialization?
 		if (session->mStartCallOnInitialize)
 		{
@@ -676,7 +843,7 @@ void LLIMModel::testMessages()
 
 //session name should not be empty
 bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, 
-						   const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice)
+						   const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg)
 {
 	if (name.empty())
 	{
@@ -690,22 +857,23 @@ bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, co
 		return false;
 	}
 
-	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice);
+	LLIMSession* session = new LLIMSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
 	mId2SessionMap[session_id] = session;
 
 	// When notifying observer, name of session is used instead of "name", because they may not be the
 	// same if it is an adhoc session (in this case name is localized in LLIMSession constructor).
 	std::string session_name = LLIMModel::getInstance()->getName(session_id);
-	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id);
+	LLIMMgr::getInstance()->notifyObserverSessionAdded(session_id, session_name, other_participant_id,has_offline_msg);
 
 	return true;
 
 }
 
-bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice)
+bool LLIMModel::newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, bool voice, bool has_offline_msg)
 {
-	uuid_vec_t no_ids;
-	return newSession(session_id, name, type, other_participant_id, no_ids, voice);
+	uuid_vec_t ids;
+	ids.push_back(other_participant_id);
+	return newSession(session_id, name, type, other_participant_id, ids, voice, has_offline_msg);
 }
 
 bool LLIMModel::clearSession(const LLUUID& session_id)
@@ -716,6 +884,16 @@ bool LLIMModel::clearSession(const LLUUID& session_id)
 	return true;
 }
 
+void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index, const bool sendNoUnreadMsgs)
+{
+	getMessagesSilently(session_id, messages, start_index);
+
+	if (sendNoUnreadMsgs)
+	{
+		sendNoUnreadMessages(session_id);
+	}
+}
+
 void LLIMModel::getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
 {
 	LLIMSession* session = findIMSession(session_id);
@@ -757,13 +935,6 @@ void LLIMModel::sendNoUnreadMessages(const LLUUID& session_id)
 	mNoUnreadMsgsSignal(arg);
 }
 
-void LLIMModel::getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index)
-{
-	getMessagesSilently(session_id, messages, start_index);
-
-	sendNoUnreadMessages(session_id);
-}
-
 bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from, const LLUUID& from_id, const std::string& utf8_text) {
 	
 	LLIMSession* session = findIMSession(session_id);
@@ -781,19 +952,20 @@ bool LLIMModel::addToHistory(const LLUUID& session_id, const std::string& from,
 
 bool LLIMModel::logToFile(const std::string& file_name, const std::string& from, const LLUUID& from_id, const std::string& utf8_text)
 {
-	if (gSavedPerAccountSettings.getBOOL("LogInstantMessages"))
+	if (gSavedPerAccountSettings.getS32("KeepConversationLogTranscripts") > 1)
 	{	
 		std::string from_name = from;
 
 		LLAvatarName av_name;
 		if (!from_id.isNull() && 
 			LLAvatarNameCache::get(from_id, &av_name) &&
-			!av_name.mIsDisplayNameDefault)
+			!av_name.isDisplayNameDefault())
 		{	
 			from_name = av_name.getCompleteName();
 		}
 
 		LLLogChat::saveHistory(file_name, from_name, from_id, utf8_text);
+		LLConversationLog::instance().cache(); // update the conversation log too
 		return true;
 	}
 	else
@@ -831,6 +1003,7 @@ bool LLIMModel::addMessage(const LLUUID& session_id, const std::string& from, co
 	arg["from"] = from;
 	arg["from_id"] = from_id;
 	arg["time"] = LLLogChat::timestamp(false);
+	arg["session_type"] = session->mSessionType;
 	mNewMsgSignal(arg);
 
 	return true;
@@ -878,7 +1051,7 @@ const std::string LLIMModel::getName(const LLUUID& session_id) const
 {
 	LLIMSession* session = findIMSession(session_id);
 
-	if (!session) 
+	if (!session)
 	{
 		llwarns << "session " << session_id << "does not exist " << llendl;
 		return LLTrans::getString("no_session_message");
@@ -904,7 +1077,7 @@ const LLUUID& LLIMModel::getOtherParticipantID(const LLUUID& session_id) const
 	LLIMSession* session = findIMSession(session_id);
 	if (!session)
 	{
-		llwarns << "session " << session_id << "does not exist " << llendl;
+		llwarns << "session " << session_id << " does not exist " << llendl;
 		return LLUUID::null;
 	}
 
@@ -1227,7 +1400,7 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 		mAgents = agents_to_invite;
 	}
 
-	virtual void error(U32 statusNum, const std::string& reason)
+	virtual void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		//try an "old school" way.
 		if ( statusNum == 400 )
@@ -1239,6 +1412,9 @@ class LLStartConferenceChatResponder : public LLHTTPClient::Responder
 				mAgents);
 		}
 
+		llwarns << "LLStartConferenceChatResponder error [status:"
+				<< statusNum << "]: " << content << llendl;
+
 		//else throw an error back to the client?
 		//in theory we should have just have these error strings
 		//etc. set up in this file as opposed to the IMMgr,
@@ -1376,7 +1552,7 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 				&& LLIMModel::getInstance()->findIMSession(mSessionID))
 			{
 				// TODO remove in 2010, for voice calls we do not open an IM window
-				//LLIMFloater::show(mSessionID);
+				//LLFloaterIMSession::show(mSessionID);
 			}
 
 			gIMMgr->clearPendingAgentListUpdates(mSessionID);
@@ -1384,8 +1560,10 @@ class LLViewerChatterBoxInvitationAcceptResponder :
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
-	{		
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "LLViewerChatterBoxInvitationAcceptResponder error [status:"
+				<< statusNum << "]: " << content << llendl;
 		//throw something back to the viewer here?
 		if ( gIMMgr )
 		{
@@ -1444,6 +1622,11 @@ LLUUID LLIMMgr::computeSessionID(
 			session_id = other_participant_id ^ agent_id;
 		}
 	}
+
+	if (gAgent.isInGroup(session_id) && (session_id != other_participant_id))
+	{
+		llwarns << "Group session id different from group id: IM type = " << dialog << ", session id = " << session_id << ", group id = " << other_participant_id << llendl;
+	}
 	return session_id;
 }
 
@@ -1520,7 +1703,7 @@ LLIMMgr::onConfirmForceCloseError(
 	//only 1 option really
 	LLUUID session_id = notification["payload"]["session_id"];
 
-	LLFloater* floater = LLIMFloater::findInstance(session_id);
+	LLFloater* floater = LLFloaterIMSession::findInstance(session_id);
 	if ( floater )
 	{
 		floater->closeFloater(FALSE);
@@ -1878,7 +2061,7 @@ void LLOutgoingCallDialog::show(const LLSD& key)
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(callee_id, &av_name))
 		{
-			final_callee_name = av_name.mDisplayName;
+			final_callee_name = av_name.getDisplayName();
 			title = av_name.getCompleteName();
 		}
 	}
@@ -1980,7 +2163,8 @@ BOOL LLOutgoingCallDialog::postBuild()
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 LLIncomingCallDialog::LLIncomingCallDialog(const LLSD& payload) :
-LLCallDialog(payload)
+LLCallDialog(payload),
+mAvatarNameCacheConnection()
 {
 }
 
@@ -2050,9 +2234,11 @@ BOOL LLIncomingCallDialog::postBuild()
 	else
 	{
 		// Get the full name information
-		LLAvatarNameCache::get(caller_id,
-			boost::bind(&LLIncomingCallDialog::onAvatarNameCache,
-				this, _1, _2, call_type));
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+		mAvatarNameCacheConnection = LLAvatarNameCache::get(caller_id, boost::bind(&LLIncomingCallDialog::onAvatarNameCache, this, _1, _2, call_type));
 	}
 
 	setIcon(session_id, caller_id);
@@ -2078,7 +2264,6 @@ BOOL LLIncomingCallDialog::postBuild()
 	getChildView("Start IM")->setVisible( is_avatar && notify_box_type != "VoiceInviteAdHoc" && notify_box_type != "VoiceInviteGroup");
 
 	setCanDrag(FALSE);
-
 	return TRUE;
 }
 
@@ -2086,7 +2271,6 @@ void LLIncomingCallDialog::setCallerName(const std::string& ui_title,
 										 const std::string& ui_label,
 										 const std::string& call_type)
 {
-	setTitle(ui_title);
 
 	// call_type may be a string like " is calling."
 	LLUICtrl* caller_name_widget = getChild<LLUICtrl>("caller name");
@@ -2097,14 +2281,15 @@ void LLIncomingCallDialog::onAvatarNameCache(const LLUUID& agent_id,
 											 const LLAvatarName& av_name,
 											 const std::string& call_type)
 {
+	mAvatarNameCacheConnection.disconnect();
 	std::string title = av_name.getCompleteName();
-	setCallerName(title, av_name.mDisplayName, call_type);
+	setCallerName(title, av_name.getCompleteName(), call_type);
 }
 
 void LLIncomingCallDialog::onOpen(const LLSD& key)
 {
 	LLCallDialog::onOpen(key);
-
+	make_ui_sound("UISndStartIM");
 	LLStringUtil::format_map_t args;
 	LLGroupData data;
 	// if it's a group call, retrieve group name to use it in question
@@ -2112,18 +2297,6 @@ void LLIncomingCallDialog::onOpen(const LLSD& key)
 	{
 		args["[GROUP]"] = data.mName;
 	}
-	// tell the user which voice channel they would be leaving
-	LLVoiceChannel *voice = LLVoiceChannel::getCurrentVoiceChannel();
-	if (voice && !voice->getSessionName().empty())
-	{
-		args["[CURRENT_CHAT]"] = voice->getSessionName();
-		getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
-	}
-	else
-	{
-		args["[CURRENT_CHAT]"] = getString("localchat");
-		getChild<LLUICtrl>("question")->setValue(getString(key["question_type"].asString(), args));
-	}
 }
 
 //static
@@ -2184,6 +2357,10 @@ void LLIncomingCallDialog::processCallResponse(S32 response, const LLSD &payload
 			{
 				gIMMgr->startCall(session_id, LLVoiceChannel::INCOMING_CALL);
 			}
+			else
+			{
+				LLAvatarActions::startIM(caller_id);
+			}
 
 			gIMMgr->clearPendingAgentListUpdates(session_id);
 			gIMMgr->clearPendingInvitation(session_id);
@@ -2386,7 +2563,7 @@ LLIMMgr::LLIMMgr()
 	mPendingInvitations = LLSD::emptyMap();
 	mPendingAgentListUpdates = LLSD::emptyMap();
 
-	LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLIMFloater::sRemoveTypingIndicator, _1));
+	LLIMModel::getInstance()->addNewMsgCallback(boost::bind(&LLFloaterIMSession::sRemoveTypingIndicator, _1));
 }
 
 // Add a message to a session. 
@@ -2395,6 +2572,7 @@ void LLIMMgr::addMessage(
 	const LLUUID& target_id,
 	const std::string& from,
 	const std::string& msg,
+	bool  is_offline_msg,
 	const std::string& session_name,
 	EInstantMessage dialog,
 	U32 parent_estate_id,
@@ -2403,6 +2581,7 @@ void LLIMMgr::addMessage(
 	bool link_name) // If this is true, then we insert the name and link it to a profile
 {
 	LLUUID other_participant_id = target_id;
+
 	LLUUID new_session_id = session_id;
 	if (new_session_id.isNull())
 	{
@@ -2412,15 +2591,22 @@ void LLIMMgr::addMessage(
 
 	//*NOTE session_name is empty in case of incoming P2P sessions
 	std::string fixed_session_name = from;
+	bool name_is_setted = false;
 	if(!session_name.empty() && session_name.size()>1)
 	{
 		fixed_session_name = session_name;
+		name_is_setted = true;
 	}
 
 	bool new_session = !hasSession(new_session_id);
 	if (new_session)
 	{
-		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id);
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(other_participant_id, &av_name) && !name_is_setted)
+		{
+			fixed_session_name = av_name.getDisplayName();
+		}
+		LLIMModel::getInstance()->newSession(new_session_id, fixed_session_name, dialog, other_participant_id, false, is_offline_msg);
 
 		// 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
@@ -2455,16 +2641,35 @@ void LLIMMgr::addMessage(
 			return;
 		}
 
-		make_ui_sound("UISndNewIncomingIMSession");
+        //Play sound for new conversations
+		if (!gAgent.isDoNotDisturb() && (gSavedSettings.getBOOL("PlaySoundNewConversation") == TRUE))
+        {
+            make_ui_sound("UISndNewIncomingIMSession");
+        }
 	}
 
-	bool skip_message = (gSavedSettings.getBOOL("VoiceCallsFriendsOnly") &&
-		LLAvatarTracker::instance().getBuddyInfo(other_participant_id) == NULL);
+	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)
+    {
+        LLFloaterReg::showInstance("im_container");
+	    LLFloaterReg::getTypedInstance<LLFloaterIMContainer>("im_container")->
+	    		flashConversationItemWidget(new_session_id, true);
+    }
 }
 
 void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& message_name, const LLSD& args)
@@ -2479,11 +2684,9 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 
 		LLChat chat(message);
 		chat.mSourceType = CHAT_SOURCE_SYSTEM;
-		
-		LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-		LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
 
-		if(nearby_chat)
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+		if (nearby_chat)
 		{
 			nearby_chat->addMessage(chat);
 		}
@@ -2497,6 +2700,7 @@ void LLIMMgr::addSystemMessage(const LLUUID& session_id, const std::string& mess
 			gIMMgr->addMessage(session_id, LLUUID::null, SYSTEM_FROM, message.getString());
 		}
 		// log message to file
+
 		else
 		{
 			std::string session_name;
@@ -2579,7 +2783,8 @@ LLUUID LLIMMgr::addSession(
 {
 	LLDynamicArray<LLUUID> ids;
 	ids.put(other_participant_id);
-	return addSession(name, dialog, other_participant_id, ids, voice);
+	LLUUID session_id = addSession(name, dialog, other_participant_id, ids, voice);
+	return session_id;
 }
 
 // Adds a session using the given session_id.  If the session already exists 
@@ -2588,7 +2793,8 @@ LLUUID LLIMMgr::addSession(
 	const std::string& name,
 	EInstantMessage dialog,
 	const LLUUID& other_participant_id,
-	const LLDynamicArray<LLUUID>& ids, bool voice)
+	const LLDynamicArray<LLUUID>& ids, bool voice,
+	const LLUUID& floater_id)
 {
 	if (0 == ids.getLength())
 	{
@@ -2603,7 +2809,21 @@ LLUUID LLIMMgr::addSession(
 
 	LLUUID session_id = computeSessionID(dialog,other_participant_id);
 
-	bool new_session = !LLIMModel::getInstance()->findIMSession(session_id);
+	if (floater_id.notNull())
+	{
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(floater_id);
+
+		if (im_floater)
+		{
+			// The IM floater should be initialized with a new session_id
+			// so that it is found by that id when creating a chiclet in LLFloaterIMSession::onIMChicletCreated,
+			// and a new floater is not created.
+			im_floater->initIMSession(session_id);
+            im_floater->reloadMessages();
+		}
+	}
+
+	bool new_session = (LLIMModel::getInstance()->findIMSession(session_id) == NULL);
 
 	//works only for outgoing ad-hoc sessions
 	if (new_session && IM_SESSION_CONFERENCE_START == dialog && ids.size())
@@ -2616,14 +2836,23 @@ LLUUID LLIMMgr::addSession(
 		}
 	}
 
+    //Notify observers that a session was added
 	if (new_session)
 	{
 		LLIMModel::getInstance()->newSession(session_id, name, dialog, other_participant_id, ids, voice);
 	}
+    //Notifies observers that the session was already added
+    else
+    {
+        std::string session_name = LLIMModel::getInstance()->getName(session_id);
+        LLIMMgr::getInstance()->notifyObserverSessionActivated(session_id, session_name, other_participant_id);
+    }
 
 	//we don't need to show notes about online/offline, mute/unmute users' statuses for existing sessions
 	if (!new_session) return session_id;
 	
+    llinfos << "LLIMMgr::addSession, new session added, name = " << name << ", session id = " << session_id << llendl;
+    
 	//Per Plan's suggestion commented "explicit offline status warning" out to make Dessie happier (see EXT-3609)
 	//*TODO After February 2010 remove this commented out line if no one will be missing that warning
 	//noteOfflineUsers(session_id, floater, ids);
@@ -2634,6 +2863,8 @@ LLUUID LLIMMgr::addSession(
 		noteMutedUsers(session_id, ids);
 	}
 
+	notifyObserverSessionVoiceOrIMStarted(session_id);
+
 	return session_id;
 }
 
@@ -2657,6 +2888,8 @@ void LLIMMgr::removeSession(const LLUUID& session_id)
 
 	LLIMModel::getInstance()->clearSession(session_id);
 
+    llinfos << "LLIMMgr::removeSession, session removed, session id = " << session_id << llendl;
+
 	notifyObserverSessionRemoved(session_id);
 }
 
@@ -2674,7 +2907,6 @@ void LLIMMgr::inviteToSession(
 	// voice invite question is different from default only for group call (EXT-7118)
 	std::string question_type = "VoiceInviteQuestionDefault";
 
-	BOOL ad_hoc_invite = FALSE;
 	BOOL voice_invite = FALSE;
 	bool is_linden = LLMuteList::getInstance()->isLinden(caller_name);
 
@@ -2697,13 +2929,11 @@ void LLIMMgr::inviteToSession(
 		//else it's an ad-hoc
 		//and a voice ad-hoc
 		notify_box_type = "VoiceInviteAdHoc";
-		ad_hoc_invite = TRUE;
 		voice_invite = TRUE;
 	}
 	else if ( inv_type == INVITATION_TYPE_IMMEDIATE )
 	{
 		notify_box_type = "InviteAdHoc";
-		ad_hoc_invite = TRUE;
 	}
 
 	LLSD payload;
@@ -2739,12 +2969,17 @@ void LLIMMgr::inviteToSession(
 
 	if (voice_invite)
 	{
-		if	(	// if we are rejecting group calls 
-				(gSavedSettings.getBOOL("VoiceCallsRejectGroup") && notify_box_type == "VoiceInviteGroup") ||
-				// or we're rejecting non-friend voice calls and this isn't a friend	
-				(gSavedSettings.getBOOL("VoiceCallsFriendsOnly") && (LLAvatarTracker::instance().getBuddyInfo(caller_id) == NULL))
-			)
+		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 (isRejectDoNotDisturb && !isRejectGroupCall && !isRejectNonFriendCall)
+			{
+				LLSD args;
+				addSystemMessage(session_id, "you_auto_rejected_call", args);
+				send_do_not_disturb_message(gMessageSystem, caller_id, session_id);
+			}
 			// silently decline the call
 			LLIncomingCallDialog::processCallResponse(1, payload);
 			return;
@@ -2806,7 +3041,7 @@ void LLIMMgr::clearPendingInvitation(const LLUUID& session_id)
 
 void LLIMMgr::processAgentListUpdates(const LLUUID& session_id, const LLSD& body)
 {
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if ( im_floater )
 	{
 		im_floater->processAgentListUpdates(body);
@@ -2912,11 +3147,27 @@ void LLIMMgr::clearPendingAgentListUpdates(const LLUUID& session_id)
 	}
 }
 
-void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+void LLIMMgr::notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg)
+{
+	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+	{
+		(*it)->sessionAdded(session_id, name, other_participant_id, has_offline_msg);
+	}
+}
+
+void LLIMMgr::notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id)
+{
+    for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
+    {
+        (*it)->sessionActivated(session_id, name, other_participant_id);
+    }
+}
+
+void LLIMMgr::notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id)
 {
 	for (session_observers_list_t::iterator it = mSessionObservers.begin(); it != mSessionObservers.end(); it++)
 	{
-		(*it)->sessionAdded(session_id, name, other_participant_id);
+		(*it)->sessionVoiceOrIMStarted(session_id);
 	}
 }
 
@@ -3016,7 +3267,7 @@ void LLIMMgr::noteOfflineUsers(
 			{
 				LLUIString offline = LLTrans::getString("offline_message");
 				// Use display name only because this user is your friend
-				offline.setArg("[NAME]", av_name.mDisplayName);
+				offline.setArg("[NAME]", av_name.getDisplayName());
 				im_model.proccessOnlineOfflineNotification(session_id, offline);
 			}
 		}
@@ -3064,7 +3315,7 @@ void LLIMMgr::processIMTypingStop(const LLIMInfo* im_info)
 void LLIMMgr::processIMTypingCore(const LLIMInfo* im_info, BOOL typing)
 {
 	LLUUID session_id = computeSessionID(im_info->mIMType, im_info->mFromID);
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if ( im_floater )
 	{
 		im_floater->processIMTyping(im_info, typing);
@@ -3109,7 +3360,7 @@ class LLViewerChatterBoxSessionStartReply : public LLHTTPNode
 				speaker_mgr->updateSpeakers(gIMMgr->getPendingAgentListUpdates(session_id));
 			}
 
-			LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+			LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 			if ( im_floater )
 			{
 				if ( body.has("session_info") )
@@ -3203,7 +3454,7 @@ class LLViewerChatterBoxSessionUpdate : public LLHTTPNode
 		const LLSD& input) const
 	{
 		LLUUID session_id = input["body"]["session_id"].asUUID();
-		LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+		LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 		if ( im_floater )
 		{
 			im_floater->processSessionUpdate(input["body"]["info"]);
@@ -3248,13 +3499,11 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			time_t timestamp =
 				(time_t) message_params["timestamp"].asInteger();
 
-			BOOL is_busy = gAgent.getBusy();
-			BOOL is_muted = LLMuteList::getInstance()->isMuted(
-				from_id,
-				name,
-				LLMute::flagTextChat);
+			BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 
-			if (is_busy || is_muted)
+			//don't return if user is muted b/c proper way to ignore a muted user who
+			//initiated an adhoc/group conference is to create then leave the session (see STORM-1731)
+			if (is_do_not_disturb)
 			{
 				return;
 			}
@@ -3269,16 +3518,16 @@ class LLViewerChatterBoxInvitation : public LLHTTPNode
 			}
 			std::string buffer = saved + message;
 
-			BOOL is_this_agent = FALSE;
 			if(from_id == gAgentID)
 			{
-				is_this_agent = TRUE;
+				return;
 			}
 			gIMMgr->addMessage(
 				session_id,
 				from_id,
 				name,
 				buffer,
+				IM_OFFLINE == offline,
 				std::string((char*)&bin_bucket[0]),
 				IM_SESSION_INVITE,
 				message_params["parent_estate_id"].asInteger(),
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 7c2cd03d9704f69c216c991c56620877ea868dae..da6039a3ae339e291499462b3c35343c4ddeb4d0 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLIMVIEW_H
 #define LL_LLIMVIEW_H
 
-#include "lldockablefloater.h"
+#include "../llui/lldockablefloater.h"
 #include "lleventtimer.h"
 #include "llinstantmessage.h"
 
@@ -70,10 +70,11 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 			GROUP_SESSION,
 			ADHOC_SESSION,
 			AVALINE_SESSION,
+			NONE_SESSION,
 		} SType;
 
 		LLIMSession(const LLUUID& session_id, const std::string& name, 
-			const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice);
+			const EInstantMessage& type, const LLUUID& other_participant_id, const uuid_vec_t& ids, bool voice, bool has_offline_msg);
 		virtual ~LLIMSession();
 
 		void sessionInitReplyReceived(const LLUUID& new_session_id);
@@ -84,7 +85,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		/** @deprecated */
 		static void chatFromLogFile(LLLogChat::ELogLineType type, const LLSD& msg, void* userdata);
 
-		bool isOutgoingAdHoc();
+		bool isOutgoingAdHoc() const;
 		bool isAdHoc();
 		bool isP2P();
 		bool isOtherParticipantAvaline();
@@ -94,10 +95,14 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		bool isGroupSessionType() const { return mSessionType == GROUP_SESSION;}
 		bool isAvalineSessionType() const { return mSessionType == AVALINE_SESSION;}
 
+		LLUUID generateOutgouigAdHocHash() const;
+
 		//*TODO make private
 		/** ad-hoc sessions involve sophisticated chat history file naming schemes */
 		void buildHistoryFileName();
 
+		void loadHistory();
+
 		LLUUID mSessionID;
 		std::string mName;
 		EInstantMessage mType;
@@ -133,22 +138,18 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 		//if IM session is created for a voice call
 		bool mStartedAsIMCall;
 
+		bool mHasOfflineMessage;
+
 	private:
 		void onAdHocNameCache(const LLAvatarName& av_name);
 
-		static std::string generateHash(const std::set<LLUUID>& sorted_uuids);
+		static LLUUID generateHash(const std::set<LLUUID>& sorted_uuids);
+		boost::signals2::connection mAvatarNameCacheConnection;
 	};
 	
 
 	LLIMModel();
 
-
-	//we should control the currently active session
-	LLUUID	mActiveSessionID;
-	void	setActiveSessionID(const LLUUID& session_id);
-	void	resetActiveSessionID() { mActiveSessionID.setNull(); }
-	LLUUID	getActiveSessionID() { return mActiveSessionID; }
-
 	/** Session id to session object */
 	std::map<LLUUID, LLIMSession*> mId2SessionMap;
 
@@ -181,22 +182,16 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	 * @param name session name should not be empty, will return false if empty
 	 */
 	bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type, const LLUUID& other_participant_id, 
-		const uuid_vec_t& ids, bool voice = false);
+		const uuid_vec_t& ids, bool voice = false, bool has_offline_msg = false);
 
 	bool newSession(const LLUUID& session_id, const std::string& name, const EInstantMessage& type,
-		const LLUUID& other_participant_id, bool voice = false);
+		const LLUUID& other_participant_id, bool voice = false, bool has_offline_msg = false);
 
 	/**
 	 * Remove all session data associated with a session specified by session_id
 	 */
 	bool clearSession(const LLUUID& session_id);
 
-	/**
-	 * Populate supplied std::list with messages starting from index specified by start_index without
-	 * emitting no unread messages signal.
-	 */
-	void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
-
 	/**
 	 * Sends no unread messages signal.
 	 */
@@ -205,7 +200,7 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	/**
 	 * Populate supplied std::list with messages starting from index specified by start_index
 	 */
-	void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+	void getMessages(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0, const bool sendNoUnreadMsgs = true);
 
 	/**
 	 * Add a message to an IM Model - the message is saved in a message store associated with a session specified by session_id
@@ -287,6 +282,12 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 
 private:
 	
+	/**
+	 * Populate supplied std::list with messages starting from index specified by start_index without
+	 * emitting no unread messages signal.
+	 */
+	void getMessagesSilently(const LLUUID& session_id, std::list<LLSD>& messages, int start_index = 0);
+
 	/**
 	 * Add message to a list of message associated with session specified by session_id
 	 */
@@ -297,7 +298,9 @@ class LLIMSessionObserver
 {
 public:
 	virtual ~LLIMSessionObserver() {}
-	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+	virtual void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, BOOL has_offline_msg) = 0;
+    virtual void sessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id) = 0;
+	virtual void sessionVoiceOrIMStarted(const LLUUID& session_id) = 0;
 	virtual void sessionRemoved(const LLUUID& session_id) = 0;
 	virtual void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id) = 0;
 };
@@ -324,6 +327,7 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 					const LLUUID& target_id,
 					const std::string& from,
 					const std::string& msg,
+					bool  is_offline_msg = false,
 					const std::string& session_name = LLStringUtil::null,
 					EInstantMessage dialog = IM_NOTHING_SPECIAL,
 					U32 parent_estate_id = 0,
@@ -347,10 +351,12 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	// Adds a session using a specific group of starting agents
 	// the dialog type is assumed correct. Returns the uuid of the session.
+	// A session can be added to a floater specified by floater_id.
 	LLUUID addSession(const std::string& name,
 					  EInstantMessage dialog,
 					  const LLUUID& other_participant_id,
-					  const LLDynamicArray<LLUUID>& ids, bool voice = false);
+					  const LLDynamicArray<LLUUID>& ids, bool voice = false,
+					  const LLUUID& floater_id = LLUUID::null);
 
 	/**
 	 * Creates a P2P session with the requisite handle for responding to voice calls.
@@ -459,7 +465,10 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 
 	static void onInviteNameLookup(LLSD payload, const LLUUID& id, const std::string& name, bool is_group);
 
-	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	void notifyObserverSessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id, bool has_offline_msg);
+    //Triggers when a session has already been added
+    void notifyObserverSessionActivated(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
+	void notifyObserverSessionVoiceOrIMStarted(const LLUUID& session_id);
 	void notifyObserverSessionRemoved(const LLUUID& session_id);
 	void notifyObserverSessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
 
@@ -541,7 +550,14 @@ class LLIncomingCallDialog : public LLCallDialog
 {
 public:
 	LLIncomingCallDialog(const LLSD& payload);
-
+	~LLIncomingCallDialog()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
+	
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void onOpen(const LLSD& key);
 
@@ -558,6 +574,8 @@ class LLIncomingCallDialog : public LLCallDialog
 		const LLAvatarName& av_name,
 		const std::string& call_type);
 
+	boost::signals2::connection mAvatarNameCacheConnection;
+
 	/*virtual*/ void onLifetimeExpired();
 };
 
diff --git a/indra/newview/llinspectavatar.cpp b/indra/newview/llinspectavatar.cpp
index 17d0b0ffbb4901e3649dbad7ff3345a3c6fb325f..9c6db3676f56baf328126c966e249388848c52e2 100644
--- a/indra/newview/llinspectavatar.cpp
+++ b/indra/newview/llinspectavatar.cpp
@@ -29,37 +29,24 @@
 
 // viewer files
 #include "llagent.h"
-#include "llagentdata.h"
 #include "llavataractions.h"
+#include "llavatariconctrl.h"
 #include "llavatarnamecache.h"
 #include "llavatarpropertiesprocessor.h"
-#include "llcallingcard.h"
 #include "lldateutil.h"
-#include "llfloaterreporter.h"
-#include "llfloaterworldmap.h"
-#include "llimview.h"
 #include "llinspect.h"
 #include "llmutelist.h"
-#include "llpanelblockedlist.h"
+#include "llslurl.h"
 #include "llstartup.h"
-#include "llspeakers.h"
-#include "llviewermenu.h"
 #include "llvoiceclient.h"
-#include "llviewerobjectlist.h"
 #include "lltransientfloatermgr.h"
-#include "llnotificationsutil.h"
 
 // Linden libraries
 #include "llfloater.h"
 #include "llfloaterreg.h"
-#include "llmenubutton.h"
 #include "lltextbox.h"
-#include "lltoggleablemenu.h"
 #include "lltooltip.h"	// positionViewNearMouse()
 #include "lltrans.h"
-#include "lluictrl.h"
-
-#include "llavatariconctrl.h"
 
 class LLFetchAvatarData;
 
@@ -80,70 +67,30 @@ class LLInspectAvatar : public LLInspect, LLTransientFloater
 	// Inspector will be positioned relative to current mouse position
 	LLInspectAvatar(const LLSD& avatar_id);
 	virtual ~LLInspectAvatar();
-	
+
 	/*virtual*/ BOOL postBuild(void);
 	
 	// Because floater is single instance, need to re-parse data on each spawn
 	// (for example, inspector about same avatar but in different position)
 	/*virtual*/ void onOpen(const LLSD& avatar_id);
 
-	// When closing they should close their gear menu 
-	/*virtual*/ void onClose(bool app_quitting);
-	
 	// Update view based on information from avatar properties processor
 	void processAvatarData(LLAvatarData* data);
 	
-	// override the inspector mouse leave so timer is only paused if 
-	// gear menu is not open
-	/* virtual */ void onMouseLeave(S32 x, S32 y, MASK mask);
-	
 	virtual LLTransientFloaterMgr::ETransientGroup getGroup() { return LLTransientFloaterMgr::GLOBAL; }
 
 private:
 	// Make network requests for all the data to display in this view.
 	// Used on construction and if avatar id changes.
 	void requestUpdate();
-	
+
 	// Set the volume slider to this user's current client-side volume setting,
 	// hiding/disabling if the user is not nearby.
 	void updateVolumeSlider();
 
-	// Shows/hides moderator panel depending on voice state 
-	void updateModeratorPanel();
-
-	// Moderator ability to enable/disable voice chat for avatar
-	void toggleSelectedVoice(bool enabled);
-	
 	// Button callbacks
-	void onClickAddFriend();
-	void onClickViewProfile();
-	void onClickIM();
-	void onClickCall();
-	void onClickTeleport();
-	void onClickInviteToGroup();
-	void onClickPay();
-	void onClickShare();
-	void onToggleMute();
-	void onClickReport();
-	void onClickFreeze();
-	void onClickEject();
-	void onClickKick();
-	void onClickCSR();
-	void onClickZoomIn();  
-	void onClickFindOnMap();
-	bool onVisibleFindOnMap();
-	bool onVisibleEject();
-	bool onVisibleFreeze();
-	bool onVisibleZoomIn();
 	void onClickMuteVolume();
 	void onVolumeChange(const LLSD& data);
-	bool enableMute();
-	bool enableUnmute();
-	bool enableTeleportOffer();
-	bool godModeEnabled();
-
-	// Is used to determine if "Add friend" option should be enabled in gear menu
-	bool isNotFriend();
 	
 	void onAvatarNameCache(const LLUUID& agent_id,
 						   const LLAvatarName& av_name);
@@ -155,6 +102,7 @@ class LLInspectAvatar : public LLInspect, LLTransientFloater
 	// an in-flight request for avatar properties from LLAvatarPropertiesProcessor
 	// is represented by this object
 	LLFetchAvatarData*	mPropertiesRequest;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 //////////////////////////////////////////////////////////////////////////////
@@ -207,41 +155,11 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 :	LLInspect( LLSD() ),	// single_instance, doesn't really need key
 	mAvatarID(),			// set in onOpen()  *Note: we used to show partner's name but we dont anymore --angela 3rd Dec* 
 	mAvatarName(),
-	mPropertiesRequest(NULL)
+	mPropertiesRequest(NULL),
+	mAvatarNameCacheConnection()
 {
-	mCommitCallbackRegistrar.add("InspectAvatar.ViewProfile",	boost::bind(&LLInspectAvatar::onClickViewProfile, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.AddFriend",	boost::bind(&LLInspectAvatar::onClickAddFriend, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.IM",
-		boost::bind(&LLInspectAvatar::onClickIM, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Call",		boost::bind(&LLInspectAvatar::onClickCall, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Teleport",	boost::bind(&LLInspectAvatar::onClickTeleport, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.InviteToGroup",	boost::bind(&LLInspectAvatar::onClickInviteToGroup, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Pay",	boost::bind(&LLInspectAvatar::onClickPay, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Share",	boost::bind(&LLInspectAvatar::onClickShare, this));
-	mCommitCallbackRegistrar.add("InspectAvatar.ToggleMute",	boost::bind(&LLInspectAvatar::onToggleMute, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Freeze", boost::bind(&LLInspectAvatar::onClickFreeze, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Eject", boost::bind(&LLInspectAvatar::onClickEject, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Kick", boost::bind(&LLInspectAvatar::onClickKick, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.CSR", boost::bind(&LLInspectAvatar::onClickCSR, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.Report",	boost::bind(&LLInspectAvatar::onClickReport, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.FindOnMap",	boost::bind(&LLInspectAvatar::onClickFindOnMap, this));	
-	mCommitCallbackRegistrar.add("InspectAvatar.ZoomIn", boost::bind(&LLInspectAvatar::onClickZoomIn, this));
-	mCommitCallbackRegistrar.add("InspectAvatar.DisableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, false));
-	mCommitCallbackRegistrar.add("InspectAvatar.EnableVoice", boost::bind(&LLInspectAvatar::toggleSelectedVoice, this, true));
-
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableGod",	boost::bind(&LLInspectAvatar::godModeEnabled, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFindOnMap",	boost::bind(&LLInspectAvatar::onVisibleFindOnMap, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleEject",	boost::bind(&LLInspectAvatar::onVisibleEject, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleFreeze",	boost::bind(&LLInspectAvatar::onVisibleFreeze, this));	
-	mEnableCallbackRegistrar.add("InspectAvatar.VisibleZoomIn", boost::bind(&LLInspectAvatar::onVisibleZoomIn, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.Enable", boost::bind(&LLInspectAvatar::isNotFriend, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableCall", boost::bind(&LLAvatarActions::canCall));
-	mEnableCallbackRegistrar.add("InspectAvatar.Gear.EnableTeleportOffer", boost::bind(&LLInspectAvatar::enableTeleportOffer, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableMute", boost::bind(&LLInspectAvatar::enableMute, this));
-	mEnableCallbackRegistrar.add("InspectAvatar.EnableUnmute", boost::bind(&LLInspectAvatar::enableUnmute, this));
-
 	// can't make the properties request until the widgets are constructed
-	// as it might return immediately, so do it in postBuild.
+	// as it might return immediately, so do it in onOpen.
 
 	LLTransientFloaterMgr::getInstance()->addControlView(LLTransientFloaterMgr::GLOBAL, this);
 	LLTransientFloater::init(this);
@@ -249,6 +167,10 @@ LLInspectAvatar::LLInspectAvatar(const LLSD& sd)
 
 LLInspectAvatar::~LLInspectAvatar()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	// clean up any pending requests so they don't call back into a deleted
 	// view
 	delete mPropertiesRequest;
@@ -260,12 +182,6 @@ LLInspectAvatar::~LLInspectAvatar()
 /*virtual*/
 BOOL LLInspectAvatar::postBuild(void)
 {
-	getChild<LLUICtrl>("add_friend_btn")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onClickAddFriend, this) );
-
-	getChild<LLUICtrl>("view_profile_btn")->setCommitCallback(
-		boost::bind(&LLInspectAvatar::onClickViewProfile, this) );
-
 	getChild<LLUICtrl>("mute_btn")->setCommitCallback(
 		boost::bind(&LLInspectAvatar::onClickMuteVolume, this) );
 
@@ -275,7 +191,6 @@ BOOL LLInspectAvatar::postBuild(void)
 	return TRUE;
 }
 
-
 // Multiple calls to showInstance("inspect_avatar", foo) will provide different
 // LLSD for foo, which we will catch here.
 //virtual
@@ -287,11 +202,6 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 	// Extract appropriate avatar id
 	mAvatarID = data["avatar_id"];
 
-	BOOL self = mAvatarID == gAgent.getID();
-	
-	getChild<LLUICtrl>("gear_self_btn")->setVisible(self);
-	getChild<LLUICtrl>("gear_btn")->setVisible(!self);
-
 	// Position the inspector relative to the mouse cursor
 	// Similar to how tooltips are positioned
 	// See LLToolTipMgr::createToolTip
@@ -304,20 +214,15 @@ void LLInspectAvatar::onOpen(const LLSD& data)
 		LLUI::positionViewNearMouse(this);
 	}
 
+	// Generate link to avatar profile.
+	getChild<LLUICtrl>("avatar_profile_link")->setTextArg("[LINK]", LLSLURL("agent", mAvatarID, "about").getSLURLString());
+
 	// can't call from constructor as widgets are not built yet
 	requestUpdate();
 
 	updateVolumeSlider();
-
-	updateModeratorPanel();
 }
 
-// virtual
-void LLInspectAvatar::onClose(bool app_quitting)
-{  
-  getChild<LLMenuButton>("gear_btn")->hideMenu();
-}	
-
 void LLInspectAvatar::requestUpdate()
 {
 	// Don't make network requests when spawning from the debug menu at the
@@ -344,25 +249,6 @@ void LLInspectAvatar::requestUpdate()
 	delete mPropertiesRequest;
 	mPropertiesRequest = new LLFetchAvatarData(mAvatarID, this);
 
-	// You can't re-add someone as a friend if they are already your friend
-	bool is_friend = LLAvatarTracker::instance().getBuddyInfo(mAvatarID) != NULL;
-	bool is_self = (mAvatarID == gAgentID);
-	if (is_self)
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
-		getChild<LLUICtrl>("im_btn")->setVisible(false);
-	}
-	else if (is_friend)
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(false);
-		getChild<LLUICtrl>("im_btn")->setVisible(true);
-	}
-	else
-	{
-		getChild<LLUICtrl>("add_friend_btn")->setVisible(true);
-		getChild<LLUICtrl>("im_btn")->setVisible(false);
-	}
-
 	// Use an avatar_icon even though the image id will come down with the
 	// avatar properties because the avatar_icon code maintains a cache of icons
 	// and this may result in the image being visible sooner.
@@ -374,9 +260,11 @@ void LLInspectAvatar::requestUpdate()
 
 	getChild<LLUICtrl>("avatar_icon")->setValue(LLSD(mAvatarID) );
 
-	LLAvatarNameCache::get(mAvatarID,
-			boost::bind(&LLInspectAvatar::onAvatarNameCache,
-				this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(mAvatarID,boost::bind(&LLInspectAvatar::onAvatarNameCache,this, _1, _2));
 }
 
 void LLInspectAvatar::processAvatarData(LLAvatarData* data)
@@ -404,141 +292,11 @@ void LLInspectAvatar::processAvatarData(LLAvatarData* data)
 	delete mPropertiesRequest;
 	mPropertiesRequest = NULL;
 }
-
-// For the avatar inspector, we only want to unpause the fade timer 
-// if neither the gear menu or self gear menu are open
-void LLInspectAvatar::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	LLToggleableMenu* gear_menu = getChild<LLMenuButton>("gear_btn")->getMenu();
-	LLToggleableMenu* gear_menu_self = getChild<LLMenuButton>("gear_self_btn")->getMenu();
-	if ( gear_menu && gear_menu->getVisible() &&
-		 gear_menu_self && gear_menu_self->getVisible() )
-	{
-		return;
-	}
-
-	if(childHasVisiblePopupMenu())
-	{
-		return;
-	}
-
-	mOpenTimer.unpause();
-}
-
-void LLInspectAvatar::updateModeratorPanel()
-{
-	bool enable_moderator_panel = false;
-
-    if (LLVoiceChannel::getCurrentVoiceChannel() &&
-		mAvatarID != gAgent.getID())
-    {
-		LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-
-		if (session_id != LLUUID::null)
-		{
-			LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
-			if (speaker_mgr)
-			{
-				LLPointer<LLSpeaker> self_speakerp = speaker_mgr->findSpeaker(gAgent.getID());
-				LLPointer<LLSpeaker> selected_speakerp = speaker_mgr->findSpeaker(mAvatarID);
-				
-				if(speaker_mgr->isVoiceActive() && selected_speakerp && 
-					selected_speakerp->isInVoiceChannel() &&
-					((self_speakerp && self_speakerp->mIsModerator) || gAgent.isGodlike()))
-				{
-					getChild<LLUICtrl>("enable_voice")->setVisible(selected_speakerp->mModeratorMutedVoice);
-					getChild<LLUICtrl>("disable_voice")->setVisible(!selected_speakerp->mModeratorMutedVoice);
-
-					enable_moderator_panel = true;
-				}
-			}
-		}
-	}
-
-	if (enable_moderator_panel)
-	{
-		if (!getChild<LLUICtrl>("moderator_panel")->getVisible())
-		{
-			getChild<LLUICtrl>("moderator_panel")->setVisible(true);
-			// stretch the floater so it can accommodate the moderator panel
-			reshape(getRect().getWidth(), getRect().getHeight() + getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());
-		}
-	}
-	else if (getChild<LLUICtrl>("moderator_panel")->getVisible())
-	{
-		getChild<LLUICtrl>("moderator_panel")->setVisible(false);
-		// shrink the inspector floater back to original size
-		reshape(getRect().getWidth(), getRect().getHeight() - getChild<LLUICtrl>("moderator_panel")->getRect().getHeight());					
-	}
-}
-
-void LLInspectAvatar::toggleSelectedVoice(bool enabled)
-{
-	LLUUID session_id = LLVoiceChannel::getCurrentVoiceChannel()->getSessionID();
-	LLIMSpeakerMgr* speaker_mgr = LLIMModel::getInstance()->getSpeakerManager(session_id);
-
-	if (speaker_mgr)
-	{
-		if (!gAgent.getRegion())
-			return;
-
-		std::string url = gAgent.getRegion()->getCapability("ChatSessionRequest");
-		LLSD data;
-		data["method"] = "mute update";
-		data["session-id"] = session_id;
-		data["params"] = LLSD::emptyMap();
-		data["params"]["agent_id"] = mAvatarID;
-		data["params"]["mute_info"] = LLSD::emptyMap();
-		// ctrl value represents ability to type, so invert
-		data["params"]["mute_info"]["voice"] = !enabled;
-
-		class MuteVoiceResponder : public LLHTTPClient::Responder
-		{
-		public:
-			MuteVoiceResponder(const LLUUID& session_id)
-			{
-				mSessionID = session_id;
-			}
-
-			virtual void error(U32 status, const std::string& reason)
-			{
-				llwarns << status << ": " << reason << llendl;
-
-				if ( gIMMgr )
-				{
-					//403 == you're not a mod
-					//should be disabled if you're not a moderator
-					if ( 403 == status )
-					{
-						gIMMgr->showSessionEventError(
-							"mute",
-							"not_a_moderator",
-							mSessionID);
-					}
-					else
-					{
-						gIMMgr->showSessionEventError(
-							"mute",
-							"generic",
-							mSessionID);
-					}
-				}
-			}
-
-		private:
-			LLUUID mSessionID;
-		};
-
-		LLHTTPClient::post(
-			url,
-			data,
-			new MuteVoiceResponder(speaker_mgr->getSessionID()));
-	}
-
-	closeFloater();
-
-}
+/*
+prep#
+			virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+				llwarns << "MuteVoiceResponder error [status:" << status << "]: " << content << llendl;
+	*/
 
 void LLInspectAvatar::updateVolumeSlider()
 {
@@ -558,12 +316,11 @@ void LLInspectAvatar::updateVolumeSlider()
 		getChild<LLUICtrl>("volume_slider")->setVisible(true);
 
 		// By convention, we only display and toggle voice mutes, not all mutes
-		bool is_muted = LLMuteList::getInstance()->
-							isMuted(mAvatarID, LLMute::flagVoiceChat);
+		bool is_muted = LLAvatarActions::isVoiceMuted(mAvatarID);
 
 		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
 
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
+		bool is_linden = LLStringUtil::endsWith(mAvatarName.getDisplayName(), " Linden");
 
 		mute_btn->setEnabled( !is_linden);
 		mute_btn->setValue( is_muted );
@@ -594,7 +351,7 @@ void LLInspectAvatar::onClickMuteVolume()
 	LLMuteList* mute_list = LLMuteList::getInstance();
 	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
 
-	LLMute mute(mAvatarID, mAvatarName.getLegacyName(), LLMute::AGENT);
+	LLMute mute(mAvatarID, mAvatarName.getDisplayName(), LLMute::AGENT);
 	if (!is_muted)
 	{
 		mute_list->add(mute, LLMute::flagVoiceChat);
@@ -617,11 +374,13 @@ void LLInspectAvatar::onAvatarNameCache(
 		const LLUUID& agent_id,
 		const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	if (agent_id == mAvatarID)
 	{
-		getChild<LLUICtrl>("user_name")->setValue(av_name.mDisplayName);
-		getChild<LLUICtrl>("user_name_small")->setValue(av_name.mDisplayName);
-		getChild<LLUICtrl>("user_slid")->setValue(av_name.mUsername);
+		getChild<LLUICtrl>("user_name")->setValue(av_name.getDisplayName());
+		getChild<LLUICtrl>("user_name_small")->setValue(av_name.getDisplayName());
+		getChild<LLUICtrl>("user_slid")->setValue(av_name.getUserName());
 		mAvatarName = av_name;
 		
 		// show smaller display name if too long to display in regular size
@@ -640,215 +399,6 @@ void LLInspectAvatar::onAvatarNameCache(
 	}
 }
 
-void LLInspectAvatar::onClickAddFriend()
-{
-	LLAvatarActions::requestFriendshipDialog(mAvatarID, mAvatarName.getLegacyName());
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickViewProfile()
-{
-	LLAvatarActions::showProfile(mAvatarID);
-	closeFloater();
-}
-
-bool LLInspectAvatar::isNotFriend()
-{
-	return !LLAvatarActions::isFriend(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleFindOnMap()
-{
-	return gAgent.isGodlike() || is_agent_mappable(mAvatarID);
-}
-
-bool LLInspectAvatar::onVisibleEject()
-{
-	return enable_freeze_eject( LLSD(mAvatarID) );
-}
-
-bool LLInspectAvatar::onVisibleFreeze()
-{
-	// either user is a god and can do long distance freeze
-	// or check for target proximity and permissions
-	return gAgent.isGodlike() || enable_freeze_eject(LLSD(mAvatarID));
-}
-
-bool LLInspectAvatar::onVisibleZoomIn()
-{
-	return gObjectList.findObject(mAvatarID);
-}
-
-void LLInspectAvatar::onClickIM()
-{ 
-	LLAvatarActions::startIM(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickCall()
-{ 
-	LLAvatarActions::startCall(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickTeleport()
-{
-	LLAvatarActions::offerTeleport(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickInviteToGroup()
-{
-	LLAvatarActions::inviteToGroup(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickPay()
-{
-	LLAvatarActions::pay(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickShare()
-{
-	LLAvatarActions::share(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onToggleMute()
-{
-	LLMute mute(mAvatarID, mAvatarName.mDisplayName, LLMute::AGENT);
-
-	if (LLMuteList::getInstance()->isMuted(mute.mID, mute.mName))
-	{
-		LLMuteList::getInstance()->remove(mute);
-	}
-	else
-	{
-		LLMuteList::getInstance()->add(mute);
-	}
-
-	LLPanelBlockedList::showPanelAndSelect(mute.mID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickReport()
-{
-	LLFloaterReporter::showFromAvatar(mAvatarID, mAvatarName.getCompleteName());
-	closeFloater();
-}
-
-bool godlike_freeze(const LLSD& notification, const LLSD& response)
-{
-	LLUUID avatar_id = notification["payload"]["avatar_id"].asUUID();
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-
-	switch (option)
-	{
-	case 0:
-		LLAvatarActions::freeze(avatar_id);
-		break;
-	case 1:
-		LLAvatarActions::unfreeze(avatar_id);
-		break;
-	default:
-		break;
-	}
-
-	return false;
-}
-
-void LLInspectAvatar::onClickFreeze()
-{
-	if (gAgent.isGodlike())
-	{
-		// use godlike freeze-at-a-distance, with confirmation
-		LLNotificationsUtil::add("FreezeAvatar",
-			LLSD(),
-			LLSD().with("avatar_id", mAvatarID),
-			godlike_freeze);
-	}
-	else
-	{
-		// use default "local" version of freezing that requires avatar to be in range
-		handle_avatar_freeze( LLSD(mAvatarID) );
-	}
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickEject()
-{
-	handle_avatar_eject( LLSD(mAvatarID) );
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickKick()
-{
-	LLAvatarActions::kick(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickCSR()
-{
-	std::string name;
-	gCacheName->getFullName(mAvatarID, name);
-	LLAvatarActions::csr(mAvatarID, name);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickZoomIn() 
-{
-	handle_zoom_to_object(mAvatarID);
-	closeFloater();
-}
-
-void LLInspectAvatar::onClickFindOnMap()
-{
-	gFloaterWorldMap->trackAvatar(mAvatarID, mAvatarName.mDisplayName);
-	LLFloaterReg::showInstance("world_map");
-}
-
-
-bool LLInspectAvatar::enableMute()
-{
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-		bool is_self = mAvatarID == gAgent.getID();
-
-		if (!is_linden && !is_self && !LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
-		{
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-}
-
-bool LLInspectAvatar::enableUnmute()
-{
-		bool is_linden = LLStringUtil::endsWith(mAvatarName.getLegacyName(), " Linden");
-		bool is_self = mAvatarID == gAgent.getID();
-
-		if (!is_linden && !is_self && LLMuteList::getInstance()->isMuted(mAvatarID, mAvatarName.getLegacyName()))
-		{
-			return true;
-		}
-		else
-		{
-			return false;
-		}
-}
-
-bool LLInspectAvatar::enableTeleportOffer()
-{
-	return LLAvatarActions::canOfferTeleport(mAvatarID);
-}
-
-bool LLInspectAvatar::godModeEnabled()
-{
-	return gAgent.isGodlike();
-}
-
 //////////////////////////////////////////////////////////////////////////////
 // LLInspectAvatarUtil
 //////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp
index 949de312be03883d5ecc7dcfefdee8a295385421..a5043a30acce7fcde10fb3a452515cdcc2a831c2 100644
--- a/indra/newview/llinventorybridge.cpp
+++ b/indra/newview/llinventorybridge.cpp
@@ -37,6 +37,7 @@
 #include "llappearancemgr.h"
 #include "llattachmentsmgr.h"
 #include "llavataractions.h" 
+#include "llfavoritesbar.h" // management of favorites folder
 #include "llfloateropenobject.h"
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
@@ -45,11 +46,12 @@
 #include "llfriendcard.h"
 #include "llgesturemgr.h"
 #include "llgiveinventory.h" 
-#include "llimfloater.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"
 #include "llclipboard.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llinventorymodelbackgroundfetch.h"
 #include "llinventorypanel.h"
@@ -94,34 +96,17 @@ struct LLMoveInv
 
 using namespace LLOldEvents;
 
-// Helpers
-// bug in busy count inc/dec right now, logic is complex... do we really need it?
-void inc_busy_count()
-{
-// 	gViewerWindow->getWindow()->incBusyCount();
-//  check balance of these calls if this code is changed to ever actually
-//  *do* something!
-}
-void dec_busy_count()
-{
-// 	gViewerWindow->getWindow()->decBusyCount();
-//  check balance of these calls if this code is changed to ever actually
-//  *do* something!
-}
-
 // Function declarations
-void remove_inventory_category_from_avatar(LLInventoryCategory* category);
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id);
 bool move_task_inventory_callback(const LLSD& notification, const LLSD& response, LLMoveInv*);
 bool confirm_attachment_rez(const LLSD& notification, const LLSD& response);
 void teleport_via_landmark(const LLUUID& asset_id);
 static BOOL can_move_to_outfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 static bool check_category(LLInventoryModel* model,
 						   const LLUUID& cat_id,
-						   LLFolderView* active_folder_view,
+						   LLInventoryPanel* active_panel,
 						   LLInventoryFilter* filter);
 static bool check_item(const LLUUID& item_id,
-					   LLFolderView* active_folder_view,
+					   LLInventoryPanel* active_panel,
 					   LLInventoryFilter* filter);
 
 // Helper functions
@@ -169,7 +154,6 @@ class LLRightClickInventoryFetchObserver : public LLInventoryFetchItemsObserver
 	{
 		if (clear_observer)
 		{
-			dec_busy_count();
 			gInventory.removeObserver(this);
 			delete this;
 		}
@@ -192,7 +176,8 @@ LLInvFVBridge::LLInvFVBridge(LLInventoryPanel* inventory,
 	mUUID(uuid), 
 	mRoot(root),
 	mInvType(LLInventoryType::IT_NONE),
-	mIsLink(FALSE)
+	mIsLink(FALSE),
+	LLFolderViewModelItemInventory(inventory->getRootViewModel())
 {
 	mInventoryPanel = inventory->getInventoryPanelHandle();
 	const LLInventoryObject* obj = getInventoryObject();
@@ -211,7 +196,11 @@ const std::string& LLInvFVBridge::getName() const
 
 const std::string& LLInvFVBridge::getDisplayName() const
 {
-	return getName();
+	if(mDisplayName.empty())
+	{
+		buildDisplayName();
+	}
+	return mDisplayName;
 }
 
 // Folders have full perms
@@ -230,9 +219,24 @@ LLFolderType::EType LLInvFVBridge::getPreferredType() const
 // Folders don't have creation dates.
 time_t LLInvFVBridge::getCreationDate() const
 {
-	return 0;
+	LLInventoryObject* objectp = getInventoryObject();
+	if (objectp)
+	{
+		return objectp->getCreationDate();
+	}
+	return (time_t)0;
 }
 
+void LLInvFVBridge::setCreationDate(time_t creation_date_utc)
+{
+	LLInventoryObject* objectp = getInventoryObject();
+	if (objectp)
+	{
+		objectp->setCreationDate(creation_date_utc);
+	}
+}
+
+
 // Can be destroyed (or moved to trash)
 BOOL LLInvFVBridge::isItemRemovable() const
 {
@@ -250,6 +254,11 @@ BOOL LLInvFVBridge::isLink() const
 	return mIsLink;
 }
 
+BOOL LLInvFVBridge::isLibraryItem() const
+{
+	return gInventory.isObjectDescendentOf(getUUID(),gInventory.getLibraryRootFolderID());
+}
+
 /*virtual*/
 /**
  * @brief Adds this item into clipboard storage
@@ -286,7 +295,7 @@ void LLInvFVBridge::showProperties()
 	*/
 }
 
-void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void LLInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
 {
 	// Deactivate gestures when moving them into Trash
 	LLInvFVBridge* bridge;
@@ -295,11 +304,11 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	LLViewerInventoryCategory* cat = NULL;
 	LLInventoryModel::cat_array_t	descendent_categories;
 	LLInventoryModel::item_array_t	descendent_items;
-	S32 count = batch.count();
+	S32 count = batch.size();
 	S32 i,j;
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if (item)
@@ -312,7 +321,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	}
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 		if (cat)
@@ -330,7 +339,7 @@ void LLInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batc
 	removeBatchNoCheck(batch);
 }
 
-void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void  LLInvFVBridge::removeBatchNoCheck(std::vector<LLFolderViewModelItem*>&  batch)
 {
 	// this method moves a bunch of items and folders to the trash. As
 	// per design guidelines for the inventory model, the message is
@@ -346,14 +355,14 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
 	uuid_vec_t move_ids;
 	LLInventoryModel::update_map_t update;
 	bool start_new_message = true;
-	S32 count = batch.count();
+	S32 count = batch.size();
 	S32 i;
 
 	// first, hide any 'preview' floaters that correspond to the items
 	// being deleted.
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if(item)
@@ -366,7 +375,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
 
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		item = (LLViewerInventoryItem*)model->getItem(bridge->getUUID());
 		if(item)
@@ -407,7 +416,7 @@ void LLInvFVBridge::removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*
 
 	for(i = 0; i < count; ++i)
 	{
-		bridge = (LLInvFVBridge*)(batch.get(i));
+		bridge = (LLInvFVBridge*)(batch[i]);
 		if(!bridge || !bridge->isItemRemovable()) continue;
 		LLViewerInventoryCategory* cat = (LLViewerInventoryCategory*)model->getCategory(bridge->getUUID());
 		if(cat)
@@ -501,8 +510,10 @@ BOOL LLInvFVBridge::isClipboardPasteable() const
 		// Each item must be copyable to be pastable
 		LLItemBridge item_br(mInventoryPanel.get(), mRoot, item_id);
 		if (!item_br.isItemCopyable())
-				return FALSE;
-			}
+		{
+			return FALSE;
+		}
+	}
 	return TRUE;
 }
 
@@ -879,6 +890,12 @@ LLInventoryModel* LLInvFVBridge::getInventoryModel() const
 	return panel ? panel->getModel() : NULL;
 }
 
+LLInventoryFilter* LLInvFVBridge::getInventoryFilter() const
+{
+	LLInventoryPanel* panel = mInventoryPanel.get();
+	return panel ? &(panel->getFilter()) : NULL;
+}
+
 BOOL LLInvFVBridge::isItemInTrash() const
 {
 	LLInventoryModel* model = getInventoryModel();
@@ -931,7 +948,7 @@ BOOL LLInvFVBridge::isCOFFolder() const
 
 BOOL LLInvFVBridge::isInboxFolder() const
 {
-	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
+	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false);
 	
 	if (inbox_id.isNull())
 	{
@@ -971,7 +988,7 @@ BOOL LLInvFVBridge::isOutboxFolderDirectParent() const
 
 const LLUUID LLInvFVBridge::getOutboxFolder() const
 {
-	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+	const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 
 	return outbox_id;
 }
@@ -1003,6 +1020,7 @@ LLInvFVBridge* LLInvFVBridge::createBridge(LLAssetType::EType asset_type,
 										   LLAssetType::EType actual_asset_type,
 										   LLInventoryType::EType inv_type,
 										   LLInventoryPanel* inventory,
+										   LLFolderViewModelInventory* view_model,
 										   LLFolderView* root,
 										   const LLUUID& uuid,
 										   U32 flags)
@@ -1253,10 +1271,10 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 
 		if (can_list)
 		{
-			LLFolderViewFolder * object_folderp = mRoot->getFolderByID(object_id);
+			LLFolderViewFolder * object_folderp =   mInventoryPanel.get() ? mInventoryPanel.get()->getFolderByID(object_id) : NULL;
 			if (object_folderp)
 			{
-				can_list = !object_folderp->isLoading();
+				can_list = !static_cast<LLFolderBridge*>(object_folderp->getViewModelItem())->isLoading();
 			}
 		}
 		
@@ -1264,7 +1282,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 		{
 			// Get outbox id
 			const LLUUID & outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
-			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(outbox_id);
+			LLFolderViewItem * outbox_itemp =   mInventoryPanel.get() ? mInventoryPanel.get()->getItemByID(outbox_id) : NULL;
 
 			if (outbox_itemp)
 			{
@@ -1274,7 +1292,7 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 				void * cargo_data = (void *) obj;
 				std::string tooltip_msg;
 				
-				can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+				can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
 			}
 		}
 	}
@@ -1286,14 +1304,30 @@ bool LLInvFVBridge::canListOnMarketplaceNow() const
 #endif
 }
 
+LLToolDragAndDrop::ESource LLInvFVBridge::getDragSource() const
+{
+	if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID()))
+	{
+		return LLToolDragAndDrop::SOURCE_AGENT;
+	}
+	else if (gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID()))
+	{
+		return LLToolDragAndDrop::SOURCE_LIBRARY;
+	}
+
+	return LLToolDragAndDrop::SOURCE_VIEWER;
+}
+
+
 
 // +=================================================+
 // |        InventoryFVBridgeBuilder                 |
 // +=================================================+
-LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset_type,
+LLInvFVBridge* LLInventoryFolderViewModelBuilder::createBridge(LLAssetType::EType asset_type,
 														LLAssetType::EType actual_asset_type,
 														LLInventoryType::EType inv_type,
 														LLInventoryPanel* inventory,
+														LLFolderViewModelInventory* view_model,
 														LLFolderView* root,
 														const LLUUID& uuid,
 														U32 flags /* = 0x00 */) const
@@ -1302,6 +1336,7 @@ LLInvFVBridge* LLInventoryFVBridgeBuilder::createBridge(LLAssetType::EType asset
 									   actual_asset_type,
 									   inv_type,
 									   inventory,
+									   view_model,
 									   root,
 									   uuid,
 									   flags);
@@ -1358,10 +1393,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 	else if ("cut" == action)
 	{
 		cutToClipboard();
-		// MAINT-1197: This is temp code to work around a deselection/reselection bug. Please discard when merging CHUI.
-		LLFolderViewItem* item_to_select = mRoot->getNextUnselectedItem();
-		LLFolderView::removeCutItems();
-		mRoot->setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, false);
+		gInventory.removeObject(mUUID);
 		return;
 	}
 	else if ("copy" == action)
@@ -1374,10 +1406,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
-		folder_view_itemp->getListener()->pasteFromClipboard();
+		folder_view_itemp->getViewModelItem()->pasteFromClipboard();
 		return;
 	}
 	else if ("paste_link" == action)
@@ -1386,10 +1418,10 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		LLFolderViewItem* folder_view_itemp = mRoot->getItemByID(itemp->getParentUUID());
+		LLFolderViewItem* folder_view_itemp =   mInventoryPanel.get()->getItemByID(itemp->getParentUUID());
 		if (!folder_view_itemp) return;
 
-		folder_view_itemp->getListener()->pasteLinkFromClipboard();
+		folder_view_itemp->getViewModelItem()->pasteLinkFromClipboard();
 		return;
 	}
 	else if (isMarketplaceCopyAction(action))
@@ -1399,7 +1431,7 @@ void LLItemBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryItem* itemp = model->getItem(mUUID);
 		if (!itemp) return;
 
-		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		copy_item_to_outbox(itemp, outbox_id, LLUUID::null, LLToolDragAndDrop::getOperationId());
 	}
 	else if ("copy_slurl" == action)
@@ -1512,7 +1544,16 @@ LLUIImagePtr LLItemBridge::getIcon() const
 										mIsLink);
 	}
 	
-	return LLInventoryIcon::getIcon(LLInventoryIcon::ICONNAME_OBJECT);
+	return LLInventoryIcon::getIcon(LLInventoryType::ICONNAME_OBJECT);
+}
+
+LLUIImagePtr LLItemBridge::getIconOverlay() const
+{
+	if (getItem() && getItem()->getIsLinkType())
+	{
+		return LLUI::getUIImage("Inv_Link");
+	}
+	return NULL;
 }
 
 PermissionMask LLItemBridge::getPermissionMask() const
@@ -1523,26 +1564,27 @@ PermissionMask LLItemBridge::getPermissionMask() const
 	return perm_mask;
 }
 
-const std::string& LLItemBridge::getDisplayName() const
+void LLItemBridge::buildDisplayName() const
 {
-	if(mDisplayName.empty())
+	if(getItem())
 	{
-		buildDisplayName(getItem(), mDisplayName);
+		mDisplayName.assign(getItem()->getName());
 	}
-	return mDisplayName;
+	else
+	{
+		mDisplayName.assign(LLStringUtil::null);
 }
 
-void LLItemBridge::buildDisplayName(LLInventoryItem* item, std::string& name)
+	mSearchableName.assign(mDisplayName);
+	mSearchableName.append(getLabelSuffix());
+	LLStringUtil::toUpper(mSearchableName);
+
+    //Name set, so trigger a sort
+    if(mParent)
 {
-	if(item)
-	{
-		name.assign(item->getName());
+        mParent->requestSort();
 	}
-	else
-	{
-		name.assign(LLStringUtil::null);
 	}
-}
 
 LLFontGL::StyleFlags LLItemBridge::getLabelStyle() const
 {
@@ -1658,18 +1700,17 @@ BOOL LLItemBridge::renameItem(const std::string& new_name)
 	{
 		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 		new_item->rename(new_name);
-		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
 
 		model->notifyObservers();
+		buildDisplayName();
 	}
 	// return FALSE because we either notified observers (& therefore
 	// rebuilt) or we didn't update.
 	return FALSE;
 }
 
-
 BOOL LLItemBridge::removeItem()
 {
 	if(!isItemRemovable())
@@ -1677,7 +1718,6 @@ BOOL LLItemBridge::removeItem()
 		return FALSE;
 	}
 
-	
 	// move it to the trash
 	LLPreview::hide(mUUID, TRUE);
 	LLInventoryModel* model = getInventoryModel();
@@ -1815,6 +1855,99 @@ void LLFolderBridge::selectItem()
 	LLInventoryModelBackgroundFetch::instance().start(getUUID(), true);
 }
 
+void LLFolderBridge::buildDisplayName() const
+{
+	LLFolderType::EType preferred_type = getPreferredType();
+
+	// *TODO: to be removed when database supports multi language. This is a
+	// temporary attempt to display the inventory folder in the user locale.
+	// mantipov: *NOTE: be sure this code is synchronized with LLFriendCardsManager::findChildFolderUUID
+	//		it uses the same way to find localized string
+
+	// HACK: EXT - 6028 ([HARD CODED]? Inventory > Library > "Accessories" folder)
+	// Translation of Accessories folder in Library inventory folder
+	bool accessories = false;
+	if(getName() == "Accessories")
+	{
+		//To ensure that Accessories folder is in Library we have to check its parent folder.
+		//Due to parent LLFolderViewFloder is not set to this item yet we have to check its parent via Inventory Model
+		LLInventoryCategory* cat = gInventory.getCategory(getUUID());
+		if(cat)
+		{
+			const LLUUID& parent_folder_id = cat->getParentUUID();
+			accessories = (parent_folder_id == gInventory.getLibraryRootFolderID());
+		}
+	}
+
+	//"Accessories" inventory category has folder type FT_NONE. So, this folder
+	//can not be detected as protected with LLFolderType::lookupIsProtectedType
+	mDisplayName.assign(getName());
+	if (accessories || LLFolderType::lookupIsProtectedType(preferred_type))
+	{
+		LLTrans::findString(mDisplayName, std::string("InvFolder ") + getName(), LLSD());
+	}
+
+	mSearchableName.assign(mDisplayName);
+	mSearchableName.append(getLabelSuffix());
+	LLStringUtil::toUpper(mSearchableName);
+
+    //Name set, so trigger a sort
+    if(mParent)
+    {
+        mParent->requestSort();
+    }
+}
+
+
+void LLFolderBridge::update()
+{
+	bool possibly_has_children = false;
+	bool up_to_date = isUpToDate();
+	if(!up_to_date && hasChildren()) // we know we have children but  haven't  fetched them (doesn't obey filter)
+	{
+		possibly_has_children = true;
+	}
+
+	bool loading = (possibly_has_children
+		&& !up_to_date );
+
+	if (loading != mIsLoading)
+	{
+		if ( loading && !mIsLoading )
+		{
+			// Measure how long we've been in the loading state
+			mTimeSinceRequestStart.reset();
+		}
+
+		const BOOL in_inventory = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getRootFolderID());
+		const BOOL in_library = gInventory.isObjectDescendentOf(getUUID(),   gInventory.getLibraryRootFolderID());
+
+		bool root_is_loading = false;
+		if (in_inventory)
+		{
+			root_is_loading =   LLInventoryModelBackgroundFetch::instance().inventoryFetchInProgress();
+		}
+		if (in_library)
+		{
+			root_is_loading =   LLInventoryModelBackgroundFetch::instance().libraryFetchInProgress();
+		}
+		if ((mIsLoading
+				&&	mTimeSinceRequestStart.getElapsedTimeF32() >=   gSavedSettings.getF32("FolderLoadingMessageWaitTime"))
+			||	(LLInventoryModelBackgroundFetch::instance().folderFetchActive()
+				&&	root_is_loading))
+		{
+			mDisplayName = LLInvFVBridge::getDisplayName() + " ( " +   LLTrans::getString("LoadingData") + " ) ";
+			mIsLoading = true;
+		}
+		else
+		{
+			mDisplayName = LLInvFVBridge::getDisplayName();
+			mIsLoading = false;
+		}
+	}
+}
+
+
 // Iterate through a folder's children to determine if
 // all the children are removable.
 class LLIsItemRemovable : public LLFolderViewFunctor
@@ -1823,11 +1956,11 @@ class LLIsItemRemovable : public LLFolderViewFunctor
 	LLIsItemRemovable() : mPassed(TRUE) {}
 	virtual void doFolder(LLFolderViewFolder* folder)
 	{
-		mPassed &= folder->getListener()->isItemRemovable();
+		mPassed &= folder->getViewModelItem()->isItemRemovable();
 	}
 	virtual void doItem(LLFolderViewItem* item)
 	{
-		mPassed &= item->getListener()->isItemRemovable();
+		mPassed &= item->getViewModelItem()->isItemRemovable();
 	}
 	BOOL mPassed;
 };
@@ -1841,7 +1974,7 @@ BOOL LLFolderBridge::isItemRemovable() const
 	}
 
 	LLInventoryPanel* panel = mInventoryPanel.get();
-	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL);
+	LLFolderViewFolder* folderp = dynamic_cast<LLFolderViewFolder*>(panel ?   panel->getItemByID(mUUID) : NULL);
 	if (folderp)
 	{
 		LLIsItemRemovable folder_test;
@@ -2080,7 +2213,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 	LLInventoryPanel* destination_panel = mInventoryPanel.get();
 	if (!destination_panel) return false;
 
-	LLInventoryFilter* filter = destination_panel->getFilter();
+	LLInventoryFilter* filter = getInventoryFilter();
 	if (!filter) return false;
 
 	const LLUUID &cat_id = inv_cat->getUUID();
@@ -2299,7 +2432,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 				{
 					// Check whether the folder being dragged from active inventory panel
 					// passes the filter of the destination panel.
-					is_movable = check_category(model, cat_id, active_folder_view, filter);
+					is_movable = check_category(model, cat_id, active_panel, filter);
 				}
 			}
 		}
@@ -2373,7 +2506,7 @@ BOOL LLFolderBridge::dragCategoryIntoFolder(LLInventoryCategory* inv_cat,
 			}
 			else
 			{
-				if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+				if (model->isObjectDescendentOf(cat_id, model->findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
 				{
 					set_dad_inbox_object(cat_id);
 				}
@@ -2515,7 +2648,6 @@ BOOL move_inv_category_world_to_agent(const LLUUID& object_id,
 	if(drop && accept)
 	{
 		it = inventory_objects.begin();
-		LLInventoryObject::object_list_t::iterator first_it = inventory_objects.begin();
 		LLMoveInv* move_inv = new LLMoveInv;
 		move_inv->mObjectID = object_id;
 		move_inv->mCategoryID = category_id;
@@ -2551,7 +2683,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 		llwarns << "LLRightClickInventoryFetchDescendentsObserver::done with empty mCompleteFolders" << llendl;
 		if (clear_observer)
 		{
-		dec_busy_count();
 		gInventory.removeObserver(this);
 		delete this;
 		}
@@ -2565,7 +2696,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 	// could notify observers and throw us into an infinite loop.
 	if (clear_observer)
 	{
-		dec_busy_count();
 		gInventory.removeObserver(this);
 		delete this;
 	}
@@ -2636,7 +2766,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 	{
 				// it's all on its way - add an observer, and the inventory
 	// will call done for us when everything is here.
-				inc_busy_count();
 	gInventory.addObserver(outfit);
 			}
 			*/
@@ -2655,7 +2784,6 @@ void LLRightClickInventoryFetchDescendentsObserver::execute(bool clear_observer)
 			{
 				// it's all on its way - add an observer, and the inventory
 				// will call done for us when everything is here.
-				inc_busy_count();
 				gInventory.addObserver(categories);
 			}
 		}
@@ -2734,7 +2862,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 {
 	if ("open" == action)
 	{
-		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder *>(mRoot->getItemByID(mUUID));
+		LLFolderViewFolder *f = dynamic_cast<LLFolderViewFolder   *>(mInventoryPanel.get()->getItemByID(mUUID));
 		if (f)
 		{
 			f->setOpen(TRUE);
@@ -2781,10 +2909,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 	else if ("cut" == action)
 	{
 		cutToClipboard();
-		// MAINT-1197: This is temp code to work around a deselection/reselection bug. Please discard when merging CHUI.
-		LLFolderViewItem* item_to_select = mRoot->getNextUnselectedItem();
-		LLFolderView::removeCutItems();
-		mRoot->setSelection(item_to_select, item_to_select ? item_to_select->isOpen() : false, false);
+		gInventory.removeObject(mUUID);
 		return;
 	}
 	else if ("copy" == action)
@@ -2799,7 +2924,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 		LLViewerInventoryCategory* cat = getCategory();
 		if(!cat) return;
 
-		remove_inventory_category_from_avatar ( cat );
+		LLAppearanceMgr::instance().takeOffOutfit( cat->getLinkedUUID() );
 		return;
 	}
 	else if ("purge" == action)
@@ -2825,7 +2950,7 @@ void LLFolderBridge::performAction(LLInventoryModel* model, std::string action)
 		LLInventoryCategory * cat = gInventory.getCategory(mUUID);
 		if (!cat) return;
 
-		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = getInventoryModel()->findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		copy_folder_to_outbox(cat, outbox_id, cat->getUUID(), LLToolDragAndDrop::getOperationId());
 	}
 #if ENABLE_MERCHANT_SEND_TO_MARKETPLACE_CONTEXT_MENU
@@ -2921,17 +3046,24 @@ LLUIImagePtr LLFolderBridge::getIcon() const
 LLUIImagePtr LLFolderBridge::getIcon(LLFolderType::EType preferred_type)
 {
 	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(preferred_type, FALSE));
-		/*case LLAssetType::AT_MESH:
-			control = "inv_folder_mesh.tga";
-			break;*/
 }
 
-LLUIImagePtr LLFolderBridge::getOpenIcon() const
+LLUIImagePtr LLFolderBridge::getIconOpen() const
 {
 	return LLUI::getUIImage(LLViewerFolderType::lookupIconName(getPreferredType(), TRUE));
 
 }
 
+LLUIImagePtr LLFolderBridge::getIconOverlay() const
+{
+	if (getInventoryObject() && getInventoryObject()->getIsLinkType())
+	{
+		return LLUI::getUIImage("Inv_Link");
+	}
+	return NULL;
+}
+
+
 BOOL LLFolderBridge::renameItem(const std::string& new_name)
 {
 	rename_category(getInventoryModel(), mUUID, new_name);
@@ -2995,6 +3127,19 @@ bool LLFolderBridge::removeItemResponse(const LLSD& notification, const LLSD& re
 	return FALSE;
 }
 
+//Recursively update the folder's creation date
+void LLFolderBridge::updateHierarchyCreationDate(time_t date)
+{
+    if(getCreationDate() < date)
+    {
+        setCreationDate(date);
+        if(mParent)
+        {
+            static_cast<LLFolderBridge *>(mParent)->updateHierarchyCreationDate(date);
+        }
+    }
+}
+
 void LLFolderBridge::pasteFromClipboard()
 {
 	LLInventoryModel* model = getInventoryModel();
@@ -3012,7 +3157,7 @@ void LLFolderBridge::pasteFromClipboard()
 
 		if (move_is_into_outbox)
 		{
-			LLFolderViewItem * outbox_itemp = mRoot->getItemByID(mUUID);
+			LLFolderViewItem * outbox_itemp =   mInventoryPanel.get()->getItemByID(mUUID);
 
 			if (outbox_itemp)
 			{
@@ -3035,7 +3180,7 @@ void LLFolderBridge::pasteFromClipboard()
 						void * cargo_data = (void *) item;
 						std::string tooltip_msg;
 
-						can_list = outbox_itemp->getListener()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
+						can_list = outbox_itemp->getViewModelItem()->dragOrDrop(mask, drop, cargo_type, cargo_data, tooltip_msg);
 					}
 				}
 
@@ -3077,7 +3222,8 @@ void LLFolderBridge::pasteFromClipboard()
 						LLViewerInventoryCategory* vicat = (LLViewerInventoryCategory *) model->getCategory(item_id);
 						llassert(vicat);
 						if (vicat)
-						{
+						{       
+                            //changeCategoryParent() implicity calls dirtyFilter
 							changeCategoryParent(model, vicat, parent_id, FALSE);
 						}
 					}
@@ -3087,6 +3233,7 @@ void LLFolderBridge::pasteFromClipboard()
 					llassert(viitem);
 					if (viitem)
 					{
+                        //changeItemParent() implicity calls dirtyFilter
 						changeItemParent(model, viitem, parent_id, FALSE);
 					}
 				}
@@ -3207,7 +3354,7 @@ BOOL LLFolderBridge::checkFolderForContentsOfType(LLInventoryModel* model, LLInv
 	return ((item_array.count() > 0) ? TRUE : FALSE );
 }
 
-void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
+void LLFolderBridge::buildContextMenuOptions(U32 flags, menuentry_vec_t&   items, menuentry_vec_t& disabled_items)
 {
 	LLInventoryModel* model = getInventoryModel();
 	llassert(model != NULL);
@@ -3219,33 +3366,33 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 	if (lost_and_found_id == mUUID)
 	{
 		// This is the lost+found folder.
-		mItems.push_back(std::string("Empty Lost And Found"));
+		items.push_back(std::string("Empty Lost And Found"));
 
-		mDisabledItems.push_back(std::string("New Folder"));
-		mDisabledItems.push_back(std::string("New Script"));
-		mDisabledItems.push_back(std::string("New Note"));
-		mDisabledItems.push_back(std::string("New Gesture"));
-		mDisabledItems.push_back(std::string("New Clothes"));
-		mDisabledItems.push_back(std::string("New Body Parts"));
+		disabled_items.push_back(std::string("New Folder"));
+		disabled_items.push_back(std::string("New Script"));
+		disabled_items.push_back(std::string("New Note"));
+		disabled_items.push_back(std::string("New Gesture"));
+		disabled_items.push_back(std::string("New Clothes"));
+		disabled_items.push_back(std::string("New Body Parts"));
 	}
 	if (favorites == mUUID)
 	{
-		mDisabledItems.push_back(std::string("New Folder"));
+		disabled_items.push_back(std::string("New Folder"));
 	}
 	if(trash_id == mUUID)
 	{
 		// This is the trash.
-		mItems.push_back(std::string("Empty Trash"));
+		items.push_back(std::string("Empty Trash"));
 	}
 	else if(isItemInTrash())
 	{
 		// This is a folder in the trash.
-		mItems.clear(); // clear any items that used to exist
-		addTrashContextMenuOptions(mItems, mDisabledItems);
+		items.clear(); // clear any items that used to exist
+		addTrashContextMenuOptions(items, disabled_items);
 	}
 	else if(isOutboxFolder())
 	{
-		addOutboxContextMenuOptions(flags, mItems, mDisabledItems);
+		addOutboxContextMenuOptions(flags, items, disabled_items);
 	}
 	else if(isAgentInventory()) // do not allow creating in library
 	{
@@ -3259,40 +3406,40 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 				// Do not allow to create 2-level subfolder in the Calling Card/Friends folder. EXT-694.
 				if (!LLFriendCardsManager::instance().isCategoryInFriendFolder(cat))
 				{
-					mItems.push_back(std::string("New Folder"));
+					items.push_back(std::string("New Folder"));
 				}
 
-				mItems.push_back(std::string("New Script"));
-				mItems.push_back(std::string("New Note"));
-				mItems.push_back(std::string("New Gesture"));
-				mItems.push_back(std::string("New Clothes"));
-				mItems.push_back(std::string("New Body Parts"));
+				items.push_back(std::string("New Script"));
+				items.push_back(std::string("New Note"));
+				items.push_back(std::string("New Gesture"));
+				items.push_back(std::string("New Clothes"));
+				items.push_back(std::string("New Body Parts"));
 			}
 #if SUPPORT_ENSEMBLES
 			// Changing folder types is an unfinished unsupported feature
 			// and can lead to unexpected behavior if enabled.
-			mItems.push_back(std::string("Change Type"));
+			items.push_back(std::string("Change Type"));
 			const LLViewerInventoryCategory *cat = getCategory();
 			if (cat && LLFolderType::lookupIsProtectedType(cat->getPreferredType()))
 			{
-				mDisabledItems.push_back(std::string("Change Type"));
+				disabled_items.push_back(std::string("Change Type"));
 			}
 #endif
-			getClipboardEntries(false, mItems, mDisabledItems, flags);
+			getClipboardEntries(false, items, disabled_items, flags);
 		}
 		else
 		{
 			// Want some but not all of the items from getClipboardEntries for outfits.
 			if (cat && (cat->getPreferredType() == LLFolderType::FT_OUTFIT))
 			{
-				mItems.push_back(std::string("Rename"));
+				items.push_back(std::string("Rename"));
 
-				addDeleteContextMenuOptions(mItems, mDisabledItems);
+				addDeleteContextMenuOptions(items, disabled_items);
 				// EXT-4030: disallow deletion of currently worn outfit
 				const LLViewerInventoryItem *base_outfit_link = LLAppearanceMgr::instance().getBaseOutfitLink();
 				if (base_outfit_link && (cat == base_outfit_link->getLinkedCategory()))
 				{
-					mDisabledItems.push_back(std::string("Delete"));
+					disabled_items.push_back(std::string("Delete"));
 				}
 			}
 		}
@@ -3321,20 +3468,43 @@ void LLFolderBridge::buildContextMenuBaseOptions(U32 flags)
 	// Preemptively disable system folder removal if more than one item selected.
 	if ((flags & FIRST_SELECTED_ITEM) == 0)
 	{
-		mDisabledItems.push_back(std::string("Delete System Folder"));
+		disabled_items.push_back(std::string("Delete System Folder"));
 	}
 
 	if (!isOutboxFolder())
 	{
-		mItems.push_back(std::string("Share"));
+		items.push_back(std::string("Share"));
 		if (!canShare())
 		{
-			mDisabledItems.push_back(std::string("Share"));
+			disabled_items.push_back(std::string("Share"));
 		}
 	}
+	// Add menu items that are dependent on the contents of the folder.
+	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
+	if (category)
+	{
+		uuid_vec_t folders;
+		folders.push_back(category->getUUID());
+
+		sSelf = getHandle();
+		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
+		fetch->startFetch();
+		if (fetch->isFinished())
+		{
+			// Do not call execute() or done() here as if the folder is here, there's likely no point drilling down 
+			// This saves lots of time as buildContextMenu() is called a lot
+			delete fetch;
+			buildContextMenuFolderOptions(flags, items, disabled_items);
+		}
+		else
+		{
+			// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
+			gInventory.addObserver(fetch);
+	}
+}
 }
 
-void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
+void LLFolderBridge::buildContextMenuFolderOptions(U32 flags,   menuentry_vec_t& items, menuentry_vec_t& disabled_items)
 {
 	// Build folder specific options back up
 	LLInventoryModel* model = getInventoryModel();
@@ -3361,21 +3531,21 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 		LLIsType is_callingcard(LLAssetType::AT_CALLINGCARD);
 		if (mCallingCards || checkFolderForContentsOfType(model, is_callingcard))
 		{
-			mItems.push_back(std::string("Calling Card Separator"));
-			mItems.push_back(std::string("Conference Chat Folder"));
-			mItems.push_back(std::string("IM All Contacts In Folder"));
+			items.push_back(std::string("Calling Card Separator"));
+			items.push_back(std::string("Conference Chat Folder"));
+			items.push_back(std::string("IM All Contacts In Folder"));
 		}
 	}
 
 	if (!isItemRemovable())
 	{
-		mDisabledItems.push_back(std::string("Delete"));
+		disabled_items.push_back(std::string("Delete"));
 	}
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	if (LLFolderType::lookupIsProtectedType(type))
 	{
-		mItems.push_back(std::string("Delete System Folder"));
+		items.push_back(std::string("Delete System Folder"));
 	}
 #endif
 
@@ -3390,7 +3560,7 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 		checkFolderForContentsOfType(model, is_object) ||
 		checkFolderForContentsOfType(model, is_gesture) )
 	{
-		mItems.push_back(std::string("Folder Wearables Separator"));
+		items.push_back(std::string("Folder Wearables Separator"));
 
 		// Only enable add/replace outfit for non-system folders.
 		if (!is_system_folder)
@@ -3398,25 +3568,25 @@ void LLFolderBridge::buildContextMenuFolderOptions(U32 flags)
 			// Adding an outfit onto another (versus replacing) doesn't make sense.
 			if (type != LLFolderType::FT_OUTFIT)
 			{
-				mItems.push_back(std::string("Add To Outfit"));
+				items.push_back(std::string("Add To Outfit"));
 			}
 
-			mItems.push_back(std::string("Replace Outfit"));
+			items.push_back(std::string("Replace Outfit"));
 		}
 		if (is_ensemble)
 		{
-			mItems.push_back(std::string("Wear As Ensemble"));
+			items.push_back(std::string("Wear As Ensemble"));
 		}
-		mItems.push_back(std::string("Remove From Outfit"));
+		items.push_back(std::string("Remove From Outfit"));
 		if (!LLAppearanceMgr::getCanRemoveFromCOF(mUUID))
 		{
-			mDisabledItems.push_back(std::string("Remove From Outfit"));
+			disabled_items.push_back(std::string("Remove From Outfit"));
 		}
 		if (!LLAppearanceMgr::instance().getCanReplaceCOF(mUUID))
 		{
-			mDisabledItems.push_back(std::string("Replace Outfit"));
+			disabled_items.push_back(std::string("Replace Outfit"));
 		}
-		mItems.push_back(std::string("Outfit Separator"));
+		items.push_back(std::string("Outfit Separator"));
 	}
 }
 
@@ -3425,49 +3595,28 @@ void LLFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	sSelf.markDead();
 
-	mItems.clear();
-	mDisabledItems.clear();
+	// fetch contents of this folder, as context menu can depend on contents
+	// still, user would have to open context menu again to see the changes
+	gInventory.fetchDescendentsOf(getUUID());
+
+
+	menuentry_vec_t items;
+	menuentry_vec_t disabled_items;
 
 	lldebugs << "LLFolderBridge::buildContextMenu()" << llendl;
 
 	LLInventoryModel* model = getInventoryModel();
 	if(!model) return;
 
-	buildContextMenuBaseOptions(flags);
-
-	// Add menu items that are dependent on the contents of the folder.
-	LLViewerInventoryCategory* category = (LLViewerInventoryCategory *) model->getCategory(mUUID);
-	if (category)
-	{
-		uuid_vec_t folders;
-		folders.push_back(category->getUUID());
-
-		sSelf = getHandle();
-		LLRightClickInventoryFetchDescendentsObserver* fetch = new LLRightClickInventoryFetchDescendentsObserver(folders);
-		fetch->startFetch();
-		if (fetch->isFinished())
-		{
-			// Do not call execute() or done() here as if the folder is here, there's likely no point drilling down 
-			// This saves lots of time as buildContextMenu() is called a lot
-			delete fetch;
-			buildContextMenuFolderOptions(flags);
-		}
-		else
-		{
-			// it's all on its way - add an observer, and the inventory will call done for us when everything is here.
-			inc_busy_count();
-			gInventory.addObserver(fetch);
-		}
-	}
-
-	hide_context_entries(menu, mItems, mDisabledItems);
+	buildContextMenuOptions(flags, items, disabled_items);
+        hide_context_entries(menu, items, disabled_items);
 
 	// Reposition the menu, in case we're adding items to an existing menu.
 	menu.needsArrange();
 	menu.arrangeAndClear();
 }
 
-BOOL LLFolderBridge::hasChildren() const
+bool LLFolderBridge::hasChildren() const
 {
 	LLInventoryModel* model = getInventoryModel();
 	if(!model) return FALSE;
@@ -3557,25 +3706,6 @@ void LLFolderBridge::pasteClipboard(void* user_data)
 	if(self) self->pasteFromClipboard();
 }
 
-void LLFolderBridge::createNewCategory(void* user_data)
-{
-	LLFolderBridge* bridge = (LLFolderBridge*)user_data;
-	if(!bridge) return;
-	LLInventoryPanel* panel = bridge->mInventoryPanel.get();
-	if (!panel) return;
-	LLInventoryModel* model = panel->getModel();
-	if(!model) return;
-	LLUUID id;
-	id = model->createNewCategory(bridge->getUUID(),
-								  LLFolderType::FT_NONE,
-								  LLStringUtil::null);
-	model->notifyObservers();
-
-	// At this point, the bridge has probably been deleted, but the
-	// view is still there.
-	panel->setSelection(id, TAKE_FOCUS_YES);
-}
-
 void LLFolderBridge::createNewShirt(void* user_data)
 {
 	LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_SHIRT);
@@ -3641,6 +3771,24 @@ void LLFolderBridge::createNewEyes(void* user_data)
 	LLFolderBridge::createWearable((LLFolderBridge*)user_data, LLWearableType::WT_EYES);
 }
 
+EInventorySortGroup LLFolderBridge::getSortGroup() const
+{
+	LLFolderType::EType preferred_type = getPreferredType();
+
+	if (preferred_type == LLFolderType::FT_TRASH)
+	{
+		return SG_TRASH_FOLDER;
+	}
+
+	if(LLFolderType::lookupIsProtectedType(preferred_type))
+	{
+		return SG_SYSTEM_FOLDER;
+	}
+
+	return SG_NORMAL_FOLDER;
+}
+
+
 // static
 void LLFolderBridge::createWearable(LLFolderBridge* bridge, LLWearableType::EType type)
 {
@@ -3743,9 +3891,10 @@ void LLFolderBridge::dropToFavorites(LLInventoryItem* inv_item)
 	LLPointer<AddFavoriteLandmarkCallback> cb = new AddFavoriteLandmarkCallback();
 	LLInventoryPanel* panel = mInventoryPanel.get();
 	LLFolderViewItem* drag_over_item = panel ? panel->getRootFolder()->getDraggingOverItem() : NULL;
-	if (drag_over_item && drag_over_item->getListener())
+	LLFolderViewModelItemInventory* view_model = drag_over_item ? static_cast<LLFolderViewModelItemInventory*>(drag_over_item->getViewModelItem()) : NULL;
+	if (view_model)
 	{
-		cb.get()->setTargetLandmarkId(drag_over_item->getListener()->getUUID());
+		cb.get()->setTargetLandmarkId(view_model->getUUID());
 	}
 
 	copy_inventory_item(
@@ -3794,7 +3943,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 	LLInventoryPanel* destination_panel = mInventoryPanel.get();
 	if (!destination_panel) return false;
 
-	LLInventoryFilter* filter = destination_panel->getFilter();
+	LLInventoryFilter* filter = getInventoryFilter();
 	if (!filter) return false;
 
 	const LLUUID &current_outfit_id = model->findCategoryUUIDForType(LLFolderType::FT_CURRENT_OUTFIT, false);
@@ -3911,13 +4060,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 		// passes the filter of the destination panel.
 		if (accept && active_panel)
 		{
-			LLFolderView* active_folder_view = active_panel->getRootFolder();
-			if (!active_folder_view) return false;
-
-			LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+			LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 			if (!fv_item) return false;
 
-			accept = filter->check(fv_item);
+			accept = filter->check(fv_item->getViewModelItem());
 		}
 
 		if (accept && drop)
@@ -3929,6 +4075,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			}
 			// If an item is being dragged between windows, unselect everything in the active window 
 			// so that we don't follow the selection to its new location (which is very annoying).
+                        // RN: a better solution would be to deselect automatically when an   item is moved
+			// and then select any item that is dropped only in the panel that it   is dropped in
 			if (active_panel && (destination_panel != active_panel))
 				{
 					active_panel->unSelectAll();
@@ -3946,8 +4094,8 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 				if (itemp)
 				{
 					LLUUID srcItemId = inv_item->getUUID();
-					LLUUID destItemId = itemp->getListener()->getUUID();
-					gInventory.rearrangeFavoriteLandmarks(srcItemId, destItemId);
+					LLUUID destItemId = static_cast<LLFolderViewModelItemInventory*>(itemp->getViewModelItem())->getUUID();
+					LLFavoritesOrderStorage::instance().rearrangeFavoriteLandmarks(srcItemId, destItemId);
 				}
 			}
 
@@ -3979,7 +4127,7 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			else
 			{
 				// set up observer to select item once drag and drop from inbox is complete 
-				if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false)))
+				if (gInventory.isObjectDescendentOf(inv_item->getUUID(), gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false)))
 				{
 					set_dad_inbox_object(inv_item->getUUID());
 				}
@@ -4134,13 +4282,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 			// passes the filter of the destination panel.
 			if (accept && active_panel)
 			{
-				LLFolderView* active_folder_view = active_panel->getRootFolder();
-				if (!active_folder_view) return false;
-
-				LLFolderViewItem* fv_item = active_folder_view->getItemByID(inv_item->getUUID());
+				LLFolderViewItem* fv_item =   active_panel->getItemByID(inv_item->getUUID());
 				if (!fv_item) return false;
 
-				accept = filter->check(fv_item);
+				accept = filter->check(fv_item->getViewModelItem());
 			}
 
 			if (accept && drop)
@@ -4180,10 +4325,10 @@ BOOL LLFolderBridge::dragItemIntoFolder(LLInventoryItem* inv_item,
 // static
 bool check_category(LLInventoryModel* model,
 					const LLUUID& cat_id,
-					LLFolderView* active_folder_view,
+					LLInventoryPanel* active_panel,
 					LLInventoryFilter* filter)
 {
-	if (!model || !active_folder_view || !filter)
+	if (!model || !active_panel || !filter)
 		return false;
 
 	if (!filter->checkFolder(cat_id))
@@ -4203,13 +4348,13 @@ bool check_category(LLInventoryModel* model,
 		// Empty folder should be checked as any other folder view item.
 		// If we are filtering by date the folder should not pass because
 		// it doesn't have its own creation date. See LLInvFVBridge::getCreationDate().
-		return check_item(cat_id, active_folder_view, filter);
+		return check_item(cat_id, active_panel, filter);
 	}
 
 	for (S32 i = 0; i < num_descendent_categories; ++i)
 	{
 		LLInventoryCategory* category = descendent_categories[i];
-		if(!check_category(model, category->getUUID(), active_folder_view, filter))
+		if(!check_category(model, category->getUUID(), active_panel, filter))
 		{
 			return false;
 		}
@@ -4218,7 +4363,7 @@ bool check_category(LLInventoryModel* model,
 	for (S32 i = 0; i < num_descendent_items; ++i)
 	{
 		LLViewerInventoryItem* item = descendent_items[i];
-		if(!check_item(item->getUUID(), active_folder_view, filter))
+		if(!check_item(item->getUUID(), active_panel, filter))
 		{
 			return false;
 		}
@@ -4229,15 +4374,15 @@ bool check_category(LLInventoryModel* model,
 
 // static
 bool check_item(const LLUUID& item_id,
-				LLFolderView* active_folder_view,
+				LLInventoryPanel* active_panel,
 				LLInventoryFilter* filter)
 {
-	if (!active_folder_view || !filter) return false;
+	if (!active_panel || !filter) return false;
 
-	LLFolderViewItem* fv_item = active_folder_view->getItemByID(item_id);
+	LLFolderViewItem* fv_item = active_panel->getItemByID(item_id);
 	if (!fv_item) return false;
 
-	return filter->check(fv_item);
+	return filter->check(fv_item->getViewModelItem());
 }
 
 // +=================================================+
@@ -4339,15 +4484,6 @@ void LLSoundBridge::openItem()
 	}
 }
 
-void LLSoundBridge::previewItem()
-{
-	LLViewerInventoryItem* item = getItem();
-	if(item)
-	{
-		send_sound_trigger(item->getAssetUUID(), 1.0);
-	}
-}
-
 void LLSoundBridge::openSoundPreview(void* which)
 {
 	LLSoundBridge *me = (LLSoundBridge *)which;
@@ -4565,7 +4701,7 @@ LLCallingCardBridge::~LLCallingCardBridge()
 void LLCallingCardBridge::refreshFolderViewItem()
 {
 	LLInventoryPanel* panel = mInventoryPanel.get();
-	LLFolderViewItem* itemp = panel ? panel->getRootFolder()->getItemByID(mUUID) : NULL;
+	LLFolderViewItem* itemp = panel ? panel->getItemByID(mUUID) : NULL;
 	if (itemp)
 	{
 		itemp->refresh();
@@ -4581,19 +4717,16 @@ void LLCallingCardBridge::performAction(LLInventoryModel* model, std::string act
 		if (item && (item->getCreatorUUID() != gAgent.getID()) &&
 			(!item->getCreatorUUID().isNull()))
 		{
-			std::string callingcard_name;
-			gCacheName->getFullName(item->getCreatorUUID(), callingcard_name);
-			// IDEVO
+			std::string callingcard_name = LLCacheName::getDefaultName();
 			LLAvatarName av_name;
-			if (LLAvatarNameCache::useDisplayNames()
-				&& LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
+			if (LLAvatarNameCache::get(item->getCreatorUUID(), &av_name))
 			{
-				callingcard_name = av_name.mDisplayName + " (" + av_name.mUsername + ")";
+				callingcard_name = av_name.getCompleteName();
 			}
 			LLUUID session_id = gIMMgr->addSession(callingcard_name, IM_NOTHING_SPECIAL, item->getCreatorUUID());
 			if (session_id != LLUUID::null)
 			{
-				LLIMFloater::show(session_id);
+				LLFloaterIMContainer::getInstance()->showConversation(session_id);
 			}
 		}
 	}
@@ -5101,7 +5234,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -5118,11 +5251,7 @@ void LLObjectBridge::performAction(LLInventoryModel* model, std::string action)
 	}
 	else if (isRemoveAction(action))
 	{
-		LLInventoryItem* item = gInventory.getItem(mUUID);
-		if(item)
-		{
-			LLVOAvatarSelf::detachAttachmentIntoInventory(item->getLinkedUUID());
-		}
+		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
 	}
 	else LLItemBridge::performAction(model, action);
 }
@@ -5339,6 +5468,7 @@ void LLObjectBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 						p.on_enable.parameter = cbparams;
 						LLView* parent = attachment->getIsHUDAttachment() ? attach_hud_menu : attach_menu;
 						LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
+						items.push_back(p.name);
 					}
 				}
 			}
@@ -5360,11 +5490,10 @@ BOOL LLObjectBridge::renameItem(const std::string& new_name)
 	{
 		LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem(item);
 		new_item->rename(new_name);
-		buildDisplayName(new_item, mDisplayName);
 		new_item->updateServer(FALSE);
 		model->updateItem(new_item);
-
 		model->notifyObservers();
+		buildDisplayName();
 
 		if (isAgentAvatarValid())
 		{
@@ -5414,120 +5543,6 @@ LLWearableBridge::LLWearableBridge(LLInventoryPanel* inventory,
 	mInvType = inv_type;
 }
 
-void remove_inventory_category_from_avatar( LLInventoryCategory* category )
-{
-	if(!category) return;
-	lldebugs << "remove_inventory_category_from_avatar( " << category->getName()
-			 << " )" << llendl;
-
-
-	if (gAgentCamera.cameraCustomizeAvatar())
-	{
-		// switching to outfit editor should automagically save any currently edited wearable
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
-
-	remove_inventory_category_from_avatar_step2(TRUE, category->getUUID() );
-}
-
-struct OnRemoveStruct
-{
-	LLUUID mUUID;
-	OnRemoveStruct(const LLUUID& uuid):
-		mUUID(uuid)
-	{
-	}
-};
-
-void remove_inventory_category_from_avatar_step2( BOOL proceed, LLUUID category_id)
-{
-
-	// Find all the wearables that are in the category's subtree.
-	lldebugs << "remove_inventory_category_from_avatar_step2()" << llendl;
-	if(proceed)
-	{
-		LLInventoryModel::cat_array_t cat_array;
-		LLInventoryModel::item_array_t item_array;
-		LLFindWearables is_wearable;
-		gInventory.collectDescendentsIf(category_id,
-										cat_array,
-										item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_wearable);
-		S32 i;
-		S32 wearable_count = item_array.count();
-
-		LLInventoryModel::cat_array_t	obj_cat_array;
-		LLInventoryModel::item_array_t	obj_item_array;
-		LLIsType is_object( LLAssetType::AT_OBJECT );
-		gInventory.collectDescendentsIf(category_id,
-										obj_cat_array,
-										obj_item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_object);
-		S32 obj_count = obj_item_array.count();
-
-		// Find all gestures in this folder
-		LLInventoryModel::cat_array_t	gest_cat_array;
-		LLInventoryModel::item_array_t	gest_item_array;
-		LLIsType is_gesture( LLAssetType::AT_GESTURE );
-		gInventory.collectDescendentsIf(category_id,
-										gest_cat_array,
-										gest_item_array,
-										LLInventoryModel::EXCLUDE_TRASH,
-										is_gesture);
-		S32 gest_count = gest_item_array.count();
-
-		if (wearable_count > 0)	//Loop through wearables.  If worn, remove.
-		{
-			for(i = 0; i  < wearable_count; ++i)
-			{
-				LLViewerInventoryItem *item = item_array.get(i);
-				if (item->getType() == LLAssetType::AT_BODYPART)
-					continue;
-				if (gAgent.isTeen() && item->isWearableType() &&
-					(item->getWearableType() == LLWearableType::WT_UNDERPANTS || item->getWearableType() == LLWearableType::WT_UNDERSHIRT))
-					continue;
-				if (get_is_item_worn(item->getUUID()))
-				{
-					LLWearableList::instance().getAsset(item->getAssetUUID(),
-														item->getName(),
-														item->getType(),
-														LLWearableBridge::onRemoveFromAvatarArrived,
-														new OnRemoveStruct(item->getLinkedUUID()));
-				}
-			}
-		}
-
-		if (obj_count > 0)
-		{
-			for(i = 0; i  < obj_count; ++i)
-			{
-				LLViewerInventoryItem *obj_item = obj_item_array.get(i);
-				if (get_is_item_worn(obj_item->getUUID()))
-				{
-					LLVOAvatarSelf::detachAttachmentIntoInventory(obj_item->getLinkedUUID());
-				}
-			}
-		}
-
-		if (gest_count > 0)
-		{
-			for(i = 0; i  < gest_count; ++i)
-			{
-				LLViewerInventoryItem *gest_item = gest_item_array.get(i);
-				if (get_is_item_worn(gest_item->getUUID()))
-				{
-					LLGestureMgr::instance().deactivateGesture( gest_item->getLinkedUUID() );
-					gInventory.updateItem( gest_item );
-					gInventory.notifyObservers();
-				}
-
-			}
-		}
-	}
-}
-
 BOOL LLWearableBridge::renameItem(const std::string& new_name)
 {
 	if (get_is_item_worn(mUUID))
@@ -5738,7 +5753,7 @@ void LLWearableBridge::wearAddOnAvatar()
 }
 
 // static
-void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
 {
 	LLUUID* item_id = (LLUUID*) userdata;
 	if(wearable)
@@ -5764,7 +5779,7 @@ void LLWearableBridge::onWearOnAvatarArrived( LLWearable* wearable, void* userda
 
 // static
 // BAP remove the "add" code path once everything is fully COF-ified.
-void LLWearableBridge::onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata )
+void LLWearableBridge::onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata )
 {
 	LLUUID* item_id = (LLUUID*) userdata;
 	if(wearable)
@@ -5824,95 +5839,12 @@ BOOL LLWearableBridge::canRemoveFromAvatar(void* user_data)
 	return FALSE;
 }
 
-// static
-void LLWearableBridge::onRemoveFromAvatar(void* user_data)
-{
-	LLWearableBridge* self = (LLWearableBridge*)user_data;
-	if(!self) return;
-	if(get_is_item_worn(self->mUUID))
-	{
-		LLViewerInventoryItem* item = self->getItem();
-		if (item)
-		{
-			LLUUID parent_id = item->getParentUUID();
-			LLWearableList::instance().getAsset(item->getAssetUUID(),
-												item->getName(),
-												item->getType(),
-												onRemoveFromAvatarArrived,
-												new OnRemoveStruct(LLUUID(self->mUUID)));
-		}
-	}
-}
-
-// static
-void LLWearableBridge::onRemoveFromAvatarArrived(LLWearable* wearable,
-												 void* userdata)
-{
-	OnRemoveStruct *on_remove_struct = (OnRemoveStruct*) userdata;
-	const LLUUID &item_id = gInventory.getLinkedItemID(on_remove_struct->mUUID);
-	if(wearable)
-	{
-		if( get_is_item_worn( item_id ) )
-		{
-			LLWearableType::EType type = wearable->getType();
-
-			if( !(type==LLWearableType::WT_SHAPE || type==LLWearableType::WT_SKIN || type==LLWearableType::WT_HAIR || type==LLWearableType::WT_EYES ) ) //&&
-				//!((!gAgent.isTeen()) && ( type==LLWearableType::WT_UNDERPANTS || type==LLWearableType::WT_UNDERSHIRT )) )
-			{
-				bool do_remove_all = false;
-				U32 index = gAgentWearables.getWearableIndex(wearable);
-				gAgentWearables.removeWearable( type, do_remove_all, index );
-			}
-		}
-	}
-
-	// Find and remove this item from the COF.
-	LLAppearanceMgr::instance().removeCOFItemLinks(item_id,false);
-	gInventory.notifyObservers();
-
-	delete on_remove_struct;
-}
-
-// static
-void LLWearableBridge::removeAllClothesFromAvatar()
-{
-	// Fetch worn clothes (i.e. the ones in COF).
-	LLInventoryModel::item_array_t clothing_items;
-	LLInventoryModel::cat_array_t dummy;
-	LLIsType is_clothing(LLAssetType::AT_CLOTHING);
-	gInventory.collectDescendentsIf(LLAppearanceMgr::instance().getCOF(),
-									dummy,
-									clothing_items,
-									LLInventoryModel::EXCLUDE_TRASH,
-									is_clothing,
-									false);
-
-	// Take them off by removing from COF.
-	for (LLInventoryModel::item_array_t::const_iterator it = clothing_items.begin(); it != clothing_items.end(); ++it)
-	{
-		LLAppearanceMgr::instance().removeItemFromAvatar((*it)->getUUID());
-	}
-}
-
-// static
-void LLWearableBridge::removeItemFromAvatar(LLViewerInventoryItem *item)
-{
-	if (item)
-	{
-		LLWearableList::instance().getAsset(item->getAssetUUID(),
-											item->getName(),
-											item->getType(),
-											LLWearableBridge::onRemoveFromAvatarArrived,
-											new OnRemoveStruct(item->getUUID()));
-	}
-}
-
 void LLWearableBridge::removeFromAvatar()
 {
+	llwarns << "safe to remove?" << llendl;
 	if (get_is_item_worn(mUUID))
 	{
-		LLViewerInventoryItem* item = getItem();
-		removeItemFromAvatar(item);
+		LLAppearanceMgr::instance().removeItemFromAvatar(mUUID);
 	}
 }
 
@@ -5965,16 +5897,6 @@ void LLMeshBridge::openItem()
 	}
 }
 
-void LLMeshBridge::previewItem()
-{
-	LLViewerInventoryItem* item = getItem();
-	if(item)
-	{
-		// preview mesh
-	}
-}
-
-
 void LLMeshBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
 	lldebugs << "LLMeshBridge::buildContextMenu()" << llendl;
@@ -6063,14 +5985,15 @@ void LLLinkFolderBridge::gotoItem()
 	const LLUUID &cat_uuid = getFolderID();
 	if (!cat_uuid.isNull())
 	{
-		if (LLFolderViewItem *base_folder = mRoot->getItemByID(cat_uuid))
+		LLFolderViewItem *base_folder = mInventoryPanel.get()->getItemByID(cat_uuid);
+		if (base_folder)
 		{
 			if (LLInventoryModel* model = getInventoryModel())
 			{
 				model->fetchDescendentsOf(cat_uuid);
 			}
 			base_folder->setOpen(TRUE);
-			mRoot->setSelectionFromRoot(base_folder,TRUE);
+			mRoot->setSelection(base_folder,TRUE);
 			mRoot->scrollToShowSelection();
 		}
 	}
@@ -6401,9 +6324,8 @@ LLInvFVBridgeAction* LLInvFVBridgeAction::createAction(LLAssetType::EType asset_
 /************************************************************************/
 void LLRecentItemsFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
-	LLFolderBridge::buildContextMenu(menu, flags);
-
-	menuentry_vec_t disabled_items, items = getMenuItems();
+	menuentry_vec_t disabled_items, items;
+        buildContextMenuOptions(flags, items, disabled_items);
 
 	items.erase(std::remove(items.begin(), items.end(), std::string("New Folder")), items.end());
 
@@ -6415,42 +6337,29 @@ LLInvFVBridge* LLRecentInventoryBridgeBuilder::createBridge(
 	LLAssetType::EType actual_asset_type,
 	LLInventoryType::EType inv_type,
 	LLInventoryPanel* inventory,
+	LLFolderViewModelInventory* view_model,
 	LLFolderView* root,
 	const LLUUID& uuid,
 	U32 flags /*= 0x00*/ ) const
 {
 	LLInvFVBridge* new_listener = NULL;
-	switch(asset_type)
+	if (asset_type == LLAssetType::AT_CATEGORY 
+		&& actual_asset_type != LLAssetType::AT_LINK_FOLDER)
 	{
-	case LLAssetType::AT_CATEGORY:
-		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
+		new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
+	}
+	else
 		{
-			// *TODO: Create a link folder handler instead if it is necessary
-			new_listener = LLInventoryFVBridgeBuilder::createBridge(
-				asset_type,
+		new_listener = LLInventoryFolderViewModelBuilder::createBridge(asset_type,
 				actual_asset_type,
 				inv_type,
 				inventory,
+																view_model,
 				root,
 				uuid,
 				flags);
-			break;
 		}
-		new_listener = new LLRecentItemsFolderBridge(inv_type, inventory, root, uuid);
-		break;
-	default:
-		new_listener = LLInventoryFVBridgeBuilder::createBridge(
-			asset_type,
-			actual_asset_type,
-			inv_type,
-			inventory,
-			root,
-			uuid,
-			flags);
-	}
 	return new_listener;
-
 }
 
-
 // EOF
diff --git a/indra/newview/llinventorybridge.h b/indra/newview/llinventorybridge.h
index 118430efe124acf3629f7c619ce639da9081a012..517153e1710c440955989e411b3e7ac3d75bcec4 100644
--- a/indra/newview/llinventorybridge.h
+++ b/indra/newview/llinventorybridge.h
@@ -29,11 +29,13 @@
 
 #include "llcallingcard.h"
 #include "llfloaterproperties.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventorymodel.h"
 #include "llinventoryobserver.h"
+#include "llinventorypanel.h"
 #include "llviewercontrol.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
+#include "lltooldraganddrop.h"
 
 class LLInventoryFilter;
 class LLInventoryPanel;
@@ -41,7 +43,7 @@ class LLInventoryModel;
 class LLMenuGL;
 class LLCallingCardObserver;
 class LLViewerJointAttachment;
-
+class LLFolderView;
 
 typedef std::vector<std::string> menuentry_vec_t;
 
@@ -56,7 +58,7 @@ typedef std::vector<std::string> menuentry_vec_t;
 // functionality a bit. (except for folders, you can create those
 // manually...)
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInvFVBridge : public LLFolderViewEventListener
+class LLInvFVBridge : public LLFolderViewModelItemInventory
 {
 public:
 	// This method is a convenience function which creates the correct
@@ -65,6 +67,7 @@ class LLInvFVBridge : public LLFolderViewEventListener
 									   LLAssetType::EType actual_asset_type,
 									   LLInventoryType::EType inv_type,
 									   LLInventoryPanel* inventory,
+									   LLFolderViewModelInventory* view_model,
 									   LLFolderView* root,
 									   const LLUUID& uuid,
 									   U32 flags = 0x00);
@@ -78,23 +81,25 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	// LLInvFVBridge functionality
 	//--------------------------------------------------------------------
 	virtual const LLUUID& getUUID() const { return mUUID; }
-	virtual void clearDisplayName() {}
+	virtual void clearDisplayName() { mDisplayName.clear(); }
 	virtual void restoreItem() {}
 	virtual void restoreToWorld() {}
 
 	//--------------------------------------------------------------------
-	// Inherited LLFolderViewEventListener functions
+	// Inherited LLFolderViewModelItemInventory functions
 	//--------------------------------------------------------------------
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
+	const std::string& getSearchableName() const { return mSearchableName; }
+
 	virtual PermissionMask getPermissionMask() const;
 	virtual LLFolderType::EType getPreferredType() const;
 	virtual time_t getCreationDate() const;
+        virtual void setCreationDate(time_t creation_date_utc);
 	virtual LLFontGL::StyleFlags getLabelStyle() const { return LLFontGL::NORMAL; }
 	virtual std::string getLabelSuffix() const { return LLStringUtil::null; }
 	virtual void openItem() {}
 	virtual void closeItem() {}
-	virtual void previewItem() {openItem();}
 	virtual void showProperties();
 	virtual BOOL isItemRenameable() const { return TRUE; }
 	//virtual BOOL renameItem(const std::string& new_name) {}
@@ -102,9 +107,10 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	virtual BOOL isItemMovable() const;
 	virtual BOOL isItemInTrash() const;
 	virtual BOOL isLink() const;
+	virtual BOOL isLibraryItem() const;
 	//virtual BOOL removeItem() = 0;
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
-	virtual void move(LLFolderViewEventListener* new_parent_bridge) {}
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+	virtual void move(LLFolderViewModelItem* new_parent_bridge) {}
 	virtual BOOL isItemCopyable() const { return FALSE; }
 	virtual BOOL copyToClipboard() const;
 	virtual BOOL cutToClipboard() const;
@@ -115,6 +121,7 @@ class LLInvFVBridge : public LLFolderViewEventListener
 	void getClipboardEntries(bool show_asset_id, menuentry_vec_t &items, 
 							 menuentry_vec_t &disabled_items, U32 flags);
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
+    virtual LLToolDragAndDrop::ESource getDragSource() const;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -122,6 +129,9 @@ class LLInvFVBridge : public LLFolderViewEventListener
 							std::string& tooltip_msg) { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return mInvType; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+        EInventorySortGroup getSortGroup()  const { return SG_ITEM; }
+	virtual LLInventoryObject* getInventoryObject() const;
+
 
 	//--------------------------------------------------------------------
 	// Convenience functions for adding various common menu options.
@@ -138,16 +148,16 @@ class LLInvFVBridge : public LLFolderViewEventListener
 protected:
 	LLInvFVBridge(LLInventoryPanel* inventory, LLFolderView* root, const LLUUID& uuid);
 
-	LLInventoryObject* getInventoryObject() const;
 	LLInventoryModel* getInventoryModel() const;
+	LLInventoryFilter* getInventoryFilter() const;
 	
 	BOOL isLinkedObjectInTrash() const; // Is this obj or its baseobj in the trash?
 	BOOL isLinkedObjectMissing() const; // Is this a linked obj whose baseobj is not in inventory?
 
 	BOOL isAgentInventory() const; // false if lost or in the inventory library
-	BOOL isCOFFolder() const; // true if COF or descendent of
-	BOOL isInboxFolder() const; // true if COF or descendent of marketplace inbox
-	BOOL isOutboxFolder() const; // true if COF or descendent of marketplace outbox
+	BOOL isCOFFolder() const;       // true if COF or descendant of
+	BOOL isInboxFolder() const;     // true if COF or descendant of   marketplace inbox
+	BOOL isOutboxFolder() const;    // true if COF or descendant of   marketplace outbox
 	BOOL isOutboxFolderDirectParent() const;
 	const LLUUID getOutboxFolder() const;
 
@@ -160,30 +170,36 @@ class LLInvFVBridge : public LLFolderViewEventListener
 									 LLViewerInventoryCategory* item,
 									 const LLUUID& new_parent,
 									 BOOL restamp);
-	void removeBatchNoCheck(LLDynamicArray<LLFolderViewEventListener*>& batch);
+	void removeBatchNoCheck(std::vector<LLFolderViewModelItem*>& batch);
 protected:
 	LLHandle<LLInventoryPanel> mInventoryPanel;
 	LLFolderView* mRoot;
 	const LLUUID mUUID;	// item id
 	LLInventoryType::EType mInvType;
-	BOOL mIsLink;
+	bool						mIsLink;
+	LLTimer						mTimeSinceRequestStart;
+	mutable std::string			mDisplayName;
+	mutable std::string			mSearchableName;
+
 	void purgeItem(LLInventoryModel *model, const LLUUID &uuid);
+	virtual void buildDisplayName() const {}
 };
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLInvFVBridgeBuilder
+// Class LLInventoryFolderViewModelBuilder
 //
-// This class intended to build Folder View Bridge via LLInvFVBridge::createBridge.
-// It can be overridden with another way of creation necessary Inventory-Folder-View-Bridge.
+// This class intended to build Folder View Model via LLInvFVBridge::createBridge.
+// It can be overridden with another way of creation necessary Inventory Folder View Models.
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLInventoryFVBridgeBuilder
+class LLInventoryFolderViewModelBuilder
 {
 public:
- 	virtual ~LLInventoryFVBridgeBuilder() {}
+ 	virtual ~LLInventoryFolderViewModelBuilder() {}
 	virtual LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
 										LLAssetType::EType actual_asset_type,
 										LLInventoryType::EType inv_type,
 										LLInventoryPanel* inventory,
+										LLFolderViewModelInventory* view_model,
 										LLFolderView* root,
 										const LLUUID& uuid,
 										U32 flags = 0x00) const;
@@ -205,7 +221,6 @@ class LLItemBridge : public LLInvFVBridge
 	virtual void restoreToWorld();
 	virtual void gotoItem();
 	virtual LLUIImagePtr getIcon() const;
-	virtual const std::string& getDisplayName() const;
 	virtual std::string getLabelSuffix() const;
 	virtual LLFontGL::StyleFlags getLabelStyle() const;
 	virtual PermissionMask getPermissionMask() const;
@@ -214,18 +229,17 @@ class LLItemBridge : public LLInvFVBridge
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL removeItem();
 	virtual BOOL isItemCopyable() const;
-	virtual BOOL hasChildren() const { return FALSE; }
+	virtual bool hasChildren() const { return FALSE; }
 	virtual BOOL isUpToDate() const { return TRUE; }
-	/*virtual*/ void clearDisplayName() { mDisplayName.clear(); }
+	virtual LLUIImagePtr getIconOverlay() const;
 
 	LLViewerInventoryItem* getItem() const;
 
 protected:
 	BOOL confirmRemoveItem(const LLSD& notification, const LLSD& response);
 	virtual BOOL isItemPermissive() const;
-	static void buildDisplayName(LLInventoryItem* item, std::string& name);
+	virtual void buildDisplayName() const;
 
-	mutable std::string mDisplayName;
 };
 
 class LLFolderBridge : public LLInvFVBridge
@@ -233,15 +247,18 @@ class LLFolderBridge : public LLInvFVBridge
 public:
 	LLFolderBridge(LLInventoryPanel* inventory, 
 				   LLFolderView* root,
-				   const LLUUID& uuid) :
-		LLInvFVBridge(inventory, root, uuid),
+				   const LLUUID& uuid) 
+        :       LLInvFVBridge(inventory, root, uuid),
 		mCallingCards(FALSE),
-		mWearables(FALSE)
+		mWearables(FALSE),
+		mIsLoading(false)
 	{}
 		
 	BOOL dragItemIntoFolder(LLInventoryItem* inv_item, BOOL drop, std::string& tooltip_msg);
 	BOOL dragCategoryIntoFolder(LLInventoryCategory* inv_category, BOOL drop, std::string& tooltip_msg);
 
+    virtual void buildDisplayName() const;
+
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual void openItem();
 	virtual void closeItem();
@@ -251,7 +268,9 @@ class LLFolderBridge : public LLInvFVBridge
 
 	virtual LLFolderType::EType getPreferredType() const;
 	virtual LLUIImagePtr getIcon() const;
-	virtual LLUIImagePtr getOpenIcon() const;
+	virtual LLUIImagePtr getIconOpen() const;
+	virtual LLUIImagePtr getIconOverlay() const;
+
 	static LLUIImagePtr getIcon(LLFolderType::EType preferred_type);
 
 	virtual BOOL renameItem(const std::string& new_name);
@@ -259,11 +278,12 @@ class LLFolderBridge : public LLInvFVBridge
 	virtual BOOL removeItem();
 	BOOL removeSystemFolder();
 	bool removeItemResponse(const LLSD& notification, const LLSD& response);
+    void updateHierarchyCreationDate(time_t date);
 
 	virtual void pasteFromClipboard();
 	virtual void pasteLinkFromClipboard();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-	virtual BOOL hasChildren() const;
+	virtual bool hasChildren() const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
 							void* cargo_data,
@@ -276,20 +296,24 @@ class LLFolderBridge : public LLInvFVBridge
 	virtual BOOL isClipboardPasteable() const;
 	virtual BOOL isClipboardPasteableAsLink() const;
 	
+	EInventorySortGroup getSortGroup()  const;
+	virtual void update();
+
 	static void createWearable(LLFolderBridge* bridge, LLWearableType::EType type);
 
 	LLViewerInventoryCategory* getCategory() const;
 	LLHandle<LLFolderBridge> getHandle() { mHandle.bind(this); return mHandle; }
 
+	bool isLoading() { return mIsLoading; }
+
 protected:
-	void buildContextMenuBaseOptions(U32 flags);
-	void buildContextMenuFolderOptions(U32 flags);
+	void buildContextMenuOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
+	void buildContextMenuFolderOptions(U32 flags, menuentry_vec_t& items,   menuentry_vec_t& disabled_items);
 
 	//--------------------------------------------------------------------
 	// Menu callbacks
 	//--------------------------------------------------------------------
 	static void pasteClipboard(void* user_data);
-	static void createNewCategory(void* user_data);
 	static void createNewShirt(void* user_data);
 	static void createNewPants(void* user_data);
 	static void createNewShoes(void* user_data);
@@ -309,8 +333,6 @@ class LLFolderBridge : public LLInvFVBridge
 	void modifyOutfit(BOOL append);
 	void determineFolderType();
 
-	menuentry_vec_t getMenuItems() { return mItems; } // returns a copy of current menu items
-
 	void dropToFavorites(LLInventoryItem* inv_item);
 	void dropToOutfit(LLInventoryItem* inv_item, BOOL move_is_into_current_outfit);
 
@@ -322,10 +344,11 @@ class LLFolderBridge : public LLInvFVBridge
 	static void staticFolderOptionsMenu();
 
 private:
-	BOOL				mCallingCards;
-	BOOL				mWearables;
-	menuentry_vec_t		mItems;
-	menuentry_vec_t		mDisabledItems;
+
+	bool							mCallingCards;
+	bool							mWearables;
+	bool							mIsLoading;
+	LLTimer							mTimeSinceRequestStart;
 	LLRootHandle<LLFolderBridge> mHandle;
 };
 
@@ -355,7 +378,6 @@ class LLSoundBridge : public LLItemBridge
 				  const LLUUID& uuid) :
 		LLItemBridge(inventory, root, uuid) {}
 	virtual void openItem();
-	virtual void previewItem();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 	static void openSoundPreview(void*);
 };
@@ -487,10 +509,10 @@ class LLWearableBridge : public LLItemBridge
 
 	static void		onWearOnAvatar( void* userdata );	// Access to wearOnAvatar() from menu
 	static BOOL		canWearOnAvatar( void* userdata );
-	static void		onWearOnAvatarArrived( LLWearable* wearable, void* userdata );
+	static void		onWearOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearOnAvatar();
 
-	static void		onWearAddOnAvatarArrived( LLWearable* wearable, void* userdata );
+	static void		onWearAddOnAvatarArrived( LLViewerWearable* wearable, void* userdata );
 	void			wearAddOnAvatar();
 
 	static BOOL		canEditOnAvatar( void* userdata );	// Access to editOnAvatar() from menu
@@ -498,9 +520,6 @@ class LLWearableBridge : public LLItemBridge
 	void			editOnAvatar();
 
 	static BOOL		canRemoveFromAvatar( void* userdata );
-	static void		onRemoveFromAvatar( void* userdata );
-	static void		onRemoveFromAvatarArrived( LLWearable* wearable, 	void* userdata );
-	static void 	removeItemFromAvatar(LLViewerInventoryItem *item);
 	static void 	removeAllClothesFromAvatar();
 	void			removeFromAvatar();
 protected:
@@ -545,7 +564,6 @@ class LLMeshBridge : public LLItemBridge
 public:
 	virtual LLUIImagePtr getIcon() const;
 	virtual void openItem();
-	virtual void previewItem();
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 
 protected:
@@ -621,7 +639,7 @@ class LLRecentItemsFolderBridge : public LLFolderBridge
 };
 
 // Bridge builder to create Inventory-Folder-View-Bridge for Recent Inventory Panel
-class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLRecentInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
 {
 public:
 	// Overrides FolderBridge for Recent Inventory Panel.
@@ -630,6 +648,7 @@ class LLRecentInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
 		LLAssetType::EType actual_asset_type,
 		LLInventoryType::EType inv_type,
 		LLInventoryPanel* inventory,
+		LLFolderViewModelInventory* view_model,
 		LLFolderView* root,
 		const LLUUID& uuid,
 		U32 flags = 0x00) const;
diff --git a/indra/newview/llinventoryfilter.cpp b/indra/newview/llinventoryfilter.cpp
index 4573074c7322683f533427032cb39f3adb8a5754..92f2d33073ec8ea029f7b9d5095f47d30cebca97 100644
--- a/indra/newview/llinventoryfilter.cpp
+++ b/indra/newview/llinventoryfilter.cpp
@@ -29,7 +29,7 @@
 #include "llinventoryfilter.h"
 
 // viewer includes
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llfolderviewitem.h"
 #include "llinventorymodel.h"
 #include "llinventorymodelbackgroundfetch.h"
@@ -44,107 +44,86 @@
 
 LLFastTimer::DeclareTimer FT_FILTER_CLIPBOARD("Filter Clipboard");
 
-LLInventoryFilter::FilterOps::FilterOps() :
-	mFilterObjectTypes(0xffffffffffffffffULL),
-	mFilterCategoryTypes(0xffffffffffffffffULL),
-	mFilterWearableTypes(0xffffffffffffffffULL),
-	mMinDate(time_min()),
-	mMaxDate(time_max()),
-	mHoursAgo(0),
-	mShowFolderState(SHOW_NON_EMPTY_FOLDERS),
-	mPermissions(PERM_NONE),
-	mFilterTypes(FILTERTYPE_OBJECT),
-	mFilterUUID(LLUUID::null),
-	mFilterLinks(FILTERLINK_INCLUDE_LINKS)
+LLInventoryFilter::FilterOps::FilterOps(const Params& p)
+:	mFilterObjectTypes(p.object_types),
+	mFilterCategoryTypes(p.category_types),
+	mFilterWearableTypes(p.wearable_types),
+	mMinDate(p.date_range.min_date),
+	mMaxDate(p.date_range.max_date),
+	mHoursAgo(p.hours_ago),
+	mShowFolderState(p.show_folder_state),
+	mPermissions(p.permissions),
+	mFilterTypes(p.types),
+	mFilterUUID(p.uuid),
+	mFilterLinks(p.links)
 {
 }
 
 ///----------------------------------------------------------------------------
 /// Class LLInventoryFilter
 ///----------------------------------------------------------------------------
-LLInventoryFilter::LLInventoryFilter(const std::string& name)
-:	mName(name),
-	mModified(FALSE),
-	mNeedTextRebuild(TRUE),
-	mEmptyLookupMessage("InventoryNoMatchingItems")
+LLInventoryFilter::LLInventoryFilter(const Params& p)
+:	mName(p.name),
+	mFilterModified(FILTER_NONE),
+	mEmptyLookupMessage("InventoryNoMatchingItems"),
+    mFilterOps(p.filter_ops),
+	mFilterSubString(p.substring),
+	mCurrentGeneration(0),
+	mFirstRequiredGeneration(0),
+	mFirstSuccessGeneration(0),
+	mFilterCount(0)
 {
-	mOrder = SO_FOLDERS_BY_NAME; // This gets overridden by a pref immediately
-
-	mSubStringMatchOffset = 0;
-	mFilterSubString.clear();
-	mFilterGeneration = 0;
-	mMustPassGeneration = S32_MAX;
-	mMinRequiredGeneration = 0;
-	mFilterCount = 0;
-	mNextFilterGeneration = mFilterGeneration + 1;
-
-	mLastLogoff = gSavedPerAccountSettings.getU32("LastLogoff");
-	mFilterBehavior = FILTER_NONE;
+	mNextFilterGeneration = mCurrentGeneration + 1;
 
 	// copy mFilterOps into mDefaultFilterOps
 	markDefault();
 }
 
-LLInventoryFilter::~LLInventoryFilter()
-{
-}
-
-BOOL LLInventoryFilter::check(const LLFolderViewItem* item) 
+bool LLInventoryFilter::check(const LLFolderViewModelItem* item) 
 {
+	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
 	// Clipboard cut items are *always* filtered so we need this value upfront
-	const LLFolderViewEventListener* listener = item->getListener();
 	const BOOL passed_clipboard = (listener ? checkAgainstClipboard(listener->getUUID()) : TRUE);
 
 	// If it's a folder and we're showing all folders, return automatically.
-	const BOOL is_folder = (dynamic_cast<const LLFolderViewFolder*>(item) != NULL);
+	const BOOL is_folder = listener->getInventoryType() == LLInventoryType::IT_CATEGORY;
 	if (is_folder && (mFilterOps.mShowFolderState == LLInventoryFilter::SHOW_ALL_FOLDERS))
 	{
 		return passed_clipboard;
 	}
 
-	mSubStringMatchOffset = mFilterSubString.size() ? item->getSearchableLabel().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ? listener->getSearchableName().find(mFilterSubString) : std::string::npos;
 
-	const BOOL passed_filtertype = checkAgainstFilterType(item);
-	const BOOL passed_permissions = checkAgainstPermissions(item);
-	const BOOL passed_filterlink = checkAgainstFilterLinks(item);
-	const BOOL passed = (passed_filtertype &&
-						 passed_permissions &&
-						 passed_filterlink &&
-						 passed_clipboard &&
-						 (mFilterSubString.size() == 0 || mSubStringMatchOffset != std::string::npos));
+	BOOL passed = (mFilterSubString.size() == 0 || string_offset != std::string::npos);
+	passed = passed && checkAgainstFilterType(listener);
+	passed = passed && checkAgainstPermissions(listener);
+	passed = passed && checkAgainstFilterLinks(listener);
+	passed = passed && passed_clipboard;
 
 	return passed;
 }
 
 bool LLInventoryFilter::check(const LLInventoryItem* item)
 {
-	mSubStringMatchOffset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
+	std::string::size_type string_offset = mFilterSubString.size() ? item->getName().find(mFilterSubString) : std::string::npos;
 
 	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 || mSubStringMatchOffset != std::string::npos));
+	const bool passed = (passed_filtertype 
+		&& passed_permissions
+		&& passed_clipboard 
+		&&	(mFilterSubString.size() == 0 || string_offset != std::string::npos));
 
 	return passed;
 }
 
-bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
+bool LLInventoryFilter::checkFolder(const LLFolderViewModelItem* item) const
 {
-	if (!folder)
-	{
-		llwarns << "The filter can not be checked on an invalid folder." << llendl;
-		llassert(false); // crash in development builds
-		return false;
-	}
-
-	const LLFolderViewEventListener* listener = folder->getListener();
+	const LLFolderViewModelItemInventory* listener = dynamic_cast<const LLFolderViewModelItemInventory*>(item);
 	if (!listener)
 	{
-		llwarns << "Folder view event listener not found." << llendl;
-		llassert(false); // crash in development builds
+		llerrs << "Folder view event listener not found." << llendl;
 		return false;
 	}
 
@@ -155,6 +134,13 @@ bool LLInventoryFilter::checkFolder(const LLFolderViewFolder* folder) const
 
 bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 {
+	// when applying a filter, matching folders get their contents downloaded first
+	if (isNotDefault()
+		&& !gInventory.isCategoryComplete(folder_id))
+	{
+		LLInventoryModelBackgroundFetch::instance().start(folder_id);
+	}
+
 	// Always check against the clipboard
 	const BOOL passed_clipboard = checkAgainstClipboard(folder_id);
 	
@@ -163,14 +149,14 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	{
 		return passed_clipboard;
 	}
-
+	
 	if (mFilterOps.mFilterTypes & FILTERTYPE_CATEGORY)
 	{
 		// Can only filter categories for items in your inventory
 		// (e.g. versus in-world object contents).
 		const LLViewerInventoryCategory *cat = gInventory.getCategory(folder_id);
 		if (!cat)
-			return false;
+			return folder_id.isNull();
 		LLFolderType::EType cat_type = cat->getPreferredType();
 		if (cat_type != LLFolderType::FT_NONE && (1LL << cat_type & mFilterOps.mFilterCategoryTypes) == U64(0))
 			return false;
@@ -179,9 +165,8 @@ bool LLInventoryFilter::checkFolder(const LLUUID& folder_id) const
 	return passed_clipboard;
 }
 
-BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterType(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
 	if (!listener) return FALSE;
 
 	LLInventoryType::EType object_type = listener->getInventoryType();
@@ -268,7 +253,7 @@ BOOL LLInventoryFilter::checkAgainstFilterType(const LLFolderViewItem* item) con
 			}
 		}
 	}
-
+	
 	return TRUE;
 }
 
@@ -347,13 +332,12 @@ bool LLInventoryFilter::checkAgainstClipboard(const LLUUID& object_id) const
 	return true;
 }
 
-BOOL LLInventoryFilter::checkAgainstPermissions(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstPermissions(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
 	if (!listener) return FALSE;
 
 	PermissionMask perm = listener->getPermissionMask();
-	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(item->getListener());
+	const LLInvFVBridge *bridge = dynamic_cast<const LLInvFVBridge *>(listener);
 	if (bridge && bridge->isLink())
 	{
 		const LLUUID& linked_uuid = gInventory.getLinkedItemID(bridge->getUUID());
@@ -375,9 +359,8 @@ bool LLInventoryFilter::checkAgainstPermissions(const LLInventoryItem* item) con
 	return (perm & mFilterOps.mPermissions) == mFilterOps.mPermissions;
 }
 
-BOOL LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewItem* item) const
+bool LLInventoryFilter::checkAgainstFilterLinks(const LLFolderViewModelItemInventory* listener) const
 {
-	const LLFolderViewEventListener* listener = item->getListener();
 	if (!listener) return TRUE;
 
 	const LLUUID object_id = listener->getUUID();
@@ -397,20 +380,20 @@ const std::string& LLInventoryFilter::getFilterSubString(BOOL trim) const
 	return mFilterSubString;
 }
 
-std::string::size_type LLInventoryFilter::getStringMatchOffset() const
+std::string::size_type LLInventoryFilter::getStringMatchOffset(LLFolderViewModelItem* item) const
 {
-	return mSubStringMatchOffset;
+	return mFilterSubString.size() ? item->getSearchableName().find(mFilterSubString) : std::string::npos;
 }
 
-BOOL LLInventoryFilter::isDefault() const
+bool LLInventoryFilter::isDefault() const
 {
 	return !isNotDefault();
 }
 
 // has user modified default filter params?
-BOOL LLInventoryFilter::isNotDefault() const
+bool LLInventoryFilter::isNotDefault() const
 {
-	BOOL not_default = FALSE;
+	S32 not_default = 0;
 
 	not_default |= (mFilterOps.mFilterObjectTypes != mDefaultFilterOps.mFilterObjectTypes);
 	not_default |= (mFilterOps.mFilterCategoryTypes != mDefaultFilterOps.mFilterCategoryTypes);
@@ -422,11 +405,11 @@ BOOL LLInventoryFilter::isNotDefault() const
 	not_default |= (mFilterOps.mMinDate != mDefaultFilterOps.mMinDate);
 	not_default |= (mFilterOps.mMaxDate != mDefaultFilterOps.mMaxDate);
 	not_default |= (mFilterOps.mHoursAgo != mDefaultFilterOps.mHoursAgo);
-	
-	return not_default;
+
+	return not_default != 0;
 }
 
-BOOL LLInventoryFilter::isActive() const
+bool LLInventoryFilter::isActive() const
 {
 	return mFilterOps.mFilterObjectTypes != 0xffffffffffffffffULL
 		|| mFilterOps.mFilterCategoryTypes != 0xffffffffffffffffULL
@@ -440,16 +423,9 @@ BOOL LLInventoryFilter::isActive() const
 		|| mFilterOps.mHoursAgo != 0;
 }
 
-BOOL LLInventoryFilter::isModified() const
-{
-	return mModified;
-}
-
-BOOL LLInventoryFilter::isModifiedAndClear()
+bool LLInventoryFilter::isModified() const
 {
-	BOOL ret = mModified;
-	mModified = FALSE;
-	return ret;
+	return mFilterModified != FILTER_NONE;
 }
 
 void LLInventoryFilter::updateFilterTypes(U64 types, U64& current_types)
@@ -613,9 +589,10 @@ void LLInventoryFilter::setDateRange(time_t min_date, time_t max_date)
 
 void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 {
+	static LLCachedControl<U32> s_last_logoff(gSavedPerAccountSettings, "LastLogoff", 0);
 	if (sl && !isSinceLogoff())
 	{
-		setDateRange(mLastLogoff, time_max());
+		setDateRange(s_last_logoff(), time_max());
 		setModified();
 	}
 	if (!sl && isSinceLogoff())
@@ -634,17 +611,18 @@ void LLInventoryFilter::setDateRangeLastLogoff(BOOL sl)
 	}
 }
 
-BOOL LLInventoryFilter::isSinceLogoff() const
+bool LLInventoryFilter::isSinceLogoff() const
 {
-	return (mFilterOps.mMinDate == (time_t)mLastLogoff) &&
+	static LLCachedControl<U32> s_last_logoff(gSavedSettings, "LastLogoff", 0);
+
+	return (mFilterOps.mMinDate == (time_t)s_last_logoff()) &&
 		(mFilterOps.mMaxDate == time_max()) &&
 		(mFilterOps.mFilterTypes & FILTERTYPE_DATE);
 }
 
 void LLInventoryFilter::clearModified()
 {
-	mModified = FALSE; 
-	mFilterBehavior = FILTER_NONE;
+	mFilterModified = FILTER_NONE;
 }
 
 void LLInventoryFilter::setHoursAgo(U32 hours)
@@ -722,15 +700,6 @@ void LLInventoryFilter::setShowFolderState(EFolderShow state)
 	}
 }
 
-void LLInventoryFilter::setSortOrder(U32 order)
-{
-	if (mOrder != order)
-	{
-		mOrder = order;
-		setModified();
-	}
-}
-
 void LLInventoryFilter::markDefault()
 {
 	mDefaultFilterOps = mFilterOps;
@@ -742,83 +711,68 @@ void LLInventoryFilter::resetDefault()
 	setModified();
 }
 
-void LLInventoryFilter::setModified(EFilterBehavior behavior)
+void LLInventoryFilter::setModified(EFilterModified behavior)
 {
-	mModified = TRUE;
-	mNeedTextRebuild = TRUE;
-	mFilterGeneration = mNextFilterGeneration++;
+	mFilterText.clear();
+	mCurrentGeneration = mNextFilterGeneration++;
 
-	if (mFilterBehavior == FILTER_NONE)
+	if (mFilterModified == FILTER_NONE)
 	{
-		mFilterBehavior = behavior;
+		mFilterModified = behavior;
 	}
-	else if (mFilterBehavior != behavior)
+	else if (mFilterModified != behavior)
 	{
 		// trying to do both less restrictive and more restrictive filter
 		// basically means restart from scratch
-		mFilterBehavior = FILTER_RESTART;
+		mFilterModified = FILTER_RESTART;
 	}
 
-	if (isNotDefault())
+	// if not keeping current filter results, update last valid as well
+	switch(mFilterModified)
 	{
-		// if not keeping current filter results, update last valid as well
-		switch(mFilterBehavior)
-		{
-			case FILTER_RESTART:
-				mMustPassGeneration = mFilterGeneration;
-				mMinRequiredGeneration = mFilterGeneration;
-				break;
-			case FILTER_LESS_RESTRICTIVE:
-				mMustPassGeneration = mFilterGeneration;
-				break;
-			case FILTER_MORE_RESTRICTIVE:
-				mMinRequiredGeneration = mFilterGeneration;
-				// must have passed either current filter generation (meaningless, as it hasn't been run yet)
-				// or some older generation, so keep the value
-				mMustPassGeneration = llmin(mMustPassGeneration, mFilterGeneration);
-				break;
-			default:
-				llerrs << "Bad filter behavior specified" << llendl;
-		}
-	}
-	else
-	{
-		// shortcut disabled filters to show everything immediately
-		mMinRequiredGeneration = 0;
-		mMustPassGeneration = S32_MAX;
+		case FILTER_RESTART:
+			mFirstRequiredGeneration = mCurrentGeneration;
+			mFirstSuccessGeneration = mCurrentGeneration;
+			break;
+		case FILTER_LESS_RESTRICTIVE:
+			mFirstRequiredGeneration = mCurrentGeneration;
+			break;
+		case FILTER_MORE_RESTRICTIVE:
+			mFirstSuccessGeneration = mCurrentGeneration;
+			break;
+		default:
+			llerrs << "Bad filter behavior specified" << llendl;
 	}
 }
 
-BOOL LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
+bool LLInventoryFilter::isFilterObjectTypesWith(LLInventoryType::EType t) const
 {
 	return mFilterOps.mFilterObjectTypes & (1LL << t);
 }
 
 const std::string& LLInventoryFilter::getFilterText()
 {
-	if (!mNeedTextRebuild)
+	if (!mFilterText.empty())
 	{
 		return mFilterText;
 	}
 
-	mNeedTextRebuild = FALSE;
 	std::string filtered_types;
 	std::string not_filtered_types;
 	BOOL filtered_by_type = FALSE;
 	BOOL filtered_by_all_types = TRUE;
 	S32 num_filter_types = 0;
+
 	mFilterText.clear();
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_ANIMATION))
 	{
-		//filtered_types += " Animations,";
 		filtered_types += LLTrans::getString("Animations");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Animations,";
 		not_filtered_types += LLTrans::getString("Animations");
 
 		filtered_by_all_types = FALSE;
@@ -826,140 +780,120 @@ const std::string& LLInventoryFilter::getFilterText()
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_CALLINGCARD))
 	{
-		//filtered_types += " Calling Cards,";
 		filtered_types += LLTrans::getString("Calling Cards");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Calling Cards,";
 		not_filtered_types += LLTrans::getString("Calling Cards");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_WEARABLE))
 	{
-		//filtered_types += " Clothing,";
 		filtered_types +=  LLTrans::getString("Clothing");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Clothing,";
 		not_filtered_types +=  LLTrans::getString("Clothing");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_GESTURE))
 	{
-		//filtered_types += " Gestures,";
 		filtered_types +=  LLTrans::getString("Gestures");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Gestures,";
 		not_filtered_types +=  LLTrans::getString("Gestures");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_LANDMARK))
 	{
-		//filtered_types += " Landmarks,";
 		filtered_types +=  LLTrans::getString("Landmarks");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Landmarks,";
 		not_filtered_types +=  LLTrans::getString("Landmarks");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_NOTECARD))
 	{
-		//filtered_types += " Notecards,";
 		filtered_types +=  LLTrans::getString("Notecards");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Notecards,";
 		not_filtered_types +=  LLTrans::getString("Notecards");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_OBJECT) && isFilterObjectTypesWith(LLInventoryType::IT_ATTACHMENT))
 	{
-		//filtered_types += " Objects,";
 		filtered_types +=  LLTrans::getString("Objects");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Objects,";
 		not_filtered_types +=  LLTrans::getString("Objects");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_LSL))
 	{
-		//filtered_types += " Scripts,";
 		filtered_types +=  LLTrans::getString("Scripts");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Scripts,";
 		not_filtered_types +=  LLTrans::getString("Scripts");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_SOUND))
 	{
-		//filtered_types += " Sounds,";
 		filtered_types +=  LLTrans::getString("Sounds");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Sounds,";
 		not_filtered_types +=  LLTrans::getString("Sounds");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_TEXTURE))
 	{
-		//filtered_types += " Textures,";
 		filtered_types +=  LLTrans::getString("Textures");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Textures,";
 		not_filtered_types +=  LLTrans::getString("Textures");
 		filtered_by_all_types = FALSE;
 	}
 
 	if (isFilterObjectTypesWith(LLInventoryType::IT_SNAPSHOT))
 	{
-		//filtered_types += " Snapshots,";
 		filtered_types +=  LLTrans::getString("Snapshots");
 		filtered_by_type = TRUE;
 		num_filter_types++;
 	}
 	else
 	{
-		//not_filtered_types += " Snapshots,";
 		not_filtered_types +=  LLTrans::getString("Snapshots");
 		filtered_by_all_types = FALSE;
 	}
@@ -975,7 +909,6 @@ const std::string& LLInventoryFilter::getFilterText()
 		}
 		else
 		{
-			//mFilterText += "No ";
 			mFilterText += LLTrans::getString("No Filters");
 			mFilterText += not_filtered_types;
 		}
@@ -985,66 +918,55 @@ const std::string& LLInventoryFilter::getFilterText()
 
 	if (isSinceLogoff())
 	{
-		//mFilterText += " - Since Logoff";
 		mFilterText += LLTrans::getString("Since Logoff");
 	}
 	return mFilterText;
 }
 
-void LLInventoryFilter::toLLSD(LLSD& data) const
-{
-	data["filter_types"] = (LLSD::Integer)getFilterObjectTypes();
-	data["min_date"] = (LLSD::Integer)getMinDate();
-	data["max_date"] = (LLSD::Integer)getMaxDate();
-	data["hours_ago"] = (LLSD::Integer)getHoursAgo();
-	data["show_folder_state"] = (LLSD::Integer)getShowFolderState();
-	data["permissions"] = (LLSD::Integer)getFilterPermissions();
-	data["substring"] = (LLSD::String)getFilterSubString();
-	data["sort_order"] = (LLSD::Integer)getSortOrder();
-	data["since_logoff"] = (LLSD::Boolean)isSinceLogoff();
-}
 
-void LLInventoryFilter::fromLLSD(LLSD& data)
+LLInventoryFilter& LLInventoryFilter::operator=( const  LLInventoryFilter&  other )
 {
-	if(data.has("filter_types"))
-	{
-		setFilterObjectTypes((U64)data["filter_types"].asInteger());
-	}
-
-	if(data.has("min_date") && data.has("max_date"))
-	{
-		setDateRange(data["min_date"].asInteger(), data["max_date"].asInteger());
-	}
-
-	if(data.has("hours_ago"))
-	{
-		setHoursAgo((U32)data["hours_ago"].asInteger());
-	}
-
-	if(data.has("show_folder_state"))
-	{
-		setShowFolderState((EFolderShow)data["show_folder_state"].asInteger());
-	}
+	setFilterObjectTypes(other.getFilterObjectTypes());
+	setDateRange(other.getMinDate(), other.getMaxDate());
+	setHoursAgo(other.getHoursAgo());
+	setShowFolderState(other.getShowFolderState());
+	setFilterPermissions(other.getFilterPermissions());
+	setFilterSubString(other.getFilterSubString());
+	setDateRangeLastLogoff(other.isSinceLogoff());
+	return *this;
+}
 
-	if(data.has("permissions"))
-	{
-		setFilterPermissions((PermissionMask)data["permissions"].asInteger());
-	}
 
-	if(data.has("substring"))
-	{
-		setFilterSubString(std::string(data["substring"].asString()));
-	}
+void LLInventoryFilter::toParams(Params& params) const
+{
+	params.filter_ops.types = getFilterObjectTypes();
+	params.filter_ops.category_types = getFilterCategoryTypes();
+	params.filter_ops.wearable_types = getFilterWearableTypes();
+	params.filter_ops.date_range.min_date = getMinDate();
+	params.filter_ops.date_range.max_date = getMaxDate();
+	params.filter_ops.hours_ago = getHoursAgo();
+	params.filter_ops.show_folder_state = getShowFolderState();
+	params.filter_ops.permissions = getFilterPermissions();
+	params.substring = getFilterSubString();
+	params.since_logoff = isSinceLogoff();
+}
 
-	if(data.has("sort_order"))
+void LLInventoryFilter::fromParams(const Params& params)
+{
+	if (!params.validateBlock())
 	{
-		setSortOrder((U32)data["sort_order"].asInteger());
+		return;
 	}
 
-	if(data.has("since_logoff"))
-	{
-		setDateRangeLastLogoff((bool)data["since_logoff"].asBoolean());
-	}
+	setFilterObjectTypes(params.filter_ops.types);
+	setFilterCategoryTypes(params.filter_ops.category_types);
+	setFilterWearableTypes(params.filter_ops.wearable_types);
+	setDateRange(params.filter_ops.date_range.min_date,   params.filter_ops.date_range.max_date);
+	setHoursAgo(params.filter_ops.hours_ago);
+	setShowFolderState(params.filter_ops.show_folder_state);
+	setFilterPermissions(params.filter_ops.permissions);
+	setFilterSubString(params.substring);
+	setDateRangeLastLogoff(params.since_logoff);
 }
 
 U64 LLInventoryFilter::getFilterObjectTypes() const
@@ -1057,11 +979,21 @@ U64 LLInventoryFilter::getFilterCategoryTypes() const
 	return mFilterOps.mFilterCategoryTypes;
 }
 
-BOOL LLInventoryFilter::hasFilterString() const
+U64 LLInventoryFilter::getFilterWearableTypes() const
+{
+	return mFilterOps.mFilterWearableTypes;
+}
+
+bool LLInventoryFilter::hasFilterString() const
 {
 	return mFilterSubString.size() > 0;
 }
 
+std::string::size_type LLInventoryFilter::getFilterStringSize() const
+{
+	return mFilterSubString.size();
+}
+
 PermissionMask LLInventoryFilter::getFilterPermissions() const
 {
 	return mFilterOps.mPermissions;
@@ -1088,14 +1020,6 @@ LLInventoryFilter::EFolderShow LLInventoryFilter::getShowFolderState() const
 { 
 	return mFilterOps.mShowFolderState; 
 }
-U32 LLInventoryFilter::getSortOrder() const 
-{ 
-	return mOrder; 
-}
-const std::string& LLInventoryFilter::getName() const 
-{ 
-	return mName; 
-}
 
 void LLInventoryFilter::setFilterCount(S32 count) 
 { 
@@ -1113,15 +1037,15 @@ void LLInventoryFilter::decrementFilterCount()
 
 S32 LLInventoryFilter::getCurrentGeneration() const 
 { 
-	return mFilterGeneration; 
+	return mCurrentGeneration;
 }
-S32 LLInventoryFilter::getMinRequiredGeneration() const 
+S32 LLInventoryFilter::getFirstSuccessGeneration() const
 { 
-	return mMinRequiredGeneration; 
+	return mFirstSuccessGeneration; 
 }
-S32 LLInventoryFilter::getMustPassGeneration() const 
+S32 LLInventoryFilter::getFirstRequiredGeneration() const
 { 
-	return mMustPassGeneration; 
+	return mFirstRequiredGeneration; 
 }
 
 void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
@@ -1129,9 +1053,12 @@ void LLInventoryFilter::setEmptyLookupMessage(const std::string& message)
 	mEmptyLookupMessage = message;
 }
 
-const std::string& LLInventoryFilter::getEmptyLookupMessage() const
+std::string LLInventoryFilter::getEmptyLookupMessage() const
 {
-	return mEmptyLookupMessage;
+	LLStringUtil::format_map_t args;
+	args["[SEARCH_TERM]"] = LLURI::escape(getFilterSubStringOrig());
+
+	return LLTrans::getString(mEmptyLookupMessage, args);
 
 }
 
@@ -1141,3 +1068,27 @@ bool LLInventoryFilter::areDateLimitsSet()
 			|| mFilterOps.mMaxDate != time_max()
 			|| mFilterOps.mHoursAgo != 0;
 }
+
+bool LLInventoryFilter::showAllResults() const
+{
+	return hasFilterString();
+}
+
+
+
+bool LLInventoryFilter::FilterOps::DateRange::validateBlock( bool   emit_errors /*= true*/ ) const
+{
+	bool valid = LLInitParam::Block<DateRange>::validateBlock(emit_errors);
+	if (valid)
+	{
+		if (max_date() < min_date())
+		{
+			if (emit_errors)
+			{
+				llwarns << "max_date should be greater or equal to min_date" <<   llendl;
+			}
+			valid = false;
+		}
+	}
+	return valid;
+}
diff --git a/indra/newview/llinventoryfilter.h b/indra/newview/llinventoryfilter.h
index 9e600c036f0e8679846b564bacbc478fb7db1d1c..4912b5ca9162ed1c128f09137b6faf4b62ea31f3 100644
--- a/indra/newview/llinventoryfilter.h
+++ b/indra/newview/llinventoryfilter.h
@@ -29,12 +29,13 @@
 
 #include "llinventorytype.h"
 #include "llpermissionsflags.h"
+#include "llfolderviewmodel.h"
 
 class LLFolderViewItem;
 class LLFolderViewFolder;
 class LLInventoryItem;
 
-class LLInventoryFilter
+class LLInventoryFilter : public LLFolderViewFilter
 {
 public:
 	enum EFolderShow
@@ -44,14 +45,6 @@ class LLInventoryFilter
 		SHOW_NO_FOLDERS
 	};
 
-	enum EFilterBehavior
-	{
-		FILTER_NONE,				// nothing to do, already filtered
-		FILTER_RESTART,				// restart filtering from scratch
-		FILTER_LESS_RESTRICTIVE,	// existing filtered items will certainly pass this filter
-		FILTER_MORE_RESTRICTIVE		// if you didn't pass the previous filter, you definitely won't pass this one
-	};
-
 	enum EFilterType	{
 		FILTERTYPE_NONE = 0,
 		FILTERTYPE_OBJECT = 0x1 << 0,	// normal default search-by-object-type
@@ -59,7 +52,7 @@ class LLInventoryFilter
 		FILTERTYPE_UUID	= 0x1 << 2,		// find the object with UUID and any links to it
 		FILTERTYPE_DATE = 0x1 << 3,		// search by date range
 		FILTERTYPE_WEARABLE = 0x1 << 4,	// search by wearable type
-		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5	// pass if folder is not a system folder to be hidden if empty
+		FILTERTYPE_EMPTYFOLDERS = 0x1 << 5		// pass if folder is not a system   folder to be hidden if
 	};
 
 	enum EFilterLink
@@ -77,16 +70,92 @@ class LLInventoryFilter
 		SO_SYSTEM_FOLDERS_TO_TOP = 0x1 << 2	// Force system folders to be on top
 	};
 
-	LLInventoryFilter(const std::string& name);
-	virtual ~LLInventoryFilter();
+	struct FilterOps
+	{
+		struct DateRange : public LLInitParam::Block<DateRange>
+		{
+			Optional<time_t>	min_date,
+								max_date;
+
+			DateRange()
+			:	min_date("min_date", time_min()),
+				max_date("max_date", time_max())
+			{}
+
+			bool validateBlock(bool emit_errors = true) const;
+		};
+
+		struct Params : public LLInitParam::Block<Params>
+		{
+			Optional<U32>				types;
+			Optional<U64>				object_types,
+										wearable_types,
+										category_types;
+			Optional<EFilterLink>		links;
+			Optional<LLUUID>			uuid;
+			Optional<DateRange>			date_range;
+			Optional<S32>				hours_ago;
+			Optional<EFolderShow>		show_folder_state;
+			Optional<PermissionMask>	permissions;
+
+			Params()
+			:	types("filter_types", FILTERTYPE_OBJECT),
+				object_types("object_types", 0xffffFFFFffffFFFFULL),
+				wearable_types("wearable_types", 0xffffFFFFffffFFFFULL),
+				category_types("category_types", 0xffffFFFFffffFFFFULL),
+				links("links", FILTERLINK_INCLUDE_LINKS),
+				uuid("uuid"),
+				date_range("date_range"),
+				hours_ago("hours_ago", 0),
+				show_folder_state("show_folder_state", SHOW_NON_EMPTY_FOLDERS),
+				permissions("permissions", PERM_NONE)
+			{}
+		};
+
+		FilterOps(const Params& = Params());
+
+		U32 			mFilterTypes;
+		U64				mFilterObjectTypes,   // For _OBJECT
+						mFilterWearableTypes,
+						mFilterLinks,
+						mFilterCategoryTypes; // For _CATEGORY
+		LLUUID      	mFilterUUID; 		  // for UUID
+
+		time_t			mMinDate,
+						mMaxDate;
+		U32				mHoursAgo;
+
+		EFolderShow		mShowFolderState;
+		PermissionMask	mPermissions;
+	};
+							
+	struct Params : public LLInitParam::Block<Params>
+	{
+		Optional<std::string>		name;
+		Optional<FilterOps::Params>	filter_ops;
+		Optional<std::string>		substring;
+		Optional<bool>				since_logoff;
+
+		Params()
+		:	name("name"),
+			filter_ops(""),
+			substring("substring"),
+			since_logoff("since_logoff")
+		{}
+	};
+									
+	LLInventoryFilter(const Params& p = Params());
+	LLInventoryFilter(const LLInventoryFilter& other) { *this = other; }
+	virtual ~LLInventoryFilter() {}
 
 	// +-------------------------------------------------------------------+
 	// + Parameters
 	// +-------------------------------------------------------------------+
-	void 				setFilterObjectTypes(U64 types);
 	U64 				getFilterObjectTypes() const;
 	U64					getFilterCategoryTypes() const;
-	BOOL 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
+	U64					getFilterWearableTypes() const;
+	bool 				isFilterObjectTypesWith(LLInventoryType::EType t) const;
+	void 				setFilterObjectTypes(U64 types);
 	void 				setFilterCategoryTypes(U64 types);
 	void 				setFilterUUID(const LLUUID &object_id);
 	void				setFilterWearableTypes(U64 types);
@@ -96,7 +165,7 @@ class LLInventoryFilter
 	void 				setFilterSubString(const std::string& string);
 	const std::string& 	getFilterSubString(BOOL trim = FALSE) const;
 	const std::string& 	getFilterSubStringOrig() const { return mFilterSubStringOrig; } 
-	BOOL 				hasFilterString() const;
+	bool 				hasFilterString() const;
 
 	void 				setFilterPermissions(PermissionMask perms);
 	PermissionMask 		getFilterPermissions() const;
@@ -115,43 +184,35 @@ class LLInventoryFilter
 	// +-------------------------------------------------------------------+
 	// + Execution And Results
 	// +-------------------------------------------------------------------+
-	BOOL 				check(const LLFolderViewItem* item);
+	bool				check(const LLFolderViewModelItem* listener);
 	bool				check(const LLInventoryItem* item);
-	bool				checkFolder(const LLFolderViewFolder* folder) const;
+	bool				checkFolder(const LLFolderViewModelItem* listener) const;
 	bool				checkFolder(const LLUUID& folder_id) const;
-	BOOL 				checkAgainstFilterType(const LLFolderViewItem* item) const;
-	bool 				checkAgainstFilterType(const LLInventoryItem* item) const;
-	BOOL 				checkAgainstPermissions(const LLFolderViewItem* item) const;
-	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
-	BOOL 				checkAgainstFilterLinks(const LLFolderViewItem* item) const;
-	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
-	std::string::size_type getStringMatchOffset() const;
+	bool				showAllResults() const;
 
+	std::string::size_type getStringMatchOffset(LLFolderViewModelItem* item) const;
+	std::string::size_type getFilterStringSize() const;
 	// +-------------------------------------------------------------------+
 	// + Presentation
 	// +-------------------------------------------------------------------+
 	void 				setShowFolderState( EFolderShow state);
 	EFolderShow 		getShowFolderState() const;
 
-	void 				setSortOrder(U32 order);
-	U32 				getSortOrder() const;
-
 	void 				setEmptyLookupMessage(const std::string& message);
-	const std::string&	getEmptyLookupMessage() const;
+	std::string			getEmptyLookupMessage() const;
 
 	// +-------------------------------------------------------------------+
 	// + Status
 	// +-------------------------------------------------------------------+
-	BOOL 				isActive() const;
-	BOOL 				isModified() const;
-	BOOL 				isModifiedAndClear();
-	BOOL 				isSinceLogoff() const;
+	bool 				isActive() const;
+	bool 				isModified() const;
+	bool 				isSinceLogoff() const;
 	void 				clearModified();
-	const std::string& 	getName() const;
+	const std::string& 	getName() const { return mName; }
 	const std::string& 	getFilterText();
 	//RN: this is public to allow system to externally force a global refilter
-	void 				setModified(EFilterBehavior behavior = FILTER_RESTART);
+	void 				setModified(EFilterModified behavior = FILTER_RESTART);
 
 	// +-------------------------------------------------------------------+
 	// + Count
@@ -163,8 +224,8 @@ class LLInventoryFilter
 	// +-------------------------------------------------------------------+
 	// + Default
 	// +-------------------------------------------------------------------+
-	BOOL 				isDefault() const;
-	BOOL 				isNotDefault() const;
+	bool 				isDefault() const;
+	bool 				isNotDefault() const;
 	void 				markDefault();
 	void 				resetDefault();
 
@@ -172,57 +233,42 @@ class LLInventoryFilter
 	// + Generation
 	// +-------------------------------------------------------------------+
 	S32 				getCurrentGeneration() const;
-	S32 				getMinRequiredGeneration() const;
-	S32 				getMustPassGeneration() const;
+	S32 				getFirstSuccessGeneration() const;
+	S32 				getFirstRequiredGeneration() const;
+
 
 	// +-------------------------------------------------------------------+
 	// + Conversion
 	// +-------------------------------------------------------------------+
-	void 				toLLSD(LLSD& data) const;
-	void 				fromLLSD(LLSD& data);
+	void 				toParams(Params& params) const;
+	void 				fromParams(const Params& p);
+
+	LLInventoryFilter& operator =(const LLInventoryFilter& other);
 
 private:
 	bool				areDateLimitsSet();
-
-	struct FilterOps
-	{
-		FilterOps();
-		U32 			mFilterTypes;
-
-		U64				mFilterObjectTypes; // For _OBJECT
-		U64				mFilterWearableTypes;
-		U64				mFilterCategoryTypes; // For _CATEGORY
-		LLUUID      	mFilterUUID; // for UUID
-
-		time_t			mMinDate;
-		time_t			mMaxDate;
-		U32				mHoursAgo;
-		EFolderShow		mShowFolderState;
-		PermissionMask	mPermissions;
-		U64				mFilterLinks;
-	};
-
-	U32						mOrder;
-	U32 					mLastLogoff;
+	bool 				checkAgainstFilterType(const class LLFolderViewModelItemInventory* listener) const;
+	bool 				checkAgainstFilterType(const LLInventoryItem* item) const;
+	bool 				checkAgainstPermissions(const class LLFolderViewModelItemInventory* listener) const;
+	bool 				checkAgainstPermissions(const LLInventoryItem* item) const;
+	bool 				checkAgainstFilterLinks(const class LLFolderViewModelItemInventory* listener) const;
+	bool				checkAgainstClipboard(const LLUUID& object_id) const;
 
 	FilterOps				mFilterOps;
 	FilterOps				mDefaultFilterOps;
 
-	std::string::size_type	mSubStringMatchOffset;
 	std::string				mFilterSubString;
 	std::string				mFilterSubStringOrig;
 	const std::string		mName;
 
-	S32						mFilterGeneration;
-	S32						mMustPassGeneration;
-	S32						mMinRequiredGeneration;
+	S32						mCurrentGeneration;
+	S32						mFirstRequiredGeneration;
+	S32						mFirstSuccessGeneration;
 	S32						mNextFilterGeneration;
 
 	S32						mFilterCount;
-	EFilterBehavior 		mFilterBehavior;
+	EFilterModified 		mFilterModified;
 
-	BOOL 					mModified;
-	BOOL 					mNeedTextRebuild;
 	std::string 			mFilterText;
 	std::string 			mEmptyLookupMessage;
 };
diff --git a/indra/newview/llinventoryfunctions.cpp b/indra/newview/llinventoryfunctions.cpp
index 68732024de311f4b9aebd7921bbeab0f6ca5a9be..f1a4889f5ac141728fb2b565b31383207ede20c2 100644
--- a/indra/newview/llinventoryfunctions.cpp
+++ b/indra/newview/llinventoryfunctions.cpp
@@ -45,7 +45,8 @@
 // newview includes
 #include "llappearancemgr.h"
 #include "llappviewer.h"
-//#include "llfirstuse.h"
+#include "llclipboard.h"
+#include "lldonotdisturbnotificationstorage.h"
 #include "llfloaterinventory.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfocusmgr.h"
@@ -74,8 +75,10 @@
 #include "llsidepanelinventory.h"
 #include "lltabcontainer.h"
 #include "lltooldraganddrop.h"
+#include "lltrans.h"
 #include "lluictrlfactory.h"
 #include "llviewermessage.h"
+#include "llviewerfoldertype.h"
 #include "llviewerobjectlist.h"
 #include "llviewerregion.h"
 #include "llviewerwindow.h"
@@ -959,7 +962,7 @@ void LLSaveFolderState::setApply(BOOL apply)
 
 void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
 {
-	LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getListener();
+	LLInvFVBridge* bridge = (LLInvFVBridge*)folder->getViewModelItem();
 	if(!bridge) return;
 	
 	if(mApply)
@@ -994,7 +997,7 @@ void LLSaveFolderState::doFolder(LLFolderViewFolder* folder)
 
 void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
 {
-	if (item->getFiltered())
+	if (item->passedFilter())
 	{
 		item->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 	}
@@ -1002,12 +1005,12 @@ void LLOpenFilteredFolders::doItem(LLFolderViewItem *item)
 
 void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getFiltered() && folder->getParentFolder())
+	if (folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
 	{
 		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
 	}
 	// if this folder didn't pass the filter, and none of its descendants did
-	else if (!folder->getFiltered() && !folder->hasFilteredDescendants())
+	else if (!folder->getViewModelItem()->passedFilter() && !folder->getViewModelItem()->descendantsPassedFilter())
 	{
 		folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_NO);
 	}
@@ -1015,7 +1018,7 @@ void LLOpenFilteredFolders::doFolder(LLFolderViewFolder* folder)
 
 void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 {
-	if (item->getFiltered() && !mItemSelected)
+	if (item->passedFilter() && !mItemSelected)
 	{
 		item->getRoot()->setSelection(item, FALSE, FALSE);
 		if (item->getParentFolder())
@@ -1028,14 +1031,12 @@ void LLSelectFirstFilteredItem::doItem(LLFolderViewItem *item)
 
 void LLSelectFirstFilteredItem::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getFiltered() && !mItemSelected)
+	// Skip if folder or item already found, if not filtered or if no parent (root folder is not selectable)
+	if (!mFolderSelected && !mItemSelected && folder->LLFolderViewItem::passedFilter() && folder->getParentFolder())
 	{
 		folder->getRoot()->setSelection(folder, FALSE, FALSE);
-		if (folder->getParentFolder())
-		{
-			folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
-		}
-		mItemSelected = TRUE;
+		folder->getParentFolder()->setOpenArrangeRecursively(TRUE, LLFolderViewFolder::RECURSE_UP);
+		mFolderSelected = TRUE;
 	}
 }
 
@@ -1055,3 +1056,113 @@ void LLOpenFoldersWithSelection::doFolder(LLFolderViewFolder* folder)
 	}
 }
 
+void LLInventoryAction::doToSelected(LLInventoryModel* model, LLFolderView* root, const std::string& action)
+{
+	if ("rename" == action)
+	{
+		root->startRenamingSelectedItem();
+		return;
+	}
+	if ("delete" == action)
+	{
+		LLSD args;
+		args["QUESTION"] = LLTrans::getString(root->getSelectedCount() > 1 ? "DeleteItems" :  "DeleteItem");
+		LLNotificationsUtil::add("DeleteItems", args, LLSD(), boost::bind(&LLInventoryAction::onItemsRemovalConfirmation, _1, _2, root));
+		return;
+	}
+	if (("copy" == action) || ("cut" == action))
+	{	
+		// Clear the clipboard before we start adding things on it
+		LLClipboard::instance().reset();
+	}
+
+	static const std::string change_folder_string = "change_folder_type_";
+	if (action.length() > change_folder_string.length() && 
+		(action.compare(0,change_folder_string.length(),"change_folder_type_") == 0))
+	{
+		LLFolderType::EType new_folder_type = LLViewerFolderType::lookupTypeFromXUIName(action.substr(change_folder_string.length()));
+		LLFolderViewModelItemInventory* inventory_item = static_cast<LLFolderViewModelItemInventory*>(root->getViewModelItem());
+		LLViewerInventoryCategory *cat = model->getCategory(inventory_item->getUUID());
+		if (!cat) return;
+		cat->changeType(new_folder_type);
+		return;
+	}
+
+
+	std::set<LLFolderViewItem*> selected_items = root->getSelectionList();
+
+	LLMultiPreview* multi_previewp = NULL;
+	LLMultiProperties* multi_propertiesp = NULL;
+
+	if (("task_open" == action  || "open" == action) && selected_items.size() > 1)
+	{
+		multi_previewp = new LLMultiPreview();
+		gFloaterView->addChild(multi_previewp);
+
+		LLFloater::setFloaterHost(multi_previewp);
+
+	}
+	else if (("task_properties" == action || "properties" == action) && selected_items.size() > 1)
+	{
+		multi_propertiesp = new LLMultiProperties();
+		gFloaterView->addChild(multi_propertiesp);
+
+		LLFloater::setFloaterHost(multi_propertiesp);
+	}
+
+	std::set<LLFolderViewItem*>::iterator set_iter;
+
+	for (set_iter = selected_items.begin(); set_iter != selected_items.end(); ++set_iter)
+	{
+		LLFolderViewItem* folder_item = *set_iter;
+		if(!folder_item) continue;
+		LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
+		if(!bridge) continue;
+		bridge->performAction(model, action);
+	}
+
+	LLFloater::setFloaterHost(NULL);
+	if (multi_previewp)
+	{
+		multi_previewp->openFloater(LLSD());
+	}
+	else if (multi_propertiesp)
+	{
+		multi_propertiesp->openFloater(LLSD());
+	}
+}
+
+void LLInventoryAction::removeItemFromDND(LLFolderView* root)
+{
+    if(gAgent.isDoNotDisturb())
+    {
+        //Get selected items
+        LLFolderView::selected_items_t selectedItems = root->getSelectedItems();
+        LLFolderViewModelItemInventory * viewModel = NULL;
+
+        //If user is in DND and deletes item, make sure the notification is not displayed by removing the notification
+        //from DND history and .xml file. Once this is done, upon exit of DND mode the item deleted will not show a notification.
+        for(LLFolderView::selected_items_t::iterator it = selectedItems.begin(); it != selectedItems.end(); ++it)
+        {
+            viewModel = dynamic_cast<LLFolderViewModelItemInventory *>((*it)->getViewModelItem());
+
+            if(viewModel && viewModel->getUUID().notNull())
+            {
+                //Will remove the item offer notification
+                LLDoNotDisturbNotificationStorage::instance().removeNotification(LLDoNotDisturbNotificationStorage::offerName, viewModel->getUUID());
+            }
+        }
+    }
+}
+
+void LLInventoryAction::onItemsRemovalConfirmation( const LLSD& notification, const LLSD& response, LLFolderView* root )
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (option == 0)
+	{
+        //Need to remove item from DND before item is removed from root folder view
+        //because once removed from root folder view the item is no longer a selected item
+        removeItemFromDND(root);
+		root->removeSelectedItems();
+	}
+}
diff --git a/indra/newview/llinventoryfunctions.h b/indra/newview/llinventoryfunctions.h
index 909f7fd10beecf7bcb9be19caf59a4c145ccaac7..f1066a4dc96622575df5a3f80d4b9a13afb195ce 100644
--- a/indra/newview/llinventoryfunctions.h
+++ b/indra/newview/llinventoryfunctions.h
@@ -419,21 +419,6 @@ class LLFindNonRemovableObjects : public LLInventoryCollectFunctor
 class LLFolderViewItem;
 class LLFolderViewFolder;
 
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-// Class LLFolderViewFunctor
-//
-// Simple abstract base class for applying a functor to folders and
-// items in a folder view hierarchy. This is suboptimal for algorithms
-// that only work folders or only work on items, but I'll worry about
-// that later when it's determined to be too slow.
-//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-class LLFolderViewFunctor
-{
-public:
-	virtual ~LLFolderViewFunctor() {}
-	virtual void doFolder(LLFolderViewFolder* folder) = 0;
-	virtual void doItem(LLFolderViewItem* item) = 0;
-};
 
 class LLInventoryState
 {
@@ -443,49 +428,14 @@ class LLInventoryState
 	static LLUUID sWearNewClothingTransactionID;	// wear all clothing in this transaction	
 };
 
-class LLSelectFirstFilteredItem : public LLFolderViewFunctor
+struct LLInventoryAction
 {
-public:
-	LLSelectFirstFilteredItem() : mItemSelected(FALSE) {}
-	virtual ~LLSelectFirstFilteredItem() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-	BOOL wasItemSelected() { return mItemSelected; }
-protected:
-	BOOL mItemSelected;
-};
+	static void doToSelected(class LLInventoryModel* model, class LLFolderView* root, const std::string& action);
 
-class LLOpenFilteredFolders : public LLFolderViewFunctor
-{
-public:
-	LLOpenFilteredFolders()  {}
-	virtual ~LLOpenFilteredFolders() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
+	static void onItemsRemovalConfirmation(const LLSD& notification, const LLSD& response, LLFolderView* root);
+    static void removeItemFromDND(LLFolderView* root);
 };
 
-class LLSaveFolderState : public LLFolderViewFunctor
-{
-public:
-	LLSaveFolderState() : mApply(FALSE) {}
-	virtual ~LLSaveFolderState() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item) {}
-	void setApply(BOOL apply);
-	void clearOpenFolders() { mOpenFolders.clear(); }
-protected:
-	std::set<LLUUID> mOpenFolders;
-	BOOL mApply;
-};
-
-class LLOpenFoldersWithSelection : public LLFolderViewFunctor
-{
-public:
-	LLOpenFoldersWithSelection() {}
-	virtual ~LLOpenFoldersWithSelection() {}
-	virtual void doFolder(LLFolderViewFolder* folder);
-	virtual void doItem(LLFolderViewItem* item);
-};
 
 #endif // LL_LLINVENTORYFUNCTIONS_H
 
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 34734d57c5f9fe842f2b91fc7771c5d7b4eedfe2..02a2475cfd44831532a232886c173baa6bdd3992 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -25,6 +25,8 @@
  */
 
 #include "llviewerprecompiledheaders.h"
+
+#include "linden_common.h"
 #include "llinventoryicon.h"
 
 #include "lldictionary.h"
@@ -41,7 +43,7 @@ struct IconEntry : public LLDictionaryEntry
 };
 
 class LLIconDictionary : public LLSingleton<LLIconDictionary>,
-						 public LLDictionary<LLInventoryIcon::EIconName, IconEntry>
+						 public LLDictionary<LLInventoryType::EIconName, IconEntry>
 {
 public:
 	LLIconDictionary();
@@ -49,48 +51,48 @@ class LLIconDictionary : public LLSingleton<LLIconDictionary>,
 
 LLIconDictionary::LLIconDictionary()
 {
-	addEntry(LLInventoryIcon::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
-	addEntry(LLInventoryIcon::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
-	addEntry(LLInventoryIcon::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
-	addEntry(LLInventoryIcon::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
-	addEntry(LLInventoryIcon::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
-
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
-	addEntry(LLInventoryIcon::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
-	addEntry(LLInventoryIcon::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
-	addEntry(LLInventoryIcon::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
-
-	addEntry(LLInventoryIcon::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
-
-	addEntry(LLInventoryIcon::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
-	addEntry(LLInventoryIcon::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
-	addEntry(LLInventoryIcon::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
-
-	addEntry(LLInventoryIcon::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
-
-	addEntry(LLInventoryIcon::ICONNAME_NONE, 					new IconEntry("NONE"));
+	addEntry(LLInventoryType::ICONNAME_TEXTURE, 				new IconEntry("Inv_Texture"));
+	addEntry(LLInventoryType::ICONNAME_SOUND, 					new IconEntry("Inv_Sound"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_ONLINE, 		new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE, 	new IconEntry("Inv_CallingCard"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK, 				new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_LANDMARK_VISITED, 		new IconEntry("Inv_Landmark"));
+	addEntry(LLInventoryType::ICONNAME_SCRIPT, 					new IconEntry("Inv_Script"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING, 				new IconEntry("Inv_Clothing"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT, 					new IconEntry("Inv_Object"));
+	addEntry(LLInventoryType::ICONNAME_OBJECT_MULTI, 			new IconEntry("Inv_Object_Multi"));
+	addEntry(LLInventoryType::ICONNAME_NOTECARD, 				new IconEntry("Inv_Notecard"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART, 				new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_SNAPSHOT, 				new IconEntry("Inv_Snapshot"));
+
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SHAPE, 			new IconEntry("Inv_BodyShape"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_SKIN, 			new IconEntry("Inv_Skin"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_HAIR, 			new IconEntry("Inv_Hair"));
+	addEntry(LLInventoryType::ICONNAME_BODYPART_EYES, 			new IconEntry("Inv_Eye"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHIRT, 			new IconEntry("Inv_Shirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PANTS, 			new IconEntry("Inv_Pants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SHOES, 			new IconEntry("Inv_Shoe"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SOCKS, 			new IconEntry("Inv_Socks"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_JACKET, 		new IconEntry("Inv_Jacket"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_GLOVES, 		new IconEntry("Inv_Gloves"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERSHIRT, 	new IconEntry("Inv_Undershirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_UNDERPANTS, 	new IconEntry("Inv_Underpants"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_SKIRT, 			new IconEntry("Inv_Skirt"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_ALPHA, 			new IconEntry("Inv_Alpha"));
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_TATTOO, 		new IconEntry("Inv_Tattoo"));
+	addEntry(LLInventoryType::ICONNAME_ANIMATION, 				new IconEntry("Inv_Animation"));
+	addEntry(LLInventoryType::ICONNAME_GESTURE, 				new IconEntry("Inv_Gesture"));
+
+	addEntry(LLInventoryType::ICONNAME_CLOTHING_PHYSICS, 		new IconEntry("Inv_Physics"));
+
+	addEntry(LLInventoryType::ICONNAME_LINKITEM, 				new IconEntry("Inv_LinkItem"));
+	addEntry(LLInventoryType::ICONNAME_LINKFOLDER, 				new IconEntry("Inv_LinkFolder"));
+	addEntry(LLInventoryType::ICONNAME_MESH,	 				new IconEntry("Inv_Mesh"));
+
+	addEntry(LLInventoryType::ICONNAME_INVALID, 				new IconEntry("Inv_Invalid"));
+
+	addEntry(LLInventoryType::ICONNAME_NONE, 					new IconEntry("NONE"));
 }
 
 LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
@@ -102,7 +104,7 @@ LLUIImagePtr LLInventoryIcon::getIcon(LLAssetType::EType asset_type,
 	return LLUI::getUIImage(icon_name);
 }
 
-LLUIImagePtr LLInventoryIcon::getIcon(EIconName idx)
+LLUIImagePtr LLInventoryIcon::getIcon(LLInventoryType::EIconName idx)
 {
 	return LLUI::getUIImage(getIconName(idx));
 }
@@ -112,56 +114,56 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 												U32 misc_flag,
 												BOOL item_is_multi)
 {
-	EIconName idx = ICONNAME_OBJECT;
+	LLInventoryType::EIconName idx = LLInventoryType::ICONNAME_OBJECT;
 	if (item_is_multi)
 	{
-		idx = ICONNAME_OBJECT_MULTI;
+		idx = LLInventoryType::ICONNAME_OBJECT_MULTI;
 		return getIconName(idx);
 	}
 	
 	switch(asset_type)
 	{
 		case LLAssetType::AT_TEXTURE:
-			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? ICONNAME_SNAPSHOT : ICONNAME_TEXTURE;
+			idx = (inventory_type == LLInventoryType::IT_SNAPSHOT) ? LLInventoryType::ICONNAME_SNAPSHOT : LLInventoryType::ICONNAME_TEXTURE;
 			break;
 		case LLAssetType::AT_SOUND:
-			idx = ICONNAME_SOUND;
+			idx = LLInventoryType::ICONNAME_SOUND;
 			break;
 		case LLAssetType::AT_CALLINGCARD:
-			idx = (misc_flag != 0) ? ICONNAME_CALLINGCARD_ONLINE : ICONNAME_CALLINGCARD_OFFLINE;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_CALLINGCARD_ONLINE : LLInventoryType::ICONNAME_CALLINGCARD_OFFLINE;
 			break;
 		case LLAssetType::AT_LANDMARK:
-			idx = (misc_flag != 0) ? ICONNAME_LANDMARK_VISITED : ICONNAME_LANDMARK;
+			idx = (misc_flag != 0) ? LLInventoryType::ICONNAME_LANDMARK_VISITED : LLInventoryType::ICONNAME_LANDMARK;
 			break;
 		case LLAssetType::AT_SCRIPT:
 		case LLAssetType::AT_LSL_TEXT:
 		case LLAssetType::AT_LSL_BYTECODE:
-			idx = ICONNAME_SCRIPT;
+			idx = LLInventoryType::ICONNAME_SCRIPT;
 			break;
 		case LLAssetType::AT_CLOTHING:
 		case LLAssetType::AT_BODYPART:
 			idx = assignWearableIcon(misc_flag);
 			break;
 		case LLAssetType::AT_NOTECARD:
-			idx = ICONNAME_NOTECARD;
+			idx = LLInventoryType::ICONNAME_NOTECARD;
 			break;
 		case LLAssetType::AT_ANIMATION:
-			idx = ICONNAME_ANIMATION;
+			idx = LLInventoryType::ICONNAME_ANIMATION;
 			break;
 		case LLAssetType::AT_GESTURE:
-			idx = ICONNAME_GESTURE;
+			idx = LLInventoryType::ICONNAME_GESTURE;
 			break;
 		case LLAssetType::AT_LINK:
-			idx = ICONNAME_LINKITEM;
+			idx = LLInventoryType::ICONNAME_LINKITEM;
 			break;
 		case LLAssetType::AT_LINK_FOLDER:
-			idx = ICONNAME_LINKFOLDER;
+			idx = LLInventoryType::ICONNAME_LINKFOLDER;
 			break;
 		case LLAssetType::AT_OBJECT:
-			idx = ICONNAME_OBJECT;
+			idx = LLInventoryType::ICONNAME_OBJECT;
 			break;
 		case LLAssetType::AT_MESH:
-			idx = ICONNAME_MESH;
+			idx = LLInventoryType::ICONNAME_MESH;
 		default:
 			break;
 	}
@@ -170,13 +172,13 @@ const std::string& LLInventoryIcon::getIconName(LLAssetType::EType asset_type,
 }
 
 
-const std::string& LLInventoryIcon::getIconName(EIconName idx)
+const std::string& LLInventoryIcon::getIconName(LLInventoryType::EIconName idx)
 {
 	const IconEntry *entry = LLIconDictionary::instance().lookup(idx);
 	return entry->mName;
 }
 
-LLInventoryIcon::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
+LLInventoryType::EIconName LLInventoryIcon::assignWearableIcon(U32 misc_flag)
 {
 	const LLWearableType::EType wearable_type = LLWearableType::EType(LLInventoryItemFlags::II_FLAGS_WEARABLES_MASK & misc_flag);
 	return LLWearableType::getIconName(wearable_type);
diff --git a/indra/newview/llinventoryicon.h b/indra/newview/llinventoryicon.h
index c7e2998a20fb37062a3bac6eb74cb7c2bb730732..2197c53bb8395c500ec97705f7cc1f01673c4a53 100644
--- a/indra/newview/llinventoryicon.h
+++ b/indra/newview/llinventoryicon.h
@@ -1,5 +1,5 @@
 /** 
- * @file llinventoryfunctions.h
+ * @file llinventoryicon.h
  * @brief Miscellaneous inventory-related functions and classes
  * class definition
  *
@@ -35,66 +35,20 @@
 class LLInventoryIcon
 {
 public:
-	enum EIconName
-	{
-		ICONNAME_TEXTURE,
-		ICONNAME_SOUND,
-		ICONNAME_CALLINGCARD_ONLINE,
-		ICONNAME_CALLINGCARD_OFFLINE,
-		ICONNAME_LANDMARK,
-		ICONNAME_LANDMARK_VISITED,
-		ICONNAME_SCRIPT,
-		ICONNAME_CLOTHING,
-		ICONNAME_OBJECT,
-		ICONNAME_OBJECT_MULTI,
-		ICONNAME_NOTECARD,
-		ICONNAME_BODYPART,
-		ICONNAME_SNAPSHOT,
-		
-		ICONNAME_BODYPART_SHAPE,
-		ICONNAME_BODYPART_SKIN,
-		ICONNAME_BODYPART_HAIR,
-		ICONNAME_BODYPART_EYES,
-		ICONNAME_CLOTHING_SHIRT,
-		ICONNAME_CLOTHING_PANTS,
-		ICONNAME_CLOTHING_SHOES,
-		ICONNAME_CLOTHING_SOCKS,
-		ICONNAME_CLOTHING_JACKET,
-		ICONNAME_CLOTHING_GLOVES,
-		ICONNAME_CLOTHING_UNDERSHIRT,
-		ICONNAME_CLOTHING_UNDERPANTS,
-		ICONNAME_CLOTHING_SKIRT,
-		ICONNAME_CLOTHING_ALPHA,
-		ICONNAME_CLOTHING_TATTOO,
-
-		ICONNAME_ANIMATION,
-		ICONNAME_GESTURE,
-
-		ICONNAME_CLOTHING_PHYSICS,
-		
-		ICONNAME_LINKITEM,
-		ICONNAME_LINKFOLDER,
-		ICONNAME_MESH,
-
-		ICONNAME_INVALID,
-		ICONNAME_COUNT,
-		ICONNAME_NONE = -1
-	};
-
 	static const std::string& getIconName(LLAssetType::EType asset_type,
 										  LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 										  U32 misc_flag = 0, // different meanings depending on item type
 										  BOOL item_is_multi = FALSE);
-	static const std::string& getIconName(EIconName idx);
+	static const std::string& getIconName(LLInventoryType::EIconName idx);
 
 	static LLUIImagePtr getIcon(LLAssetType::EType asset_type,
 								LLInventoryType::EType inventory_type = LLInventoryType::IT_NONE,
 								U32 misc_flag = 0, // different meanings depending on item type
 								BOOL item_is_multi = FALSE);
-	static LLUIImagePtr getIcon(EIconName idx);
+	static LLUIImagePtr getIcon(LLInventoryType::EIconName idx);
 
 protected:
-	static EIconName assignWearableIcon(U32 misc_flag);
+	static LLInventoryType::EIconName assignWearableIcon(U32 misc_flag);
 };
 #endif // LL_LLINVENTORYICON_H
 
diff --git a/indra/newview/llinventorylistitem.cpp b/indra/newview/llinventorylistitem.cpp
index 3e0849a79578d793e0890e45d8a4d74b77b46545..06017964365eed2b2d0b57e5ddda5271ddcf21e4 100644
--- a/indra/newview/llinventorylistitem.cpp
+++ b/indra/newview/llinventorylistitem.cpp
@@ -37,6 +37,7 @@
 #include "lltextutil.h"
 
 // newview
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
 
@@ -230,7 +231,7 @@ const std::string& LLPanelInventoryListItemBase::getDescription() const
 	{
 		return LLStringUtil::null;
 	}
-	return inv_item->getDescription();
+	return inv_item->getActualDescription();
 }
 
 time_t LLPanelInventoryListItemBase::getCreationDate() const
diff --git a/indra/newview/llinventorymodel.cpp b/indra/newview/llinventorymodel.cpp
old mode 100644
new mode 100755
index 6e23d7c70139e5ed863067121f224af7d68032ac..935fe2b4d0e88c6c70c7e5f310ebaf7e4755f9e0
--- a/indra/newview/llinventorymodel.cpp
+++ b/indra/newview/llinventorymodel.cpp
@@ -373,13 +373,12 @@ void LLInventoryModel::unlockDirectDescendentArrays(const LLUUID& cat_id)
 // specifies 'type' as what it defaults to containing. The category is
 // not necessarily only for that type. *NOTE: This will create a new
 // inventory category on the fly if one does not exist.
-const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, 
-													   bool create_folder, 
-													   bool find_in_library)
+const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder/*, 
+					  bool find_in_library*/)
 {
 	LLUUID rv = LLUUID::null;
 	
-	const LLUUID &root_id = (find_in_library) ? gInventory.getLibraryRootFolderID() : gInventory.getRootFolderID();
+	const LLUUID &root_id = /*(find_in_library) ? gInventory.getLibraryRootFolderID() :*/ gInventory.getRootFolderID();
 	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
 	{
 		rv = root_id;
@@ -402,7 +401,44 @@ const LLUUID LLInventoryModel::findCategoryUUIDForType(LLFolderType::EType prefe
 		}
 	}
 	
-	if(rv.isNull() && isInventoryUsable() && (create_folder && !find_in_library))
+	if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
+	{
+		if(root_id.notNull())
+		{
+			return createNewCategory(root_id, preferred_type, LLStringUtil::null);
+		}
+	}
+	return rv;
+}
+
+const LLUUID LLInventoryModel::findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, bool create_folder)
+{
+	LLUUID rv = LLUUID::null;
+
+	const LLUUID &root_id = gInventory.getLibraryRootFolderID();
+	if(LLFolderType::FT_ROOT_INVENTORY == preferred_type)
+	{
+		rv = root_id;
+	}
+	else if (root_id.notNull())
+	{
+		cat_array_t* cats = NULL;
+		cats = get_ptr_in_map(mParentChildCategoryTree, root_id);
+		if(cats)
+		{
+			S32 count = cats->count();
+			for(S32 i = 0; i < count; ++i)
+			{
+				if(cats->get(i)->getPreferredType() == preferred_type)
+				{
+					rv = cats->get(i)->getUUID();
+					break;
+				}
+			}
+		}
+	}
+
+	if(rv.isNull() && isInventoryUsable() && (create_folder && true/*!find_in_library*/))
 	{
 		if(root_id.notNull())
 		{
@@ -424,9 +460,10 @@ class LLCreateInventoryCategoryResponder : public LLHTTPClient::Responder
 	{
 	}
 	
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("InvAPI") << "CreateInventoryCategory failed.   status = " << status << ", reasion = \"" << reason << "\"" << LL_ENDL;
+		LL_WARNS("InvAPI") << "CreateInventoryCategory failed [status:"
+				<< status << "]: " << content << LL_ENDL;
 	}
 	
 	virtual void result(const LLSD& content)
@@ -950,6 +987,7 @@ void LLInventoryModel::updateCategory(const LLViewerInventoryCategory* cat)
 				cat_array->put(old_cat);
 			}
 			mask |= LLInventoryObserver::STRUCTURE;
+            mask |= LLInventoryObserver::INTERNAL;
 		}
 		if(old_cat->getName() != cat->getName())
 		{
@@ -1245,14 +1283,33 @@ void LLInventoryModel::purgeDescendentsOf(const LLUUID& id)
 							   items,
 							   INCLUDE_TRASH);
 			S32 count = items.count();
+
+			item_map_t::iterator item_map_end = mItemMap.end();
+			cat_map_t::iterator cat_map_end = mCategoryMap.end();
+			LLUUID uu_id;
+
 			for(S32 i = 0; i < count; ++i)
 			{
-				deleteObject(items.get(i)->getUUID());
+				uu_id = items.get(i)->getUUID();
+
+				// This check prevents the deletion of a previously deleted item.
+				// This is necessary because deletion is not done in a hierarchical
+				// order. The current item may have been already deleted as a child
+				// of its deleted parent.
+				if (mItemMap.find(uu_id) != item_map_end)
+				{
+					deleteObject(uu_id);
+				}
 			}
+
 			count = categories.count();
 			for(S32 i = 0; i < count; ++i)
 			{
-				deleteObject(categories.get(i)->getUUID());
+				uu_id = categories.get(i)->getUUID();
+				if (mCategoryMap.find(uu_id) != cat_map_end)
+				{
+					deleteObject(uu_id);
+				}
 			}
 		}
 	}
@@ -1354,7 +1411,6 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 	item_array_t items;
 	update_map_t update;
 	S32 count = content["items"].size();
-	bool all_one_folder = true;
 	LLUUID folder_id;
 	// Does this loop ever execute more than once?
 	for(S32 i = 0; i < count; ++i)
@@ -1387,10 +1443,6 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 		{
 			folder_id = titem->getParentUUID();
 		}
-		else
-		{
-			all_one_folder = false;
-		}
 	}
 
 	U32 changes = 0x0;
@@ -1404,10 +1456,9 @@ void  LLInventoryModel::fetchInventoryResponder::result(const LLSD& content)
 }
 
 //If we get back an error (not found, etc...), handle it here
-void LLInventoryModel::fetchInventoryResponder::error(U32 status, const std::string& reason)
+void LLInventoryModel::fetchInventoryResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "fetchInventory::error "
-		<< status << ": " << reason << llendl;
+	llwarns << "fetchInventory error [status:" << status << "]: " << content << llendl;
 	gInventory.notifyObservers();
 }
 
@@ -1940,8 +1991,9 @@ bool LLInventoryModel::loadSkeleton(
 		{
 			LLViewerInventoryCategory* cat = (*invalid_cat_it).get();
 			cat->setVersion(NO_VERSION);
-			llinfos << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
+			LL_DEBUGS("Inventory") << "Invalidating category name: " << cat->getName() << " UUID: " << cat->getUUID() << " due to invalid descendents cache" << llendl;
 		}
+		LL_INFOS("Inventory") << "Invalidated " << invalid_categories.size() << " categories due to invalid descendents cache" << llendl;
 
 		// At this point, we need to set the known descendents for each
 		// category which successfully cached so that we do not
@@ -2478,7 +2530,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
 	item_array_t items;
 	update_map_t update;
 	S32 count = msg->getNumberOfBlocksFast(_PREHASH_InventoryData);
-	bool all_one_folder = true;
 	LLUUID folder_id;
 	// Does this loop ever execute more than once?
 	for(S32 i = 0; i < count; ++i)
@@ -2510,10 +2561,6 @@ bool LLInventoryModel::messageUpdateCore(LLMessageSystem* msg, bool account)
 		{
 			folder_id = titem->getParentUUID();
 		}
-		else
-		{
-			all_one_folder = false;
-		}
 	}
 	if(account)
 	{
@@ -3240,6 +3287,7 @@ void LLInventoryModel::updateItemsOrder(LLInventoryModel::item_array_t& items, c
 }
 
 //* @param[in] items vector of items in order to be saved.
+/*
 void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& items)
 {
 	int sortField = 0;
@@ -3261,7 +3309,7 @@ void LLInventoryModel::saveItemsOrder(const LLInventoryModel::item_array_t& item
 
 	notifyObservers();
 }
-
+*/
 // See also LLInventorySort where landmarks in the Favorites folder are sorted.
 class LLViewerInventoryItemSort
 {
@@ -3277,14 +3325,15 @@ class LLViewerInventoryItemSort
  *
  * @param[in, out] items - array of items, not sorted.
  */
-static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
-{
-	static LLViewerInventoryItemSort sort_functor;
-	std::sort(items.begin(), items.end(), sort_functor);
-}
+//static void rearrange_item_order_by_sort_field(LLInventoryModel::item_array_t& items)
+//{
+//	static LLViewerInventoryItemSort sort_functor;
+//	std::sort(items.begin(), items.end(), sort_functor);
+//}
 
 // * @param source_item_id - LLUUID of the source item to be moved into new position
 // * @param target_item_id - LLUUID of the target item before which source item should be placed.
+/*
 void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id)
 {
 	LLInventoryModel::cat_array_t cats;
@@ -3301,7 +3350,7 @@ void LLInventoryModel::rearrangeFavoriteLandmarks(const LLUUID& source_item_id,
 
 	saveItemsOrder(items);
 }
-
+*/
 //----------------------------------------------------------------------------
 
 // *NOTE: DEBUG functionality
diff --git a/indra/newview/llinventorymodel.h b/indra/newview/llinventorymodel.h
index 8382e875b48690a67c87feefa92ea03747aac248..8aac879a93780c1e9b27296b6589905b9684d938 100644
--- a/indra/newview/llinventorymodel.h
+++ b/indra/newview/llinventorymodel.h
@@ -84,7 +84,7 @@ class LLInventoryModel
 	public:
 		fetchInventoryResponder(const LLSD& request_sd) : mRequestSD(request_sd) {};
 		void result(const LLSD& content);			
-		void error(U32 status, const std::string& reason);
+		void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	protected:
 		LLSD mRequestSD;
 	};
@@ -234,8 +234,10 @@ class LLInventoryModel
 	//    on the fly if one does not exist. *NOTE: if find_in_library is true it 
 	//    will search in the user's library folder instead of "My Inventory"
 	const LLUUID findCategoryUUIDForType(LLFolderType::EType preferred_type, 
-										 bool create_folder = true, 
-										 bool find_in_library = false);
+										 bool create_folder = true);
+	//    will search in the user's library folder instead of "My Inventory"
+	const LLUUID findLibraryCategoryUUIDForType(LLFolderType::EType preferred_type, 
+												bool create_folder = true);
 	
 	// Get whatever special folder this object is a child of, if any.
 	const LLViewerInventoryCategory *getFirstNondefaultParent(const LLUUID& obj_id) const;
@@ -362,14 +364,11 @@ class LLInventoryModel
 	// Returns end() of the vector if not found.
 	static LLInventoryModel::item_array_t::iterator findItemIterByUUID(LLInventoryModel::item_array_t& items, const LLUUID& id);
 
-	// Saves current order of the passed items using inventory item sort field.
-	// Resets 'items' sort fields and saves them on server.
-	// Is used to save order for Favorites folder.
-	void saveItemsOrder(const LLInventoryModel::item_array_t& items);
 
 	// Rearranges Landmarks inside Favorites folder.
 	// Moves source landmark before target one.
 	void rearrangeFavoriteLandmarks(const LLUUID& source_item_id, const LLUUID& target_item_id);
+	//void saveItemsOrder(const LLInventoryModel::item_array_t& items);
 
 	//--------------------------------------------------------------------
 	// Creation
diff --git a/indra/newview/llinventorymodelbackgroundfetch.cpp b/indra/newview/llinventorymodelbackgroundfetch.cpp
index f4d0110b0f478114b74ea91d7fb3ed635355713a..f2b39e71863d35f0f962f47d78677b2031d90f75 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.cpp
+++ b/indra/newview/llinventorymodelbackgroundfetch.cpp
@@ -183,7 +183,7 @@ void LLInventoryModelBackgroundFetch::backgroundFetchCB(void *)
 
 void LLInventoryModelBackgroundFetch::backgroundFetch()
 {
-	if (mBackgroundFetchActive && gAgent.getRegion())
+	if (mBackgroundFetchActive && gAgent.getRegion() && gAgent.getRegion()->capabilitiesReceived())
 	{
 		// If we'll be using the capability, we'll be sending batches and the background thing isn't as important.
 		if (gSavedSettings.getBOOL("UseHTTPInventory")) 
@@ -366,7 +366,7 @@ class LLInventoryModelFetchItemResponder : public LLInventoryModel::fetchInvento
 public:
 	LLInventoryModelFetchItemResponder(const LLSD& request_sd) : LLInventoryModel::fetchInventoryResponder(request_sd) {};
 	void result(const LLSD& content);			
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 };
 
 void LLInventoryModelFetchItemResponder::result( const LLSD& content )
@@ -375,9 +375,9 @@ void LLInventoryModelFetchItemResponder::result( const LLSD& content )
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
-void LLInventoryModelFetchItemResponder::error( U32 status, const std::string& reason )
+void LLInventoryModelFetchItemResponder::errorWithContent( U32 status, const std::string& reason, const LLSD& content )
 {
-	LLInventoryModel::fetchInventoryResponder::error(status, reason);
+	LLInventoryModel::fetchInventoryResponder::errorWithContent(status, reason, content);
 	LLInventoryModelBackgroundFetch::instance().incrFetchCount(-1);
 }
 
@@ -391,7 +391,7 @@ class LLInventoryModelFetchDescendentsResponder: public LLHTTPClient::Responder
 	{};
 	//LLInventoryModelFetchDescendentsResponder() {};
 	void result(const LLSD& content);
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 protected:
 	BOOL getIsRecursive(const LLUUID& cat_id) const;
 private:
@@ -529,12 +529,12 @@ void LLInventoryModelFetchDescendentsResponder::result(const LLSD& content)
 }
 
 // If we get back an error (not found, etc...), handle it here.
-void LLInventoryModelFetchDescendentsResponder::error(U32 status, const std::string& reason)
+void LLInventoryModelFetchDescendentsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	LLInventoryModelBackgroundFetch *fetcher = LLInventoryModelBackgroundFetch::getInstance();
 
-	llinfos << "LLInventoryModelFetchDescendentsResponder::error "
-		<< status << ": " << reason << llendl;
+	llinfos << "LLInventoryModelFetchDescendentsResponder::error [status:"
+			<< status << "]: " << content << llendl;
 						
 	fetcher->incrFetchCount(-1);
 
@@ -564,7 +564,6 @@ BOOL LLInventoryModelFetchDescendentsResponder::getIsRecursive(const LLUUID& cat
 {
 	return (std::find(mRecursiveCatUUIDs.begin(),mRecursiveCatUUIDs.end(), cat_id) != mRecursiveCatUUIDs.end());
 }
-
 // Bundle up a bunch of requests to send all at once.
 // static   
 void LLInventoryModelBackgroundFetch::bulkFetch()
@@ -687,20 +686,23 @@ void LLInventoryModelBackgroundFetch::bulkFetch()
 	{
 		if (folder_count)
 		{
-			std::string url = region->getCapability("FetchInventoryDescendents2");   
-			mFetchCount++;
-			if (folder_request_body["folders"].size())
-			{
-				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
-				LLHTTPClient::post(url, folder_request_body, fetcher, 300.0);
-			}
-			if (folder_request_body_lib["folders"].size())
+			std::string url = region->getCapability("FetchInventoryDescendents2");   			
+			if ( !url.empty() )
 			{
-				std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");
+				mFetchCount++;
+				if (folder_request_body["folders"].size())
+				{
+					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body, recursive_cats);
+					LLHTTPClient::post(url, folder_request_body, fetcher, 300.0);
+				}
+				if (folder_request_body_lib["folders"].size())
+				{
+					std::string url_lib = gAgent.getRegion()->getCapability("FetchLibDescendents2");
 
-				LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
-				LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0);
-			}
+					LLInventoryModelFetchDescendentsResponder *fetcher = new LLInventoryModelFetchDescendentsResponder(folder_request_body_lib, recursive_cats);
+					LLHTTPClient::post(url_lib, folder_request_body_lib, fetcher, 300.0);
+				}
+			}					
 		}
 		if (item_count)
 		{
diff --git a/indra/newview/llinventorypanel.cpp b/indra/newview/llinventorypanel.cpp
index f7567baa2b81da4dddfcf332964c4978ab6e04ff..cf1fd4c0d08d43778c1de8930eb6dbc7210b803a 100644
--- a/indra/newview/llinventorypanel.cpp
+++ b/indra/newview/llinventorypanel.cpp
@@ -38,11 +38,13 @@
 #include "llfloaterreg.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfolderview.h"
-#include "llimfloater.h"
+#include "llfolderviewitem.h"
+#include "llfloaterimcontainer.h"
 #include "llimview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodelbackgroundfetch.h"
+#include "llpreview.h"
 #include "llsidepanelinventory.h"
 #include "lltrans.h"
 #include "llviewerattachmenu.h"
@@ -54,8 +56,16 @@ static LLDefaultChildRegistry::Register<LLInventoryPanel> r("inventory_panel");
 const std::string LLInventoryPanel::DEFAULT_SORT_ORDER = std::string("InventorySortOrder");
 const std::string LLInventoryPanel::RECENTITEMS_SORT_ORDER = std::string("RecentItemsSortOrder");
 const std::string LLInventoryPanel::INHERIT_SORT_ORDER = std::string("");
-static const LLInventoryFVBridgeBuilder INVENTORY_BRIDGE_BUILDER;
+static const LLInventoryFolderViewModelBuilder INVENTORY_BRIDGE_BUILDER;
 
+// statics 
+bool LLInventoryPanel::sColorSetInitialized = false;
+LLUIColor LLInventoryPanel::sDefaultColor;
+LLUIColor LLInventoryPanel::sDefaultHighlightColor;
+LLUIColor LLInventoryPanel::sLibraryColor;
+LLUIColor LLInventoryPanel::sLinkColor;
+
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // Class LLInventoryPanelObserver
@@ -135,76 +145,86 @@ LLInventoryPanel::LLInventoryPanel(const LLInventoryPanel::Params& p) :
 	mAllowMultiSelect(p.allow_multi_select),
 	mShowItemLinkOverlays(p.show_item_link_overlays),
 	mShowEmptyMessage(p.show_empty_message),
-	mShowLoadStatus(p.show_load_status),
 	mViewsInitialized(false),
 	mInvFVBridgeBuilder(NULL)
 {
 	mInvFVBridgeBuilder = &INVENTORY_BRIDGE_BUILDER;
 
-	// contex menu callbacks
+	if (!sColorSetInitialized)
+	{
+		sDefaultColor = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+		sDefaultHighlightColor = LLUIColorTable::instance().getColor("MenuItemHighlightFgColor", DEFAULT_WHITE);
+		sLibraryColor = LLUIColorTable::instance().getColor("InventoryItemLibraryColor", DEFAULT_WHITE);
+		sLinkColor = LLUIColorTable::instance().getColor("InventoryItemLinkColor", DEFAULT_WHITE);
+		sColorSetInitialized = true;
+	}
+	
+	// context menu callbacks
 	mCommitCallbackRegistrar.add("Inventory.DoToSelected", boost::bind(&LLInventoryPanel::doToSelected, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.EmptyTrash", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyTrash", LLFolderType::FT_TRASH));
 	mCommitCallbackRegistrar.add("Inventory.EmptyLostAndFound", boost::bind(&LLInventoryModel::emptyFolderType, &gInventory, "ConfirmEmptyLostAndFound", LLFolderType::FT_LOST_AND_FOUND));
 	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&LLInventoryPanel::doCreate, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&LLInventoryPanel::attachObject, this, _2));
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&LLInventoryPanel::beginIMSession, this));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 
 }
 
-void LLInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
+LLFolderView * LLInventoryPanel::createFolderRoot(LLUUID root_id )
 {
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	std::string start_folder_name(params.start_folder());
-	
-	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(start_folder_name);
-
-	LLUUID root_id;
-
-	if ("LIBRARY" == params.start_folder())
-	{
-		root_id = gInventory.getLibraryRootFolderID();
-	}
-	else
-	{
-		root_id = (preferred_type != LLFolderType::FT_NONE)
-				? gInventory.findCategoryUUIDForType(preferred_type, false, false) 
-				: LLUUID::null;
-	}
-	
-	if ((root_id == LLUUID::null) && !start_folder_name.empty())
-	{
-		llwarns << "No category found that matches start_folder: " << start_folder_name << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
+    LLFolderView::Params p(mParams.folder_view);
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = this;
+    p.tool_tip = p.name;
+    p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
 																	LLAssetType::AT_CATEGORY,
 																	LLInventoryType::IT_CATEGORY,
 																	this,
+																	&mInventoryViewModel,
 																	NULL,
 																	root_id);
+    p.view_model = &mInventoryViewModel;
+    p.use_label_suffix = mParams.use_label_suffix;
+    p.allow_multiselect = mAllowMultiSelect;
+    p.show_empty_message = mShowEmptyMessage;
+    p.show_item_link_overlays = mShowItemLinkOverlays;
+    p.root = NULL;
+    p.options_menu = "menu_inventory.xml";
 	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
+    return LLUICtrlFactory::create<LLFolderView>(p);
 }
 
 void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 {
+	// save off copy of params
+	mParams = params;
+	// Clear up the root view
+	// Note: This needs to be done *before* we build the new folder view 
+	LLUUID root_id = getRootFolderID();
+	if (mFolderRoot)
+	{
+		removeItemID(root_id);
+		mFolderRoot->destroyView();
+		mFolderRoot = NULL;
+	}
+
 	mCommitCallbackRegistrar.pushScope(); // registered as a widget; need to push callback scope ourselves
+	{
+		// Determine the root folder in case specified, and
+		// build the views starting with that folder.
+		mFolderRoot = createFolderRoot(root_id);
 	
-	buildFolderView(params);
-
+		addItemID(root_id, mFolderRoot);
+	}
 	mCommitCallbackRegistrar.popScope();
-	
 	mFolderRoot->setCallbackRegistrar(&mCommitCallbackRegistrar);
 	
 	// Scroller
-	{
 		LLRect scroller_view_rect = getRect();
 		scroller_view_rect.translate(-scroller_view_rect.mLeft, -scroller_view_rect.mBottom);
-		LLScrollContainer::Params scroller_params(params.scroll());
+	LLScrollContainer::Params scroller_params(mParams.scroll());
 		scroller_params.rect(scroller_view_rect);
 		mScroller = LLUICtrlFactory::create<LLFolderViewScrollContainer>(scroller_params);
 		addChild(mScroller);
@@ -212,7 +232,6 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 		mFolderRoot->setScrollContainer(mScroller);
 		mFolderRoot->setFollowsAll();
 		mFolderRoot->addChild(mFolderRoot->mStatusTextBox);
-	}
 
 	// Set up the callbacks from the inventory we're viewing, and then build everything.
 	mInventoryObserver = new LLInventoryPanelObserver(this);
@@ -227,6 +246,7 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	{
 		initializeViews();
 	}
+	
 	gIdleCallbacks.addFunction(onIdle, (void*)this);
 
 	if (mSortOrderSetting != INHERIT_SORT_ORDER)
@@ -239,32 +259,31 @@ void LLInventoryPanel::initFromParams(const LLInventoryPanel::Params& params)
 	}
 
 	// hide inbox
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_INBOX));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << LLFolderType::FT_OUTBOX));
 
 	// set the filter for the empty folder if the debug setting is on
 	if (gSavedSettings.getBOOL("DebugHideEmptySystemFolders"))
 	{
-		getFilter()->setFilterEmptySystemFolders();
+		getFilter().setFilterEmptySystemFolders();
 	}
 	
 	// keep track of the clipboard state so that we avoid filtering too much
 	mClipboardState = LLClipboard::instance().getGeneration();
 	
 	// Initialize base class params.
-	LLPanel::initFromParams(params);
+	LLPanel::initFromParams(mParams);
 }
 
 LLInventoryPanel::~LLInventoryPanel()
 {
-	if (mFolderRoot)
-	{
-		U32 sort_order = mFolderRoot->getSortOrder();
+	gIdleCallbacks.deleteFunction(idle, this);
+
+	U32 sort_order = getFolderViewModel()->getSorter().getSortOrder();
 		if (mSortOrderSetting != INHERIT_SORT_ORDER)
 		{
 			gSavedSettings.setU32(mSortOrderSetting, sort_order);
 		}
-	}
 
 	gIdleCallbacks.deleteFunction(onIdle, this);
 
@@ -280,82 +299,68 @@ LLInventoryPanel::~LLInventoryPanel()
 void LLInventoryPanel::draw()
 {
 	// Select the desired item (in case it wasn't loaded when the selection was requested)
-	mFolderRoot->updateSelection();
-	
-	// Nudge the filter if the clipboard state changed
-	if (mClipboardState != LLClipboard::instance().getGeneration())
-	{
-		mClipboardState = LLClipboard::instance().getGeneration();
-		getFilter()->setModified(LLClipboard::instance().isCutMode() ? LLInventoryFilter::FILTER_MORE_RESTRICTIVE : LLInventoryFilter::FILTER_LESS_RESTRICTIVE);
-	}
+	updateSelection();
 	
 	LLPanel::draw();
 }
 
-LLInventoryFilter* LLInventoryPanel::getFilter()
+const LLInventoryFilter& LLInventoryPanel::getFilter() const
 {
-	if (mFolderRoot) 
-	{
-		return mFolderRoot->getFilter();
-	}
-	return NULL;
+	return getFolderViewModel()->getFilter();
 }
 
-const LLInventoryFilter* LLInventoryPanel::getFilter() const
+LLInventoryFilter& LLInventoryPanel::getFilter()
 {
-	if (mFolderRoot)
-	{
-		return mFolderRoot->getFilter();
-	}
-	return NULL;
+	return getFolderViewModel()->getFilter();
 }
 
 void LLInventoryPanel::setFilterTypes(U64 types, LLInventoryFilter::EFilterType filter_type)
 {
 	if (filter_type == LLInventoryFilter::FILTERTYPE_OBJECT)
-		getFilter()->setFilterObjectTypes(types);
+		getFilter().setFilterObjectTypes(types);
 	if (filter_type == LLInventoryFilter::FILTERTYPE_CATEGORY)
-		getFilter()->setFilterCategoryTypes(types);
+		getFilter().setFilterCategoryTypes(types);
 }
 
 U32 LLInventoryPanel::getFilterObjectTypes() const 
 { 
-	return mFolderRoot->getFilterObjectTypes(); 
+	return getFilter().getFilterObjectTypes();
 }
 
 U32 LLInventoryPanel::getFilterPermMask() const 
 { 
-	return mFolderRoot->getFilterPermissions(); 
+	return getFilter().getFilterPermissions();
 }
 
 
 void LLInventoryPanel::setFilterPermMask(PermissionMask filter_perm_mask)
 {
-	getFilter()->setFilterPermissions(filter_perm_mask);
+	getFilter().setFilterPermissions(filter_perm_mask);
 }
 
 void LLInventoryPanel::setFilterWearableTypes(U64 types)
 {
-	getFilter()->setFilterWearableTypes(types);
+	getFilter().setFilterWearableTypes(types);
 }
 
 void LLInventoryPanel::setFilterSubString(const std::string& string)
 {
-	getFilter()->setFilterSubString(string);
+	getFilter().setFilterSubString(string);
 }
 
 const std::string LLInventoryPanel::getFilterSubString() 
 { 
-	return mFolderRoot->getFilterSubString(); 
+	return getFilter().getFilterSubString();
 }
 
 
 void LLInventoryPanel::setSortOrder(U32 order)
 {
-	getFilter()->setSortOrder(order);
-	if (getFilter()->isModified())
+    LLInventorySort sorter(order);
+	if (order != getFolderViewModel()->getSorter().getSortOrder())
 	{
-		mFolderRoot->setSortOrder(order);
+		getFolderViewModel()->setSorter(sorter);
+		mFolderRoot->arrangeAll();
 		// try to keep selection onscreen, even if it wasn't to start with
 		mFolderRoot->scrollToShowSelection();
 	}
@@ -363,37 +368,32 @@ void LLInventoryPanel::setSortOrder(U32 order)
 
 U32 LLInventoryPanel::getSortOrder() const 
 { 
-	return mFolderRoot->getSortOrder(); 
-}
-
-void LLInventoryPanel::requestSort()
-{
-	mFolderRoot->requestSort();
+	return getFolderViewModel()->getSorter().getSortOrder();
 }
 
 void LLInventoryPanel::setSinceLogoff(BOOL sl)
 {
-	getFilter()->setDateRangeLastLogoff(sl);
+	getFilter().setDateRangeLastLogoff(sl);
 }
 
 void LLInventoryPanel::setHoursAgo(U32 hours)
 {
-	getFilter()->setHoursAgo(hours);
+	getFilter().setHoursAgo(hours);
 }
 
 void LLInventoryPanel::setFilterLinks(U64 filter_links)
 {
-	getFilter()->setFilterLinks(filter_links);
+	getFilter().setFilterLinks(filter_links);
 }
 
 void LLInventoryPanel::setShowFolderState(LLInventoryFilter::EFolderShow show)
 {
-	getFilter()->setShowFolderState(show);
+	getFilter().setShowFolderState(show);
 }
 
 LLInventoryFilter::EFolderShow LLInventoryPanel::getShowFolderState()
 {
-	return getFilter()->getShowFolderState();
+	return getFilter().getShowFolderState();
 }
 
 void LLInventoryPanel::modelChanged(U32 mask)
@@ -401,8 +401,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	static LLFastTimer::DeclareTimer FTM_REFRESH("Inventory Refresh");
 	LLFastTimer t2(FTM_REFRESH);
 
-	bool handled = false;
-
 	if (!mViewsInitialized) return;
 	
 	const LLInventoryModel* model = getModel();
@@ -417,22 +415,30 @@ void LLInventoryPanel::modelChanged(U32 mask)
 	{
 		const LLUUID& item_id = (*items_iter);
 		const LLInventoryObject* model_item = model->getObject(item_id);
-		LLFolderViewItem* view_item = mFolderRoot->getItemByID(item_id);
+		LLFolderViewItem* view_item = getItemByID(item_id);
+		LLFolderViewModelItemInventory* viewmodel_item = 
+			static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
 
 		// LLFolderViewFolder is derived from LLFolderViewItem so dynamic_cast from item
 		// to folder is the fast way to get a folder without searching through folders tree.
-		LLFolderViewFolder* view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+		LLFolderViewFolder* view_folder = NULL;
+
+		// Check requires as this item might have already been deleted
+		// as a child of its deleted parent.
+		if (model_item && view_item)
+		{
+			view_folder = dynamic_cast<LLFolderViewFolder*>(view_item);
+		}
 
 		//////////////////////////////
 		// LABEL Operation
 		// Empty out the display name for relabel.
 		if (mask & LLInventoryObserver::LABEL)
 		{
-			handled = true;
 			if (view_item)
 			{
 				// Request refresh on this item (also flags for filtering)
-				LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getListener();
+				LLInvFVBridge* bridge = (LLInvFVBridge*)view_item->getViewModelItem();
 				if(bridge)
 				{	// Clear the display name first, so it gets properly re-built during refresh()
 					bridge->clearDisplayName();
@@ -447,12 +453,15 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		// Destroy and regenerate the UI.
 		if (mask & LLInventoryObserver::REBUILD)
 		{
-			handled = true;
-			if (model_item && view_item)
+			if (model_item && view_item && viewmodel_item)
 			{
+				const LLUUID& idp = viewmodel_item->getUUID();
 				view_item->destroyView();
+				removeItemID(idp);
 			}
 			view_item = buildNewViews(item_id);
+			viewmodel_item = 
+				static_cast<LLFolderViewModelItemInventory*>(view_item ? view_item->getViewModelItem() : NULL);
 			view_folder = dynamic_cast<LLFolderViewFolder *>(view_item);
 		}
 
@@ -474,7 +483,7 @@ void LLInventoryPanel::modelChanged(U32 mask)
 		{
 			if (view_folder)
 			{
-				view_folder->requestSort();
+				view_folder->getViewModelItem()->requestSort();
 			}
 		}	
 
@@ -487,8 +496,6 @@ void LLInventoryPanel::modelChanged(U32 mask)
 					LLInventoryObserver::ADD |
 					LLInventoryObserver::REMOVE))
 		{
-			handled = true;
-
 			//////////////////////////////
 			// ADD Operation
 			// Item exists in memory but a UI element hasn't been created for it.
@@ -509,20 +516,24 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			else if (model_item && view_item)
 			{
 				// Don't process the item if it is the root
-				if (view_item->getRoot() != view_item)
+				if (view_item->getParentFolder())
 				{
-					LLFolderViewFolder* new_parent = (LLFolderViewFolder*)mFolderRoot->getItemByID(model_item->getParentUUID());
+					LLFolderViewFolder* new_parent =   (LLFolderViewFolder*)getItemByID(model_item->getParentUUID());
 					// Item has been moved.
 					if (view_item->getParentFolder() != new_parent)
 					{
 						if (new_parent != NULL)
 						{
 							// Item is to be moved and we found its new parent in the panel's directory, so move the item's UI.
-							view_item->getParentFolder()->extractItem(view_item);
-							view_item->addToFolder(new_parent, mFolderRoot);
+							view_item->addToFolder(new_parent);
+							addItemID(viewmodel_item->getUUID(), view_item);
 						}
 						else 
 						{
+							// Remove the item ID before destroying the view because the view-model-item gets
+							// destroyed when the view is destroyed
+                            removeItemID(viewmodel_item->getUUID());
+
 							// Item is to be moved outside the panel's directory (e.g. moved to trash for a panel that 
 							// doesn't include trash).  Just remove the item's UI.
 							view_item->destroyView();
@@ -534,9 +545,10 @@ void LLInventoryPanel::modelChanged(U32 mask)
 			//////////////////////////////
 			// REMOVE Operation
 			// This item has been removed from memory, but its associated UI element still exists.
-			else if (!model_item && view_item)
+			else if (!model_item && view_item && viewmodel_item)
 			{
 				// Remove the item's UI.
+                removeItemID(viewmodel_item->getUUID());
 				view_item->destroyView();
 			}
 		}
@@ -548,6 +560,43 @@ LLFolderView* LLInventoryPanel::getRootFolder()
 	return mFolderRoot; 
 }
 
+LLUUID LLInventoryPanel::getRootFolderID()
+{
+	if (mFolderRoot && mFolderRoot->getViewModelItem())
+	{
+		return static_cast<LLFolderViewModelItemInventory*>(mFolderRoot->getViewModelItem())->getUUID();
+
+	}
+	else
+	{
+		LLUUID root_id;
+		if (mParams.start_folder.id.isChosen())
+		{
+			root_id = mParams.start_folder.id;
+		}
+		else
+		{
+			const LLFolderType::EType preferred_type = mParams.start_folder.type.isChosen() 
+				? mParams.start_folder.type
+				: LLViewerFolderType::lookupTypeFromNewCategoryName(mParams.start_folder.name);
+
+			if ("LIBRARY" == mParams.start_folder.name())
+			{
+				root_id = gInventory.getLibraryRootFolderID();
+			}
+			else if (preferred_type != LLFolderType::FT_NONE)
+			{
+				root_id = gInventory.findCategoryUUIDForType(preferred_type, false);
+				if (root_id.isNull())
+				{
+					llwarns << "Could not find folder of type " << preferred_type << llendl;
+					root_id.generateNewID();
+				}
+			}
+		}
+		return root_id;
+	}
+}
 
 // static
 void LLInventoryPanel::onIdle(void *userdata)
@@ -567,16 +616,73 @@ void LLInventoryPanel::onIdle(void *userdata)
 	}
 }
 
-const LLUUID& LLInventoryPanel::getRootFolderID() const
+struct DirtyFilterFunctor : public LLFolderViewFunctor
 {
-	return mFolderRoot->getListener()->getUUID();
+	/*virtual*/ void doFolder(LLFolderViewFolder* folder)
+	{
+		folder->getViewModelItem()->dirtyFilter();
+	}
+	/*virtual*/ void doItem(LLFolderViewItem* item)
+	{
+		item->getViewModelItem()->dirtyFilter();
+	}
+};
+
+void LLInventoryPanel::idle(void* user_data)
+{
+	LLInventoryPanel* panel = (LLInventoryPanel*)user_data;
+	// Nudge the filter if the clipboard state changed
+	if (panel->mClipboardState != LLClipboard::instance().getGeneration())
+	{
+		panel->mClipboardState = LLClipboard::instance().getGeneration();
+		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
+		LLFolderViewFolder* trash_folder = panel->getFolderByID(trash_id);
+		if (trash_folder)
+		{
+            DirtyFilterFunctor dirtyFilterFunctor;
+			trash_folder->applyFunctorToChildren(dirtyFilterFunctor);
+		}
+
+	}
+
+	panel->mFolderRoot->update();
+	// while dragging, update selection rendering to reflect single/multi drag status
+	if (LLToolDragAndDrop::getInstance()->hasMouseCapture())
+	{
+		EAcceptance last_accept = LLToolDragAndDrop::getInstance()->getLastAccept();
+		if (last_accept == ACCEPT_YES_SINGLE || last_accept == ACCEPT_YES_COPY_SINGLE)
+		{
+			panel->mFolderRoot->setShowSingleSelection(TRUE);
+		}
+		else
+		{
+			panel->mFolderRoot->setShowSingleSelection(FALSE);
+		}
+}
+	else
+	{
+		panel->mFolderRoot->setShowSingleSelection(FALSE);
+	}
 }
 
+
 void LLInventoryPanel::initializeViews()
 {
 	if (!gInventory.isInventoryUsable()) return;
 
-	rebuildViewsFor(getRootFolderID());
+	LLUUID root_id = getRootFolderID();
+	if (root_id.notNull())
+	{
+		buildNewViews(getRootFolderID());
+	}
+	else
+	{
+		// Default case: always add "My Inventory" first, "Library" second
+		buildNewViews(gInventory.getRootFolderID());		// My Inventory
+		buildNewViews(gInventory.getLibraryRootFolderID());	// Library
+	}
+
+	gIdleCallbacks.addFunction(idle, this);
 
 	mViewsInitialized = true;
 	
@@ -586,14 +692,14 @@ void LLInventoryPanel::initializeViews()
 	if (gAgent.isFirstLogin())
 	{
 		// Auto open the user's library
-		LLFolderViewFolder* lib_folder = mFolderRoot->getFolderByID(gInventory.getLibraryRootFolderID());
+		LLFolderViewFolder* lib_folder =   getFolderByID(gInventory.getLibraryRootFolderID());
 		if (lib_folder)
 		{
 			lib_folder->setOpen(TRUE);
 		}
 		
 		// Auto close the user's my inventory folder
-		LLFolderViewFolder* my_inv_folder = mFolderRoot->getFolderByID(gInventory.getRootFolderID());
+		LLFolderViewFolder* my_inv_folder =   getFolderByID(gInventory.getRootFolderID());
 		if (my_inv_folder)
 		{
 			my_inv_folder->setOpenArrangeRecursively(FALSE, LLFolderViewFolder::RECURSE_DOWN);
@@ -601,79 +707,35 @@ void LLInventoryPanel::initializeViews()
 	}
 }
 
-LLFolderViewItem* LLInventoryPanel::rebuildViewsFor(const LLUUID& id)
-{
-	// Destroy the old view for this ID so we can rebuild it.
-	LLFolderViewItem* old_view = mFolderRoot->getItemByID(id);
-	if (old_view)
-	{
-		old_view->destroyView();
-	}
-
-	return buildNewViews(id);
-}
-
-LLFolderView * LLInventoryPanel::createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix)
-{
-	LLRect folder_rect(0,
-					   0,
-					   getRect().getWidth(),
-					   0);
-
-	LLFolderView::Params p;
-	
-	p.name = getName();
-	p.title = getLabel();
-	p.rect = folder_rect;
-	p.parent_panel = this;
-	p.tool_tip = p.name;
-	p.listener =  bridge;
-	p.use_label_suffix = useLabelSuffix;
-	p.allow_multiselect = mAllowMultiSelect;
-	p.show_empty_message = mShowEmptyMessage;
-	p.show_load_status = mShowLoadStatus;
-
-	return LLUICtrlFactory::create<LLFolderView>(p);
-}
 
 LLFolderViewFolder * LLInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
 {
-	LLFolderViewFolder::Params params;
+	LLFolderViewFolder::Params params(mParams.folder);
 
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
 
+	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
+	
 	return LLUICtrlFactory::create<LLFolderViewFolder>(params);
 }
 
 LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
 {
-	LLFolderViewItem::Params params;
+	LLFolderViewItem::Params params(mParams.item);
 	
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
 	params.creation_date = bridge->getCreationDate();
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
+
+	params.font_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultColor));
+	params.font_highlight_color = (bridge->isLibraryItem() ? sLibraryColor : (bridge->isLink() ? sLinkColor : sDefaultHighlightColor));
 	
 	return LLUICtrlFactory::create<LLFolderViewItem>(params);
 }
@@ -681,20 +743,15 @@ LLFolderViewItem * LLInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge
 LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 {
  	LLInventoryObject const* objectp = gInventory.getObject(id);
- 	LLUUID root_id = mFolderRoot->getListener()->getUUID();
- 	LLFolderViewFolder* parent_folder = NULL;
-	LLFolderViewItem* itemp = NULL;
 	
- 	if (id == root_id)
- 	{
- 		parent_folder = mFolderRoot;
- 	}
- 	else if (objectp)
- 	{
+	if (!objectp) return NULL;
+
+	LLFolderViewItem* folder_view_item = getItemByID(id);
+
  		const LLUUID &parent_id = objectp->getParentUUID();
- 		parent_folder = (LLFolderViewFolder*)mFolderRoot->getItemByID(parent_id);
+	LLFolderViewFolder* parent_folder = (LLFolderViewFolder*)getItemByID(parent_id);
   		
-  		if (parent_folder)
+ 	if (!folder_view_item && parent_folder)
   		{
   			if (objectp->getType() <= LLAssetType::AT_NONE ||
   				objectp->getType() >= LLAssetType::AT_COUNT)
@@ -712,16 +769,12 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				objectp->getType(),
   																				LLInventoryType::IT_CATEGORY,
   																				this,
+																			&mInventoryViewModel,
   																				mFolderRoot,
   																				objectp->getUUID());
   				if (new_listener)
   				{
-					LLFolderViewFolder* folderp = createFolderViewFolder(new_listener);
-					if (folderp)
-					{
-						folderp->setItemSortOrder(mFolderRoot->getSortOrder());
-					}
-  					itemp = folderp;
+				folder_view_item = createFolderViewFolder(new_listener);
   				}
   			}
   			else
@@ -732,28 +785,28 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
   																				item->getActualType(),
   																				item->getInventoryType(),
   																				this,
+																			&mInventoryViewModel,
   																				mFolderRoot,
   																				item->getUUID(),
   																				item->getFlags());
  
   				if (new_listener)
   				{
-					itemp = createFolderViewItem(new_listener);
+				folder_view_item = createFolderViewItem(new_listener);
   				}
   			}
  
-  			if (itemp)
+  	    if (folder_view_item)
   			{
-  				itemp->addToFolder(parent_folder, mFolderRoot);
-   			}
+            llassert(parent_folder != NULL);
+            folder_view_item->addToFolder(parent_folder);
+			addItemID(id, folder_view_item);
 		}
 	}
 
 	// If this is a folder, add the children of the folder and recursively add any 
 	// child folders.
-	if (id.isNull()
-		||	(objectp
-			&& objectp->getType() == LLAssetType::AT_CATEGORY))
+	if (folder_view_item && objectp->getType() == LLAssetType::AT_CATEGORY)
 	{
 		LLViewerInventoryCategory::cat_array_t* categories;
 		LLViewerInventoryItem::item_array_t* items;
@@ -770,7 +823,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 			}
 		}
 		
-		if(items && parent_folder)
+		if(items)
 		{
 			for (LLViewerInventoryItem::item_array_t::const_iterator item_iter = items->begin();
 				 item_iter != items->end();
@@ -783,7 +836,7 @@ LLFolderViewItem* LLInventoryPanel::buildNewViews(const LLUUID& id)
 		mInventory->unlockDirectDescendentArrays(id);
 	}
 	
-	return itemp;
+	return folder_view_item;
 }
 
 // bit of a hack to make sure the inventory is open.
@@ -794,8 +847,8 @@ void LLInventoryPanel::openStartFolderOrMyInventory()
 	{
 		LLFolderViewFolder *fchild = dynamic_cast<LLFolderViewFolder*>(child);
 		if (fchild
-			&& fchild->getListener()
-				&& fchild->getListener()->getUUID() == gInventory.getRootFolderID())
+			&& fchild->getViewModelItem()
+			&& fchild->getViewModelItem()->getName() == "My Inventory")
 		{
 			fchild->setOpen(TRUE);
 			break;
@@ -812,7 +865,7 @@ void LLInventoryPanel::openSelected()
 {
 	LLFolderViewItem* folder_item = mFolderRoot->getCurSelectedItem();
 	if(!folder_item) return;
-	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getListener();
+	LLInvFVBridge* bridge = (LLInvFVBridge*)folder_item->getViewModelItem();
 	if(!bridge) return;
 	bridge->openItem();
 }
@@ -916,7 +969,7 @@ void LLInventoryPanel::setSelection(const LLUUID& obj_id, BOOL take_keyboard_foc
 	{
 		return;
 	}
-	mFolderRoot->setSelectionByID(obj_id, take_keyboard_focus);
+	setSelectionByID(obj_id, take_keyboard_focus);
 }
 
 void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb) 
@@ -929,7 +982,7 @@ void LLInventoryPanel::setSelectCallback(const boost::function<void (const std::
 
 void LLInventoryPanel::clearSelection()
 {
-	mFolderRoot->clearSelection();
+	mSelectThisID.setNull();
 }
 
 void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& items, BOOL user_action)
@@ -938,7 +991,7 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 	mCompletionObserver->reset();
 	for (std::deque<LLFolderViewItem*>::const_iterator it = items.begin(); it != items.end(); ++it)
 	{
-		LLUUID id = (*it)->getListener()->getUUID();
+		LLUUID id = static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID();
 		LLViewerInventoryItem* inv_item = mInventory->getItem(id);
 
 		if (inv_item && !inv_item->isFinished())
@@ -958,40 +1011,34 @@ void LLInventoryPanel::onSelectionChange(const std::deque<LLFolderViewItem*>& it
 	}
 }
 
-void LLInventoryPanel::doToSelected(const LLSD& userdata)
-{
-	mFolderRoot->doToSelected(&gInventory, userdata);
-}
-
 void LLInventoryPanel::doCreate(const LLSD& userdata)
 {
 	reset_inventory_filter();
-	menu_create_inventory_item(mFolderRoot, LLFolderBridge::sSelf.get(), userdata);
+	menu_create_inventory_item(this, LLFolderBridge::sSelf.get(), userdata);
 }
 
 bool LLInventoryPanel::beginIMSession()
 {
-	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items =   mFolderRoot->getSelectionList();
 
 	std::string name;
 
 	LLDynamicArray<LLUUID> members;
 	EInstantMessage type = IM_SESSION_CONFERENCE_START;
 
-	std::set<LLUUID>::const_iterator iter;
+	std::set<LLFolderViewItem*>::const_iterator iter;
 	for (iter = selected_items.begin(); iter != selected_items.end(); iter++)
 	{
 
-		LLUUID item = *iter;
-		LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
+		LLFolderViewItem* folder_item = (*iter);
 			
 		if(folder_item) 
 		{
-			LLFolderViewEventListener* fve_listener = folder_item->getListener();
+			LLFolderViewModelItemInventory* fve_listener = static_cast<LLFolderViewModelItemInventory*>(folder_item->getViewModelItem());
 			if (fve_listener && (fve_listener->getInventoryType() == LLInventoryType::IT_CATEGORY))
 			{
 
-				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getListener();
+				LLFolderBridge* bridge = (LLFolderBridge*)folder_item->getViewModelItem();
 				if(!bridge) return true;
 				LLViewerInventoryCategory* cat = bridge->getCategory();
 				if(!cat) return true;
@@ -1025,9 +1072,7 @@ bool LLInventoryPanel::beginIMSession()
 			}
 			else
 			{
-				LLFolderViewItem* folder_item = mFolderRoot->getItemByID(item);
-				if(!folder_item) return true;
-				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getListener();
+				LLInvFVBridge* listenerp = (LLInvFVBridge*)folder_item->getViewModelItem();
 
 				if (listenerp->getInventoryType() == LLInventoryType::IT_CALLINGCARD)
 				{
@@ -1059,7 +1104,7 @@ bool LLInventoryPanel::beginIMSession()
 	LLUUID session_id = gIMMgr->addSession(name, type, members[0], members);
 	if (session_id != LLUUID::null)
 	{
-		LLIMFloater::show(session_id);
+		LLFloaterIMContainer::getInstance()->showConversation(session_id);
 	}
 		
 	return true;
@@ -1068,13 +1113,13 @@ bool LLInventoryPanel::beginIMSession()
 bool LLInventoryPanel::attachObject(const LLSD& userdata)
 {
 	// Copy selected item UUIDs to a vector.
-	std::set<LLUUID> selected_items = mFolderRoot->getSelectionList();
+	std::set<LLFolderViewItem*> selected_items = mFolderRoot->getSelectionList();
 	uuid_vec_t items;
-	for (std::set<LLUUID>::const_iterator set_iter = selected_items.begin(); 
+	for (std::set<LLFolderViewItem*>::const_iterator set_iter = selected_items.begin();
 		 set_iter != selected_items.end(); 
 		 ++set_iter)
 	{
-		items.push_back(*set_iter);
+		items.push_back(static_cast<LLFolderViewModelItemInventory*>((*set_iter)->getViewModelItem())->getUUID());
 	}
 
 	// Attach selected items.
@@ -1087,7 +1132,7 @@ bool LLInventoryPanel::attachObject(const LLSD& userdata)
 
 BOOL LLInventoryPanel::getSinceLogoff()
 {
-	return getFilter()->isSinceLogoff();
+	return getFilter().isSinceLogoff();
 }
 
 // DEBUG ONLY
@@ -1213,14 +1258,150 @@ void LLInventoryPanel::openInventoryPanelAndSetSelection(BOOL auto_open, const L
 
 void LLInventoryPanel::addHideFolderType(LLFolderType::EType folder_type)
 {
-	getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() & ~(1ULL << folder_type));
+	getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() & ~(1ULL << folder_type));
 }
 
 BOOL LLInventoryPanel::getIsHiddenFolderType(LLFolderType::EType folder_type) const
 {
-	return !(getFilter()->getFilterCategoryTypes() & (1ULL << folder_type));
+	return !(getFilter().getFilterCategoryTypes() & (1ULL << folder_type));
+}
+
+void LLInventoryPanel::addItemID( const LLUUID& id, LLFolderViewItem*   itemp )
+{
+	mItemMap[id] = itemp;
+}
+
+void LLInventoryPanel::removeItemID(const LLUUID& id)
+{
+	LLInventoryModel::cat_array_t categories;
+	LLInventoryModel::item_array_t items;
+	gInventory.collectDescendents(id, categories, items, TRUE);
+
+	mItemMap.erase(id);
+
+	for (LLInventoryModel::cat_array_t::iterator it = categories.begin(),    end_it = categories.end();
+		it != end_it;
+		++it)
+	{
+		mItemMap.erase((*it)->getUUID());
+}
+
+	for (LLInventoryModel::item_array_t::iterator it = items.begin(),   end_it  = items.end();
+		it != end_it;
+		++it)
+	{
+		mItemMap.erase((*it)->getUUID());
+	}
+}
+
+LLFastTimer::DeclareTimer FTM_GET_ITEM_BY_ID("Get FolderViewItem by ID");
+LLFolderViewItem* LLInventoryPanel::getItemByID(const LLUUID& id)
+{
+	LLFastTimer _(FTM_GET_ITEM_BY_ID);
+
+	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+	map_it = mItemMap.find(id);
+	if (map_it != mItemMap.end())
+	{
+		return map_it->second;
+	}
+
+	return NULL;
+}
+
+LLFolderViewFolder* LLInventoryPanel::getFolderByID(const LLUUID& id)
+{
+	LLFolderViewItem* item = getItemByID(id);
+	return dynamic_cast<LLFolderViewFolder*>(item);
+}
+
+
+void LLInventoryPanel::setSelectionByID( const LLUUID& obj_id, BOOL    take_keyboard_focus )
+{
+	LLFolderViewItem* itemp = getItemByID(obj_id);
+	if(itemp && itemp->getViewModelItem())
+	{
+		itemp->arrangeAndSet(TRUE, take_keyboard_focus);
+		mSelectThisID.setNull();
+		return;
+	}
+	else
+	{
+		// save the desired item to be selected later (if/when ready)
+		mSelectThisID = obj_id;
+	}
+}
+
+void LLInventoryPanel::updateSelection()
+{
+	if (mSelectThisID.notNull())
+	{
+		setSelectionByID(mSelectThisID, false);
+	}
 }
 
+void LLInventoryPanel::doToSelected(const LLSD& userdata)
+{
+	LLInventoryAction::doToSelected(mInventory, mFolderRoot, userdata.asString());
+
+	return;
+}
+
+BOOL LLInventoryPanel::handleKeyHere( KEY key, MASK mask )
+{
+	BOOL handled = FALSE;
+	switch (key)
+	{
+	case KEY_RETURN:
+		// Open selected items if enter key hit on the inventory panel
+		if (mask == MASK_NONE)
+		{
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "open");
+			handled = TRUE;
+		}
+		break;
+	case KEY_DELETE:
+	case KEY_BACKSPACE:
+		// Delete selected items if delete or backspace key hit on the inventory panel
+		// Note: on Mac laptop keyboards, backspace and delete are one and the same
+		if (isSelectionRemovable() && (mask == MASK_NONE))
+		{
+			LLInventoryAction::doToSelected(mInventory, mFolderRoot, "delete");
+			handled = TRUE;
+		}
+		break;
+	}
+	return handled;
+}
+
+bool LLInventoryPanel::isSelectionRemovable()
+{
+	bool can_delete = false;
+	if (mFolderRoot)
+	{
+		std::set<LLFolderViewItem*> selection_set = mFolderRoot->getSelectionList();
+		if (!selection_set.empty()) 
+		{
+			can_delete = true;
+			for (std::set<LLFolderViewItem*>::iterator iter = selection_set.begin();
+				 iter != selection_set.end();
+				 ++iter)
+			{
+				LLFolderViewItem *item = *iter;
+				const LLFolderViewModelItemInventory *listener = static_cast<const LLFolderViewModelItemInventory*>(item->getViewModelItem());
+				if (!listener)
+				{
+					can_delete = false;
+				}
+				else
+				{
+					can_delete &= listener->isItemRemovable() && !listener->isItemInTrash();
+				}
+			}
+		}
+	}
+	return can_delete;
+}
 
 /************************************************************************/
 /* Recent Inventory Panel related class                                 */
@@ -1239,7 +1420,7 @@ class LLInventoryRecentItemsPanel : public LLInventoryPanel
 	{
 		LLInventoryPanel::initFromParams(p);
 		// turn on inbox for recent items
-		getFilter()->setFilterCategoryTypes(getFilter()->getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
+		getFilter().setFilterCategoryTypes(getFilter().getFilterCategoryTypes() | (1ULL << LLFolderType::FT_INBOX));
 	}
 
 protected:
@@ -1254,3 +1435,34 @@ LLInventoryRecentItemsPanel::LLInventoryRecentItemsPanel( const Params& params)
 	mInvFVBridgeBuilder = &RECENT_ITEMS_BUILDER;
 }
 
+namespace LLInitParam
+{
+	void TypeValues<LLFolderType::EType>::declareValues()
+	{
+		declare(LLFolderType::lookup(LLFolderType::FT_TEXTURE)          , LLFolderType::FT_TEXTURE);
+		declare(LLFolderType::lookup(LLFolderType::FT_SOUND)            , LLFolderType::FT_SOUND);
+		declare(LLFolderType::lookup(LLFolderType::FT_CALLINGCARD)      , LLFolderType::FT_CALLINGCARD);
+		declare(LLFolderType::lookup(LLFolderType::FT_LANDMARK)         , LLFolderType::FT_LANDMARK);
+		declare(LLFolderType::lookup(LLFolderType::FT_CLOTHING)         , LLFolderType::FT_CLOTHING);
+		declare(LLFolderType::lookup(LLFolderType::FT_OBJECT)           , LLFolderType::FT_OBJECT);
+		declare(LLFolderType::lookup(LLFolderType::FT_NOTECARD)         , LLFolderType::FT_NOTECARD);
+		declare(LLFolderType::lookup(LLFolderType::FT_ROOT_INVENTORY)   , LLFolderType::FT_ROOT_INVENTORY);
+		declare(LLFolderType::lookup(LLFolderType::FT_LSL_TEXT)         , LLFolderType::FT_LSL_TEXT);
+		declare(LLFolderType::lookup(LLFolderType::FT_BODYPART)         , LLFolderType::FT_BODYPART);
+		declare(LLFolderType::lookup(LLFolderType::FT_TRASH)            , LLFolderType::FT_TRASH);
+		declare(LLFolderType::lookup(LLFolderType::FT_SNAPSHOT_CATEGORY), LLFolderType::FT_SNAPSHOT_CATEGORY);
+		declare(LLFolderType::lookup(LLFolderType::FT_LOST_AND_FOUND)   , LLFolderType::FT_LOST_AND_FOUND);
+		declare(LLFolderType::lookup(LLFolderType::FT_ANIMATION)        , LLFolderType::FT_ANIMATION);
+		declare(LLFolderType::lookup(LLFolderType::FT_GESTURE)          , LLFolderType::FT_GESTURE);
+		declare(LLFolderType::lookup(LLFolderType::FT_FAVORITE)         , LLFolderType::FT_FAVORITE);
+		declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_START)   , LLFolderType::FT_ENSEMBLE_START);
+		declare(LLFolderType::lookup(LLFolderType::FT_ENSEMBLE_END)     , LLFolderType::FT_ENSEMBLE_END);
+		declare(LLFolderType::lookup(LLFolderType::FT_CURRENT_OUTFIT)   , LLFolderType::FT_CURRENT_OUTFIT);
+		declare(LLFolderType::lookup(LLFolderType::FT_OUTFIT)           , LLFolderType::FT_OUTFIT);
+		declare(LLFolderType::lookup(LLFolderType::FT_MY_OUTFITS)       , LLFolderType::FT_MY_OUTFITS);
+		declare(LLFolderType::lookup(LLFolderType::FT_MESH )            , LLFolderType::FT_MESH );
+		declare(LLFolderType::lookup(LLFolderType::FT_INBOX)            , LLFolderType::FT_INBOX);
+		declare(LLFolderType::lookup(LLFolderType::FT_OUTBOX)           , LLFolderType::FT_OUTBOX);
+		declare(LLFolderType::lookup(LLFolderType::FT_BASIC_ROOT)       , LLFolderType::FT_BASIC_ROOT);
+	}
+}
diff --git a/indra/newview/llinventorypanel.h b/indra/newview/llinventorypanel.h
index 6db59afb9b92a7a967a3bf5d81e4aeb30ac50b86..00a90325ad0161417bca2ac914bd69d2875cd2e7 100644
--- a/indra/newview/llinventorypanel.h
+++ b/indra/newview/llinventorypanel.h
@@ -30,6 +30,8 @@
 
 #include "llassetstorage.h"
 #include "lldarray.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodelinventory.h"
 #include "llfloater.h"
 #include "llinventory.h"
 #include "llinventoryfilter.h"
@@ -38,22 +40,19 @@
 #include "lluictrlfactory.h"
 #include <set>
 
-class LLFolderView;
-class LLFolderViewFolder;
-class LLFolderViewItem;
-class LLInventoryFilter;
-class LLInventoryModel;
 class LLInvFVBridge;
-class LLInventoryFVBridgeBuilder;
-class LLMenuBarGL;
-class LLCheckBoxCtrl;
-class LLSpinCtrl;
-class LLTextBox;
-class LLIconCtrl;
-class LLSaveFolderState;
-class LLFilterEditor;
-class LLTabContainer;
+class LLInventoryFolderViewModelBuilder;
 class LLInvPanelComplObserver;
+class LLFolderViewModelInventory;
+
+namespace LLInitParam
+{
+	template<>
+	struct TypeValues<LLFolderType::EType> : public TypeValuesHelper<LLFolderType::EType>
+	{
+		static void declareValues();
+	};
+}
 
 class LLInventoryPanel : public LLPanel
 {
@@ -74,6 +73,19 @@ class LLInventoryPanel : public LLPanel
 		{}
 	};
 
+	struct StartFolder : public LLInitParam::ChoiceBlock<StartFolder>
+	{
+		Alternative<std::string>			name;
+		Alternative<LLUUID>					id;
+		Alternative<LLFolderType::EType>	type;
+
+		StartFolder()
+		:	name("name"), 
+			id("id"),
+			type("type")
+		{}
+	};
+
 	struct Params 
 	:	public LLInitParam::Block<Params, LLPanel::Params>
 	{
@@ -82,12 +94,14 @@ class LLInventoryPanel : public LLPanel
 		Optional<bool>						allow_multi_select;
 		Optional<bool>						show_item_link_overlays;
 		Optional<Filter>					filter;
-		Optional<std::string>               start_folder;
+		Optional<StartFolder>               start_folder;
 		Optional<bool>						use_label_suffix;
 		Optional<bool>						show_empty_message;
-		Optional<bool>						show_load_status;
 		Optional<LLScrollContainer::Params>	scroll;
 		Optional<bool>						accepts_drag_and_drop;
+		Optional<LLFolderView::Params>		folder_view;
+		Optional<LLFolderViewFolder::Params> folder;
+		Optional<LLFolderViewItem::Params>	 item;
 
 		Params()
 		:	sort_order_setting("sort_order_setting"),
@@ -98,27 +112,38 @@ class LLInventoryPanel : public LLPanel
 			start_folder("start_folder"),
 			use_label_suffix("use_label_suffix", true),
 			show_empty_message("show_empty_message", true),
-			show_load_status("show_load_status"),
 			scroll("scroll"),
-			accepts_drag_and_drop("accepts_drag_and_drop")
+			accepts_drag_and_drop("accepts_drag_and_drop"),
+			folder_view("folder_view"),
+			folder("folder"),
+			item("item")
 		{}
 	};
 
+	struct InventoryState : public LLInitParam::Block<InventoryState>
+	{
+		Mandatory<LLInventoryFilter::Params> filter;
+		Mandatory<LLInventorySort::Params> sort;
+	};
+
 	//--------------------------------------------------------------------
 	// Initialization
 	//--------------------------------------------------------------------
 protected:
 	LLInventoryPanel(const Params&);
 	void initFromParams(const Params&);
+
 	friend class LLUICtrlFactory;
 public:
 	virtual ~LLInventoryPanel();
 
 public:
 	LLInventoryModel* getModel() { return mInventory; }
+	LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
 
 	// LLView methods
 	void draw();
+	/*virtual*/ BOOL handleKeyHere( KEY key, MASK mask );
 	BOOL handleHover(S32 x, S32 y, MASK mask);
 	BOOL handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 								   EDragAndDropType cargo_type,
@@ -137,8 +162,9 @@ class LLInventoryPanel : public LLPanel
 	void setSelection(const LLUUID& obj_id, BOOL take_keyboard_focus);
 	void setSelectCallback(const boost::function<void (const std::deque<LLFolderViewItem*>& items, BOOL user_action)>& cb);
 	void clearSelection();
-	LLInventoryFilter* getFilter();
-	const LLInventoryFilter* getFilter() const;
+	bool isSelectionRemovable();
+	LLInventoryFilter& getFilter();
+	const LLInventoryFilter& getFilter() const;
 	void setFilterTypes(U64 filter, LLInventoryFilter::EFilterType = LLInventoryFilter::FILTERTYPE_OBJECT);
 	U32 getFilterObjectTypes() const;
 	void setFilterPermMask(PermissionMask filter_perm_mask);
@@ -156,6 +182,7 @@ class LLInventoryPanel : public LLPanel
 	// This method is called when something has changed about the inventory.
 	void modelChanged(U32 mask);
 	LLFolderView* getRootFolder();
+	LLUUID getRootFolderID();
 	LLScrollContainer* getScrollableContainer() { return mScroller; }
 	
 	void onSelectionChange(const std::deque<LLFolderViewItem*> &items, BOOL user_action);
@@ -167,7 +194,8 @@ class LLInventoryPanel : public LLPanel
 	void doCreate(const LLSD& userdata);
 	bool beginIMSession();
 	bool attachObject(const LLSD& userdata);
-	
+	static void idle(void* user_data);
+
 	// DEBUG ONLY:
 	static void dumpSelectionInformation(void* user_data);
 
@@ -182,30 +210,44 @@ class LLInventoryPanel : public LLPanel
 	
 	static void openInventoryPanelAndSetSelection(BOOL auto_open, const LLUUID& obj_id);
 
+	void addItemID(const LLUUID& id, LLFolderViewItem* itemp);
+	void removeItemID(const LLUUID& id);
+	LLFolderViewItem* getItemByID(const LLUUID& id);
+	LLFolderViewFolder* getFolderByID(const LLUUID& id);
+	void setSelectionByID(const LLUUID& obj_id, BOOL take_keyboard_focus);
+	void updateSelection();
+
+	LLFolderViewModelInventory* getFolderViewModel();
+	const LLFolderViewModelInventory* getFolderViewModel() const;
+
 protected:
 	void openStartFolderOrMyInventory(); // open the first level of inventory
 	void onItemsCompletion();			// called when selected items are complete
 
+    LLUUID						mSelectThisID;	
 	LLInventoryModel*			mInventory;
 	LLInventoryObserver*		mInventoryObserver;
 	LLInvPanelComplObserver*	mCompletionObserver;
-	BOOL						mAcceptsDragAndDrop;
-	BOOL 						mAllowMultiSelect;
-	BOOL 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
-	BOOL						mShowEmptyMessage;
-	BOOL						mShowLoadStatus;
+	bool						mAcceptsDragAndDrop;
+	bool 						mAllowMultiSelect;
+	bool 						mShowItemLinkOverlays; // Shows link graphic over inventory item icons
+	bool						mShowEmptyMessage;
 
 	LLFolderView*				mFolderRoot;
 	LLScrollContainer*			mScroller;
 
+	LLFolderViewModelInventory	mInventoryViewModel;
+	Params						mParams;	// stored copy of parameter block
+
+	std::map<LLUUID, LLFolderViewItem*> mItemMap;
 	/**
-	 * Pointer to LLInventoryFVBridgeBuilder.
+	 * Pointer to LLInventoryFolderViewModelBuilder.
 	 *
 	 * It is set in LLInventoryPanel's constructor and can be overridden in derived classes with 
 	 * another implementation.
 	 * Take into account it will not be deleted by LLInventoryPanel itself.
 	 */
-	const LLInventoryFVBridgeBuilder* mInvFVBridgeBuilder;
+	const LLInventoryFolderViewModelBuilder* mInvFVBridgeBuilder;
 
 
 	//--------------------------------------------------------------------
@@ -218,7 +260,6 @@ class LLInventoryPanel : public LLPanel
 	
 	void setSortOrder(U32 order);
 	U32 getSortOrder() const;
-	void requestSort();
 
 private:
 	std::string					mSortOrderSetting;
@@ -231,26 +272,27 @@ class LLInventoryPanel : public LLPanel
 	void addHideFolderType(LLFolderType::EType folder_type);
 
 public:
-	BOOL 				getIsViewsInitialized() const { return mViewsInitialized; }
-	const LLUUID&		getRootFolderID() const;
+	BOOL getIsViewsInitialized() const { return mViewsInitialized; }
 protected:
 	// Builds the UI.  Call this once the inventory is usable.
 	void 				initializeViews();
-	LLFolderViewItem*	rebuildViewsFor(const LLUUID& id); // Given the id and the parent, build all of the folder views.
 
-	virtual void		buildFolderView(const LLInventoryPanel::Params& params);
+	// Specific inventory colors
+	static bool                 sColorSetInitialized;
+	static LLUIColor			sDefaultColor;
+	static LLUIColor			sDefaultHighlightColor;
+	static LLUIColor			sLibraryColor;
+	static LLUIColor			sLinkColor;
+	
 	LLFolderViewItem*	buildNewViews(const LLUUID& id);
 	BOOL				getIsHiddenFolderType(LLFolderType::EType folder_type) const;
 	
-	virtual LLFolderView*		createFolderView(LLInvFVBridge * bridge, bool useLabelSuffix);
+    virtual LLFolderView * createFolderRoot(LLUUID root_id );
 	virtual LLFolderViewFolder*	createFolderViewFolder(LLInvFVBridge * bridge);
 	virtual LLFolderViewItem*	createFolderViewItem(LLInvFVBridge * bridge);
 private:
-	BOOL				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
-	BOOL				mViewsInitialized; // Views have been generated
-	// UUID of category from which hierarchy should be built.  Set with the 
-	// "start_folder" xml property.  Default is LLUUID::null that means total Inventory hierarchy. 
-	LLUUID				mStartFolderID;
+	bool				mBuildDefaultHierarchy; // default inventory hierarchy should be created in postBuild()
+	bool				mViewsInitialized; // Views have been generated
 };
 
 #endif // LL_LLINVENTORYPANEL_H
diff --git a/indra/newview/lllistcontextmenu.h b/indra/newview/lllistcontextmenu.h
index fabd68ee20d2b7c6a56d9efd886a313bfb91b861..04d331482999b23dbd824dea4d752cec7c05e090 100644
--- a/indra/newview/lllistcontextmenu.h
+++ b/indra/newview/lllistcontextmenu.h
@@ -37,7 +37,7 @@ class LLContextMenu;
 /**
  * Context menu for single or multiple list items.
  * 
- * Derived classes must implement contextMenu().
+ * Derived classes must implement createMenu().
  * 
  * Typical usage:
  * <code>
diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp
index 97ba5b634a1f99c83541bc6f7ac9f1d5b1d396cf..25df4889b0d69973132c69da1ad3b0517575b3ae 100644
--- a/indra/newview/lllocalbitmaps.cpp
+++ b/indra/newview/lllocalbitmaps.cpp
@@ -53,7 +53,7 @@
 #include "llviewerobject.h"
 #include "llface.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "llagentwearables.h"
 #include "lltexlayerparams.h"
 #include "llvovolume.h"
@@ -195,7 +195,7 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate)
 					mLastModified = new_last_modified;
 
 					LLPointer<LLViewerFetchedTexture> texture = new LLViewerFetchedTexture
-						("file://"+mFilename, mWorldID, LL_LOCAL_USE_MIPMAPS);
+						("file://"+mFilename, FTT_LOCAL_FILE, mWorldID, LL_LOCAL_USE_MIPMAPS);
 
 					texture->createGLTexture(LL_LOCAL_DISCARD_LEVEL, raw_image);
 					texture->setCachedRawImage(LL_LOCAL_DISCARD_LEVEL, raw_image);
@@ -437,8 +437,8 @@ void LLLocalBitmap::updateUserPrims(LLUUID old_id, LLUUID new_id)
 					LLFace* face = object->mDrawable->getFace(face_iter);
 					if (face && face->getTexture() && face->getTexture()->getID() == old_id)
 					{
-						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture
-							(new_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						object->setTEImage(face_iter, LLViewerTextureManager::getFetchedTexture(
+							new_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 
 						update_obj = true;
 					}
@@ -481,7 +481,7 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 	U32 count = gAgentWearables.getWearableCount(type);
 	for(U32 wearable_iter = 0; wearable_iter < count; wearable_iter++)
 	{
-		LLWearable* wearable = gAgentWearables.getWearable(type, wearable_iter);
+		LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_iter);
 		if (wearable)
 		{
 			std::vector<LLLocalTextureObject*> texture_list = wearable->getLocalTextureListSeq();
@@ -493,11 +493,11 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 				if (lto && lto->getID() == old_id)
 				{
 					U32 local_texlayer_index = 0; /* can't keep that as static const, gives errors, so i'm leaving this var here */
-					LLVOAvatarDefines::EBakedTextureIndex baked_texind =
+					LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind =
 						lto->getTexLayer(local_texlayer_index)->getTexLayerSet()->getBakedTexIndex();
 				
-					LLVOAvatarDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
-					if (reg_texind != LLVOAvatarDefines::TEX_NUM_INDICES)
+					LLAvatarAppearanceDefines::ETextureIndex reg_texind = getTexIndex(type, baked_texind);
+					if (reg_texind != LLAvatarAppearanceDefines::TEX_NUM_INDICES)
 					{
 						U32 index = gAgentWearables.getWearableIndex(wearable);
 						gAgentAvatarp->setLocalTexture(reg_texind, gTextureList.getImage(new_id), FALSE, index);
@@ -513,10 +513,10 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp
 	}
 }
 
-LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
-	LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind)
+LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex(
+	LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind)
 {
-	LLVOAvatarDefines::ETextureIndex result = LLVOAvatarDefines::TEX_NUM_INDICES; // using as a default/fail return.
+	LLAvatarAppearanceDefines::ETextureIndex result = LLAvatarAppearanceDefines::TEX_NUM_INDICES; // using as a default/fail return.
 
 	switch(type)
 	{
@@ -524,32 +524,32 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_EYES:
+				case LLAvatarAppearanceDefines::BAKED_EYES:
 				{
-					result = LLVOAvatarDefines::TEX_EYES_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_EYES_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_HAIR:
+				case LLAvatarAppearanceDefines::BAKED_HAIR:
 				{
-					result = LLVOAvatarDefines::TEX_HAIR_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_HAIR_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_ALPHA;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_ALPHA;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_ALPHA;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_ALPHA;
 					break;
 				}
 
@@ -565,9 +565,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_EYES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_EYES)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_EYES)
 			{
-				result = LLVOAvatarDefines::TEX_EYES_IRIS;
+				result = LLAvatarAppearanceDefines::TEX_EYES_IRIS;
 			}
 
 			break;
@@ -575,9 +575,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_GLOVES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_GLOVES;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_GLOVES;
 			}
 
 			break;
@@ -585,13 +585,13 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_JACKET:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_JACKET;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_JACKET;
 			}
-			else if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			else if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_JACKET;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_JACKET;
 			}
 
 			break;
@@ -599,9 +599,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_PANTS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_PANTS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_PANTS;
 			}
 
 			break;
@@ -609,9 +609,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SHIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_SHIRT;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_SHIRT;
 			}
 
 			break;
@@ -619,9 +619,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SHOES:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_SHOES;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_SHOES;
 			}
 
 			break;
@@ -631,20 +631,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_BODYPAINT;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_BODYPAINT;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_BODYPAINT;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_BODYPAINT;
 					break;
 				}
 
@@ -659,9 +659,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SKIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_SKIRT)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_SKIRT)
 			{
-				result = LLVOAvatarDefines::TEX_SKIRT;
+				result = LLAvatarAppearanceDefines::TEX_SKIRT;
 			}
 
 			break;
@@ -669,9 +669,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_SOCKS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_SOCKS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_SOCKS;
 			}
 
 			break;
@@ -681,20 +681,20 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 		{
 			switch(baked_texind)
 			{
-				case LLVOAvatarDefines::BAKED_HEAD:
+				case LLAvatarAppearanceDefines::BAKED_HEAD:
 				{
-					result = LLVOAvatarDefines::TEX_HEAD_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_HEAD_TATTOO;
 					break;
 				}
 
-				case LLVOAvatarDefines::BAKED_LOWER:
+				case LLAvatarAppearanceDefines::BAKED_LOWER:
 				{
-					result = LLVOAvatarDefines::TEX_LOWER_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_LOWER_TATTOO;
 					break;
 				}
-				case LLVOAvatarDefines::BAKED_UPPER:
+				case LLAvatarAppearanceDefines::BAKED_UPPER:
 				{
-					result = LLVOAvatarDefines::TEX_UPPER_TATTOO;
+					result = LLAvatarAppearanceDefines::TEX_UPPER_TATTOO;
 					break;
 				}
 
@@ -709,9 +709,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_UNDERPANTS:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_LOWER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_LOWER)
 			{
-				result = LLVOAvatarDefines::TEX_LOWER_UNDERPANTS;
+				result = LLAvatarAppearanceDefines::TEX_LOWER_UNDERPANTS;
 			}
 
 			break;
@@ -719,9 +719,9 @@ LLVOAvatarDefines::ETextureIndex LLLocalBitmap::getTexIndex(
 
 		case LLWearableType::WT_UNDERSHIRT:
 		{
-			if (baked_texind == LLVOAvatarDefines::BAKED_UPPER)
+			if (baked_texind == LLAvatarAppearanceDefines::BAKED_UPPER)
 			{
-				result = LLVOAvatarDefines::TEX_UPPER_UNDERSHIRT;
+				result = LLAvatarAppearanceDefines::TEX_UPPER_UNDERSHIRT;
 			}
 
 			break;
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index 7a23c7ef6e3d2a203b07b4137960f58e00fafd40..580b6dfa7e06ffff4ded45e3247b10a59c9bc8e2 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -28,11 +28,14 @@
 #ifndef LL_LOCALBITMAPS_H
 #define LL_LOCALBITMAPS_H
 
+#include "llavatarappearancedefines.h"
 #include "lleventtimer.h"
+#include "llimage.h"
+#include "llpointer.h"
 #include "llwearabletype.h"
-#include "llvoavatardefines.h"
 
 class LLScrollListCtrl;
+class LLViewerObject;
 
 class LLLocalBitmap
 {
@@ -63,7 +66,7 @@ class LLLocalBitmap
 		void updateUserPrims(LLUUID old_id, LLUUID new_id);
 		void updateUserSculpts(LLUUID old_id, LLUUID new_id);
 		void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type);
-		LLVOAvatarDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLVOAvatarDefines::EBakedTextureIndex baked_texind);
+		LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind);
 
 	private: /* private enums */
 		enum ELinkStatus
diff --git a/indra/newview/lllocationinputctrl.cpp b/indra/newview/lllocationinputctrl.cpp
index 8d9d70b50eea2892118cd4c13d676ac6ead1b4e5..5022dba934415c8dc27ac55b0cd90d0779afd035 100644
--- a/indra/newview/lllocationinputctrl.cpp
+++ b/indra/newview/lllocationinputctrl.cpp
@@ -1217,11 +1217,11 @@ void LLLocationInputCtrl::onParcelIconClick(EParcelIcon icon)
 	case SCRIPTS_ICON:
 	{
 		LLViewerRegion* region = gAgent.getRegion();
-		if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsStopped");
 		}
-		else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+		else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsNotRunning");
 		}
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index ebb5912ace1647770722937e1abb23a0718af1f7..2d7454b636b2254b512c3907ff9debf80285fc26 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -28,11 +28,13 @@
 
 #include "llagent.h"
 #include "llagentui.h"
+#include "llavatarnamecache.h"
 #include "lllogchat.h"
 #include "lltrans.h"
 #include "llviewercontrol.h"
 
 #include "lldiriterator.h"
+#include "llfloaterimsessiontab.h"
 #include "llinstantmessage.h"
 #include "llsingleton.h" // for LLSingleton
 
@@ -40,6 +42,7 @@
 #include <boost/algorithm/string/replace.hpp>
 #include <boost/regex.hpp>
 #include <boost/regex/v4/match_results.hpp>
+#include <boost/foreach.hpp>
 
 #if LL_MSVC
 #pragma warning(push)  
@@ -58,10 +61,11 @@
 
 const S32 LOG_RECALL_SIZE = 2048;
 
-const std::string IM_TIME("time");
-const std::string IM_TEXT("message");
-const std::string IM_FROM("from");
-const std::string IM_FROM_ID("from_id");
+const std::string LL_IM_TIME("time");
+const std::string LL_IM_TEXT("message");
+const std::string LL_IM_FROM("from");
+const std::string LL_IM_FROM_ID("from_id");
+const std::string LL_TRANSCRIPT_FILE_EXTENSION("txt");
 
 const static std::string IM_SEPARATOR(": ");
 const static std::string NEW_LINE("\n");
@@ -84,6 +88,7 @@ const static std::string MULTI_LINE_PREFIX(" ");
  * Note: "You" was used as an avatar names in viewers of previous versions
  */
 const static boost::regex TIMESTAMP_AND_STUFF("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]\\s+|\\[\\d{1,2}:\\d{2}\\]\\s+)?(.*)$");
+const static boost::regex TIMESTAMP("^(\\[\\d{4}/\\d{1,2}/\\d{1,2}\\s+\\d{1,2}:\\d{2}\\]|\\[\\d{1,2}:\\d{2}\\]).*");
 
 /**
  *  Regular expression suitable to match names like
@@ -116,6 +121,15 @@ const static int IDX_TEXT = 3;
 using namespace boost::posix_time;
 using namespace boost::gregorian;
 
+void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
+{
+	if (!messages.size()) return;
+
+	std::string im_text = messages.back()[LL_IM_TEXT].asString();
+	im_text.append(line);
+	messages.back()[LL_IM_TEXT] = im_text;
+}
+
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 {
 public:
@@ -191,15 +205,17 @@ class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 	std::stringstream mTimeStream;
 };
 
+LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
+
 //static
 std::string LLLogChat::makeLogFileName(std::string filename)
 {
 	/**
-	* Testing for in bound and out bound ad-hoc file names
-	* if it is then skip date stamping.
-	**/
-	//LL_INFOS("") << "Befor:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    boost::match_results<std::string::const_iterator> matches;
+	 * Testing for in bound and out bound ad-hoc file names
+	 * if it is then skip date stamping.
+	 **/
+
+	boost::match_results<std::string::const_iterator> matches;
 	bool inboundConf = boost::regex_match(filename, matches, INBOUND_CONFERENCE);
 	bool outboundConf = boost::regex_match(filename, matches, OUTBOUND_CONFERENCE);
 	if (!(inboundConf || outboundConf))
@@ -220,17 +236,17 @@ std::string LLLogChat::makeLogFileName(std::string filename)
 			filename += dbuffer;
 		}
 	}
-	//LL_INFOS("") << "After:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
 	filename = cleanFileName(filename);
-	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS,filename);
-	filename += ".txt";
-	//LL_INFOS("") << "Full:" << filename << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+	filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_ACCOUNT_CHAT_LOGS, filename);
+	filename += '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+
 	return filename;
 }
 
 std::string LLLogChat::cleanFileName(std::string filename)
 {
-    std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
+	std::string invalidChars = "\"\'\\/?*:.<>|[]{}~"; // Cannot match glob or illegal filename chars
 	std::string::size_type position = filename.find_first_of(invalidChars);
 	while (position != filename.npos)
 	{
@@ -242,27 +258,24 @@ std::string LLLogChat::cleanFileName(std::string filename)
 
 std::string LLLogChat::timestamp(bool withdate)
 {
-	time_t utc_time;
-	utc_time = time_corrected();
-
 	std::string timeStr;
-	LLSD substitution;
-	substitution["datetime"] = (S32) utc_time;
-
 	if (withdate)
 	{
-		timeStr = "["+LLTrans::getString ("TimeYear")+"]/["
-		          +LLTrans::getString ("TimeMonth")+"]/["
-				  +LLTrans::getString ("TimeDay")+"] ["
-				  +LLTrans::getString ("TimeHour")+"]:["
-				  +LLTrans::getString ("TimeMin")+"]";
+		timeStr = "[" + LLTrans::getString ("TimeYear") + "]/["
+				  + LLTrans::getString ("TimeMonth") + "]/["
+				  + LLTrans::getString ("TimeDay") + "] ["
+				  + LLTrans::getString ("TimeHour") + "]:["
+				  + LLTrans::getString ("TimeMin") + "]";
 	}
 	else
 	{
 		timeStr = "[" + LLTrans::getString("TimeHour") + "]:["
-			      + LLTrans::getString ("TimeMin")+"]";
+				  + LLTrans::getString ("TimeMin")+"]";
 	}
 
+	LLSD substitution;
+	substitution["datetime"] = (S32)time_corrected();
+
 	LLStringUtil::format (timeStr, substitution);
 	return timeStr;
 }
@@ -270,9 +283,9 @@ std::string LLLogChat::timestamp(bool withdate)
 
 //static
 void LLLogChat::saveHistory(const std::string& filename,
-			    const std::string& from,
-			    const LLUUID& from_id,
-			    const std::string& line)
+							const std::string& from,
+							const LLUUID& from_id,
+							const std::string& line)
 {
 	std::string tmp_filename = filename;
 	LLStringUtil::trim(tmp_filename);
@@ -312,108 +325,41 @@ void LLLogChat::saveHistory(const std::string& filename,
 	file << LLChatLogFormatter(item) << std::endl;
 
 	file.close();
-}
 
-void LLLogChat::loadHistory(const std::string& filename, void (*callback)(ELogLineType, const LLSD&, void*), void* userdata)
-{
-	if(!filename.size())
-	{
-		llwarns << "Filename is Empty!" << llendl;
-		return ;
-	}
-        
-	LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "r");		/*Flawfinder: ignore*/
-	if (!fptr)
-	{
-		callback(LOG_EMPTY, LLSD(), userdata);
-		return;			//No previous conversation with this name.
-	}
-	else
+	if (NULL != sSaveHistorySignal)
 	{
-		char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
-		char *bptr;
-		S32 len;
-		bool firstline=TRUE;
-
-		if ( fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END) )		
-		{	//File is smaller than recall size.  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)
-			{
-				LLSD item;
-				std::string line(buffer);
-				std::istringstream iss(line);
-				
-				if (!LLChatLogParser::parse(line, item))
-				{
-					item["message"]	= line;
-					callback(LOG_LINE, item, userdata);
-				}
-				else
-				{
-					callback(LOG_LLSD, item, userdata);
-				}
-			}
-			else
-			{
-				firstline = FALSE;
-			}
-		}
-		callback(LOG_END, LLSD(), userdata);
-		
-		fclose(fptr);
+		(*sSaveHistorySignal)();
 	}
 }
 
-void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
-{
-	if (!messages.size()) return;
-
-	std::string im_text = messages.back()[IM_TEXT].asString();
-	im_text.append(line);
-	messages.back()[IM_TEXT] = im_text;
-}
-
 // static
-void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& messages)
+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 ;
 	}
-	//LL_INFOS("") << "Loading:" << file_name << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	//LL_INFOS("") << "Current:" << makeLogFileName(file_name) << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
+
+	bool load_all_history = load_params.has("load_all_history") ? load_params["load_all_history"].asBoolean() : false;
+
 	LLFILE* fptr = LLFile::fopen(makeLogFileName(file_name), "r");/*Flawfinder: ignore*/
 	if (!fptr)
-    {
+	{
 		fptr = LLFile::fopen(oldLogFileName(file_name), "r");/*Flawfinder: ignore*/
-        if (!fptr)
-        {
-			if (!fptr) return;      //No previous conversation with this name.
-        }
+		if (!fptr)
+		{
+			return;						//No previous conversation with this name.
+		}
 	}
  
-    //LL_INFOS("") << "Reading:" << file_name << LL_ENDL;
 	char buffer[LOG_RECALL_SIZE];		/*Flawfinder: ignore*/
 	char *bptr;
 	S32 len;
 	bool firstline = TRUE;
 
-	if (fseek(fptr, (LOG_RECALL_SIZE - 1) * -1  , SEEK_END))
-	{	//File is smaller than recall size.  Get it all.
+	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))
 		{
@@ -449,9 +395,9 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me
 		else
 		{
 			LLSD item;
-			if (!LLChatLogParser::parse(line, item))
+			if (!LLChatLogParser::parse(line, item, load_params))
 			{
-				item[IM_TEXT] = line;
+				item[LL_IM_TEXT] = line;
 			}
 			messages.push_back(item);
 		}
@@ -459,9 +405,259 @@ void LLLogChat::loadAllHistory(const std::string& file_name, std::list<LLSD>& me
 	fclose(fptr);
 }
 
+// static
+std::string LLLogChat::oldLogFileName(std::string filename)
+{
+	// get Users log directory
+	std::string directory = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	directory += gDirUtilp->getDirDelimiter();
+
+	// lest make sure the file name has no invalid characters before making the pattern
+	filename = cleanFileName(filename);
+
+	// create search pattern
+	std::string pattern = filename + ( filename == "chat" ? "-???\?-?\?-??.txt" : "-???\?-??.txt");
+
+	std::vector<std::string> allfiles;
+	LLDirIterator iter(directory, pattern);
+	std::string scanResult;
+
+	while (iter.next(scanResult))
+	{
+		allfiles.push_back(scanResult);
+	}
+
+	if (allfiles.size() == 0)  // if no result from date search, return generic filename
+	{
+		scanResult = directory + filename + '.' + LL_TRANSCRIPT_FILE_EXTENSION;
+	}
+	else 
+	{
+		sort(allfiles.begin(), allfiles.end());
+		scanResult = directory + allfiles.back();
+		// this file is now the most recent version of the file.
+	}
+
+	return scanResult;
+}
+
+// static
+void LLLogChat::findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions)
+{
+	// get Users log directory
+	std::string dirname = gDirUtilp->getPerAccountChatLogsDir();
+
+	// add final OS dependent delimiter
+	dirname += gDirUtilp->getDirDelimiter();
+
+	LLDirIterator iter(dirname, pattern);
+	std::string filename;
+	while (iter.next(filename))
+	{
+		std::string fullname = gDirUtilp->add(dirname, filename);
+
+		LLFILE * filep = LLFile::fopen(fullname, "rb");
+		if (NULL != filep)
+		{
+			char buffer[LOG_RECALL_SIZE];
+
+			fseek(filep, 0, SEEK_END);			// seek to end of file
+			S32 bytes_to_read = ftell(filep);	// get current file pointer
+			fseek(filep, 0, SEEK_SET);			// seek back to beginning of file
+
+			// limit the number characters to read from file
+			if (bytes_to_read >= LOG_RECALL_SIZE)
+			{
+				bytes_to_read = LOG_RECALL_SIZE - 1;
+			}
+
+			if (bytes_to_read > 0 && NULL != fgets(buffer, bytes_to_read, filep))
+			{
+				//matching a timestamp
+				boost::match_results<std::string::const_iterator> matches;
+				if (boost::regex_match(std::string(buffer), matches, TIMESTAMP))
+				{
+					list_of_transcriptions.push_back(gDirUtilp->add(dirname, filename));
+				}
+			}
+			LLFile::close(filep);
+		}
+	}
+}
+
+// static
+void LLLogChat::getListOfTranscriptFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION;
+	findTranscriptFiles(pattern, list_of_transcriptions);
+}
+
+// static
+void LLLogChat::getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions)
+{
+	// create search pattern
+	std::string pattern = "*." + LL_TRANSCRIPT_FILE_EXTENSION + ".backup*";
+	findTranscriptFiles(pattern, list_of_transcriptions);
+}
+
+//static
+boost::signals2::connection LLLogChat::setSaveHistorySignal(const save_history_signal_t::slot_type& cb)
+{
+	if (NULL == sSaveHistorySignal)
+	{
+		sSaveHistorySignal = new save_history_signal_t();
+	}
+
+	return sSaveHistorySignal->connect(cb);
+}
+
+//static
+bool LLLogChat::moveTranscripts(const std::string originDirectory, 
+								const std::string targetDirectory, 
+								std::vector<std::string>& listOfFilesToMove,
+								std::vector<std::string>& listOfFilesMoved)
+{
+	std::string newFullPath;
+	bool movedAllTranscripts = true;
+	std::string backupFileName;
+	unsigned backupFileCount;
+
+	BOOST_FOREACH(const std::string& fullpath, listOfFilesToMove)
+	{
+		backupFileCount = 0;
+		newFullPath = targetDirectory + fullpath.substr(originDirectory.length(), std::string::npos);
+
+		//The target directory contains that file already, so lets store it
+		if(LLFile::isfile(newFullPath))
+		{
+			backupFileName = newFullPath + ".backup";
+
+			//If needed store backup file as .backup1 etc.
+			while(LLFile::isfile(backupFileName))
+			{
+				++backupFileCount;
+				backupFileName = newFullPath + ".backup" + boost::lexical_cast<std::string>(backupFileCount);
+			}
+
+			//Rename the file to its backup name so it is not overwritten
+			LLFile::rename(newFullPath, backupFileName);
+		}
+
+		S32 retry_count = 0;
+		while (retry_count < 5)
+		{
+			//success is zero
+			if (LLFile::rename(fullpath, newFullPath) != 0)
+			{
+				retry_count++;
+				S32 result = errno;
+				LL_WARNS("LLLogChat::moveTranscripts") << "Problem renaming " << fullpath << " - errorcode: "
+					<< result << " attempt " << retry_count << LL_ENDL;
+
+				ms_sleep(100);
+			}
+			else
+			{
+				listOfFilesMoved.push_back(newFullPath);
+
+				if (retry_count)
+				{
+					LL_WARNS("LLLogChat::moveTranscripts") << "Successfully renamed " << fullpath << LL_ENDL;
+				}
+				break;
+			}			
+		}
+	}
+
+	if(listOfFilesMoved.size() != listOfFilesToMove.size())
+	{
+		movedAllTranscripts = false;
+	}		
+
+	return movedAllTranscripts;
+}
+
+//static
+bool LLLogChat::moveTranscripts(const std::string currentDirectory, 
+	const std::string newDirectory, 
+	std::vector<std::string>& listOfFilesToMove)
+{
+	std::vector<std::string> listOfFilesMoved;
+	return moveTranscripts(currentDirectory, newDirectory, listOfFilesToMove, listOfFilesMoved);
+}
+
+//static
+void LLLogChat::deleteTranscripts()
+{
+	std::vector<std::string> list_of_transcriptions;
+	getListOfTranscriptFiles(list_of_transcriptions);
+	getListOfTranscriptBackupFiles(list_of_transcriptions);
+
+	BOOST_FOREACH(const std::string& fullpath, list_of_transcriptions)
+	{
+		S32 retry_count = 0;
+		while (retry_count < 5)
+		{
+			if (0 != LLFile::remove(fullpath))
+			{
+				retry_count++;
+				S32 result = errno;
+				LL_WARNS("LLLogChat::deleteTranscripts") << "Problem removing " << fullpath << " - errorcode: "
+					<< result << " attempt " << retry_count << LL_ENDL;
+
+				if(retry_count >= 5)
+				{
+					LL_WARNS("LLLogChat::deleteTranscripts") << "Failed to remove " << fullpath << LL_ENDL;
+					return;
+				}
+
+				ms_sleep(100);
+			}
+			else
+			{
+				if (retry_count)
+				{
+					LL_WARNS("LLLogChat::deleteTranscripts") << "Successfully removed " << fullpath << LL_ENDL;
+				}
+				break;
+			}			
+		}
+	}
+
+	LLFloaterIMSessionTab::processChatHistoryStyleUpdate(true);
+}
+
+// static
+bool LLLogChat::isTranscriptExist(const LLUUID& avatar_id)
+{
+	std::vector<std::string> list_of_transcriptions;
+	LLLogChat::getListOfTranscriptFiles(list_of_transcriptions);
+
+	if (list_of_transcriptions.size() > 0)
+	{
+		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 (std::string::npos != transcript_file_name.find(avatar_user_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 writen like "Object <actual_object's_name>"
+//Example, an object's name can be written like "Object <actual_object's_name>"
 void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 {
 	if (!im.isMap())
@@ -470,19 +666,19 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		return;
 	}
 
-	if (im[IM_TIME].isDefined())
+	if (im[LL_IM_TIME].isDefined())
 {
-		std::string timestamp = im[IM_TIME].asString();
+		std::string timestamp = im[LL_IM_TIME].asString();
 		boost::trim(timestamp);
 		ostr << '[' << timestamp << ']' << TWO_SPACES;
 	}
 	
 	//*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 writen like "Object <actual_object's_name>"
-	if (im[IM_FROM].isDefined())
+	//Example, an object's name can be written like "Object <actual_object's_name>"
+	if (im[LL_IM_FROM].isDefined())
 	{
-		std::string from = im[IM_FROM].asString();
+		std::string from = im[LL_IM_FROM].asString();
 		boost::trim(from);
 		if (from.size())
 		{
@@ -490,9 +686,9 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 		}
 	}
 
-	if (im[IM_TEXT].isDefined())
+	if (im[LL_IM_TEXT].isDefined())
 	{
-		std::string im_text = im[IM_TEXT].asString();
+		std::string im_text = im[LL_IM_TEXT].asString();
 
 		//multilined text will be saved with prepended spaces
 		boost::replace_all(im_text, NEW_LINE, NEW_LINE_SPACE_PREFIX);
@@ -500,10 +696,11 @@ void LLChatLogFormatter::format(const LLSD& im, std::ostream& ostr) const
 	}
 	}
 
-bool LLChatLogParser::parse(std::string& raw, LLSD& im)
+bool LLChatLogParser::parse(std::string& raw, LLSD& im, const LLSD& parse_params)
 {
 	if (!raw.length()) return false;
 	
+	bool cut_off_todays_date = parse_params.has("cut_off_todays_date")  ? parse_params["cut_off_todays_date"].asBoolean()  : true;
 	im = LLSD::emptyMap();
 
 	//matching a timestamp
@@ -518,13 +715,18 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 		boost::trim(timestamp);
 		timestamp.erase(0, 1);
 		timestamp.erase(timestamp.length()-1, 1);
-		LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
-		im[IM_TIME] = timestamp;
+
+		if (cut_off_todays_date)
+		{
+			LLLogChatTimeScanner::instance().checkAndCutOffDate(timestamp);
+		}
+
+		im[LL_IM_TIME] = timestamp;
 	}
 	else
 	{
 		//timestamp is optional
-		im[IM_TIME] = "";
+		im[LL_IM_TIME] = "";
 	}
 
 	bool has_stuff = matches[IDX_STUFF].matched;
@@ -550,8 +752,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 	if (!has_name || name == SYSTEM_FROM)
 	{
 		//name is optional too
-		im[IM_FROM] = SYSTEM_FROM;
-		im[IM_FROM_ID] = LLUUID::null;
+		im[LL_IM_FROM] = SYSTEM_FROM;
+		im[LL_IM_FROM_ID] = LLUUID::null;
 	}
 
 	//possibly a case of complex object names consisting of 3+ words
@@ -560,8 +762,8 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 		U32 divider_pos = stuff.find(NAME_TEXT_DIVIDER);
 		if (divider_pos != std::string::npos && divider_pos < (stuff.length() - NAME_TEXT_DIVIDER.length()))
 		{
-			im[IM_FROM] = stuff.substr(0, divider_pos);
-			im[IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
+			im[LL_IM_FROM] = stuff.substr(0, divider_pos);
+			im[LL_IM_TEXT] = stuff.substr(divider_pos + NAME_TEXT_DIVIDER.length());
 			return true;
 		}
 	}
@@ -569,7 +771,7 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 	if (!has_name)
 	{
 		//text is mandatory
-		im[IM_TEXT] = stuff;
+		im[LL_IM_TEXT] = stuff;
 		return true; //parse as a message from Second Life
 	}
 	
@@ -581,45 +783,15 @@ bool LLChatLogParser::parse(std::string& raw, LLSD& im)
 	{
 		std::string agent_name;
 		LLAgentUI::buildFullname(agent_name);
-		im[IM_FROM] = agent_name;
-		im[IM_FROM_ID] = gAgentID;
+		im[LL_IM_FROM] = agent_name;
+		im[LL_IM_FROM_ID] = gAgentID;
 	}
 	else
 	{
-		im[IM_FROM] = name;
+		im[LL_IM_FROM] = name;
 	}
 	
 
-	im[IM_TEXT] = name_and_text[IDX_TEXT];
+	im[LL_IM_TEXT] = name_and_text[IDX_TEXT];
 	return true;  //parsed name and message text, maybe have a timestamp too
 }
-std::string LLLogChat::oldLogFileName(std::string filename)
-{
-    std::string scanResult;
-	std::string directory = gDirUtilp->getPerAccountChatLogsDir();/* get Users log directory */
-	directory += gDirUtilp->getDirDelimiter();/* add final OS dependent delimiter */
-	filename=cleanFileName(filename);/* lest make shure the file name has no invalad charecters befor making the pattern */
-	std::string pattern = (filename+(( filename == "chat" ) ? "-???\?-?\?-??.txt" : "-???\?-??.txt"));/* create search pattern*/
-	//LL_INFOS("") << "Checking:" << directory << " for " << pattern << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-	std::vector<std::string> allfiles;
-
-	LLDirIterator iter(directory, pattern);
-	while (iter.next(scanResult))
-    {
-		//LL_INFOS("") << "Found   :" << scanResult << LL_ENDL;
-        allfiles.push_back(scanResult);
-    }
-
-    if (allfiles.size() == 0)  // if no result from date search, return generic filename
-    {
-        scanResult = directory + filename + ".txt";
-    }
-    else 
-    {
-        std::sort(allfiles.begin(), allfiles.end());
-        scanResult = directory + allfiles.back();
-        // thisfile is now the most recent version of the file.
-    }
-	//LL_INFOS("") << "Reading:" << scanResult << LL_ENDL;/* uncomment if you want to verify step, delete on commit */
-    return scanResult;
-}
diff --git a/indra/newview/lllogchat.h b/indra/newview/lllogchat.h
index 27752452c9e613f236b967f155328fd66171a69e..e819f00dd9c5f6e3cea756a24ddcc3c521fe2995 100644
--- a/indra/newview/lllogchat.h
+++ b/indra/newview/lllogchat.h
@@ -49,15 +49,29 @@ class LLLogChat
 				const std::string& from,
 				const LLUUID& from_id,
 				const std::string& line);
+	static void findTranscriptFiles(std::string pattern, std::vector<std::string>& list_of_transcriptions);
+	static void getListOfTranscriptFiles(std::vector<std::string>& list);
+	static void getListOfTranscriptBackupFiles(std::vector<std::string>& list_of_transcriptions);
 
-	/** @deprecated @see loadAllHistory() */
-	static void loadHistory(const std::string& filename, 
-		                    void (*callback)(ELogLineType, const LLSD&, void*), 
-							void* userdata);
+	static void loadChatHistory(const std::string& file_name, std::list<LLSD>& messages, const LLSD& load_params = LLSD());
+
+	typedef boost::signals2::signal<void ()> save_history_signal_t;
+	static boost::signals2::connection setSaveHistorySignal(const save_history_signal_t::slot_type& cb);
+
+	static bool moveTranscripts(const std::string currentDirectory, 
+									const std::string newDirectory, 
+									std::vector<std::string>& listOfFilesToMove,
+									std::vector<std::string>& listOfFilesMoved);
+	static bool moveTranscripts(const std::string currentDirectory, 
+		const std::string newDirectory, 
+		std::vector<std::string>& listOfFilesToMove);
+
+	static void deleteTranscripts();
+	static bool isTranscriptExist(const LLUUID& avatar_id);
 
-	static void loadAllHistory(const std::string& file_name, std::list<LLSD>& messages);
 private:
 	static std::string cleanFileName(std::string filename);
+	static save_history_signal_t * sSaveHistorySignal;
 };
 
 /**
@@ -105,7 +119,7 @@ class LLChatLogParser
 	 *
 	 * @return false if failed to parse mandatory data - message text
 	 */
-	static bool parse(std::string& raw, LLSD& im);
+	static bool parse(std::string& raw, LLSD& im, const LLSD& parse_params = LLSD());
 
 protected:
 	LLChatLogParser();
@@ -113,9 +127,10 @@ class LLChatLogParser
 };
 
 // LLSD map lookup constants
-extern const std::string IM_TIME; //("time");
-extern const std::string IM_TEXT; //("message");
-extern const std::string IM_FROM; //("from");
-extern const std::string IM_FROM_ID; //("from_id");
+extern const std::string LL_IM_TIME; //("time");
+extern const std::string LL_IM_TEXT; //("message");
+extern const std::string LL_IM_FROM; //("from");
+extern const std::string LL_IM_FROM_ID; //("from_id");
+extern const std::string LL_TRANSCRIPT_FILE_EXTENSION; //("txt");
 
 #endif
diff --git a/indra/newview/llmanip.cpp b/indra/newview/llmanip.cpp
index 9ec5d7c20c4c60026f77cb98defd0b0da8b25c35..a7d6cb5eac0ae4e35b201b07162952d903585965 100644
--- a/indra/newview/llmanip.cpp
+++ b/indra/newview/llmanip.cpp
@@ -53,7 +53,7 @@
 #include "llresmgr.h"
 #include "pipeline.h"
 #include "llglheaders.h"
-
+#include "lluiimage.h"
 // Local constants...
 const S32 VERTICAL_OFFSET = 50;
 
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index 826e8d560a5ffc01746fb2e9a69c0169f6f8f23d..d79f1040bba740c385ecbf13e72e446df852f073 100644
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1689,7 +1689,6 @@ void LLManipRotate::highlightManipulators( S32 x, S32 y )
 		return;
 	}
 	
-	LLQuaternion object_rot = first_object->getRenderRotation();
 	LLVector3 rotation_center = gAgent.getPosAgentFromGlobal(mRotationCenter);
 	LLVector3 mouse_dir_x;
 	LLVector3 mouse_dir_y;
diff --git a/indra/newview/llmanipscale.cpp b/indra/newview/llmanipscale.cpp
index 00a0bf889431465a0f36383a00a3e97be8ea53b4..ae0884ac5d179f75bc01fe14780a6f1864d56fc9 100644
--- a/indra/newview/llmanipscale.cpp
+++ b/indra/newview/llmanipscale.cpp
@@ -1191,9 +1191,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
 		mInSnapRegime = FALSE;
 	}
 
-	BOOL send_scale_update = FALSE;
-	BOOL send_position_update = FALSE;
-
 	LLVector3 dir_agent;
 	if( part_dir_local.mV[VX] )
 	{
@@ -1210,8 +1207,6 @@ void LLManipScale::dragFace( S32 x, S32 y )
 	stretchFace( 
 		projected_vec(drag_start_dir_f, dir_agent) + drag_start_center_agent,
 		projected_vec(drag_delta, dir_agent));
-	send_position_update = TRUE;
-	send_scale_update = TRUE;
 
 	mDragPointGlobal = drag_point_global;
 }
diff --git a/indra/newview/llmaniptranslate.cpp b/indra/newview/llmaniptranslate.cpp
index 362308c1765d4b402283ecfaf9618cecf321b01d..b62db70ec84e4e0d75ddb767e118065a444387b0 100644
--- a/indra/newview/llmaniptranslate.cpp
+++ b/indra/newview/llmaniptranslate.cpp
@@ -485,7 +485,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 	}
 
 	// Throttle updates to 10 per second.
-	BOOL send_update = FALSE;
 
 	LLVector3		axis_f;
 	LLVector3d		axis_d;
@@ -702,11 +701,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				LLVector3 old_position_local = object->getPosition();
 				LLVector3 new_position_local = selectNode->mSavedPositionLocal + (clamped_relative_move_f * objWorldRotation);
 
-				// move and clamp root object first, before adjusting children
-				if (new_position_local != old_position_local)
-				{
-					send_update = TRUE;
-				}
 				//RN: I forget, but we need to do this because of snapping which doesn't often result
 				// in position changes even when the mouse moves
 				object->setPosition(new_position_local);
@@ -716,8 +710,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 
 				if (selectNode->mIndividualSelection)
 				{
-					send_update = FALSE;
-		
 					// counter-translate child objects if we are moving the root as an individual
 					object->resetChildrenPosition(old_position_local - new_position_local, TRUE) ;					
 				}
@@ -753,7 +745,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				}
 
 				// PR: Only update if changed
-				LLVector3d old_position_global = object->getPositionGlobal();
 				LLVector3 old_position_agent = object->getPositionAgent();
 				LLVector3 new_position_agent = gAgent.getPosAgentFromGlobal(new_position_global);
 				if (object->isRootEdit())
@@ -775,11 +766,6 @@ BOOL LLManipTranslate::handleHover(S32 x, S32 y, MASK mask)
 				{
 					// counter-translate child objects if we are moving the root as an individual
 					object->resetChildrenPosition(old_position_agent - new_position_agent, TRUE) ;					
-					send_update = FALSE;
-				}
-				else if (old_position_global != new_position_global)
-				{
-					send_update = TRUE;
 				}
 			}
 			selectNode->mLastPositionLocal  = object->getPosition();
@@ -1310,7 +1296,6 @@ void LLManipTranslate::renderSnapGuides()
 					// add in off-axis offset
 					tick_start += (mSnapOffsetAxis * mSnapOffsetMeters);
 
-					BOOL is_sub_tick = FALSE;
 					F32 tick_scale = 1.f;
 					for (F32 division_level = max_subdivisions; division_level >= sGridMinSubdivisionLevel; division_level /= 2.f)
 					{
@@ -1319,7 +1304,6 @@ void LLManipTranslate::renderSnapGuides()
 							break;
 						}
 						tick_scale *= 0.7f;
-						is_sub_tick = TRUE;
 					}
 
 // 					S32 num_ticks_to_fade = is_sub_tick ? num_ticks_per_side / 2 : num_ticks_per_side;
@@ -1542,7 +1526,6 @@ void LLManipTranslate::renderSnapGuides()
 		
 		float a = line_alpha;
 
-		LLColor4 col = LLUIColorTable::instance().getColor("SilhouetteChildColor");
 		{
 			//draw grid behind objects
 			LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE);
diff --git a/indra/newview/llmediactrl.cpp b/indra/newview/llmediactrl.cpp
index 99b4707158fbc9d8d2ff3119826dfbed8075d951..2075aeed63210d69a80e552a4f3361dc026b0eb3 100644
--- a/indra/newview/llmediactrl.cpp
+++ b/indra/newview/llmediactrl.cpp
@@ -119,8 +119,8 @@ LLMediaCtrl::LLMediaCtrl( const Params& p) :
 
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)getRect().getWidth() * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)getRect().getHeight() * LLUI::getScaleFactor().mV[VY]);
 			
 		setTextureSize(screen_width, screen_height);
 	}
@@ -469,8 +469,8 @@ void LLMediaCtrl::reshape( S32 width, S32 height, BOOL called_from_parent )
 {
 	if(!getDecoupleTextureSize())
 	{
-		S32 screen_width = llround((F32)width * LLUI::sGLScaleFactor.mV[VX]);
-		S32 screen_height = llround((F32)height * LLUI::sGLScaleFactor.mV[VY]);
+		S32 screen_width = llround((F32)width * LLUI::getScaleFactor().mV[VX]);
+		S32 screen_height = llround((F32)height * LLUI::getScaleFactor().mV[VY]);
 
 		// when floater is minimized, these sizes are negative
 		if ( screen_height > 0 && screen_width > 0 )
@@ -667,7 +667,7 @@ bool LLMediaCtrl::ensureMediaSourceExists()
 			mMediaSource->addObserver( this );
 			mMediaSource->setBackgroundColor( getBackgroundColor() );
 			mMediaSource->setTrustedBrowser(mTrusted);
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			if(mClearCache)
 			{
@@ -750,7 +750,7 @@ void LLMediaCtrl::draw()
 	{
 		gGL.pushUIMatrix();
 		{
-			mMediaSource->setPageZoomFactor( LLUI::sGLScaleFactor.mV[ VX ] );
+			mMediaSource->setPageZoomFactor( LLUI::getScaleFactor().mV[ VX ] );
 
 			// scale texture to fit the space using texture coords
 			gGL.getTexUnit(0)->bind(media_texture);
@@ -864,14 +864,14 @@ void LLMediaCtrl::convertInputCoords(S32& x, S32& y)
 		coords_opengl = mMediaSource->getMediaPlugin()->getTextureCoordsOpenGL();
 	}
 	
-	x = llround((F32)x * LLUI::sGLScaleFactor.mV[VX]);
+	x = llround((F32)x * LLUI::getScaleFactor().mV[VX]);
 	if ( ! coords_opengl )
 	{
-		y = llround((F32)(y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(y) * LLUI::getScaleFactor().mV[VY]);
 	}
 	else
 	{
-		y = llround((F32)(getRect().getHeight() - y) * LLUI::sGLScaleFactor.mV[VY]);
+		y = llround((F32)(getRect().getHeight() - y) * LLUI::getScaleFactor().mV[VY]);
 	};
 }
 
diff --git a/indra/newview/llmediadataclient.cpp b/indra/newview/llmediadataclient.cpp
index 31038b4aaca1c5e63653597c2f9ce0513762520b..e3b46d5d2f3fd7727d844cf69d51e1c3e94b330f 100644
--- a/indra/newview/llmediadataclient.cpp
+++ b/indra/newview/llmediadataclient.cpp
@@ -564,7 +564,7 @@ LLMediaDataClient::Responder::Responder(const request_ptr_t &request)
 }
 
 /*virtual*/
-void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
+void LLMediaDataClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	mRequest->stopTracking();
 
@@ -596,8 +596,8 @@ void LLMediaDataClient::Responder::error(U32 status, const std::string& reason)
 	}
 	else 
 	{
-		std::string msg = boost::lexical_cast<std::string>(status) + ": " + reason;
-		LL_WARNS("LLMediaDataClient") << *mRequest << " http error(" << msg << ")" << LL_ENDL;
+		LL_WARNS("LLMediaDataClient") << *mRequest << " http error [status:" 
+				<< status << "]:" << content << ")" << LL_ENDL;
 	}
 }
 
@@ -1003,7 +1003,7 @@ LLMediaDataClient::Responder *LLObjectMediaNavigateClient::RequestNavigate::crea
 }
 
 /*virtual*/
-void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string& reason)
+void LLObjectMediaNavigateClient::Responder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
 	getRequest()->stopTracking();
 
@@ -1017,7 +1017,7 @@ void LLObjectMediaNavigateClient::Responder::error(U32 status, const std::string
 	// class
 	if (status == HTTP_SERVICE_UNAVAILABLE)
 	{
-		LLMediaDataClient::Responder::error(status, reason);
+		LLMediaDataClient::Responder::errorWithContent(status, reason, content);
 	}
 	else
 	{
diff --git a/indra/newview/llmediadataclient.h b/indra/newview/llmediadataclient.h
index ab90915c555410284ee0fa339eddd47a98bf3598..89e20a28d097e95c732b206fb509a9ec7498ea61 100644
--- a/indra/newview/llmediadataclient.h
+++ b/indra/newview/llmediadataclient.h
@@ -195,7 +195,7 @@ class LLMediaDataClient : public LLRefCount
 	public:
 		Responder(const request_ptr_t &request);
 		//If we get back an error (not found, etc...), handle it here
-		virtual void error(U32 status, const std::string& reason);
+		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 		//If we get back a normal response, handle it here.	 Default just logs it.
 		virtual void result(const LLSD& content);
 
@@ -400,7 +400,7 @@ class LLObjectMediaNavigateClient : public LLMediaDataClient
     public:
         Responder(const request_ptr_t &request)
             : LLMediaDataClient::Responder(request) {}
-		virtual void error(U32 status, const std::string& reason);
+		virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
         virtual void result(const LLSD &content);
     private:
         void mediaNavigateBounceBack();
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index 1223615079772e274ff703f6ea17e85964ca2c5f..17311dd75e5663efc98bf5f5b5ceaff5acb1eb89 100755
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -3222,6 +3222,7 @@ void LLPhysicsDecomp::doDecomposition()
 		param_map[params[i].mName] = params+i;
 	}
 
+	U32 ret = LLCD_OK;
 	//set parameter values
 	for (decomp_params::iterator iter = mCurRequest->mParams.begin(); iter != mCurRequest->mParams.end(); ++iter)
 	{
@@ -3235,7 +3236,6 @@ void LLPhysicsDecomp::doDecomposition()
 			continue;
 		}
 
-		U32 ret = LLCD_OK;
 
 		if (param->mType == LLCDParam::LLCD_FLOAT)
 		{
@@ -3254,8 +3254,6 @@ void LLPhysicsDecomp::doDecomposition()
 
 	mCurRequest->setStatusMessage("Executing.");
 
-	LLCDResult ret = LLCD_OK;
-	
 	if (LLConvexDecomposition::getInstance() != NULL)
 	{
 		ret = LLConvexDecomposition::getInstance()->executeStage(stage);
diff --git a/indra/newview/llmorphview.cpp b/indra/newview/llmorphview.cpp
index eaa044cb593053442337d8aedc3578fb7edfb42e..252d1b78ea013e96402ee87f4cd704acddb104b4 100644
--- a/indra/newview/llmorphview.cpp
+++ b/indra/newview/llmorphview.cpp
@@ -99,8 +99,6 @@ void	LLMorphView::initialize()
 //-----------------------------------------------------------------------------
 void	LLMorphView::shutdown()
 {
-	LLVOAvatarSelf::onCustomizeEnd();
-
 	if (isAgentAvatarValid())
 	{
 		gAgentAvatarp->startMotion( ANIM_AGENT_BODY_NOISE );
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index b0fbad33b004a9166cb291b96d8c875a500b43d3..7f396b7b7ed42d4067feb20800efdaf14ad69483 100644
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -64,7 +64,8 @@ LLNameListCtrl::LLNameListCtrl(const LLNameListCtrl::Params& p)
 	mNameColumnIndex(p.name_column.column_index),
 	mNameColumn(p.name_column.column_name),
 	mAllowCallingCardDrop(p.allow_calling_card_drop),
-	mShortNames(p.short_names)
+	mShortNames(p.short_names),
+	mAvatarNameCacheConnection()
 {}
 
 // public
@@ -320,16 +321,20 @@ LLScrollListItem* LLNameListCtrl::addNameItemRow(
 			else if (LLAvatarNameCache::get(id, &av_name))
 			{
 				if (mShortNames)
-					fullname = av_name.mDisplayName;
+					fullname = av_name.getDisplayName();
 				else
 					fullname = av_name.getCompleteName();
 			}
 			else
 			{
 				// ...schedule a callback
-				LLAvatarNameCache::get(id,
-					boost::bind(&LLNameListCtrl::onAvatarNameCache,
-						this, _1, _2, item->getHandle()));
+				// This is not correct and will likely lead to partially populated lists in cases where avatar names are not cached.
+				// *TODO : Change this to have 2 callbacks : one callback per list item and one for the whole list.
+				if (mAvatarNameCacheConnection.connected())
+				{
+					mAvatarNameCacheConnection.disconnect();
+				}
+				mAvatarNameCacheConnection = LLAvatarNameCache::get(id,boost::bind(&LLNameListCtrl::onAvatarNameCache,this, _1, _2, item->getHandle()));
 			}
 			break;
 		}
@@ -388,9 +393,11 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 									   const LLAvatarName& av_name,
 									   LLHandle<LLNameListItem> item)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	std::string name;
 	if (mShortNames)
-		name = av_name.mDisplayName;
+		name = av_name.getDisplayName();
 	else
 		name = av_name.getCompleteName();
 
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 3ac0565761f6678c283fb4cc10de266d76344cce..271802d48a52ad5c99e483494a9063b45f539135 100644
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -111,6 +111,13 @@ class LLNameListCtrl
 
 protected:
 	LLNameListCtrl(const Params&);
+	virtual ~LLNameListCtrl()
+	{
+		if (mAvatarNameCacheConnection.connected())
+		{
+			mAvatarNameCacheConnection.disconnect();
+		}
+	}
 	friend class LLUICtrlFactory;
 public:
 	// Add a user to the list by name.  It will be added, the name
@@ -154,6 +161,7 @@ class LLNameListCtrl
 	std::string		mNameColumn;
 	BOOL			mAllowCallingCardDrop;
 	bool			mShortNames;  // display name only, no SLID
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
diff --git a/indra/newview/llnearbychat.cpp b/indra/newview/llnearbychat.cpp
deleted file mode 100644
index a7303ad0352ceddcd1465a5c562d8d7004b92564..0000000000000000000000000000000000000000
--- a/indra/newview/llnearbychat.cpp
+++ /dev/null
@@ -1,338 +0,0 @@
-/** 
- * @file LLNearbyChat.cpp
- * @brief Nearby chat history scrolling panel implementation
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llnearbychat.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-//#include "llchatitemscontainerctrl.h"
-#include "lliconctrl.h"
-#include "llfloatersidepanelcontainer.h"
-#include "llfocusmgr.h"
-#include "lllogchat.h"
-#include "llresizebar.h"
-#include "llresizehandle.h"
-#include "llmenugl.h"
-#include "llviewermenu.h"//for gMenuHolder
-
-#include "llnearbychathandler.h"
-#include "llchannelmanager.h"
-
-#include "llagent.h" 			// gAgent
-#include "llchathistory.h"
-#include "llstylemap.h"
-
-#include "llavatarnamecache.h"
-
-#include "lldraghandle.h"
-
-#include "llnearbychatbar.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-
-static const S32 RESIZE_BAR_THICKNESS = 3;
-
-
-static LLRegisterPanelClassWrapper<LLNearbyChat> t_panel_nearby_chat("panel_nearby_chat");
-
-LLNearbyChat::LLNearbyChat(const LLNearbyChat::Params& p) 
-:	LLPanel(p),
-	mChatHistory(NULL)
-{
-}
-
-BOOL LLNearbyChat::postBuild()
-{
-	//menu
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-
-	enable_registrar.add("NearbyChat.Check", boost::bind(&LLNearbyChat::onNearbyChatCheckContextMenuItem, this, _2));
-	registrar.add("NearbyChat.Action", boost::bind(&LLNearbyChat::onNearbyChatContextMenuItemClicked, this, _2));
-
-	
-	LLMenuGL* menu = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_nearby_chat.xml", gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(menu)
-		mPopupMenuHandle = menu->getHandle();
-
-	gSavedSettings.declareS32("nearbychat_showicons_and_names",2,"NearByChat header settings",true);
-
-	mChatHistory = getChild<LLChatHistory>("chat_history");
-
-	if(!LLPanel::postBuild())
-		return false;
-	
-	return true;
-}
-
-std::string appendTime()
-{
-	time_t utc_time;
-	utc_time = time_corrected();
-	std::string timeStr ="["+ LLTrans::getString("TimeHour")+"]:["
-		+LLTrans::getString("TimeMin")+"]";
-
-	LLSD substitution;
-
-	substitution["datetime"] = (S32) utc_time;
-	LLStringUtil::format (timeStr, substitution);
-
-	return timeStr;
-}
-
-
-void	LLNearbyChat::addMessage(const LLChat& chat,bool archive,const LLSD &args)
-{
-	LLChat& tmp_chat = const_cast<LLChat&>(chat);
-
-	if(tmp_chat.mTimeStr.empty())
-		tmp_chat.mTimeStr = appendTime();
-
-	bool use_plain_text_chat_history = gSavedSettings.getBOOL("PlainTextChatHistory");
-	
-	if (!chat.mMuted)
-	{
-		tmp_chat.mFromName = chat.mFromName;
-		LLSD chat_args = args;
-		chat_args["use_plain_text_chat_history"] = use_plain_text_chat_history;
-		mChatHistory->appendMessage(chat, chat_args);
-	}
-
-	if(archive)
-	{
-		mMessageArchive.push_back(chat);
-		if(mMessageArchive.size()>200)
-			mMessageArchive.erase(mMessageArchive.begin());
-	}
-
-	if (args["do_not_log"].asBoolean()) 
-	{
-		return;
-	}
-
-	if (gSavedPerAccountSettings.getBOOL("LogNearbyChat"))
-	{
-		std::string from_name = chat.mFromName;
-
-		if (chat.mSourceType == CHAT_SOURCE_AGENT)
-		{
-			// if the chat is coming from an agent, log the complete name
-			LLAvatarName av_name;
-			LLAvatarNameCache::get(chat.mFromID, &av_name);
-
-			if (!av_name.mIsDisplayNameDefault)
-			{
-				from_name = av_name.getCompleteName();
-			}
-		}
-
-		LLLogChat::saveHistory("chat", from_name, chat.mFromID, chat.mText);
-	}
-}
-
-void LLNearbyChat::onNearbySpeakers()
-{
-	LLSD param;
-	param["people_panel_tab_name"] = "nearby_panel";
-	LLFloaterSidePanelContainer::showPanel("people", "panel_people", param);
-}
-
-
-void	LLNearbyChat::onNearbyChatContextMenuItemClicked(const LLSD& userdata)
-{
-}
-bool	LLNearbyChat::onNearbyChatCheckContextMenuItem(const LLSD& userdata)
-{
-	std::string str = userdata.asString();
-	if(str == "nearby_people")
-		onNearbySpeakers();	
-	return false;
-}
-
-void LLNearbyChat::removeScreenChat()
-{
-	LLNotificationsUI::LLScreenChannelBase* chat_channel = LLNotificationsUI::LLChannelManager::getInstance()->findChannelByID(LLUUID(gSavedSettings.getString("NearByChatChannelUUID")));
-	if(chat_channel)
-	{
-		chat_channel->removeToastsFromChannel();
-	}
-}
-
-void	LLNearbyChat::setVisible(BOOL visible)
-{
-	if(visible)
-	{
-		removeScreenChat();
-	}
-
-	LLPanel::setVisible(visible);
-}
-
-
-void LLNearbyChat::getAllowedRect(LLRect& rect)
-{
-	rect = gViewerWindow->getWorldViewRectScaled();
-}
-
-void LLNearbyChat::updateChatHistoryStyle()
-{
-	mChatHistory->clear();
-
-	LLSD do_not_log;
-	do_not_log["do_not_log"] = true;
-	for(std::vector<LLChat>::iterator it = mMessageArchive.begin();it!=mMessageArchive.end();++it)
-	{
-		// Update the messages without re-writing them to a log file.
-		addMessage(*it,false, do_not_log);
-	}
-}
-
-//static 
-void LLNearbyChat::processChatHistoryStyleUpdate(const LLSD& newvalue)
-{
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-	LLNearbyChat* nearby_chat = chat_bar->findChild<LLNearbyChat>("nearby_chat");
-	if(nearby_chat)
-		nearby_chat->updateChatHistoryStyle();
-}
-
-bool isWordsName(const std::string& name)
-{
-	// checking to see if it's display name plus username in parentheses 
-	S32 open_paren = name.find(" (", 0);
-	S32 close_paren = name.find(')', 0);
-
-	if (open_paren != std::string::npos &&
-		close_paren == name.length()-1)
-	{
-		return true;
-	}
-	else
-	{
-		//checking for a single space
-		S32 pos = name.find(' ', 0);
-		return std::string::npos != pos && name.rfind(' ', name.length()) == pos && 0 != pos && name.length()-1 != pos;
-	}
-}
-
-void LLNearbyChat::loadHistory()
-{
-	LLSD do_not_log;
-	do_not_log["do_not_log"] = true;
-
-	std::list<LLSD> history;
-	LLLogChat::loadAllHistory("chat", history);
-
-	std::list<LLSD>::const_iterator it = history.begin();
-	while (it != history.end())
-	{
-		const LLSD& msg = *it;
-
-		std::string from = msg[IM_FROM];
-		LLUUID from_id;
-		if (msg[IM_FROM_ID].isDefined())
-		{
-			from_id = msg[IM_FROM_ID].asUUID();
-		}
-		else
- 		{
-			std::string legacy_name = gCacheName->buildLegacyName(from);
- 			gCacheName->getUUID(legacy_name, from_id);
- 		}
-
-		LLChat chat;
-		chat.mFromName = from;
-		chat.mFromID = from_id;
-		chat.mText = msg[IM_TEXT].asString();
-		chat.mTimeStr = msg[IM_TIME].asString();
-		chat.mChatStyle = CHAT_STYLE_HISTORY;
-
-		chat.mSourceType = CHAT_SOURCE_AGENT;
-		if (from_id.isNull() && SYSTEM_FROM == from)
-		{	
-			chat.mSourceType = CHAT_SOURCE_SYSTEM;
-			
-		}
-		else if (from_id.isNull())
-		{
-			chat.mSourceType = isWordsName(from) ? CHAT_SOURCE_UNKNOWN : CHAT_SOURCE_OBJECT;
-		}
-
-		addMessage(chat, true, do_not_log);
-
-		it++;
-	}
-}
-
-//static
-LLNearbyChat* LLNearbyChat::getInstance()
-{
-	LLFloater* chat_bar = LLFloaterReg::getInstance("chat_bar");
-	return chat_bar->findChild<LLNearbyChat>("nearby_chat");
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusReceived()
-{
-	setBackgroundOpaque(true);
-	LLPanel::onFocusReceived();
-}
-
-////////////////////////////////////////////////////////////////////////////////
-//
-void LLNearbyChat::onFocusLost()
-{
-	setBackgroundOpaque(false);
-	LLPanel::onFocusLost();
-}
-
-BOOL	LLNearbyChat::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	//fix for EXT-6625
-	//highlight NearbyChat history whenever mouseclick happen in NearbyChat
-	//setting focus to eidtor will force onFocusLost() call that in its turn will change 
-	//background opaque. This all happenn since NearByChat is "chrome" and didn't process focus change.
-	
-	if(mChatHistory)
-		mChatHistory->setFocus(TRUE);
-	return LLPanel::handleMouseDown(x, y, mask);
-}
-
-void LLNearbyChat::draw()
-{
-	// *HACK: Update transparency type depending on whether our children have focus.
-	// This is needed because this floater is chrome and thus cannot accept focus, so
-	// the transparency type setting code from LLFloater::setFocus() isn't reached.
-	if (getTransparencyType() != TT_DEFAULT)
-	{
-		setTransparencyType(hasFocus() ? TT_ACTIVE : TT_INACTIVE);
-	}
-
-	LLPanel::draw();
-}
diff --git a/indra/newview/llnearbychat.h b/indra/newview/llnearbychat.h
deleted file mode 100644
index 7c5975cbc5500546740a50fb09064ee9fcf5cc3e..0000000000000000000000000000000000000000
--- a/indra/newview/llnearbychat.h
+++ /dev/null
@@ -1,83 +0,0 @@
- /** 
- * @file llnearbychat.h
- * @brief nearby chat history scrolling panel implementation
- *
- * $LicenseInfo:firstyear=2004&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_LLNEARBYCHAT_H_
-#define LL_LLNEARBYCHAT_H_
-
-#include "llscrollbar.h"
-#include "llviewerchat.h"
-#include "llfloater.h"
-
-class LLResizeBar;
-class LLChatHistory;
-
-class LLNearbyChat: public LLPanel
-{
-public:
-	LLNearbyChat(const Params& p = LLPanel::getDefaultParams());
-
-	BOOL	postBuild			();
-
-	/** @param archive true - to save a message to the chat history log */
-	void	addMessage			(const LLChat& message,bool archive = true, const LLSD &args = LLSD());	
-	void	onNearbyChatContextMenuItemClicked(const LLSD& userdata);
-	bool	onNearbyChatCheckContextMenuItem(const LLSD& userdata);
-
-	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
-	virtual void	draw();
-
-	// focus overrides
-	/*virtual*/ void	onFocusLost();
-	/*virtual*/ void	onFocusReceived();
-	
-	/*virtual*/ void	setVisible(BOOL visible);
-	
-	virtual void updateChatHistoryStyle();
-
-	static void processChatHistoryStyleUpdate(const LLSD& newvalue);
-
-	void loadHistory();
-
-	static LLNearbyChat* getInstance();
-	void removeScreenChat();
-
-private:
-
-	void	getAllowedRect		(LLRect& rect);
-
-	void	onNearbySpeakers	();
-
-
-private:
-	LLHandle<LLView>	mPopupMenuHandle;
-	LLChatHistory*		mChatHistory;
-
-	std::vector<LLChat> mMessageArchive;
-};
-
-#endif
-
-
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
deleted file mode 100644
index c00dc4bc89dd70a5b99b9b70dcb92d4f74f23234..0000000000000000000000000000000000000000
--- a/indra/newview/llnearbychatbar.cpp
+++ /dev/null
@@ -1,684 +0,0 @@
-/** 
- * @file llnearbychatbar.cpp
- * @brief LLNearbyChatBar class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "message.h"
-
-#include "llappviewer.h"
-#include "llfloaterreg.h"
-#include "lltrans.h"
-
-#include "llfirstuse.h"
-#include "llnearbychatbar.h"
-#include "llnearbychatbarlistener.h"
-#include "llagent.h"
-#include "llgesturemgr.h"
-#include "llmultigesture.h"
-#include "llkeyboard.h"
-#include "llanimationstates.h"
-#include "llviewerstats.h"
-#include "llcommandhandler.h"
-#include "llviewercontrol.h"
-#include "llnavigationbar.h"
-#include "llwindow.h"
-#include "llviewerwindow.h"
-#include "llrootview.h"
-#include "llviewerchat.h"
-#include "llnearbychat.h"
-#include "lltranslate.h"
-
-#include "llresizehandle.h"
-#include "llautoreplace.h"
-
-S32 LLNearbyChatBar::sLastSpecialChatChannel = 0;
-
-const S32 EXPANDED_HEIGHT = 300;
-const S32 COLLAPSED_HEIGHT = 60;
-const S32 EXPANDED_MIN_HEIGHT = 150;
-
-// legacy callback glue
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel);
-
-struct LLChatTypeTrigger {
-	std::string name;
-	EChatType type;
-};
-
-static LLChatTypeTrigger sChatTypeTriggers[] = {
-	{ "/whisper"	, CHAT_TYPE_WHISPER},
-	{ "/shout"	, CHAT_TYPE_SHOUT}
-};
-
-LLNearbyChatBar::LLNearbyChatBar(const LLSD& key)
-:	LLFloater(key),
-	mChatBox(NULL),
-	mNearbyChat(NULL),
-	mOutputMonitor(NULL),
-	mSpeakerMgr(NULL),
-	mExpandedHeight(COLLAPSED_HEIGHT + EXPANDED_HEIGHT)
-{
-	mSpeakerMgr = LLLocalSpeakerMgr::getInstance();
-	mListener.reset(new LLNearbyChatBarListener(*this));
-}
-
-//virtual
-BOOL LLNearbyChatBar::postBuild()
-{
-	mChatBox = getChild<LLLineEditor>("chat_box");
-
-	mChatBox->setAutoreplaceCallback(boost::bind(&LLAutoReplace::autoreplaceCallback, LLAutoReplace::getInstance(), _1, _2));
-	mChatBox->setCommitCallback(boost::bind(&LLNearbyChatBar::onChatBoxCommit, this));
-	mChatBox->setKeystrokeCallback(&onChatBoxKeystroke, this);
-	mChatBox->setFocusLostCallback(boost::bind(&onChatBoxFocusLost, _1, this));
-	mChatBox->setFocusReceivedCallback(boost::bind(&LLNearbyChatBar::onChatBoxFocusReceived, this));
-
-	mChatBox->setIgnoreArrowKeys( FALSE ); 
-	mChatBox->setCommitOnFocusLost( FALSE );
-	mChatBox->setRevertOnEsc( FALSE );
-	mChatBox->setIgnoreTab(TRUE);
-	mChatBox->setPassDelete(TRUE);
-	mChatBox->setReplaceNewlinesWithSpaces(FALSE);
-	mChatBox->setEnableLineHistory(TRUE);
-	mChatBox->setFont(LLViewerChat::getChatFont());
-
-	mNearbyChat = getChildView("nearby_chat");
-
-	gSavedSettings.declareBOOL("nearbychat_history_visibility", mNearbyChat->getVisible(), "Visibility state of nearby chat history", TRUE);
-	BOOL show_nearby_chat = gSavedSettings.getBOOL("nearbychat_history_visibility");
-
-	LLButton* show_btn = getChild<LLButton>("show_nearby_chat");
-	show_btn->setCommitCallback(boost::bind(&LLNearbyChatBar::onToggleNearbyChatPanel, this));
-	show_btn->setToggleState(show_nearby_chat);
-
-	mOutputMonitor = getChild<LLOutputMonitorCtrl>("chat_zone_indicator");
-	mOutputMonitor->setVisible(FALSE);
-
-	showNearbyChatPanel(show_nearby_chat);
-
-	// Register for font change notifications
-	LLViewerChat::setFontChangedCallback(boost::bind(&LLNearbyChatBar::onChatFontChange, this, _1));
-
-	enableResizeCtrls(true, true, false);
-
-	return TRUE;
-}
-
-// virtual
-void LLNearbyChatBar::onOpen(const LLSD& key)
-{
-	showTranslationCheckbox(LLTranslate::isTranslationConfigured());
-}
-
-bool LLNearbyChatBar::applyRectControl()
-{
-	bool rect_controlled = LLFloater::applyRectControl();
-
-	if (!mNearbyChat->getVisible())
-	{
-		reshape(getRect().getWidth(), getMinHeight());
-		enableResizeCtrls(true, true, false);
-	}
-	else
-	{
-		enableResizeCtrls(true);
-		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-	}
-	
-	return rect_controlled;
-}
-
-void LLNearbyChatBar::onChatFontChange(LLFontGL* fontp)
-{
-	// Update things with the new font whohoo
-	if (mChatBox)
-	{
-		mChatBox->setFont(fontp);
-	}
-}
-
-//static
-LLNearbyChatBar* LLNearbyChatBar::getInstance()
-{
-	return LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar");
-}
-
-void LLNearbyChatBar::showHistory()
-{
-	openFloater();
-
-	if (!getChildView("nearby_chat")->getVisible())
-	{
-		onToggleNearbyChatPanel();
-	}
-}
-
-void LLNearbyChatBar::showTranslationCheckbox(BOOL show)
-{
-	getChild<LLUICtrl>("translate_chat_checkbox_lp")->setVisible(show);
-}
-
-void LLNearbyChatBar::draw()
-{
-	displaySpeakingIndicator();
-	LLFloater::draw();
-}
-
-std::string LLNearbyChatBar::getCurrentChat()
-{
-	return mChatBox ? mChatBox->getText() : LLStringUtil::null;
-}
-
-// virtual
-BOOL LLNearbyChatBar::handleKeyHere( KEY key, MASK mask )
-{
-	BOOL handled = FALSE;
-
-	if( KEY_RETURN == key && mask == MASK_CONTROL)
-	{
-		// shout
-		sendChat(CHAT_TYPE_SHOUT);
-		handled = TRUE;
-	}
-	else if (KEY_RETURN == key && mask == MASK_SHIFT)
-	{
-		// whisper
-		sendChat(CHAT_TYPE_WHISPER);
-		handled = TRUE;
-	}
-	return handled;
-}
-
-BOOL LLNearbyChatBar::matchChatTypeTrigger(const std::string& in_str, std::string* out_str)
-{
-	U32 in_len = in_str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (in_len > sChatTypeTriggers[n].name.length())
-			continue;
-
-		std::string trigger_trunc = sChatTypeTriggers[n].name;
-		LLStringUtil::truncate(trigger_trunc, in_len);
-
-		if (!LLStringUtil::compareInsensitive(in_str, trigger_trunc))
-		{
-			*out_str = sChatTypeTriggers[n].name;
-			return TRUE;
-		}
-	}
-
-	return FALSE;
-}
-
-void LLNearbyChatBar::onChatBoxKeystroke(LLLineEditor* caller, void* userdata)
-{
-	LLFirstUse::otherAvatarChatFirst(false);
-
-	LLNearbyChatBar* self = (LLNearbyChatBar *)userdata;
-
-	LLWString raw_text = self->mChatBox->getWText();
-
-	// Can't trim the end, because that will cause autocompletion
-	// to eat trailing spaces that might be part of a gesture.
-	LLWStringUtil::trimHead(raw_text);
-
-	S32 length = raw_text.length();
-
-	if( (length > 0) && (raw_text[0] != '/') )  // forward slash is used for escape (eg. emote) sequences
-	{
-		gAgent.startTyping();
-	}
-	else
-	{
-		gAgent.stopTyping();
-	}
-
-	/* Doesn't work -- can't tell the difference between a backspace
-	   that killed the selection vs. backspace at the end of line.
-	if (length > 1 
-		&& text[0] == '/'
-		&& key == KEY_BACKSPACE)
-	{
-		// the selection will already be deleted, but we need to trim
-		// off the character before
-		std::string new_text = raw_text.substr(0, length-1);
-		self->mInputEditor->setText( new_text );
-		self->mInputEditor->setCursorToEnd();
-		length = length - 1;
-	}
-	*/
-
-	KEY key = gKeyboard->currentKey();
-
-	// Ignore "special" keys, like backspace, arrows, etc.
-	if (length > 1 
-		&& raw_text[0] == '/'
-		&& key < KEY_SPECIAL)
-	{
-		// we're starting a gesture, attempt to autocomplete
-
-		std::string utf8_trigger = wstring_to_utf8str(raw_text);
-		std::string utf8_out_str(utf8_trigger);
-
-		if (LLGestureMgr::instance().matchPrefix(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match); // keep original capitalization for user-entered part
-			S32 outlength = self->mChatBox->getLength(); // in characters
-
-			// Select to end of line, starting from the character
-			// after the last one the user typed.
-			self->mChatBox->setSelection(length, outlength);
-		}
-		else if (matchChatTypeTrigger(utf8_trigger, &utf8_out_str))
-		{
-			std::string rest_of_match = utf8_out_str.substr(utf8_trigger.size());
-			self->mChatBox->setText(utf8_trigger + rest_of_match + " "); // keep original capitalization for user-entered part
-			self->mChatBox->setCursorToEnd();
-		}
-
-		//llinfos << "GESTUREDEBUG " << trigger 
-		//	<< " len " << length
-		//	<< " outlen " << out_str.getLength()
-		//	<< llendl;
-	}
-}
-
-// static
-void LLNearbyChatBar::onChatBoxFocusLost(LLFocusableElement* caller, void* userdata)
-{
-	// stop typing animation
-	gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::onChatBoxFocusReceived()
-{
-	mChatBox->setEnabled(!gDisconnected);
-}
-
-EChatType LLNearbyChatBar::processChatTypeTriggers(EChatType type, std::string &str)
-{
-	U32 length = str.length();
-	S32 cnt = sizeof(sChatTypeTriggers) / sizeof(*sChatTypeTriggers);
-	
-	for (S32 n = 0; n < cnt; n++)
-	{
-		if (length >= sChatTypeTriggers[n].name.length())
-		{
-			std::string trigger = str.substr(0, sChatTypeTriggers[n].name.length());
-
-			if (!LLStringUtil::compareInsensitive(trigger, sChatTypeTriggers[n].name))
-			{
-				U32 trigger_length = sChatTypeTriggers[n].name.length();
-
-				// It's to remove space after trigger name
-				if (length > trigger_length && str[trigger_length] == ' ')
-					trigger_length++;
-
-				str = str.substr(trigger_length, length);
-
-				if (CHAT_TYPE_NORMAL == type)
-					return sChatTypeTriggers[n].type;
-				else
-					break;
-			}
-		}
-	}
-
-	return type;
-}
-
-void LLNearbyChatBar::sendChat( EChatType type )
-{
-	if (mChatBox)
-	{
-		LLWString text = mChatBox->getConvertedText();
-		if (!text.empty())
-		{
-			// store sent line in history, duplicates will get filtered
-			mChatBox->updateHistory();
-			// Check if this is destined for another channel
-			S32 channel = 0;
-			stripChannelNumber(text, &channel);
-			
-			std::string utf8text = wstring_to_utf8str(text);
-			// Try to trigger a gesture, if not chat to a script.
-			std::string utf8_revised_text;
-			if (0 == channel)
-			{
-				// discard returned "found" boolean
-				LLGestureMgr::instance().triggerAndReviseString(utf8text, &utf8_revised_text);
-			}
-			else
-			{
-				utf8_revised_text = utf8text;
-			}
-
-			utf8_revised_text = utf8str_trim(utf8_revised_text);
-
-			type = processChatTypeTriggers(type, utf8_revised_text);
-
-			if (!utf8_revised_text.empty())
-			{
-				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
-			}
-		}
-
-		mChatBox->setText(LLStringExplicit(""));
-	}
-
-	gAgent.stopTyping();
-
-}
-
-void LLNearbyChatBar::showNearbyChatPanel(bool show)
-{
-	if (!show)
-	{
-		if (mNearbyChat->getVisible() && !isMinimized())
-		{
-			mExpandedHeight = getRect().getHeight();
-		}
-		setResizeLimits(getMinWidth(), COLLAPSED_HEIGHT);
-		mNearbyChat->setVisible(FALSE);
-		reshape(getRect().getWidth(), COLLAPSED_HEIGHT);
-		enableResizeCtrls(true, true, false);
-		storeRectControl();
-	}
-	else
-	{
-		mNearbyChat->setVisible(TRUE);
-		setResizeLimits(getMinWidth(), EXPANDED_MIN_HEIGHT);
-		reshape(getRect().getWidth(), mExpandedHeight);
-		enableResizeCtrls(true);
-		storeRectControl();
-	}
-
-	gSavedSettings.setBOOL("nearbychat_history_visibility", mNearbyChat->getVisible());
-}
-
-void LLNearbyChatBar::onToggleNearbyChatPanel()
-{
-	showNearbyChatPanel(!mNearbyChat->getVisible());
-}
-
-void LLNearbyChatBar::setMinimized(BOOL b)
-{
-	LLNearbyChat* nearby_chat = getChild<LLNearbyChat>("nearby_chat");
-	// when unminimizing with nearby chat visible, go ahead and kill off screen chats
-	if (!b && nearby_chat->getVisible())
-	{
-		nearby_chat->removeScreenChat();
-	}
-		LLFloater::setMinimized(b);
-}
-
-void LLNearbyChatBar::onChatBoxCommit()
-{
-	if (mChatBox->getText().length() > 0)
-	{
-		sendChat(CHAT_TYPE_NORMAL);
-	}
-	// If the user wants to stop chatting on hitting return, lose focus
-	// and go out of chat mode.
-	if (gSavedSettings.getBOOL("CloseChatOnReturn"))
-	{
-		stopChat();
-	}
-	gAgent.stopTyping();
-}
-
-void LLNearbyChatBar::displaySpeakingIndicator()
-{
-	LLSpeakerMgr::speaker_list_t speaker_list;
-	LLUUID id;
-
-	id.setNull();
-	mSpeakerMgr->update(TRUE);
-	mSpeakerMgr->getSpeakerList(&speaker_list, FALSE);
-
-	for (LLSpeakerMgr::speaker_list_t::iterator i = speaker_list.begin(); i != speaker_list.end(); ++i)
-	{
-		LLPointer<LLSpeaker> s = *i;
-		if (s->mSpeechVolume > 0 || s->mStatus == LLSpeaker::STATUS_SPEAKING)
-		{
-			id = s->mID;
-			break;
-		}
-	}
-
-	if (!id.isNull())
-	{
-		mOutputMonitor->setVisible(TRUE);
-		mOutputMonitor->setSpeakerId(id);
-	}
-	else
-	{
-		mOutputMonitor->setVisible(FALSE);
-	}
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const std::string &utf8text, EChatType type, BOOL animate)
-{
-	sendChatFromViewer(utf8str_to_wstring(utf8text), type, animate);
-}
-
-void LLNearbyChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL animate)
-{
-	// Look for "/20 foo" channel chats.
-	S32 channel = 0;
-	LLWString out_text = stripChannelNumber(wtext, &channel);
-	std::string utf8_out_text = wstring_to_utf8str(out_text);
-	std::string utf8_text = wstring_to_utf8str(wtext);
-
-	utf8_text = utf8str_trim(utf8_text);
-	if (!utf8_text.empty())
-	{
-		utf8_text = utf8str_truncate(utf8_text, MAX_STRING - 1);
-	}
-
-	// Don't animate for chats people can't hear (chat to scripts)
-	if (animate && (channel == 0))
-	{
-		if (type == CHAT_TYPE_WHISPER)
-		{
-			lldebugs << "You whisper " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_WHISPER, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_NORMAL)
-		{
-			lldebugs << "You say " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_TALK, ANIM_REQUEST_START);
-		}
-		else if (type == CHAT_TYPE_SHOUT)
-		{
-			lldebugs << "You shout " << utf8_text << llendl;
-			gAgent.sendAnimationRequest(ANIM_AGENT_SHOUT, ANIM_REQUEST_START);
-		}
-		else
-		{
-			llinfos << "send_chat_from_viewer() - invalid volume" << llendl;
-			return;
-		}
-	}
-	else
-	{
-		if (type != CHAT_TYPE_START && type != CHAT_TYPE_STOP)
-		{
-			lldebugs << "Channel chat: " << utf8_text << llendl;
-		}
-	}
-
-	send_chat_from_viewer(utf8_out_text, type, channel);
-}
-
-// static 
-void LLNearbyChatBar::startChat(const char* line)
-{
-	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
-	if (!cb )
-		return;
-
-	cb->setVisible(TRUE);
-	cb->setFocus(TRUE);
-	cb->mChatBox->setFocus(TRUE);
-
-	if (line)
-	{
-		std::string line_string(line);
-		cb->mChatBox->setText(line_string);
-	}
-
-	cb->mChatBox->setCursorToEnd();
-}
-
-// Exit "chat mode" and do the appropriate focus changes
-// static
-void LLNearbyChatBar::stopChat()
-{
-	LLNearbyChatBar* cb = LLNearbyChatBar::getInstance();
-
-	if (!cb)
-		return;
-
-	cb->mChatBox->setFocus(FALSE);
-
- 	// stop typing animation
- 	gAgent.stopTyping();
-}
-
-// If input of the form "/20foo" or "/20 foo", returns "foo" and channel 20.
-// Otherwise returns input and channel 0.
-LLWString LLNearbyChatBar::stripChannelNumber(const LLWString &mesg, S32* channel)
-{
-	if (mesg[0] == '/'
-		&& mesg[1] == '/')
-	{
-		// This is a "repeat channel send"
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(2, mesg.length() - 2);
-	}
-	else if (mesg[0] == '/'
-			 && mesg[1]
-			 && LLStringOps::isDigit(mesg[1]))
-	{
-		// This a special "/20" speak on a channel
-		S32 pos = 0;
-
-		// Copy the channel number into a string
-		LLWString channel_string;
-		llwchar c;
-		do
-		{
-			c = mesg[pos+1];
-			channel_string.push_back(c);
-			pos++;
-		}
-		while(c && pos < 64 && LLStringOps::isDigit(c));
-		
-		// Move the pointer forward to the first non-whitespace char
-		// Check isspace before looping, so we can handle "/33foo"
-		// as well as "/33 foo"
-		while(c && iswspace(c))
-		{
-			c = mesg[pos+1];
-			pos++;
-		}
-		
-		sLastSpecialChatChannel = strtol(wstring_to_utf8str(channel_string).c_str(), NULL, 10);
-		*channel = sLastSpecialChatChannel;
-		return mesg.substr(pos, mesg.length() - pos);
-	}
-	else
-	{
-		// This is normal chat.
-		*channel = 0;
-		return mesg;
-	}
-}
-
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-
-class LLChatCommandHandler : public LLCommandHandler
-{
-public:
-	// not allowed from outside the app
-	LLChatCommandHandler() : LLCommandHandler("chat", UNTRUSTED_BLOCK) { }
-
-    // Your code here
-	bool handle(const LLSD& tokens, const LLSD& query_map,
-				LLMediaCtrl* web)
-	{
-		bool retval = false;
-		// Need at least 2 tokens to have a valid message.
-		if (tokens.size() < 2)
-		{
-			retval = false;
-		}
-		else
-		{
-		S32 channel = tokens[0].asInteger();
-			// VWR-19499 Restrict function to chat channels greater than 0.
-			if ((channel > 0) && (channel < CHAT_CHANNEL_DEBUG))
-			{
-				retval = true;
-		// Send unescaped message, see EXT-6353.
-		std::string unescaped_mesg (LLURI::unescape(tokens[1].asString()));
-		send_chat_from_viewer(unescaped_mesg, CHAT_TYPE_NORMAL, channel);
-			}
-			else
-			{
-				retval = false;
-				// Tell us this is an unsupported SLurl.
-			}
-		}
-		return retval;
-	}
-};
-
-// Creating the object registers with the dispatcher.
-LLChatCommandHandler gChatHandler;
-
-
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 1bda7640bd32825149e429ab3a451a85adfd5692..dea90b90426f1ee72360ecf39418b8a2667e9e04 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -150,7 +150,7 @@ void LLNetMap::draw()
 	static LLUIColor map_avatar_color = LLUIColorTable::instance().getColor("MapAvatarColor", LLColor4::white);
 	static LLUIColor map_avatar_friend_color = LLUIColorTable::instance().getColor("MapAvatarFriendColor", LLColor4::white);
 	static LLUIColor map_track_color = LLUIColorTable::instance().getColor("MapTrackColor", LLColor4::white);
-	static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
+	//static LLUIColor map_track_disabled_color = LLUIColorTable::instance().getColor("MapTrackDisabledColor", LLColor4::white);
 	static LLUIColor map_frustum_color = LLUIColorTable::instance().getColor("MapFrustumColor", LLColor4::white);
 	static LLUIColor map_frustum_rotating_color = LLUIColorTable::instance().getColor("MapFrustumRotatingColor", LLColor4::white);
 	
diff --git a/indra/newview/llnotificationalerthandler.cpp b/indra/newview/llnotificationalerthandler.cpp
index 89fe7bb3c22d76f9de9c7e89c539de7cbd696e01..58a9b01a45944df8e232110ac02650f7eee0a33d 100644
--- a/indra/newview/llnotificationalerthandler.cpp
+++ b/indra/newview/llnotificationalerthandler.cpp
@@ -29,6 +29,7 @@
 
 #include "llnotificationhandler.h"
 
+#include "llagentcamera.h"
 #include "llnotifications.h"
 #include "llprogressview.h"
 #include "lltoastnotifypanel.h"
@@ -40,10 +41,10 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLAlertHandler::LLAlertHandler(e_notification_type type, const LLSD& id) : mIsModal(false)
+LLAlertHandler::LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal) 
+:	LLSystemNotificationHandler(name, notification_type),
+	mIsModal(is_modal)
 {
-	mType = type;
-
 	LLScreenChannelBase::Params p;
 	p.id = LLUUID(gSavedSettings.getString("AlertChannelUUID"));
 	p.display_toasts_always = true;
@@ -68,79 +69,83 @@ void LLAlertHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLAlertHandler::processNotification(const LLSD& notify)
+bool LLAlertHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(mChannel.isDead())
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel.get()->getVisible())
 	{
 		initChannel();
 	}
 
-	if (notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "load")
+	if (notification->canLogToIM() && notification->hasFormElements())
 	{
-		if (LLHandlerUtil::canSpawnSessionAndLogToIM(notification))
-		{
-			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
-			LLUUID from_id = notification->getPayload()["from_id"];
-
-			// firstly create session...
-			LLHandlerUtil::spawnIMSession(name, from_id);
-
-			// ...then log message to have IM Well notified about new message
-			LLHandlerUtil::logToIMP2P(notification);
-		}
-
-		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
-		p.enable_hide_btn = false;
-		p.can_fade = false;
-		p.is_modal = mIsModal;
-		p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
-
-		// Show alert in middle of progress view (during teleport) (EXT-1093)
-		LLProgressView* progress = gViewerWindow->getProgressView();
-		LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
-		mChannel.get()->updatePositionAndSize(rc);
-
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
-	}
-	else if (notify["sigtype"].asString() == "change")
-	{
-		LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
-	}
-	else
-	{
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->killToastByNotificationID(notification->getID());
+		const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+		LLUUID from_id = notification->getPayload()["from_id"];
+
+		// firstly create session...
+		LLHandlerUtil::spawnIMSession(name, from_id);
+
+		// ...then log message to have IM Well notified about new message
+		LLHandlerUtil::logToIMP2P(notification);
 	}
+
+	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.panel = dynamic_cast<LLToastPanel*>(alert_dialog);
+	p.enable_hide_btn = false;
+	p.can_fade = false;
+	p.is_modal = mIsModal;
+	p.on_delete_toast = boost::bind(&LLAlertHandler::onDeleteToast, this, _1);
+
+	// Show alert in middle of progress view (during teleport) (EXT-1093)
+	LLProgressView* progress = gViewerWindow->getProgressView();
+	LLRect rc = progress && progress->getVisible() ? progress->getRect() : gViewerWindow->getWorldViewRectScaled();
+	mChannel.get()->updatePositionAndSize(rc);
+
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
+	
 	return false;
 }
 
+void LLAlertHandler::onChange( LLNotificationPtr notification )
+{
+	LLToastAlertPanel* alert_dialog = new LLToastAlertPanel(notification, mIsModal);
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->modifyToastByNotificationID(notification->getID(), (LLToastPanel*)alert_dialog);
+}
+
 //--------------------------------------------------------------------------
+LLViewerAlertHandler::LLViewerAlertHandler(const std::string& name, const std::string& notification_type)
+	: LLSystemNotificationHandler(name, notification_type)
+{
+}
 
-void LLAlertHandler::onDeleteToast(LLToast* toast)
+bool LLViewerAlertHandler::processNotification(const LLNotificationPtr& p)
 {
+	if (gHeadlessClient)
+	{
+		LL_INFOS("LLViewerAlertHandler") << "Alert: " << p->getName() << LL_ENDL;
+	}
+
+	// If we're in mouselook, the mouse is hidden and so the user can't click 
+	// the dialog buttons.  In that case, change to First Person instead.
+	if( gAgentCamera.cameraMouselook() )
+	{
+		gAgentCamera.changeCameraToDefault();
+	}
+
+	return false;
 }
 
-//--------------------------------------------------------------------------
 
diff --git a/indra/newview/llnotificationgrouphandler.cpp b/indra/newview/llnotificationgrouphandler.cpp
index ad51389241caf864174ad411a1df65c4f734f285..8fef102cf889236b44222e49954d84735ef7cf1a 100644
--- a/indra/newview/llnotificationgrouphandler.cpp
+++ b/indra/newview/llnotificationgrouphandler.cpp
@@ -37,15 +37,13 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLGroupHandler::LLGroupHandler(e_notification_type type, const LLSD& id)
+LLGroupHandler::LLGroupHandler()
+:	LLCommunicationNotificationHandler("Group Notifications", "groupnotify")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
-		channel->setOnRejectToastCallback(boost::bind(&LLGroupHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -64,72 +62,37 @@ void LLGroupHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLGroupHandler::processNotification(const LLSD& notify)
+bool LLGroupHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(mChannel.isDead())
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel.get()->getVisible())
 	{
 		initChannel();
 	}
 	
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
-		LLHandlerUtil::logGroupNoticeToIMGroup(notification);
+	LLHandlerUtil::logGroupNoticeToIMGroup(notification);
 
-		LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.panel = notify_box;
-		p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
+	LLPanel* notify_box = new LLToastGroupNotifyPanel(notification);
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.panel = notify_box;
+	p.on_delete_toast = boost::bind(&LLGroupHandler::onDeleteToast, this, _1);
 
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
 
-		// send a signal to the counter manager
-		mNewNotificationSignal();
+	LLGroupActions::refresh_notices();
 
-		LLGroupActions::refresh_notices();
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		mChannel.get()->killToastByNotificationID(notification->getID());
-	}
 	return false;
 }
 
-//--------------------------------------------------------------------------
-void LLGroupHandler::onDeleteToast(LLToast* toast)
-{
-	// send a signal to the counter manager
-	mDelNotificationSignal();
-
-	// send a signal to a listener to let him perform some action
-	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
-}
-
-//--------------------------------------------------------------------------
-void LLGroupHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
-
-	if (notification && LLNotificationManager::getInstance()->getHandlerForNotification(notification->getType()) == this)
-	{
-		LLNotifications::instance().cancel(notification);
-	}
-}
 
 //--------------------------------------------------------------------------
 
diff --git a/indra/newview/llnotificationhandler.h b/indra/newview/llnotificationhandler.h
index 3569ad644796b64b5648186354a207904a38e26b..bff4efa9eaebc8393b0ae5e2fe9f11ce439bed71 100644
--- a/indra/newview/llnotificationhandler.h
+++ b/indra/newview/llnotificationhandler.h
@@ -27,33 +27,20 @@
 #ifndef LL_LLNOTIFICATIONHANDLER_H
 #define LL_LLNOTIFICATIONHANDLER_H
 
+#include <boost/intrusive_ptr.hpp>
 
 #include "llwindow.h"
 
-//#include "llnotificationsutil.h"
+#include "llnotifications.h"
 #include "llchannelmanager.h"
 #include "llchat.h"
 #include "llinstantmessage.h"
 #include "llnotificationptr.h"
 
-class LLIMFloater;
+class LLFloaterIMSession;
 
 namespace LLNotificationsUI
 {
-// ENotificationType enumerates all possible types of notifications that could be met
-// 
-typedef enum e_notification_type
-{
-	NT_NOTIFY, 
-	NT_NOTIFYTIP,
-	NT_GROUPNOTIFY,
-	NT_IMCHAT, 
-	NT_GROUPCHAT, 
-	NT_NEARBYCHAT, 
-	NT_ALERT,
-	NT_ALERTMODAL,
-	NT_OFFER
-} ENotificationType;
 
 /**
  * Handler of notification events.
@@ -81,21 +68,8 @@ class LLEventHandler
 public:
 	virtual ~LLEventHandler() {};
 
-	// callbacks for counters
-	typedef boost::function<void (void)> notification_callback_t;
-	typedef boost::signals2::signal<void (void)> notification_signal_t;
-	notification_signal_t mNewNotificationSignal;
-	notification_signal_t mDelNotificationSignal;
-	boost::signals2::connection setNewNotificationCallback(notification_callback_t cb) { return mNewNotificationSignal.connect(cb); }
-	boost::signals2::connection setDelNotification(notification_callback_t cb) { return mDelNotificationSignal.connect(cb); }
-	// callback for notification/toast
-	typedef boost::function<void (const LLUUID id)> notification_id_callback_t;
-	typedef boost::signals2::signal<void (const LLUUID id)> notification_id_signal_t;
-	notification_id_signal_t mNotificationIDSignal;
-	boost::signals2::connection setNotificationIDCallback(notification_id_callback_t cb) { return mNotificationIDSignal.connect(cb); }
-
 protected:
-	virtual void onDeleteToast(LLToast* toast)=0;
+	virtual void onDeleteToast(LLToast* toast) {}
 
 	// arrange handler's channel on a screen
 	// is necessary to unbind a moment of creation of a channel and a moment of positioning of it
@@ -104,8 +78,6 @@ class LLEventHandler
 	virtual void initChannel()=0;
 
 	LLHandle<LLScreenChannelBase>	mChannel;
-	e_notification_type				mType;
-
 };
 
 // LLSysHandler and LLChatHandler are more specific base classes
@@ -115,24 +87,37 @@ class LLEventHandler
 /**
  * Handler for system notifications.
  */
-class LLSysHandler : public LLEventHandler
+class LLNotificationHandler : public LLEventHandler, public LLNotificationChannel
 {
 public:
-	LLSysHandler();
-	virtual ~LLSysHandler() {};
+	LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName);
+	virtual ~LLNotificationHandler() {};
 
-	virtual bool processNotification(const LLSD& notify)=0;
+	// base interface functions
+	virtual void onAdd(LLNotificationPtr p) { processNotification(p); }
+	virtual void onChange(LLNotificationPtr p) { processNotification(p); }
+	virtual void onLoad(LLNotificationPtr p) { processNotification(p); }
+	virtual void onDelete(LLNotificationPtr p) { if (mChannel.get()) mChannel.get()->removeToastByNotificationID(p->getID());}
 
-protected :
-	static void init();
-	void removeExclusiveNotifications(const LLNotificationPtr& notif);
+	virtual bool processNotification(const LLNotificationPtr& notify) = 0;
+};
 
-	typedef std::list< std::set<std::string> > exclusive_notif_sets;
-	static exclusive_notif_sets sExclusiveNotificationGroups;
+class LLSystemNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLSystemNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLSystemNotificationHandler() {};
+};
+
+class LLCommunicationNotificationHandler : public LLNotificationHandler
+{
+public:
+	LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLCommunicationNotificationHandler() {};
 };
 
 /**
- * Handler for chat message notifications.
+ * Handler for chat message notifications. 
  */
 class LLChatHandler : public LLEventHandler
 {
@@ -146,17 +131,14 @@ class LLChatHandler : public LLEventHandler
  * Handler for IM notifications.
  * It manages life time of IMs, group messages.
  */
-class LLIMHandler : public LLSysHandler
+class LLIMHandler : public LLCommunicationNotificationHandler
 {
 public:
-	LLIMHandler(e_notification_type type, const LLSD& id);
+	LLIMHandler();
 	virtual ~LLIMHandler();
-
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 };
 
@@ -164,18 +146,15 @@ class LLIMHandler : public LLSysHandler
  * Handler for system informational notices.
  * It manages life time of tip notices.
  */
-class LLTipHandler : public LLSysHandler
+class LLTipHandler : public LLSystemNotificationHandler
 {
 public:
-	LLTipHandler(e_notification_type type, const LLSD& id);
+	LLTipHandler();
 	virtual ~LLTipHandler();
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
-	virtual void onRejectToast(const LLUUID& id);
 	virtual void initChannel();
 };
 
@@ -183,167 +162,143 @@ class LLTipHandler : public LLSysHandler
  * Handler for system informational notices.
  * It manages life time of script notices.
  */
-class LLScriptHandler : public LLSysHandler
+class LLScriptHandler : public LLSystemNotificationHandler
 {
 public:
-	LLScriptHandler(e_notification_type type, const LLSD& id);
+	LLScriptHandler();
 	virtual ~LLScriptHandler();
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
 	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 
 /**
  * Handler for group system notices.
  */
-class LLGroupHandler : public LLSysHandler
+class LLGroupHandler : public LLCommunicationNotificationHandler
 {
 public:
-	LLGroupHandler(e_notification_type type, const LLSD& id);
+	LLGroupHandler();
 	virtual ~LLGroupHandler();
 	
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 /**
  * Handler for alert system notices.
  */
-class LLAlertHandler : public LLSysHandler
+class LLAlertHandler : public LLSystemNotificationHandler
 {
 public:
-	LLAlertHandler(e_notification_type type, const LLSD& id);
+	LLAlertHandler(const std::string& name, const std::string& notification_type, bool is_modal);
 	virtual ~LLAlertHandler();
 
-	void setAlertMode(bool is_modal) { mIsModal = is_modal; }
-
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual void onChange(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
 
 	bool	mIsModal;
 };
 
+class LLViewerAlertHandler  : public LLSystemNotificationHandler
+{
+	LOG_CLASS(LLViewerAlertHandler);
+public:
+	LLViewerAlertHandler(const std::string& name, const std::string& notification_type);
+	virtual ~LLViewerAlertHandler() {};
+
+	virtual void onDelete(LLNotificationPtr p) {};
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
+};
+
 /**
  * Handler for offers notices.
  * It manages life time of offer notices.
  */
-class LLOfferHandler : public LLSysHandler
+class LLOfferHandler : public LLCommunicationNotificationHandler
 {
 public:
-	LLOfferHandler(e_notification_type type, const LLSD& id);
+	LLOfferHandler();
 	virtual ~LLOfferHandler();
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual void onChange(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr notification);
+	virtual bool processNotification(const LLNotificationPtr& p);
 
 protected:
-	virtual void onDeleteToast(LLToast* toast);
 	virtual void initChannel();
-
-	// own handlers
-	void onRejectToast(LLUUID& id);
 };
 
 /**
  * Handler for UI hints.
  */
-class LLHintHandler : public LLSingleton<LLHintHandler>
+class LLHintHandler : public LLSystemNotificationHandler
 {
 public:
 	LLHintHandler();
-	virtual ~LLHintHandler();
+	virtual ~LLHintHandler() {}
 
-	// base interface functions
-	virtual bool processNotification(const LLSD& notify);
+	virtual void onAdd(LLNotificationPtr p);
+	virtual void onLoad(LLNotificationPtr p);
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 
 /**
  * Handler for browser notifications
  */
-class LLBrowserNotification : public LLSingleton<LLBrowserNotification>
+class LLBrowserNotification : public LLSystemNotificationHandler
 {
 public:
-	virtual bool processNotification(const LLSD& notify);
+	LLBrowserNotification();
+	virtual ~LLBrowserNotification() {}
+
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 /**
  * Handler for outbox notifications
  */
-class LLOutboxNotification : public LLSingleton<LLOutboxNotification>
+class LLOutboxNotification : public LLSystemNotificationHandler
 {
 public:
-	virtual bool processNotification(const LLSD& notify);
+	LLOutboxNotification();
+	virtual ~LLOutboxNotification() {};
+	virtual void onChange(LLNotificationPtr p) { }
+	virtual void onDelete(LLNotificationPtr p);
+	virtual bool processNotification(const LLNotificationPtr& p);
+
+protected:
+	virtual void initChannel() {};
 };
 	
 class LLHandlerUtil
 {
 public:
-	/**
-	 * Checks sufficient conditions to log notification message to IM session.
-	 */
-	static bool canLogToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to log notification message to nearby chat session.
-	 */
-	static bool canLogToNearbyChat(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to spawn IM session.
-	 */
-	static bool canSpawnIMSession(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks sufficient conditions to add notification toast panel IM floater.
-	 */
-	static bool canAddNotifPanelToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks whether notification can be used multiple times or not.
-	 */
-	static bool isNotificationReusable(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks if passed notification can create IM session and be written into it.
-	 *
-	 * This method uses canLogToIM() & canSpawnIMSession().
-	 */
-	static bool canSpawnSessionAndLogToIM(const LLNotificationPtr& notification);
-
-	/**
-	 * Checks if passed notification can create toast.
-	 */
-	static bool canSpawnToast(const LLNotificationPtr& notification);
-
 	/**
 	 * Determines whether IM floater is opened.
 	 */
 	static bool isIMFloaterOpened(const LLNotificationPtr& notification);
 
-	/**
-	* Determines whether IM floater is focused.
-	*/
-	static bool isIMFloaterFocused(const LLNotificationPtr& notification);
-
 	/**
 	 * Writes notification message to IM session.
 	 */
@@ -355,12 +310,7 @@ class LLHandlerUtil
 	/**
 	 * Writes notification message to IM  p2p session.
 	 */
-	static void logToIMP2P(const LLNotificationPtr& notification);
-
-	/**
-	 * Writes notification message to IM  p2p session.
-	 */
-	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only);
+	static void logToIMP2P(const LLNotificationPtr& notification, bool to_file_only = false);
 
 	/**
 	 * Writes group notice notification message to IM  group session.
@@ -406,13 +356,6 @@ class LLHandlerUtil
 	 */
 	static void decIMMesageCounter(const LLNotificationPtr& notification);
 
-private:
-
-	/**
-	 * Find IM floater based on "from_id"
-	 */
-	static LLIMFloater* findIMFloater(const LLNotificationPtr& notification);
-
 };
 
 }
diff --git a/indra/newview/llnotificationhandlerutil.cpp b/indra/newview/llnotificationhandlerutil.cpp
index 34cb27d5ce47b77261181ecacb553fc0a20db269..eb4601a4690744b4cf28c67f79ee1d2c75d968c7 100644
--- a/indra/newview/llnotificationhandlerutil.cpp
+++ b/indra/newview/llnotificationhandlerutil.cpp
@@ -34,219 +34,34 @@
 #include "llurlaction.h"
 
 #include "llagent.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llimview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationhandler.h"
 
 using namespace LLNotificationsUI;
 
-// static
-std::list< std::set<std::string> > LLSysHandler::sExclusiveNotificationGroups;
-
-// static
-void LLSysHandler::init()
-{
-	std::set<std::string> online_offline_group;
-	online_offline_group.insert("FriendOnline");
-	online_offline_group.insert("FriendOffline");
+LLNotificationHandler::LLNotificationHandler(const std::string& name, const std::string& notification_type, const std::string& parentName)
+:	LLNotificationChannel(name, parentName, LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, notification_type))
+{}
 
-	sExclusiveNotificationGroups.push_back(online_offline_group);
-}
-
-LLSysHandler::LLSysHandler()
-{
-	if(sExclusiveNotificationGroups.empty())
-	{
-		init();
-	}
-}
+LLSystemNotificationHandler::LLSystemNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "System")
+{}
 
-void LLSysHandler::removeExclusiveNotifications(const LLNotificationPtr& notif)
-{
-	LLScreenChannel* channel = dynamic_cast<LLScreenChannel *>(mChannel.get());
-	if (channel == NULL)
-	{
-		return;
-	}
-
-	class ExclusiveMatcher: public LLScreenChannel::Matcher
-	{
-	public:
-		ExclusiveMatcher(const std::set<std::string>& excl_group,
-				const std::string& from_name) :
-			mExclGroup(excl_group), mFromName(from_name)
-		{
-		}
-		bool matches(const LLNotificationPtr notification) const
-		{
-			for (std::set<std::string>::const_iterator it = mExclGroup.begin(); it
-					!= mExclGroup.end(); it++)
-			{
-				std::string from_name = LLHandlerUtil::getSubstitutionName(notification);
-				if (notification->getName() == *it && from_name == mFromName)
-				{
-					return true;
-				}
-			}
-			return false;
-		}
-	private:
-		const std::set<std::string>& mExclGroup;
-		const std::string& mFromName;
-	};
-
-
-	for (exclusive_notif_sets::iterator it = sExclusiveNotificationGroups.begin(); it
-			!= sExclusiveNotificationGroups.end(); it++)
-	{
-		std::set<std::string> group = *it;
-		std::set<std::string>::iterator g_it = group.find(notif->getName());
-		if (g_it != group.end())
-		{
-			channel->killMatchedToasts(ExclusiveMatcher(group,
-					LLHandlerUtil::getSubstitutionName(notif)));
-		}
-	}
-}
-
-const static std::string GRANTED_MODIFY_RIGHTS("GrantedModifyRights"),
-		REVOKED_MODIFY_RIGHTS("RevokedModifyRights"),
-		OBJECT_GIVE_ITEM("ObjectGiveItem"),
-		OBJECT_GIVE_ITEM_UNKNOWN_USER("ObjectGiveItemUnknownUser"),
-						PAYMENT_RECEIVED("PaymentReceived"),
-						PAYMENT_SENT("PaymentSent"),
-						ADD_FRIEND_WITH_MESSAGE("AddFriendWithMessage"),
-						USER_GIVE_ITEM("UserGiveItem"),
-						INVENTORY_ACCEPTED("InventoryAccepted"),
-						INVENTORY_DECLINED("InventoryDeclined"),
-						OFFER_FRIENDSHIP("OfferFriendship"),
-						FRIENDSHIP_ACCEPTED("FriendshipAccepted"),
-						FRIENDSHIP_OFFERED("FriendshipOffered"),
-						FRIENDSHIP_ACCEPTED_BYME("FriendshipAcceptedByMe"),
-						FRIENDSHIP_DECLINED_BYME("FriendshipDeclinedByMe"),
-						FRIEND_ONLINE("FriendOnline"), FRIEND_OFFLINE("FriendOffline"),
-						SERVER_OBJECT_MESSAGE("ServerObjectMessage"),
-						TELEPORT_OFFERED("TeleportOffered"),
-						TELEPORT_OFFERED_MATURITY_EXCEEDED("TeleportOffered_MaturityExceeded"),
-						TELEPORT_OFFERED_MATURITY_BLOCKED("TeleportOffered_MaturityBlocked"),
-						TELEPORT_OFFER_SENT("TeleportOfferSent"),
-						IM_SYSTEM_MESSAGE_TIP("IMSystemMessageTip");
-
-
-// static
-bool LLHandlerUtil::canLogToIM(const LLNotificationPtr& notification)
-{
-	return GRANTED_MODIFY_RIGHTS == notification->getName()
-			|| REVOKED_MODIFY_RIGHTS == notification->getName()
-			|| PAYMENT_RECEIVED == notification->getName()
-			|| PAYMENT_SENT == notification->getName()
-			|| OFFER_FRIENDSHIP == notification->getName()
-			|| FRIENDSHIP_OFFERED == notification->getName()
-			|| FRIENDSHIP_ACCEPTED == notification->getName()
-			|| FRIENDSHIP_ACCEPTED_BYME == notification->getName()
-			|| FRIENDSHIP_DECLINED_BYME == notification->getName()
-			|| SERVER_OBJECT_MESSAGE == notification->getName()
-			|| INVENTORY_ACCEPTED == notification->getName()
-			|| INVENTORY_DECLINED == notification->getName()
-			|| USER_GIVE_ITEM == notification->getName()
-			|| TELEPORT_OFFERED == notification->getName()
-			|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
-			|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName()
-			|| TELEPORT_OFFER_SENT == notification->getName()
-			|| IM_SYSTEM_MESSAGE_TIP == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canLogToNearbyChat(const LLNotificationPtr& notification)
-{
-	return notification->getType() == "notifytip"
-			&&  FRIEND_ONLINE != notification->getName()
-			&& FRIEND_OFFLINE != notification->getName()
-			&& INVENTORY_ACCEPTED != notification->getName()
-			&& INVENTORY_DECLINED != notification->getName()
-			&& IM_SYSTEM_MESSAGE_TIP != notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnIMSession(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-			|| USER_GIVE_ITEM == notification->getName()
-			|| TELEPORT_OFFERED == notification->getName()
-			|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
-			|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canAddNotifPanelToIM(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-					|| USER_GIVE_ITEM == notification->getName()
-					|| TELEPORT_OFFERED == notification->getName()
-					|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
-					|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::isNotificationReusable(const LLNotificationPtr& notification)
-{
-	return OFFER_FRIENDSHIP == notification->getName()
-		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName()
-		|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
-		|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName();
-}
-
-// static
-bool LLHandlerUtil::canSpawnSessionAndLogToIM(const LLNotificationPtr& notification)
-{
-	return canLogToIM(notification) && canSpawnIMSession(notification);
-}
+LLCommunicationNotificationHandler::LLCommunicationNotificationHandler(const std::string& name, const std::string& notification_type)
+	: LLNotificationHandler(name, notification_type, "Communication")
+{}
 
 // static
-bool LLHandlerUtil::canSpawnToast(const LLNotificationPtr& notification)
+bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 {
-	if(INVENTORY_DECLINED == notification->getName() 
-		|| INVENTORY_ACCEPTED == notification->getName())
-	{
-		// return false for inventory accepted/declined notifications if respective IM window is open (EXT-5909)
-		return ! isIMFloaterOpened(notification);
-	}
-
-	if(FRIENDSHIP_ACCEPTED == notification->getName())
-	{
-		// don't show FRIENDSHIP_ACCEPTED if IM window is opened and focused - EXT-6441
-		return ! isIMFloaterFocused(notification);
-	}
-
-	if(OFFER_FRIENDSHIP == notification->getName()
-		|| USER_GIVE_ITEM == notification->getName()
-		|| TELEPORT_OFFERED == notification->getName()
-		|| TELEPORT_OFFERED_MATURITY_EXCEEDED == notification->getName()
-		|| TELEPORT_OFFERED_MATURITY_BLOCKED == notification->getName())
-	{
-		// When ANY offer arrives, show toast, unless IM window is already open - EXT-5904
-		return ! isIMFloaterOpened(notification);
-	}
-
-	return true;
-}
+	bool res = false;
 
-// static
-LLIMFloater* LLHandlerUtil::findIMFloater(const LLNotificationPtr& notification)
-{
 	LLUUID from_id = notification->getPayload()["from_id"];
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
-	return LLFloaterReg::findTypedInstance<LLIMFloater>("impanel", session_id);
-}
-
-// static
-bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
-{
-	bool res = false;
+	LLFloaterIMSession* im_floater = LLFloaterReg::findTypedInstance<LLFloaterIMSession>("impanel", session_id);
 
-	LLIMFloater* im_floater = findIMFloater(notification);
 	if (im_floater != NULL)
 	{
 		res = im_floater->getVisible() == TRUE;
@@ -255,19 +70,6 @@ bool LLHandlerUtil::isIMFloaterOpened(const LLNotificationPtr& notification)
 	return res;
 }
 
-bool LLHandlerUtil::isIMFloaterFocused(const LLNotificationPtr& notification)
-{
-	bool res = false;
-
-	LLIMFloater* im_floater = findIMFloater(notification);
-	if (im_floater != NULL)
-	{
-		res = im_floater->hasFocus() == TRUE;
-	}
-
-	return res;
-}
-
 // static
 void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 		const std::string& session_name, const std::string& from_name,
@@ -299,13 +101,6 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 	}
 	else
 	{
-		// store active session id
-		const LLUUID & active_session_id =
-				LLIMModel::instance().getActiveSessionID();
-
-		// set searched session as active to avoid IM toast popup
-		LLIMModel::instance().setActiveSessionID(session_id);
-
 		S32 unread = session->mNumUnread;
 		S32 participant_unread = session->mParticipantUnreadMessageCount;
 		LLIMModel::instance().addMessageSilently(session_id, from, from_id,
@@ -316,25 +111,9 @@ void LLHandlerUtil::logToIM(const EInstantMessage& session_type,
 
 		// update IM floater messages
 		updateIMFLoaterMesages(session_id);
-
-		// restore active session id
-		if (active_session_id.isNull())
-		{
-			LLIMModel::instance().resetActiveSessionID();
-		}
-		else
-		{
-			LLIMModel::instance().setActiveSessionID(active_session_id);
-		}
 	}
 }
 
-// static
-void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification)
-{
-	logToIMP2P(notification, false);
-}
-
 void log_name_callback(const std::string& full_name, const std::string& from_name, 
 					   const std::string& message, const LLUUID& from_id)
 
@@ -346,9 +125,6 @@ void log_name_callback(const std::string& full_name, const std::string& from_nam
 // static
 void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_file_only)
 {
-	// don't create IM p2p session with objects, it's necessary condition to log
-	if (notification->getName() != OBJECT_GIVE_ITEM)
-	{
 		LLUUID from_id = notification->getPayload()["from_id"];
 
 		if (from_id.isNull())
@@ -367,7 +143,6 @@ void LLHandlerUtil::logToIMP2P(const LLNotificationPtr& notification, bool to_fi
 			gCacheName->get(from_id, false, boost::bind(&log_name_callback, _2, INTERACTIVE_SYSTEM_FROM, notification->getMessage(), from_id));
 		}
 	}
-}
 
 // static
 void LLHandlerUtil::logGroupNoticeToIMGroup(
@@ -398,8 +173,8 @@ void LLHandlerUtil::logGroupNoticeToIMGroup(
 // static
 void LLHandlerUtil::logToNearbyChat(const LLNotificationPtr& notification, EChatSourceType type)
 {
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-	if(nearby_chat)
+    LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
 		LLChat chat_msg(notification->getMessage());
 		chat_msg.mSourceType = type;
@@ -478,7 +253,7 @@ void LLHandlerUtil::addNotifPanelToIM(const LLNotificationPtr& notification)
 // static
 void LLHandlerUtil::updateIMFLoaterMesages(const LLUUID& session_id)
 {
-	LLIMFloater* im_floater = LLIMFloater::findInstance(session_id);
+	LLFloaterIMSession* im_floater = LLFloaterIMSession::findInstance(session_id);
 	if (im_floater != NULL && im_floater->getVisible())
 	{
 		im_floater->updateMessages();
@@ -502,14 +277,10 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
 	LLUUID from_id = notification->getPayload()["from_id"];
 	LLUUID session_id = LLIMMgr::computeSessionID(IM_NOTHING_SPECIAL, from_id);
 
-	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(
-			session_id);
+	LLIMModel::LLIMSession * session = LLIMModel::getInstance()->findIMSession(session_id);
 
-	if (session == NULL)
+	if (session)
 	{
-		return;
-	}
-
 	LLSD arg;
 	arg["session_id"] = session_id;
 	session->mNumUnread--;
@@ -518,3 +289,5 @@ void LLHandlerUtil::decIMMesageCounter(const LLNotificationPtr& notification)
 	arg["participant_unread"] = session->mParticipantUnreadMessageCount;
 	LLIMModel::getInstance()->mNewMsgSignal(arg);
 }
+}
+
diff --git a/indra/newview/llnotificationhinthandler.cpp b/indra/newview/llnotificationhinthandler.cpp
index f7163cb04ff769d2c8a8a77be3b7dfcf1d6ae845..f40369a2e061735eaa67b9eff730addf3e9c3944 100644
--- a/indra/newview/llnotificationhinthandler.cpp
+++ b/indra/newview/llnotificationhinthandler.cpp
@@ -34,25 +34,26 @@
 using namespace LLNotificationsUI;
 
 LLHintHandler::LLHintHandler()
+	: LLSystemNotificationHandler("Hints", "hint")
 {
 }
 
-LLHintHandler::~LLHintHandler()
+void LLHintHandler::onAdd(LLNotificationPtr p)
 {
+	LLHints::show(p);
 }
 
-bool LLHintHandler::processNotification(const LLSD& notify)
+void LLHintHandler::onLoad(LLNotificationPtr p)
+{
+	LLHints::show(p);
+}
+
+void LLHintHandler::onDelete(LLNotificationPtr p)
+{
+	LLHints::hide(p);
+}
+
+bool LLHintHandler::processNotification(const LLNotificationPtr& p)
 {
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	std::string sigtype = notify["sigtype"].asString();
-	if (sigtype == "add" || sigtype == "load")
-	{
-		LLHints::show(notification);
-	}
-	else if (sigtype == "delete")
-	{
-		LLHints::hide(notification);
-	}
 	return false;
 }
diff --git a/indra/newview/llnotificationmanager.cpp b/indra/newview/llnotificationmanager.cpp
index 3d8150eed39c20f48d62e116d2affc081b5ec9f1..152581c5a0f5b362af1c5c173818f50a49dd78f0 100644
--- a/indra/newview/llnotificationmanager.cpp
+++ b/indra/newview/llnotificationmanager.cpp
@@ -31,7 +31,7 @@
 
 #include "llnotificationmanager.h"
 
-#include "llnearbychathandler.h"
+#include "llfloaterimnearbychathandler.h"
 #include "llnotifications.h"
 
 #include <boost/bind.hpp>
@@ -42,114 +42,35 @@ using namespace LLNotificationsUI;
 //--------------------------------------------------------------------------
 LLNotificationManager::LLNotificationManager()
 {
-	mNotifyHandlers.clear();
 	init();
 }
 
 //--------------------------------------------------------------------------
 LLNotificationManager::~LLNotificationManager()
 {
-	BOOST_FOREACH(listener_pair_t& pair, mChannelListeners)
-	{
-		pair.second.disconnect();
-	}
 }
 
 //--------------------------------------------------------------------------
 void LLNotificationManager::init()
 {
-	LLNotificationChannel::buildChannel("Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notify"));
-	LLNotificationChannel::buildChannel("NotificationTips", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytip"));
-	LLNotificationChannel::buildChannel("Group Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "groupnotify"));
-	LLNotificationChannel::buildChannel("Alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
-	LLNotificationChannel::buildChannel("AlertModal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
-	LLNotificationChannel::buildChannel("IM Notifications", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "notifytoast"));
-	LLNotificationChannel::buildChannel("Offer", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "offer"));
-	LLNotificationChannel::buildChannel("Hints", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "hint"));
-	LLNotificationChannel::buildChannel("Browser", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "browser"));
-	LLNotificationChannel::buildChannel("Outbox", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "outbox"));
+	mChannels.push_back(new LLScriptHandler());
+	mChannels.push_back(new LLTipHandler());
+	mChannels.push_back(new LLGroupHandler());
+	mChannels.push_back(new LLAlertHandler("Alerts", "alert", false));
+	mChannels.push_back(new LLAlertHandler("AlertModal", "alertmodal", true));
+	mChannels.push_back(new LLOfferHandler());
+	mChannels.push_back(new LLHintHandler());
+	mChannels.push_back(new LLBrowserNotification());
+	mChannels.push_back(new LLOutboxNotification());
+	mChannels.push_back(new LLIMHandler());
   
-	mChannelListeners["Notifications"] = LLNotifications::instance().getChannel("Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["NotificationTips"] = LLNotifications::instance().getChannel("NotificationTips")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["Group Notifications"] = LLNotifications::instance().getChannel("Group Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["Alerts"] = LLNotifications::instance().getChannel("Alerts")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["AlertModal"] = LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["IM Notifications"] = LLNotifications::instance().getChannel("IM Notifications")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["Offer"] = LLNotifications::instance().getChannel("Offer")->connectChanged(boost::bind(&LLNotificationManager::onNotification, this, _1));
-	mChannelListeners["Hints"] = LLNotifications::instance().getChannel("Hints")->connectChanged(boost::bind(&LLHintHandler::processNotification, LLHintHandler::getInstance(), _1));
-	mChannelListeners["Browser"] = LLNotifications::instance().getChannel("Browser")->connectChanged(boost::bind(&LLBrowserNotification::processNotification, LLBrowserNotification::getInstance(), _1));
-	mChannelListeners["Outbox"] = LLNotifications::instance().getChannel("Outbox")->connectChanged(boost::bind(&LLOutboxNotification::processNotification, LLOutboxNotification::getInstance(), _1));
-
-	mNotifyHandlers["notify"] = boost::shared_ptr<LLEventHandler>(new LLScriptHandler(NT_NOTIFY, LLSD()));
-	mNotifyHandlers["notifytip"] =  boost::shared_ptr<LLEventHandler>(new LLTipHandler(NT_NOTIFY, LLSD()));
-	mNotifyHandlers["groupnotify"] = boost::shared_ptr<LLEventHandler>(new LLGroupHandler(NT_GROUPNOTIFY, LLSD()));
-	mNotifyHandlers["alert"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
-	mNotifyHandlers["alertmodal"] = boost::shared_ptr<LLEventHandler>(new LLAlertHandler(NT_ALERT, LLSD()));
-	static_cast<LLAlertHandler*>(mNotifyHandlers["alertmodal"].get())->setAlertMode(true);
-	mNotifyHandlers["notifytoast"] = boost::shared_ptr<LLEventHandler>(new LLIMHandler(NT_IMCHAT, LLSD()));
-	
-	mNotifyHandlers["nearbychat"] = boost::shared_ptr<LLEventHandler>(new LLNearbyChatHandler(NT_NEARBYCHAT, LLSD()));
-	mNotifyHandlers["offer"] = boost::shared_ptr<LLEventHandler>(new LLOfferHandler(NT_OFFER, LLSD()));
-}
-
-//--------------------------------------------------------------------------
-bool LLNotificationManager::onNotification(const LLSD& notify)
-{
-	LLSysHandler* handle = NULL;
-
-	// Don't bother if we're going down.
-	// Otherwise we might crash when trying to use handlers that are already dead.
-	if( LLApp::isExiting() )
-	{
-		return false;
-	}
-
-	if (LLNotifications::destroyed())
-		return false;
-
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-	
-	if (!notification) 
-		return false;
-
-	std::string notification_type = notification->getType();
-	handle = static_cast<LLSysHandler*>(mNotifyHandlers[notification_type].get());
-
-	if(!handle)
-		return false;
-	
-	return handle->processNotification(notify);
+	mChatHandler = boost::shared_ptr<LLFloaterIMNearbyChatHandler>(new LLFloaterIMNearbyChatHandler());
 }
 
 //--------------------------------------------------------------------------
 void LLNotificationManager::onChat(const LLChat& msg, const LLSD &args)
 {
-	// check ENotificationType argument
-	switch(args["type"].asInteger())
-	{
-	case NT_NEARBYCHAT:
-		{
-			LLNearbyChatHandler* handle = dynamic_cast<LLNearbyChatHandler*>(mNotifyHandlers["nearbychat"].get());
-
-			if(handle)
-				handle->processChat(msg, args);
+	if(mChatHandler)
+		mChatHandler->processChat(msg, args);
 		}
-		break;
-	default: 	//no need to handle all enum types
-		break;
-	}
-}
-
-//--------------------------------------------------------------------------
-LLEventHandler* LLNotificationManager::getHandlerForNotification(std::string notification_type) 
-{ 
-	std::map<std::string, boost::shared_ptr<LLEventHandler> >::iterator it = mNotifyHandlers.find(notification_type);
-
-	if(it != mNotifyHandlers.end())
-		return (*it).second.get();
-
-	return NULL;
-}
-
-//--------------------------------------------------------------------------
 
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index 27b6ba1c7173521cd059d67f57004c943a3a616a..f37c6b833c0b406827d1427ca03c09488089a919 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -28,8 +28,6 @@
 #ifndef LL_LLNOTIFICATIONMANAGER_H
 #define LL_LLNOTIFICATIONMANAGER_H
 
-#include "llevents.h"
-
 #include "lluictrl.h"
 #include "llnotificationhandler.h"
 
@@ -49,7 +47,6 @@ class LLToast;
 class LLNotificationManager : public LLSingleton<LLNotificationManager>
 {
 	typedef std::pair<std::string, LLEventHandler*> eventhandlers;
-	typedef std::pair<const std::string, LLBoundListener> listener_pair_t;
 public:	
 	LLNotificationManager();	
 	virtual ~LLNotificationManager();
@@ -59,22 +56,12 @@ class LLNotificationManager : public LLSingleton<LLNotificationManager>
 	void init(void);
 	//TODO: combine processing and storage (*)
 	
-	// this method reacts on system notifications and calls an appropriate handler
-	bool onNotification(const LLSD& notification);
-
 	// this method reacts on chat notifications and calls an appropriate handler
 	void onChat(const LLChat& msg, const LLSD &args);
 
-	// get a handler for a certain type of notification
-	LLEventHandler* getHandlerForNotification(std::string notification_type);
-
-
 private:
-	//TODO (*)
-	std::map<std::string, boost::shared_ptr<LLEventHandler> > mNotifyHandlers;
-	// cruft std::map<std::string, LLChatHandler*> mChatHandlers;
-
-	std::map<std::string, LLBoundListener> mChannelListeners;
+	boost::shared_ptr<class LLFloaterIMNearbyChatHandler> mChatHandler;
+	std::vector<LLNotificationChannelPtr> mChannels;
 };
 
 }
diff --git a/indra/newview/llnotificationofferhandler.cpp b/indra/newview/llnotificationofferhandler.cpp
index 1552ed3346c3e3e0865bbebe4beb2b557711bdac..2657b84ef30379962260d45674ee1bd7d33604d2 100644
--- a/indra/newview/llnotificationofferhandler.cpp
+++ b/indra/newview/llnotificationofferhandler.cpp
@@ -40,16 +40,14 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLOfferHandler::LLOfferHandler(e_notification_type type, const LLSD& id)
+LLOfferHandler::LLOfferHandler()
+:	LLCommunicationNotificationHandler("Offer", "offer")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
 		channel->setControlHovering(true);
-		channel->setOnRejectToastCallback(boost::bind(&LLOfferHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -68,147 +66,124 @@ void LLOfferHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLOfferHandler::processNotification(const LLSD& notify)
+bool LLOfferHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(mChannel.isDead())
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel.get()->getVisible())
 	{
 		initChannel();
 	}
 
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
 
+	if( notification->getPayload().has("give_inventory_notification")
+		&& notification->getPayload()["give_inventory_notification"].asBoolean() == false)
+	{
+		// This is an original inventory offer, so add a script floater
+		LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+	}
+	else
+	{
+		bool add_notif_to_im = notification->canLogToIM() && notification->hasFormElements();
 
-		if( notification->getPayload().has("give_inventory_notification")
-			&& !notification->getPayload()["give_inventory_notification"] )
+		if (add_notif_to_im)
 		{
-			// This is an original inventory offer, so add a script floater
-			LLScriptFloaterManager::instance().onAddNotification(notification->getID());
+			const std::string name = LLHandlerUtil::getSubstitutionName(notification);
+
+			LLUUID from_id = notification->getPayload()["from_id"];
+
+			//Will not play a notification sound for inventory and teleport offer based upon chat preference
+			bool playSound = (!notification->isDND()
+							  && ((notification->getName() == "UserGiveItem"
+			                  && gSavedSettings.getBOOL("PlaySoundInventoryOffer"))
+			                  || (notification->getName() == "TeleportOffered"
+			                  && gSavedSettings.getBOOL("PlaySoundTeleportOffer"))));
+
+			            if(playSound)
+			            {
+			                notification->playSound();
+			            }
+
+			LLHandlerUtil::spawnIMSession(name, from_id);
+			LLHandlerUtil::addNotifPanelToIM(notification);
+
 		}
-		else
+
+		if (!notification->canShowToast())
 		{
-			notification->setReusable(LLHandlerUtil::isNotificationReusable(notification));
-
-			LLUUID session_id;
-			if (LLHandlerUtil::canSpawnIMSession(notification))
-			{
-				const std::string name = LLHandlerUtil::getSubstitutionName(notification);
-
-				LLUUID from_id = notification->getPayload()["from_id"];
-
-				session_id = LLHandlerUtil::spawnIMSession(name, from_id);
-			}
-
-			bool show_toast = LLHandlerUtil::canSpawnToast(notification);
-			bool add_notid_to_im = LLHandlerUtil::canAddNotifPanelToIM(notification);
-			if (add_notid_to_im)
-			{
-				LLHandlerUtil::addNotifPanelToIM(notification);
-			}
-
-			if (notification->getPayload().has("SUPPRESS_TOAST")
-						&& notification->getPayload()["SUPPRESS_TOAST"])
-			{
-				LLNotificationsUtil::cancel(notification);
-			}
-			else if(show_toast)
-			{
-				LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
-				// don't close notification on panel destroy since it will be used by IM floater
-				notify_box->setCloseNotificationOnDestroy(!add_notid_to_im);
-				LLToast::Params p;
-				p.notif_id = notification->getID();
-				p.notification = notification;
-				p.panel = notify_box;
-				p.on_delete_toast = boost::bind(&LLOfferHandler::onDeleteToast, this, _1);
-				// we not save offer notifications to the syswell floater that should be added to the IM floater
-				p.can_be_stored = !add_notid_to_im;
-
-				LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-				if(channel)
-					channel->addToast(p);
-
-				// if we not add notification to IM - add it to notification well
-				if (!add_notid_to_im)
-				{
-					// send a signal to the counter manager
-					mNewNotificationSignal();
-				}
-			}
-
-			if (LLHandlerUtil::canLogToIM(notification))
-			{
-				// log only to file if notif panel can be embedded to IM and IM is opened
-				if (add_notid_to_im && LLHandlerUtil::isIMFloaterOpened(notification))
-				{
-					LLHandlerUtil::logToIMP2P(notification, true);
-				}
-				else
-				{
-					LLHandlerUtil::logToIMP2P(notification);
-				}
-			}
+			LLNotificationsUtil::cancel(notification);
 		}
-	}
-	else if (notify["sigtype"].asString() == "delete")
-	{
-		if( notification->getPayload().has("give_inventory_notification")
-			&& !notification->getPayload()["give_inventory_notification"] )
+		else if(!notification->canLogToIM() || !LLHandlerUtil::isIMFloaterOpened(notification))
 		{
-			// Remove original inventory offer script floater
-			LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+			LLToastNotifyPanel* notify_box = new LLToastNotifyPanel(notification);
+			LLToast::Params p;
+			p.notif_id = notification->getID();
+			p.notification = notification;
+			p.panel = notify_box;
+			// we not save offer notifications to the syswell floater that should be added to the IM floater
+			p.can_be_stored = !add_notif_to_im;
+			p.force_show = notification->getOfferFromAgent();
+
+			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+			if(channel)
+				channel->addToast(p);
+
 		}
-		else
+
+		if (notification->canLogToIM())
 		{
-			if (LLHandlerUtil::canAddNotifPanelToIM(notification)
-					&& !LLHandlerUtil::isIMFloaterOpened(notification))
-			{
-				LLHandlerUtil::decIMMesageCounter(notification);
-			}
-			mChannel.get()->killToastByNotificationID(notification->getID());
+			// log only to file if notif panel can be embedded to IM and IM is opened
+			bool file_only = add_notif_to_im && LLHandlerUtil::isIMFloaterOpened(notification);
+			LLHandlerUtil::logToIMP2P(notification, file_only);
 		}
 	}
 
 	return false;
 }
 
-//--------------------------------------------------------------------------
-
-void LLOfferHandler::onDeleteToast(LLToast* toast)
+/*virtual*/ void LLOfferHandler::onChange(LLNotificationPtr p)
 {
-	if (!LLHandlerUtil::canAddNotifPanelToIM(toast->getNotification()))
+	LLToastNotifyPanel* panelp = LLToastNotifyPanel::getInstance(p->getID());
+	if (panelp)
 	{
-		// send a signal to the counter manager
-		mDelNotificationSignal();
+		//
+		// HACK: if we're dealing with a notification embedded in IM, update it
+		// otherwise remove its toast
+		//
+		if (dynamic_cast<LLIMToastNotifyPanel*>(panelp))
+		{
+			panelp->updateNotification();
+		}
+		else
+		{
+			// if notification has changed, hide it
+			mChannel.get()->removeToastByNotificationID(p->getID());
+		}
 	}
-
-	// send a signal to a listener to let him perform some action
-	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
 }
 
-//--------------------------------------------------------------------------
-void LLOfferHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this
-					// don't delete notification since it may be used by IM floater
-					&& !LLHandlerUtil::canAddNotifPanelToIM(notification))
+/*virtual*/ void LLOfferHandler::onDelete(LLNotificationPtr notification)
+{
+	if( notification->getPayload().has("give_inventory_notification")
+		&& !notification->getPayload()["give_inventory_notification"] )
 	{
-		LLNotifications::instance().cancel(notification);
+		// Remove original inventory offer script floater
+		LLScriptFloaterManager::instance().onRemoveNotification(notification->getID());
+	}
+	else
+	{
+		if (notification->canLogToIM() 
+			&& notification->hasFormElements()
+			&& !LLHandlerUtil::isIMFloaterOpened(notification))
+		{
+			LLHandlerUtil::decIMMesageCounter(notification);
+		}
+		mChannel.get()->removeToastByNotificationID(notification->getID());
 	}
 }
+
diff --git a/indra/newview/llnotificationscripthandler.cpp b/indra/newview/llnotificationscripthandler.cpp
index 398f54c6f799d0f41047df69c00f8b7d1cd580e1..08c98e4f282e7c15d062925884f72f25376439e0 100644
--- a/indra/newview/llnotificationscripthandler.cpp
+++ b/indra/newview/llnotificationscripthandler.cpp
@@ -27,6 +27,7 @@
 
 #include "llviewerprecompiledheaders.h" // must be first include
 
+#include "llagent.h"
 #include "llnotificationhandler.h"
 #include "lltoastnotifypanel.h"
 #include "llviewercontrol.h"
@@ -37,21 +38,15 @@
 
 using namespace LLNotificationsUI;
 
-static const std::string SCRIPT_DIALOG				("ScriptDialog");
-static const std::string SCRIPT_DIALOG_GROUP		("ScriptDialogGroup");
-static const std::string SCRIPT_LOAD_URL			("LoadWebPage");
-
 //--------------------------------------------------------------------------
-LLScriptHandler::LLScriptHandler(e_notification_type type, const LLSD& id)
+LLScriptHandler::LLScriptHandler()
+:	LLSystemNotificationHandler("Notifications", "notify")
 {
-	mType = type;
-
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
 		channel->setControlHovering(true);
-		channel->setOnRejectToastCallback(boost::bind(&LLScriptHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -70,104 +65,83 @@ void LLScriptHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLScriptHandler::processNotification(const LLSD& notify)
+bool LLScriptHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(mChannel.isDead())
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;
-
 	// arrange a channel on a screen
 	if(!mChannel.get()->getVisible())
 	{
 		initChannel();
 	}
 	
-	if(notify["sigtype"].asString() == "add")
+	if (notification->canLogToIM())
 	{
-		if (LLHandlerUtil::canLogToIM(notification))
-		{
-			LLHandlerUtil::logToIMP2P(notification);
-		}
+		LLHandlerUtil::logToIMP2P(notification);
+	}
 
-		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
-		{
-			LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+	if(notification->hasFormElements() && !notification->canShowToast())
+	{
+		LLScriptFloaterManager::getInstance()->onAddNotification(notification->getID());
+	}
+	else
+	{
+		LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+		LLToast::Params p;
+		p.notif_id = notification->getID();
+		p.notification = notification;
+		p.panel = notify_box;
+		p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
+		if(gAgent.isDoNotDisturb())
+		{ 
+			p.force_show = notification->getName() == "SystemMessage" 
+							||	notification->getName() == "GodMessage" 
+							|| notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
 		}
-		else
+
+		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+		if(channel)
 		{
-			LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
-
-			LLToast::Params p;
-			p.notif_id = notification->getID();
-			p.notification = notification;
-			p.panel = notify_box;	
-			p.on_delete_toast = boost::bind(&LLScriptHandler::onDeleteToast, this, _1);
-
-			LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-			if(channel)
-			{
-				channel->addToast(p);
-			}
-
-			// send a signal to the counter manager
-			mNewNotificationSignal();
+			channel->addToast(p);
 		}
 	}
-	else if (notify["sigtype"].asString() == "delete")
+
+	return false;
+}
+
+
+void LLScriptHandler::onDelete( LLNotificationPtr notification )
 	{
-		if(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName() || SCRIPT_LOAD_URL == notification->getName())
+	if(notification->hasFormElements() && !notification->canShowToast())
 		{
 			LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 		}
 		else
 		{
-			mChannel.get()->killToastByNotificationID(notification->getID());
+			mChannel.get()->removeToastByNotificationID(notification->getID());
 		}
 	}
-	return false;
-}
+
 
 //--------------------------------------------------------------------------
 
 void LLScriptHandler::onDeleteToast(LLToast* toast)
 {
-	// send a signal to the counter manager
-	mDelNotificationSignal();
-
 	// send a signal to a listener to let him perform some action
 	// in this case listener is a SysWellWindow and it will remove a corresponding item from its list
-	mNotificationIDSignal(toast->getNotificationID());
-
 	LLNotificationPtr notification = LLNotifications::getInstance()->find(toast->getNotificationID());
 	
-	if( notification && 
-		(SCRIPT_DIALOG == notification->getName() || SCRIPT_DIALOG_GROUP == notification->getName()) )
+	if( notification && notification->hasFormElements() && !notification->canShowToast())
 	{
 		LLScriptFloaterManager::getInstance()->onRemoveNotification(notification->getID());
 	}
-}
-
-//--------------------------------------------------------------------------
-void LLScriptHandler::onRejectToast(LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this)
-	{
-		LLNotifications::instance().cancel(notification);
-	}
 }
 
-//--------------------------------------------------------------------------
-
 
 
 
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index 4cad96fdc7f51e6f8ddae4d7aa781a4e10824409..2923221c90787356742b9ad8ee66fa9ef7d86ccd 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -25,225 +25,115 @@
 */
 
 #include "llviewerprecompiledheaders.h" // must be first include
+
 #include "llnotificationstorage.h"
 
-#include "llxmlnode.h" // for linux compilers
+#include <string>
+#include <map>
 
-#include "llchannelmanager.h"
-#include "llscreenchannel.h"
-#include "llscriptfloater.h"
+#include "llerror.h"
+#include "llfile.h"
+#include "llnotifications.h"
+#include "llpointer.h"
+#include "llsd.h"
 #include "llsdserialize.h"
-#include "llviewermessage.h"
+#include "llsingleton.h"
+#include "llregistry.h"
+#include "llviewermessage.h" 
 
-//////////////////////////////////////////////////////////////////////////
+typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)> responder_constructor_t;
 
-class LLResponderRegistry
+class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry>
 {
-public:
-
-	static void registerResponders();
-
-	static LLNotificationResponderInterface* createResponder(const std::string& notification_name, const LLSD& params);
-
-private:
-
-	template<typename RESPONDER_TYPE>
-	static LLNotificationResponderInterface* create(const LLSD& params)
-	{
-		RESPONDER_TYPE* responder = new RESPONDER_TYPE();
-		responder->fromLLSD(params);
-		return responder;
-	}
-
-	typedef boost::function<LLNotificationResponderInterface* (const LLSD& params)> responder_constructor_t;
+    public:
+        template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
+        LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
+};
 
-	static void add(const std::string& notification_name, const responder_constructor_t& ctr);
+template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams)
+{
+    RESPONDER_TYPE* responder = new RESPONDER_TYPE();
+    responder->fromLLSD(pParams);
+    return responder;
+}
 
-private:
 
-	typedef std::map<std::string, responder_constructor_t> build_map_t;
+LLNotificationResponderInterface * LLResponderRegistry::createResponder(const std::string& pNotificationName, const LLSD& pParams)
+{
+    responder_constructor_t * factoryFunc = (LLResponderRegistry::getValue(pNotificationName));
+
+    if(factoryFunc)
+    {
+        return (*factoryFunc)(pParams);
+    }
+    
+    return NULL;
+}
 
-	static build_map_t sBuildMap;
-};
+LLResponderRegistry::StaticRegistrar sRegisterObjectGiveItem("ObjectGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterUserGiveItem("UserGiveItem", &LLResponderRegistry::create<LLOfferInfo>);
+LLResponderRegistry::StaticRegistrar sRegisterOfferInfo("offer_info", &LLResponderRegistry::create<LLOfferInfo>);
 
-//////////////////////////////////////////////////////////////////////////
 
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+LLNotificationStorage::LLNotificationStorage(std::string pFileName)
+	: mFileName(pFileName)
 {
-	mFileName = gDirUtilp->getExpandedFilename ( LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml" );
 }
 
-bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+LLNotificationStorage::~LLNotificationStorage()
 {
-	// we ignore "load" messages, but rewrite the persistence file on any other
-	const std::string sigtype = payload["sigtype"].asString();
-	if ("load" != sigtype)
-	{
-		saveNotifications();
-	}
-	return false;
 }
 
-// Storing or loading too many persistent notifications will severely hurt 
-// viewer load times, possibly to the point of failing to log in. Example case
-// from MAINT-994 is 821 notifications. 
-static const S32 MAX_PERSISTENT_NOTIFICATIONS = 250;
-
-void LLPersistentNotificationStorage::saveNotifications()
+bool LLNotificationStorage::writeNotifications(const LLSD& pNotificationData) const
 {
-	// TODO - think about save optimization.
 
-	llofstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
+	llofstream notifyFile(mFileName.c_str());
+	bool didFileOpen = notifyFile.is_open();
+
+	if (!didFileOpen)
 	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	LLSD output;
-	LLSD& data = output["data"];
-
-	LLNotificationChannelPtr history_channel = LLNotifications::instance().getChannel("Persistent");
-	LLNotificationSet::iterator it = history_channel->begin();
-
-	for ( ; history_channel->end() != it; ++it)
+	else
 	{
-		LLNotificationPtr notification = *it;
-
-		// After a notification was placed in Persist channel, it can become
-		// responded, expired or canceled - in this case we are should not save it
-		if(notification->isRespondedTo() || notification->isCancelled()
-			|| notification->isExpired())
-		{
-			continue;
-		}
-
-		data.append(notification->asLLSD());
-
-		if (data.size() >= MAX_PERSISTENT_NOTIFICATIONS)
-		{
-			llwarns << "Too many persistent notifications."
-					<< " Saved " << MAX_PERSISTENT_NOTIFICATIONS << " of " << history_channel->size() << " persistent notifications." << llendl;
-			break;
-		}
+		LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
+		formatter->format(pNotificationData, notifyFile, LLSDFormatter::OPTIONS_PRETTY);
 	}
 
-	LLPointer<LLSDFormatter> formatter = new LLSDXMLFormatter();
-	formatter->format(output, notify_file, LLSDFormatter::OPTIONS_PRETTY);
+	return didFileOpen;
 }
 
-void LLPersistentNotificationStorage::loadNotifications()
+bool LLNotificationStorage::readNotifications(LLSD& pNotificationData) const
 {
-	LLResponderRegistry::registerResponders();
-
-	llifstream notify_file(mFileName.c_str());
-	if (!notify_file.is_open())
-	{
-		llwarns << "Failed to open " << mFileName << llendl;
-		return;
-	}
+	LL_INFOS("LLNotificationStorage") << "starting read '" << mFileName << "'" << LL_ENDL;
 
-	LLSD input;
-	LLPointer<LLSDParser> parser = new LLSDXMLParser();
-	if (parser->parse(notify_file, input, LLSDSerialize::SIZE_UNLIMITED) < 0)
-	{
-		llwarns << "Failed to parse open notifications" << llendl;
-		return;
-	}
+	bool didFileRead;
 
-	if (input.isUndefined())
-	{
-		return;
-	}
+	pNotificationData.clear();
 
-	LLSD& data = input["data"];
-	if (data.isUndefined())
+	llifstream notifyFile(mFileName.c_str());
+	didFileRead = notifyFile.is_open();
+	if (!didFileRead)
 	{
-		return;
+		LL_WARNS("LLNotificationStorage") << "Failed to open file '" << mFileName << "'" << LL_ENDL;
 	}
-
-	using namespace LLNotificationsUI;
-	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
-		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
-
-	LLNotifications& instance = LLNotifications::instance();
-	S32 processed_notifications = 0;
-	for (LLSD::array_const_iterator notification_it = data.beginArray();
-		notification_it != data.endArray();
-		++notification_it)
+	else
 	{
-		LLSD notification_params = *notification_it;
-
-		if (instance.templateExists(notification_params["name"].asString()))
-		{
-			LLNotificationPtr notification(new LLNotification(notification_params));
-
-			LLNotificationResponderPtr responder(LLResponderRegistry::
-				createResponder(notification_params["name"], notification_params["responder"]));
-			notification->setResponseFunctor(responder);
-
-			instance.add(notification);
-
-			// hide script floaters so they don't confuse the user and don't overlap startup toast
-			LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
-
-			if(notification_channel)
-			{
-				// hide saved toasts so they don't confuse the user
-				notification_channel->hideToast(notification->getID());
-			}
-		}
-		else
-		{
-			llwarns << "Failed to find template for persistent notification " << notification_params["name"].asString() << llendl;
-		}
-
-		++processed_notifications;
-		if (processed_notifications >= MAX_PERSISTENT_NOTIFICATIONS)
+		LLPointer<LLSDParser> parser = new LLSDXMLParser();
+		didFileRead = (parser->parse(notifyFile, pNotificationData, LLSDSerialize::SIZE_UNLIMITED) >= 0);
+		if (!didFileRead)
 		{
-			llwarns << "Too many persistent notifications."
-					<< " Processed " << MAX_PERSISTENT_NOTIFICATIONS << " of " << data.size() << " persistent notifications." << llendl;
-			break;
+			LL_WARNS("LLNotificationStorage") << "Failed to parse open notifications from file '" << mFileName 
+				<< "'" << LL_ENDL;
 		}
 	}
 
-	LLNotifications::instance().getChannel("Persistent")->
-		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
-}
-
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
-//////////////////////////////////////////////////////////////////////////
+	LL_INFOS("LLNotificationStorage") << "ending read '" << mFileName << "'" << LL_ENDL;
 
-LLResponderRegistry::build_map_t LLResponderRegistry::sBuildMap;
-
-void LLResponderRegistry::registerResponders()
-{
-	sBuildMap.clear();
-
-	add("ObjectGiveItem", &create<LLOfferInfo>);
-	add("UserGiveItem", &create<LLOfferInfo>);
+	return didFileRead;
 }
 
-LLNotificationResponderInterface* LLResponderRegistry::createResponder(const std::string& notification_name, const LLSD& params)
+LLNotificationResponderInterface * LLNotificationStorage::createResponder(const std::string& pNotificationName, const LLSD& pParams) const
 {
-	build_map_t::const_iterator it = sBuildMap.find(notification_name);
-	if(sBuildMap.end() == it)
-	{
-		return NULL;
-	}
-	responder_constructor_t ctr = it->second;
-	return ctr(params);
+	return LLResponderRegistry::getInstance()->createResponder(pNotificationName, pParams);
 }
-
-void LLResponderRegistry::add(const std::string& notification_name, const responder_constructor_t& ctr)
-{
-	if(sBuildMap.find(notification_name) != sBuildMap.end())
-	{
-		llwarns << "Responder is already registered : " << notification_name << llendl;
-		llassert(!"Responder already registered");
-	}
-	sBuildMap[notification_name] = ctr;
-}
-
-// EOF
diff --git a/indra/newview/llnotificationstorage.h b/indra/newview/llnotificationstorage.h
index 8635c797c0c9f1f0d2cd2a98abf45332cd334913..7aabf7d09e03a9586a2516fd64b3bf30665f97a5 100644
--- a/indra/newview/llnotificationstorage.h
+++ b/indra/newview/llnotificationstorage.h
@@ -27,32 +27,27 @@
 #ifndef LL_NOTIFICATIONSTORAGE_H
 #define LL_NOTIFICATIONSTORAGE_H
 
-#include "llnotifications.h"
-
-// Class that saves not responded(unread) notifications.
-// Unread notifications are saved in open_notifications.xml in SL account folder
-//
-// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
-// Notifications using functor responders are saved automatically (see llviewermessage.cpp
-// lure_callback_reg for example).
-// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
-// be a) serializable(implement LLNotificationResponderInterface),
-// b) registered with LLResponderRegistry (found in llnotificationstorage.cpp).
-class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>
-{
-	LOG_CLASS(LLPersistentNotificationStorage);
-public:
+#include <string>
 
-	LLPersistentNotificationStorage();
+#include "llerror.h"
 
-	void saveNotifications();
+class LLNotificationResponderInterface;
+class LLSD;
 
-	void loadNotifications();
+class LLNotificationStorage
+{
+	LOG_CLASS(LLNotificationStorage);
+public:
+	LLNotificationStorage(std::string pFileName);
+	~LLNotificationStorage();
 
-private:
+protected:
+	bool writeNotifications(const LLSD& pNotificationData) const;
+	bool readNotifications(LLSD& pNotificationData) const;
 
-	bool onPersistentChannelChanged(const LLSD& payload);
+	LLNotificationResponderInterface* createResponder(const std::string& pNotificationName, const LLSD& pParams) const;
 
+private:
 	std::string mFileName;
 };
 
diff --git a/indra/newview/llnotificationtiphandler.cpp b/indra/newview/llnotificationtiphandler.cpp
index e397cfa046d97efa2142bf3ca5ca02f9d43f1b04..a85335f1ba9c0a3a2e5ccd8c1f05b016a78df934 100644
--- a/indra/newview/llnotificationtiphandler.cpp
+++ b/indra/newview/llnotificationtiphandler.cpp
@@ -28,8 +28,8 @@
 #include "llviewerprecompiledheaders.h" // must be first include
 
 #include "llfloaterreg.h"
-#include "llnearbychat.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotificationhandler.h"
 #include "llnotifications.h"
 #include "lltoastnotifypanel.h"
@@ -41,15 +41,13 @@
 using namespace LLNotificationsUI;
 
 //--------------------------------------------------------------------------
-LLTipHandler::LLTipHandler(e_notification_type type, const LLSD& id)
+LLTipHandler::LLTipHandler()
+:	LLSystemNotificationHandler("NotificationTips", "notifytip")
 {
-	mType = type;	
-
 	// Getting a Channel for our notifications
 	LLScreenChannel* channel = LLChannelManager::getInstance()->createNotificationChannel();
 	if(channel)
 	{
-		channel->setOnRejectToastCallback(boost::bind(&LLTipHandler::onRejectToast, this, _1));
 		mChannel = channel->getHandle();
 	}
 }
@@ -68,102 +66,67 @@ void LLTipHandler::initChannel()
 }
 
 //--------------------------------------------------------------------------
-bool LLTipHandler::processNotification(const LLSD& notify)
+bool LLTipHandler::processNotification(const LLNotificationPtr& notification)
 {
 	if(mChannel.isDead())
 	{
 		return false;
 	}
 
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if(!notification)
-		return false;	
-
 	// arrange a channel on a screen
 	if(!mChannel.get()->getVisible())
 	{
 		initChannel();
 	}
 
-	if(notify["sigtype"].asString() == "add" || notify["sigtype"].asString() == "change")
-	{
 		// archive message in nearby chat
-		if (LLHandlerUtil::canLogToNearbyChat(notification))
-		{
-			LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
-
-			// don't show toast if Nearby Chat is opened
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			LLNearbyChatBar* nearby_chat_bar = LLNearbyChatBar::getInstance();
-			if (!nearby_chat_bar->isMinimized() && nearby_chat_bar->getVisible() && nearby_chat->getVisible())
-			{
-				return false;
-			}
-		}
-
-		std::string session_name = notification->getPayload()["SESSION_NAME"];
-		const std::string name = notification->getSubstitutions()["NAME"];
-		if (session_name.empty())
-		{
-			session_name = name;
-		}
-		LLUUID from_id = notification->getPayload()["from_id"];
-		if (LLHandlerUtil::canLogToIM(notification))
-		{
-			LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
-					notification->getMessage(), from_id, from_id);
-		}
-
-		if (LLHandlerUtil::canSpawnIMSession(notification))
-		{
-			LLHandlerUtil::spawnIMSession(name, from_id);
-		}
+	if (notification->canLogToChat())
+	{
+		LLHandlerUtil::logToNearbyChat(notification, CHAT_SOURCE_SYSTEM);
 
-		// don't spawn toast for inventory accepted/declined offers if respective IM window is open (EXT-5909)
-		if (!LLHandlerUtil::canSpawnToast(notification))
+		// don't show toast if Nearby Chat is opened
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+		if (nearby_chat->isChatVisible())
 		{
 			return false;
 		}
+	}
 
-		LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
-
-		LLToast::Params p;
-		p.notif_id = notification->getID();
-		p.notification = notification;
-		p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
-		p.panel = notify_box;
-		p.is_tip = true;
-		p.can_be_stored = false;
-		
-		removeExclusiveNotifications(notification);
-
-		LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
-		if(channel)
-			channel->addToast(p);
+	std::string session_name = notification->getPayload()["SESSION_NAME"];
+	const std::string name = notification->getSubstitutions()["NAME"];
+	if (session_name.empty())
+	{
+		session_name = name;
 	}
-	else if (notify["sigtype"].asString() == "delete")
+	LLUUID from_id = notification->getPayload()["from_id"];
+	if (notification->canLogToIM())
 	{
-		mChannel.get()->killToastByNotificationID(notification->getID());
+		LLHandlerUtil::logToIM(IM_NOTHING_SPECIAL, session_name, name,
+				notification->getMessage(), from_id, from_id);
 	}
-	return false;
-}
-
-//--------------------------------------------------------------------------
-void LLTipHandler::onDeleteToast(LLToast* toast)
-{
-}
-
-//--------------------------------------------------------------------------
 
-void LLTipHandler::onRejectToast(const LLUUID& id)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(id);
+	if (notification->canLogToIM() && notification->hasFormElements())
+	{
+		LLHandlerUtil::spawnIMSession(name, from_id);
+	}
 
-	if (notification
-			&& LLNotificationManager::getInstance()->getHandlerForNotification(
-					notification->getType()) == this)
+	if (notification->canLogToIM() && LLHandlerUtil::isIMFloaterOpened(notification))
 	{
-		LLNotifications::instance().cancel(notification);
+		return false;
 	}
+
+	LLToastPanel* notify_box = LLToastPanel::buidPanelFromNotification(notification);
+
+	LLToast::Params p;
+	p.notif_id = notification->getID();
+	p.notification = notification;
+	p.lifetime_secs = gSavedSettings.getS32("NotificationTipToastLifeTime");
+	p.panel = notify_box;
+	p.is_tip = true;
+	p.can_be_stored = false;
+		
+	LLScreenChannel* channel = dynamic_cast<LLScreenChannel*>(mChannel.get());
+	if(channel)
+		channel->addToast(p);
+	return false;
 }
diff --git a/indra/newview/lloutputmonitorctrl.cpp b/indra/newview/lloutputmonitorctrl.cpp
index 85626d8783877bdd6d5722103c52f205d0bfa05f..6c26073d5baa7283fbdcb505fa145e4dd2494341 100644
--- a/indra/newview/lloutputmonitorctrl.cpp
+++ b/indra/newview/lloutputmonitorctrl.cpp
@@ -28,6 +28,7 @@
 #include "lloutputmonitorctrl.h"
 
 // library includes 
+#include "llfloaterreg.h"
 #include "llui.h"
 
 // viewer includes
@@ -72,8 +73,8 @@ LLOutputMonitorCtrl::LLOutputMonitorCtrl(const LLOutputMonitorCtrl::Params& p)
 	mAutoUpdate(p.auto_update),
 	mSpeakerId(p.speaker_id),
 	mIsAgentControl(false),
-	mIsSwitchDirty(false),
-	mShouldSwitchOn(false)
+	mIndicatorToggled(false),
+	mShowParticipantsSpeaking(false)
 {
 	//static LLUIColor output_monitor_muted_color = LLUIColorTable::instance().getColor("OutputMonitorMutedColor", LLColor4::orange);
 	//static LLUIColor output_monitor_overdriven_color = LLUIColorTable::instance().getColor("OutputMonitorOverdrivenColor", LLColor4::red);
@@ -114,26 +115,6 @@ void LLOutputMonitorCtrl::setPower(F32 val)
 
 void LLOutputMonitorCtrl::draw()
 {
-	// see also switchIndicator()
-	if (mIsSwitchDirty)
-	{
-		mIsSwitchDirty = false;
-		if (mShouldSwitchOn)
-		{
-			// just notify parent visibility may have changed
-			notifyParentVisibilityChanged();
-		}
-		else
-		{
-			// make itself invisible and notify parent about this
-			setVisible(FALSE);
-			notifyParentVisibilityChanged();
-
-			// no needs to render for invisible element
-			return;
-		}
-	}
-
 	// Copied from llmediaremotectrl.cpp
 	// *TODO: Give the LLOutputMonitorCtrl an agent-id to monitor, then
 	// call directly into LLVoiceClient::getInstance() to ask if that agent-id is muted, is
@@ -156,6 +137,24 @@ void LLOutputMonitorCtrl::draw()
 		}
 	}
 
+	if ((mPower == 0.f && !mIsTalking) && mShowParticipantsSpeaking)
+	{
+		std::set<LLUUID> participant_uuids;
+		LLVoiceClient::instance().getParticipantList(participant_uuids);
+		std::set<LLUUID>::const_iterator part_it = participant_uuids.begin();
+
+		F32 power = 0;
+		for (; part_it != participant_uuids.end(); ++part_it)
+		{
+			power = LLVoiceClient::instance().getCurrentPower(*part_it);
+			if (power)
+			{
+				mPower = power;
+				break;
+			}
+		}
+	}
+
 	LLPointer<LLUIImage> icon;
 	if (mIsMuted)
 	{
@@ -241,14 +240,34 @@ void LLOutputMonitorCtrl::draw()
 		gl_rect_2d(0, monh, monw, 0, sColorBound, FALSE);
 }
 
-void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/)
+// virtual
+BOOL LLOutputMonitorCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
+{
+	if (mSpeakerId != gAgentID && !mShowParticipantsSpeaking)
+	{
+		LLFloaterReg::showInstance("floater_voice_volume", LLSD().with("avatar_id", mSpeakerId));
+	}
+	else if(mShowParticipantsSpeaking)
+	{
+		LLFloaterReg::showInstance("chat_voice", LLSD());
+	}
+
+	return TRUE;
+}
+
+void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id/* = LLUUID::null*/, bool show_other_participants_speaking /* = false */)
 {
 	if (speaker_id.isNull() && mSpeakerId.notNull())
 	{
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
+        switchIndicator(false);
+        mSpeakerId = speaker_id;
 	}
 
-	if (speaker_id.isNull() || speaker_id == mSpeakerId) return;
+	if (speaker_id.isNull() || (speaker_id == mSpeakerId))
+	{
+		return;
+	}
 
 	if (mSpeakerId.notNull())
 	{
@@ -256,6 +275,7 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 		LLSpeakingIndicatorManager::unregisterSpeakingIndicator(mSpeakerId, this);
 	}
 
+	mShowParticipantsSpeaking = show_other_participants_speaking;
 	mSpeakerId = speaker_id;
 	LLSpeakingIndicatorManager::registerSpeakingIndicator(mSpeakerId, this, session_id);
 
@@ -264,12 +284,12 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 	{
 		if (speaker_id == gAgentID)
 		{
-			setIsMuted(false);
+			mIsMuted = false;
 		}
 		else
 		{
 			// check only blocking on voice. EXT-3542
-			setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+			mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
 			LLMuteList::getInstance()->addObserver(this);
 		}
 	}
@@ -278,32 +298,34 @@ void LLOutputMonitorCtrl::setSpeakerId(const LLUUID& speaker_id, const LLUUID& s
 void LLOutputMonitorCtrl::onChange()
 {
 	// check only blocking on voice. EXT-3542
-	setIsMuted(LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat));
+	mIsMuted = LLMuteList::getInstance()->isMuted(mSpeakerId, LLMute::flagVoiceChat);
 }
 
 // virtual
 void LLOutputMonitorCtrl::switchIndicator(bool switch_on)
 {
-	// ensure indicator is visible in case it is not in visible chain
-	// to be called when parent became visible next time to notify parent that visibility is changed.
-	setVisible(TRUE);
-
-	// if parent is in visible chain apply switch_on state and notify it immediately
-	if (getParent() && getParent()->isInVisibleChain())
-	{
-		LL_DEBUGS("SpeakingIndicator") << "Indicator is in visible chain, notifying parent: " << mSpeakerId << LL_ENDL;
-		setVisible((BOOL)switch_on);
-		notifyParentVisibilityChanged();
-	}
 
-	// otherwise remember necessary state and mark itself as dirty.
-	// State will be applied in next draw when parents chain becomes visible.
-	else
-	{
-		LL_DEBUGS("SpeakingIndicator") << "Indicator is not in visible chain, parent won't be notified: " << mSpeakerId << LL_ENDL;
-		mIsSwitchDirty = true;
-		mShouldSwitchOn = switch_on;
-	}
+    if(getVisible() != (BOOL)switch_on)
+    {
+        setVisible(switch_on);
+        
+        //Let parent adjust positioning of icons adjacent to speaker indicator
+        //(when speaker indicator hidden, adjacent icons move to right and when speaker
+        //indicator visible, adjacent icons move to the left) 
+        if (getParent() && getParent()->isInVisibleChain())
+        {
+            notifyParentVisibilityChanged();
+            //Ignore toggled state in case it was set when parent visibility was hidden
+            mIndicatorToggled = false;
+        }
+        else
+        {
+            //Makes sure to only adjust adjacent icons when parent becomes visible
+            //(!mIndicatorToggled ensures that changes of TFT and FTF are discarded, real state changes are TF or FT)
+            mIndicatorToggled = !mIndicatorToggled;
+        }
+
+    }
 }
 
 //////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/lloutputmonitorctrl.h b/indra/newview/lloutputmonitorctrl.h
index 2d23753d46edb1aba27085cb4f5d8c290c8fc322..0682af1278c95dda4fde4c44b32255d2f982893f 100644
--- a/indra/newview/lloutputmonitorctrl.h
+++ b/indra/newview/lloutputmonitorctrl.h
@@ -28,10 +28,10 @@
 #define LL_LLOUTPUTMONITORCTRL_H
 
 #include "v4color.h"
-#include "llview.h"
+#include "../llui/llview.h"
 #include "llmutelist.h"
 #include "llspeakingindicatormanager.h"
-#include "lluiimage.h"
+//#include "../llui/lluiimage.h"
 
 class LLTextBox;
 class LLUICtrlFactory;
@@ -68,19 +68,19 @@ class LLOutputMonitorCtrl
 
 	// llview overrides
 	virtual void	draw();
+	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 
 	void			setPower(F32 val);
 	F32				getPower(F32 val) const { return mPower; }
 	
-	bool			getIsMuted() const { return mIsMuted; }
-	void			setIsMuted(bool val) { mIsMuted = val; }
-
 	// For the current user, need to know the PTT state to show
 	// correct button image.
 	void			setIsAgentControl(bool val) { mIsAgentControl = val; }
 
 	void			setIsTalking(bool val) { mIsTalking = val; }
 
+	void			setShowParticipantsSpeaking(bool show) { mShowParticipantsSpeaking = show; }
+
 	/**
 	 * Sets avatar UUID to interact with voice channel.
 	 *
@@ -89,7 +89,7 @@ class LLOutputMonitorCtrl
 	 *		If this parameter is set registered indicator will be shown only in voice channel
 	 *		which has the same session id (EXT-5562).
 	 */
-	void			setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null);
+	void			setSpeakerId(const LLUUID& speaker_id, const LLUUID& session_id = LLUUID::null, bool show_other_participants_speaking = false);
 
 	//called by mute list
 	virtual void onChange();
@@ -105,6 +105,8 @@ class LLOutputMonitorCtrl
 	 * It will be applied in next draw and parent will be notified.
 	 */
 	virtual void	switchIndicator(bool switch_on);
+    bool getIndicatorToggled() { return mIndicatorToggled;}
+    void setIndicatorToggled(bool value) { mIndicatorToggled = value;}
 
 private:
 
@@ -131,6 +133,7 @@ class LLOutputMonitorCtrl
 	bool			mIsAgentControl;
 	bool			mIsMuted;
 	bool			mIsTalking;
+	bool			mShowParticipantsSpeaking;
 	LLPointer<LLUIImage> mImageMute;
 	LLPointer<LLUIImage> mImageOff;
 	LLPointer<LLUIImage> mImageOn;
@@ -144,9 +147,7 @@ class LLOutputMonitorCtrl
 	/** uuid of a speaker being monitored */
 	LLUUID			mSpeakerId;
 
-	/** indicates if the instance is dirty and should notify parent */
-	bool			mIsSwitchDirty;
-	bool			mShouldSwitchOn;
+    bool mIndicatorToggled;
 };
 
 #endif
diff --git a/indra/newview/llpanelblockedlist.cpp b/indra/newview/llpanelblockedlist.cpp
index 5c85ec438cb4e059a462a5b6944f480fb05d40f9..115114bb53ba5f3fa2171b299855a7bb19575855 100644
--- a/indra/newview/llpanelblockedlist.cpp
+++ b/indra/newview/llpanelblockedlist.cpp
@@ -30,15 +30,23 @@
 
 // library include
 #include "llavatarname.h"
+#include "llfiltereditor.h"
 #include "llfloater.h"
 #include "llfloaterreg.h"
 #include "llnotificationsutil.h"
 #include "llscrolllistctrl.h"
+#include "llmenubutton.h"
 
 // project include
+#include "llavatarlistitem.h"
+#include "llblocklist.h"
+#include "llblockedlistitem.h"
 #include "llfloateravatarpicker.h"
 #include "llfloatersidepanelcontainer.h"
+#include "llinventorylistitem.h"
+#include "llinventorymodel.h"
 #include "llsidetraypanelcontainer.h"
+#include "llviewercontrol.h"
 
 static LLRegisterPanelClassWrapper<LLPanelBlockedList> t_panel_blocked_list("panel_block_list_sidetray");
 
@@ -54,26 +62,47 @@ const std::string BLOCKED_PARAM_NAME = "blocked_to_select";
 LLPanelBlockedList::LLPanelBlockedList()
 :	LLPanel()
 {
-	mCommitCallbackRegistrar.add("Block.ClickPick",			boost::bind(&LLPanelBlockedList::onPickBtnClick, this));
-	mCommitCallbackRegistrar.add("Block.ClickBlockByName",	boost::bind(&LLPanelBlockedList::onBlockByNameClick, this));
-	mCommitCallbackRegistrar.add("Block.ClickRemove",		boost::bind(&LLPanelBlockedList::onRemoveBtnClick, this));
+	mCommitCallbackRegistrar.add("Block.Action",	boost::bind(&LLPanelBlockedList::onCustomAction,  this, _2));
+	mEnableCallbackRegistrar.add("Block.Check",		boost::bind(&LLPanelBlockedList::isActionChecked, this, _2));
 }
 
-LLPanelBlockedList::~LLPanelBlockedList()
+void LLPanelBlockedList::removePicker()
 {
-	LLMuteList::getInstance()->removeObserver(this);
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
 }
 
 BOOL LLPanelBlockedList::postBuild()
 {
-	mBlockedList = getChild<LLScrollListCtrl>("blocked");
+	mBlockedList = getChild<LLBlockList>("blocked");
 	mBlockedList->setCommitOnSelectionChange(TRUE);
+    this->setVisibleCallback(boost::bind(&LLPanelBlockedList::removePicker, this));
 
-	childSetCommitCallback("back", boost::bind(&LLPanelBlockedList::onBackBtnClick, this), NULL);
+	switch (gSavedSettings.getU32("BlockPeopleSortOrder"))
+	{
+	case E_SORT_BY_NAME:
+		mBlockedList->sortByName();
+		break;
+
+	case E_SORT_BY_TYPE:
+		mBlockedList->sortByType();
+		break;
+	default:
+		llwarns << "Unrecognized sort order for blocked list" << llendl;
+		break;
+	}
+
+	// Use the context menu of the Block list for the Block tab gear menu.
+	LLToggleableMenu* blocked_gear_menu = mBlockedList->getContextMenu();
+	if (blocked_gear_menu)
+	{
+		getChild<LLMenuButton>("blocked_gear_btn")->setMenu(blocked_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
 
-	LLMuteList::getInstance()->addObserver(this);
-	
-	refreshBlockedList();
+	getChild<LLButton>("unblock_btn")->setCommitCallback(boost::bind(&LLPanelBlockedList::unblockItem, this));
+	getChild<LLFilterEditor>("blocked_filter_input")->setCommitCallback(boost::bind(&LLPanelBlockedList::onFilterEdit, this, _2));
 
 	return LLPanel::postBuild();
 }
@@ -94,97 +123,112 @@ void LLPanelBlockedList::onOpen(const LLSD& key)
 
 void LLPanelBlockedList::selectBlocked(const LLUUID& mute_id)
 {
-	mBlockedList->selectByID(mute_id);
+	mBlockedList->selectItemByUUID(mute_id);
 }
 
 void LLPanelBlockedList::showPanelAndSelect(const LLUUID& idToSelect)
 {
-	LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD().with(BLOCKED_PARAM_NAME, idToSelect));
+	LLFloaterSidePanelContainer::showPanel("people", "panel_people",
+		LLSD().with("people_panel_tab_name", "blocked_panel").with(BLOCKED_PARAM_NAME, idToSelect));
 }
 
 
 //////////////////////////////////////////////////////////////////////////
 // Private Section
 //////////////////////////////////////////////////////////////////////////
-void LLPanelBlockedList::refreshBlockedList()
+void LLPanelBlockedList::updateButtons()
 {
-	mBlockedList->deleteAllItems();
+	bool hasSelected = NULL != mBlockedList->getSelectedItem();
+	getChildView("unblock_btn")->setEnabled(hasSelected);
+	getChildView("blocked_gear_btn")->setEnabled(hasSelected);
+}
 
-	std::vector<LLMute> mutes = LLMuteList::getInstance()->getMutes();
-	std::vector<LLMute>::iterator it;
-	for (it = mutes.begin(); it != mutes.end(); ++it)
+void LLPanelBlockedList::unblockItem()
+{
+	LLBlockedListItem* item = mBlockedList->getBlockedItem();
+	if (item)
 	{
-		LLScrollListItem::Params item_p;
-		item_p.enabled(TRUE);
-		item_p.value(it->mID); // link UUID of blocked item with ScrollListItem
-		item_p.columns.add().column("item_name").value(it->mName);//.type("text");
-		item_p.columns.add().column("item_type").value(it->getDisplayType());//.type("text").width(111);
-
-		mBlockedList->addRow(item_p, ADD_BOTTOM);
+		LLMute mute(item->getUUID(), item->getName());
+		LLMuteList::instance().remove(mute);
 	}
 }
 
-void LLPanelBlockedList::updateButtons()
+void LLPanelBlockedList::onCustomAction(const LLSD& userdata)
 {
-	bool hasSelected = NULL != mBlockedList->getFirstSelected();
-	getChildView("Unblock")->setEnabled(hasSelected);
-}
-
+	const std::string command_name = userdata.asString();
 
-
-void LLPanelBlockedList::onBackBtnClick()
-{
-	LLSideTrayPanelContainer* parent = dynamic_cast<LLSideTrayPanelContainer*>(getParent());
-	if(parent)
+	if ("block_obj_by_name" == command_name)
+	{
+		blockObjectByName();
+	}
+	else if ("block_res_by_name" == command_name)
+	{
+		blockResidentByName();
+	}
+	else if ("sort_by_name" == command_name)
+	{
+		mBlockedList->sortByName();
+		gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_NAME);
+	}
+	else if ("sort_by_type" == command_name)
 	{
-		parent->openPreviousPanel();
+		mBlockedList->sortByType();
+		gSavedSettings.setU32("BlockPeopleSortOrder", E_SORT_BY_TYPE);
 	}
 }
 
-void LLPanelBlockedList::onRemoveBtnClick()
+BOOL LLPanelBlockedList::isActionChecked(const LLSD& userdata)
 {
-	std::string name = mBlockedList->getSelectedItemLabel();
-	LLUUID id = mBlockedList->getStringUUIDSelectedItem();
-	LLMute mute(id, name);
-	
-	S32 last_selected = mBlockedList->getFirstSelectedIndex();
-	if (LLMuteList::getInstance()->remove(mute))
+	std::string item = userdata.asString();
+	U32 sort_order = gSavedSettings.getU32("BlockPeopleSortOrder");
+
+	if ("sort_by_name" == item)
+	{
+		return E_SORT_BY_NAME == sort_order;
+	}
+	else if ("sort_by_type" == item)
 	{
-		// Above removals may rebuild this dialog.
-		
-		if (last_selected == mBlockedList->getItemCount())
-		{
-			// we were on the last item, so select the last item again
-			mBlockedList->selectNthItem(last_selected - 1);
-		}
-		else
-		{
-			// else select the item after the last item previously selected
-			mBlockedList->selectNthItem(last_selected);
-		}
+		return E_SORT_BY_TYPE == sort_order;
 	}
+
+	return false;
 }
 
-void LLPanelBlockedList::onPickBtnClick()
+void LLPanelBlockedList::blockResidentByName()
 {
 	const BOOL allow_multiple = FALSE;
 	const BOOL close_on_select = TRUE;
-	/*LLFloaterAvatarPicker* picker = */LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), allow_multiple, close_on_select);
-
-	// *TODO: mantipov: should LLFloaterAvatarPicker be closed when panel is closed?
-	// old Floater dependency is not enable in panel
-	// addDependentFloater(picker);
+    
+    LLView * button = findChild<LLButton>("plus_btn", TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker * picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelBlockedList::callbackBlockPicked, this, _1, _2), 
+                                                                                    allow_multiple, close_on_select, FALSE, root_floater->getName(), button);
+    
+    if (root_floater)
+    {
+        root_floater->addDependentFloater(picker);
+    }
+
+    mPicker = picker->getHandle();
 }
 
-void LLPanelBlockedList::onBlockByNameClick()
+void LLPanelBlockedList::blockObjectByName()
 {
 	LLFloaterGetBlockedObjectName::show(&LLPanelBlockedList::callbackBlockByName);
 }
 
+void LLPanelBlockedList::onFilterEdit(const std::string& search_string)
+{
+	std::string filter = search_string;
+	LLStringUtil::trimHead(filter);
+
+	mBlockedList->setNameFilter(filter);
+}
+
 void LLPanelBlockedList::callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
 	if (names.empty() || ids.empty()) return;
-	LLMute mute(ids[0], names[0].getLegacyName(), LLMute::AGENT);
+	LLMute mute(ids[0], names[0].getAccountName(), LLMute::AGENT);
 	LLMuteList::getInstance()->add(mute);
 	showPanelAndSelect(mute.mID);
 }
diff --git a/indra/newview/llpanelblockedlist.h b/indra/newview/llpanelblockedlist.h
index 74ad82e32d697b9bb278e700d9b95e91cdf106af..07f04376566c9350e1637fa8f974f95518bf9541 100644
--- a/indra/newview/llpanelblockedlist.h
+++ b/indra/newview/llpanelblockedlist.h
@@ -30,21 +30,15 @@
 #include "llpanel.h"
 #include "llmutelist.h"
 #include "llfloater.h"
-// #include <vector>
 
-// class LLButton;
-// class LLLineEditor;
-// class LLMessageSystem;
-// class LLUUID;
 class LLAvatarName;
-class LLScrollListCtrl;
+class LLBlockList;
 
-class LLPanelBlockedList
-	:	public LLPanel, public LLMuteListObserver
+class LLPanelBlockedList : public LLPanel
 {
 public:
 	LLPanelBlockedList();
-	~LLPanelBlockedList();
+	~LLPanelBlockedList(){};
 
 	virtual BOOL postBuild();
 	virtual void draw();
@@ -59,25 +53,33 @@ class LLPanelBlockedList
 	 *			If it is LLUUID::null, nothing will be selected.
 	 */
 	static void showPanelAndSelect(const LLUUID& idToSelect);
-
-	// LLMuteListObserver callback interface implementation.
-	/* virtual */ void onChange() {	refreshBlockedList();}
 	
 private:
-	void refreshBlockedList();
+
+	typedef enum e_sort_oder{
+		E_SORT_BY_NAME = 0,
+		E_SORT_BY_TYPE = 1,
+	} ESortOrder;
+
+    void removePicker();
 	void updateButtons();
 
 	// UI callbacks
-	void onBackBtnClick();
-	void onRemoveBtnClick();
-	void onPickBtnClick();
-	void onBlockByNameClick();
+	void unblockItem();
+	void blockResidentByName();
+	void blockObjectByName();
+	void onFilterEdit(const std::string& search_string);
+
+	// List commnads
+	void onCustomAction(const LLSD& userdata);
+	BOOL isActionChecked(const LLSD& userdata);
 
 	void callbackBlockPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names);
 	static void callbackBlockByName(const std::string& text);
 
 private:
-	LLScrollListCtrl* mBlockedList;
+	LLBlockList* mBlockedList;
+    LLHandle<LLFloater> mPicker;
 };
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 6889b98ab1778e46ef334cb8f6d81b026c5df9c7..862e4be203a5dea41b621fc98acf92b814b7bd2d 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -55,6 +55,7 @@
 #include "lltrans.h"
 #include "llscrollcontainer.h"
 #include "llstatusbar.h"
+#include "llviewertexture.h"
 
 const S32 MINIMUM_PRICE_FOR_LISTING = 50;	// L$
 
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index 77e1487f3835764938b749fae338a67cfb70c95b..1a427338e5ae54c2cd11b41d743538bc1010388a 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -78,8 +78,6 @@ const char* LLPanelContents::PERMS_ANYONE_CONTROL_KEY = "perms_anyone_control";
 
 BOOL LLPanelContents::postBuild()
 {
-	LLRect rect = this->getRect();
-
 	setMouseOpaque(FALSE);
 
 	childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index 6b9edcb07c6f890a3835d5e2b09271d778209adf..e71dba5caee73871c17c7e9d531ceeed95a2b2a2 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -28,7 +28,7 @@
 
 #include "llpaneleditwearable.h"
 #include "llpanel.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "lluictrl.h"
 #include "llscrollingpanellist.h"
 #include "llvisualparam.h"
@@ -52,6 +52,7 @@
 #include "lltexturectrl.h"
 #include "lltextureentry.h"
 #include "llviewercontrol.h"    // gSavedSettings
+#include "llviewerregion.h"
 #include "llviewertexturelist.h"
 #include "llagentcamera.h"
 #include "llmorphview.h"
@@ -104,7 +105,7 @@ enum ESubpart {
         SUBPART_PHYSICS_ADVANCED,
  };
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 typedef std::vector<ESubpart> subpart_vec_t;
 
@@ -718,8 +719,8 @@ BOOL LLPanelEditWearable::postBuild()
         mBtnBack = getChild<LLButton>("back_btn");
         mBackBtnLabel = mBtnBack->getLabelUnselected();
         mBtnBack->setLabel(LLStringUtil::null);
-        // handled at appearance panel level?
-        //mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
+
+        mBtnBack->setClickedCallback(boost::bind(&LLPanelEditWearable::onBackButtonClicked, this));
 
         mNameEditor = getChild<LLLineEditor>("description");
 
@@ -762,11 +763,11 @@ BOOL LLPanelEditWearable::postBuild()
 
         mWearablePtr = NULL;
 
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
-        configureAlphaCheckbox(LLVOAvatarDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_LOWER_ALPHA, "lower alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_UPPER_ALPHA, "upper alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HEAD_ALPHA, "head alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_EYES_ALPHA, "eye alpha texture invisible");
+        configureAlphaCheckbox(LLAvatarAppearanceDefines::TEX_HAIR_ALPHA, "hair alpha texture invisible");
 
         // configure tab expanded callbacks
         for (U32 type_index = 0; type_index < (U32)LLWearableType::WT_COUNT; ++type_index)
@@ -856,6 +857,14 @@ void LLPanelEditWearable::draw()
         LLPanel::draw();
 }
 
+void LLPanelEditWearable::onClose()
+{
+	if ( isDirty() )
+	{
+		revertChanges();
+	}
+}
+
 void LLPanelEditWearable::setVisible(BOOL visible)
 {
         if (!visible)
@@ -865,13 +874,22 @@ void LLPanelEditWearable::setVisible(BOOL visible)
         LLPanel::setVisible(visible);
 }
 
-void LLPanelEditWearable::setWearable(LLWearable *wearable, BOOL disable_camera_switch)
+void LLPanelEditWearable::setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch)
 {
         showWearable(mWearablePtr, FALSE, disable_camera_switch);
         mWearablePtr = wearable;
         showWearable(mWearablePtr, TRUE, disable_camera_switch);
 }
 
+//static 
+void LLPanelEditWearable::onBackButtonClicked(void* userdata)
+{
+    LLPanelEditWearable *panel = (LLPanelEditWearable*) userdata;
+	if ( panel->isDirty() )
+	{
+		LLAppearanceMgr::instance().setOutfitDirty( true );		
+	}
+}
 
 //static 
 void LLPanelEditWearable::onRevertButtonClicked(void* userdata)
@@ -922,7 +940,7 @@ void LLPanelEditWearable::onCommitSexChange()
         }
 
         bool is_new_sex_male = (gSavedSettings.getU32("AvatarSex") ? SEX_MALE : SEX_FEMALE) == SEX_MALE;
-        LLWearable*     wearable = gAgentWearables.getWearable(type, index);
+        LLViewerWearable*     wearable = gAgentWearables.getViewerWearable(type, index);
         if (wearable)
         {
                 wearable->setVisualParamWeight(param->getID(), is_new_sex_male, FALSE);
@@ -1007,13 +1025,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
                 return;
 
         bool is_modifiable = false;
-        bool is_copyable   = false;
 
         if(mWearableItem)
         {
                 const LLPermissions& perm = mWearableItem->getPermissions();
                 is_modifiable = perm.allowModifyBy(gAgent.getID(), gAgent.getGroupID());
-                is_copyable = perm.allowCopyBy(gAgent.getID(), gAgent.getGroupID());
         }
 
         if (is_modifiable)
@@ -1030,6 +1046,11 @@ void LLPanelEditWearable::updatePanelPickerControls(LLWearableType::EType type)
         }
 }
 
+void LLPanelEditWearable::incrementCofVersionLegacy()
+{
+
+}
+
 void LLPanelEditWearable::saveChanges(bool force_save_as)
 {
         if (!mWearablePtr || !isDirty())
@@ -1041,17 +1062,50 @@ void LLPanelEditWearable::saveChanges(bool force_save_as)
         U32 index = gAgentWearables.getWearableIndex(mWearablePtr);
 
         std::string new_name = mNameEditor->getText();
+
+		// Find an existing link to this wearable's inventory item, if any, and its description field.
+		LLInventoryItem *link_item = NULL;
+		std::string description;
+		LLInventoryModel::item_array_t links =
+			LLAppearanceMgr::instance().findCOFItemLinks(mWearablePtr->getItemID());
+		if (links.size()>0)
+		{
+			link_item = links.get(0).get();
+			if (link_item && link_item->getIsLinkType())
+			{
+				description = link_item->getActualDescription();
+			}
+		}
+
         if (force_save_as)
         {
                 // the name of the wearable has changed, re-save wearable with new name
-                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID(),false);
-                gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, FALSE);
+                LLAppearanceMgr::instance().removeCOFItemLinks(mWearablePtr->getItemID());
+			gAgentWearables.saveWearableAs(mWearablePtr->getType(), index, new_name, description, FALSE);
                 mNameEditor->setText(mWearableItem->getName());
         }
         else
         {
+			// Make another copy of this link, with the same
+			// description.  This is needed to bump the COF
+			// version so texture baking service knows appearance has changed.
+			if (link_item)
+			{
+				// Create new link
+				link_inventory_item( gAgent.getID(),
+									 link_item->getLinkedUUID(),
+									 LLAppearanceMgr::instance().getCOF(),
+									 link_item->getName(),
+									 description,
+									 LLAssetType::AT_LINK,
+									 NULL);
+				// Remove old link
+				gInventory.purgeObject(link_item->getUUID());
+			}
                 gAgentWearables.saveWearable(mWearablePtr->getType(), index, TRUE, new_name);
         }
+
+	
 }
 
 void LLPanelEditWearable::revertChanges()
@@ -1069,7 +1123,7 @@ void LLPanelEditWearable::revertChanges()
         gAgentAvatarp->wearableUpdated(mWearablePtr->getType(), FALSE);
 }
 
-void LLPanelEditWearable::showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch)
+void LLPanelEditWearable::showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch)
 {
         if (!wearable)
         {
@@ -1440,12 +1494,11 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
         {
                 panel_list->clearPanels();
                 value_map_t::iterator end = sorted_params.end();
-                S32 height = 0;
                 for(value_map_t::iterator it = sorted_params.begin(); it != end; ++it)
                 {
                         LLPanel::Params p;
                         p.name("LLScrollingPanelParam");
-                        LLWearable *wearable = this->getWearable();
+                        LLViewerWearable *wearable = this->getWearable();
                         LLScrollingPanelParamBase *panel_param = NULL;
                         if (wearable && wearable->getType() == LLWearableType::WT_PHYSICS) // Hack to show a different panel for physics.  Should generalize this later.
                         {
@@ -1455,7 +1508,7 @@ void LLPanelEditWearable::buildParamList(LLScrollingPanelList *panel_list, value
                         {
                                 panel_param = new LLScrollingPanelParam( p, NULL, (*it).second, TRUE, this->getWearable(), jointp);
                         }
-                        height = panel_list->addPanel( panel_param );
+                        panel_list->addPanel( panel_param );
                 }
         }
 }
@@ -1505,7 +1558,7 @@ void LLPanelEditWearable::updateVerbs()
         }
 }
 
-void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name)
+void LLPanelEditWearable::configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name)
 {
         LLCheckBoxCtrl* checkbox = mPanelAlpha->getChild<LLCheckBoxCtrl>(name);
         checkbox->setCommitCallback(boost::bind(&LLPanelEditWearable::onInvisibilityCommit, this, checkbox, te));
@@ -1513,7 +1566,7 @@ void LLPanelEditWearable::configureAlphaCheckbox(LLVOAvatarDefines::ETextureInde
         mAlphaCheckbox2Index[name] = te;
 }
 
-void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te)
 {
         if (!checkbox_ctrl) return;
         if (!getWearable()) return;
@@ -1557,7 +1610,7 @@ void LLPanelEditWearable::updateAlphaCheckboxes()
         for(string_texture_index_map_t::iterator iter = mAlphaCheckbox2Index.begin();
                 iter != mAlphaCheckbox2Index.end(); ++iter )
         {
-                LLVOAvatarDefines::ETextureIndex te = (LLVOAvatarDefines::ETextureIndex)iter->second;
+                LLAvatarAppearanceDefines::ETextureIndex te = (LLAvatarAppearanceDefines::ETextureIndex)iter->second;
                 LLCheckBoxCtrl* ctrl = mPanelAlpha->getChild<LLCheckBoxCtrl>(iter->first);
                 if (ctrl)
                 {
@@ -1575,7 +1628,7 @@ void LLPanelEditWearable::initPreviousAlphaTextures()
         initPreviousAlphaTextureEntry(TEX_LOWER_ALPHA);
 }
 
-void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te)
+void LLPanelEditWearable::initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te)
 {
         LLLocalTextureObject *lto = getWearable()->getLocalTextureObject(te);
         if (lto)
diff --git a/indra/newview/llpaneleditwearable.h b/indra/newview/llpaneleditwearable.h
index 692a7ce90fa06df8939da6d094ca1acbb3ec9614..6533d55f2fc6e1ea9cc141d0023689fd9e7a92ef 100644
--- a/indra/newview/llpaneleditwearable.h
+++ b/indra/newview/llpaneleditwearable.h
@@ -30,12 +30,12 @@
 #include "llpanel.h"
 #include "llscrollingpanellist.h"
 #include "llmodaldialog.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 #include "llwearabletype.h"
 
 class LLAccordionCtrl;
 class LLCheckBoxCtrl;
-class LLWearable;
+class LLViewerWearable;
 class LLTextBox;
 class LLViewerInventoryItem;
 class LLViewerVisualParam;
@@ -54,12 +54,13 @@ class LLPanelEditWearable : public LLPanel
 	/*virtual*/ BOOL 		postBuild();
 	/*virtual*/ BOOL		isDirty() const;	// LLUICtrl
 	/*virtual*/ void		draw();	
+				void		onClose();
 
 	// changes camera angle to default for selected subpart
 	void				changeCamera(U8 subpart);
 
-	LLWearable* 		getWearable() { return mWearablePtr; }
-	void				setWearable(LLWearable *wearable, BOOL disable_camera_switch = FALSE);
+	LLViewerWearable*	getWearable() { return mWearablePtr; }
+	void				setWearable(LLViewerWearable *wearable, BOOL disable_camera_switch = FALSE);
 
 	void				saveChanges(bool force_save_as = false);
 	void				revertChanges();
@@ -70,17 +71,17 @@ class LLPanelEditWearable : public LLPanel
 	void 				updateScrollingPanelList();
 
 	static void			onRevertButtonClicked(void* userdata);
+	static void			onBackButtonClicked(void* userdata); 
 	void				onCommitSexChange();
 	void				onSaveAsButtonClicked();
 	void				saveAsCallback(const LLSD& notification, const LLSD& response);
 
 	virtual void		setVisible(BOOL visible);
 
-
 private:
 	typedef std::map<F32, LLViewerVisualParam*> value_map_t;
 
-	void				showWearable(LLWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
+	void				showWearable(LLViewerWearable* wearable, BOOL show, BOOL disable_camera_switch = FALSE);
 	void				updateScrollingPanelUI();
 	LLPanel*			getPanel(LLWearableType::EType type);
 	void				getSortedParams(value_map_t &sorted_params, const std::string &edit_group);
@@ -94,17 +95,17 @@ class LLPanelEditWearable : public LLPanel
 	void				toggleTypeSpecificControls(LLWearableType::EType type);
 	void				updateTypeSpecificControls(LLWearableType::EType type);
 
-	//alpha mask checkboxes
-	void configureAlphaCheckbox(LLVOAvatarDefines::ETextureIndex te, const std::string& name);
-	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLVOAvatarDefines::ETextureIndex te);
+	// alpha mask checkboxes
+	void configureAlphaCheckbox(LLAvatarAppearanceDefines::ETextureIndex te, const std::string& name);
+	void onInvisibilityCommit(LLCheckBoxCtrl* checkbox_ctrl, LLAvatarAppearanceDefines::ETextureIndex te);
 	void updateAlphaCheckboxes();
 	void initPreviousAlphaTextures();
-	void initPreviousAlphaTextureEntry(LLVOAvatarDefines::ETextureIndex te);
+	void initPreviousAlphaTextureEntry(LLAvatarAppearanceDefines::ETextureIndex te);
 
 	// callback for HeightUnits parameter.
 	bool changeHeightUnits(const LLSD& new_value);
 
-	// updates current metric and replacemet metric label text
+	// updates current metric and replacement metric label text
 	void updateMetricLayout(BOOL new_value);
 
 	// updates avatar height label
@@ -114,8 +115,11 @@ class LLPanelEditWearable : public LLPanel
 
 	void setWearablePanelVisibilityChangeCallback(LLPanel* bodypart_panel);
 
+	// *HACK Remove this when serverside texture baking is available on all regions.
+	void incrementCofVersionLegacy();
+
 	// the pointer to the wearable we're editing. NULL means we're not editing a wearable.
-	LLWearable *mWearablePtr;
+	LLViewerWearable *mWearablePtr;
 	LLViewerInventoryItem* mWearableItem;
 
 	// these are constant no matter what wearable we're editing
@@ -128,7 +132,7 @@ class LLPanelEditWearable : public LLPanel
 	LLTextBox *mTxtAvatarHeight;
 
 
-	// localized and parametrized strings that used to build avatar_height_label
+	// localized and parameterized strings that used to build avatar_height_label
 	std::string mMeters;
 	std::string mFeet;
 	std::string mHeigth;
@@ -151,7 +155,7 @@ class LLPanelEditWearable : public LLPanel
 	LLPanel *mPanelEyes;
 	LLPanel *mPanelHair;
 
-	//clothes
+	// clothes
 	LLPanel *mPanelShirt;
 	LLPanel *mPanelPants;
 	LLPanel *mPanelShoes;
@@ -165,10 +169,10 @@ class LLPanelEditWearable : public LLPanel
 	LLPanel *mPanelTattoo;
 	LLPanel *mPanelPhysics;
 
-	typedef std::map<std::string, LLVOAvatarDefines::ETextureIndex> string_texture_index_map_t;
+	typedef std::map<std::string, LLAvatarAppearanceDefines::ETextureIndex> string_texture_index_map_t;
 	string_texture_index_map_t mAlphaCheckbox2Index;
 
-	typedef std::map<LLVOAvatarDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
+	typedef std::map<LLAvatarAppearanceDefines::ETextureIndex, LLUUID> s32_uuid_map_t;
 	s32_uuid_map_t mPreviousAlphaTexture;
 };
 
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 202be9671b4d4bdb092b69391c7f518de57fecba..445c0d811f202a76c7e701eb46e8440d84b6557d 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -84,7 +84,6 @@ BOOL	LLPanelFace::postBuild()
 	childSetCommitCallback("TexOffsetV",LLPanelFace::onCommitTextureInfo, this);
 	childSetAction("button align",&LLPanelFace::onClickAutoFix,this);
 
-	LLRect	rect = this->getRect();
 	LLTextureCtrl*	mTextureCtrl;
 	LLColorSwatchCtrl*	mColorSwatch;
 
diff --git a/indra/newview/llpanelgroupgeneral.cpp b/indra/newview/llpanelgroupgeneral.cpp
index 993ffb7825dc530358f4ac7665d17a571330b926..0cd93b330ad2ff1593ebebc9cb25f1ae0b50ae77 100644
--- a/indra/newview/llpanelgroupgeneral.cpp
+++ b/indra/newview/llpanelgroupgeneral.cpp
@@ -79,13 +79,18 @@ LLPanelGroupGeneral::LLPanelGroupGeneral()
 	mCtrlReceiveNotices(NULL),
 	mCtrlListGroup(NULL),
 	mActiveTitleLabel(NULL),
-	mComboActiveTitle(NULL)
+	mComboActiveTitle(NULL),
+	mAvatarNameCacheConnection()
 {
 
 }
 
 LLPanelGroupGeneral::~LLPanelGroupGeneral()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 BOOL LLPanelGroupGeneral::postBuild()
@@ -727,9 +732,12 @@ void LLPanelGroupGeneral::updateMembers()
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			LLAvatarNameCache::get(mMemberProgress->first, 
-									boost::bind(&LLPanelGroupGeneral::onNameCache,
-												this, gdatap->getMemberVersion(), member, _2));
+			// *TODO : Use a callback per member, not for the panel group.
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupGeneral::onNameCache, this, gdatap->getMemberVersion(), member, _2));
 		}
 	}
 
@@ -769,6 +777,8 @@ void LLPanelGroupGeneral::addMember(LLGroupMemberData* member)
 
 void LLPanelGroupGeneral::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 
 	if (!gdatap
diff --git a/indra/newview/llpanelgroupgeneral.h b/indra/newview/llpanelgroupgeneral.h
index 1b4e8e2645225c769b6f109ddc995f9b8995fa8b..b7f4a011397575d92aa7e785cd0aa5bc628ff098 100644
--- a/indra/newview/llpanelgroupgeneral.h
+++ b/indra/newview/llpanelgroupgeneral.h
@@ -111,6 +111,7 @@ class LLPanelGroupGeneral : public LLPanelGroupTab
 	LLComboBox		*mComboMature;
 
 	LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 #endif
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index b9b347d4bea0eab4ca116d782a4f0fadb711627e..133b269c112433824dea63880210092b1880d552 100644
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -89,6 +89,8 @@ class LLPanelGroupInvite::impl
 	void (*mCloseCallback)(void* data);
 
 	void* mCloseCallbackUserData;
+
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 
@@ -102,12 +104,17 @@ LLPanelGroupInvite::impl::impl(const LLUUID& group_id):
 	mGroupName( NULL ),
 	mConfirmedOwnerInvite( false ),
 	mCloseCallback( NULL ),
-	mCloseCallbackUserData( NULL )
+	mCloseCallbackUserData( NULL ),
+	mAvatarNameCacheConnection()
 {
 }
 
 LLPanelGroupInvite::impl::~impl()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
@@ -301,11 +308,13 @@ void LLPanelGroupInvite::impl::callbackClickAdd(void* userdata)
 		//Soon the avatar picker will be embedded into this panel
 		//instead of being it's own separate floater.  But that is next week.
 		//This will do for now. -jwolk May 10, 2006
+        LLView * button = panelp->findChild<LLButton>("add_button");
+        LLFloater * root_floater = gFloaterView->getParentFloater(panelp);
 		LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(
-			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE);
+			boost::bind(impl::callbackAddUsers, _1, panelp->mImplementation), TRUE, FALSE, FALSE, root_floater->getName(), button);
 		if (picker)
 		{
-			gFloaterView->getParentFloater(panelp)->addDependentFloater(picker);
+			root_floater->addDependentFloater(picker);
 		}
 	}
 }
@@ -378,8 +387,24 @@ void LLPanelGroupInvite::impl::callbackAddUsers(const uuid_vec_t& agent_ids, voi
 	std::vector<std::string> names;
 	for (S32 i = 0; i < (S32)agent_ids.size(); i++)
 	{
-		LLAvatarNameCache::get(agent_ids[i],
-			boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+		LLAvatarName av_name;
+		if (LLAvatarNameCache::get(agent_ids[i], &av_name))
+		{
+			LLPanelGroupInvite::impl::onAvatarNameCache(agent_ids[i], av_name, user_data);
+		}
+		else 
+		{
+			impl* selfp = (impl*) user_data;
+			if (selfp)
+			{
+				if (selfp->mAvatarNameCacheConnection.connected())
+				{
+					selfp->mAvatarNameCacheConnection.disconnect();
+				}
+				// *TODO : Add a callback per avatar name being fetched.
+				selfp->mAvatarNameCacheConnection = LLAvatarNameCache::get(agent_ids[i],boost::bind(&LLPanelGroupInvite::impl::onAvatarNameCache, _1, _2, user_data));
+			}
+		}
 	}	
 	
 }
@@ -392,6 +417,10 @@ void LLPanelGroupInvite::impl::onAvatarNameCache(const LLUUID& agent_id,
 
 	if (selfp)
 	{
+		if (selfp->mAvatarNameCacheConnection.connected())
+		{
+			selfp->mAvatarNameCacheConnection.disconnect();
+		}
 		std::vector<std::string> names;
 		uuid_vec_t agent_ids;
 		agent_ids.push_back(agent_id);
@@ -471,8 +500,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				if (!LLAvatarNameCache::get(agent_id, &av_name))
 				{
 					// actually it should happen, just in case
-					LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(
-							&LLPanelGroupInvite::addUserCallback, this, _1, _2));
+					//LLAvatarNameCache::get(LLUUID(agent_id), boost::bind(&LLPanelGroupInvite::addUserCallback, this, _1, _2));
 					// for this special case!
 					//when there is no cached name we should remove resident from agent_ids list to avoid breaking of sequence
 					// removed id will be added in callback
@@ -480,7 +508,7 @@ void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
 				}
 				else
 				{
-					names.push_back(av_name.getLegacyName());
+					names.push_back(av_name.getAccountName());
 				}
 			}
 		}
@@ -493,7 +521,7 @@ void LLPanelGroupInvite::addUserCallback(const LLUUID& id, const LLAvatarName& a
 	std::vector<std::string> names;
 	uuid_vec_t agent_ids;
 	agent_ids.push_back(id);
-	names.push_back(av_name.getLegacyName());
+	names.push_back(av_name.getAccountName());
 
 	mImplementation->addUsers(names, agent_ids);
 }
diff --git a/indra/newview/llpanelgrouplandmoney.cpp b/indra/newview/llpanelgrouplandmoney.cpp
index 37755fb851a5b75e7b8154d898d072b260cd5e46..c927aeacb30d4b495e9110bc5501ce5595042ea4 100644
--- a/indra/newview/llpanelgrouplandmoney.cpp
+++ b/indra/newview/llpanelgrouplandmoney.cpp
@@ -1383,13 +1383,11 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
 	S32 cur_land_tax;
 	S32 cur_group_tax;
 	S32 cur_parcel_dir_fee;
-	S32 cur_total_tax;
 	S32 proj_object_tax;
 	S32 proj_light_tax;
 	S32 proj_land_tax;
 	S32 proj_group_tax;
 	S32 proj_parcel_dir_fee;
-	S32 proj_total_tax;
 	S32	non_exempt_members;
 
 	msg->getS32Fast(_PREHASH_MoneyData, _PREHASH_IntervalDays, interval_days );
@@ -1413,8 +1411,6 @@ void LLGroupMoneyPlanningTabEventHandler::processReply(LLMessageSystem* msg,
 	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_LastTaxDate, last_stipend_date);
 	msg->getStringFast(_PREHASH_MoneyData, _PREHASH_TaxDate, next_stipend_date);
 
-	cur_total_tax = cur_object_tax + cur_light_tax + cur_land_tax + cur_group_tax +  cur_parcel_dir_fee;
-	proj_total_tax = proj_object_tax + proj_light_tax + proj_land_tax + proj_group_tax + proj_parcel_dir_fee;
 
 	if (interval_days != mImplementationp->mIntervalLength || 
 		current_interval != mImplementationp->mCurrentInterval)
diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp
index 31c0e3d01a740015b8d343b86181321aca8d6336..522ba5afae403b2c17f3492adf4200ab0dbf7e09 100644
--- a/indra/newview/llpanelgroupnotices.cpp
+++ b/indra/newview/llpanelgroupnotices.cpp
@@ -35,6 +35,7 @@
 #include "llviewerinventory.h"
 #include "llinventorydefines.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llinventorymodel.h"
 #include "llfloaterinventory.h"
 #include "llagent.h"
@@ -543,10 +544,7 @@ void LLPanelGroupNotices::processNotices(LLMessageSystem* msg)
 		msg->getU32("Data","Timestamp",timestamp,i);
 
 		// we only have the legacy name here, convert it to a username
-		if (LLAvatarNameCache::useDisplayNames())
-		{
-			name = LLCacheName::buildUsername(name);
-		}
+		name = LLCacheName::buildUsername(name);
 
 		LLSD row;
 		row["id"] = id;
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index ff106882f46f1da5d78007f55a4b5cbf9c43ff88..cfdac11d26b6bfb0ccbf04c4fbd042121fa5643f 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -743,12 +743,17 @@ LLPanelGroupMembersSubTab::LLPanelGroupMembersSubTab()
 	mChanged(FALSE),
 	mPendingMemberUpdate(FALSE),
 	mHasMatch(FALSE),
-	mNumOwnerAdditions(0)
+	mNumOwnerAdditions(0),
+	mAvatarNameCacheConnection()
 {
 }
 
 LLPanelGroupMembersSubTab::~LLPanelGroupMembersSubTab()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 	if (mMembersList)
 	{
 		gSavedSettings.setString("GroupMembersSortOrder", mMembersList->getSortColumnName());
@@ -1604,6 +1609,8 @@ void LLPanelGroupMembersSubTab::addMemberToList(LLGroupMemberData* data)
 
 void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemberData* member, const LLAvatarName& av_name)
 {
+	mAvatarNameCacheConnection.disconnect();
+
 	LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(mGroupID);
 	if (!gdatap
 		|| gdatap->getMemberVersion() != update_id
@@ -1613,7 +1620,7 @@ void LLPanelGroupMembersSubTab::onNameCache(const LLUUID& update_id, LLGroupMemb
 	}
 	
 	// trying to avoid unnecessary hash lookups
-	if (matchesSearchFilter(av_name.getLegacyName()))
+	if (matchesSearchFilter(av_name.getAccountName()))
 	{
 		addMemberToList(member);
 		if(!mMembersList->getEnabled())
@@ -1667,7 +1674,7 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(mMemberProgress->first, &av_name))
 		{
-			if (matchesSearchFilter(av_name.getLegacyName()))
+			if (matchesSearchFilter(av_name.getAccountName()))
 			{
 				addMemberToList(mMemberProgress->second);
 			}
@@ -1675,8 +1682,12 @@ void LLPanelGroupMembersSubTab::updateMembers()
 		else
 		{
 			// If name is not cached, onNameCache() should be called when it is cached and add this member to list.
-			LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache,
-									this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
+			// *TODO : Add one callback per fetched avatar name
+			if (mAvatarNameCacheConnection.connected())
+			{
+				mAvatarNameCacheConnection.disconnect();
+			}
+			mAvatarNameCacheConnection = LLAvatarNameCache::get(mMemberProgress->first, boost::bind(&LLPanelGroupMembersSubTab::onNameCache, this, gdatap->getMemberVersion(), mMemberProgress->second, _2));
 		}
 	}
 
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index bead8bd85b4dd9d7b87c4f9545c8f349e0765db4..78bb3c57a16a282c73868897305820fb5341b0a5 100644
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -214,6 +214,7 @@ class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab
 	U32 mNumOwnerAdditions;
 
 	LLGroupMgrGroupData::member_list_t::iterator mMemberProgress;
+	boost::signals2::connection mAvatarNameCacheConnection;
 };
 
 class LLPanelGroupRolesSubTab : public LLPanelGroupSubTab
diff --git a/indra/newview/llpanelimcontrolpanel.cpp b/indra/newview/llpanelimcontrolpanel.cpp
index eda0749cdb56afb2f9214498b8ddde1e96f7780c..389baa86cd49a8c95b0cf70c78930c9e8708d583 100644
--- a/indra/newview/llpanelimcontrolpanel.cpp
+++ b/indra/newview/llpanelimcontrolpanel.cpp
@@ -1,31 +1,30 @@
-/** 
+/**
  * @file llpanelavatar.cpp
  * @brief LLPanelAvatar and related class implementations
  *
  * $LicenseInfo:firstyear=2004&license=viewerlgpl$
  * Second Life Viewer Source Code
  * Copyright (C) 2010, Linden Research, Inc.
- * 
+ *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation;
  * version 2.1 of the License only.
- * 
+ *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
+ *
  * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
  * $/LicenseInfo$
  */
 
 #include "llviewerprecompiledheaders.h"
-
 #include "llfloaterreg.h"
 
 #include "llpanelimcontrolpanel.h"
@@ -39,393 +38,7 @@
 #include "llavatarlist.h"
 #include "llparticipantlist.h"
 #include "llimview.h"
-#include "llvoicechannel.h"
 #include "llspeakers.h"
 #include "lltrans.h"
 
-void LLPanelChatControlPanel::onCallButtonClicked()
-{
-	gIMMgr->startCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onEndCallButtonClicked()
-{
-	gIMMgr->endCall(mSessionId);
-}
-
-void LLPanelChatControlPanel::onOpenVoiceControlsClicked()
-{
-	LLFloaterReg::showInstance("voice_controls");
-}
-
-void LLPanelChatControlPanel::onChange(EStatusType status, const std::string &channelURI, bool proximal)
-{
-	if(status == STATUS_JOINING || status == STATUS_LEFT_CHANNEL)
-	{
-		return;
-	}
-
-	updateCallButton();
-}
-
-void LLPanelChatControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	updateButtons(new_state);
-}
-
-void LLPanelChatControlPanel::updateCallButton()
-{
-	// hide/show call button
-	bool voice_enabled = LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
-
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(mSessionId);
-	
-	if (!session) 
-	{
-		getChildView("call_btn")->setEnabled(false);
-		return;
-	}
-
-	bool session_initialized = session->mSessionInitialized;
-	bool callback_enabled = session->mCallBackEnabled;
-
-	BOOL enable_connect = session_initialized
-		&& voice_enabled
-		&& callback_enabled;
-	getChildView("call_btn")->setEnabled(enable_connect);
-}
-
-void LLPanelChatControlPanel::updateButtons(LLVoiceChannel::EState state)
-{
-	bool is_call_started = state >= LLVoiceChannel::STATE_CALL_STARTED;
-	getChildView("end_call_btn_panel")->setVisible( is_call_started);
-	getChildView("voice_ctrls_btn_panel")->setVisible( is_call_started && findChild<LLView>("voice_ctrls_btn_panel"));
-	getChildView("call_btn_panel")->setVisible( ! is_call_started);
-	
-	getChildView("volume_ctrl_panel")->setVisible(state == LLVoiceChannel::STATE_CONNECTED);
-	
-	updateCallButton();
-	
-}
-
-LLPanelChatControlPanel::~LLPanelChatControlPanel()
-{
-	mVoiceChannelStateChangeConnection.disconnect();
-	if(LLVoiceClient::instanceExists())
-	{
-		LLVoiceClient::getInstance()->removeObserver(this);
-	}
-}
-
-BOOL LLPanelChatControlPanel::postBuild()
-{
-	childSetAction("call_btn", boost::bind(&LLPanelChatControlPanel::onCallButtonClicked, this));
-	childSetAction("end_call_btn", boost::bind(&LLPanelChatControlPanel::onEndCallButtonClicked, this));
-	childSetAction("voice_ctrls_btn", boost::bind(&LLPanelChatControlPanel::onOpenVoiceControlsClicked, this));
-
-	LLVoiceClient::getInstance()->addObserver(this);
-
-	return TRUE;
-}
-
-void LLPanelChatControlPanel::setSessionId(const LLUUID& session_id)
-{
-	//Method is called twice for AdHoc and Group chat. Second time when server init reply received
-	mSessionId = session_id;
-	LLVoiceChannel* voice_channel = LLIMModel::getInstance()->getVoiceChannel(mSessionId);
-	if(voice_channel)
-	{
-		mVoiceChannelStateChangeConnection = voice_channel->setStateChangedCallback(boost::bind(&LLPanelChatControlPanel::onVoiceChannelStateChanged, this, _1, _2));
-		
-		//call (either p2p, group or ad-hoc) can be already in started state
-		updateButtons(voice_channel->getState());
-	}
-}
-
-LLPanelIMControlPanel::LLPanelIMControlPanel()
-{
-}
-
-LLPanelIMControlPanel::~LLPanelIMControlPanel()
-{
-	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
-}
-
-BOOL LLPanelIMControlPanel::postBuild()
-{
-	childSetAction("view_profile_btn", boost::bind(&LLPanelIMControlPanel::onViewProfileButtonClicked, this));
-	childSetAction("add_friend_btn", boost::bind(&LLPanelIMControlPanel::onAddFriendButtonClicked, this));
-
-	childSetAction("share_btn", boost::bind(&LLPanelIMControlPanel::onShareButtonClicked, this));
-	childSetAction("teleport_btn", boost::bind(&LLPanelIMControlPanel::onTeleportButtonClicked, this));
-	childSetAction("pay_btn", boost::bind(&LLPanelIMControlPanel::onPayButtonClicked, this));
-
-	childSetAction("mute_btn", boost::bind(&LLPanelIMControlPanel::onClickMuteVolume, this));
-	childSetAction("block_btn", boost::bind(&LLPanelIMControlPanel::onClickBlock, this));
-	childSetAction("unblock_btn", boost::bind(&LLPanelIMControlPanel::onClickUnblock, this));
-	
-	getChild<LLUICtrl>("volume_slider")->setCommitCallback(boost::bind(&LLPanelIMControlPanel::onVolumeChange, this, _2));
-
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(getChild<LLAvatarIconCtrl>("avatar_icon")->getAvatarId()));
-
-	setFocusReceivedCallback(boost::bind(&LLPanelIMControlPanel::onFocusReceived, this));
-	
-	return LLPanelChatControlPanel::postBuild();
-}
-
-void LLPanelIMControlPanel::draw()
-{
-	bool is_muted = LLMuteList::getInstance()->isMuted(mAvatarID);
-
-	getChild<LLUICtrl>("block_btn_panel")->setVisible(!is_muted);
-	getChild<LLUICtrl>("unblock_btn_panel")->setVisible(is_muted);
-
-	if (getChildView("volume_ctrl_panel")->getVisible())
-	{
-
-		bool is_muted_voice = LLMuteList::getInstance()->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
-		LLUICtrl* mute_btn = getChild<LLUICtrl>("mute_btn");
-		mute_btn->setValue( is_muted_voice );
-
-		LLUICtrl* volume_slider = getChild<LLUICtrl>("volume_slider");
-		volume_slider->setEnabled( !is_muted_voice );
-
-		F32 volume;
-
-		if (is_muted_voice)
-		{
-			// it's clearer to display their volume as zero
-			volume = 0.f;
-		}
-		else
-		{
-			// actual volume
-			volume = LLVoiceClient::getInstance()->getUserVolume(mAvatarID);
-		}
-		volume_slider->setValue( (F64)volume );
-	}
-
-	LLPanelChatControlPanel::draw();
-}
-
-void LLPanelIMControlPanel::onClickMuteVolume()
-{
-	// By convention, we only display and toggle voice mutes, not all mutes
-	LLMuteList* mute_list = LLMuteList::getInstance();
-	bool is_muted = mute_list->isMuted(mAvatarID, LLMute::flagVoiceChat);
-
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-	if (!is_muted)
-	{
-		mute_list->add(mute, LLMute::flagVoiceChat);
-	}
-	else
-	{
-		mute_list->remove(mute, LLMute::flagVoiceChat);
-	}
-}
-
-void LLPanelIMControlPanel::onClickBlock()
-{
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-	
-	LLMuteList::getInstance()->add(mute);
-}
-
-void LLPanelIMControlPanel::onClickUnblock()
-{
-	LLMute mute(mAvatarID, getChild<LLTextBox>("avatar_name")->getText(), LLMute::AGENT);
-
-	LLMuteList::getInstance()->remove(mute);
-}
-
-void LLPanelIMControlPanel::onVolumeChange(const LLSD& data)
-{
-	F32 volume = (F32)data.asReal();
-	LLVoiceClient::getInstance()->setUserVolume(mAvatarID, volume);
-}
-
-void LLPanelIMControlPanel::onTeleportButtonClicked()
-{
-	LLAvatarActions::offerTeleport(mAvatarID);
-}
-void LLPanelIMControlPanel::onPayButtonClicked()
-{
-	LLAvatarActions::pay(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onViewProfileButtonClicked()
-{
-	LLAvatarActions::showProfile(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onAddFriendButtonClicked()
-{
-	LLAvatarIconCtrl* avatar_icon = getChild<LLAvatarIconCtrl>("avatar_icon");
-	std::string full_name = avatar_icon->getFullName();
-	LLAvatarActions::requestFriendshipDialog(mAvatarID, full_name);
-}
-
-void LLPanelIMControlPanel::onShareButtonClicked()
-{
-	LLAvatarActions::share(mAvatarID);
-}
-
-void LLPanelIMControlPanel::onFocusReceived()
-{
-	// Disable all the buttons (Call, Teleport, etc) if disconnected.
-	if (gDisconnected)
-	{
-		setAllChildrenEnabled(FALSE);
-	}
-}
-
-void LLPanelIMControlPanel::setSessionId(const LLUUID& session_id)
-{
-	LLPanelChatControlPanel::setSessionId(session_id);
-
-	LLIMModel& im_model = LLIMModel::instance();
-
-	LLAvatarTracker::instance().removeParticularFriendObserver(mAvatarID, this);
-	mAvatarID = im_model.getOtherParticipantID(session_id);
-	LLAvatarTracker::instance().addParticularFriendObserver(mAvatarID, this);
-
-	// Disable "Add friend" button for friends.
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-	
-	// Disable "Teleport" button if friend is offline
-	if(LLAvatarActions::isFriend(mAvatarID))
-	{
-		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
-	}
-
-	getChild<LLAvatarIconCtrl>("avatar_icon")->setValue(mAvatarID);
-
-	// Disable most profile buttons if the participant is
-	// not really an SL avatar (e.g., an Avaline caller).
-	LLIMModel::LLIMSession* im_session =
-		im_model.findIMSession(session_id);
-	if( im_session && !im_session->mOtherParticipantIsAvatar )
-	{
-		getChildView("view_profile_btn")->setEnabled(FALSE);
-		getChildView("add_friend_btn")->setEnabled(FALSE);
-
-		getChildView("share_btn")->setEnabled(FALSE);
-		getChildView("teleport_btn")->setEnabled(FALSE);
-		getChildView("pay_btn")->setEnabled(FALSE);
-
-        getChild<LLTextBox>("avatar_name")->setValue(im_session->mName);
-        getChild<LLTextBox>("avatar_name")->setToolTip(im_session->mName);
-	}
-	else
-	{
-		// If the participant is an avatar, fetch the currect name
-		gCacheName->get(mAvatarID, false,
-			boost::bind(&LLPanelIMControlPanel::onNameCache, this, _1, _2, _3));
-	}
-}
-
-//virtual
-void LLPanelIMControlPanel::changed(U32 mask)
-{
-	getChildView("add_friend_btn")->setEnabled(!LLAvatarActions::isFriend(mAvatarID));
-	
-	// Disable "Teleport" button if friend is offline
-	if(LLAvatarActions::isFriend(mAvatarID))
-	{
-		getChildView("teleport_btn")->setEnabled(LLAvatarTracker::instance().isBuddyOnline(mAvatarID));
-	}
-}
-
-void LLPanelIMControlPanel::onNameCache(const LLUUID& id, const std::string& full_name, bool is_group)
-{
-	if ( id == mAvatarID )
-	{
-		std::string avatar_name = full_name;
-		getChild<LLTextBox>("avatar_name")->setValue(avatar_name);
-		getChild<LLTextBox>("avatar_name")->setToolTip(avatar_name);
-
-		bool is_linden = LLStringUtil::endsWith(full_name, " Linden");
-		getChild<LLUICtrl>("mute_btn")->setEnabled( !is_linden);
-	}
-}
-
-LLPanelGroupControlPanel::LLPanelGroupControlPanel(const LLUUID& session_id):
-mParticipantList(NULL)
-{
-}
-
-BOOL LLPanelGroupControlPanel::postBuild()
-{
-	childSetAction("group_info_btn", boost::bind(&LLPanelGroupControlPanel::onGroupInfoButtonClicked, this));
-
-	return LLPanelChatControlPanel::postBuild();
-}
-
-LLPanelGroupControlPanel::~LLPanelGroupControlPanel()
-{
-	delete mParticipantList;
-	mParticipantList = NULL;
-}
-
-// virtual
-void LLPanelGroupControlPanel::draw()
-{
-	// Need to resort the participant list if it's in sort by recent speaker order.
-	if (mParticipantList)
-		mParticipantList->update();
-	LLPanelChatControlPanel::draw();
-}
-
-void LLPanelGroupControlPanel::onGroupInfoButtonClicked()
-{
-	LLGroupActions::show(mGroupID);
-}
-
-void LLPanelGroupControlPanel::onSortMenuItemClicked(const LLSD& userdata)
-{
-	// TODO: Check this code when when sort order menu will be added. (EM)
-	if (false && !mParticipantList)
-		return;
-
-	std::string chosen_item = userdata.asString();
-
-	if (chosen_item == "sort_name")
-	{
-		mParticipantList->setSortOrder(LLParticipantList::E_SORT_BY_NAME);
-	}
-
-}
-
-void LLPanelGroupControlPanel::onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state)
-{
-	LLPanelChatControlPanel::onVoiceChannelStateChanged(old_state, new_state);
-	mParticipantList->setSpeakingIndicatorsVisible(new_state >= LLVoiceChannel::STATE_CALL_STARTED);
-}
-
-void LLPanelGroupControlPanel::setSessionId(const LLUUID& session_id)
-{
-	LLPanelChatControlPanel::setSessionId(session_id);
-
-	mGroupID = session_id;
-
-	// for group and Ad-hoc chat we need to include agent into list 
-	if(!mParticipantList)
-	{
-		LLSpeakerMgr* speaker_manager = LLIMModel::getInstance()->getSpeakerManager(session_id);
-		mParticipantList = new LLParticipantList(speaker_manager, getChild<LLAvatarList>("speakers_list"), true,false);
-	}
-}
-
-
-LLPanelAdHocControlPanel::LLPanelAdHocControlPanel(const LLUUID& session_id):LLPanelGroupControlPanel(session_id)
-{
-}
-
-BOOL LLPanelAdHocControlPanel::postBuild()
-{
-	//We don't need LLPanelGroupControlPanel::postBuild() to be executed as there is no group_info_btn at AdHoc chat
-	return LLPanelChatControlPanel::postBuild();
-}
 
diff --git a/indra/newview/llpanelimcontrolpanel.h b/indra/newview/llpanelimcontrolpanel.h
index bba847b5d4e59616acb36e04284887a8dc928447..02915ec4bb84f7e3154d0cdf94bf9135bae3e84b 100644
--- a/indra/newview/llpanelimcontrolpanel.h
+++ b/indra/newview/llpanelimcontrolpanel.h
@@ -28,14 +28,12 @@
 #define LL_LLPANELIMCONTROLPANEL_H
 
 #include "llpanel.h"
-#include "llvoicechannel.h"
 #include "llcallingcard.h"
 
 class LLParticipantList;
 
-class LLPanelChatControlPanel 
+class LLPanelChatControlPanel
 	: public LLPanel
-	, public LLVoiceClientStatusObserver
 {
 public:
 	LLPanelChatControlPanel() :
@@ -44,21 +42,6 @@ class LLPanelChatControlPanel
 
 	virtual BOOL postBuild();
 
-	void onCallButtonClicked();
-	void onEndCallButtonClicked();
-	void onOpenVoiceControlsClicked();
-
-	// Implements LLVoiceClientStatusObserver::onChange() to enable the call
-	// button when voice is available
-	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
-
-	virtual void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
-
-	void updateButtons(LLVoiceChannel::EState state);
-	
-	// Enables/disables call button depending on voice availability
-	void updateCallButton();
-
 	virtual void setSessionId(const LLUUID& session_id);
 	const LLUUID& getSessionId() { return mSessionId; }
 
@@ -69,41 +52,6 @@ class LLPanelChatControlPanel
 	boost::signals2::connection mVoiceChannelStateChangeConnection;
 };
 
-
-class LLPanelIMControlPanel : public LLPanelChatControlPanel, LLFriendObserver
-{
-public:
-	LLPanelIMControlPanel();
-	~LLPanelIMControlPanel();
-
-	BOOL postBuild();
-
-	void setSessionId(const LLUUID& session_id);
-
-	// LLFriendObserver trigger
-	virtual void changed(U32 mask);
-
-protected:
-	void onNameCache(const LLUUID& id, const std::string& full_name, bool is_group);
-
-private:
-	void onViewProfileButtonClicked();
-	void onAddFriendButtonClicked();
-	void onShareButtonClicked();
-	void onTeleportButtonClicked();
-	void onPayButtonClicked();
-	void onFocusReceived();
-
-	void onClickMuteVolume();
-	void onClickBlock();
-	void onClickUnblock();
-	/*virtual*/ void draw();
-	void onVolumeChange(const LLSD& data);
-
-	LLUUID mAvatarID;
-};
-
-
 class LLPanelGroupControlPanel : public LLPanelChatControlPanel
 {
 public:
@@ -121,9 +69,7 @@ class LLPanelGroupControlPanel : public LLPanelChatControlPanel
 	LLParticipantList* mParticipantList;
 
 private:
-	void onGroupInfoButtonClicked();
 	void onSortMenuItemClicked(const LLSD& userdata);
-	/*virtual*/ void onVoiceChannelStateChanged(const LLVoiceChannel::EState& old_state, const LLVoiceChannel::EState& new_state);
 };
 
 class LLPanelAdHocControlPanel : public LLPanelGroupControlPanel
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index 04c1a86f69fd73fee2dfc166aba0e7ea25ab45b2..5321ebc7773d5d8d825885840d38f06f57ab3522 100644
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -166,7 +166,7 @@ void LLPanelLandInfo::refresh()
 		getChildView("button abandon land")->setEnabled(owner_release || manager_releaseable || gAgent.isGodlike());
 
 		// only mainland sims are subdividable by owner
-		if (regionp->getRegionFlags() && REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (regionp->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			getChildView("button subdivide land")->setEnabled(owner_divide || manager_divideable || gAgent.isGodlike());
 		}
diff --git a/indra/newview/llpanellandmarkinfo.cpp b/indra/newview/llpanellandmarkinfo.cpp
index c57746ec00abe8a5f31992612fc18c1b1c8256ca..5c9b968ac908e3c5b19b0c8af053df0d6b60e712 100644
--- a/indra/newview/llpanellandmarkinfo.cpp
+++ b/indra/newview/llpanellandmarkinfo.cpp
@@ -209,24 +209,6 @@ void LLPanelLandmarkInfo::processParcelInfo(const LLParcelData& parcel_data)
 		mMaturityRatingText->setText(LLViewerRegion::accessToString(SIM_ACCESS_PG));
 	}
 
-	S32 region_x;
-	S32 region_y;
-	S32 region_z;
-
-	// If the region position is zero, grab position from the global
-	if(mPosRegion.isExactlyZero())
-	{
-		region_x = llround(parcel_data.global_x) % REGION_WIDTH_UNITS;
-		region_y = llround(parcel_data.global_y) % REGION_WIDTH_UNITS;
-		region_z = llround(parcel_data.global_z);
-	}
-	else
-	{
-		region_x = llround(mPosRegion.mV[VX]);
-		region_y = llround(mPosRegion.mV[VY]);
-		region_z = llround(mPosRegion.mV[VZ]);
-	}
-
 	LLSD info;
 	info["update_verbs"] = true;
 	info["global_x"] = parcel_data.global_x;
diff --git a/indra/newview/llpanellandmarks.cpp b/indra/newview/llpanellandmarks.cpp
index d6fccb97053ca4cb1c643db4e036b073918c0d31..88400e4ef2f0e8ba1b68ad735c0b961847e7b80f 100644
--- a/indra/newview/llpanellandmarks.cpp
+++ b/indra/newview/llpanellandmarks.cpp
@@ -52,6 +52,7 @@
 #include "llmenubutton.h"
 #include "llplacesinventorybridge.h"
 #include "llplacesinventorypanel.h"
+#include "llplacesfolderview.h"
 #include "lltoggleablemenu.h"
 #include "llviewermenu.h"
 #include "llviewerregion.h"
@@ -102,7 +103,7 @@ void LLCheckFolderState::doFolder(LLFolderViewFolder* folder)
 	// Counting only folders that pass the filter.
 	// The listener check allow us to avoid counting the folder view
 	// object itself because it has no listener assigned.
-	if (folder->hasFilteredDescendants() && folder->getListener())
+	if (folder->getViewModelItem()->descendantsPassedFilter())
 	{
 		if (folder->isOpen())
 		{
@@ -138,7 +139,7 @@ class LLOpenFolderByID : public LLFolderViewFunctor
 // virtual
 void LLOpenFolderByID::doFolder(LLFolderViewFolder* folder)
 {
-	if (folder->getListener() && folder->getListener()->getUUID() == mFolderID)
+	if (folder->getViewModelItem() && static_cast<LLFolderViewModelItemInventory*>(folder->getViewModelItem())->getUUID() == mFolderID)
 	{
 		if (!folder->isOpen())
 		{
@@ -177,7 +178,7 @@ void LLLandmarksPanelObserver::changed(U32 mask)
 	if (!mIsLibraryLandmarksOpen && library)
 	{
 		// Search for "Landmarks" folder in the Library and open it once on start up. See EXT-4827.
-		const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+		const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
 		if (landmarks_cat.notNull())
 		{
 			LLOpenFolderByID opener(landmarks_cat);
@@ -247,10 +248,7 @@ void LLLandmarksPanel::onSearchEdit(const std::string& string)
 		LLPlacesInventoryPanel* inventory_list = dynamic_cast<LLPlacesInventoryPanel*>(tab->getAccordionView());
 		if (NULL == inventory_list) continue;
 
-		if (inventory_list->getFilter())
-		{
-			filter_list(inventory_list, string);
-		}
+		filter_list(inventory_list, string);
 	}
 
 	if (sFilterSubString != string)
@@ -281,28 +279,21 @@ void LLLandmarksPanel::onShowOnMap()
 //virtual
 void LLLandmarksPanel::onShowProfile()
 {
-	LLFolderViewItem* cur_item = getCurSelectedItem();
+	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 
 	if(!cur_item)
 		return;
 
-	cur_item->getListener()->performAction(mCurrentSelectedList->getModel(),"about");
+	cur_item->performAction(mCurrentSelectedList->getModel(),"about");
 }
 
 // virtual
 void LLLandmarksPanel::onTeleport()
 {
-	LLFolderViewItem* current_item = getCurSelectedItem();
-	if (!current_item)
-	{
-		llwarns << "There are no selected list. No actions are performed." << llendl;
-		return;
-	}
-
-	LLFolderViewEventListener* listenerp = current_item->getListener();
-	if (listenerp && listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	LLFolderViewModelItemInventory* view_model_item = getCurSelectedViewModelItem();
+	if (view_model_item && view_model_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
-		listenerp->openItem();
+		view_model_item->openItem();
 	}
 }
 
@@ -313,8 +304,7 @@ bool LLLandmarksPanel::isSingleItemSelected()
 
 	if (mCurrentSelectedList != NULL)
 	{
-		LLPlacesFolderView* root_view =
-				static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder());
+		LLFolderView* root_view = mCurrentSelectedList->getRootFolder();
 
 		if (root_view->getSelectedCount() == 1)
 		{
@@ -360,7 +350,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 	LLFolderViewItem* cur_item = mFavoritesInventoryPanel->getRootFolder()->getCurSelectedItem();
 	if (!cur_item) return;
 
-	LLFolderViewEventListener* listenerp = cur_item->getListener();
+	LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
 	if (listenerp->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		LLSD key;
@@ -373,10 +363,7 @@ void LLLandmarksPanel::onSelectorButtonClicked()
 
 void LLLandmarksPanel::updateShowFolderState()
 {
-	if (!mLandmarksInventoryPanel->getFilter())
-		return;
-
-	bool show_all_folders = mLandmarksInventoryPanel->getRootFolder()->getFilterSubString().empty();
+	bool show_all_folders =   mLandmarksInventoryPanel->getFilterSubString().empty();
 	if (show_all_folders)
 	{
 		show_all_folders = category_has_descendents(mLandmarksInventoryPanel);
@@ -417,14 +404,14 @@ void LLLandmarksPanel::setItemSelected(const LLUUID& obj_id, BOOL take_keyboard_
 
 bool LLLandmarksPanel::isLandmarkSelected() const 
 {
-	LLFolderViewItem* current_item = getCurSelectedItem();
-	return current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK;
+	LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+	return current_item && (current_item->getInventoryType() == LLInventoryType::IT_LANDMARK);
 }
 
 bool LLLandmarksPanel::isFolderSelected() const
 {
-	LLFolderViewItem* current_item = getCurSelectedItem();
-	return current_item && current_item->getListener()->getInventoryType() == LLInventoryType::IT_CATEGORY;
+	LLFolderViewModelItemInventory* current_item = getCurSelectedViewModelItem();
+	return current_item && (current_item->getInventoryType() == LLInventoryType::IT_CATEGORY);
 }
 
 bool LLLandmarksPanel::isReceivedFolderSelected() const
@@ -441,10 +428,10 @@ bool LLLandmarksPanel::isReceivedFolderSelected() const
 
 void LLLandmarksPanel::doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb)
 {
-	LLFolderViewItem* cur_item = getCurSelectedItem();
-	if(cur_item && cur_item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
+	if(cur_item && cur_item->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{ 
-		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getListener()->getUUID(), cb);
+		LLLandmark* landmark = LLLandmarkActions::getLandmark(cur_item->getUUID(), cb);
 		if (landmark)
 		{
 			cb(landmark);
@@ -457,6 +444,17 @@ LLFolderViewItem* LLLandmarksPanel::getCurSelectedItem() const
 	return mCurrentSelectedList ?  mCurrentSelectedList->getRootFolder()->getCurSelectedItem() : NULL;
 }
 
+LLFolderViewModelItemInventory* LLLandmarksPanel::getCurSelectedViewModelItem() const
+{
+	LLFolderViewItem* cur_item = getCurSelectedItem();
+	if (cur_item)
+	{
+		return 	static_cast<LLFolderViewModelItemInventory*>(cur_item->getViewModelItem());
+	}
+	return NULL;
+}
+
+
 LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPanel* inventory_list,
 															 const std::string& tab_name,
 															 const LLUUID& obj_id,
@@ -467,7 +465,7 @@ LLFolderViewItem* LLLandmarksPanel::selectItemInAccordionTab(LLPlacesInventoryPa
 
 	LLFolderView* root = inventory_list->getRootFolder();
 
-	LLFolderViewItem* item = root->getItemByID(obj_id);
+	LLFolderViewItem* item = inventory_list->getItemByID(obj_id);
 	if (!item)
 		return NULL;
 
@@ -509,12 +507,12 @@ void LLLandmarksPanel::processParcelInfo(const LLParcelData& parcel_data)
 	// We have to make request to sever to get parcel_id and snaption_id. 
 	if(isLandmarkSelected())
 	{
-		LLFolderViewItem* cur_item = getCurSelectedItem();
+		LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 		if (!cur_item) return;
-		LLUUID id = cur_item->getListener()->getUUID();
+		LLUUID id = cur_item->getUUID();
 		LLInventoryItem* inv_item = mCurrentSelectedList->getModel()->getItem(id);
 		doActionOnCurSelectedLandmark(boost::bind(
-				&LLLandmarksPanel::doProcessParcelInfo, this, _1, cur_item, inv_item, parcel_data));
+				&LLLandmarksPanel::doProcessParcelInfo, this, _1, getCurSelectedItem(), inv_item, parcel_data));
 	}
 }
 
@@ -544,7 +542,7 @@ void LLLandmarksPanel::initFavoritesInventoryPanel()
 	mFavoritesInventoryPanel = getChild<LLPlacesInventoryPanel>("favorites_list");
 
 	initLandmarksPanel(mFavoritesInventoryPanel);
-	mFavoritesInventoryPanel->getFilter()->setEmptyLookupMessage("FavoritesNoMatchingItems");
+	mFavoritesInventoryPanel->getFilter().setEmptyLookupMessage("FavoritesNoMatchingItems");
 
 	initAccordion("tab_favorites", mFavoritesInventoryPanel, true);
 }
@@ -555,12 +553,7 @@ void LLLandmarksPanel::initLandmarksInventoryPanel()
 
 	initLandmarksPanel(mLandmarksInventoryPanel);
 
-	// Check if mLandmarksInventoryPanel is properly initialized and has a Filter created.
-	// In case of a dummy widget getFilter() will return NULL.
-	if (mLandmarksInventoryPanel->getFilter())
-	{
-		mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
-	}
+	mLandmarksInventoryPanel->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
 
 	// subscribe to have auto-rename functionality while creating New Folder
 	mLandmarksInventoryPanel->setSelectCallback(boost::bind(&LLInventoryPanel::onSelectionChange, mLandmarksInventoryPanel, _1, _2));
@@ -584,7 +577,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
 	initLandmarksPanel(mLibraryInventoryPanel);
 
 	// We want to fetch only "Landmarks" category from the library.
-	const LLUUID &landmarks_cat = gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK, false, true);
+	const LLUUID &landmarks_cat = gInventory.findLibraryCategoryUUIDForType(LLFolderType::FT_LANDMARK, false);
 	if (landmarks_cat.notNull())
 	{
 		LLInventoryModelBackgroundFetch::instance().start(landmarks_cat);
@@ -596,12 +589,7 @@ void LLLandmarksPanel::initLibraryInventoryPanel()
 
 void LLLandmarksPanel::initLandmarksPanel(LLPlacesInventoryPanel* inventory_list)
 {
-	// In case of a dummy widget further we have no Folder View widget and no Filter,
-	// so further initialization leads to crash.
-	if (!inventory_list->getFilter())
-		return;
-
-	inventory_list->getFilter()->setEmptyLookupMessage("PlacesNoMatchingItems");
+	inventory_list->getFilter().setEmptyLookupMessage("PlacesNoMatchingItems");
 	inventory_list->setFilterTypes(0x1 << LLInventoryType::IT_LANDMARK);
 	inventory_list->setSelectCallback(boost::bind(&LLLandmarksPanel::onSelectionChange, this, inventory_list, _1, _2));
 
@@ -666,20 +654,20 @@ void LLLandmarksPanel::deselectOtherThan(const LLPlacesInventoryPanel* inventory
 {
 	if (inventory_list != mFavoritesInventoryPanel)
 	{
-		mFavoritesInventoryPanel->getRootFolder()->clearSelection();
+		mFavoritesInventoryPanel->clearSelection();
 	}
 
 	if (inventory_list != mLandmarksInventoryPanel)
 	{
-		mLandmarksInventoryPanel->getRootFolder()->clearSelection();
+		mLandmarksInventoryPanel->clearSelection();
 	}
 	if (inventory_list != mMyInventoryPanel)
 	{
-		mMyInventoryPanel->getRootFolder()->clearSelection();
+		mMyInventoryPanel->clearSelection();
 	}
 	if (inventory_list != mLibraryInventoryPanel)
 	{
-		mLibraryInventoryPanel->getRootFolder()->clearSelection();
+		mLibraryInventoryPanel->clearSelection();
 	}
 }
 
@@ -732,14 +720,9 @@ void LLLandmarksPanel::onActionsButtonClick()
 {
 	LLToggleableMenu* menu = mGearFolderMenu;
 
-	LLFolderViewItem* cur_item = NULL;
 	if(mCurrentSelectedList)
 	{
-		cur_item = mCurrentSelectedList->getRootFolder()->getCurSelectedItem();
-		if(!cur_item)
-			return;
-
-		LLFolderViewEventListener* listenerp = cur_item->getListener();
+		LLFolderViewModelItemInventory* listenerp = getCurSelectedViewModelItem();
 		if(!listenerp)
 			return;
 
@@ -777,6 +760,9 @@ void LLLandmarksPanel::onTrashButtonClick() const
 
 void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 {
+	LLFolderViewModelItemInventory* view_model = getCurSelectedViewModelItem();
+	LLFolderViewItem* item = getCurSelectedItem();
+
 	std::string command_name = userdata.asString();
 	if("add_landmark" == command_name)
 	{
@@ -792,24 +778,24 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 	} 
 	else if ("category" == command_name)
 	{
-		LLFolderViewItem* item = getCurSelectedItem();
 		if (item && mCurrentSelectedList == mLandmarksInventoryPanel)
 		{
-			LLFolderViewEventListener* folder_bridge = NULL;
-			if (item-> getListener()->getInventoryType()
+			LLFolderViewModelItem* folder_bridge = NULL;
+
+			if (view_model->getInventoryType()
 					== LLInventoryType::IT_LANDMARK)
 			{
 				// for a landmark get parent folder bridge
-				folder_bridge = item->getParentFolder()->getListener();
+				folder_bridge = item->getParentFolder()->getViewModelItem();
 			}
-			else if (item-> getListener()->getInventoryType()
+			else if (view_model->getInventoryType()
 					== LLInventoryType::IT_CATEGORY)
 			{
 				// for a folder get its own bridge
-				folder_bridge = item->getListener();
+				folder_bridge = view_model;
 			}
 
-			menu_create_inventory_item(mCurrentSelectedList->getRootFolder(),
+			menu_create_inventory_item(mCurrentSelectedList,
 					dynamic_cast<LLFolderBridge*> (folder_bridge), LLSD(
 							"category"), gInventory.findCategoryUUIDForType(
 							LLFolderType::FT_LANDMARK));
@@ -817,7 +803,7 @@ void LLLandmarksPanel::onAddAction(const LLSD& userdata) const
 		else
 		{
 			//in case My Landmarks tab is completely empty (thus cannot be determined as being selected)
-			menu_create_inventory_item(mLandmarksInventoryPanel->getRootFolder(), NULL, LLSD("category"), 
+			menu_create_inventory_item(mLandmarksInventoryPanel, NULL,  LLSD("category"), 
 				gInventory.findCategoryUUIDForType(LLFolderType::FT_LANDMARK));
 
 			if (mMyLandmarksAccordionTab)
@@ -835,9 +821,9 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
 	std::string command_name = userdata.asString();
     if("copy_slurl" == command_name)
 	{
-    	LLFolderViewItem* cur_item = getCurSelectedItem();
+    	LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 		if(cur_item)
-			LLLandmarkActions::copySLURLtoClipboard(cur_item->getListener()->getUUID());
+			LLLandmarkActions::copySLURLtoClipboard(cur_item->getUUID());
 	}
 	else if ( "paste" == command_name)
 	{
@@ -849,7 +835,7 @@ void LLLandmarksPanel::onClipboardAction(const LLSD& userdata) const
 	}
 	else
 	{
-		mCurrentSelectedList->getRootFolder()->doToSelected(mCurrentSelectedList->getModel(),command_name);
+		mCurrentSelectedList->doToSelected(command_name);
 	}
 }
 
@@ -894,7 +880,7 @@ void LLLandmarksPanel::onFoldingAction(const LLSD& userdata)
 	{
 		if(mCurrentSelectedList)
 		{
-			mCurrentSelectedList->getRootFolder()->doToSelected(&gInventory, userdata);
+			mCurrentSelectedList->doToSelected(userdata);
 		}
 	}
 }
@@ -916,8 +902,9 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 {
 	std::string command_name = userdata.asString();
 
-	LLPlacesFolderView* root_folder_view = mCurrentSelectedList ?
-		static_cast<LLPlacesFolderView*>(mCurrentSelectedList->getRootFolder()) : NULL;
+	LLFolderView* root_folder_view = mCurrentSelectedList 
+		? mCurrentSelectedList->getRootFolder() 
+		: NULL;
 
 	if ("collapse_all" == command_name)
 	{
@@ -978,18 +965,13 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 	{
 		if (!root_folder_view) return false;
 
-		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+		std::set<LLFolderViewItem*> selected_uuids =    root_folder_view->getSelectionList();
 
 		// Allow to execute the command only if it can be applied to all selected items.
-		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
 		{
-			LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+			LLFolderViewItem* item = *iter;
 
-			// If no item is found it might be a folder id.
-			if (!item)
-			{
-				item = root_folder_view->getFolderByID(*iter);
-			}
 			if (!item) return false;
 
 			if (!canItemBeModified(command_name, item)) return false;
@@ -1013,10 +995,10 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 
 		if ("show_on_map" == command_name)
 		{
-			LLFolderViewItem* cur_item = root_folder_view->getCurSelectedItem();
+			LLFolderViewModelItemInventory* cur_item = getCurSelectedViewModelItem();
 			if (!cur_item) return false;
 
-			LLViewerInventoryItem* inv_item = cur_item->getInventoryItem();
+			LLViewerInventoryItem* inv_item = dynamic_cast<LLViewerInventoryItem*>(cur_item->getInventoryObject());
 			if (!inv_item) return false;
 
 			LLUUID asset_uuid = inv_item->getAssetUUID();
@@ -1050,7 +1032,7 @@ bool LLLandmarksPanel::isActionEnabled(const LLSD& userdata) const
 	{
 		if (mCurrentSelectedList)
 		{
-			std::set<LLUUID> selection = mCurrentSelectedList->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selection =    mCurrentSelectedList->getRootFolder()->getSelectionList();
 			if (!selection.empty())
 			{
 				return ( 1 == selection.size() && !LLAgentPicksInfo::getInstance()->isPickLimitReached() );
@@ -1106,27 +1088,23 @@ void LLLandmarksPanel::onMenuVisibilityChange(LLUICtrl* ctrl, const LLSD& param)
 	{
 		const LLUUID trash_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_TRASH);
 
-		std::set<LLUUID> selected_uuids = root_folder_view->getSelectionList();
+		std::set<LLFolderViewItem*> selected_items =    root_folder_view->getSelectionList();
 
 		// Iterate through selected items to find out if any of these items are in Trash
 		// or all the items are in Trash category.
-		for (std::set<LLUUID>::const_iterator iter = selected_uuids.begin(); iter != selected_uuids.end(); ++iter)
+		for (std::set<LLFolderViewItem*>::const_iterator iter =    selected_items.begin(); iter != selected_items.end(); ++iter)
 		{
-			LLFolderViewItem* item = root_folder_view->getItemByID(*iter);
+			LLFolderViewItem* item = *iter;
 
 			// If no item is found it might be a folder id.
-			if (!item)
-			{
-				item = root_folder_view->getFolderByID(*iter);
-			}
 			if (!item) continue;
 
-			LLFolderViewEventListener* listenerp = item->getListener();
+			LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
 			if(!listenerp) continue;
 
 			// Trash category itself should not be included because it can't be
 			// actually restored from trash.
-			are_all_items_in_trash &= listenerp->isItemInTrash() && *iter != trash_id;
+			are_all_items_in_trash &= listenerp->isItemInTrash() &&    listenerp->getUUID() != trash_id;
 
 			// If there are any selected items in Trash including the Trash category itself
 			// we show "Restore Item" in context menu and hide other irrelevant items.
@@ -1165,7 +1143,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 	bool can_be_modified = false;
 
 	// landmarks can be modified in any other accordion...
-	if (item->getListener()->getInventoryType() == LLInventoryType::IT_LANDMARK)
+	if (static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem())->getInventoryType() == LLInventoryType::IT_LANDMARK)
 	{
 		can_be_modified = true;
 
@@ -1203,7 +1181,7 @@ bool LLLandmarksPanel::canItemBeModified(const std::string& command_name, LLFold
 
 	if (can_be_modified)
 	{
-		LLFolderViewEventListener* listenerp = item->getListener();
+		LLFolderViewModelItemInventory* listenerp = static_cast<LLFolderViewModelItemInventory*>(item->getViewModelItem());
 
 		if ("cut" == command_name)
 		{
@@ -1263,8 +1241,9 @@ bool LLLandmarksPanel::handleDragAndDropToTrash(BOOL drop, EDragAndDropType carg
 				LLInventoryItem* item = static_cast<LLInventoryItem*>(cargo_data);
 				if (item)
 				{
-					LLFolderViewItem* fv_item = (mCurrentSelectedList && mCurrentSelectedList->getRootFolder()) ?
-						mCurrentSelectedList->getRootFolder()->getItemByID(item->getUUID()) : NULL;
+					LLFolderViewItem* fv_item = mCurrentSelectedList
+						? mCurrentSelectedList->getItemByID(item->getUUID())
+						: NULL;
 
 					if (fv_item)
 					{
@@ -1392,7 +1371,7 @@ void LLLandmarksPanel::doCreatePick(LLLandmark* landmark)
 static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::string& string)
 {
 	// When search is cleared, restore the old folder state.
-	if (!inventory_list->getRootFolder()->getFilterSubString().empty() && string == "")
+	if (!inventory_list->getFilterSubString().empty() && string == "")
 	{
 		inventory_list->setFilterSubString(LLStringUtil::null);
 		// Re-open folders that were open before
@@ -1406,7 +1385,7 @@ static void filter_list(LLPlacesInventoryPanel* inventory_list, const std::strin
 	}
 
 	// save current folder open state if no filter currently applied
-	if (inventory_list->getRootFolder()->getFilterSubString().empty())
+	if (inventory_list->getFilterSubString().empty())
 	{
 		inventory_list->saveFolderState();
 	}
diff --git a/indra/newview/llpanellandmarks.h b/indra/newview/llpanellandmarks.h
index 4e787317baff74f987a7daaaa22dae61d80c04d9..8fae0f0b67f7db6862ccdfda46b2f3274d951235 100644
--- a/indra/newview/llpanellandmarks.h
+++ b/indra/newview/llpanellandmarks.h
@@ -44,6 +44,7 @@ class LLMenuGL;
 class LLToggleableMenu;
 class LLInventoryPanel;
 class LLPlacesInventoryPanel;
+class LLFolderViewModelItemInventory;
 
 class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 {
@@ -88,6 +89,7 @@ class LLLandmarksPanel : public LLPanelPlacesTab, LLRemoteParcelInfoObserver
 	bool isReceivedFolderSelected() const;
 	void doActionOnCurSelectedLandmark(LLLandmarkList::loaded_callback_t cb);
 	LLFolderViewItem* getCurSelectedItem() const;
+	LLFolderViewModelItemInventory* getCurSelectedViewModelItem() const;
 
 	/**
 	 * Selects item with "obj_id" in "inventory_list" and scrolls accordion
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index fabb8daa6eb4f731340410ea475131f4aada895b..d6535c88e927f830850dcbad957a03e16abdd595 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -47,12 +47,14 @@
 #include "llresmgr.h"
 #include "llscrollcontainer.h"
 #include "llsdserialize.h"
+#include "llsdparam.h"
 #include "llspinctrl.h"
 #include "lltoggleablemenu.h"
 #include "lltooldraganddrop.h"
 #include "llviewermenu.h"
 #include "llviewertexturelist.h"
 #include "llsidepanelinventory.h"
+#include "llfolderview.h"
 
 const std::string FILTERS_FILENAME("filters.xml");
 
@@ -115,7 +117,7 @@ LLPanelMainInventory::LLPanelMainInventory(const LLPanel::Params& p)
 	mCommitCallbackRegistrar.add("Inventory.ShowFilters", boost::bind(&LLPanelMainInventory::toggleFindOptions, this));
 	mCommitCallbackRegistrar.add("Inventory.ResetFilters", boost::bind(&LLPanelMainInventory::resetFilters, this));
 	mCommitCallbackRegistrar.add("Inventory.SetSortBy", boost::bind(&LLPanelMainInventory::setSortBy, this, _2));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 
 	mSavedFolderState = new LLSaveFolderState();
 	mSavedFolderState->setApply(FALSE);
@@ -128,7 +130,7 @@ BOOL LLPanelMainInventory::postBuild()
 	mFilterTabs = getChild<LLTabContainer>("inventory filter tabs");
 	mFilterTabs->setCommitCallback(boost::bind(&LLPanelMainInventory::onFilterSelected, this));
 	
-	//panel->getFilter()->markDefault();
+	//panel->getFilter().markDefault();
 
 	// Set up the default inv. panel/filter settings.
 	mActivePanel = getChild<LLInventoryPanel>("All Items");
@@ -136,7 +138,7 @@ BOOL LLPanelMainInventory::postBuild()
 	{
 		// "All Items" is the previous only view, so it gets the InventorySortOrder
 		mActivePanel->setSortOrder(gSavedSettings.getU32(LLInventoryPanel::DEFAULT_SORT_ORDER));
-		mActivePanel->getFilter()->markDefault();
+		mActivePanel->getFilter().markDefault();
 		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
 		mActivePanel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, mActivePanel, _1, _2));
 		mResortActivePanel = true;
@@ -147,7 +149,7 @@ BOOL LLPanelMainInventory::postBuild()
 		recent_items_panel->setSinceLogoff(TRUE);
 		recent_items_panel->setSortOrder(LLInventoryFilter::SO_DATE);
 		recent_items_panel->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		recent_items_panel->getFilter()->markDefault();
+		recent_items_panel->getFilter().markDefault();
 		recent_items_panel->setSelectCallback(boost::bind(&LLPanelMainInventory::onSelectionChange, this, recent_items_panel, _1, _2));
 	}
 
@@ -166,11 +168,14 @@ BOOL LLPanelMainInventory::postBuild()
 		// Note that the "All Items" settings do not persist.
 		if(recent_items_panel)
 		{
-			if(savedFilterState.has(recent_items_panel->getFilter()->getName()))
+			if(savedFilterState.has(recent_items_panel->getFilter().getName()))
 			{
 				LLSD recent_items = savedFilterState.get(
-					recent_items_panel->getFilter()->getName());
-				recent_items_panel->getFilter()->fromLLSD(recent_items);
+					recent_items_panel->getFilter().getName());
+				LLInventoryFilter::Params p;
+				LLParamSDParser parser;
+				parser.readSD(recent_items, p);
+				recent_items_panel->getFilter().fromParams(p);
 			}
 		}
 
@@ -207,24 +212,28 @@ LLPanelMainInventory::~LLPanelMainInventory( void )
 	LLInventoryPanel* all_items_panel = getChild<LLInventoryPanel>("All Items");
 	if (all_items_panel)
 	{
-		LLInventoryFilter* filter = all_items_panel->getFilter();
-		if (filter)
+		LLSD filterState;
+		LLInventoryPanel::InventoryState p;
+		all_items_panel->getFilter().toParams(p.filter);
+		all_items_panel->getRootViewModel().getSorter().toParams(p.sort);
+		if (p.validateBlock(false))
 		{
-			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
+			LLParamSDParser().writeSD(filterState, p);
+			filterRoot[all_items_panel->getName()] = filterState;
 		}
 	}
 
-	LLInventoryPanel* recent_items_panel = getChild<LLInventoryPanel>("Recent Items");
-	if (recent_items_panel)
+	LLInventoryPanel* panel = findChild<LLInventoryPanel>("Recent Items");
+	if (panel)
 	{
-		LLInventoryFilter* filter = recent_items_panel->getFilter();
-		if (filter)
+		LLSD filterState;
+		LLInventoryPanel::InventoryState p;
+		panel->getFilter().toParams(p.filter);
+		panel->getRootViewModel().getSorter().toParams(p.sort);
+		if (p.validateBlock(false))
 		{
-			LLSD filterState;
-			filter->toLLSD(filterState);
-			filterRoot[filter->getName()] = filterState;
+			LLParamSDParser().writeSD(filterState, p);
+			filterRoot[panel->getName()] = filterState;
 		}
 	}
 
@@ -284,7 +293,7 @@ BOOL LLPanelMainInventory::handleKeyHere(KEY key, MASK mask)
 
 void LLPanelMainInventory::doToSelected(const LLSD& userdata)
 {
-	getPanel()->getRootFolder()->doToSelected(&gInventory, userdata);
+	getPanel()->doToSelected(userdata);
 }
 
 void LLPanelMainInventory::closeAllFolders()
@@ -306,13 +315,13 @@ void LLPanelMainInventory::newWindow()
 void LLPanelMainInventory::doCreate(const LLSD& userdata)
 {
 	reset_inventory_filter();
-	menu_create_inventory_item(getPanel()->getRootFolder(), NULL, userdata);
+	menu_create_inventory_item(getPanel(), NULL, userdata);
 }
 
 void LLPanelMainInventory::resetFilters()
 {
 	LLFloaterInventoryFinder *finder = getFinder();
-	getActivePanel()->getFilter()->resetDefault();
+	getActivePanel()->getFilter().resetDefault();
 	if (finder)
 	{
 		finder->updateElementsFromFilter();
@@ -417,7 +426,7 @@ void LLPanelMainInventory::onFilterEdit(const std::string& search_string )
 	}
 
 	// save current folder open state if no filter currently applied
-	if (!mActivePanel->getRootFolder()->isFilterModified())
+	if (!mActivePanel->getFilter().isNotDefault())
 	{
 		mSavedFolderState->setApply(FALSE);
 		mActivePanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -479,13 +488,13 @@ void LLPanelMainInventory::onFilterSelected()
 	}
 
 	setFilterSubString(mFilterSubString);
-	LLInventoryFilter* filter = mActivePanel->getFilter();
+	LLInventoryFilter& filter = mActivePanel->getFilter();
 	LLFloaterInventoryFinder *finder = getFinder();
 	if (finder)
 	{
-		finder->changeFilter(filter);
+		finder->changeFilter(&filter);
 	}
-	if (filter->isActive())
+	if (filter.isActive())
 	{
 		// If our filter is active we may be the first thing requiring a fetch so we better start it here.
 		LLInventoryModelBackgroundFetch::instance().start();
@@ -598,7 +607,7 @@ void LLPanelMainInventory::onFocusReceived()
 
 void LLPanelMainInventory::setFilterTextFromFilter() 
 { 
-	mFilterText = mActivePanel->getFilter()->getFilterText(); 
+	mFilterText = mActivePanel->getFilter().getFilterText(); 
 }
 
 void LLPanelMainInventory::toggleFindOptions()
@@ -647,7 +656,7 @@ LLFloaterInventoryFinder* LLPanelMainInventory::getFinder()
 LLFloaterInventoryFinder::LLFloaterInventoryFinder(LLPanelMainInventory* inventory_view) :	
 	LLFloater(LLSD()),
 	mPanelMainInventory(inventory_view),
-	mFilter(inventory_view->getPanel()->getFilter())
+	mFilter(&inventory_view->getPanel()->getFilter())
 {
 	buildFromFile("floater_inventory_view_finder.xml");
 	updateElementsFromFilter();
@@ -959,7 +968,7 @@ void LLPanelMainInventory::onTrashButtonClick()
 void LLPanelMainInventory::onClipboardAction(const LLSD& userdata)
 {
 	std::string command_name = userdata.asString();
-	getActivePanel()->getRootFolder()->doToSelected(getActivePanel()->getModel(),command_name);
+	getActivePanel()->doToSelected(command_name);
 }
 
 void LLPanelMainInventory::saveTexture(const LLSD& userdata)
@@ -970,7 +979,7 @@ void LLPanelMainInventory::saveTexture(const LLSD& userdata)
 		return;
 	}
 	
-	const LLUUID& item_id = current_item->getListener()->getUUID();
+	const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 	LLPreviewTexture* preview_texture = LLFloaterReg::showTypedInstance<LLPreviewTexture>("preview_texture", LLSD(item_id), TAKE_FOCUS_YES);
 	if (preview_texture)
 	{
@@ -1043,7 +1052,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID item_id = current_item->getListener()->getUUID();
+		const LLUUID item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item)
 		{
@@ -1058,7 +1067,7 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		current_item->getListener()->performAction(getActivePanel()->getModel(), "goto");
+		static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(getActivePanel()->getModel(), "goto");
 	}
 
 	if (command_name == "find_links")
@@ -1068,17 +1077,17 @@ void LLPanelMainInventory::onCustomAction(const LLSD& userdata)
 		{
 			return;
 		}
-		const LLUUID& item_id = current_item->getListener()->getUUID();
-		const std::string &item_name = current_item->getListener()->getName();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
+		const std::string &item_name = current_item->getViewModelItem()->getName();
 		mFilterSubString = item_name;
-		LLInventoryFilter *filter = mActivePanel->getFilter();
-		filter->setFilterSubString(item_name);
+		LLInventoryFilter &filter = mActivePanel->getFilter();
+		filter.setFilterSubString(item_name);
 		mFilterEditor->setText(item_name);
 
 		mFilterEditor->setFocus(TRUE);
-		filter->setFilterUUID(item_id);
-		filter->setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
-		filter->setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
+		filter.setFilterUUID(item_id);
+		filter.setShowFolderState(LLInventoryFilter::SHOW_NON_EMPTY_FOLDERS);
+		filter.setFilterLinks(LLInventoryFilter::FILTERLINK_ONLY_LINKS);
 	}
 }
 
@@ -1087,11 +1096,11 @@ bool LLPanelMainInventory::isSaveTextureEnabled(const LLSD& userdata)
 	LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 	if (current_item) 
 	{
-		LLViewerInventoryItem *inv_item = current_item->getInventoryItem();
+		LLViewerInventoryItem *inv_item = dynamic_cast<LLViewerInventoryItem*>(static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryObject());
 		if(inv_item)
 		{
 			bool can_save = inv_item->checkPermissionsSet(PERM_ITEM_UNRESTRICTED);
-			LLInventoryType::EType curr_type = current_item->getListener()->getInventoryType();
+			LLInventoryType::EType curr_type = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getInventoryType();
 			return can_save && (curr_type == LLInventoryType::IT_TEXTURE || curr_type == LLInventoryType::IT_SNAPSHOT);
 		}
 	}
@@ -1103,28 +1112,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	const std::string command_name = userdata.asString();
 	if (command_name == "delete")
 	{
-		BOOL can_delete = FALSE;
-		LLFolderView* root = getActivePanel()->getRootFolder();
-		if (root)
-		{
-			can_delete = TRUE;
-			std::set<LLUUID> selection_set = root->getSelectionList();
-			if (selection_set.empty()) return FALSE;
-			for (std::set<LLUUID>::iterator iter = selection_set.begin();
-				 iter != selection_set.end();
-				 ++iter)
-			{
-				const LLUUID &item_id = (*iter);
-				LLFolderViewItem *item = root->getItemByID(item_id);
-				const LLFolderViewEventListener *listener = item->getListener();
-				llassert(listener);
-				if (!listener) return FALSE;
-				can_delete &= listener->isItemRemovable();
-				can_delete &= !listener->isItemInTrash();
-			}
-			return can_delete;
-		}
-		return FALSE;
+		return getActivePanel()->isSelectionRemovable();
 	}
 	if (command_name == "save_texture")
 	{
@@ -1134,7 +1122,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsLinkType() && !item->getIsBrokenLink())
 		{
@@ -1146,11 +1134,11 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	if (command_name == "find_links")
 	{
 		LLFolderView* root = getActivePanel()->getRootFolder();
-		std::set<LLUUID> selection_set = root->getSelectionList();
+		std::set<LLFolderViewItem*> selection_set = root->getSelectionList();
 		if (selection_set.size() != 1) return FALSE;
 		LLFolderViewItem* current_item = root->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLInventoryObject *obj = gInventory.getObject(item_id);
 		if (obj && !obj->getIsLinkType() && LLAssetType::lookupCanLink(obj->getType()))
 		{
@@ -1163,7 +1151,7 @@ BOOL LLPanelMainInventory::isActionEnabled(const LLSD& userdata)
 	{
 		LLFolderViewItem* current_item = getActivePanel()->getRootFolder()->getCurSelectedItem();
 		if (!current_item) return FALSE;
-		const LLUUID& item_id = current_item->getListener()->getUUID();
+		const LLUUID& item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 		const LLViewerInventoryItem *item = gInventory.getItem(item_id);
 		if (item && item->getIsBrokenLink())
 		{
diff --git a/indra/newview/llpanelmarketplaceinbox.cpp b/indra/newview/llpanelmarketplaceinbox.cpp
index 5d7537584776332d46e5f038522373d858158fb2..dcecce6fe427725e64c552514f07050a0185fd96 100644
--- a/indra/newview/llpanelmarketplaceinbox.cpp
+++ b/indra/newview/llpanelmarketplaceinbox.cpp
@@ -94,14 +94,14 @@ LLInventoryPanel * LLPanelMarketplaceInbox::setupInventoryPanel()
 	mInventoryPanel->setShape(inventory_placeholder_rect);
 	
 	// Set the sort order newest to oldest
-	mInventoryPanel->setSortOrder(LLInventoryFilter::SO_DATE);	
-	mInventoryPanel->getFilter()->markDefault();
+	mInventoryPanel->getFolderViewModel()->setSorter(LLInventoryFilter::SO_DATE);
+	mInventoryPanel->getFilter().markDefault();
 
 	// Set selection callback for proper update of inventory status buttons
 	mInventoryPanel->setSelectCallback(boost::bind(&LLPanelMarketplaceInbox::onSelectionChange, this));
 
 	// Set up the note to display when the inbox is empty
-	mInventoryPanel->getFilter()->setEmptyLookupMessage("InventoryInboxNoItems");
+	mInventoryPanel->getFilter().setEmptyLookupMessage("InventoryInboxNoItems");
 	
 	// Hide the placeholder text
 	inbox_inventory_placeholder->setVisible(FALSE);
@@ -128,7 +128,6 @@ BOOL LLPanelMarketplaceInbox::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL dr
 
 U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	
 	//
 	// NOTE: When turning this on, be sure to test the no inbox/outbox case because this code probably
@@ -139,7 +138,7 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 
 	if (mInventoryPanel)
 	{
-		const LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
+		LLFolderViewFolder * inbox_folder = mInventoryPanel->getRootFolder();
 		
 		if (inbox_folder)
 		{
@@ -174,9 +173,6 @@ U32 LLPanelMarketplaceInbox::getFreshItemCount() const
 	}
 
 	return fresh_item_count;
-#else
-	return getTotalItemCount();
-#endif
 }
 
 U32 LLPanelMarketplaceInbox::getTotalItemCount() const
@@ -231,7 +227,6 @@ void LLPanelMarketplaceInbox::draw()
 		args["[NUM]"] = item_count_str;
 		mInboxButton->setLabel(getString("InboxLabelWithArg", args));
 
-#if SUPPORTING_FRESH_ITEM_COUNT
 		// set green text to fresh item count
 		U32 fresh_item_count = getFreshItemCount();
 		mFreshCountCtrl->setVisible((fresh_item_count > 0));
@@ -240,9 +235,6 @@ void LLPanelMarketplaceInbox::draw()
 		{
 			mFreshCountCtrl->setTextArg("[NUM]", llformat("%d", fresh_item_count));
 		}
-#else
-		mFreshCountCtrl->setVisible(FALSE);
-#endif
 	}
 	else
 	{
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.cpp b/indra/newview/llpanelmarketplaceinboxinventory.cpp
index 678e4f28433bade734f6c66edd5434915cf69547..adfb2dee86da79831649193ae48cc22b1fd9ba3a 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.cpp
+++ b/indra/newview/llpanelmarketplaceinboxinventory.cpp
@@ -29,7 +29,8 @@
 #include "llpanelmarketplaceinboxinventory.h"
 
 #include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewitem.h"
+#include "llfolderviewmodel.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
@@ -39,6 +40,8 @@
 
 #define DEBUGGING_FRESHNESS	0
 
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
+
 //
 // statics
 //
@@ -53,107 +56,42 @@ static LLDefaultChildRegistry::Register<LLInboxFolderViewItem> r3("inbox_folder_
 //
 
 LLInboxInventoryPanel::LLInboxInventoryPanel(const LLInboxInventoryPanel::Params& p)
-	: LLInventoryPanel(p)
-{
-}
+:	LLInventoryPanel(p)
+{}
 
 LLInboxInventoryPanel::~LLInboxInventoryPanel()
-{
-}
-
-// virtual
-void LLInboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, false, false);
-	
-	// leslie -- temporary HACK to work around sim not creating inbox with proper system folder type
-	if (root_id.isNull())
-	{
-		std::string start_folder_name(params.start_folder());
-		
-		LLInventoryModel::cat_array_t* cats;
-		LLInventoryModel::item_array_t* items;
-		
-		gInventory.getDirectDescendentsOf(gInventory.getRootFolderID(), cats, items);
-		
-		if (cats)
-		{
-			for (LLInventoryModel::cat_array_t::const_iterator cat_it = cats->begin(); cat_it != cats->end(); ++cat_it)
-			{
-				LLInventoryCategory* cat = *cat_it;
-				
-				if (cat->getName() == start_folder_name)
-				{
-					root_id = cat->getUUID();
-					break;
-				}
-			}
-		}
-		
-		if (root_id == LLUUID::null)
-		{
-			llwarns << "No category found that matches inbox inventory panel start_folder: " << start_folder_name << llendl;
-		}
-	}
-	// leslie -- end temporary HACK
-	
-	if (root_id == LLUUID::null)
-	{
-		llwarns << "Inbox inventory panel has no root folder!" << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-																	NULL,
-																	root_id);
-	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
+{}
 
 LLFolderViewFolder * LLInboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	LLInboxFolderViewFolder::Params params;
 	
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-	
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.tool_tip = params.name;
+	params.font_color = item_color;
+	params.font_highlight_color = item_color;
 	
 	return LLUICtrlFactory::create<LLInboxFolderViewFolder>(params);
 }
 
 LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	LLInboxFolderViewItem::Params params;
 
 	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
 	params.creation_date = bridge->getCreationDate();
 	params.root = mFolderRoot;
 	params.listener = bridge;
 	params.rect = LLRect (0, 0, 0, 0);
 	params.tool_tip = params.name;
+	params.font_color = item_color;
+	params.font_highlight_color = item_color;
 
 	return LLUICtrlFactory::create<LLInboxFolderViewItem>(params);
 }
@@ -163,26 +101,40 @@ LLFolderViewItem * LLInboxInventoryPanel::createFolderViewItem(LLInvFVBridge * b
 //
 
 LLInboxFolderViewFolder::LLInboxFolderViewFolder(const Params& p)
-	: LLFolderViewFolder(p)
-	, LLBadgeOwner(getHandle())
-	, mFresh(false)
+:	LLFolderViewFolder(p),
+	LLBadgeOwner(getHandle()),
+	mFresh(false)
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
-#endif
+}
+
+void LLInboxFolderViewFolder::addItem(LLFolderViewItem* item)
+{
+    LLFolderViewFolder::addItem(item);
+
+    if(item)
+    {
+        LLInvFVBridge* itemBridge = static_cast<LLInvFVBridge*>(item->getViewModelItem());
+        LLFolderBridge * bridge = static_cast<LLFolderBridge *>(getViewModelItem());
+        bridge->updateHierarchyCreationDate(itemBridge->getCreationDate());
+    }
+
+    // Compute freshness if our parent is the root folder for the inbox
+    if (mParentFolder == mRoot)
+    {
+        computeFreshness();
+    }
 }
 
 // virtual
 void LLInboxFolderViewFolder::draw()
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	if (!badgeHasParent())
 	{
 		addBadgeToParentPanel();
 	}
 	
 	setBadgeVisibility(mFresh);
-#endif
 
 	LLFolderViewFolder::draw();
 }
@@ -207,7 +159,7 @@ void LLInboxFolderViewFolder::computeFreshness()
 
 	if (last_expansion_utc > 0)
 	{
-		mFresh = (mCreationDate > last_expansion_utc);
+		mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
 
 #if DEBUGGING_FRESHNESS
 		if (mFresh)
@@ -229,16 +181,6 @@ void LLInboxFolderViewFolder::deFreshify()
 	gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 }
 
-void LLInboxFolderViewFolder::setCreationDate(time_t creation_date_utc)
-{ 
-	mCreationDate = creation_date_utc; 
-
-	if (mParentFolder == mRoot)
-	{
-		computeFreshness();
-	}
-}
-
 //
 // LLInboxFolderViewItem Implementation
 //
@@ -248,24 +190,18 @@ LLInboxFolderViewItem::LLInboxFolderViewItem(const Params& p)
 	, LLBadgeOwner(getHandle())
 	, mFresh(false)
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	initBadgeParams(p.new_badge());
-#endif
 }
 
-BOOL LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder, LLFolderView* root)
+void LLInboxFolderViewItem::addToFolder(LLFolderViewFolder* folder)
 {
-	BOOL retval = LLFolderViewItem::addToFolder(folder, root);
+	LLFolderViewItem::addToFolder(folder);
 
-#if SUPPORTING_FRESH_ITEM_COUNT
 	// Compute freshness if our parent is the root folder for the inbox
 	if (mParentFolder == mRoot)
 	{
 		computeFreshness();
 	}
-#endif
-	
-	return retval;
 }
 
 BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
@@ -278,14 +214,12 @@ BOOL LLInboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
 // virtual
 void LLInboxFolderViewItem::draw()
 {
-#if SUPPORTING_FRESH_ITEM_COUNT
 	if (!badgeHasParent())
 	{
 		addBadgeToParentPanel();
 	}
 
 	setBadgeVisibility(mFresh);
-#endif
 
 	LLFolderViewItem::draw();
 }
@@ -303,7 +237,7 @@ void LLInboxFolderViewItem::computeFreshness()
 
 	if (last_expansion_utc > 0)
 	{
-		mFresh = (mCreationDate > last_expansion_utc);
+		mFresh = (static_cast<LLFolderViewModelItemInventory*>(getViewModelItem())->getCreationDate() > last_expansion_utc);
 
 #if DEBUGGING_FRESHNESS
 		if (mFresh)
diff --git a/indra/newview/llpanelmarketplaceinboxinventory.h b/indra/newview/llpanelmarketplaceinboxinventory.h
index d6b827ee3ecde04a73fd747f093470eef49f6a26..c05e18c3007f52a39b261523531783f5c7f4a196 100644
--- a/indra/newview/llpanelmarketplaceinboxinventory.h
+++ b/indra/newview/llpanelmarketplaceinboxinventory.h
@@ -33,7 +33,6 @@
 #include "llfolderviewitem.h"
 
 
-#define SUPPORTING_FRESH_ITEM_COUNT	1
 
 
 
@@ -46,9 +45,6 @@ class LLInboxInventoryPanel : public LLInventoryPanel
 	LLInboxInventoryPanel(const Params& p);
 	~LLInboxInventoryPanel();
 
-	// virtual
-	void buildFolderView(const LLInventoryPanel::Params& params);
-
 	// virtual
 	LLFolderViewFolder * createFolderViewFolder(LLInvFVBridge * bridge);
 	LLFolderViewItem * createFolderViewItem(LLInvFVBridge * bridge);
@@ -63,13 +59,13 @@ class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
 		Optional<LLBadge::Params>	new_badge;
 		
 		Params()
-		: new_badge("new_badge")
-		{
-		}
+		:	new_badge("new_badge")
+		{}
 	};
 	
 	LLInboxFolderViewFolder(const Params& p);
 	
+    void addItem(LLFolderViewItem* item);
 	void draw();
 	
 	void selectItem();
@@ -81,8 +77,6 @@ class LLInboxFolderViewFolder : public LLFolderViewFolder, public LLBadgeOwner
 	bool isFresh() const { return mFresh; }
 	
 protected:
-	void setCreationDate(time_t creation_date_utc);
-
 	bool mFresh;
 };
 
@@ -95,14 +89,13 @@ class LLInboxFolderViewItem : public LLFolderViewItem, public LLBadgeOwner
 		Optional<LLBadge::Params>	new_badge;
 
 		Params()
-			: new_badge("new_badge")
-		{
-		}
+		:	new_badge("new_badge")
+		{}
 	};
 
 	LLInboxFolderViewItem(const Params& p);
 
-	BOOL addToFolder(LLFolderViewFolder* folder, LLFolderView* root);
+	void addToFolder(LLFolderViewFolder* folder);
 	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
 
 	void draw();
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.cpp b/indra/newview/llpanelmarketplaceoutboxinventory.cpp
deleted file mode 100644
index ff62cb23dbb18f6cc5b01fa6ff66d8e79e79136b..0000000000000000000000000000000000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.cpp
+++ /dev/null
@@ -1,156 +0,0 @@
-/** 
- * @file llpanelmarketplaceoutboxinventory.cpp
- * @brief LLOutboxInventoryPanel  class definition
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llpanelmarketplaceoutboxinventory.h"
-
-#include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
-#include "llinventorybridge.h"
-#include "llinventoryfunctions.h"
-#include "llpanellandmarks.h"
-#include "llplacesinventorybridge.h"
-#include "lltrans.h"
-#include "llviewerfoldertype.h"
-
-
-//
-// statics
-//
-
-static LLDefaultChildRegistry::Register<LLOutboxInventoryPanel> r1("outbox_inventory_panel");
-static LLDefaultChildRegistry::Register<LLOutboxFolderViewFolder> r2("outbox_folder_view_folder");
-
-
-//
-// LLOutboxInventoryPanel Implementation
-//
-
-LLOutboxInventoryPanel::LLOutboxInventoryPanel(const LLOutboxInventoryPanel::Params& p)
-	: LLInventoryPanel(p)
-{
-}
-
-LLOutboxInventoryPanel::~LLOutboxInventoryPanel()
-{
-}
-
-// virtual
-void LLOutboxInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	
-	LLUUID root_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
-	
-	if (root_id == LLUUID::null)
-	{
-		llwarns << "Outbox inventory panel has no root folder!" << llendl;
-		root_id = LLUUID::generateNewID();
-	}
-	
-	LLInvFVBridge* new_listener = mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-																	LLAssetType::AT_CATEGORY,
-																	LLInventoryType::IT_CATEGORY,
-																	this,
-																	NULL,
-																	root_id);
-	
-	mFolderRoot = createFolderView(new_listener, params.use_label_suffix());
-}
-
-LLFolderViewFolder * LLOutboxInventoryPanel::createFolderViewFolder(LLInvFVBridge * bridge)
-{
-	LLOutboxFolderViewFolder::Params params;
-	
-	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-	
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-	
-	params.root = mFolderRoot;
-	params.listener = bridge;
-	params.tool_tip = params.name;
-	
-	return LLUICtrlFactory::create<LLOutboxFolderViewFolder>(params);
-}
-
-LLFolderViewItem * LLOutboxInventoryPanel::createFolderViewItem(LLInvFVBridge * bridge)
-{
-	LLFolderViewItem::Params params;
-
-	params.name = bridge->getDisplayName();
-	params.icon = bridge->getIcon();
-	params.icon_open = bridge->getOpenIcon();
-
-	if (mShowItemLinkOverlays) // if false, then links show up just like normal items
-	{
-		params.icon_overlay = LLUI::getUIImage("Inv_Link");
-	}
-
-	params.creation_date = bridge->getCreationDate();
-	params.root = mFolderRoot;
-	params.listener = bridge;
-	params.rect = LLRect (0, 0, 0, 0);
-	params.tool_tip = params.name;
-
-	return LLUICtrlFactory::create<LLOutboxFolderViewItem>(params);
-}
-
-//
-// LLOutboxFolderViewFolder Implementation
-//
-
-LLOutboxFolderViewFolder::LLOutboxFolderViewFolder(const Params& p)
-	: LLFolderViewFolder(p)
-{
-}
-
-//
-// LLOutboxFolderViewItem Implementation
-//
-
-LLOutboxFolderViewItem::LLOutboxFolderViewItem(const Params& p)
-	: LLFolderViewItem(p)
-{
-}
-
-BOOL LLOutboxFolderViewItem::handleDoubleClick(S32 x, S32 y, MASK mask)
-{
-	return TRUE;
-}
-
-void LLOutboxFolderViewItem::openItem()
-{
-	// Intentionally do nothing to block attaching items from the outbox
-}
-
-// eof
diff --git a/indra/newview/llpanelmarketplaceoutboxinventory.h b/indra/newview/llpanelmarketplaceoutboxinventory.h
deleted file mode 100644
index a6c522b7c235401e411655856e1fa7a05a0c67e6..0000000000000000000000000000000000000000
--- a/indra/newview/llpanelmarketplaceoutboxinventory.h
+++ /dev/null
@@ -1,78 +0,0 @@
-/** 
- * @file llpanelmarketplaceoutboxinventory.h
- * @brief LLOutboxInventoryPanel class declaration
- *
- * $LicenseInfo:firstyear=2009&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#ifndef LL_OUTBOXINVENTORYPANEL_H
-#define LL_OUTBOXINVENTORYPANEL_H
-
-
-#include "llinventorypanel.h"
-#include "llfolderviewitem.h"
-
-
-class LLOutboxInventoryPanel : public LLInventoryPanel
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLInventoryPanel::Params>
-	{
-		Params() {}
-	};
-	
-	LLOutboxInventoryPanel(const Params& p);
-	~LLOutboxInventoryPanel();
-
-	// virtual
-	void buildFolderView(const LLInventoryPanel::Params& params);
-
-	// virtual
-	LLFolderViewFolder *	createFolderViewFolder(LLInvFVBridge * bridge);
-	LLFolderViewItem *		createFolderViewItem(LLInvFVBridge * bridge);
-};
-
-
-class LLOutboxFolderViewFolder : public LLFolderViewFolder
-{
-public:
-	struct Params : public LLInitParam::Block<Params, LLFolderViewFolder::Params>
-	{
-		Params() {}
-	};
-	
-	LLOutboxFolderViewFolder(const Params& p);
-};
-
-
-class LLOutboxFolderViewItem : public LLFolderViewItem
-{
-public:
-	LLOutboxFolderViewItem(const Params& p);
-
-	// virtual
-	BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
-	void openItem();
-};
-
-
-#endif //LL_OUTBOXINVENTORYPANEL_H
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index d87b565b328d1b6fe6a0b98f177b11babf98a3ae..25ef9a3d6a7f280efb1e2452c5e60382b0afbb0e 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -439,10 +439,9 @@ void LLPanelObject::getState( )
 	mCtrlRotY->setEnabled( enable_rotate );
 	mCtrlRotZ->setEnabled( enable_rotate );
 
-	BOOL owners_identical;
 	LLUUID owner_id;
 	std::string owner_name;
-	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+	LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 
 	// BUG? Check for all objects being editable?
 	S32 roots_selected = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp
index 1ca24f30316339da42901fe3e6e0acddb20090cc..d7130820ab0b6b0bd6e4a1d0905946edccce31fe 100644
--- a/indra/newview/llpanelobjectinventory.cpp
+++ b/indra/newview/llpanelobjectinventory.cpp
@@ -47,6 +47,7 @@
 #include "llfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventorydefines.h"
+#include "llinventoryicon.h"
 #include "llinventoryfilter.h"
 #include "llinventoryfunctions.h"
 #include "llpreviewanim.h"
@@ -66,17 +67,19 @@
 #include "llviewerobjectlist.h"
 #include "llviewermessage.h"
 
+const LLColor4U DEFAULT_WHITE(255, 255, 255);
 
 ///----------------------------------------------------------------------------
 /// Class LLTaskInvFVBridge
 ///----------------------------------------------------------------------------
 
-class LLTaskInvFVBridge : public LLFolderViewEventListener
+class LLTaskInvFVBridge : public LLFolderViewModelItemInventory
 {
 protected:
 	LLUUID mUUID;
 	std::string mName;
 	mutable std::string mDisplayName;
+	mutable std::string mSearchableName;
 	LLPanelObjectInventory* mPanel;
 	U32 mFlags;
 	LLAssetType::EType mAssetType;	
@@ -102,26 +105,29 @@ class LLTaskInvFVBridge : public LLFolderViewEventListener
 	S32 getPrice();
 	static bool commitBuyItem(const LLSD& notification, const LLSD& response);
 
-	// LLFolderViewEventListener functionality
+	// LLFolderViewModelItemInventory functionality
 	virtual const std::string& getName() const;
 	virtual const std::string& getDisplayName() const;
+	virtual const std::string& getSearchableName() const;
+
 	virtual PermissionMask getPermissionMask() const { return PERM_NONE; }
 	/*virtual*/ LLFolderType::EType getPreferredType() const { return LLFolderType::FT_NONE; }
 	virtual const LLUUID& getUUID() const { return mUUID; }
 	virtual time_t getCreationDate() const;
+	virtual void setCreationDate(time_t creation_date_utc);
+
 	virtual LLUIImagePtr getIcon() const;
 	virtual void openItem();
 	virtual BOOL canOpenItem() const { return FALSE; }
 	virtual void closeItem() {}
-	virtual void previewItem();
 	virtual void selectItem() {}
 	virtual BOOL isItemRenameable() const;
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL isItemMovable() const;
 	virtual BOOL isItemRemovable() const;
 	virtual BOOL removeItem();
-	virtual void removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch);
-	virtual void move(LLFolderViewEventListener* parent_listener);
+	virtual void removeBatch(std::vector<LLFolderViewModelItem*>& batch);
+	virtual void move(LLFolderViewModelItem* parent_listener);	
 	virtual BOOL isItemCopyable() const;
 	virtual BOOL copyToClipboard() const;
 	virtual BOOL cutToClipboard() const;
@@ -131,11 +137,15 @@ class LLTaskInvFVBridge : public LLFolderViewEventListener
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
 	virtual void performAction(LLInventoryModel* model, std::string action);
 	virtual BOOL isUpToDate() const { return TRUE; }
-	virtual BOOL hasChildren() const { return FALSE; }
+	virtual bool hasChildren() const { return FALSE; }
 	virtual LLInventoryType::EType getInventoryType() const { return LLInventoryType::IT_NONE; }
 	virtual LLWearableType::EType getWearableType() const { return LLWearableType::WT_NONE; }
+	virtual EInventorySortGroup getSortGroup() const { return SG_ITEM; }
+	virtual LLInventoryObject* getInventoryObject() const { return findInvObject(); }
+
 
 	// LLDragAndDropBridge functionality
+	virtual LLToolDragAndDrop::ESource getDragSource() const { return LLToolDragAndDrop::SOURCE_WORLD; }
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -147,7 +157,8 @@ LLTaskInvFVBridge::LLTaskInvFVBridge(
 	LLPanelObjectInventory* panel,
 	const LLUUID& uuid,
 	const std::string& name,
-	U32 flags):
+	U32 flags)
+:	LLFolderViewModelItemInventory(panel->getRootViewModel()),
 	mUUID(uuid),
 	mName(name),
 	mPanel(panel),
@@ -330,15 +341,27 @@ const std::string& LLTaskInvFVBridge::getDisplayName() const
 		}
 	}
 
+	mSearchableName.assign(mDisplayName + getLabelSuffix());
+
 	return mDisplayName;
 }
 
+const std::string& LLTaskInvFVBridge::getSearchableName() const
+{
+	return mSearchableName;
+}
+
+
 // BUG: No creation dates for task inventory
 time_t LLTaskInvFVBridge::getCreationDate() const
 {
 	return 0;
 }
 
+void LLTaskInvFVBridge::setCreationDate(time_t creation_date_utc)
+{}
+
+
 LLUIImagePtr LLTaskInvFVBridge::getIcon() const
 {
 	const BOOL item_is_multi = (mFlags & LLInventoryItemFlags::II_FLAGS_OBJECT_HAS_MULTIPLE_ITEMS);
@@ -352,11 +375,6 @@ void LLTaskInvFVBridge::openItem()
 	lldebugs << "LLTaskInvFVBridge::openItem()" << llendl;
 }
 
-void LLTaskInvFVBridge::previewItem()
-{
-	openItem();
-}
-
 BOOL LLTaskInvFVBridge::isItemRenameable() const
 {
 	if(gAgent.isGodlike()) return TRUE;
@@ -467,7 +485,7 @@ BOOL LLTaskInvFVBridge::removeItem()
 	return FALSE;
 }
 
-void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>& batch)
+void   LLTaskInvFVBridge::removeBatch(std::vector<LLFolderViewModelItem*>& batch)
 {
 	if (!mPanel)
 	{
@@ -507,7 +525,7 @@ void LLTaskInvFVBridge::removeBatch(LLDynamicArray<LLFolderViewEventListener*>&
 	}
 }
 
-void LLTaskInvFVBridge::move(LLFolderViewEventListener* parent_listener)
+void LLTaskInvFVBridge::move(LLFolderViewModelItem* parent_listener)
 {
 }
 
@@ -709,7 +727,7 @@ class LLTaskCategoryBridge : public LLTaskInvFVBridge
 	virtual BOOL renameItem(const std::string& new_name);
 	virtual BOOL isItemRemovable() const;
 	virtual void buildContextMenu(LLMenuGL& menu, U32 flags);
-	virtual BOOL hasChildren() const;
+	virtual bool hasChildren() const;
 	virtual BOOL startDrag(EDragAndDropType* type, LLUUID* id) const;
 	virtual BOOL dragOrDrop(MASK mask, BOOL drop,
 							EDragAndDropType cargo_type,
@@ -717,6 +735,7 @@ class LLTaskCategoryBridge : public LLTaskInvFVBridge
 							std::string& tooltip_msg);
 	virtual BOOL canOpenItem() const { return TRUE; }
 	virtual void openItem();
+	virtual EInventorySortGroup getSortGroup() const { return SG_NORMAL_FOLDER; }
 };
 
 LLTaskCategoryBridge::LLTaskCategoryBridge(
@@ -739,15 +758,7 @@ const std::string& LLTaskCategoryBridge::getDisplayName() const
 
 	if (cat)
 	{
-		// Localize "Contents" folder.
-		if (cat->getParentUUID().isNull() && cat->getName() == "Contents")
-		{
-			mDisplayName.assign(LLTrans::getString("ViewerObjectContents"));
-		}
-		else
-		{
-			mDisplayName.assign(cat->getName());
-		}
+		mDisplayName.assign(cat->getName());
 	}
 
 	return mDisplayName;
@@ -775,7 +786,7 @@ void LLTaskCategoryBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 	hide_context_entries(menu, items, disabled_items);
 }
 
-BOOL LLTaskCategoryBridge::hasChildren() const
+bool LLTaskCategoryBridge::hasChildren() const
 {
 	// return TRUE if we have or do know know if we have children.
 	// *FIX: For now, return FALSE - we will know for sure soon enough.
@@ -1489,7 +1500,7 @@ LLPanelObjectInventory::LLPanelObjectInventory(const LLPanelObjectInventory::Par
 	mCommitCallbackRegistrar.add("Inventory.DoCreate", boost::bind(&do_nothing));
 	mCommitCallbackRegistrar.add("Inventory.AttachObject", boost::bind(&do_nothing));
 	mCommitCallbackRegistrar.add("Inventory.BeginIMSession", boost::bind(&do_nothing));
-	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars));
+	mCommitCallbackRegistrar.add("Inventory.Share",  boost::bind(&LLAvatarActions::shareWithAvatars, this));
 }
 
 // Destroys the object
@@ -1514,7 +1525,7 @@ BOOL LLPanelObjectInventory::postBuild()
 
 void LLPanelObjectInventory::doToSelected(const LLSD& userdata)
 {
-	mFolders->doToSelected(&gInventory, userdata);
+	LLInventoryAction::doToSelected(&gInventory, mFolders, userdata.asString());
 }
 
 void LLPanelObjectInventory::clearContents()
@@ -1526,6 +1537,8 @@ void LLPanelObjectInventory::clearContents()
 		LLToolDragAndDrop::getInstance()->endDrag();
 	}
 
+	clearItemIDs();
+
 	if( mScroller )
 	{
 		// removes mFolders
@@ -1541,21 +1554,26 @@ void LLPanelObjectInventory::reset()
 {
 	clearContents();
 
-	//setBorderVisible(FALSE);
-	
 	mCommitCallbackRegistrar.pushScope(); // push local callbacks
 	
+	// Reset the inventory model to show all folders by default
+	mInventoryViewModel.getFilter().setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+	
+	// Create a new folder view root
 	LLRect dummy_rect(0, 1, 1, 0);
 	LLFolderView::Params p;
 	p.name = "task inventory";
 	p.title = "task inventory";
-	p.task_id = getTaskUUID();
 	p.parent_panel = this;
 	p.tool_tip= LLTrans::getString("PanelContentsTooltip");
 	p.listener = LLTaskInvFVBridge::createObjectBridge(this, NULL);
+	p.folder_indentation = -14; // subtract space normally reserved for folder expanders
+	p.view_model = &mInventoryViewModel;
+	p.root = NULL;
+    p.options_menu = "menu_inventory.xml";
+
 	mFolders = LLUICtrlFactory::create<LLFolderView>(p);
-	// this ensures that we never say "searching..." or "no items found"
-	mFolders->getFilter()->setShowFolderState(LLInventoryFilter::SHOW_ALL_FOLDERS);
+
 	mFolders->setCallbackRegistrar(&mCommitCallbackRegistrar);
 
 	if (hasFocus())
@@ -1600,7 +1618,7 @@ void LLPanelObjectInventory::inventoryChanged(LLViewerObject* object,
 			 iter != inventory->end(); )
 		{
 			LLInventoryObject* item = *iter++;
-			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properites", item->getUUID());
+			LLFloaterProperties* floater = LLFloaterReg::findTypedInstance<LLFloaterProperties>("properties", item->getUUID());
 			if(floater)
 			{
 				floater->refresh();
@@ -1615,15 +1633,20 @@ void LLPanelObjectInventory::updateInventory()
 	//		<< " panel UUID: " << panel->mTaskUUID << "\n"
 	//		<< " task  UUID: " << object->mID << llendl;
 	// We're still interested in this task's inventory.
-	std::set<LLUUID> selected_items;
+	std::vector<LLUUID> selected_item_ids;
+	std::set<LLFolderViewItem*> selected_items;
 	BOOL inventory_has_focus = FALSE;
-	if (mHaveInventory)
+	if (mHaveInventory && mFolders)
 	{
 		selected_items = mFolders->getSelectionList();
 		inventory_has_focus = gFocusMgr.childHasKeyboardFocus(mFolders);
 	}
-
-	reset();
+	for (std::set<LLFolderViewItem*>::iterator it = selected_items.begin(), end_it = selected_items.end();
+		it != end_it;
+		++it)
+	{
+		selected_item_ids.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+	}
 
 	LLViewerObject* objectp = gObjectList.findObject(mTaskUUID);
 	if (objectp)
@@ -1631,19 +1654,21 @@ void LLPanelObjectInventory::updateInventory()
 		LLInventoryObject* inventory_root = objectp->getInventoryRoot();
 		LLInventoryObject::object_list_t contents;
 		objectp->getInventoryContents(contents);
+
 		if (inventory_root)
 		{
-			createFolderViews(inventory_root, contents);
-			mHaveInventory = TRUE;
+			reset();
 			mIsInventoryEmpty = FALSE;
+			createFolderViews(inventory_root, contents);
 			mFolders->setEnabled(TRUE);
 		}
 		else
 		{
 			// TODO: create an empty inventory
 			mIsInventoryEmpty = TRUE;
-			mHaveInventory = TRUE;
 		}
+
+		mHaveInventory = TRUE;
 	}
 	else
 	{
@@ -1653,11 +1678,12 @@ void LLPanelObjectInventory::updateInventory()
 	}
 
 	// restore previous selection
-	std::set<LLUUID>::iterator selection_it;
-	BOOL first_item = TRUE;
-	for (selection_it = selected_items.begin(); selection_it != selected_items.end(); ++selection_it)
+	std::vector<LLUUID>::iterator selection_it;
+	bool first_item = true;
+	for (selection_it = selected_item_ids.begin(); selection_it != selected_item_ids.end(); ++selection_it)
 	{
-		LLFolderViewItem* selected_item = mFolders->getItemByID(*selection_it);
+		LLFolderViewItem* selected_item = getItemByID(*selection_it);
+		
 		if (selected_item)
 		{
 			//HACK: "set" first item then "change" each other one to get keyboard focus right
@@ -1673,7 +1699,10 @@ void LLPanelObjectInventory::updateInventory()
 		}
 	}
 
-	mFolders->requestArrange();
+	if (mFolders)
+	{
+		mFolders->requestArrange();
+	}
 	mInventoryNeedsUpdate = FALSE;
 	// Edit menu handler is set in onFocusReceived
 }
@@ -1694,19 +1723,24 @@ void LLPanelObjectInventory::createFolderViews(LLInventoryObject* inventory_root
 	bridge = LLTaskInvFVBridge::createObjectBridge(this, inventory_root);
 	if(bridge)
 	{
-		LLFolderViewFolder* new_folder = NULL;
+		LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 		LLFolderViewFolder::Params p;
 		p.name = inventory_root->getName();
-		p.icon = LLUI::getUIImage("Inv_FolderClosed");
-		p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
+		p.tool_tip = p.name;
 		p.root = mFolders;
 		p.listener = bridge;
-		p.tool_tip = p.name;
-		new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
-		new_folder->addToFolder(mFolders, mFolders);
+		p.font_color = item_color;
+		p.font_highlight_color = item_color;
+
+		LLFolderViewFolder* new_folder = LLUICtrlFactory::create<LLFolderViewFolder>(p);
+		new_folder->addToFolder(mFolders);
 		new_folder->toggleOpen();
 
-		createViewsForCategory(&contents, inventory_root, new_folder);
+		if (!contents.empty())
+		{
+			createViewsForCategory(&contents, inventory_root, new_folder);
+		}
 	}
 }
 
@@ -1716,6 +1750,8 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 											  LLInventoryObject* parent,
 											  LLFolderViewFolder* folder)
 {
+	LLUIColor item_color = LLUIColorTable::instance().getColor("MenuItemEnabledColor", DEFAULT_WHITE);
+
 	// Find all in the first pass
 	LLDynamicArray<obj_folder_pair*> child_categories;
 	LLTaskInvFVBridge* bridge;
@@ -1738,11 +1774,11 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 			{
 				LLFolderViewFolder::Params p;
 				p.name = obj->getName();
-				p.icon = LLUI::getUIImage("Inv_FolderClosed");
-				p.icon_open = LLUI::getUIImage("Inv_FolderOpen");
 				p.root = mFolders;
 				p.listener = bridge;
 				p.tool_tip = p.name;
+				p.font_color = item_color;
+				p.font_highlight_color = item_color;
 				view = LLUICtrlFactory::create<LLFolderViewFolder>(p);
 				child_categories.put(new obj_folder_pair(obj,
 														 (LLFolderViewFolder*)view));
@@ -1751,15 +1787,17 @@ void LLPanelObjectInventory::createViewsForCategory(LLInventoryObject::object_li
 			{
 				LLFolderViewItem::Params params;
 				params.name(obj->getName());
-				params.icon(bridge->getIcon());
 				params.creation_date(bridge->getCreationDate());
 				params.root(mFolders);
 				params.listener(bridge);
 				params.rect(LLRect());
 				params.tool_tip = params.name;
+				params.font_color = item_color;
+				params.font_highlight_color = item_color;
 				view = LLUICtrlFactory::create<LLFolderViewItem> (params);
 			}
-			view->addToFolder(folder, mFolders);
+			view->addToFolder(folder);
+			addItemID(obj->getUUID(), view);
 		}
 	}
 
@@ -1827,6 +1865,7 @@ void LLPanelObjectInventory::refresh()
 		removeVOInventoryListener();
 		clearContents();
 	}
+	mInventoryViewModel.setTaskID(mTaskUUID);
 	//llinfos << "LLPanelObjectInventory::refresh() " << mTaskUUID << llendl;
 }
 
@@ -1914,7 +1953,10 @@ void LLPanelObjectInventory::idle(void* user_data)
 {
 	LLPanelObjectInventory* self = (LLPanelObjectInventory*)user_data;
 
-
+	if (self->mFolders)
+	{
+		self->mFolders->update();
+	}
 	if (self->mInventoryNeedsUpdate)
 	{
 		self->updateInventory();
@@ -1939,3 +1981,32 @@ void LLPanelObjectInventory::onFocusReceived()
 	
 	LLPanel::onFocusReceived();
 }
+
+
+LLFolderViewItem* LLPanelObjectInventory::getItemByID( const LLUUID& id )
+{
+	std::map<LLUUID, LLFolderViewItem*>::iterator map_it;
+	map_it = mItemMap.find(id);
+	if (map_it != mItemMap.end())
+	{
+		return map_it->second;
+	}
+
+	return NULL;
+}
+
+void LLPanelObjectInventory::removeItemID( const LLUUID& id )
+{
+	mItemMap.erase(id);
+}
+
+void LLPanelObjectInventory::addItemID( const LLUUID& id, LLFolderViewItem* itemp )
+{
+	mItemMap[id] = itemp;
+}
+
+void LLPanelObjectInventory::clearItemIDs()
+{
+	mItemMap.clear();
+}
+
diff --git a/indra/newview/llpanelobjectinventory.h b/indra/newview/llpanelobjectinventory.h
index 607b705f7f85809392b13382305ca243070fc42b..f497c695b352841da162bea78ce2399f1807d4e0 100644
--- a/indra/newview/llpanelobjectinventory.h
+++ b/indra/newview/llpanelobjectinventory.h
@@ -29,6 +29,7 @@
 
 #include "llvoinventorylistener.h"
 #include "llpanel.h"
+#include "llinventorypanel.h" // for LLFolderViewModelInventory
 
 #include "llinventory.h"
 
@@ -55,6 +56,8 @@ class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
 	
 	virtual BOOL postBuild();
 
+	LLFolderViewModelInventory& getRootViewModel() { return mInventoryViewModel; }
+
 	void doToSelected(const LLSD& userdata);
 	
 	void refresh();
@@ -85,8 +88,15 @@ class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
 								LLInventoryObject* parent,
 								LLFolderViewFolder* folder);
 	void clearContents();
+	LLFolderViewItem* getItemByID(const LLUUID& id);
+
+	void addItemID( const LLUUID& id, LLFolderViewItem*   itemp );
+	void removeItemID(const LLUUID& id);
+	void clearItemIDs();
 
 private:
+	std::map<LLUUID, LLFolderViewItem*> mItemMap;
+
 	LLScrollContainer* mScroller;
 	LLFolderView* mFolders;
 	
@@ -94,6 +104,7 @@ class LLPanelObjectInventory : public LLPanel, public LLVOInventoryListener
 	BOOL mHaveInventory;
 	BOOL mIsInventoryEmpty;
 	BOOL mInventoryNeedsUpdate;
+	LLFolderViewModelInventory	mInventoryViewModel;	
 };
 
 #endif // LL_LLPANELOBJECTINVENTORY_H
diff --git a/indra/newview/llpaneloutfitedit.cpp b/indra/newview/llpaneloutfitedit.cpp
index 36234b953660b65f3188cea306ed74a02e92a7c2..c09d4393c81c79e3f9f2a5a8e9fd9fc2e0c7d92b 100644
--- a/indra/newview/llpaneloutfitedit.cpp
+++ b/indra/newview/llpaneloutfitedit.cpp
@@ -169,7 +169,7 @@ class LLPanelOutfitEditGearMenu
 
 		return menu;
 	}
-
+	
 private:
 	static void onCreate(const LLSD& param)
 	{
@@ -186,11 +186,8 @@ class LLPanelOutfitEditGearMenu
 	// Populate the menu with items like "New Skin", "New Pants", etc.
 	static void populateCreateWearableSubmenus(LLMenuGL* menu)
 	{
-        // MAINT-2276...these menus are created as dummies because they are not available
-        // when this function is called. This prevents their parent from popping up later.
-        //
-		//LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
-		//LLView* menu_bp			= gMenuHolder->getChildView("COF.Geear.New_Body_Parts", FALSE);
+		LLView* menu_clothes	= gMenuHolder->getChildView("COF.Gear.New_Clothes", FALSE);
+		LLView* menu_bp			= gMenuHolder->getChildView("COF.Gear.New_Body_Parts", FALSE);
 
 		for (U8 i = LLWearableType::WT_SHAPE; i != (U8) LLWearableType::WT_COUNT; ++i)
 		{
@@ -203,11 +200,7 @@ class LLPanelOutfitEditGearMenu
 			p.on_click.function_name = "Wearable.Create";
 			p.on_click.parameter = LLSD(type_name);
 
-            //LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;
-            // This is a work-around for MAINT-2276 wherein the parent toggleable menu does not appear
-            // It puts everything under one menu, but that menu appears, which is better than not.
-            // 
-			LLView* parent =  menu;
+            LLView* parent = LLWearableType::getAssetType(type) == LLAssetType::AT_CLOTHING ? menu_clothes : menu_bp;
 			LLUICtrlFactory::create<LLMenuItemCallGL>(p, parent);
 		}
 	}
@@ -276,7 +269,7 @@ class LLAddWearablesGearMenu : public LLInitClass<LLAddWearablesGearMenu>
 
 		if (inventory_panel->getVisible())
 		{
-			inventory_panel->setSortOrder(sort_order);
+			inventory_panel->getFolderViewModel()->setSorter(sort_order);
 		}
 		else
 		{
@@ -744,7 +737,7 @@ void LLPanelOutfitEdit::onSearchEdit(const std::string& string)
 	}
 	
 	// save current folder open state if no filter currently applied
-	if (mInventoryItemsPanel->getRootFolder()->getFilterSubString().empty())
+	if (mInventoryItemsPanel->getFilterSubString().empty())
 	{
 		mSavedFolderState->setApply(FALSE);
 		mInventoryItemsPanel->getRootFolder()->applyFunctorRecursively(*mSavedFolderState);
@@ -891,13 +884,13 @@ LLPanelOutfitEdit::selection_info_t LLPanelOutfitEdit::getAddMorePanelSelectionT
 	{
 		if (mInventoryItemsPanel != NULL && mInventoryItemsPanel->getVisible())
 		{
-			std::set<LLUUID> selected_uuids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selected_items =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
 
-			result.second = selected_uuids.size();
+			result.second = selected_items.size();
 
 			if (result.second == 1)
 			{
-				result.first = getWearableTypeByItemUUID(*(selected_uuids.begin()));
+				result.first = getWearableTypeByItemUUID(static_cast<LLFolderViewModelItemInventory*>((*selected_items.begin())->getViewModelItem())->getUUID());
 			}
 		}
 		else if (mWearableItemsList != NULL && mWearableItemsList->getVisible())
@@ -1316,7 +1309,7 @@ void LLPanelOutfitEdit::getCurrentItemUUID(LLUUID& selected_id)
 		LLFolderViewItem* curr_item = mInventoryItemsPanel->getRootFolder()->getCurSelectedItem();
 		if (!curr_item) return;
 
-		LLFolderViewEventListener* listenerp  = curr_item->getListener();
+		LLFolderViewModelItemInventory* listenerp  = static_cast<LLFolderViewModelItemInventory*>(curr_item->getViewModelItem());
 		if (!listenerp) return;
 
 		selected_id = listenerp->getUUID();
@@ -1333,9 +1326,13 @@ void LLPanelOutfitEdit::getSelectedItemsUUID(uuid_vec_t& uuid_list)
 	void (uuid_vec_t::* tmp)(LLUUID const &) = &uuid_vec_t::push_back;
 	if (mInventoryItemsPanel->getVisible())
 	{
-		std::set<LLUUID> item_set = mInventoryItemsPanel->getRootFolder()->getSelectionList();
-
-		std::for_each(item_set.begin(), item_set.end(), boost::bind( tmp, &uuid_list, _1));
+		std::set<LLFolderViewItem*> item_set =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
+		for (std::set<LLFolderViewItem*>::iterator it = item_set.begin(),    end_it = item_set.end();
+			it != end_it;
+			++it)
+		{
+			uuid_list.push_back(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+		}
 	}
 	else if (mWearablesListViewPanel->getVisible())
 	{
@@ -1380,13 +1377,13 @@ void LLPanelOutfitEdit::saveListSelection()
 {
 	if(mWearablesListViewPanel->getVisible())
 	{
-		std::set<LLUUID> selected_ids = mInventoryItemsPanel->getRootFolder()->getSelectionList();
+		std::set<LLFolderViewItem*> selected_ids =    mInventoryItemsPanel->getRootFolder()->getSelectionList();
 
 		if(!selected_ids.size()) return;
 
-		for (std::set<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
+		for (std::set<LLFolderViewItem*>::const_iterator item_id =    selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			mWearableItemsList->selectItemByUUID(*item_id, true);
+			mWearableItemsList->selectItemByUUID(static_cast<LLFolderViewModelItemInventory*>((*item_id)->getViewModelItem())->getUUID(),    true);
 		}
 		mWearableItemsList->scrollToShowFirstSelectedItem();
 	}
@@ -1404,7 +1401,7 @@ void LLPanelOutfitEdit::saveListSelection()
 
 		for(std::vector<LLUUID>::const_iterator item_id = selected_ids.begin(); item_id != selected_ids.end(); ++item_id)
 		{
-			LLFolderViewItem* item = root->getItemByID(*item_id);
+			LLFolderViewItem* item = mInventoryItemsPanel->getItemByID(*item_id);
 			if (!item) continue;
 
 			LLFolderViewFolder* parent = item->getParentFolder();
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index f1380e7a3628a4bf9e2c754b29dad164fae90315..4138558bad150b4414f45eceb37845ab78a49c6c 100644
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -72,6 +72,7 @@ static const std::string NEARBY_TAB_NAME	= "nearby_panel";
 static const std::string FRIENDS_TAB_NAME	= "friends_panel";
 static const std::string GROUP_TAB_NAME		= "groups_panel";
 static const std::string RECENT_TAB_NAME	= "recent_panel";
+static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars
 
 static const std::string COLLAPSED_BY_USER  = "collapsed_by_user";
 
@@ -492,26 +493,37 @@ class LLRecentListUpdater : public LLAvatarListUpdater, public boost::signals2::
 
 LLPanelPeople::LLPanelPeople()
 	:	LLPanel(),
-		mFilterSubString(LLStringUtil::null),
-		mFilterSubStringOrig(LLStringUtil::null),
-		mFilterEditor(NULL),
 		mTabContainer(NULL),
 		mOnlineFriendList(NULL),
 		mAllFriendList(NULL),
 		mNearbyList(NULL),
 		mRecentList(NULL),
 		mGroupList(NULL),
-		mNearbyGearButton(NULL),
-		mFriendsGearButton(NULL),
-		mGroupsGearButton(NULL),
-		mRecentGearButton(NULL),
 		mMiniMap(NULL)
 {
 	mFriendListUpdater = new LLFriendListUpdater(boost::bind(&LLPanelPeople::updateFriendList,	this));
 	mNearbyListUpdater = new LLNearbyListUpdater(boost::bind(&LLPanelPeople::updateNearbyList,	this));
 	mRecentListUpdater = new LLRecentListUpdater(boost::bind(&LLPanelPeople::updateRecentList,	this));
 	mButtonsUpdater = new LLButtonsUpdater(boost::bind(&LLPanelPeople::updateButtons, this));
-	mCommitCallbackRegistrar.add("People.addFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+
+	mCommitCallbackRegistrar.add("People.AddFriend", boost::bind(&LLPanelPeople::onAddFriendButtonClicked, this));
+	mCommitCallbackRegistrar.add("People.AddFriendWizard",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.DelFriend",		boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this));
+	mCommitCallbackRegistrar.add("People.Group.Minus",		boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
+	mCommitCallbackRegistrar.add("People.Chat",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
+	mCommitCallbackRegistrar.add("People.Gear",			boost::bind(&LLPanelPeople::onGearButtonClicked,		this, _1));
+
+	mCommitCallbackRegistrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2));
+	mCommitCallbackRegistrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2));
+
+	mEnableCallbackRegistrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2));
+	mEnableCallbackRegistrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2));
+
+	mEnableCallbackRegistrar.add("People.Group.Plus.Validate",	boost::bind(&LLPanelPeople::onGroupPlusButtonValidate,	this));
 }
 
 LLPanelPeople::~LLPanelPeople()
@@ -525,13 +537,6 @@ LLPanelPeople::~LLPanelPeople()
 	{
 		LLVoiceClient::getInstance()->removeObserver(this);
 	}
-
-	if (mGroupPlusMenuHandle.get()) mGroupPlusMenuHandle.get()->die();
-	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
-	if (mNearbyViewSortMenuHandle.get()) mNearbyViewSortMenuHandle.get()->die();
-	if (mGroupsViewSortMenuHandle.get()) mGroupsViewSortMenuHandle.get()->die();
-	if (mRecentViewSortMenuHandle.get()) mRecentViewSortMenuHandle.get()->die();
-
 }
 
 void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LLSD& param, LLAvatarList* avatar_list)
@@ -551,17 +556,31 @@ void LLPanelPeople::onFriendsAccordionExpandedCollapsed(LLUICtrl* ctrl, const LL
 	}
 }
 
+
+void LLPanelPeople::removePicker()
+{
+    if(mPicker.get())
+    {
+        mPicker.get()->closeFloater();
+    }
+}
+
 BOOL LLPanelPeople::postBuild()
 {
-	mFilterEditor = getChild<LLFilterEditor>("filter_input");
-	mFilterEditor->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("nearby_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("friends_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("groups_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
+	getChild<LLFilterEditor>("recent_filter_input")->setCommitCallback(boost::bind(&LLPanelPeople::onFilterEdit, this, _2));
 
 	mTabContainer = getChild<LLTabContainer>("tabs");
 	mTabContainer->setCommitCallback(boost::bind(&LLPanelPeople::onTabSelected, this, _2));
+	mSavedFilters.resize(mTabContainer->getTabCount());
+	mSavedOriginalFilters.resize(mTabContainer->getTabCount());
 
 	LLPanel* friends_tab = getChild<LLPanel>(FRIENDS_TAB_NAME);
 	// updater is active only if panel is visible to user.
 	friends_tab->setVisibleCallback(boost::bind(&Updater::setActive, mFriendListUpdater, _2));
+    friends_tab->setVisibleCallback(boost::bind(&LLPanelPeople::removePicker, this));
 	mOnlineFriendList = friends_tab->getChild<LLAvatarList>("avatars_online");
 	mAllFriendList = friends_tab->getChild<LLAvatarList>("avatars_all");
 	mOnlineFriendList->setNoItemsCommentText(getString("no_friends_online"));
@@ -592,23 +611,15 @@ BOOL LLPanelPeople::postBuild()
 	mGroupList->setNoItemsMsg(getString("no_groups_msg"));
 	mGroupList->setNoFilteredItemsMsg(getString("no_filtered_groups_msg"));
 
-	mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mRecentList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
-	mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gNearbyMenu);
+	mNearbyList->setContextMenu(&LLPanelPeopleMenus::gNearbyPeopleContextMenu);
+	mRecentList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+	mAllFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
+	mOnlineFriendList->setContextMenu(&LLPanelPeopleMenus::gPeopleContextMenu);
 
 	setSortOrder(mRecentList,		(ESortOrder)gSavedSettings.getU32("RecentPeopleSortOrder"),	false);
 	setSortOrder(mAllFriendList,	(ESortOrder)gSavedSettings.getU32("FriendsSortOrder"),		false);
 	setSortOrder(mNearbyList,		(ESortOrder)gSavedSettings.getU32("NearbyPeopleSortOrder"),	false);
 
-	LLPanel* groups_panel = getChild<LLPanel>(GROUP_TAB_NAME);
-	groups_panel->childSetAction("activate_btn", boost::bind(&LLPanelPeople::onActivateButtonClicked,	this));
-	groups_panel->childSetAction("plus_btn",	boost::bind(&LLPanelPeople::onGroupPlusButtonClicked,	this));
-
-	LLPanel* friends_panel = getChild<LLPanel>(FRIENDS_TAB_NAME);
-	friends_panel->childSetAction("add_btn",	boost::bind(&LLPanelPeople::onAddFriendWizButtonClicked,	this));
-	friends_panel->childSetAction("del_btn",	boost::bind(&LLPanelPeople::onDeleteFriendButtonClicked,	this));
-
 	mOnlineFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
 	mAllFriendList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
 	mNearbyList->setItemDoubleClickCallback(boost::bind(&LLPanelPeople::onAvatarListDoubleClicked, this, _1));
@@ -629,6 +640,19 @@ BOOL LLPanelPeople::postBuild()
 	mGroupList->setCommitCallback(boost::bind(&LLPanelPeople::updateButtons, this));
 	mGroupList->setReturnCallback(boost::bind(&LLPanelPeople::onChatButtonClicked, this));
 
+	LLMenuButton* groups_gear_btn = getChild<LLMenuButton>("groups_gear_btn");
+
+	// Use the context menu of the Groups list for the Groups tab gear menu.
+	LLToggleableMenu* groups_gear_menu = mGroupList->getContextMenu();
+	if (groups_gear_menu)
+	{
+		groups_gear_btn->setMenu(groups_gear_menu, LLMenuButton::MP_BOTTOM_LEFT);
+	}
+	else
+	{
+		llwarns << "People->Groups list menu not found" << llendl;
+	}
+
 	LLAccordionCtrlTab* accordion_tab = getChild<LLAccordionCtrlTab>("tab_all");
 	accordion_tab->setDropDownStateChangedCallback(
 		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mAllFriendList));
@@ -637,70 +661,9 @@ BOOL LLPanelPeople::postBuild()
 	accordion_tab->setDropDownStateChangedCallback(
 		boost::bind(&LLPanelPeople::onFriendsAccordionExpandedCollapsed, this, _1, _2, mOnlineFriendList));
 
-	buttonSetAction("view_profile_btn",	boost::bind(&LLPanelPeople::onViewProfileButtonClicked,	this));
-	buttonSetAction("group_info_btn",	boost::bind(&LLPanelPeople::onGroupInfoButtonClicked,	this));
-	buttonSetAction("chat_btn",			boost::bind(&LLPanelPeople::onChatButtonClicked,		this));
-	buttonSetAction("im_btn",			boost::bind(&LLPanelPeople::onImButtonClicked,			this));
-	buttonSetAction("call_btn",			boost::bind(&LLPanelPeople::onCallButtonClicked,		this));
-	buttonSetAction("group_call_btn",	boost::bind(&LLPanelPeople::onGroupCallButtonClicked,	this));
-	buttonSetAction("teleport_btn",		boost::bind(&LLPanelPeople::onTeleportButtonClicked,	this));
-	buttonSetAction("share_btn",		boost::bind(&LLPanelPeople::onShareButtonClicked,		this));
-
 	// Must go after setting commit callback and initializing all pointers to children.
 	mTabContainer->selectTabByName(NEARBY_TAB_NAME);
 
-	// Create menus.
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	
-	registrar.add("People.Group.Plus.Action",  boost::bind(&LLPanelPeople::onGroupPlusMenuItemClicked,  this, _2));
-	registrar.add("People.Group.Minus.Action", boost::bind(&LLPanelPeople::onGroupMinusButtonClicked,  this));
-	registrar.add("People.Friends.ViewSort.Action",  boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Nearby.ViewSort.Action",  boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Groups.ViewSort.Action",  boost::bind(&LLPanelPeople::onGroupsViewSortMenuItemClicked,  this, _2));
-	registrar.add("People.Recent.ViewSort.Action",  boost::bind(&LLPanelPeople::onRecentViewSortMenuItemClicked,  this, _2));
-
-	enable_registrar.add("People.Group.Minus.Enable",	boost::bind(&LLPanelPeople::isRealGroup,	this));
-	enable_registrar.add("People.Friends.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onFriendsViewSortMenuItemCheck,	this, _2));
-	enable_registrar.add("People.Recent.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onRecentViewSortMenuItemCheck,	this, _2));
-	enable_registrar.add("People.Nearby.ViewSort.CheckItem",	boost::bind(&LLPanelPeople::onNearbyViewSortMenuItemCheck,	this, _2));
-
-	mNearbyGearButton = getChild<LLMenuButton>("nearby_view_sort_btn");
-	mFriendsGearButton = getChild<LLMenuButton>("friends_viewsort_btn");
-	mGroupsGearButton = getChild<LLMenuButton>("groups_viewsort_btn");
-	mRecentGearButton = getChild<LLMenuButton>("recent_viewsort_btn");
-
-	LLMenuGL* plus_menu  = LLUICtrlFactory::getInstance()->createFromFile<LLMenuGL>("menu_group_plus.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	mGroupPlusMenuHandle  = plus_menu->getHandle();
-
-	LLToggleableMenu* nearby_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_nearby_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(nearby_view_sort)
-	{
-		mNearbyViewSortMenuHandle  = nearby_view_sort->getHandle();
-		mNearbyGearButton->setMenu(nearby_view_sort);
-	}
-
-	LLToggleableMenu* friend_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_friends_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(friend_view_sort)
-	{
-		mFriendsViewSortMenuHandle  = friend_view_sort->getHandle();
-		mFriendsGearButton->setMenu(friend_view_sort);
-	}
-
-	LLToggleableMenu* group_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_groups_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(group_view_sort)
-	{
-		mGroupsViewSortMenuHandle  = group_view_sort->getHandle();
-		mGroupsGearButton->setMenu(group_view_sort);
-	}
-
-	LLToggleableMenu* recent_view_sort  = LLUICtrlFactory::getInstance()->createFromFile<LLToggleableMenu>("menu_people_recent_view_sort.xml",  gMenuHolder, LLViewerMenuHolderGL::child_registry_t::instance());
-	if(recent_view_sort)
-	{
-		mRecentViewSortMenuHandle  = recent_view_sort->getHandle();
-		mRecentGearButton->setMenu(recent_view_sort);
-	}
-
 	LLVoiceClient::getInstance()->addObserver(this);
 
 	// call this method in case some list is empty and buttons can be in inconsistent state
@@ -735,9 +698,11 @@ void LLPanelPeople::updateFriendListHelpText()
 	if (no_friends_text->getVisible())
 	{
 		//update help text for empty lists
-		std::string message_name = mFilterSubString.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
+		const std::string& filter = mSavedOriginalFilters[mTabContainer->getCurrentPanelIndex()];
+
+		std::string message_name = filter.empty() ? "no_friends_msg" : "no_filtered_friends_msg";
 		LLStringUtil::format_map_t args;
-		args["[SEARCH_TERM]"] = LLURI::escape(mFilterSubStringOrig);
+		args["[SEARCH_TERM]"] = LLURI::escape(filter);
 		no_friends_text->setText(getString(message_name, args));
 	}
 }
@@ -821,31 +786,9 @@ void LLPanelPeople::updateRecentList()
 	mRecentList->setDirty();
 }
 
-void LLPanelPeople::buttonSetVisible(std::string btn_name, BOOL visible)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setVisible(visible);
-}
-
-void LLPanelPeople::buttonSetEnabled(const std::string& btn_name, bool enabled)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setEnabled(enabled);
-}
-
-void LLPanelPeople::buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb)
-{
-	// To make sure we're referencing the right widget (a child of the button bar).
-	LLButton* button = getChild<LLView>("button_bar")->getChild<LLButton>(btn_name);
-	button->setClickedCallback(cb);
-}
-
 void LLPanelPeople::updateButtons()
 {
 	std::string cur_tab		= getActiveTabName();
-	bool nearby_tab_active	= (cur_tab == NEARBY_TAB_NAME);
 	bool friends_tab_active = (cur_tab == FRIENDS_TAB_NAME);
 	bool group_tab_active	= (cur_tab == GROUP_TAB_NAME);
 	//bool recent_tab_active	= (cur_tab == RECENT_TAB_NAME);
@@ -856,63 +799,45 @@ void LLPanelPeople::updateButtons()
 	bool item_selected = (selected_uuids.size() == 1);
 	bool multiple_selected = (selected_uuids.size() >= 1);
 
-	buttonSetVisible("group_info_btn",		group_tab_active);
-	buttonSetVisible("chat_btn",			group_tab_active);
-	buttonSetVisible("view_profile_btn",	!group_tab_active);
-	buttonSetVisible("im_btn",				!group_tab_active);
-	buttonSetVisible("call_btn",			!group_tab_active);
-	buttonSetVisible("group_call_btn",		group_tab_active);
-	buttonSetVisible("teleport_btn",		friends_tab_active);
-	buttonSetVisible("share_btn",			nearby_tab_active || friends_tab_active);
-
 	if (group_tab_active)
 	{
-		bool cur_group_active = true;
-
 		if (item_selected)
 		{
 			selected_id = mGroupList->getSelectedUUID();
-			cur_group_active = (gAgent.getGroupID() == selected_id);
 		}
 
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
-		groups_panel->getChildView("activate_btn")->setEnabled(item_selected && !cur_group_active); // "none" or a non-active group selected
-		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull());
+		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
 	}
 	else
 	{
 		bool is_friend = true;
-
+		bool is_self = false;
 		// Check whether selected avatar is our friend.
 		if (item_selected)
 		{
 			selected_id = selected_uuids.front();
 			is_friend = LLAvatarTracker::instance().getBuddyInfo(selected_id) != NULL;
+			is_self = gAgent.getID() == selected_id;
 		}
 
 		LLPanel* cur_panel = mTabContainer->getCurrentPanel();
 		if (cur_panel)
 		{
-			cur_panel->getChildView("add_friend_btn")->setEnabled(!is_friend);
+			if (cur_panel->hasChild("add_friend_btn", TRUE))
+				cur_panel->getChildView("add_friend_btn")->setEnabled(item_selected && !is_friend && !is_self);
+
 			if (friends_tab_active)
 			{
-				cur_panel->getChildView("del_btn")->setEnabled(multiple_selected);
+				cur_panel->getChildView("friends_del_btn")->setEnabled(multiple_selected);
+			}
+
+			if (!group_tab_active)
+			{
+				cur_panel->getChildView("gear_btn")->setEnabled(multiple_selected);
 			}
 		}
 	}
-
-	bool enable_calls = LLVoiceClient::getInstance()->isVoiceWorking() && LLVoiceClient::getInstance()->voiceEnabled();
-
-	buttonSetEnabled("view_profile_btn",item_selected);
-	buttonSetEnabled("share_btn",		item_selected);
-	buttonSetEnabled("im_btn",			multiple_selected); // allow starting the friends conference for multiple selection
-	buttonSetEnabled("call_btn",		multiple_selected && enable_calls);
-	buttonSetEnabled("teleport_btn",	multiple_selected && LLAvatarActions::canOfferTeleport(selected_uuids));
-
-	bool none_group_selected = item_selected && selected_id.isNull();
-	buttonSetEnabled("group_info_btn", !none_group_selected);
-	buttonSetEnabled("group_call_btn", !none_group_selected && enable_calls);
-	buttonSetEnabled("chat_btn", !none_group_selected);
 }
 
 std::string LLPanelPeople::getActiveTabName() const
@@ -943,6 +868,9 @@ LLUUID LLPanelPeople::getCurrentItemID() const
 	if (cur_tab == GROUP_TAB_NAME)
 		return mGroupList->getSelectedUUID();
 
+	if (cur_tab == BLOCKED_TAB_NAME)
+		return LLUUID::null; // FIXME?
+
 	llassert(0 && "unknown tab selected");
 	return LLUUID::null;
 }
@@ -963,6 +891,8 @@ void LLPanelPeople::getCurrentItemIDs(uuid_vec_t& selected_uuids) const
 		mRecentList->getSelectedUUIDs(selected_uuids);
 	else if (cur_tab == GROUP_TAB_NAME)
 		mGroupList->getSelectedUUIDs(selected_uuids);
+	else if (cur_tab == BLOCKED_TAB_NAME)
+		selected_uuids.clear(); // FIXME?
 	else
 		llassert(0 && "unknown tab selected");
 
@@ -1031,49 +961,60 @@ void LLPanelPeople::setSortOrder(LLAvatarList* list, ESortOrder order, bool save
 	}
 }
 
-bool LLPanelPeople::isRealGroup()
-{
-	return getCurrentItemID() != LLUUID::null;
-}
-
 void LLPanelPeople::onFilterEdit(const std::string& search_string)
 {
-	mFilterSubStringOrig = search_string;
-	LLStringUtil::trimHead(mFilterSubStringOrig);
+	const S32 cur_tab_idx = mTabContainer->getCurrentPanelIndex();
+	std::string& filter = mSavedOriginalFilters[cur_tab_idx];
+	std::string& saved_filter = mSavedFilters[cur_tab_idx];
+
+	filter = search_string;
+	LLStringUtil::trimHead(filter);
+
 	// Searches are case-insensitive
-	std::string search_upper = mFilterSubStringOrig;
+	std::string search_upper = filter;
 	LLStringUtil::toUpper(search_upper);
 
-	if (mFilterSubString == search_upper)
+	if (saved_filter == search_upper)
 		return;
 
-	mFilterSubString = search_upper;
+	saved_filter = search_upper;
 
-	//store accordion tabs state before any manipulation with accordion tabs
-	if(!mFilterSubString.empty())
+	// Apply new filter to the current tab.
+	const std::string cur_tab = getActiveTabName();
+	if (cur_tab == NEARBY_TAB_NAME)
+	{
+		mNearbyList->setNameFilter(filter);
+	}
+	else if (cur_tab == FRIENDS_TAB_NAME)
+	{
+		// store accordion tabs opened/closed state before any manipulation with accordion tabs
+		if (!saved_filter.empty())
 	{
 		notifyChildren(LLSD().with("action","store_state"));
 	}
 
-
-	// Apply new filter.
-	mNearbyList->setNameFilter(mFilterSubStringOrig);
-	mOnlineFriendList->setNameFilter(mFilterSubStringOrig);
-	mAllFriendList->setNameFilter(mFilterSubStringOrig);
-	mRecentList->setNameFilter(mFilterSubStringOrig);
-	mGroupList->setNameFilter(mFilterSubStringOrig);
+		mOnlineFriendList->setNameFilter(filter);
+		mAllFriendList->setNameFilter(filter);
 
 	setAccordionCollapsedByUser("tab_online", false);
 	setAccordionCollapsedByUser("tab_all", false);
-
 	showFriendsAccordionsIfNeeded();
 
-	//restore accordion tabs state _after_ all manipulations...
-	if(mFilterSubString.empty())
+		// restore accordion tabs state _after_ all manipulations
+		if(saved_filter.empty())
 	{
 		notifyChildren(LLSD().with("action","restore_state"));
 	}
 }
+	else if (cur_tab == GROUP_TAB_NAME)
+	{
+		mGroupList->setNameFilter(filter);
+	}
+	else if (cur_tab == RECENT_TAB_NAME)
+	{
+		mRecentList->setNameFilter(filter);
+	}
+}
 
 void LLPanelPeople::onTabSelected(const LLSD& param)
 {
@@ -1081,11 +1022,6 @@ void LLPanelPeople::onTabSelected(const LLSD& param)
 	updateButtons();
 
 	showFriendsAccordionsIfNeeded();
-
-	if (GROUP_TAB_NAME == tab_name)
-		mFilterEditor->setLabel(getString("groups_filter_label"));
-	else
-		mFilterEditor->setLabel(getString("people_filter_label"));
 }
 
 void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
@@ -1097,6 +1033,10 @@ void LLPanelPeople::onAvatarListDoubleClicked(LLUICtrl* ctrl)
 	}
 
 	LLUUID clicked_id = item->getAvatarId();
+	if(gAgent.getID() == clicked_id)
+	{
+		return;
+	}
 	
 #if 0 // SJB: Useful for testing, but not currently functional or to spec
 	LLAvatarActions::showProfile(clicked_id);
@@ -1127,12 +1067,6 @@ void LLPanelPeople::onAvatarListCommitted(LLAvatarList* list)
 	updateButtons();
 }
 
-void LLPanelPeople::onViewProfileButtonClicked()
-{
-	LLUUID id = getCurrentItemID();
-	LLAvatarActions::showProfile(id);
-}
-
 void LLPanelPeople::onAddFriendButtonClicked()
 {
 	LLUUID id = getCurrentItemID();
@@ -1160,8 +1094,12 @@ bool LLPanelPeople::isItemsFreeOfFriends(const uuid_vec_t& uuids)
 
 void LLPanelPeople::onAddFriendWizButtonClicked()
 {
+    LLPanel* cur_panel = mTabContainer->getCurrentPanel();
+    LLView * button = cur_panel->findChild<LLButton>("friends_add_btn", TRUE);
+
 	// Show add friend wizard.
-	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE);
+    LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	LLFloaterAvatarPicker* picker = LLFloaterAvatarPicker::show(boost::bind(&LLPanelPeople::onAvatarPicked, _1, _2), FALSE, TRUE, FALSE, root_floater->getName(), button);
 	if (!picker)
 	{
 		return;
@@ -1169,11 +1107,13 @@ void LLPanelPeople::onAddFriendWizButtonClicked()
 
 	// Need to disable 'ok' button when friend occurs in selection
 	picker->setOkBtnEnableCb(boost::bind(&LLPanelPeople::isItemsFreeOfFriends, this, _1));
-	LLFloater* root_floater = gFloaterView->getParentFloater(this);
+	
 	if (root_floater)
 	{
 		root_floater->addDependentFloater(picker);
 	}
+
+    mPicker = picker->getHandle();
 }
 
 void LLPanelPeople::onDeleteFriendButtonClicked()
@@ -1191,11 +1131,6 @@ void LLPanelPeople::onDeleteFriendButtonClicked()
 	}
 }
 
-void LLPanelPeople::onGroupInfoButtonClicked()
-{
-	LLGroupActions::show(getCurrentItemID());
-}
-
 void LLPanelPeople::onChatButtonClicked()
 {
 	LLUUID group_id = getCurrentItemID();
@@ -1203,6 +1138,17 @@ void LLPanelPeople::onChatButtonClicked()
 		LLGroupActions::startIM(group_id);
 }
 
+void LLPanelPeople::onGearButtonClicked(LLUICtrl* btn)
+{
+	uuid_vec_t selected_uuids;
+	getCurrentItemIDs(selected_uuids);
+	// Spawn at bottom left corner of the button.
+	if (getActiveTabName() == NEARBY_TAB_NAME)
+		LLPanelPeopleMenus::gNearbyPeopleContextMenu.show(btn, selected_uuids, 0, 0);
+	else
+		LLPanelPeopleMenus::gPeopleContextMenu.show(btn, selected_uuids, 0, 0);
+}
+
 void LLPanelPeople::onImButtonClicked()
 {
 	uuid_vec_t selected_uuids;
@@ -1219,11 +1165,6 @@ void LLPanelPeople::onImButtonClicked()
 	}
 }
 
-void LLPanelPeople::onActivateButtonClicked()
-{
-	LLGroupActions::activate(mGroupList->getSelectedUUID());
-}
-
 // static
 void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAvatarName> names)
 {
@@ -1231,19 +1172,15 @@ void LLPanelPeople::onAvatarPicked(const uuid_vec_t& ids, const std::vector<LLAv
 		LLAvatarActions::requestFriendshipDialog(ids[0], names[0].getCompleteName());
 }
 
-void LLPanelPeople::onGroupPlusButtonClicked()
+bool LLPanelPeople::onGroupPlusButtonValidate()
 {
 	if (!gAgent.canJoinGroups())
 	{
 		LLNotificationsUtil::add("JoinedTooManyGroups");
-		return;
+		return false;
 	}
 
-	LLMenuGL* plus_menu = (LLMenuGL*)mGroupPlusMenuHandle.get();
-	if (!plus_menu)
-		return;
-
-	showGroupMenu(plus_menu);
+	return true;
 }
 
 void LLPanelPeople::onGroupMinusButtonClicked()
@@ -1288,10 +1225,6 @@ void LLPanelPeople::onFriendsViewSortMenuItemClicked(const LLSD& userdata)
 		mAllFriendList->showPermissions(show_permissions);
 		mOnlineFriendList->showPermissions(show_permissions);
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 void LLPanelPeople::onGroupsViewSortMenuItemClicked(const LLSD& userdata)
@@ -1324,10 +1257,6 @@ void LLPanelPeople::onNearbyViewSortMenuItemClicked(const LLSD& userdata)
 	{
 		setSortOrder(mNearbyList, E_SORT_BY_DISTANCE);
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 bool LLPanelPeople::onNearbyViewSortMenuItemCheck(const LLSD& userdata)
@@ -1361,10 +1290,6 @@ void LLPanelPeople::onRecentViewSortMenuItemClicked(const LLSD& userdata)
 	{
 		mRecentList->toggleIcons();
 	}
-	else if (chosen_item == "panel_block_list_sidetray")
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-	}
 }
 
 bool LLPanelPeople::onFriendsViewSortMenuItemCheck(const LLSD& userdata) 
@@ -1393,40 +1318,6 @@ bool LLPanelPeople::onRecentViewSortMenuItemCheck(const LLSD& userdata)
 	return false;
 }
 
-void LLPanelPeople::onCallButtonClicked()
-{
-	uuid_vec_t selected_uuids;
-	getCurrentItemIDs(selected_uuids);
-
-	if (selected_uuids.size() == 1)
-	{
-		// initiate a P2P voice chat with the selected user
-		LLAvatarActions::startCall(getCurrentItemID());
-	}
-	else if (selected_uuids.size() > 1)
-	{
-		// initiate an ad-hoc voice chat with multiple users
-		LLAvatarActions::startAdhocCall(selected_uuids);
-	}
-}
-
-void LLPanelPeople::onGroupCallButtonClicked()
-{
-	LLGroupActions::startCall(getCurrentItemID());
-}
-
-void LLPanelPeople::onTeleportButtonClicked()
-{
-	uuid_vec_t selected_uuids;
-	getCurrentItemIDs(selected_uuids);
-	LLAvatarActions::offerTeleport(selected_uuids);
-}
-
-void LLPanelPeople::onShareButtonClicked()
-{
-	LLAvatarActions::share(getCurrentItemID());
-}
-
 void LLPanelPeople::onMoreButtonClicked()
 {
 	// *TODO: not implemented yet
diff --git a/indra/newview/llpanelpeople.h b/indra/newview/llpanelpeople.h
index 46c58cd139ab3fb660a1d78cd2f0903eaa0e7e55..4740964deefab783e390b8bc38442ad2481231c7 100644
--- a/indra/newview/llpanelpeople.h
+++ b/indra/newview/llpanelpeople.h
@@ -68,6 +68,8 @@ class LLPanelPeople
 		E_SORT_BY_RECENT_SPEAKERS = 4,
 	} ESortOrder;
 
+    void				    removePicker();
+
 	// methods indirectly called by the updaters
 	void					updateFriendListHelpText();
 	void					updateFriendList();
@@ -80,31 +82,22 @@ class LLPanelPeople
 	std::string				getActiveTabName() const;
 	LLUUID					getCurrentItemID() const;
 	void					getCurrentItemIDs(uuid_vec_t& selected_uuids) const;
-	void					buttonSetVisible(std::string btn_name, BOOL visible);
-	void					buttonSetEnabled(const std::string& btn_name, bool enabled);
-	void					buttonSetAction(const std::string& btn_name, const commit_signal_t::slot_type& cb);
 	void					showGroupMenu(LLMenuGL* menu);
 	void					setSortOrder(LLAvatarList* list, ESortOrder order, bool save = true);
 
 	// UI callbacks
 	void					onFilterEdit(const std::string& search_string);
 	void					onTabSelected(const LLSD& param);
-	void					onViewProfileButtonClicked();
 	void					onAddFriendButtonClicked();
 	void					onAddFriendWizButtonClicked();
 	void					onDeleteFriendButtonClicked();
-	void					onGroupInfoButtonClicked();
 	void					onChatButtonClicked();
+	void					onGearButtonClicked(LLUICtrl* btn);
 	void					onImButtonClicked();
-	void					onCallButtonClicked();
-	void					onGroupCallButtonClicked();
-	void					onTeleportButtonClicked();
-	void					onShareButtonClicked();
 	void					onMoreButtonClicked();
-	void					onActivateButtonClicked();
 	void					onAvatarListDoubleClicked(LLUICtrl* ctrl);
 	void					onAvatarListCommitted(LLAvatarList* list);
-	void					onGroupPlusButtonClicked();
+	bool					onGroupPlusButtonValidate();
 	void					onGroupMinusButtonClicked();
 	void					onGroupPlusMenuItemClicked(const LLSD& userdata);
 
@@ -113,8 +106,6 @@ class LLPanelPeople
 	void					onGroupsViewSortMenuItemClicked(const LLSD& userdata);
 	void					onRecentViewSortMenuItemClicked(const LLSD& userdata);
 
-	//returns false only if group is "none"
-	bool					isRealGroup();
 	bool					onFriendsViewSortMenuItemCheck(const LLSD& userdata);
 	bool					onRecentViewSortMenuItemCheck(const LLSD& userdata);
 	bool					onNearbyViewSortMenuItemCheck(const LLSD& userdata);
@@ -135,7 +126,6 @@ class LLPanelPeople
 	bool					isAccordionCollapsedByUser(LLUICtrl* acc_tab);
 	bool					isAccordionCollapsedByUser(const std::string& name);
 
-	LLFilterEditor*			mFilterEditor;
 	LLTabContainer*			mTabContainer;
 	LLAvatarList*			mOnlineFriendList;
 	LLAvatarList*			mAllFriendList;
@@ -144,24 +134,14 @@ class LLPanelPeople
 	LLGroupList*			mGroupList;
 	LLNetMap*				mMiniMap;
 
-	LLHandle<LLView>		mGroupPlusMenuHandle;
-	LLHandle<LLView>		mNearbyViewSortMenuHandle;
-	LLHandle<LLView>		mFriendsViewSortMenuHandle;
-	LLHandle<LLView>		mGroupsViewSortMenuHandle;
-	LLHandle<LLView>		mRecentViewSortMenuHandle;
+	std::vector<std::string> mSavedOriginalFilters;
+	std::vector<std::string> mSavedFilters;
 
 	Updater*				mFriendListUpdater;
 	Updater*				mNearbyListUpdater;
 	Updater*				mRecentListUpdater;
 	Updater*				mButtonsUpdater;
-
-	LLMenuButton*			mNearbyGearButton;
-	LLMenuButton*			mFriendsGearButton;
-	LLMenuButton*			mGroupsGearButton;
-	LLMenuButton*			mRecentGearButton;
-
-	std::string				mFilterSubString;
-	std::string				mFilterSubStringOrig;
+    LLHandle< LLFloater >	mPicker;
 };
 
 #endif //LL_LLPANELPEOPLE_H
diff --git a/indra/newview/llpanelpeoplemenus.cpp b/indra/newview/llpanelpeoplemenus.cpp
index f12c4de2f764894f25b6230df4c6337e55a1ebf7..49f7361c4ad78dc217cc7be84381c3c2b2a5159d 100644
--- a/indra/newview/llpanelpeoplemenus.cpp
+++ b/indra/newview/llpanelpeoplemenus.cpp
@@ -37,20 +37,25 @@
 #include "llagentdata.h"			// for gAgentID
 #include "llavataractions.h"
 #include "llcallingcard.h"			// for LLAvatarTracker
+#include "lllogchat.h"
 #include "llviewermenu.h"			// for gMenuHolder
+#include "llconversationmodel.h"
+#include "llviewerobjectlist.h"
 
 namespace LLPanelPeopleMenus
 {
 
-NearbyMenu gNearbyMenu;
+PeopleContextMenu gPeopleContextMenu;
+NearbyPeopleContextMenu gNearbyPeopleContextMenu;
 
-//== NearbyMenu ===============================================================
+//== PeopleContextMenu ===============================================================
 
-LLContextMenu* NearbyMenu::createMenu()
+LLContextMenu* PeopleContextMenu::createMenu()
 {
 	// set up the callbacks for all of the avatar menu items
 	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
+	LLContextMenu* menu;
 
 	if ( mUUIDs.size() == 1 )
 	{
@@ -62,38 +67,86 @@ LLContextMenu* NearbyMenu::createMenu()
 		registrar.add("Avatar.RemoveFriend",	boost::bind(&LLAvatarActions::removeFriendDialog, 		id));
 		registrar.add("Avatar.IM",				boost::bind(&LLAvatarActions::startIM,					id));
 		registrar.add("Avatar.Call",			boost::bind(&LLAvatarActions::startCall,				id));
-		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
+		registrar.add("Avatar.OfferTeleport",	boost::bind(&PeopleContextMenu::offerTeleport,			this));
+		registrar.add("Avatar.ZoomIn",			boost::bind(&handle_zoom_to_object,						id));
 		registrar.add("Avatar.ShowOnMap",		boost::bind(&LLAvatarActions::showOnMap,				id));
 		registrar.add("Avatar.Share",			boost::bind(&LLAvatarActions::share,					id));
 		registrar.add("Avatar.Pay",				boost::bind(&LLAvatarActions::pay,						id));
 		registrar.add("Avatar.BlockUnblock",	boost::bind(&LLAvatarActions::toggleBlock,				id));
+		registrar.add("Avatar.InviteToGroup",	boost::bind(&LLAvatarActions::inviteToGroup,			id));
+		registrar.add("Avatar.Calllog",			boost::bind(&LLAvatarActions::viewChatHistory,			id));
 
-		enable_registrar.add("Avatar.EnableItem", boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
-		enable_registrar.add("Avatar.CheckItem",  boost::bind(&NearbyMenu::checkContextMenuItem,	this, _2));
+		enable_registrar.add("Avatar.EnableItem", boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
+		enable_registrar.add("Avatar.CheckItem",  boost::bind(&PeopleContextMenu::checkContextMenuItem,	this, _2));
 
 		// create the context menu from the XUI
-		return createFromFile("menu_people_nearby.xml");
+		menu = createFromFile("menu_people_nearby.xml");
+		buildContextMenu(*menu, 0x0);
 	}
 	else
 	{
 		// Set up for multi-selected People
 
 		// registrar.add("Avatar.AddFriend",	boost::bind(&LLAvatarActions::requestFriendshipDialog,	mUUIDs)); // *TODO: unimplemented
-		registrar.add("Avatar.IM",			boost::bind(&LLAvatarActions::startConference,			mUUIDs));
-		registrar.add("Avatar.Call",		boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs));
-		registrar.add("Avatar.OfferTeleport",	boost::bind(&NearbyMenu::offerTeleport,					this));
-		registrar.add("Avatar.RemoveFriend",boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
+		registrar.add("Avatar.IM",				boost::bind(&LLAvatarActions::startConference,			mUUIDs, LLUUID::null));
+		registrar.add("Avatar.Call",			boost::bind(&LLAvatarActions::startAdhocCall,			mUUIDs, LLUUID::null));
+		registrar.add("Avatar.OfferTeleport",	boost::bind(&PeopleContextMenu::offerTeleport,			this));
+		registrar.add("Avatar.RemoveFriend",	boost::bind(&LLAvatarActions::removeFriendsDialog,		mUUIDs));
 		// registrar.add("Avatar.Share",		boost::bind(&LLAvatarActions::startIM,					mUUIDs)); // *TODO: unimplemented
-		// registrar.add("Avatar.Pay",		boost::bind(&LLAvatarActions::pay,						mUUIDs)); // *TODO: unimplemented
-		enable_registrar.add("Avatar.EnableItem",	boost::bind(&NearbyMenu::enableContextMenuItem,	this, _2));
+		// registrar.add("Avatar.Pay",			boost::bind(&LLAvatarActions::pay,						mUUIDs)); // *TODO: unimplemented
+		
+		enable_registrar.add("Avatar.EnableItem",	boost::bind(&PeopleContextMenu::enableContextMenuItem, this, _2));
 
 		// create the context menu from the XUI
-		return createFromFile("menu_people_nearby_multiselect.xml");
+		menu = createFromFile("menu_people_nearby_multiselect.xml");
+		buildContextMenu(*menu, ITEM_IN_MULTI_SELECTION);
 	}
+
+    return menu;
+}
+
+void PeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	if (flags & ITEM_IN_MULTI_SELECTION)
+	{
+		items.push_back(std::string("add_friends"));
+		items.push_back(std::string("remove_friends"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("call"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("offer_teleport"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+	}
+
+    hide_context_entries(menu, items, disabled_items);
 }
 
-bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
+bool PeopleContextMenu::enableContextMenuItem(const LLSD& userdata)
 {
+	if(gAgent.getID() == mUUIDs.front())
+	{
+		return false;
+	}
 	std::string item = userdata.asString();
 
 	// Note: can_block and can_delete is used only for one person selected menu
@@ -160,6 +213,12 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canCall();
 	}
+	else if (item == std::string("can_zoom_in"))
+	{
+		const LLUUID& id = mUUIDs.front();
+
+		return gObjectList.findObject(id);
+	}
 	else if (item == std::string("can_show_on_map"))
 	{
 		const LLUUID& id = mUUIDs.front();
@@ -171,10 +230,19 @@ bool NearbyMenu::enableContextMenuItem(const LLSD& userdata)
 	{
 		return LLAvatarActions::canOfferTeleport(mUUIDs);
 	}
+	else if (item == std::string("can_callog"))
+	{
+		return LLLogChat::isTranscriptExist(mUUIDs.front());
+	}
+	else if (item == std::string("can_im") || item == std::string("can_invite") ||
+	         item == std::string("can_share") || item == std::string("can_pay"))
+	{
+		return true;
+	}
 	return false;
 }
 
-bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
+bool PeopleContextMenu::checkContextMenuItem(const LLSD& userdata)
 {
 	std::string item = userdata.asString();
 	const LLUUID& id = mUUIDs.front();
@@ -187,11 +255,50 @@ bool NearbyMenu::checkContextMenuItem(const LLSD& userdata)
 	return false;
 }
 
-void NearbyMenu::offerTeleport()
+void PeopleContextMenu::offerTeleport()
 {
 	// boost::bind cannot recognize overloaded method LLAvatarActions::offerTeleport(),
 	// so we have to use a wrapper.
 	LLAvatarActions::offerTeleport(mUUIDs);
 }
 
+//== NearbyPeopleContextMenu ===============================================================
+
+void NearbyPeopleContextMenu::buildContextMenu(class LLMenuGL& menu, U32 flags)
+{
+    menuentry_vec_t items;
+    menuentry_vec_t disabled_items;
+	
+	if (flags & ITEM_IN_MULTI_SELECTION)
+	{
+		items.push_back(std::string("add_friends"));
+		items.push_back(std::string("remove_friends"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("call"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("offer_teleport"));
+	}
+	else 
+	{
+		items.push_back(std::string("view_profile"));
+		items.push_back(std::string("im"));
+		items.push_back(std::string("offer_teleport"));
+		items.push_back(std::string("voice_call"));
+		items.push_back(std::string("chat_history"));
+		items.push_back(std::string("separator_chat_history"));
+		items.push_back(std::string("add_friend"));
+		items.push_back(std::string("remove_friend"));
+		items.push_back(std::string("invite_to_group"));
+		items.push_back(std::string("separator_invite_to_group"));
+		items.push_back(std::string("zoom_in"));
+		items.push_back(std::string("map"));
+		items.push_back(std::string("share"));
+		items.push_back(std::string("pay"));
+		items.push_back(std::string("block_unblock"));
+	}
+
+    hide_context_entries(menu, items, disabled_items);
+}
+
 } // namespace LLPanelPeopleMenus
diff --git a/indra/newview/llpanelpeoplemenus.h b/indra/newview/llpanelpeoplemenus.h
index d51eaec7167a9b80c905796e6196a9fb5d999f63..0a1dcef303f65cc55096adb79d18f1858a3f0df3 100644
--- a/indra/newview/llpanelpeoplemenus.h
+++ b/indra/newview/llpanelpeoplemenus.h
@@ -33,19 +33,33 @@ namespace LLPanelPeopleMenus
 {
 
 /**
- * Menu used in the nearby people list.
+ * Menu used in the people lists.
  */
-class NearbyMenu : public LLListContextMenu
+class PeopleContextMenu : public LLListContextMenu
 {
 public:
 	/*virtual*/ LLContextMenu* createMenu();
+
+protected:
+	virtual void buildContextMenu(class LLMenuGL& menu, U32 flags);
+
 private:
 	bool enableContextMenuItem(const LLSD& userdata);
 	bool checkContextMenuItem(const LLSD& userdata);
 	void offerTeleport();
 };
 
-extern NearbyMenu gNearbyMenu;
+/**
+ * Menu used in the nearby people list.
+ */
+class NearbyPeopleContextMenu : public PeopleContextMenu
+{
+protected:
+	/*virtual*/ void buildContextMenu(class LLMenuGL& menu, U32 flags);
+};
+
+extern PeopleContextMenu gPeopleContextMenu;
+extern NearbyPeopleContextMenu gNearbyPeopleContextMenu;
 
 } // namespace LLPanelPeopleMenus
 
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index e641370d2eb0d15960931d1a49f8611973643f3e..131e8e9359122b1a9d0a701a2d4654590845d2b7 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -365,10 +365,8 @@ void LLPanelPermissions::refresh()
 	
 	// Update creator text field
 	getChildView("Creator:")->setEnabled(TRUE);
-	BOOL creators_identical;
 	std::string creator_name;
-	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
-																	  creator_name);
+	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
 
 	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
 	getChildView("Creator Name")->setEnabled(TRUE);
diff --git a/indra/newview/llpanelplaceprofile.cpp b/indra/newview/llpanelplaceprofile.cpp
index ce8057eeaddd74746192e9c2130466569081b133..5d9971c16c14ad562dc7a8e9aaa32b42bbf453c0 100644
--- a/indra/newview/llpanelplaceprofile.cpp
+++ b/indra/newview/llpanelplaceprofile.cpp
@@ -499,9 +499,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 			std::string parcel_owner =
 				LLSLURL("agent", parcel->getOwnerID(), "inspect").getSLURLString();
 			mParcelOwner->setText(parcel_owner);
-			LLAvatarNameCache::get(region->getOwner(),
-								   boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
-											   _1, _2, mRegionOwnerText));
+			LLAvatarNameCache::get(region->getOwner(), boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mRegionOwnerText));
 		}
 
 		if(LLParcel::OS_LEASE_PENDING == parcel->getOwnershipStatus())
@@ -523,9 +521,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		const LLUUID& auth_buyer_id = parcel->getAuthorizedBuyerID();
 		if(auth_buyer_id.notNull())
 		{
-			LLAvatarNameCache::get(auth_buyer_id,
-								   boost::bind(&LLPanelPlaceInfo::onAvatarNameCache,
-											   _1, _2, mSaleToText));
+			LLAvatarNameCache::get(auth_buyer_id, boost::bind(&LLPanelPlaceInfo::onAvatarNameCache, _1, _2, mSaleToText));
 			
 			// Show sales info to a specific person or a group he belongs to.
 			if (auth_buyer_id != gAgent.getID() && !gAgent.isInGroup(auth_buyer_id))
@@ -572,7 +568,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 
 		mTerraformLimitsText->setText(parcel->getAllowTerraform() ? on : off);
 
-		if (region->getRegionFlags() & REGION_FLAGS_ALLOW_PARCEL_CHANGES)
+		if (region->getRegionFlag(REGION_FLAGS_ALLOW_PARCEL_CHANGES))
 		{
 			mSubdivideText->setText(getString("can_change"));
 		}
@@ -580,7 +576,7 @@ void LLPanelPlaceProfile::displaySelectedParcelInfo(LLParcel* parcel,
 		{
 			mSubdivideText->setText(getString("can_not_change"));
 		}
-		if (region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL))
 		{
 			mResaleText->setText(getString("can_not_resell"));
 		}
diff --git a/indra/newview/llpanelplaceprofile.h b/indra/newview/llpanelplaceprofile.h
index a33fc12ce429296e32197de96f1d2b2bbeca90a5..f4c614588179cf48ae6ee4e0299774f980ac09e9 100644
--- a/indra/newview/llpanelplaceprofile.h
+++ b/indra/newview/llpanelplaceprofile.h
@@ -38,7 +38,7 @@ class LLPanelPlaceProfile : public LLPanelPlaceInfo
 public:
 	LLPanelPlaceProfile();
 	/*virtual*/ ~LLPanelPlaceProfile();
-
+	
 	/*virtual*/ BOOL postBuild();
 
 	/*virtual*/ void resetLocation();
diff --git a/indra/newview/llpaneltopinfobar.cpp b/indra/newview/llpaneltopinfobar.cpp
index 1830086da29fcf7c6ce867acb39d431834db0962..9dd665198f6b7d165e505c14ff7113c126fd943f 100644
--- a/indra/newview/llpaneltopinfobar.cpp
+++ b/indra/newview/llpaneltopinfobar.cpp
@@ -232,7 +232,7 @@ void LLPanelTopInfoBar::buildLocationString(std::string& loc_str, bool show_coor
 void LLPanelTopInfoBar::setParcelInfoText(const std::string& new_text)
 {
 	LLRect old_rect = getRect();
-	const LLFontGL* font = mParcelInfoText->getDefaultFont();
+	const LLFontGL* font = mParcelInfoText->getFont();
 	S32 new_text_width = font->getWidth(new_text);
 
 	mParcelInfoText->setText(new_text);
@@ -417,11 +417,11 @@ void LLPanelTopInfoBar::onParcelIconClick(EParcelIcon icon)
 	case SCRIPTS_ICON:
 	{
 		LLViewerRegion* region = gAgent.getRegion();
-		if(region && region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		if(region && region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsStopped");
 		}
-		else if(region && region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
+		else if(region && region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS))
 		{
 			LLNotificationsUtil::add("ScriptsNotRunning");
 		}
diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp
index 13b746dbabb3ccc24f6006e97f1971819e4eafeb..02d363d7952eb3d99e74feedeef75014b4162dec 100644
--- a/indra/newview/llpanelvolume.cpp
+++ b/indra/newview/llpanelvolume.cpp
@@ -252,10 +252,9 @@ void LLPanelVolume::getState( )
 		return;
 	}
 
-	BOOL owners_identical;
 	LLUUID owner_id;
 	std::string owner_name;
-	owners_identical = LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
+	LLSelectMgr::getInstance()->selectGetOwner(owner_id, owner_name);
 
 	// BUG? Check for all objects being editable?
 	BOOL editable = root_objectp->permModify() && !root_objectp->isPermanentEnforced();
diff --git a/indra/newview/llpanelwearing.cpp b/indra/newview/llpanelwearing.cpp
index 3b9934d4be36b08b941ac55b711a455af598fc3d..aa3ed22bee8b7b089e559e9187c0f0391a5da882 100644
--- a/indra/newview/llpanelwearing.cpp
+++ b/indra/newview/llpanelwearing.cpp
@@ -77,11 +77,7 @@ class LLWearingGearMenu
 	{
 		uuid_vec_t selected_uuids;
 		mPanelWearing->getSelectedItemsUUIDs(selected_uuids);
-
-		for (uuid_vec_t::const_iterator it=selected_uuids.begin(); it != selected_uuids.end(); ++it)
-		{
-				LLAppearanceMgr::instance().removeItemFromAvatar(*it);
-		}
+		LLAppearanceMgr::instance().removeItemsFromAvatar(selected_uuids);
 	}
 
 	LLToggleableMenu*		mMenu;
@@ -97,12 +93,11 @@ class LLWearingContextMenu : public LLListContextMenu
 	{
 		LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
 
-		functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
 		registrar.add("Wearing.Edit", boost::bind(&edit_outfit));
-		registrar.add("Wearing.TakeOff", boost::bind(handleMultiple, take_off, mUUIDs));
-		registrar.add("Wearing.Detach", boost::bind(handleMultiple, take_off, mUUIDs));
-
+		registrar.add("Wearing.TakeOff",
+					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
+		registrar.add("Wearing.Detach", 
+					  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), mUUIDs));
 		LLContextMenu* menu = createFromFile("menu_wearing_tab.xml");
 
 		updateMenuItemsVisibility(menu);
diff --git a/indra/newview/llparticipantlist.cpp b/indra/newview/llparticipantlist.cpp
index 975a6c67d80a57390b6246e939420db6f2df8acd..c53760bca15c929c08b9e370521688659ca3d90e 100644
--- a/indra/newview/llparticipantlist.cpp
+++ b/indra/newview/llparticipantlist.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.cpp
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -26,38 +26,17 @@
 
 #include "llviewerprecompiledheaders.h"
 
-// common includes
-#include "lltrans.h"
-#include "llavataractions.h"
-#include "llagent.h"
-
+#include "llavatarnamecache.h"
 #include "llimview.h"
-#include "llnotificationsutil.h"
+#include "llfloaterimcontainer.h"
 #include "llparticipantlist.h"
 #include "llspeakers.h"
-#include "llviewercontrol.h"
-#include "llviewermenu.h"
-#include "llvoiceclient.h"
 
 //LLParticipantList retrieves add, clear and remove events and updates view accordingly 
 #if LL_MSVC
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
 #endif
 
-static const LLAvatarItemAgentOnTopComparator AGENT_ON_TOP_NAME_COMPARATOR;
-
-// helper function to update AvatarList Item's indicator in the voice participant list
-static void update_speaker_indicator(const LLAvatarList* const avatar_list, const LLUUID& avatar_uuid, bool is_muted)
-{
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(avatar_list->getItemByValue(avatar_uuid));
-	if (item)
-	{
-		LLOutputMonitorCtrl* indicator = item->getChild<LLOutputMonitorCtrl>("speaking_indicator");
-		indicator->setIsMuted(is_muted);
-	}
-}
-
-
 // See EXT-4301.
 /**
  * class LLAvalineUpdater - observe the list of voice participants in session and check
@@ -197,15 +176,9 @@ class LLAvalineUpdater : public LLVoiceClientParticipantObserver
 	uuid_set_t mAvalineCallers;
 };
 
-LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, 
-									 LLAvatarList* avatar_list,
-									 bool use_context_menu/* = true*/,
-									 bool exclude_agent /*= true*/, 
-									 bool can_toggle_icons /*= true*/) :
+LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model) :
+	LLConversationItemSession(data_source->getSessionID(), root_view_model),
 	mSpeakerMgr(data_source),
-	mAvatarList(avatar_list),
-	mParticipantListMenu(NULL),
-	mExcludeAgent(exclude_agent),
 	mValidateSpeakerCallback(NULL)
 {
 
@@ -216,36 +189,16 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 	mSpeakerRemoveListener = new SpeakerRemoveListener(*this);
 	mSpeakerClearListener = new SpeakerClearListener(*this);
 	mSpeakerModeratorListener = new SpeakerModeratorUpdateListener(*this);
+	mSpeakerUpdateListener = new SpeakerUpdateListener(*this);
 	mSpeakerMuteListener = new SpeakerMuteListener(*this);
 
 	mSpeakerMgr->addListener(mSpeakerAddListener, "add");
 	mSpeakerMgr->addListener(mSpeakerRemoveListener, "remove");
 	mSpeakerMgr->addListener(mSpeakerClearListener, "clear");
 	mSpeakerMgr->addListener(mSpeakerModeratorListener, "update_moderator");
+	mSpeakerMgr->addListener(mSpeakerUpdateListener, "update_speaker");
 
-	mAvatarList->setNoItemsCommentText(LLTrans::getString("LoadingData"));
-	LL_DEBUGS("SpeakingIndicator") << "Set session for speaking indicators: " << mSpeakerMgr->getSessionID() << LL_ENDL;
-	mAvatarList->setSessionID(mSpeakerMgr->getSessionID());
-	mAvatarListDoubleClickConnection = mAvatarList->setItemDoubleClickCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, _1));
-	mAvatarListRefreshConnection = mAvatarList->setRefreshCompleteCallback(boost::bind(&LLParticipantList::onAvatarListRefreshed, this, _1, _2));
-    // Set onAvatarListDoubleClicked as default on_return action.
-	mAvatarListReturnConnection = mAvatarList->setReturnCallback(boost::bind(&LLParticipantList::onAvatarListDoubleClicked, this, mAvatarList));
-
-	if (use_context_menu)
-	{
-		mParticipantListMenu = new LLParticipantListMenu(*this);
-		mAvatarList->setContextMenu(mParticipantListMenu);
-	}
-	else
-	{
-		mAvatarList->setContextMenu(NULL);
-	}
-
-	if (use_context_menu && can_toggle_icons)
-	{
-		mAvatarList->setShowIcons("ParticipantListShowIcons");
-		mAvatarListToggleIconsConnection = gSavedSettings.getControl("ParticipantListShowIcons")->getSignal()->connect(boost::bind(&LLAvatarList::toggleIcons, mAvatarList));
-	}
+	setSessionID(mSpeakerMgr->getSessionID());
 
 	//Lets fill avatarList with existing speakers
 	LLSpeakerMgr::speaker_list_t speaker_list;
@@ -264,138 +217,32 @@ LLParticipantList::LLParticipantList(LLSpeakerMgr* data_source,
 			mModeratorToRemoveList.insert(speakerp->mID);
 		}
 	}
-	// we need to exclude agent id for non group chat
-	sort();
-}
-
-LLParticipantList::~LLParticipantList()
-{
-	mAvatarListDoubleClickConnection.disconnect();
-	mAvatarListRefreshConnection.disconnect();
-	mAvatarListReturnConnection.disconnect();
-	mAvatarListToggleIconsConnection.disconnect();
-
-	// It is possible Participant List will be re-created from LLCallFloater::onCurrentChannelChanged()
-	// See ticket EXT-3427
-	// hide menu before deleting it to stop enable and check handlers from triggering.
-	if(mParticipantListMenu && !LLApp::isExiting())
-	{
-		mParticipantListMenu->hide();
-	}
-
-	if (mParticipantListMenu)
-	{
-		delete mParticipantListMenu;
-		mParticipantListMenu = NULL;
-	}
-
-	mAvatarList->setContextMenu(NULL);
-	mAvatarList->setComparator(NULL);
-
-	delete mAvalineUpdater;
-}
-
-void LLParticipantList::setSpeakingIndicatorsVisible(BOOL visible)
-{
-	mAvatarList->setSpeakingIndicatorsVisible(visible);
-};
-
-void LLParticipantList::onAvatarListDoubleClicked(LLUICtrl* ctrl)
-{
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(ctrl);
-	if(!item)
-	{
-		return;
-	}
-
-	LLUUID clicked_id = item->getAvatarId();
-
-	if (clicked_id.isNull() || clicked_id == gAgent.getID())
-		return;
 	
-	LLAvatarActions::startIM(clicked_id);
-}
-
-void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
-{
-	LLAvatarList* list = dynamic_cast<LLAvatarList*>(ctrl);
-	if (list)
+	// Identify and store what kind of session we are
+	LLIMModel::LLIMSession* im_session = LLIMModel::getInstance()->findIMSession(data_source->getSessionID());
+	if (im_session)
 	{
-		const std::string moderator_indicator(LLTrans::getString("IM_moderator_label")); 
-		const std::size_t moderator_indicator_len = moderator_indicator.length();
-
-		// Firstly remove moderators indicator
-		std::set<LLUUID>::const_iterator
-			moderator_list_it = mModeratorToRemoveList.begin(),
-			moderator_list_end = mModeratorToRemoveList.end();
-		for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
+		// By default, sessions that can't be identified as group or ad-hoc will be considered P2P (i.e. 1 on 1)
+		mConvType = CONV_SESSION_1_ON_1;
+		if (im_session->isAdHocSessionType())
 		{
-			LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
-			if ( item )
-			{
-				std::string name = item->getAvatarName();
-				std::string tooltip = item->getAvatarToolTip();
-				size_t found = name.find(moderator_indicator);
-				if (found != std::string::npos)
-				{
-					name.erase(found, moderator_indicator_len);
-					item->setAvatarName(name);
-				}
-				found = tooltip.find(moderator_indicator);
-				if (found != tooltip.npos)
-				{
-					tooltip.erase(found, moderator_indicator_len);
-					item->setAvatarToolTip(tooltip);
-				}
-			}
-		}
-
-		mModeratorToRemoveList.clear();
-
-		// Add moderators indicator
-		moderator_list_it = mModeratorList.begin();
-		moderator_list_end = mModeratorList.end();
-		for (;moderator_list_it != moderator_list_end; ++moderator_list_it)
-		{
-			LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*> (list->getItemByValue(*moderator_list_it));
-			if ( item )
-			{
-				std::string name = item->getAvatarName();
-				std::string tooltip = item->getAvatarToolTip();
-				size_t found = name.find(moderator_indicator);
-				if (found == std::string::npos)
-				{
-					name += " ";
-					name += moderator_indicator;
-					item->setAvatarName(name);
-				}
-				found = tooltip.find(moderator_indicator);
-				if (found == std::string::npos)
-				{
-					tooltip += " ";
-					tooltip += moderator_indicator;
-					item->setAvatarToolTip(tooltip);
-				}
-			}
+			mConvType = CONV_SESSION_AD_HOC;
 		}
-
-		// update voice mute state of all items. See EXT-7235
-		LLSpeakerMgr::speaker_list_t speaker_list;
-
-		// Use also participants which are not in voice session now (the second arg is TRUE).
-		// They can already have mModeratorMutedVoice set from the previous voice session
-		// and LLSpeakerVoiceModerationEvent will not be sent when speaker manager is updated next time.
-		mSpeakerMgr->getSpeakerList(&speaker_list, TRUE);
-		for(LLSpeakerMgr::speaker_list_t::iterator it = speaker_list.begin(); it != speaker_list.end(); it++)
+		else if (im_session->isGroupSessionType())
 		{
-			const LLPointer<LLSpeaker>& speakerp = *it;
-
-			if (speakerp->mStatus == LLSpeaker::STATUS_TEXT_ONLY)
-			{
-				update_speaker_indicator(list, speakerp->mID, speakerp->mModeratorMutedVoice);
-			}
+			mConvType = CONV_SESSION_GROUP;
 		}
 	}
+	else 
+	{
+		// That's the only session that doesn't get listed in the LLIMModel as a session...
+		mConvType = CONV_SESSION_NEARBY;
+	}
+}
+
+LLParticipantList::~LLParticipantList()
+{
+	delete mAvalineUpdater;
 }
 
 /*
@@ -411,31 +258,11 @@ void LLParticipantList::onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param)
 */
 void LLParticipantList::onAvalineCallerFound(const LLUUID& participant_id)
 {
-	LLPanel* item = mAvatarList->getItemByValue(participant_id);
-
-	if (NULL == item)
+	LLConversationItemParticipant* participant = findParticipant(participant_id);
+	if (participant)
 	{
-		LL_WARNS("Avaline") << "Something wrong. Unable to find item for: " << participant_id << LL_ENDL;
-		return;
+		removeParticipant(participant);
 	}
-
-	if (typeid(*item) == typeid(LLAvalineListItem))
-	{
-		LL_DEBUGS("Avaline") << "Avaline caller has already correct class type for: " << participant_id << LL_ENDL;
-		// item representing an Avaline caller has a correct type already.
-		return;
-	}
-
-	LL_DEBUGS("Avaline") << "remove item from the list and re-add it: " << participant_id << LL_ENDL;
-
-	// remove UUID from LLAvatarList::mIDs to be able add it again.
-	uuid_vec_t& ids = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(ids.begin(), ids.end(), participant_id);
-	ids.erase(pos);
-
-	// remove item directly
-	mAvatarList->removeItem(item);
-
 	// re-add avaline caller with a correct class instance.
 	addAvatarIDExceptAgent(participant_id);
 }
@@ -447,23 +274,6 @@ void LLParticipantList::onAvalineCallerRemoved(const LLUUID& participant_id)
 	mSpeakerMgr->removeAvalineSpeaker(participant_id);
 }
 
-void LLParticipantList::setSortOrder(EParticipantSortOrder order)
-{
-	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-
-	if ( speaker_sort_order != order )
-	{
-		gSavedSettings.setU32("SpeakerParticipantDefaultOrder", (U32)order);
-		sort();
-	}
-}
-
-const LLParticipantList::EParticipantSortOrder LLParticipantList::getSortOrder() const
-{
-	const U32 speaker_sort_order = gSavedSettings.getU32("SpeakerParticipantDefaultOrder");
-	return EParticipantSortOrder(speaker_sort_order);
-}
-
 void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t cb)
 {
 	mValidateSpeakerCallback = cb;
@@ -472,19 +282,6 @@ void LLParticipantList::setValidateSpeakerCallback(validate_speaker_callback_t c
 void LLParticipantList::update()
 {
 	mSpeakerMgr->update(true);
-
-	if (E_SORT_BY_RECENT_SPEAKERS == getSortOrder() && !isHovered())
-	{
-		// Resort avatar list
-		sort();
-	}
-}
-
-bool LLParticipantList::isHovered()
-{
-	S32 x, y;
-	LLUI::getMousePositionScreen(&x, &y);
-	return mAvatarList->calcScreenRect().pointInRect(x, y);
 }
 
 bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
@@ -497,27 +294,34 @@ bool LLParticipantList::onAddItemEvent(LLPointer<LLOldEvents::LLEvent> event, co
 	}
 
 	addAvatarIDExceptAgent(uu_id);
-	sort();
 	return true;
 }
 
 bool LLParticipantList::onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
-	uuid_vec_t& group_members = mAvatarList->getIDs();
-	uuid_vec_t::iterator pos = std::find(group_members.begin(), group_members.end(), event->getValue().asUUID());
-	if(pos != group_members.end())
-	{
-		group_members.erase(pos);
-		mAvatarList->setDirty();
-	}
+	LLUUID avatar_id = event->getValue().asUUID();
+	removeParticipant(avatar_id);
 	return true;
 }
 
 bool LLParticipantList::onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
-	uuid_vec_t& group_members = mAvatarList->getIDs();
-	group_members.clear();
-	mAvatarList->setDirty();
+	clearParticipants();
+	return true;
+}
+
+bool LLParticipantList::onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	const LLSD& evt_data = event->getValue();
+	if ( evt_data.has("id") )
+	{
+		LLUUID participant_id = evt_data["id"];
+		LLFloaterIMContainer* im_box = LLFloaterIMContainer::findInstance();
+		if (im_box)
+		{
+			im_box->setTimeNow(mUUID,participant_id);
+		}
+	}
 	return true;
 }
 
@@ -541,9 +345,7 @@ bool LLParticipantList::onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> e
 					mModeratorList.erase(id);
 				}
 			}
-
-			// apply changes immediately
-			onAvatarListRefreshed(mAvatarList, LLSD());
+			// *TODO : do we have to fire an event so that LLFloaterIMSessionTab::refreshConversation() gets called
 		}
 	}
 	return true;
@@ -557,60 +359,45 @@ bool LLParticipantList::onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event
 	// update UI on confirmation of moderator mutes
 	if (event->getValue().asString() == "voice")
 	{
-		update_speaker_indicator(mAvatarList, speakerp->mID, speakerp->mModeratorMutedVoice);
+		setParticipantIsMuted(speakerp->mID, speakerp->mModeratorMutedVoice);
 	}
 	return true;
 }
 
-void LLParticipantList::sort()
+void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
 {
-	if ( !mAvatarList )
-		return;
-
-	switch ( getSortOrder() ) 
+	// Do not add if already in there, is the session id (hence not an avatar) or excluded for some reason
+	if (findParticipant(avatar_id) || (avatar_id == mUUID))
 	{
-		case E_SORT_BY_NAME :
-			// if mExcludeAgent == true , then no need to keep agent on top of the list
-			if(mExcludeAgent)
-			{
-				mAvatarList->sortByName();
-			}
-			else
-			{
-				mAvatarList->setComparator(&AGENT_ON_TOP_NAME_COMPARATOR);
-				mAvatarList->sort();
-			}
-			break;
-		case E_SORT_BY_RECENT_SPEAKERS:
-			if (mSortByRecentSpeakers.isNull())
-				mSortByRecentSpeakers = new LLAvatarItemRecentSpeakerComparator(*this);
-			mAvatarList->setComparator(mSortByRecentSpeakers.get());
-			mAvatarList->sort();
-			break;
-		default :
-			llwarns << "Unrecognized sort order for " << mAvatarList->getName() << llendl;
-			return;
+		return;
 	}
-}
-
-void LLParticipantList::addAvatarIDExceptAgent(const LLUUID& avatar_id)
-{
-	if (mExcludeAgent && gAgent.getID() == avatar_id) return;
-	if (mAvatarList->contains(avatar_id)) return;
 
 	bool is_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(avatar_id);
 
+	LLConversationItemParticipant* participant = NULL;
+	
 	if (is_avatar)
 	{
-		mAvatarList->getIDs().push_back(avatar_id);
-		mAvatarList->setDirty();
+		// Create a participant view model instance
+		LLAvatarName avatar_name;
+		bool has_name = LLAvatarNameCache::get(avatar_id, &avatar_name);
+		participant = new LLConversationItemParticipant(!has_name ? LLTrans::getString("AvatarNameWaiting") : avatar_name.getDisplayName() , avatar_id, mRootViewModel);
+		participant->fetchAvatarName();
 	}
 	else
 	{
 		std::string display_name = LLVoiceClient::getInstance()->getDisplayName(avatar_id);
-		mAvatarList->addAvalineItem(avatar_id, mSpeakerMgr->getSessionID(), display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name);
+		// Create a participant view model instance
+		participant = new LLConversationItemParticipant(display_name.empty() ? LLTrans::getString("AvatarNameWaiting") : display_name, avatar_id, mRootViewModel);
 		mAvalineUpdater->watchAvalineCaller(avatar_id);
 	}
+
+	// *TODO : Need to update the online/offline status of the participant
+	// Hack for this: LLAvatarTracker::instance().isBuddyOnline(avatar_id))
+	
+	// Add the participant model to the session's children list
+	addParticipant(participant);
+
 	adjustParticipant(avatar_id);
 }
 
@@ -629,12 +416,12 @@ void LLParticipantList::adjustParticipant(const LLUUID& speaker_id)
 bool LLParticipantList::SpeakerAddListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
 {
 	/**
-	 * We need to filter speaking objects. These objects shouldn't appear in the list
+	 * We need to filter speaking objects. These objects shouldn't appear in the list.
 	 * @see LLFloaterChat::addChat() in llviewermessage.cpp to get detailed call hierarchy
 	 */
 	const LLUUID& speaker_id = event->getValue().asUUID();
 	LLPointer<LLSpeaker> speaker = mParent.mSpeakerMgr->findSpeaker(speaker_id);
-	if(speaker.isNull() || speaker->mType == LLSpeaker::SPEAKER_OBJECT)
+	if (speaker.isNull() || (speaker->mType == LLSpeaker::SPEAKER_OBJECT))
 	{
 		return false;
 	}
@@ -657,6 +444,14 @@ bool LLParticipantList::SpeakerClearListener::handleEvent(LLPointer<LLOldEvents:
 	return mParent.onClearListEvent(event, userdata);
 }
 
+//
+// LLParticipantList::SpeakerUpdateListener
+//
+bool LLParticipantList::SpeakerUpdateListener::handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata)
+{
+	return mParent.onSpeakerUpdateEvent(event, userdata);
+}
+
 //
 // LLParticipantList::SpeakerModeratorListener
 //
@@ -670,377 +465,4 @@ bool LLParticipantList::SpeakerMuteListener::handleEvent(LLPointer<LLOldEvents::
 	return mParent.onSpeakerMuteEvent(event, userdata);
 }
 
-LLContextMenu* LLParticipantList::LLParticipantListMenu::createMenu()
-{
-	// set up the callbacks for all of the avatar menu items
-	LLUICtrl::CommitCallbackRegistry::ScopedRegistrar registrar;
-	LLUICtrl::EnableCallbackRegistry::ScopedRegistrar enable_registrar;
-	
-	registrar.add("ParticipantList.Sort", boost::bind(&LLParticipantList::LLParticipantListMenu::sortParticipantList, this, _2));
-	registrar.add("ParticipantList.ToggleAllowTextChat", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleAllowTextChat, this, _2));
-	registrar.add("ParticipantList.ToggleMuteText", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteText, this, _2));
-
-	registrar.add("Avatar.Profile",	boost::bind(&LLAvatarActions::showProfile, mUUIDs.front()));
-	registrar.add("Avatar.IM", boost::bind(&LLAvatarActions::startIM, mUUIDs.front()));
-	registrar.add("Avatar.AddFriend", boost::bind(&LLAvatarActions::requestFriendshipDialog, mUUIDs.front()));
-	registrar.add("Avatar.BlockUnblock", boost::bind(&LLParticipantList::LLParticipantListMenu::toggleMuteVoice, this, _2));
-	registrar.add("Avatar.Share", boost::bind(&LLAvatarActions::share, mUUIDs.front()));
-	registrar.add("Avatar.Pay",	boost::bind(&LLAvatarActions::pay, mUUIDs.front()));
-	registrar.add("Avatar.Call", boost::bind(&LLAvatarActions::startCall, mUUIDs.front()));
-
-	registrar.add("ParticipantList.ModerateVoice", boost::bind(&LLParticipantList::LLParticipantListMenu::moderateVoice, this, _2));
-
-	enable_registrar.add("ParticipantList.EnableItem", boost::bind(&LLParticipantList::LLParticipantListMenu::enableContextMenuItem,	this, _2));
-	enable_registrar.add("ParticipantList.EnableItem.Moderate", boost::bind(&LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem,	this, _2));
-	enable_registrar.add("ParticipantList.CheckItem",  boost::bind(&LLParticipantList::LLParticipantListMenu::checkContextMenuItem,	this, _2));
-
-	// create the context menu from the XUI
-	LLContextMenu* main_menu = createFromFile("menu_participant_list.xml");
-
-	// Don't show sort options for P2P chat
-	bool is_sort_visible = (mParent.mAvatarList && mParent.mAvatarList->size() > 1);
-	main_menu->setItemVisible("SortByName", is_sort_visible);
-	main_menu->setItemVisible("SortByRecentSpeakers", is_sort_visible);
-	main_menu->setItemVisible("Moderator Options Separator", isGroupModerator());
-	main_menu->setItemVisible("Moderator Options", isGroupModerator());
-	main_menu->setItemVisible("View Icons Separator", mParent.mAvatarListToggleIconsConnection.connected());
-	main_menu->setItemVisible("View Icons", mParent.mAvatarListToggleIconsConnection.connected());
-	main_menu->arrangeAndClear();
-
-	return main_menu;
-}
-
-void LLParticipantList::LLParticipantListMenu::show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y)
-{
-	if (uuids.size() == 0) return;
-
-	LLListContextMenu::show(spawning_view, uuids, x, y);
-
-	const LLUUID& speaker_id = mUUIDs.front();
-	BOOL is_muted = isMuted(speaker_id);
-
-	if (is_muted)
-	{
-		LLMenuGL::sMenuContainer->getChildView("ModerateVoiceMuteSelected")->setVisible( false);
-	}
-	else
-	{
-		LLMenuGL::sMenuContainer->getChildView("ModerateVoiceUnMuteSelected")->setVisible( false);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::sortParticipantList(const LLSD& userdata)
-{
-	std::string param = userdata.asString();
-	if ("sort_by_name" == param)
-	{
-		mParent.setSortOrder(E_SORT_BY_NAME);
-	}
-	else if ("sort_by_recent_speakers" == param)
-	{
-		mParent.setSortOrder(E_SORT_BY_RECENT_SPEAKERS);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleAllowTextChat(const LLSD& userdata)
-{
-
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		const LLUUID speaker_id = mUUIDs.front();
-		mgr->toggleAllowTextChat(speaker_id);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMute(const LLSD& userdata, U32 flags)
-{
-	const LLUUID speaker_id = mUUIDs.front();
-	BOOL is_muted = LLMuteList::getInstance()->isMuted(speaker_id, flags);
-	std::string name;
-
-	//fill in name using voice client's copy of name cache
-	LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(speaker_id);
-	if (speakerp.isNull())
-	{
-		LL_WARNS("Speakers") << "Speaker " << speaker_id << " not found" << llendl;
-		return;
-	}
-	LLAvatarListItem* item = dynamic_cast<LLAvatarListItem*>(mParent.mAvatarList->getItemByValue(speaker_id));
-	if (NULL == item) return;
-
-	name = item->getAvatarName();
-
-	LLMute::EType mute_type;
-	switch (speakerp->mType)
-	{
-		case LLSpeaker::SPEAKER_AGENT:
-			mute_type = LLMute::AGENT;
-			break;
-		case LLSpeaker::SPEAKER_OBJECT:
-			mute_type = LLMute::OBJECT;
-			break;
-		case LLSpeaker::SPEAKER_EXTERNAL:
-		default:
-			mute_type = LLMute::EXTERNAL;
-			break;
-	}
-	LLMute mute(speaker_id, name, mute_type);
-
-	if (!is_muted)
-	{
-		LLMuteList::getInstance()->add(mute, flags);
-	}
-	else
-	{
-		LLMuteList::getInstance()->remove(mute, flags);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteText(const LLSD& userdata)
-{
-	toggleMute(userdata, LLMute::flagTextChat);
-}
-
-void LLParticipantList::LLParticipantListMenu::toggleMuteVoice(const LLSD& userdata)
-{
-	toggleMute(userdata, LLMute::flagVoiceChat);
-}
-
-bool LLParticipantList::LLParticipantListMenu::isGroupModerator()
-{
-	if (!mParent.mSpeakerMgr)
-	{
-		llwarns << "Speaker manager is missing" << llendl;
-		return false;
-	}
-
-	// Is session a group call/chat?
-	if(gAgent.isInGroup(mParent.mSpeakerMgr->getSessionID()))
-	{
-		LLSpeaker* speaker = mParent.mSpeakerMgr->findSpeaker(gAgentID).get();
-
-		// Is agent a moderator?
-		return speaker && speaker->mIsModerator;
-	}
-	return false;
-}
-
-bool LLParticipantList::LLParticipantListMenu::isMuted(const LLUUID& avatar_id)
-{
-	LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(avatar_id);
-	if (!selected_speakerp) return true;
-
-	return selected_speakerp->mStatus == LLSpeaker::STATUS_MUTED;
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoice(const LLSD& userdata)
-{
-	if (!gAgent.getRegion()) return;
-
-	bool moderate_selected = userdata.asString() == "selected";
-
-	if (moderate_selected)
-	{
-		const LLUUID& selected_avatar_id = mUUIDs.front();
-		bool is_muted = isMuted(selected_avatar_id);
-		moderateVoiceParticipant(selected_avatar_id, is_muted);
-	}
-	else
-	{
-		bool unmute_all = userdata.asString() == "unmute_all";
-		moderateVoiceAllParticipants(unmute_all);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute)
-{
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		mgr->moderateVoiceParticipant(avatar_id, unmute);
-	}
-}
-
-void LLParticipantList::LLParticipantListMenu::moderateVoiceAllParticipants(bool unmute)
-{
-	LLIMSpeakerMgr* mgr = dynamic_cast<LLIMSpeakerMgr*>(mParent.mSpeakerMgr);
-	if (mgr)
-	{
-		if (!unmute)
-		{
-			LLSD payload;
-			payload["session_id"] = mgr->getSessionID();
-			LLNotificationsUtil::add("ConfirmMuteAll", LLSD(), payload, confirmMuteAllCallback);
-			return;
-		}
-
-		mgr->moderateVoiceAllParticipants(unmute);
-	}
-}
-
-// static
-void LLParticipantList::LLParticipantListMenu::confirmMuteAllCallback(const LLSD& notification, const LLSD& response)
-{
-	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	// if Cancel pressed
-	if (option == 1)
-	{
-		return;
-	}
-
-	const LLSD& payload = notification["payload"];
-	const LLUUID& session_id = payload["session_id"];
-
-	LLIMSpeakerMgr * speaker_manager = dynamic_cast<LLIMSpeakerMgr*> (
-		LLIMModel::getInstance()->getSpeakerManager(session_id));
-	if (speaker_manager)
-	{
-		speaker_manager->moderateVoiceAllParticipants(false);
-	}
-
-	return;
-}
-
-
-bool LLParticipantList::LLParticipantListMenu::enableContextMenuItem(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	const LLUUID& participant_id = mUUIDs.front();
-
-	// For now non of "can_view_profile" action and menu actions listed below except "can_block"
-	// can be performed for Avaline callers.
-	bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
-	if (!is_participant_avatar && "can_block" != item) return false;
-
-	if (item == "can_mute_text" || "can_block" == item || "can_share" == item || "can_im" == item 
-		|| "can_pay" == item)
-	{
-		return mUUIDs.front() != gAgentID;
-	}
-	else if (item == std::string("can_add"))
-	{
-		// We can add friends if:
-		// - there are selected people
-		// - and there are no friends among selection yet.
-
-		bool result = (mUUIDs.size() > 0);
-
-		uuid_vec_t::const_iterator
-			id = mUUIDs.begin(),
-			uuids_end = mUUIDs.end();
-
-		for (;id != uuids_end; ++id)
-		{
-			if ( *id == gAgentID || LLAvatarActions::isFriend(*id) )
-			{
-				result = false;
-				break;
-			}
-		}
-		return result;
-	}
-	else if (item == "can_call")
-	{
-		bool not_agent = mUUIDs.front() != gAgentID;
-		bool can_call = not_agent &&  LLVoiceClient::getInstance()->voiceEnabled() && LLVoiceClient::getInstance()->isVoiceWorking();
-		return can_call;
-	}
-
-	return true;
-}
-
-/*
-  Processed menu items with such parameters:
-  can_allow_text_chat
-  can_moderate_voice
-*/
-bool LLParticipantList::LLParticipantListMenu::enableModerateContextMenuItem(const LLSD& userdata)
-{
-	// only group moderators can perform actions related to this "enable callback"
-	if (!isGroupModerator()) return false;
-
-	const LLUUID& participant_id = mUUIDs.front();
-	LLPointer<LLSpeaker> speakerp = mParent.mSpeakerMgr->findSpeaker(participant_id);
-
-	// not in voice participants can not be moderated
-	bool speaker_in_voice = speakerp.notNull() && speakerp->isInVoiceChannel();
-
-	const std::string& item = userdata.asString();
-
-	if ("can_moderate_voice" == item)
-	{
-		return speaker_in_voice;
-	}
-
-	// For now non of menu actions except "can_moderate_voice" can be performed for Avaline callers.
-	bool is_participant_avatar = LLVoiceClient::getInstance()->isParticipantAvatar(participant_id);
-	if (!is_participant_avatar) return false;
-
-	return true;
-}
-
-bool LLParticipantList::LLParticipantListMenu::checkContextMenuItem(const LLSD& userdata)
-{
-	std::string item = userdata.asString();
-	const LLUUID& id = mUUIDs.front();
-
-	if (item == "is_muted")
-	{
-		return LLMuteList::getInstance()->isMuted(id, LLMute::flagTextChat);
-	}
-	else if (item == "is_allowed_text_chat")
-	{
-		LLPointer<LLSpeaker> selected_speakerp = mParent.mSpeakerMgr->findSpeaker(id);
-
-		if (selected_speakerp.notNull())
-		{
-			return !selected_speakerp->mModeratorMutedText;
-		}
-	}
-	else if(item == "is_blocked")
-	{
-		return LLMuteList::getInstance()->isMuted(id, LLMute::flagVoiceChat);
-	}
-	else if(item == "is_sorted_by_name")
-	{
-		return E_SORT_BY_NAME == mParent.getSortOrder();
-	}
-	else if(item == "is_sorted_by_recent_speakers")
-	{
-		return E_SORT_BY_RECENT_SPEAKERS == mParent.getSortOrder();
-	}
-
-	return false;
-}
-
-bool LLParticipantList::LLAvatarItemRecentSpeakerComparator::doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const
-{
-	if (mParent.mSpeakerMgr)
-	{
-		LLPointer<LLSpeaker> lhs = mParent.mSpeakerMgr->findSpeaker(avatar_item1->getAvatarId());
-		LLPointer<LLSpeaker> rhs = mParent.mSpeakerMgr->findSpeaker(avatar_item2->getAvatarId());
-		if ( lhs.notNull() && rhs.notNull() )
-		{
-			// Compare by last speaking time
-			if( lhs->mLastSpokeTime != rhs->mLastSpokeTime )
-				return ( lhs->mLastSpokeTime > rhs->mLastSpokeTime );
-			else if ( lhs->mSortIndex != rhs->mSortIndex )
-				return ( lhs->mSortIndex < rhs->mSortIndex );
-		}
-		else if ( lhs.notNull() )
-		{
-			// True if only avatar_item1 speaker info available
-			return true;
-		}
-		else if ( rhs.notNull() )
-		{
-			// False if only avatar_item2 speaker info available
-			return false;
-		}
-	}
-	// By default compare by name.
-	return LLAvatarItemNameComparator::doCompare(avatar_item1, avatar_item2);
-}
-
 //EOF
diff --git a/indra/newview/llparticipantlist.h b/indra/newview/llparticipantlist.h
index 53966c15fe6297096fcbf90892a8a81b44dfe85e..3a3ae76604a9c17bc8d0df5629b082bf66f686e9 100644
--- a/indra/newview/llparticipantlist.h
+++ b/indra/newview/llparticipantlist.h
@@ -1,6 +1,6 @@
 /** 
  * @file llparticipantlist.h
- * @brief LLParticipantList intended to update view(LLAvatarList) according to incoming messages
+ * @brief LLParticipantList : model of a conversation session with added speaker events handling
  *
  * $LicenseInfo:firstyear=2009&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -28,35 +28,21 @@
 #define LL_PARTICIPANTLIST_H
 
 #include "llviewerprecompiledheaders.h"
-#include "llevent.h"
-#include "llavatarlist.h" // for LLAvatarItemRecentSpeakerComparator
-#include "lllistcontextmenu.h"
+#include "llconversationmodel.h"
 
 class LLSpeakerMgr;
-class LLAvatarList;
 class LLUICtrl;
 class LLAvalineUpdater;
 
-class LLParticipantList
+class LLParticipantList : public LLConversationItemSession
 {
 	LOG_CLASS(LLParticipantList);
 public:
 
 	typedef boost::function<bool (const LLUUID& speaker_id)> validate_speaker_callback_t;
 
-	LLParticipantList(LLSpeakerMgr* data_source, 
-					  LLAvatarList* avatar_list, 
-					  bool use_context_menu = true, 
-					  bool exclude_agent = true, 
-					  bool can_toggle_icons = true);
+	LLParticipantList(LLSpeakerMgr* data_source, LLFolderViewModelInterface& root_view_model);
 	~LLParticipantList();
-	void setSpeakingIndicatorsVisible(BOOL visible);
-
-	enum EParticipantSortOrder
-	{
-		E_SORT_BY_NAME = 0,
-		E_SORT_BY_RECENT_SPEAKERS = 1,
-	};
 
 	/**
 	 * Adds specified avatar ID to the existing list if it is not Agent's ID
@@ -65,12 +51,6 @@ class LLParticipantList
 	 */
 	void addAvatarIDExceptAgent(const LLUUID& avatar_id);
 
-	/**
-	 * Set and sort Avatarlist by given order
-	 */
-	void setSortOrder(EParticipantSortOrder order = E_SORT_BY_NAME);
-	const EParticipantSortOrder getSortOrder() const;
-
 	/**
 	 * Refreshes the participant list.
 	 */
@@ -93,13 +73,9 @@ class LLParticipantList
 	bool onRemoveItemEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onClearListEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onModeratorUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+	bool onSpeakerUpdateEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	bool onSpeakerMuteEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 
-	/**
-	 * Sorts the Avatarlist by stored order
-	 */
-	void sort();
-
 	/**
 	 * List of listeners implementing LLOldEvents::LLSimpleListener.
 	 * There is no way to handle all the events in one listener as LLSpeakerMgr registers
@@ -134,6 +110,13 @@ class LLParticipantList
 		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	};
 
+	class SpeakerUpdateListener : public BaseSpeakerListener
+	{
+	public:
+		SpeakerUpdateListener(LLParticipantList& parent) : BaseSpeakerListener(parent) {}
+		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
+	};
+	
 	class SpeakerModeratorUpdateListener : public BaseSpeakerListener
 	{
 	public:
@@ -149,98 +132,7 @@ class LLParticipantList
 		/*virtual*/ bool handleEvent(LLPointer<LLOldEvents::LLEvent> event, const LLSD& userdata);
 	};
 
-	/**
-	 * Menu used in the participant list.
-	 */
-	class LLParticipantListMenu : public LLListContextMenu
-	{
-	public:
-		LLParticipantListMenu(LLParticipantList& parent):mParent(parent){};
-		/*virtual*/ LLContextMenu* createMenu();
-		/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
-	protected:
-		LLParticipantList& mParent;
-	private:
-		bool enableContextMenuItem(const LLSD& userdata);
-		bool enableModerateContextMenuItem(const LLSD& userdata);
-		bool checkContextMenuItem(const LLSD& userdata);
-
-		void sortParticipantList(const LLSD& userdata);
-		void toggleAllowTextChat(const LLSD& userdata);
-		void toggleMute(const LLSD& userdata, U32 flags);
-		void toggleMuteText(const LLSD& userdata);
-		void toggleMuteVoice(const LLSD& userdata);
-		
-		/**
-		 * Return true if Agent is group moderator(and moderator of group call).
-		 */
-		bool isGroupModerator();
-
-		// Voice moderation support
-		/**
-		 * Check whether specified by argument avatar is muted for group chat or not.
-		 */
-		bool isMuted(const LLUUID& avatar_id);
-
-		/**
-		 * Processes Voice moderation menu items.
-		 *
-		 * It calls either moderateVoiceParticipant() or moderateVoiceParticipant() depend on
-		 * passed parameter.
-		 *
-		 * @param userdata can be "selected" or "others".
-		 *
-		 * @see moderateVoiceParticipant()
-		 * @see moderateVoiceAllParticipants()
-		 */
-		void moderateVoice(const LLSD& userdata);
-
-		/**
-		 * Mutes/Unmutes avatar for current group voice chat.
-		 *
-		 * It only marks avatar as muted for session and does not use local Agent's Block list.
-		 * It does not mute Agent itself.
-		 *
-		 * @param[in] avatar_id UUID of avatar to be processed
-		 * @param[in] unmute if true - specified avatar will be muted, otherwise - unmuted.
-		 *
-		 * @see moderateVoiceAllParticipants()
-		 */
-		void moderateVoiceParticipant(const LLUUID& avatar_id, bool unmute);
-
-		/**
-		 * Mutes/Unmutes all avatars for current group voice chat.
-		 *
-		 * It only marks avatars as muted for session and does not use local Agent's Block list.
-		 *
-		 * @param[in] unmute if true - avatars will be muted, otherwise - unmuted.
-		 *
-		 * @see moderateVoiceParticipant()
-		 */
-		void moderateVoiceAllParticipants(bool unmute);
-
-		static void confirmMuteAllCallback(const LLSD& notification, const LLSD& response);
-	};
-
-	/**
-	 * Comparator for comparing avatar items by last spoken time
-	 */
-	class LLAvatarItemRecentSpeakerComparator : public LLAvatarItemNameComparator, public LLRefCount
-	{
-		LOG_CLASS(LLAvatarItemRecentSpeakerComparator);
-	public:
-		LLAvatarItemRecentSpeakerComparator(LLParticipantList& parent):mParent(parent){};
-		virtual ~LLAvatarItemRecentSpeakerComparator() {};
-	protected:
-		virtual bool doCompare(const LLAvatarListItem* avatar_item1, const LLAvatarListItem* avatar_item2) const;
-	private:
-		LLParticipantList& mParent;
-	};
-
 private:
-	void onAvatarListDoubleClicked(LLUICtrl* ctrl);
-	void onAvatarListRefreshed(LLUICtrl* ctrl, const LLSD& param);
-
 	void onAvalineCallerFound(const LLUUID& participant_id);
 	void onAvalineCallerRemoved(const LLUUID& participant_id);
 
@@ -251,10 +143,7 @@ class LLParticipantList
 	 */
 	void adjustParticipant(const LLUUID& speaker_id);
 
-	bool isHovered();
-
 	LLSpeakerMgr*		mSpeakerMgr;
-	LLAvatarList*		mAvatarList;
 
 	std::set<LLUUID>	mModeratorList;
 	std::set<LLUUID>	mModeratorToRemoveList;
@@ -262,25 +151,10 @@ class LLParticipantList
 	LLPointer<SpeakerAddListener>				mSpeakerAddListener;
 	LLPointer<SpeakerRemoveListener>			mSpeakerRemoveListener;
 	LLPointer<SpeakerClearListener>				mSpeakerClearListener;
+	LLPointer<SpeakerUpdateListener>	        mSpeakerUpdateListener;
 	LLPointer<SpeakerModeratorUpdateListener>	mSpeakerModeratorListener;
 	LLPointer<SpeakerMuteListener>				mSpeakerMuteListener;
 
-	LLParticipantListMenu*    mParticipantListMenu;
-
-	/**
-	 * This field manages an adding  a new avatar_id in the mAvatarList
-	 * If true, then agent_id wont  be added into mAvatarList
-	 * Also by default this field is controlling a sort procedure, @c sort() 
-	 */
-	bool mExcludeAgent;
-
-	// boost::connections
-	boost::signals2::connection mAvatarListDoubleClickConnection;
-	boost::signals2::connection mAvatarListRefreshConnection;
-	boost::signals2::connection mAvatarListReturnConnection;
-	boost::signals2::connection mAvatarListToggleIconsConnection;
-
-	LLPointer<LLAvatarItemRecentSpeakerComparator> mSortByRecentSpeakers;
 	validate_speaker_callback_t mValidateSpeakerCallback;
 	LLAvalineUpdater* mAvalineUpdater;
 };
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 2dd01e931e097b9c510adfab4af61b63b772401a..c277359133285f460f0000c587b14118ff9dd854 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -108,7 +108,7 @@ class NavMeshStatusResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshStatusResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -130,7 +130,7 @@ class NavMeshResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -151,7 +151,7 @@ class AgentStateResponder : public LLHTTPClient::Responder
 	virtual ~AgentStateResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -170,7 +170,7 @@ class NavMeshRebakeResponder : public LLHTTPClient::Responder
 	virtual ~NavMeshRebakeResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string& pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent);
 
 protected:
 
@@ -190,9 +190,11 @@ class LinksetsResponder
 	virtual ~LinksetsResponder();
 
 	void handleObjectLinksetsResult(const LLSD &pContent);
-	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL);
+	void handleObjectLinksetsError(U32 pStatus, const std::string &pReason, 
+								   const LLSD& pContent, const std::string &pURL);
 	void handleTerrainLinksetsResult(const LLSD &pContent);
-	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL);
+	void handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+									const LLSD& pContent, const std::string &pURL);
 
 protected:
 
@@ -230,7 +232,7 @@ class ObjectLinksetsResponder : public LLHTTPClient::Responder
 	virtual ~ObjectLinksetsResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -250,7 +252,7 @@ class TerrainLinksetsResponder : public LLHTTPClient::Responder
 	virtual ~TerrainLinksetsResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -270,7 +272,7 @@ class CharactersResponder : public LLHTTPClient::Responder
 	virtual ~CharactersResponder();
 
 	virtual void result(const LLSD &pContent);
-	virtual void error(U32 pStatus, const std::string &pReason);
+	virtual void errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent);
 
 protected:
 
@@ -800,9 +802,9 @@ void NavMeshStatusResponder::result(const LLSD &pContent)
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
 
-void NavMeshStatusResponder::error(U32 pStatus, const std::string& pReason)
+void NavMeshStatusResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "NavMeshStatusResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	LLPathfindingNavMeshStatus navMeshStatus(mRegionUUID);
 	LLPathfindingManager::getInstance()->handleNavMeshStatusRequest(navMeshStatus, mRegion, mIsGetStatusOnly);
 }
@@ -828,9 +830,9 @@ void NavMeshResponder::result(const LLSD &pContent)
 	mNavMeshPtr->handleNavMeshResult(pContent, mNavMeshVersion);
 }
 
-void NavMeshResponder::error(U32 pStatus, const std::string& pReason)
+void NavMeshResponder::errorWithContent(U32 pStatus, const std::string& pReason, const LLSD& pContent)
 {
-	mNavMeshPtr->handleNavMeshError(pStatus, pReason, mCapabilityURL, mNavMeshVersion);
+	mNavMeshPtr->handleNavMeshError(pStatus, pReason, pContent, mCapabilityURL, mNavMeshVersion);
 }
 
 //---------------------------------------------------------------------------
@@ -855,9 +857,9 @@ void AgentStateResponder::result(const LLSD &pContent)
 	LLPathfindingManager::getInstance()->handleAgentState(canRebakeRegion);
 }
 
-void AgentStateResponder::error(U32 pStatus, const std::string &pReason)
+void AgentStateResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "AgentStateResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	LLPathfindingManager::getInstance()->handleAgentState(FALSE);
 }
 
@@ -881,9 +883,9 @@ void NavMeshRebakeResponder::result(const LLSD &pContent)
 	mRebakeNavMeshCallback(true);
 }
 
-void NavMeshRebakeResponder::error(U32 pStatus, const std::string &pReason)
+void NavMeshRebakeResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "NavMeshRebakeResponder error [status:" << pStatus << "]: " << pContent << llendl;
 	mRebakeNavMeshCallback(false);
 }
 
@@ -916,9 +918,11 @@ void LinksetsResponder::handleObjectLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL)
+void LinksetsResponder::handleObjectLinksetsError(U32 pStatus, const std::string &pReason,
+												 const LLSD& pContent, const std::string &pURL)
 {
-	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "LinksetsResponder object linksets error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	mObjectMessagingState = kReceivedError;
 	if (mTerrainMessagingState != kWaiting)
 	{
@@ -937,8 +941,11 @@ void LinksetsResponder::handleTerrainLinksetsResult(const LLSD &pContent)
 	}
 }
 
-void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason, const std::string &pURL)
+void LinksetsResponder::handleTerrainLinksetsError(U32 pStatus, const std::string &pReason,
+												   const LLSD& pContent, const std::string &pURL)
 {
+	llwarns << "LinksetsResponder terrain linksets error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	mTerrainMessagingState = kReceivedError;
 	if (mObjectMessagingState != kWaiting)
 	{
@@ -988,9 +995,9 @@ void ObjectLinksetsResponder::result(const LLSD &pContent)
 	mLinksetsResponsderPtr->handleObjectLinksetsResult(pContent);
 }
 
-void ObjectLinksetsResponder::error(U32 pStatus, const std::string &pReason)
+void ObjectLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, mCapabilityURL);
+	mLinksetsResponsderPtr->handleObjectLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
 }
 
 //---------------------------------------------------------------------------
@@ -1013,9 +1020,9 @@ void TerrainLinksetsResponder::result(const LLSD &pContent)
 	mLinksetsResponsderPtr->handleTerrainLinksetsResult(pContent);
 }
 
-void TerrainLinksetsResponder::error(U32 pStatus, const std::string &pReason)
+void TerrainLinksetsResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, mCapabilityURL);
+	mLinksetsResponsderPtr->handleTerrainLinksetsError(pStatus, pReason, pContent, mCapabilityURL);
 }
 
 //---------------------------------------------------------------------------
@@ -1040,9 +1047,9 @@ void CharactersResponder::result(const LLSD &pContent)
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestCompleted, characterListPtr);
 }
 
-void CharactersResponder::error(U32 pStatus, const std::string &pReason)
+void CharactersResponder::errorWithContent(U32 pStatus, const std::string &pReason, const LLSD& pContent)
 {
-	llwarns << "error with request to URL '" << mCapabilityURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "CharactersResponder error [status:" << pStatus << "]: " << pContent << llendl;
 
 	LLPathfindingObjectListPtr characterListPtr =  LLPathfindingObjectListPtr(new LLPathfindingCharacterList());
 	mCharactersCallback(mRequestId, LLPathfindingManager::kRequestError, characterListPtr);
diff --git a/indra/newview/llpathfindingnavmesh.cpp b/indra/newview/llpathfindingnavmesh.cpp
index e01dd3a152f78baf17db8aa69aea42fe29e7ea2d..0c23e5ac923785ae99a64625f321ad6b4af2bf1e 100644
--- a/indra/newview/llpathfindingnavmesh.cpp
+++ b/indra/newview/llpathfindingnavmesh.cpp
@@ -184,9 +184,10 @@ void LLPathfindingNavMesh::handleNavMeshError()
 	setRequestStatus(kNavMeshRequestError);
 }
 
-void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion)
+void LLPathfindingNavMesh::handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion)
 {
-	llwarns << "error with request to URL '" << pURL << "' because " << pReason << " (statusCode:" << pStatus << ")" << llendl;
+	llwarns << "LLPathfindingNavMesh error with request to URL '" << pURL << "' [status:"
+			<< pStatus << "]: " << pContent << llendl;
 	if (mNavMeshStatus.getVersion() == pNavMeshVersion)
 	{
 		handleNavMeshError();
diff --git a/indra/newview/llpathfindingnavmesh.h b/indra/newview/llpathfindingnavmesh.h
index 7a844f54cebf407f6350b8596a7f38e993d02467..b872ccad7cbd24235889a427beb36b512cd2c292 100644
--- a/indra/newview/llpathfindingnavmesh.h
+++ b/indra/newview/llpathfindingnavmesh.h
@@ -74,7 +74,7 @@ class LLPathfindingNavMesh
 	void handleNavMeshResult(const LLSD &pContent, U32 pNavMeshVersion);
 	void handleNavMeshNotEnabled();
 	void handleNavMeshError();
-	void handleNavMeshError(U32 pStatus, const std::string &pReason, const std::string &pURL, U32 pNavMeshVersion);
+	void handleNavMeshError(U32 pStatus, const std::string &pReason, const LLSD& pContent, const std::string &pURL, U32 pNavMeshVersion);
 
 protected:
 
diff --git a/indra/newview/llpathfindingobject.cpp b/indra/newview/llpathfindingobject.cpp
index 858d3203c0c4be8c6079d61e7bb166ac12cd43b5..900763eae479cc9d52878daf483fb5c1feef0724 100644
--- a/indra/newview/llpathfindingobject.cpp
+++ b/indra/newview/llpathfindingobject.cpp
@@ -173,6 +173,7 @@ void LLPathfindingObject::fetchOwnerName()
 		mHasOwnerName = LLAvatarNameCache::get(mOwnerUUID, &mOwnerName);
 		if (!mHasOwnerName)
 		{
+			disconnectAvatarNameCacheConnection();
 			mAvatarNameCacheConnection = LLAvatarNameCache::get(mOwnerUUID, boost::bind(&LLPathfindingObject::handleAvatarNameFetch, this, _1, _2));
 		}
 	}
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..666f10df964ae036a076594ff40117b903704796
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -0,0 +1,149 @@
+/** 
+* @file llpersistentnotificationstorage.cpp
+* @brief Implementation of llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $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 "llpersistentnotificationstorage.h"
+
+#include "llchannelmanager.h"
+#include "llnotificationstorage.h"
+#include "llscreenchannel.h"
+#include "llscriptfloater.h"
+#include "llviewermessage.h"
+
+LLPersistentNotificationStorage::LLPersistentNotificationStorage()
+	: LLSingleton<LLPersistentNotificationStorage>()
+	, LLNotificationStorage(gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, "open_notifications.xml"))
+{
+}
+
+LLPersistentNotificationStorage::~LLPersistentNotificationStorage()
+{
+}
+
+static LLFastTimer::DeclareTimer FTM_SAVE_NOTIFICATIONS("Save Notifications");
+
+void LLPersistentNotificationStorage::saveNotifications()
+{
+	LLFastTimer _(FTM_SAVE_NOTIFICATIONS);
+
+	boost::intrusive_ptr<LLPersistentNotificationChannel> history_channel = boost::dynamic_pointer_cast<LLPersistentNotificationChannel>(LLNotifications::instance().getChannel("Persistent"));
+	if (!history_channel)
+	{
+		return;
+	}
+
+	LLSD output = LLSD::emptyMap();
+	LLSD& data = output["data"];
+
+	for ( std::vector<LLNotificationPtr>::iterator it = history_channel->beginHistory(), end_it = history_channel->endHistory();
+		it != end_it;
+		++it)
+	{
+		LLNotificationPtr notification = *it;
+
+		// After a notification was placed in Persist channel, it can become
+		// responded, expired or canceled - in this case we are should not save it
+		if(notification->isRespondedTo() || notification->isCancelled()
+			|| notification->isExpired())
+		{
+			continue;
+		}
+
+		data.append(notification->asLLSD(true));
+	}
+
+	writeNotifications(output);
+}
+
+static LLFastTimer::DeclareTimer FTM_LOAD_NOTIFICATIONS("Load Notifications");
+
+void LLPersistentNotificationStorage::loadNotifications()
+{
+	LLFastTimer _(FTM_LOAD_NOTIFICATIONS);
+
+	LL_INFOS("LLPersistentNotificationStorage") << "start loading notifications" << LL_ENDL;
+
+	LLNotifications::instance().getChannel("Persistent")->
+		connectChanged(boost::bind(&LLPersistentNotificationStorage::onPersistentChannelChanged, this, _1));
+
+	LLSD input;
+	if (!readNotifications(input) ||input.isUndefined())
+	{
+		return;
+	}
+
+	LLSD& data = input["data"];
+	if (data.isUndefined())
+	{
+		return;
+	}
+
+	using namespace LLNotificationsUI;
+	LLScreenChannel* notification_channel = dynamic_cast<LLScreenChannel*>(LLChannelManager::getInstance()->
+		findChannelByID(LLUUID(gSavedSettings.getString("NotificationChannelUUID"))));
+
+	LLNotifications& instance = LLNotifications::instance();
+
+	for (LLSD::array_const_iterator notification_it = data.beginArray();
+		notification_it != data.endArray();
+		++notification_it)
+	{
+		LLSD notification_params = *notification_it;
+		LLNotificationPtr notification(new LLNotification(notification_params));
+
+		LLNotificationResponderPtr responder(createResponder(notification_params["name"], notification_params["responder"]));
+		notification->setResponseFunctor(responder);
+
+		instance.add(notification);
+
+		// hide script floaters so they don't confuse the user and don't overlap startup toast
+		LLScriptFloaterManager::getInstance()->setFloaterVisible(notification->getID(), false);
+
+		if(notification_channel)
+		{
+			// hide saved toasts so they don't confuse the user
+			notification_channel->hideToast(notification->getID());
+		}
+	}
+
+	LL_INFOS("LLPersistentNotificationStorage") << "finished loading notifications" << LL_ENDL;
+}
+
+bool LLPersistentNotificationStorage::onPersistentChannelChanged(const LLSD& payload)
+{
+	// we ignore "load" messages, but rewrite the persistence file on any other
+	const std::string sigtype = payload["sigtype"].asString();
+	if ("load" != sigtype)
+	{
+		saveNotifications();
+	}
+	return false;
+}
+
+// EOF
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
new file mode 100644
index 0000000000000000000000000000000000000000..98a825d2c139148807cd79a36225703954ad380e
--- /dev/null
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -0,0 +1,63 @@
+/** 
+* @file   llpersistentnotificationstorage.h
+* @brief  Header file for llpersistentnotificationstorage
+* @author Stinson@lindenlab.com
+*
+* $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_LLPERSISTENTNOTIFICATIONSTORAGE_H
+#define LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
+#include "llerror.h"
+#include "llnotificationstorage.h"
+#include "llsingleton.h"
+
+class LLSD;
+
+// Class that saves not responded(unread) notifications.
+// Unread notifications are saved in open_notifications.xml in SL account folder
+//
+// Notifications that should be saved(if unread) are marked with persist="true" in notifications.xml
+// Notifications using functor responders are saved automatically (see llviewermessage.cpp
+// lure_callback_reg for example).
+// Notifications using object responders(LLOfferInfo) need additional tuning. Responder object should
+// be a) serializable(implement LLNotificationResponderInterface),
+// b) registered with LLResponderRegistry (found in llpersistentnotificationstorage.cpp).
+
+class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
+{
+	LOG_CLASS(LLPersistentNotificationStorage);
+public:
+	LLPersistentNotificationStorage();
+	~LLPersistentNotificationStorage();
+
+	void saveNotifications();
+	void loadNotifications();
+
+protected:
+
+private:
+	bool onPersistentChannelChanged(const LLSD& payload);
+};
+
+#endif // LL_LLPERSISTENTNOTIFICATIONSTORAGE_H
+
diff --git a/indra/newview/llphysicsmotion.cpp b/indra/newview/llphysicsmotion.cpp
index cb6989c9dde1c42c7bb8c1d1a084ab36c573b515..3ee0746412f826b37ac211cebc4237bdde72b5a7 100644
--- a/indra/newview/llphysicsmotion.cpp
+++ b/indra/newview/llphysicsmotion.cpp
@@ -166,7 +166,7 @@ class LLPhysicsMotion
 		}
 
         
-        void setParamValue(LLViewerVisualParam *param,
+        void setParamValue(const LLViewerVisualParam *param,
                            const F32 new_value_local,
                                                    F32 behavior_maxeffect);
 
@@ -428,14 +428,13 @@ F32 LLPhysicsMotion::toLocal(const LLVector3 &world)
 F32 LLPhysicsMotion::calculateVelocity_local()
 {
 	const F32 world_to_model_scale = 100.0f;
-        LLJoint *joint = mJointState->getJoint();
-        const LLVector3 position_world = joint->getWorldPosition();
-        const LLQuaternion rotation_world = joint->getWorldRotation();
-        const LLVector3 last_position_world = mPosition_world;
+	LLJoint *joint = mJointState->getJoint();
+	const LLVector3 position_world = joint->getWorldPosition();
+	const LLVector3 last_position_world = mPosition_world;
 	const LLVector3 positionchange_world = (position_world-last_position_world) * world_to_model_scale;
-        const LLVector3 velocity_world = positionchange_world;
-        const F32 velocity_local = toLocal(velocity_world);
-        return velocity_local;
+	const LLVector3 velocity_world = positionchange_world;
+	const F32 velocity_local = toLocal(velocity_world);
+	return velocity_local;
 }
 
 F32 LLPhysicsMotion::calculateAcceleration_local(const F32 velocity_local)
@@ -673,12 +672,10 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
 								 0,
 								 FALSE);
 			}
-			for (LLDriverParam::entry_list_t::iterator iter = driver_param->mDriven.begin();
-			     iter != driver_param->mDriven.end();
-			     ++iter)
+			S32 num_driven = driver_param->getDrivenParamsCount();
+			for (S32 i = 0; i < num_driven; ++i)
 			{
-				LLDrivenEntry &entry = (*iter);
-				LLViewerVisualParam *driven_param = entry.mParam;
+				const LLViewerVisualParam *driven_param = driver_param->getDrivenParam(i);
 				setParamValue(driven_param,position_new_local_clamped, behavior_maxeffect);
 			}
 		}
@@ -758,7 +755,7 @@ BOOL LLPhysicsMotion::onUpdate(F32 time)
 }
 
 // Range of new_value_local is assumed to be [0 , 1] normalized.
-void LLPhysicsMotion::setParamValue(LLViewerVisualParam *param,
+void LLPhysicsMotion::setParamValue(const LLViewerVisualParam *param,
                                     F32 new_value_normalized,
 				    F32 behavior_maxeffect)
 {
diff --git a/indra/newview/llpipelinelistener.cpp b/indra/newview/llpipelinelistener.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..20759239bf5f66663c8b77385d6bc56135b426da
--- /dev/null
+++ b/indra/newview/llpipelinelistener.cpp
@@ -0,0 +1,216 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Implementation for LLPipelineListener
+ * 
+ * $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$
+ */
+
+// Precompiled header
+#include "llviewerprecompiledheaders.h"
+
+#include "llpipelinelistener.h"
+
+#include "pipeline.h"
+#include "stringize.h"
+#include <sstream>
+#include "llviewermenu.h"
+
+
+namespace {
+	// Render Types
+	void toggle_render_types_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["types"].beginArray();
+			iter != request["types"].endArray();
+			++iter)
+		{
+			U32 render_type = render_type_from_string( iter->asString() );
+			if ( render_type != 0 )
+			{
+				LLPipeline::toggleRenderTypeControl( (void*) render_type );
+			}
+		}
+	}
+
+	void has_render_type_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_type = render_type_from_string( request["type"].asString() );
+		if ( render_type != 0 )
+		{
+			response["value"] = LLPipeline::hasRenderTypeControl( (void*) render_type );
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown type '" << request["type"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderTypes();
+	}
+
+	void enable_all_render_types_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderTypes();
+	}
+
+	// Render Features
+	void toggle_render_features_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["features"].beginArray();
+			iter != request["features"].endArray();
+			++iter)
+		{
+			U32 render_feature = feature_from_string( iter->asString() );
+			if ( render_feature != 0 )
+			{
+				LLPipeline::toggleRenderDebugControl( (void*) render_feature );
+			}
+		}
+	}
+
+	void has_render_feature_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 render_feature = feature_from_string( request["feature"].asString() );
+		if ( render_feature != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugFeatureMask(render_feature);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown feature '" << request["feature"].asString() << "'"));
+		}
+	}
+
+	void disable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugFeatures();
+	}
+
+	void enable_all_render_features_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugFeatures();
+	}
+
+	// Render Info Displays
+	void toggle_info_displays_wrapper(LLSD const& request)
+	{
+		for (LLSD::array_const_iterator iter = request["displays"].beginArray();
+			iter != request["displays"].endArray();
+			++iter)
+		{
+			U32 info_display = info_display_from_string( iter->asString() );
+			if ( info_display != 0 )
+			{
+				LLPipeline::toggleRenderDebug( (void*) info_display );
+			}
+		}
+	}
+
+	void has_info_display_wrapper(LLSD const& request)
+	{
+		LLEventAPI::Response response(LLSD(), request);
+		U32 info_display = info_display_from_string( request["display"].asString() );
+		if ( info_display != 0 )
+		{
+			response["value"] = gPipeline.hasRenderDebugMask(info_display);
+		}
+		else
+		{
+			response.error(STRINGIZE("unknown display '" << request["display"].asString() << "'"));
+		}
+	}
+
+	void disable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.clearAllRenderDebugDisplays();
+	}
+
+	void enable_all_info_displays_wrapper(LLSD const& request)
+	{
+		gPipeline.setAllRenderDebugDisplays();
+	}
+
+}
+
+
+LLPipelineListener::LLPipelineListener():
+	LLEventAPI("LLPipeline",
+			   "API to te rendering pipeline.")
+{
+	// Render Types
+	add("toggleRenderTypes",
+		"Toggle rendering [\"types\"]:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&toggle_render_types_wrapper);
+	add("hasRenderType",
+		"Check if rendering [\"type\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_type_from_string for list of available types.",
+		&has_render_type_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderTypes",
+		"Turn off all rendering types.",
+		&disable_all_render_types_wrapper);
+	add("enableAllRenderTypes",
+		"Turn on all rendering types.",
+		&enable_all_render_types_wrapper);
+
+	// Render Features
+	add("toggleRenderFeatures",
+		"Toggle rendering [\"features\"]:\n"
+		"See: llviewermenu.cpp:feature_from_string for list of available features.",
+		&toggle_render_features_wrapper);
+	add("hasRenderFeature",
+		"Check if rendering [\"feature\"] is enabled:\n"
+		"See: llviewermenu.cpp:render_feature_from_string for list of available features.",
+		&has_render_feature_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderFeatures",
+		"Turn off all rendering features.",
+		&disable_all_render_features_wrapper);
+	add("enableAllRenderFeatures",
+		"Turn on all rendering features.",
+		&enable_all_render_features_wrapper);
+
+	// Render Info Displays
+	add("toggleRenderInfoDisplays",
+		"Toggle info [\"displays\"]:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&toggle_info_displays_wrapper);
+	add("hasRenderInfoDisplay",
+		"Check if info [\"display\"] is enabled:\n"
+		"See: llviewermenu.cpp:info_display_from_string for list of available displays.",
+		&has_info_display_wrapper,
+		LLSDMap("reply", LLSD()));
+	add("disableAllRenderInfoDisplays",
+		"Turn off all info displays.",
+		&disable_all_info_displays_wrapper);
+	add("enableAllRenderInfoDisplays",
+		"Turn on all info displays.",
+		&enable_all_info_displays_wrapper);
+}
+
diff --git a/indra/newview/llpipelinelistener.h b/indra/newview/llpipelinelistener.h
new file mode 100644
index 0000000000000000000000000000000000000000..da1898e57b62caed56c36d3268c19ce7fbd38fcd
--- /dev/null
+++ b/indra/newview/llpipelinelistener.h
@@ -0,0 +1,41 @@
+/**
+ * @file   llpipelinelistener.h
+ * @author Don Kjer
+ * @date   2012-07-09
+ * @brief  Wrap subset of LLPipeline API in event API
+ * 
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLPIPELINELISTENER_H)
+#define LL_LLPIPELINELISTENER_H
+
+#include "lleventapi.h"
+
+/// Listen on an LLEventPump with specified name for LLPipeline request events.
+class LLPipelineListener: public LLEventAPI
+{
+public:
+	LLPipelineListener();
+};
+
+#endif /* ! defined(LL_LLPIPELINELISTENER_H) */
diff --git a/indra/newview/llplacesfolderview.cpp b/indra/newview/llplacesfolderview.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..3caa93ae71695d116c5bd4b97f07da71adda0b08
--- /dev/null
+++ b/indra/newview/llplacesfolderview.cpp
@@ -0,0 +1,74 @@
+/** 
+* @file llplacesfolderview.cpp
+* @brief llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $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 "llplacesfolderview.h"
+
+#include "llplacesinventorypanel.h"
+#include "llpanellandmarks.h"
+
+LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
+    : LLFolderView(p)
+{
+    // we do not need auto select functionality in places landmarks, so override default behavior.
+    // this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
+    // Fixed issues: EXT-1631, EXT-4994.
+    mAutoSelectOverride = TRUE;
+}
+
+BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
+{
+    // let children to change selection first
+    childrenHandleRightMouseDown(x, y, mask);
+    mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
+
+    // then determine its type and set necessary menu handle
+    if (getCurSelectedItem())
+    {
+        LLInventoryType::EType inventory_type = static_cast<LLFolderViewModelItemInventory*>(getCurSelectedItem()->getViewModelItem())->getInventoryType();
+        inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
+
+        if (it_handle != mMenuHandlesByInventoryType.end())
+        {
+            mPopupMenuHandle = (*it_handle).second;
+        }
+        else
+        {
+            llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
+        }
+
+    }
+
+    return LLFolderView::handleRightMouseDown(x, y, mask);
+}
+
+void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
+{
+    mMenuHandlesByInventoryType[asset_type] = menu_handle;
+}
+
diff --git a/indra/newview/llplacesfolderview.h b/indra/newview/llplacesfolderview.h
new file mode 100644
index 0000000000000000000000000000000000000000..8c5be39b5e5c92a6840749b824e1dfcec954c0c1
--- /dev/null
+++ b/indra/newview/llplacesfolderview.h
@@ -0,0 +1,72 @@
+/** 
+* @file   llplacesfolderview.h
+* @brief  llplacesfolderview used within llplacesinventorypanel
+* @author Gilbert@lindenlab.com
+*
+* $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_LLPLACESFOLDERVIEW_H
+#define LL_LLPLACESFOLDERVIEW_H
+
+#include "llfolderview.h"
+#include "llinventorypanel.h"
+
+class LLLandmarksPanel;
+
+class LLPlacesFolderView : public LLFolderView
+{
+public:
+
+    struct Params : public LLInitParam::Block<Params, LLFolderView::Params>
+    {
+        Params()
+		{}
+    };
+
+	LLPlacesFolderView(const LLFolderView::Params& p);
+	/**
+	 *	Handles right mouse down
+	 *
+	 * Contains workaround for EXT-2786: sets current selected list for landmark
+	 * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
+	 */
+	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
+
+	void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
+
+	void setParentLandmarksPanel(LLLandmarksPanel* panel)
+	{
+		mParentLandmarksPanel = panel;
+	}
+
+private:
+	/**
+	 * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
+	 */
+	LLLandmarksPanel* mParentLandmarksPanel;
+	typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
+	inventory_type_menu_handle_t mMenuHandlesByInventoryType;
+
+};
+
+#endif // LL_LLPLACESFOLDERVIEW_H
+
diff --git a/indra/newview/llplacesinventorybridge.cpp b/indra/newview/llplacesinventorybridge.cpp
index fe4cc0f55ff5f89a5f93bae0e91d894fd9f806c0..ebd9604c5b3155f0f471d904fd3022cf06cfab03 100644
--- a/indra/newview/llplacesinventorybridge.cpp
+++ b/indra/newview/llplacesinventorybridge.cpp
@@ -85,34 +85,33 @@ void LLPlacesLandmarkBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 
 void LLPlacesFolderBridge::buildContextMenu(LLMenuGL& menu, U32 flags)
 {
+	std::vector<std::string> items;
+	std::vector<std::string> disabled_items;
+
+	LLInventoryPanel* inv_panel = mInventoryPanel.get();
+	bool is_open = false;
+	if (inv_panel)
 	{
-		std::vector<std::string> items;
-		std::vector<std::string> disabled_items;
+		LLFolderViewFolder* folder =  dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
+		is_open = (NULL != folder) && folder->isOpen();
+	}
 
-		LLInventoryPanel* inv_panel = mInventoryPanel.get();
-		bool is_open = false;
-		if (inv_panel)
-		{
-			LLFolderViewFolder* folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
-			is_open = (NULL != folder) && folder->isOpen();
-		}
+	// collect all items' names
+	fill_items_with_menu_items(items, menu);
 
-		// collect all items' names
-		fill_items_with_menu_items(items, menu);
+	// remove expand or collapse menu item depend on folder state
+	std::string collapse_expand_item_to_hide(is_open ? "expand" :  "collapse");
+	std::vector<std::string>::iterator it = std::find(items.begin(),  items.end(), collapse_expand_item_to_hide);
+	if (it != items.end())	items.erase(it);
 
-		// remove expand or collapse menu item depend on folder state
-		std::string collapse_expand_item_to_hide(is_open ? "expand" : "collapse");
-		std::vector<std::string>::iterator it = std::find(items.begin(), items.end(), collapse_expand_item_to_hide);
-		if (it != items.end())	items.erase(it);
 
-		// Disabled items are processed via LLLandmarksPanel::isActionEnabled()
-		// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 
+	// Disabled items are processed via LLLandmarksPanel::isActionEnabled()
+	// they should be synchronized with Places/My Landmarks/Gear menu. See EXT-1601 
 
-		// repeat parent functionality
- 		sSelf = getHandle(); // necessary for "New Folder" functionality
+	// repeat parent functionality
+ 	sSelf = getHandle(); // necessary for "New Folder" functionality
 
-		hide_context_entries(menu, items, disabled_items);
-	}
+	hide_context_entries(menu, items, disabled_items);
 }
 
 //virtual
@@ -140,7 +139,7 @@ LLFolderViewFolder* LLPlacesFolderBridge::getFolder()
 	LLInventoryPanel* inv_panel = mInventoryPanel.get();
 	if (inv_panel)
 	{
-		folder = dynamic_cast<LLFolderViewFolder*>(inv_panel->getRootFolder()->getItemByID(mUUID));
+		folder =    dynamic_cast<LLFolderViewFolder*>(inv_panel->getItemByID(mUUID));
 	}
 
 	return folder;
@@ -152,6 +151,7 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 	LLAssetType::EType actual_asset_type,
 	LLInventoryType::EType inv_type,
 	LLInventoryPanel* inventory,
+	LLFolderViewModelInventory* view_model,
 	LLFolderView* root,
 	const LLUUID& uuid,
 	U32 flags/* = 0x00*/) const
@@ -170,11 +170,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 		if (actual_asset_type == LLAssetType::AT_LINK_FOLDER)
 		{
 			// *TODO: Create a link folder handler instead if it is necessary
-			new_listener = LLInventoryFVBridgeBuilder::createBridge(
+			new_listener = LLInventoryFolderViewModelBuilder::createBridge(
 				asset_type,
 				actual_asset_type,
 				inv_type,
 				inventory,
+				view_model,
 				root,
 				uuid,
 				flags);
@@ -183,11 +184,12 @@ LLInvFVBridge* LLPlacesInventoryBridgeBuilder::createBridge(
 		new_listener = new LLPlacesFolderBridge(inv_type, inventory, root, uuid);
 		break;
 	default:
-		new_listener = LLInventoryFVBridgeBuilder::createBridge(
+		new_listener = LLInventoryFolderViewModelBuilder::createBridge(
 			asset_type,
 			actual_asset_type,
 			inv_type,
 			inventory,
+			view_model,
 			root,
 			uuid,
 			flags);
diff --git a/indra/newview/llplacesinventorybridge.h b/indra/newview/llplacesinventorybridge.h
index 52beacef9cf107a0f21d2e4a4ccc506fa7e797f5..07d18d03c57042fa492467ffab97be3cdd6916f6 100644
--- a/indra/newview/llplacesinventorybridge.h
+++ b/indra/newview/llplacesinventorybridge.h
@@ -82,13 +82,14 @@ class LLPlacesFolderBridge : public LLFolderBridge
  *
  * It builds Bridges for Landmarks and Folders in Places Landmarks Panel
  */
-class LLPlacesInventoryBridgeBuilder : public LLInventoryFVBridgeBuilder
+class LLPlacesInventoryBridgeBuilder : public LLInventoryFolderViewModelBuilder
 {
 public:
 	/*virtual*/ LLInvFVBridge* createBridge(LLAssetType::EType asset_type,
 											LLAssetType::EType actual_asset_type,
 											LLInventoryType::EType inv_type,
 											LLInventoryPanel* inventory,
+											LLFolderViewModelInventory* view_model,
 											LLFolderView* root,
 											const LLUUID& uuid,
 											U32 flags = 0x00) const;
diff --git a/indra/newview/llplacesinventorypanel.cpp b/indra/newview/llplacesinventorypanel.cpp
index f7823f4fe86938cfd3dd91262a7bc28ac0da93f3..4c2213c1982087b4b28394dfac133435ec238e5c 100644
--- a/indra/newview/llplacesinventorypanel.cpp
+++ b/indra/newview/llplacesinventorypanel.cpp
@@ -30,7 +30,8 @@
 
 #include "llplacesinventorypanel.h"
 
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
+#include "llplacesfolderview.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
 #include "llpanellandmarks.h"
@@ -57,44 +58,35 @@ LLPlacesInventoryPanel::~LLPlacesInventoryPanel()
 	delete mSavedFolderState;
 }
 
-void LLPlacesInventoryPanel::buildFolderView(const LLInventoryPanel::Params& params)
-{
-	// Determine the root folder in case specified, and
-	// build the views starting with that folder.
-	const LLFolderType::EType preferred_type = LLViewerFolderType::lookupTypeFromNewCategoryName(params.start_folder);
-
-	LLUUID root_id;
 
-	if ("LIBRARY" == params.start_folder())
-	{
-		root_id = gInventory.getLibraryRootFolderID();
-	}
-	else
-	{
-		root_id = (preferred_type != LLFolderType::FT_NONE ? gInventory.findCategoryUUIDForType(preferred_type) : LLUUID::null);
-	}
-
-	LLRect folder_rect(0,
-		0,
-		getRect().getWidth(),
-		0);
-	LLPlacesFolderView::Params p;
-	p.name = getName();
-	p.title = getLabel();
-	p.rect = folder_rect;
-	p.listener =  mInvFVBridgeBuilder->createBridge(LLAssetType::AT_CATEGORY,
-													LLAssetType::AT_CATEGORY,
-													LLInventoryType::IT_CATEGORY,
-													this,
-													NULL,
-													root_id);
-	p.parent_panel = this;
-	p.allow_multiselect = mAllowMultiSelect;
-	p.use_ellipses = true;	// truncate inventory item text so remove horizontal scroller
-	mFolderRoot = (LLFolderView*)LLUICtrlFactory::create<LLPlacesFolderView>(p);
+LLFolderView * LLPlacesInventoryPanel::createFolderRoot(LLUUID root_id )
+{
+    LLPlacesFolderView::Params p;
+    
+    p.name = getName();
+    p.title = getLabel();
+    p.rect = LLRect(0, 0, getRect().getWidth(), 0);
+    p.parent_panel = this;
+    p.tool_tip = p.name;
+    p.listener = mInvFVBridgeBuilder->createBridge(	LLAssetType::AT_CATEGORY,
+        LLAssetType::AT_CATEGORY,
+        LLInventoryType::IT_CATEGORY,
+        this,
+        &mInventoryViewModel,
+        NULL,
+        root_id);
+    p.view_model = &mInventoryViewModel;
+    p.use_label_suffix = mParams.use_label_suffix;
+    p.allow_multiselect = mAllowMultiSelect;
+    p.show_empty_message = mShowEmptyMessage;
+    p.show_item_link_overlays = mShowItemLinkOverlays;
+    p.root = NULL;
+    p.use_ellipses = mParams.folder_view.use_ellipses;
+    p.options_menu = "menu_inventory.xml";
+
+    return LLUICtrlFactory::create<LLPlacesFolderView>(p);
 }
 
-
 // save current folder open state
 void LLPlacesInventoryPanel::saveFolderState()
 {
@@ -128,59 +120,3 @@ S32	LLPlacesInventoryPanel::notify(const LLSD& info)
 	}
 	return 0;
 }
-
-/************************************************************************/
-/* PROTECTED METHODS                                                    */
-/************************************************************************/
-
-
-
-/************************************************************************/
-/*              LLPlacesFolderView implementation                       */
-/************************************************************************/
-
-//////////////////////////////////////////////////////////////////////////
-//  PUBLIC METHODS
-//////////////////////////////////////////////////////////////////////////
-
-LLPlacesFolderView::LLPlacesFolderView(const LLFolderView::Params& p)
-: LLFolderView(p)
-{
-	// we do not need auto select functionality in places landmarks, so override default behavior.
-	// this disables applying of the LLSelectFirstFilteredItem in LLFolderView::doIdle.
-	// Fixed issues: EXT-1631, EXT-4994.
-	mAutoSelectOverride = TRUE;
-}
-
-BOOL LLPlacesFolderView::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	// let children to change selection first
-	childrenHandleRightMouseDown(x, y, mask);
-	mParentLandmarksPanel->setCurrentSelectedList((LLPlacesInventoryPanel*)getParentPanel());
-
-	// then determine its type and set necessary menu handle
-	if (getCurSelectedItem())
-	{
-		LLInventoryType::EType inventory_type = getCurSelectedItem()->getListener()->getInventoryType();
-		inventory_type_menu_handle_t::iterator it_handle = mMenuHandlesByInventoryType.find(inventory_type);
-
-		if (it_handle != mMenuHandlesByInventoryType.end())
-		{
-			mPopupMenuHandle = (*it_handle).second;
-		}
-		else
-		{
-			llwarns << "Requested menu handle for non-setup inventory type: " << inventory_type << llendl;
-		}
-
-	}
-
-	return LLFolderView::handleRightMouseDown(x, y, mask);
-}
-
-void LLPlacesFolderView::setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle)
-{
-	mMenuHandlesByInventoryType[asset_type] = menu_handle;
-}
-
-// EOF
diff --git a/indra/newview/llplacesinventorypanel.h b/indra/newview/llplacesinventorypanel.h
index f647e7f970e5dc90f9f33b0c8bb00362f6e46f34..2805fc425716c7d4e8f33b9e8187162e35d24635 100644
--- a/indra/newview/llplacesinventorypanel.h
+++ b/indra/newview/llplacesinventorypanel.h
@@ -29,9 +29,9 @@
 
 #include "llfloaterinventory.h"
 #include "llinventorypanel.h"
-#include "llfolderview.h"
 
 class LLLandmarksPanel;
+class LLFolderView;
 
 class LLPlacesInventoryPanel : public LLInventoryPanel
 {
@@ -46,8 +46,7 @@ class LLPlacesInventoryPanel : public LLInventoryPanel
 	LLPlacesInventoryPanel(const Params& p);
 	~LLPlacesInventoryPanel();
 
-	/*virtual*/ void buildFolderView(const LLInventoryPanel::Params& params);
-
+    LLFolderView * createFolderRoot(LLUUID root_id );
 	void saveFolderState();
 	void restoreFolderState();
 
@@ -57,36 +56,4 @@ class LLPlacesInventoryPanel : public LLInventoryPanel
 	LLSaveFolderState*			mSavedFolderState;
 };
 
-
-class LLPlacesFolderView : public LLFolderView
-{
-public:
-	LLPlacesFolderView(const LLFolderView::Params& p);
-	/**
-	 *	Handles right mouse down
-	 *
-	 * Contains workaround for EXT-2786: sets current selected list for landmark
-	 * panel using @c mParentLandmarksPanel which is set in @c LLLandmarksPanel::initLandmarksPanel
-	 */
-	/*virtual*/ BOOL handleRightMouseDown( S32 x, S32 y, MASK mask );
-
-	void setupMenuHandle(LLInventoryType::EType asset_type, LLHandle<LLView> menu_handle);
-
-	void setParentLandmarksPanel(LLLandmarksPanel* panel)
-	{
-		mParentLandmarksPanel = panel;
-	}
-
-	S32 getSelectedCount() { return (S32)mSelectedItems.size(); }
-
-private:
-	/**
-	 * holds pointer to landmark panel. This pointer is used in @c LLPlacesFolderView::handleRightMouseDown
-	 */
-	LLLandmarksPanel* mParentLandmarksPanel;
-	typedef std::map<LLInventoryType::EType, LLHandle<LLView> > inventory_type_menu_handle_t;
-	inventory_type_menu_handle_t mMenuHandlesByInventoryType;
-
-};
-
 #endif //LL_LLINVENTORYSUBTREEPANEL_H
diff --git a/indra/newview/llpostcard.cpp b/indra/newview/llpostcard.cpp
index 4f2d6da7e593be9494fb66b07e9139358e386b0e..aebe636f5994e093fcacd4d2b1316641daf02e01 100644
--- a/indra/newview/llpostcard.cpp
+++ b/indra/newview/llpostcard.cpp
@@ -35,6 +35,7 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "llassetstorage.h"
 #include "llassetuploadresponders.h"
 
 ///////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 9c25e69db006b15297970ad54fe84ce4e63fadd0..968a912ea28c51825c51bddd1df00b3bf27618fd 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -305,7 +305,11 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
 {
 	if (mEditorCore)
 	{
-		return mEditorCore->handleKeyHere(key, mask);
+		BOOL handled = mEditorCore->handleKeyHere(key, mask);
+		if (!handled)
+		{
+			LLFloater::handleKeyHere(key, mask);
+		}
 	}
 
 	return FALSE;
diff --git a/indra/newview/llpreviewtexture.cpp b/indra/newview/llpreviewtexture.cpp
index 3ff5a05d81e7b7a3a12246b19d879a56307af28b..91a98792eb56b3dd0e529db8c3dce9e9d1e4d916 100644
--- a/indra/newview/llpreviewtexture.cpp
+++ b/indra/newview/llpreviewtexture.cpp
@@ -70,7 +70,7 @@ LLPreviewTexture::LLPreviewTexture(const LLSD& key)
 	  mAspectRatio(0.f),
 	  mPreviewToSave(FALSE),
 	  mImage(NULL),
-	  mImageOldBoostLevel(LLViewerTexture::BOOST_NONE)
+	  mImageOldBoostLevel(LLGLTexture::BOOST_NONE)
 {
 	updateImageID();
 	if (key.has("save_as"))
@@ -468,9 +468,9 @@ void LLPreviewTexture::onAspectRatioCommit(LLUICtrl* ctrl, void* userdata)
 
 void LLPreviewTexture::loadAsset()
 {
-	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mImage = LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	mImageOldBoostLevel = mImage->getBoostLevel();
-	mImage->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+	mImage->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 	mImage->forceToSaveRawImage(0) ;
 	mAssetStatus = PREVIEW_ASSET_LOADING;
 	mUpdateDimensions = TRUE;
diff --git a/indra/newview/llproductinforequest.cpp b/indra/newview/llproductinforequest.cpp
index 93bf8b232898eb62540da8de050c8eb1e2fcaf1a..1390000fc506eb1bbba570224824e0283f52fe64 100644
--- a/indra/newview/llproductinforequest.cpp
+++ b/indra/newview/llproductinforequest.cpp
@@ -43,10 +43,10 @@ class LLProductInfoRequestResponder : public LLHTTPClient::Responder
 	}
 
 	//If we get back an error (not found, etc...), handle it here
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		llwarns << "LLProductInfoRequest::error("
-		<< status << ": " << reason << ")" << llendl;
+		llwarns << "LLProductInfoRequest error [status:"
+				<< status << ":] " << content << llendl;
 	}
 };
 
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index f86e583b9e23ccf8543e4181f5e5636840465aca..989f0b0e6056a4cc7448a1f73d10dc74cdc732cc 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -96,7 +96,7 @@ BOOL LLProgressView::postBuild()
 	getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage, this);
 
 	// hidden initially, until we need it
-	LLPanel::setVisible(FALSE);
+	setVisible(FALSE);
 
 	LLNotifications::instance().getChannel("AlertModal")->connectChanged(boost::bind(&LLProgressView::onAlertModal, this, _1));
 
@@ -265,7 +265,7 @@ void LLProgressView::draw()
 			gFocusMgr.releaseFocusIfNeeded( this );
 
 			// turn off panel that hosts intro so we see the world
-			LLPanel::setVisible(FALSE);
+			setVisible(FALSE);
 
 			// stop observing events since we no longer care
 			mMediaCtrl->remObserver( this );
diff --git a/indra/newview/llregioninfomodel.cpp b/indra/newview/llregioninfomodel.cpp
index 698c4f9bb93833a084e40903dba5933a715e42a8..590e24648238644d0a5db6c7c3cdee467daa218a 100644
--- a/indra/newview/llregioninfomodel.cpp
+++ b/indra/newview/llregioninfomodel.cpp
@@ -119,7 +119,7 @@ void LLRegionInfoModel::sendRegionTerrain(const LLUUID& invoice) const
 
 bool LLRegionInfoModel::getUseFixedSun() const
 {
-	return mRegionFlags & REGION_FLAGS_SUN_FIXED;
+	return ((mRegionFlags & REGION_FLAGS_SUN_FIXED) != 0);
 }
 
 void LLRegionInfoModel::setUseFixedSun(bool fixed)
@@ -141,7 +141,6 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getStringFast(_PREHASH_RegionInfo, _PREHASH_SimName, mSimName);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_EstateID, mEstateID);
 	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_ParentEstateID, mParentEstateID);
-	msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, mRegionFlags);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_SimAccess, mSimAccess);
 	msg->getU8Fast(_PREHASH_RegionInfo, _PREHASH_MaxAgents, mAgentLimit);
 	msg->getF32Fast(_PREHASH_RegionInfo, _PREHASH_ObjectBonusFactor, mObjectBonusFactor);
@@ -159,6 +158,17 @@ void LLRegionInfoModel::update(LLMessageSystem* msg)
 	msg->getF32(_PREHASH_RegionInfo, _PREHASH_SunHour, mSunHour);
 	LL_DEBUGS("Windlight Sync") << "Got region sun hour: " << mSunHour << LL_ENDL;
 
+	if (msg->has(_PREHASH_RegionInfo3))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo3, _PREHASH_RegionFlagsExtended, mRegionFlags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		mRegionFlags = flags;
+	}
+
 	// the only reasonable way to decide if we actually have any data is to
 	// check to see if any of these fields have nonzero sizes
 	if (msg->getSize(_PREHASH_RegionInfo2, _PREHASH_ProductSKU) > 0 ||
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index 89efd827674980814e915f9416ca5894afca2f62..d22a0de4635bfd14abd5e7f862aeb86073fd26aa 100644
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -52,7 +52,7 @@ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel>
 	U8			mSimAccess;
 	U8			mAgentLimit;
 
-	U32			mRegionFlags;
+	U64			mRegionFlags;
 	U32			mEstateID;
 	U32			mParentEstateID;
 
diff --git a/indra/newview/llremoteparcelrequest.cpp b/indra/newview/llremoteparcelrequest.cpp
index 3862dac340d0db44d3ed0411a56c7cbee3a4ac01..500dec7ee5841878bfbddb2857f9a590c6b847b9 100644
--- a/indra/newview/llremoteparcelrequest.cpp
+++ b/indra/newview/llremoteparcelrequest.cpp
@@ -62,10 +62,10 @@ void LLRemoteParcelRequestResponder::result(const LLSD& content)
 
 //If we get back an error (not found, etc...), handle it here
 //virtual
-void LLRemoteParcelRequestResponder::error(U32 status, const std::string& reason)
+void LLRemoteParcelRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llinfos << "LLRemoteParcelRequest::error("
-		<< status << ": " << reason << ")" << llendl;
+	llwarns << "LLRemoteParcelRequest error [status:"
+			<< status << "]: " << content << llendl;
 
 	// Panel inspecting the information may be closed and destroyed
 	// before this response is received.
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index 74cf1616dfada4296020107f8eedcbc79c290b03..b87056573b1bfea0ea4753f9a220b57b83b11763 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -44,7 +44,7 @@ class LLRemoteParcelRequestResponder : public LLHTTPClient::Responder
 	/*virtual*/ void result(const LLSD& content);
 
 	//If we get back an error (not found, etc...), handle it here
-	/*virtual*/ void error(U32 status, const std::string& reason);
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 protected:
 	LLHandle<LLRemoteParcelInfoObserver> mObserverHandle;
diff --git a/indra/newview/llsaveoutfitcombobtn.cpp b/indra/newview/llsaveoutfitcombobtn.cpp
index cbad85cfd3f794a23a38e7a5101f2f8b2f32bd46..32295cd96f29b3c5acf352b8accb1e571b4579fa 100644
--- a/indra/newview/llsaveoutfitcombobtn.cpp
+++ b/indra/newview/llsaveoutfitcombobtn.cpp
@@ -76,8 +76,8 @@ void LLSaveOutfitComboBtn::saveOutfit(bool as_new)
 	if (panel_outfits_inventory)
 	{
 		panel_outfits_inventory->onSave();
-	}
-
+	} 	
+    
 	//*TODO how to get to know when base outfit is updated or new outfit is created?
 }
 
diff --git a/indra/newview/llscreenchannel.cpp b/indra/newview/llscreenchannel.cpp
index d2280ea0890fae7fb0b7259565ff7d69a921862f..168a941ec379fe10092caa913a4c5bfbafafe202 100644
--- a/indra/newview/llscreenchannel.cpp
+++ b/indra/newview/llscreenchannel.cpp
@@ -39,7 +39,7 @@
 
 #include "lldockablefloater.h"
 #include "llsyswellwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llscriptfloater.h"
 #include "llrootview.h"
 
@@ -253,12 +253,26 @@ void LLScreenChannel::addToast(const LLToast::Params& p)
 {
 	bool store_toast = false, show_toast = false;
 
-	mDisplayToastsAlways ? show_toast = true : show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+	if (mDisplayToastsAlways)
+	{
+		show_toast = true;
+	}
+	else
+	{
+		show_toast = mWasStartUpToastShown && (mShowToasts || p.force_show);
+	}
 	store_toast = !show_toast && p.can_be_stored && mCanStoreToasts;
 
 	if(!show_toast && !store_toast)
 	{
-		mRejectToastSignal(p.notif_id);
+		LLNotificationPtr notification = LLNotifications::instance().find(p.notif_id);
+
+		if (notification &&
+			(!notification->canLogToIM() || !notification->hasFormElements()))
+		{
+			// only cancel notification if it isn't being used in IM session
+			LLNotifications::instance().cancel(notification);
+		}
 		return;
 	}
 
@@ -371,7 +385,7 @@ void LLScreenChannel::storeToast(ToastElem& toast_elem)
 	const LLToast* toast = toast_elem.getToast();
 	if (toast)
 	{
-		mStoredToastList.push_back(toast_elem);
+	mStoredToastList.push_back(toast_elem);
 		mOnStoreToast(toast->getPanel(), toast->getNotificationID());
 	}
 }
@@ -410,49 +424,27 @@ void LLScreenChannel::loadStoredToastByNotificationIDToChannel(LLUUID id)
 	LLToast* toast = it->getToast();
 	if (toast)
 	{
-		if(toast->getVisible())
-		{
-			// toast is already in channel
-			return;
-		}
+	if(toast->getVisible())
+	{
+		// toast is already in channel
+		return;
+	}
 
-		toast->setIsHidden(false);
-		toast->startTimer();
+	toast->setIsHidden(false);
+	toast->startTimer();
 		mToastList.push_back(*it);
 	}
 
 	redrawToasts();
 }
 
-//--------------------------------------------------------------------------
-void LLScreenChannel::removeStoredToastByNotificationID(LLUUID id)
-{
-	// *TODO: may be remove this function
-	std::vector<ToastElem>::iterator it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
-	if( it == mStoredToastList.end() )
-		return;
-
-	const LLToast* toast = it->getToast();
-	if (toast)
-	{
-		mRejectToastSignal(toast->getNotificationID());
-	}
-
-	// Call find() once more, because the mStoredToastList could have been changed
-	// in mRejectToastSignal callback and the iterator could have become invalid.
-	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-	if (it != mStoredToastList.end())
-	{
-		mStoredToastList.erase(it);
-	}
-}
-
 //--------------------------------------------------------------------------
 void LLScreenChannel::killToastByNotificationID(LLUUID id)
 {
 	// searching among toasts on a screen
 	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+	LLNotificationPtr notification = LLNotifications::instance().find(id);
+	if (!notification) return;
 	
 	if( it != mToastList.end())
 	{
@@ -465,42 +457,67 @@ void LLScreenChannel::killToastByNotificationID(LLUUID id)
 		//			the toast will be destroyed.
 		if(toast && toast->isNotificationValid())
 		{
-			mRejectToastSignal(toast->getNotificationID());
+			if (!notification->canLogToIM() || !notification->hasFormElements())
+			{
+				// only cancel notification if it isn't being used in IM session
+				LLNotifications::instance().cancel(notification);
+			}
 		}
 		else
 		{
-
-			deleteToast(toast);
-			mToastList.erase(it);
-			redrawToasts();
+			removeToastByNotificationID(id);
 		}
-		return;
 	}
-
-	// searching among stored toasts
-	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
-
-	if (it != mStoredToastList.end())
+	else
 	{
-		LLToast* toast = it->getToast();
-		if (toast)
+		// searching among stored toasts
+		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+
+		if( it != mStoredToastList.end() )
 		{
-			// send signal to a listener to let him perform some action on toast rejecting
-			mRejectToastSignal(toast->getNotificationID());
-			deleteToast(toast);
+			LLToast* toast = it->getToast();
+			if (toast)
+			{
+				if (!notification->canLogToIM() || !notification->hasFormElements())
+				{
+					// only cancel notification if it isn't being used in IM session
+					LLNotifications::instance().cancel(notification);
+				}
+				deleteToast(toast);
+			}
+		}
+	
+		// Call find() once more, because the mStoredToastList could have been changed
+		// via notification cancellation and the iterator could have become invalid.
+		it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
+		if (it != mStoredToastList.end())
+		{
+			mStoredToastList.erase(it);
 		}
 	}
+}
+
+void LLScreenChannel::removeToastByNotificationID(LLUUID id)
+{
+	std::vector<ToastElem>::iterator it = find(mToastList.begin(), mToastList.end(), id);
+	while( it != mToastList.end())
+	{
+		deleteToast(it->getToast());
+		mToastList.erase(it);
+		redrawToasts();
+		// find next toast with matching id
+		it = find(mToastList.begin(), mToastList.end(), id);
+	}
 
-	// Call find() once more, because the mStoredToastList could have been changed
-	// in mRejectToastSignal callback and the iterator could have become invalid.
 	it = find(mStoredToastList.begin(), mStoredToastList.end(), id);
 	if (it != mStoredToastList.end())
 	{
+		deleteToast(it->getToast());
 		mStoredToastList.erase(it);
 	}
-
 }
 
+
 void LLScreenChannel::killMatchedToasts(const Matcher& matcher)
 {
 	std::list<const LLToast*> to_delete = findToasts(matcher);
@@ -521,11 +538,11 @@ void LLScreenChannel::modifyToastByNotificationID(LLUUID id, LLPanel* panel)
 		LLToast* toast = it->getToast();
 		if (toast)
 		{
-			LLPanel* old_panel = toast->getPanel();
-			toast->removeChild(old_panel);
-			delete old_panel;
-			toast->insertPanel(panel);
-			toast->startTimer();
+		LLPanel* old_panel = toast->getPanel();
+		toast->removeChild(old_panel);
+		delete old_panel;
+		toast->insertPanel(panel);
+		toast->startTimer();
 		}
 		redrawToasts();
 	}
@@ -685,7 +702,7 @@ void LLScreenChannel::showToastsCentre()
 		return;
 	}
 
-	LLRect	toast_rect;
+	LLRect	toast_rect;	
 	S32		bottom = (getRect().mTop - getRect().mBottom)/2 + toast->getRect().getHeight()/2;
 	std::vector<ToastElem>::reverse_iterator it;
 
@@ -713,7 +730,6 @@ void LLScreenChannel::showToastsTop()
 
 	LLRect	toast_rect;	
 	S32		top = channel_rect.mTop;
-	S32		toast_margin = 0;
 	std::vector<ToastElem>::reverse_iterator it;
 
 	updateRect();
@@ -736,7 +752,7 @@ void LLScreenChannel::showToastsTop()
 			}
 
 			top = toast->getRect().mBottom - toast->getTopPad();
-			toast_margin = gSavedSettings.getS32("ToastGap");
+			gSavedSettings.getS32("ToastGap");
 		}
 
 		LLToast* toast = it->getToast();
diff --git a/indra/newview/llscreenchannel.h b/indra/newview/llscreenchannel.h
index 56a9cf8b4ba6f8ced608745b9350f81009dafc7f..e5f4807ab7ca5131599d47da28a3a4cce2e51a7f 100644
--- a/indra/newview/llscreenchannel.h
+++ b/indra/newview/llscreenchannel.h
@@ -84,6 +84,7 @@ class LLScreenChannelBase : public LLUICtrl
 	// kill or modify a toast by its ID
 	virtual void		killToastByNotificationID(LLUUID id) {};
 	virtual void		modifyToastNotificationByID(LLUUID id, LLSD data) {};
+	virtual void		removeToastByNotificationID(LLUUID id){};
 	
 	// hide all toasts from screen, but not remove them from a channel
 	virtual void		hideToastsFromScreen() {};
@@ -175,6 +176,7 @@ class LLScreenChannel : public LLScreenChannelBase
 	void		addToast(const LLToast::Params& p);
 	// kill or modify a toast by its ID
 	void		killToastByNotificationID(LLUUID id);
+	void		removeToastByNotificationID(LLUUID id);
 	void		killMatchedToasts(const Matcher& matcher);
 	void		modifyToastByNotificationID(LLUUID id, LLPanel* panel);
 	// hide all toasts from screen, but not remove them from a channel
@@ -195,8 +197,6 @@ class LLScreenChannel : public LLScreenChannelBase
 	void		loadStoredToastsToChannel();
 	// finds a toast among stored by its Notification ID and throws it on a screen to a channel
 	void		loadStoredToastByNotificationIDToChannel(LLUUID id);
-	// removes a toast from stored finding it by its Notification ID 
-	void		removeStoredToastByNotificationID(LLUUID id);
 	// removes from channel all toasts that belongs to the certain IM session 
 	void		removeToastsBySessionID(LLUUID id);
 	// remove all storable toasts from screen and store them
@@ -227,16 +227,12 @@ class LLScreenChannel : public LLScreenChannelBase
 
 	// Channel's signals
 	// signal on storing of faded toasts event
-	typedef boost::function<void (LLPanel* info_panel, const LLUUID id)> store_tost_callback_t;
-	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_tost_signal_t;
-	store_tost_signal_t mOnStoreToast;	
-	boost::signals2::connection setOnStoreToastCallback(store_tost_callback_t cb) { return mOnStoreToast.connect(cb); }
-	// signal on rejecting of a toast event
-	typedef boost::function<void (LLUUID id)> reject_tost_callback_t;
-	typedef boost::signals2::signal<void (LLUUID id)> reject_tost_signal_t;
-	reject_tost_signal_t mRejectToastSignal; boost::signals2::connection setOnRejectToastCallback(reject_tost_callback_t cb) { return mRejectToastSignal.connect(cb); }
+	typedef boost::signals2::signal<void (LLPanel* info_panel, const LLUUID id)> store_toast_signal_t;
+	boost::signals2::connection addOnStoreToastCallback(store_toast_signal_t::slot_type cb) { return mOnStoreToast.connect(cb); }
 
 private:
+	store_toast_signal_t mOnStoreToast;	
+
 	class ToastElem
 	{
 	public:
diff --git a/indra/newview/llscriptfloater.cpp b/indra/newview/llscriptfloater.cpp
index 6f98be1cb8763f89d2fbb2c982ab2a7766da1586..0e0da6bdc7221d67d06758a617da707d6ff5da4a 100644
--- a/indra/newview/llscriptfloater.cpp
+++ b/indra/newview/llscriptfloater.cpp
@@ -41,7 +41,7 @@
 #include "lltoastscripttextbox.h"
 #include "lltrans.h"
 #include "llviewerwindow.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 
 //////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////
@@ -95,7 +95,12 @@ bool LLScriptFloater::toggle(const LLUUID& notification_id)
 		show(notification_id);
 	}
 
-	LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(notification_id, true);
+	LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+	if (NULL != chiclet_panelp)
+	{
+		chiclet_panelp->setChicletToggleState(notification_id, true);
+	}
+
 	return true;
 }
 
@@ -206,10 +211,14 @@ void LLScriptFloater::setVisible(BOOL visible)
 
 	if(!visible)
 	{
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
-		if(chiclet)
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			chiclet->setToggleState(false);
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+			if(NULL != chicletp)
+			{
+				chicletp->setToggleState(false);
+			}
 		}
 	}
 }
@@ -218,15 +227,19 @@ void LLScriptFloater::onMouseDown()
 {
 	if(getNotificationId().notNull())
 	{
-		// Remove new message icon
-		LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(getNotificationId());
-		if (chiclet == NULL)
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
-		}
-		else
-		{
-			chiclet->setShowNewMessagesIcon(false);
+			LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(getNotificationId());
+			// Remove new message icon
+			if (NULL == chicletp)
+			{
+				llerror("Dock chiclet for LLScriptFloater doesn't exist", 0);
+			}
+			else
+			{
+				chicletp->setShowNewMessagesIcon(false);
+			}
 		}
 	}
 }
@@ -262,7 +275,11 @@ void LLScriptFloater::onFocusLost()
 {
 	if(getNotificationId().notNull())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), false);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->setChicletToggleState(getNotificationId(), false);
+		}
 	}
 }
 
@@ -271,7 +288,11 @@ void LLScriptFloater::onFocusReceived()
 	// first focus will be received before setObjectId() call - don't toggle chiclet
 	if(getNotificationId().notNull())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->setChicletToggleState(getNotificationId(), true);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->setChicletToggleState(getNotificationId(), true);
+		}
 	}
 }
 
@@ -279,28 +300,30 @@ void LLScriptFloater::dockToChiclet(bool dock)
 {
 	if (getDockControl() == NULL)
 	{
-		LLChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLChiclet>(getNotificationId());
-		if (chiclet == NULL)
-		{
-			llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
-			return;
-		}
-		else
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
 		{
-			LLChicletBar::getInstance()->getChicletPanel()->scrollToChiclet(chiclet);
-		}
+			LLChiclet * chicletp = chiclet_panelp->findChiclet<LLChiclet>(getNotificationId());
+			if (NULL == chicletp)
+			{
+				llwarns << "Dock chiclet for LLScriptFloater doesn't exist" << llendl;
+				return;
+			}
 
-		// Stop saving position while we dock floater
-		bool save = getSavePosition();
-		setSavePosition(false);
+			chiclet_panelp->scrollToChiclet(chicletp);
 
-		setDockControl(new LLDockControl(chiclet, this, getDockTongue(),
-			LLDockControl::BOTTOM));
+			// Stop saving position while we dock floater
+			bool save = getSavePosition();
+			setSavePosition(false);
 
-		setDocked(dock);
+			setDockControl(new LLDockControl(chicletp, this, getDockTongue(),
+				LLDockControl::BOTTOM));
 
-		// Restore saving
-		setSavePosition(save);
+			setDocked(dock);
+
+			// Restore saving
+			setSavePosition(save);
+		}
 	}
 }
 
@@ -347,11 +370,15 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
 		script_notification_map_t::const_iterator it = findUsingObjectId(object_id);
 		if(it != mNotifications.end())
 		{
-			LLIMChiclet* chiclet = LLChicletBar::getInstance()->getChicletPanel()->findChiclet<LLIMChiclet>(it->first);
-			if(chiclet)
+			LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+			if (NULL != chiclet_panelp)
 			{
-				// Pass the new_message icon state further.
-				set_new_message = chiclet->getShowNewMessagesIcon();
+				LLIMChiclet * chicletp = chiclet_panelp->findChiclet<LLIMChiclet>(it->first);
+				if(NULL != chicletp)
+				{
+					// Pass the new_message icon state further.
+					set_new_message = chicletp->getShowNewMessagesIcon();
+				}
 			}
 
 			LLScriptFloater* floater = LLFloaterReg::findTypedInstance<LLScriptFloater>("script_floater", it->first);
@@ -367,14 +394,18 @@ void LLScriptFloaterManager::onAddNotification(const LLUUID& notification_id)
 
 	mNotifications.insert(std::make_pair(notification_id, object_id));
 
-	// Create inventory offer chiclet for offer type notifications
-	if( OBJ_GIVE_INVENTORY == obj_type )
+	LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+	if (NULL != chiclet_panelp)
 	{
-		LLChicletBar::instance().getChicletPanel()->createChiclet<LLInvOfferChiclet>(notification_id);
-	}
-	else
-	{
-		LLChicletBar::getInstance()->getChicletPanel()->createChiclet<LLScriptChiclet>(notification_id);
+		// Create inventory offer chiclet for offer type notifications
+		if( OBJ_GIVE_INVENTORY == obj_type )
+		{
+			chiclet_panelp->createChiclet<LLInvOfferChiclet>(notification_id);
+		}
+		else
+		{
+			chiclet_panelp->createChiclet<LLScriptChiclet>(notification_id);
+		}
 	}
 
 	LLIMWellWindow::getInstance()->addObjectRow(notification_id, set_new_message);
@@ -410,7 +441,11 @@ void LLScriptFloaterManager::onRemoveNotification(const LLUUID& notification_id)
 	// remove related chiclet
 	if (LLChicletBar::instanceExists())
 	{
-		LLChicletBar::getInstance()->getChicletPanel()->removeChiclet(notification_id);
+		LLChicletPanel * chiclet_panelp = LLChicletBar::getInstance()->getChicletPanel();
+		if (NULL != chiclet_panelp)
+		{
+			chiclet_panelp->removeChiclet(notification_id);
+		}
 	}
 
 	LLIMWellWindow* im_well_window = LLIMWellWindow::findInstance();
diff --git a/indra/newview/llscrollingpanelparam.cpp b/indra/newview/llscrollingpanelparam.cpp
index 05b82ba967e3dfda182491e45553b80da7d32c42..a7e24b86b13e765fb727e29e766ee0044cb1b759 100644
--- a/indra/newview/llscrollingpanelparam.cpp
+++ b/indra/newview/llscrollingpanelparam.cpp
@@ -267,7 +267,7 @@ void LLScrollingPanelParam::onHintHeldDown( LLVisualParamHint* hint )
 				&& new_percent < slider->getMaxValue())
 			{
 				mWearable->setVisualParamWeight( hint->getVisualParam()->getID(), new_weight, FALSE);
-				mWearable->writeToAvatar();
+				mWearable->writeToAvatar(gAgentAvatarp);
 				gAgentAvatarp->updateVisualParams();
 
 				slider->setValue( weightToPercent( new_weight ) );
@@ -300,7 +300,7 @@ void LLScrollingPanelParam::onHintMinMouseUp( void* userdata )
 				&& new_percent < slider->getMaxValue())
 			{
 				self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
-				self->mWearable->writeToAvatar();
+				self->mWearable->writeToAvatar(gAgentAvatarp);
 				slider->setValue( self->weightToPercent( new_weight ) );
 			}
 		}
@@ -334,7 +334,7 @@ void LLScrollingPanelParam::onHintMaxMouseUp( void* userdata )
 					&& new_percent < slider->getMaxValue())
 				{
 					self->mWearable->setVisualParamWeight(hint->getVisualParam()->getID(), new_weight, FALSE);
-					self->mWearable->writeToAvatar();
+					self->mWearable->writeToAvatar(gAgentAvatarp);
 					slider->setValue( self->weightToPercent( new_weight ) );
 				}
 			}
diff --git a/indra/newview/llscrollingpanelparambase.cpp b/indra/newview/llscrollingpanelparambase.cpp
index 62e3039d2fe67ea1f2183395b18bfbd17ae13af3..8e083ddb6c8ff60d466f01d8e72f2d3ee1c96f0f 100644
--- a/indra/newview/llscrollingpanelparambase.cpp
+++ b/indra/newview/llscrollingpanelparambase.cpp
@@ -94,7 +94,7 @@ void LLScrollingPanelParamBase::onSliderMoved(LLUICtrl* ctrl, void* userdata)
 	if (current_weight != new_weight )
 	{
 		self->mWearable->setVisualParamWeight( param->getID(), new_weight, FALSE );
-		self->mWearable->writeToAvatar();
+		self->mWearable->writeToAvatar(gAgentAvatarp);
 		gAgentAvatarp->updateVisualParams();
 	}
 }
diff --git a/indra/newview/llsechandler_basic.cpp b/indra/newview/llsechandler_basic.cpp
index 30400a4c6a6b7d44a616ca8c33ae0414a3f32627..928d26646b2b777f5e45213117ddb425f6f324da 100644
--- a/indra/newview/llsechandler_basic.cpp
+++ b/indra/newview/llsechandler_basic.cpp
@@ -1239,7 +1239,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
 									llifstream::binary);
 
 	if (!protected_data_stream.fail()) {
-		int offset;
 		U8 salt[STORE_SALT_SIZE];
 		U8 buffer[BUFFER_READ_SIZE];
 		U8 decrypted_buffer[BUFFER_READ_SIZE];
@@ -1250,7 +1249,6 @@ void LLSecAPIBasicHandler::_readProtectedData()
 
 		// read in the salt and key
 		protected_data_stream.read((char *)salt, STORE_SALT_SIZE);
-		offset = 0;
 		if (protected_data_stream.gcount() < STORE_SALT_SIZE)
 		{
 			throw LLProtectedDataException("Config file too short.");
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index 343316d30a79349370a401a6464928f52137b736..4681efd3e5901335ca04f36ce61ac7d1ef1b8d38 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1180,7 +1180,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
 	if (mGridMode == GRID_MODE_LOCAL && mSelectedObjects->getObjectCount())
 	{
 		//LLViewerObject* root = getSelectedParentObject(mSelectedObjects->getFirstObject());
-		LLBBox bbox = mSavedSelectionBBox;
 		mGridOrigin = mSavedSelectionBBox.getCenterAgent();
 		mGridScale = mSavedSelectionBBox.getExtentLocal() * 0.5f;
 
@@ -1198,7 +1197,6 @@ void LLSelectMgr::getGrid(LLVector3& origin, LLQuaternion &rotation, LLVector3 &
 	else if (mGridMode == GRID_MODE_REF_OBJECT && first_grid_object && first_grid_object->mDrawable.notNull())
 	{
 		mGridRotation = first_grid_object->getRenderRotation();
-		LLVector3 first_grid_obj_pos = first_grid_object->getRenderPosition();
 
 		LLVector4a min_extents(F32_MAX);
 		LLVector4a max_extents(-F32_MAX);
@@ -1605,7 +1603,7 @@ void LLSelectMgr::selectionSetImage(const LLUUID& imageid)
 				// Texture picker defaults aren't inventory items
 				// * Don't need to worry about permissions for them
 				// * Can just apply the texture and be done with it.
-				objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+				objectp->setTEImage(te, LLViewerTextureManager::getFetchedTexture(mImageID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 			}
 			return true;
 		}
@@ -1771,7 +1769,7 @@ BOOL LLSelectMgr::selectionRevertTextures()
 					}
 					else
 					{
-						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+						object->setTEImage(te, LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 					}
 				}
 			}
@@ -5185,7 +5183,7 @@ void LLSelectMgr::updateSilhouettes()
 
 	if (!mSilhouetteImagep)
 	{
-		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", TRUE, LLViewerTexture::BOOST_UI);
+		mSilhouetteImagep = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI);
 	}
 
 	mHighlightedObjects->cleanupNodes();
diff --git a/indra/newview/llsidepanelappearance.cpp b/indra/newview/llsidepanelappearance.cpp
index d909a218e387c83314517b8b3b246cf764d13c9f..74fa5a87bba7b96cf49046ce58da33e501b2bf49 100644
--- a/indra/newview/llsidepanelappearance.cpp
+++ b/indra/newview/llsidepanelappearance.cpp
@@ -38,7 +38,7 @@
 #include "llfiltereditor.h"
 #include "llfloaterreg.h"
 #include "llfloaterworldmap.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "lloutfitobserver.h"
 #include "llpaneleditwearable.h"
 #include "llpaneloutfitsinventory.h"
@@ -47,7 +47,7 @@
 #include "llviewercontrol.h"
 #include "llviewerregion.h"
 #include "llvoavatarself.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 
 static LLRegisterPanelClassWrapper<LLSidepanelAppearance> t_appearance("sidepanel_appearance");
 
@@ -198,7 +198,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 
 		if (is_outfit_edit_visible || is_wearable_edit_visible)
 		{
-			const LLWearable *wearable_ptr = mEditWearable->getWearable();
+			const LLViewerWearable *wearable_ptr = mEditWearable->getWearable();
 			if (!wearable_ptr)
 			{
 				llwarns << "Visibility change to invalid wearable" << llendl;
@@ -206,12 +206,9 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 			}
 			// Disable camera switch is currently just for WT_PHYSICS type since we don't want to freeze the avatar
 			// when editing its physics.
-			const BOOL disable_camera_motion = LLWearableType::getDisableCameraSwitch(wearable_ptr->getType());
-			if (!gAgentCamera.cameraCustomizeAvatar() && 
-				!disable_camera_motion &&
-				gSavedSettings.getBOOL("AppearanceCameraMovement"))
+			if (!gAgentCamera.cameraCustomizeAvatar())
 			{
-				gAgentCamera.changeCameraToCustomizeAvatar();
+				LLVOAvatarSelf::onCustomizeStart(LLWearableType::getDisableCameraSwitch(wearable_ptr->getType()));
 			}
 			if (is_wearable_edit_visible)
 			{
@@ -234,7 +231,7 @@ void LLSidepanelAppearance::updateToVisibility(const LLSD &new_visibility)
 		{
 			gAgentCamera.changeCameraToDefault();
 			gAgentCamera.resetView();
-		}
+		}	
 	}
 }
 
@@ -267,11 +264,11 @@ void LLSidepanelAppearance::onOpenOutfitButtonClicked()
 		if (inventory_panel)
 		{
 			LLFolderView* root = inventory_panel->getRootFolder();
-			LLFolderViewItem *outfit_folder = root->getItemByID(outfit_link->getLinkedUUID());
+			LLFolderViewItem *outfit_folder =    inventory_panel->getItemByID(outfit_link->getLinkedUUID());
 			if (outfit_folder)
 			{
 				outfit_folder->setOpen(!outfit_folder->isOpen());
-				root->setSelectionFromRoot(outfit_folder,TRUE);
+				root->setSelection(outfit_folder,TRUE);
 				root->scrollToShowSelection();
 			}
 		}
@@ -283,7 +280,7 @@ void LLSidepanelAppearance::onEditAppearanceButtonClicked()
 {
 	if (gAgentWearables.areWearablesLoaded())
 	{
-		gAgentCamera.changeCameraToCustomizeAvatar();
+		LLVOAvatarSelf::onCustomizeStart();
 	}
 }
 
@@ -329,7 +326,7 @@ void LLSidepanelAppearance::showOutfitEditPanel()
 	toggleOutfitEditPanel(TRUE);
 }
 
-void LLSidepanelAppearance::showWearableEditPanel(LLWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
+void LLSidepanelAppearance::showWearableEditPanel(LLViewerWearable *wearable /* = NULL*/, BOOL disable_camera_switch)
 {
 	toggleMyOutfitsPanel(FALSE);
 	toggleOutfitEditPanel(FALSE, TRUE); // don't switch out of edit appearance mode
@@ -371,19 +368,19 @@ void LLSidepanelAppearance::toggleOutfitEditPanel(BOOL visible, BOOL disable_cam
 	if (visible)
 	{
 		mOutfitEdit->onOpen(LLSD());
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
-		{
-			gAgentCamera.changeCameraToCustomizeAvatar();
-		}
+		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
 	}
-	else if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+	else 
 	{
-		gAgentCamera.changeCameraToDefault();
-		gAgentCamera.resetView();
+		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.
+		{
+			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
+			LLAppearanceMgr::getInstance()->updateIsDirty();
+		}
 	}
 }
 
-void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *wearable, BOOL disable_camera_switch)
+void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLViewerWearable *wearable, BOOL disable_camera_switch)
 {
 	if (!mEditWearable || mEditWearable->getVisible() == visible)
 	{
@@ -393,7 +390,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 
 	if (!wearable)
 	{
-		wearable = gAgentWearables.getWearable(LLWearableType::WT_SHAPE, 0);
+		wearable = gAgentWearables.getViewerWearable(LLWearableType::WT_SHAPE, 0);
 	}
 	if (!wearable)
 	{
@@ -405,10 +402,7 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 
 	if (visible)
 	{
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
-		{
-			gAgentCamera.changeCameraToCustomizeAvatar();
-		}
+		LLVOAvatarSelf::onCustomizeStart(disable_camera_switch);
 		mEditWearable->setWearable(wearable, disable_camera_switch);
 		mEditWearable->onOpen(LLSD()); // currently no-op, just for consistency
 	}
@@ -416,10 +410,10 @@ void LLSidepanelAppearance::toggleWearableEditPanel(BOOL visible, LLWearable *we
 	{
 		// Save changes if closing.
 		mEditWearable->saveChanges();
-		if (!disable_camera_switch && gSavedSettings.getBOOL("AppearanceCameraMovement") )
+		LLAppearanceMgr::getInstance()->updateIsDirty();
+		if (!disable_camera_switch)   // if we're just switching between outfit and wearable editing, don't end customization.
 		{
-			gAgentCamera.changeCameraToDefault();
-			gAgentCamera.resetView();
+			LLVOAvatarSelf::onCustomizeEnd(disable_camera_switch);
 		}
 	}
 }
@@ -453,13 +447,12 @@ void LLSidepanelAppearance::refreshCurrentOutfitName(const std::string& name)
 }
 
 //static
-void LLSidepanelAppearance::editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch)
+void LLSidepanelAppearance::editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch)
 {
 	LLFloaterSidePanelContainer::showPanel("appearance", LLSD());
 	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(data);
 	if (panel)
 	{
-		panel->showOutfitsInventoryPanel();
 		panel->showWearableEditPanel(wearable, disable_camera_switch);
 	}
 }
diff --git a/indra/newview/llsidepanelappearance.h b/indra/newview/llsidepanelappearance.h
index 6dd35202665663707e7911ff330d717273b6ddb0..762f557a8004e471b1a9f9b14a255e3f0817ff17 100644
--- a/indra/newview/llsidepanelappearance.h
+++ b/indra/newview/llsidepanelappearance.h
@@ -36,7 +36,7 @@
 class LLFilterEditor;
 class LLCurrentlyWornFetchObserver;
 class LLPanelEditWearable;
-class LLWearable;
+class LLViewerWearable;
 class LLPanelOutfitsInventory;
 
 class LLSidepanelAppearance : public LLPanel
@@ -47,11 +47,11 @@ class LLSidepanelAppearance : public LLPanel
 	virtual ~LLSidepanelAppearance();
 
 	/*virtual*/ BOOL postBuild();
-	/*virtual*/ void onOpen(const LLSD& key);
+	/*virtual*/ void onOpen(const LLSD& key);	
 
 	void refreshCurrentOutfitName(const std::string& name = "");
 
-	static void editWearable(LLWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
+	static void editWearable(LLViewerWearable *wearable, LLView *data, BOOL disable_camera_switch = FALSE);
 
 	void fetchInventory();
 	void inventoryFetched();
@@ -59,11 +59,12 @@ class LLSidepanelAppearance : public LLPanel
 
 	void showOutfitsInventoryPanel();
 	void showOutfitEditPanel();
-	void showWearableEditPanel(LLWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
+	void showWearableEditPanel(LLViewerWearable *wearable = NULL, BOOL disable_camera_switch = FALSE);
 	void setWearablesLoading(bool val);
 	void showDefaultSubpart();
 	void updateScrollingPanelList();
 	void updateToVisibility( const LLSD& new_visibility );
+	LLPanelEditWearable* getWearable(){ return mEditWearable; }
 
 private:
 	void onFilterEdit(const std::string& search_string);
@@ -74,7 +75,7 @@ class LLSidepanelAppearance : public LLPanel
 
 	void toggleMyOutfitsPanel(BOOL visible);
 	void toggleOutfitEditPanel(BOOL visible, BOOL disable_camera_switch = FALSE);
-	void toggleWearableEditPanel(BOOL visible, LLWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
+	void toggleWearableEditPanel(BOOL visible, LLViewerWearable* wearable = NULL, BOOL disable_camera_switch = FALSE);
 
 	LLFilterEditor*			mFilterEditor;
 	LLPanelOutfitsInventory* mPanelOutfitsInventory;
diff --git a/indra/newview/llsidepanelinventory.cpp b/indra/newview/llsidepanelinventory.cpp
index 4f9ab318a56807443cc0fdee6c3bad8f0b25d207..8915bb2fef789c78f5c9c4a88dd178d987381f17 100644
--- a/indra/newview/llsidepanelinventory.cpp
+++ b/indra/newview/llsidepanelinventory.cpp
@@ -36,6 +36,7 @@
 #include "llfirstuse.h"
 #include "llfloatersidepanelcontainer.h"
 #include "llfoldertype.h"
+#include "llfolderview.h"
 #include "llhttpclient.h"
 #include "llinventorybridge.h"
 #include "llinventoryfunctions.h"
@@ -259,9 +260,8 @@ void LLSidepanelInventory::updateInbox()
 	//
 
 	const bool do_not_create_folder = false;
-	const bool do_not_find_in_library = false;
 
-	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder, do_not_find_in_library);
+	const LLUUID inbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_INBOX, do_not_create_folder);
 	
 	// Set up observer to listen for creation of inbox if at least one of them doesn't exist
 	if (inbox_id.isNull())
@@ -383,10 +383,10 @@ void LLSidepanelInventory::onToggleInboxBtn()
 	{
 		inboxPanel->setTargetDim(gSavedPerAccountSettings.getS32("InventoryInboxHeight"));
 		if (inboxPanel->isInVisibleChain())
-		{
-			gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
-		}
+	{
+		gSavedPerAccountSettings.setU32("LastInventoryInboxActivity", time_corrected());
 	}
+}
 	else
 	{
 		gSavedPerAccountSettings.setS32("InventoryInboxHeight", inboxPanel->getTargetDim());
@@ -448,7 +448,7 @@ void LLSidepanelInventory::onInfoButtonClicked()
 
 void LLSidepanelInventory::onShareButtonClicked()
 {
-	LLAvatarActions::shareWithAvatars();
+	LLAvatarActions::shareWithAvatars(this);
 }
 
 void LLSidepanelInventory::onShopButtonClicked()
@@ -472,7 +472,7 @@ void LLSidepanelInventory::performActionOnSelection(const std::string &action)
 		}
 	}
 
-	current_item->getListener()->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
+	static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->performAction(mPanelMainInventory->getActivePanel()->getModel(), action);
 }
 
 void LLSidepanelInventory::onWearButtonClicked()
@@ -662,7 +662,7 @@ LLInventoryItem *LLSidepanelInventory::getSelectedItem()
 			return NULL;
 		}
 	}
-	const LLUUID &item_id = current_item->getListener()->getUUID();
+	const LLUUID &item_id = static_cast<LLFolderViewModelItemInventory*>(current_item->getViewModelItem())->getUUID();
 	LLInventoryItem *item = gInventory.getItem(item_id);
 	return item;
 }
@@ -671,7 +671,7 @@ U32 LLSidepanelInventory::getSelectedCount()
 {
 	int count = 0;
 
-	std::set<LLUUID> selection_list = mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
+	std::set<LLFolderViewItem*> selection_list =    mPanelMainInventory->getActivePanel()->getRootFolder()->getSelectionList();
 	count += selection_list.size();
 
 	if ((count == 0) && mInboxEnabled && (mInventoryPanelInbox != NULL))
@@ -722,9 +722,9 @@ void LLSidepanelInventory::clearSelections(bool clearMain, bool clearInbox)
 	updateVerbs();
 }
 
-std::set<LLUUID> LLSidepanelInventory::getInboxSelectionList()
+std::set<LLFolderViewItem*> LLSidepanelInventory::getInboxSelectionList()
 {
-	std::set<LLUUID> inventory_selected_uuids;
+	std::set<LLFolderViewItem*> inventory_selected_uuids;
 	
 	if (mInboxEnabled && (mInventoryPanelInbox != NULL))
 	{
diff --git a/indra/newview/llsidepanelinventory.h b/indra/newview/llsidepanelinventory.h
index a33607f50d8a76177b133d0259118f325fad4ac6..e8b2808d4fd7e00538314726c2af239f3cc6d192 100644
--- a/indra/newview/llsidepanelinventory.h
+++ b/indra/newview/llsidepanelinventory.h
@@ -63,7 +63,7 @@ class LLSidepanelInventory : public LLPanel
 	BOOL isMainInventoryPanelActive() const;
 
 	void clearSelections(bool clearMain, bool clearInbox);
-	std::set<LLUUID> getInboxSelectionList();
+    std::set<LLFolderViewItem*> getInboxSelectionList();
 
 	void showItemInfoPanel();
 	void showTaskInfoPanel();
diff --git a/indra/newview/llsidepaneltaskinfo.cpp b/indra/newview/llsidepaneltaskinfo.cpp
index 5532bdc71a8a2dc12ee5c0bdfd6f12e340e53b96..ad7c939728fe36b668a7f4d8283c13223a0289f4 100644
--- a/indra/newview/llsidepaneltaskinfo.cpp
+++ b/indra/newview/llsidepaneltaskinfo.cpp
@@ -370,10 +370,8 @@ void LLSidepanelTaskInfo::refresh()
 	
 	// Update creator text field
 	getChildView("Creator:")->setEnabled(TRUE);
-	BOOL creators_identical;
 	std::string creator_name;
-	creators_identical = LLSelectMgr::getInstance()->selectGetCreator(mCreatorID,
-																	  creator_name);
+	LLSelectMgr::getInstance()->selectGetCreator(mCreatorID, creator_name);
 
 	getChild<LLUICtrl>("Creator Name")->setValue(creator_name);
 	getChildView("Creator Name")->setEnabled(TRUE);
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index af740fe73d5241cdf7a5ad08f2c9ff90c28a3598..f85e855fd3a87549da2ee1faecc14906daf024f2 100644
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -2746,7 +2746,7 @@ void renderVisibility(LLSpatialGroup* group, LLCamera* camera)
 
 void renderCrossHairs(LLVector3 position, F32 size, LLColor4 color)
 {
-	gGL.diffuseColor4fv(color.mV);
+	gGL.color4fv(color.mV);
 	gGL.begin(LLRender::LINES);
 	{
 		gGL.vertex3fv((position - LLVector3(size, 0.f, 0.f)).mV);
@@ -3544,9 +3544,9 @@ void renderTexturePriority(LLDrawable* drawable)
 		drawBox(center, size);
 		
 		/*S32 boost = imagep->getBoostLevel();
-		if (boost>LLViewerTexture::BOOST_NONE)
+		if (boost>LLGLTexture::BOOST_NONE)
 		{
-			F32 t = (F32) boost / (F32) (LLViewerTexture::BOOST_MAX_LEVEL-1);
+			F32 t = (F32) boost / (F32) (LLGLTexture::BOOST_MAX_LEVEL-1);
 			LLVector4 col = lerp(boost_cold, boost_hot, t);
 			LLGLEnable blend_on(GL_BLEND);
 			gGL.blendFunc(GL_SRC_ALPHA, GL_ONE);
@@ -3997,8 +3997,8 @@ void renderAgentTarget(LLVOAvatar* avatar)
 	if (avatar->isSelf())
 	{
 		renderCrossHairs(avatar->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
-		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(1, 0, 0, 0.8f));
-		renderCrossHairs(avatar->mRoot.getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
+		renderCrossHairs(avatar->mDrawable->getPositionAgent(), 0.2f, LLColor4(0, 1, 0, 0.8f));
+		renderCrossHairs(avatar->mRoot->getWorldPosition(), 0.2f, LLColor4(1, 1, 1, 0.8f));
 		renderCrossHairs(avatar->mPelvisp->getWorldPosition(), 0.2f, LLColor4(0, 0, 1, 0.8f));
 	}
 }
@@ -4062,9 +4062,6 @@ class LLOctreeRenderNonOccluded : public LLOctreeTraveler<LLDrawable>
 			return;
 		}
 
-		LLVector4a nodeCenter = group->mBounds[0];
-		LLVector4a octCenter = group->mOctreeNode->getCenter();
-
 		group->rebuildGeom();
 		group->rebuildMesh();
 
@@ -4539,9 +4536,6 @@ class LLOctreeIntersect : public LLSpatialGroup::OctreeTraveler
 
 	virtual bool check(LLDrawable* drawable)
 	{	
-		LLVector3 local_start = mStart;
-		LLVector3 local_end = mEnd;
-
 		if (!drawable || !gPipeline.hasRenderType(drawable->getRenderType()) || !drawable->isVisible())
 		{
 			return false;
diff --git a/indra/newview/llspeakers.cpp b/indra/newview/llspeakers.cpp
index 07d2f1ad6f98bb29a0c48d755949d6a8806f2cd2..a4582071e8b3922b4d8fe60d74511496f7b62a37 100644
--- a/indra/newview/llspeakers.cpp
+++ b/indra/newview/llspeakers.cpp
@@ -31,12 +31,15 @@
 #include "llagent.h"
 #include "llappviewer.h"
 #include "llimview.h"
+#include "llgroupmgr.h"
 #include "llsdutil.h"
 #include "lluicolortable.h"
 #include "llviewerobjectlist.h"
 #include "llvoavatar.h"
 #include "llworld.h"
 
+extern LLControlGroup gSavedSettings;
+
 const LLColor4 INACTIVE_COLOR(0.3f, 0.3f, 0.3f, 0.5f);
 const LLColor4 ACTIVE_COLOR(0.5f, 0.5f, 0.5f, 1.f);
 
@@ -84,6 +87,19 @@ bool LLSpeaker::isInVoiceChannel()
 	return mStatus <= LLSpeaker::STATUS_VOICE_ACTIVE || mStatus == LLSpeaker::STATUS_MUTED;
 }
 
+LLSpeakerUpdateSpeakerEvent::LLSpeakerUpdateSpeakerEvent(LLSpeaker* source)
+: LLEvent(source, "Speaker update speaker event"),
+  mSpeakerID (source->mID)
+{
+}
+
+LLSD LLSpeakerUpdateSpeakerEvent::getValue()
+{
+	LLSD ret;
+	ret["id"] = mSpeakerID;
+	return ret;
+}
+
 LLSpeakerUpdateModeratorEvent::LLSpeakerUpdateModeratorEvent(LLSpeaker* source)
 : LLEvent(source, "Speaker add moderator event"),
   mSpeakerID (source->mID),
@@ -241,16 +257,63 @@ bool LLSpeakersDelayActionsStorage::onTimerActionCallback(const LLUUID& speaker_
 	return true;
 }
 
+bool LLSpeakersDelayActionsStorage::isTimerStarted(const LLUUID& speaker_id)
+{
+	return (mActionTimersMap.size() > 0) && (mActionTimersMap.find(speaker_id) != mActionTimersMap.end());
+}
+
+//
+// ModerationResponder
+//
+
+class ModerationResponder : public LLHTTPClient::Responder
+{
+public:
+	ModerationResponder(const LLUUID& session_id)
+	{
+		mSessionID = session_id;
+	}
+	
+	virtual void error(U32 status, const std::string& reason)
+	{
+		llwarns << status << ": " << reason << llendl;
+		
+		if ( gIMMgr )
+		{
+			//403 == you're not a mod
+			//should be disabled if you're not a moderator
+			if ( 403 == status )
+			{
+				gIMMgr->showSessionEventError(
+											  "mute",
+											  "not_a_mod_error",
+											  mSessionID);
+			}
+			else
+			{
+				gIMMgr->showSessionEventError(
+											  "mute",
+											  "generic_request_error",
+											  mSessionID);
+			}
+		}
+	}
+	
+private:
+	LLUUID mSessionID;
+};
 
 //
 // LLSpeakerMgr
 //
 
 LLSpeakerMgr::LLSpeakerMgr(LLVoiceChannel* channelp) : 
-	mVoiceChannel(channelp)
-, mVoiceModerated(false)
-, mModerateModeHandledFirstTime(false)
+	mVoiceChannel(channelp),
+	mVoiceModerated(false),
+	mModerateModeHandledFirstTime(false),
+	mSpeakerListUpdated(false)
 {
+    mGetListTime.reset();
 	static LLUICachedControl<F32> remove_delay ("SpeakerParticipantRemoveDelay", 10.0);
 
 	mSpeakerDelayRemover = new LLSpeakersDelayActionsStorage(boost::bind(&LLSpeakerMgr::removeSpeaker, this, _1), remove_delay);
@@ -263,7 +326,11 @@ LLSpeakerMgr::~LLSpeakerMgr()
 
 LLPointer<LLSpeaker> LLSpeakerMgr::setSpeaker(const LLUUID& id, const std::string& name, LLSpeaker::ESpeakerStatus status, LLSpeaker::ESpeakerType type)
 {
-	if (id.isNull()) return NULL;
+	LLUUID session_id = getSessionID();
+	if (id.isNull() || (id == session_id))
+	{
+		return NULL;
+	}
 
 	LLPointer<LLSpeaker> speakerp;
 	if (mSpeakers.find(id) == mSpeakers.end())
@@ -345,12 +412,10 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 
 	// update status of all current speakers
 	BOOL voice_channel_active = (!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive());
-	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end();)
+	for (speaker_map_t::iterator speaker_it = mSpeakers.begin(); speaker_it != mSpeakers.end(); speaker_it++)
 	{
 		LLUUID speaker_id = speaker_it->first;
 		LLSpeaker* speakerp = speaker_it->second;
-		
-		speaker_map_t::iterator  cur_speaker_it = speaker_it++;
 
 		if (voice_channel_active && LLVoiceClient::getInstance()->getVoiceEnabled(speaker_id))
 		{
@@ -374,6 +439,7 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 				{
 					speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 					speakerp->mHasSpoken = TRUE;
+					fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 				}
 				speakerp->mStatus = LLSpeaker::STATUS_SPEAKING;
 				// interpolate between active color and full speaking color based on power of speech output
@@ -448,24 +514,89 @@ void LLSpeakerMgr::update(BOOL resort_ok)
 
 void LLSpeakerMgr::updateSpeakerList()
 {
-	// are we bound to the currently active voice channel?
+	// Are we bound to the currently active voice channel?
 	if ((!mVoiceChannel && LLVoiceClient::getInstance()->inProximalChannel()) || (mVoiceChannel && mVoiceChannel->isActive()))
 	{
-	        std::set<LLUUID> participants;
-	        LLVoiceClient::getInstance()->getParticipantList(participants);
-		// add new participants to our list of known speakers
-		for (std::set<LLUUID>::iterator participant_it = participants.begin();
-			 participant_it != participants.end(); 
-			 ++participant_it)
+		std::set<LLUUID> participants;
+		LLVoiceClient::getInstance()->getParticipantList(participants);
+		// If we are, add all voice client participants to our list of known speakers
+		for (std::set<LLUUID>::iterator participant_it = participants.begin(); participant_it != participants.end(); ++participant_it)
 		{
 				setSpeaker(*participant_it, 
 						   LLVoiceClient::getInstance()->getDisplayName(*participant_it),
 						   LLSpeaker::STATUS_VOICE_ACTIVE, 
 						   (LLVoiceClient::getInstance()->isParticipantAvatar(*participant_it)?LLSpeaker::SPEAKER_AGENT:LLSpeaker::SPEAKER_EXTERNAL));
-
-
 		}
 	}
+	else 
+	{
+		// If not, check if the list is empty, except if it's Nearby Chat (session_id NULL).
+		LLUUID session_id = getSessionID();
+		if (!session_id.isNull() && !mSpeakerListUpdated)
+		{
+			// If the list is empty, we update it with whatever we have locally so that it doesn't stay empty too long.
+			// *TODO: Fix the server side code that sometimes forgets to send back the list of participants after a chat started.
+			// (IOW, fix why we get no ChatterBoxSessionAgentListUpdates message after the initial ChatterBoxSessionStartReply)
+			LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
+			if (session->isGroupSessionType() && (mSpeakers.size() <= 1))
+			{
+                const F32 load_group_timeout = gSavedSettings.getF32("ChatLoadGroupTimeout");
+				// For groups, we need to hit the group manager.
+				// Note: The session uuid and the group uuid are actually one and the same. If that was to change, this will fail.
+				LLGroupMgrGroupData* gdatap = LLGroupMgr::getInstance()->getGroupData(session_id);
+				if (!gdatap && (mGetListTime.getElapsedTimeF32() >= load_group_timeout))
+				{
+					// Request the data the first time around
+					LLGroupMgr::getInstance()->sendCapGroupMembersRequest(session_id);
+				}
+				else if (gdatap && gdatap->isMemberDataComplete() && !gdatap->mMembers.empty())
+				{
+					// Add group members when we get the complete list (note: can take a while before we get that list)
+					LLGroupMgrGroupData::member_list_t::iterator member_it = gdatap->mMembers.begin();
+                    const S32 load_group_max_members = gSavedSettings.getS32("ChatLoadGroupMaxMembers");
+                    S32 updated = 0;
+					while (member_it != gdatap->mMembers.end())
+					{
+						LLGroupMemberData* member = member_it->second;
+                        LLUUID id = member_it->first;
+						// Add only members who are online and not already in the list
+						if ((member->getOnlineStatus() == "Online") && (mSpeakers.find(id) == mSpeakers.end()))
+						{
+							LLPointer<LLSpeaker> speakerp = setSpeaker(id, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+							speakerp->mIsModerator = ((member->getAgentPowers() & GP_SESSION_MODERATOR) == GP_SESSION_MODERATOR);
+                            updated++;
+						}
+						++member_it;
+                        // Limit the number of "manually updated" participants to a reasonable number to avoid severe fps drop
+                        // *TODO : solve the perf issue of having several hundreds of widgets in the conversation list
+                        if (updated >= load_group_max_members)
+                            break;
+					}
+                    mSpeakerListUpdated = true;
+				}
+			}
+			else if (mSpeakers.size() == 0)
+			{
+				// For all other session type (ad-hoc, P2P, avaline), we use the initial participants targets list
+				for (uuid_vec_t::iterator it = session->mInitialTargetIDs.begin();it!=session->mInitialTargetIDs.end();++it)
+				{
+					// Add buddies if they are on line, add any other avatar.
+					if (!LLAvatarTracker::instance().isBuddy(*it) || LLAvatarTracker::instance().isBuddyOnline(*it))
+					{
+						setSpeaker(*it, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
+					}
+				}
+				mSpeakerListUpdated = true;
+			}
+			else
+			{
+				// The list has been updated the normal way (i.e. by a ChatterBoxSessionAgentListUpdates received from the server)
+				mSpeakerListUpdated = true;
+			}
+		}
+	}
+	// Always add the current agent (it has to be there...). Will do nothing if already there.
+	setSpeaker(gAgentID, "", LLSpeaker::STATUS_VOICE_ACTIVE, LLSpeaker::SPEAKER_AGENT);
 }
 
 void LLSpeakerMgr::setSpeakerNotInChannel(LLSpeaker* speakerp)
@@ -530,6 +661,10 @@ const LLUUID LLSpeakerMgr::getSessionID()
 	return mVoiceChannel->getSessionID(); 
 }
 
+bool LLSpeakerMgr::isSpeakerToBeRemoved(const LLUUID& speaker_id)
+{
+	return mSpeakerDelayRemover && mSpeakerDelayRemover->isTimerStarted(speaker_id);
+}
 
 void LLSpeakerMgr::setSpeakerTyping(const LLUUID& speaker_id, BOOL typing)
 {
@@ -548,6 +683,7 @@ void LLSpeakerMgr::speakerChatted(const LLUUID& speaker_id)
 	{
 		speakerp->mLastSpokeTime = mSpeechTimer.getElapsedTimeF32();
 		speakerp->mHasSpoken = TRUE;
+		fireEvent(new LLSpeakerUpdateSpeakerEvent(speakerp), "update_speaker");
 	}
 }
 
@@ -717,44 +853,10 @@ void LLIMSpeakerMgr::updateSpeakers(const LLSD& update)
 		}
 	}
 }
-
-class ModerationResponder : public LLHTTPClient::Responder
-{
-public:
-	ModerationResponder(const LLUUID& session_id)
-	{
-		mSessionID = session_id;
-	}
-
-	virtual void error(U32 status, const std::string& reason)
-	{
-		llwarns << status << ": " << reason << llendl;
-
-		if ( gIMMgr )
-		{
-			//403 == you're not a mod
-			//should be disabled if you're not a moderator
-			if ( 403 == status )
-			{
-				gIMMgr->showSessionEventError(
-					"mute",
-					"not_a_mod_error",
-					mSessionID);
-			}
-			else
-			{
-				gIMMgr->showSessionEventError(
-					"mute",
-					"generic_request_error",
-					mSessionID);
-			}
-		}
-	}
-
-private:
-	LLUUID mSessionID;
-};
-
+/*prep#
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+		llwarns << "ModerationResponder error [status:" << status << "]: " << content << llendl;
+		*/
 void LLIMSpeakerMgr::toggleAllowTextChat(const LLUUID& speaker_id)
 {
 	LLPointer<LLSpeaker> speakerp = findSpeaker(speaker_id);
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index b9358cf37c0856b9681c28a11545f4be8840b227..e953dd0e1a516c7db03354ba17d12685f639fbf3 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -29,7 +29,6 @@
 
 #include "llevent.h"
 #include "lleventtimer.h"
-#include "llspeakers.h"
 #include "llvoicechannel.h"
 
 class LLSpeakerMgr;
@@ -80,6 +79,15 @@ class LLSpeaker : public LLRefCount, public LLOldEvents::LLObservable, public LL
 	BOOL			mModeratorMutedText;
 };
 
+class LLSpeakerUpdateSpeakerEvent : public LLOldEvents::LLEvent
+{
+public:
+	LLSpeakerUpdateSpeakerEvent(LLSpeaker* source);
+	/*virtual*/ LLSD getValue();
+private:
+	const LLUUID& mSpeakerID;
+};
+
 class LLSpeakerUpdateModeratorEvent : public LLOldEvents::LLEvent
 {
 public:
@@ -185,6 +193,8 @@ class LLSpeakersDelayActionsStorage
 	void unsetActionTimer(const LLUUID& speaker_id);
 
 	void removeAllTimers();
+
+	bool isTimerStarted(const LLUUID& speaker_id);
 private:
 	/**
 	 * Callback of the each instance of LLSpeakerActionTimer.
@@ -229,6 +239,7 @@ class LLSpeakerMgr : public LLOldEvents::LLObservable
 	void getSpeakerList(speaker_list_t* speaker_list, BOOL include_text);
 	LLVoiceChannel* getVoiceChannel() { return mVoiceChannel; }
 	const LLUUID getSessionID();
+	bool isSpeakerToBeRemoved(const LLUUID& speaker_id);
 
 	/**
 	 * Removes avaline speaker.
@@ -252,6 +263,8 @@ class LLSpeakerMgr : public LLOldEvents::LLObservable
 
 	typedef std::map<LLUUID, LLPointer<LLSpeaker> > speaker_map_t;
 	speaker_map_t		mSpeakers;
+	bool                mSpeakerListUpdated;
+    LLTimer             mGetListTime;
 
 	speaker_list_t		mSpeakersSorted;
 	LLFrameTimer		mSpeechTimer;
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 9b38bf22ffe03ec7cea5ca373633c7f807ecb5f2..07e9371124f5ccb36b991d5abe50f10b1020a9c7 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -74,6 +74,16 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L
 	 */
 	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
 
+	/**
+	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
+	 *
+	 * Switches off indicators had been switched on and switches on indicators of current participants list.
+	 * There is only a few indicators in lists should be switched off/on.
+	 * So, method does not calculate difference between these list it only switches off already 
+	 * switched on indicators and switches on indicators of voice channel participants
+	 */
+	void onParticipantsChanged();
+	
 private:
 	typedef std::set<LLUUID> speaker_ids_t;
 	typedef std::multimap<LLUUID, LLSpeakingIndicator*> speaking_indicators_mmap_t;
@@ -93,16 +103,6 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L
 	 */
 	void sOnCurrentChannelChanged(const LLUUID& session_id);
 
-	/**
-	 * Callback of changing voice participant list (from LLVoiceClientParticipantObserver).
-	 *
-	 * Switches off indicators had been switched on and switches on indicators of current participants list.
-	 * There is only a few indicators in lists should be switched off/on.
-	 * So, method does not calculate difference between these list it only switches off already 
-	 * switched on indicators and switches on indicators of voice channel participants
-	 */
-	void onParticipantsChanged();
-
 	/**
 	 * Changes state of indicators specified by LLUUIDs
 	 *
@@ -237,28 +237,18 @@ void SpeakingIndicatorManager::switchSpeakerIndicators(const speaker_ids_t& spea
 		{
 			was_found = true;
 			LLSpeakingIndicator* indicator = (*it_indicator).second;
+			was_switched_on = was_switched_on || switch_on;
 
-			BOOL switch_current_on = switch_on;
-
-			// we should show indicator for specified voice session only if this is current channel. EXT-5562.
-			if (switch_current_on && indicator->getTargetSessionID().notNull())
-			{
-				switch_current_on = indicator->getTargetSessionID() == session_id;
-				LL_DEBUGS("SpeakingIndicator") << "Session: " << session_id << ", target: " << indicator->getTargetSessionID() << ", the same? = " << switch_current_on << LL_ENDL;
-			}
-			was_switched_on = was_switched_on || switch_current_on;
-
-			indicator->switchIndicator(switch_current_on);
-
+			indicator->switchIndicator(switch_on);
 		}
 
 		if (was_found)
 		{
-			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators where found" << LL_ENDL;
+			LL_DEBUGS("SpeakingIndicator") << mSpeakingIndicators.count(*it_uuid) << " indicators were found" << LL_ENDL;
 
 			if (switch_on && !was_switched_on)
 			{
-				LL_DEBUGS("SpeakingIndicator") << "but non of them where switched on" << LL_ENDL;
+				LL_DEBUGS("SpeakingIndicator") << "but none of them were switched on" << LL_ENDL;
 			}
 
 			if (was_switched_on)
@@ -314,5 +304,13 @@ void LLSpeakingIndicatorManager::unregisterSpeakingIndicator(const LLUUID& speak
 	}
 }
 
+void LLSpeakingIndicatorManager::updateSpeakingIndicators()
+{
+	if(SpeakingIndicatorManager::instanceExists())
+	{
+		SpeakingIndicatorManager::instance().onParticipantsChanged();
+	}
+}
+
 // EOF
 
diff --git a/indra/newview/llspeakingindicatormanager.h b/indra/newview/llspeakingindicatormanager.h
index b0a147865b8eaf3e660e4cd5798f18853435cec9..e5afcd1cb7ade6f0bf2b4806b9949066f586147e 100644
--- a/indra/newview/llspeakingindicatormanager.h
+++ b/indra/newview/llspeakingindicatormanager.h
@@ -78,6 +78,11 @@ namespace LLSpeakingIndicatorManager
 	 * @param speaking_indicator instance of the speaker indicator to be unregistered.
 	 */
 	void unregisterSpeakingIndicator(const LLUUID& speaker_id, const LLSpeakingIndicator* const speaking_indicator);
+
+	/**
+	 * Switch on/off registered speaking indicator according to the most current voice client status
+	 */
+	 void updateSpeakingIndicators();
 }
 
 #endif // LL_LLSPEAKINGINDICATORMANAGER_H
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 18ef36a8934fa825a74629a53d8df561a50d358a..9d5fd46a1d3310a47040444b86bd996bce8d44bf 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -54,7 +54,7 @@
 #include "llfloaterreg.h"
 #include "llfocusmgr.h"
 #include "llhttpsender.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "lllocationhistory.h"
 #include "llimageworker.h"
 
@@ -63,7 +63,8 @@
 #include "llmemorystream.h"
 #include "llmessageconfig.h"
 #include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llfloaterimcontainer.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llteleporthistory.h"
@@ -94,6 +95,7 @@
 #include "llcallingcard.h"
 #include "llconsole.h"
 #include "llcontainerview.h"
+#include "llconversationlog.h"
 #include "lldebugview.h"
 #include "lldrawable.h"
 #include "lleventnotifier.h"
@@ -314,7 +316,6 @@ bool idle_startup()
 {
 	const F32 PRECACHING_DELAY = gSavedSettings.getF32("PrecachingDelay");
 	static LLTimer timeout;
-	static S32 timeout_count = 0;
 
 	static LLTimer login_time;
 
@@ -330,7 +331,6 @@ bool idle_startup()
 
 	// last location by default
 	static S32  agent_location_id = START_LOCATION_ID_LAST;
-	static S32  location_which = START_LOCATION_ID_LAST;
 
 	static bool show_connect_box = true;
 
@@ -742,8 +742,6 @@ bool idle_startup()
 
 		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
 
-		timeout_count = 0;
-
 		// Login screen needs menus for preferences, but we can enter
 		// this startup phase more than once.
 		if (gLoginMenuBarView == NULL)
@@ -770,10 +768,6 @@ bool idle_startup()
 				gUserCredential = gLoginHandler.initializeLoginInfo();                 
 				display_startup();
 			}     
-			if (gHeadlessClient)
-			{
-				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL;
-			}
 			// Make sure the process dialog doesn't hide things
 			display_startup();
 			gViewerWindow->setShowProgress(FALSE);
@@ -915,6 +909,13 @@ bool idle_startup()
 		// Overwrite default user settings with user settings								 
 		LLAppViewer::instance()->loadSettingsFromDirectory("Account");
 
+		// Convert 'LogInstantMessages' into 'KeepConversationLogTranscripts' for backward compatibility (CHUI-743).
+		LLControlVariablePtr logInstantMessagesControl = gSavedPerAccountSettings.getControl("LogInstantMessages");
+		if (logInstantMessagesControl.notNull())
+		{
+			gSavedPerAccountSettings.setS32("KeepConversationLogTranscripts", logInstantMessagesControl->getValue() ? 2 : 1);
+		}
+
 		// Need to set the LastLogoff time here if we don't have one.  LastLogoff is used for "Recent Items" calculation
 		// and startup time is close enough if we don't have a real value.
 		if (gSavedPerAccountSettings.getU32("LastLogoff") == 0)
@@ -984,15 +985,12 @@ bool idle_startup()
 		  {
 		  case LLSLURL::LOCATION:
 		    agent_location_id = START_LOCATION_ID_URL;
-		    location_which = START_LOCATION_ID_LAST;
 		    break;
 		  case LLSLURL::LAST_LOCATION:
 		    agent_location_id = START_LOCATION_ID_LAST;
-		    location_which = START_LOCATION_ID_LAST;
 		    break;
 		  default:
 		    agent_location_id = START_LOCATION_ID_HOME;
-		    location_which = START_LOCATION_ID_HOME;
 		    break;
 		  }
 
@@ -1245,6 +1243,9 @@ bool idle_startup()
 		LLPostProcess::initClass();
 		display_startup();
 
+		LLAvatarAppearance::initClass();
+		display_startup();
+
 		LLViewerObject::initVOClasses();
 		display_startup();
 
@@ -1291,6 +1292,8 @@ bool idle_startup()
 		display_startup();
 		LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
 		
+		LLConversationLog::getInstance();
+
 		return FALSE;
 	}
 
@@ -1401,14 +1404,9 @@ bool idle_startup()
 		LLVoiceClient::getInstance()->updateSettings();
 		display_startup();
 
-		//gCacheName is required for nearby chat history loading
-		//so I just moved nearby history loading a few states further
-		if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
-		{
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-			if (nearby_chat) nearby_chat->loadHistory();
-		}
-		display_startup();
+		// create a container's instance for start a controlling conversation windows
+		// by the voice's events
+		LLFloaterIMContainer::getInstance();
 
 		// *Note: this is where gWorldMap used to be initialized.
 
@@ -1519,7 +1517,7 @@ bool idle_startup()
 	}
 
 	//---------------------------------------------------------------------
-	// Agent Send
+	// World Wait
 	//---------------------------------------------------------------------
 	if(STATE_WORLD_WAIT == LLStartUp::getStartupState())
 	{
@@ -1845,6 +1843,10 @@ bool idle_startup()
 			// Set the show start location to true, now that the user has logged
 			// on with this install.
 			gSavedSettings.setBOOL("ShowStartLocation", TRUE);
+
+			// Open Conversation floater on first login.
+			LLFloaterReg::toggleInstanceOrBringToFront("im_container");
+
 		}
 
 		display_startup();
@@ -2166,7 +2168,6 @@ bool idle_startup()
 		LLStartUp::setStartupState( STATE_STARTED );
 		display_startup();
 
-		// Unmute audio if desired and setup volumes.
 		// Unmute audio if desired and setup volumes.
 		// This is a not-uncommon crash site, so surround it with
 		// llinfos output to aid diagnosis.
@@ -2188,7 +2189,6 @@ bool idle_startup()
 
 		LLAgentPicksInfo::getInstance()->requestNumberOfPicks();
 
-		LLIMFloater::initIMFloater();
 		display_startup();
 
 		llassert(LLPathfindingManager::getInstance() != NULL);
@@ -2580,12 +2580,17 @@ void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
 	}
 	else
 	{
+		// FIXME SH-3860 - this creates a race condition, where COF
+		// changes (base outfit link added) after appearance update
+		// request has been submitted.
 		sWearablesLoadedCon = gAgentWearables.addLoadedCallback(LLStartUp::saveInitialOutfit);
 
 		bool do_copy = true;
 		bool do_append = false;
 		LLViewerInventoryCategory *cat = gInventory.getCategory(cat_id);
-		LLAppearanceMgr::instance().wearInventoryCategory(cat, do_copy, do_append);
+		// Need to fetch cof contents before we can wear.
+		callAfterCategoryFetch(LLAppearanceMgr::instance().getCOF(),
+							   boost::bind(&LLAppearanceMgr::wearInventoryCategory, LLAppearanceMgr::getInstance(), cat, do_copy, do_append));
 		lldebugs << "initial outfit category id: " << cat_id << llendl;
 	}
 
@@ -2803,7 +2808,7 @@ void LLStartUp::initNameCache()
 
 	// Start cache in not-running state until we figure out if we have
 	// capabilities for display name lookup
-	LLAvatarNameCache::initClass(false);
+	LLAvatarNameCache::initClass(false,gSavedSettings.getBOOL("UsePeopleAPI"));
 	LLAvatarNameCache::setUseDisplayNames(gSavedSettings.getBOOL("UseDisplayNames"));
 }
 
@@ -3447,6 +3452,14 @@ bool process_login_success_response()
 
 	}
 
+	// set the location of the Agent Appearance service, from which we can request
+	// avatar baked textures if they are supported by the current region
+	std::string agent_appearance_url = response["agent_appearance_service"];
+	if (!agent_appearance_url.empty())
+	{
+		LLAppearanceMgr::instance().setAppearanceServiceURL(agent_appearance_url);
+	}
+
 	// Set the location of the snapshot sharing config endpoint
 	std::string snapshot_config_url = response["snapshot_config_url"];
 	if(!snapshot_config_url.empty())
@@ -3491,13 +3504,6 @@ bool process_login_success_response()
 
 void transition_back_to_login_panel(const std::string& emsg)
 {
-	if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin"))
-	{
-		LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
-		LL_WARNS("AppInit") << emsg << LL_ENDL;
-		exit(0);
-	}
-
 	// Bounce back to the login screen.
 	reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 	gSavedSettings.setBOOL("AutoLogin", FALSE);
diff --git a/indra/newview/llsurface.cpp b/indra/newview/llsurface.cpp
index ec11a23eb8c290915177331e1b9436910b2a9532..93c7f54101372724aea6ef9e381aecca56354d08 100644
--- a/indra/newview/llsurface.cpp
+++ b/indra/newview/llsurface.cpp
@@ -1246,8 +1246,6 @@ BOOL LLSurface::generateWaterTexture(const F32 x, const F32 y,
 		y_end = tex_width;
 	}
 
-	LLVector3d origin_global = from_region_handle(getRegion()->getHandle());
-
 	// OK, for now, just have the composition value equal the height at the point.
 	LLVector3 location;
 	LLColor4U coloru;
diff --git a/indra/newview/llsyswellwindow.cpp b/indra/newview/llsyswellwindow.cpp
index 2002647fef1797cb734b08f0de8c57bddf5c661b..e92bd766ca7f60b442178a37cff4b257dd289eee 100644
--- a/indra/newview/llsyswellwindow.cpp
+++ b/indra/newview/llsyswellwindow.cpp
@@ -23,29 +23,18 @@
  * $/LicenseInfo$
  */
 
-
 #include "llviewerprecompiledheaders.h" // must be first include
-
 #include "llsyswellwindow.h"
 
-#include "llagent.h"
-#include "llavatarnamecache.h"
-
-#include "llflatlistview.h"
-#include "llfloaterreg.h"
-#include "llnotifications.h"
-
-#include "llscriptfloater.h"
-#include "llviewercontrol.h"
-#include "llviewerwindow.h"
-
 #include "llchiclet.h"
 #include "llchicletbar.h"
-#include "lltoastpanel.h"
+#include "llflatlistview.h"
+#include "llfloaterreg.h"
 #include "llnotificationmanager.h"
 #include "llnotificationsutil.h"
+#include "llscriptfloater.h"
 #include "llspeakers.h"
-#include "lltoolbarview.h"
+#include "lltoastpanel.h"
 
 //---------------------------------------------------------------------------------
 LLSysWellWindow::LLSysWellWindow(const LLSD& key) : LLTransientDockableFloater(NULL, true,  key),
@@ -68,10 +57,6 @@ BOOL LLSysWellWindow::postBuild()
 	// get a corresponding channel
 	initChannel();
 
-	// click on SysWell Window should clear "new message" state (and 'Lit' status). EXT-3147.
-	// mouse up callback is not called in this case.
-	setMouseDownCallback(boost::bind(&LLSysWellWindow::releaseNewMessagesState, this));
-
 	return LLTransientDockableFloater::postBuild();
 }
 
@@ -98,9 +83,12 @@ void LLSysWellWindow::onStartUpToastClick(S32 x, S32 y, MASK mask)
 void LLSysWellWindow::setSysWellChiclet(LLSysWellChiclet* chiclet) 
 { 
 	mSysWellChiclet = chiclet;
-	if(mSysWellChiclet)
-		mSysWellChiclet->updateWidget(isWindowEmpty()); 
+	if(NULL != mSysWellChiclet)
+	{
+		mSysWellChiclet->updateWidget(isWindowEmpty());
+	}
 }
+
 //---------------------------------------------------------------------------------
 LLSysWellWindow::~LLSysWellWindow()
 {
@@ -111,7 +99,10 @@ void LLSysWellWindow::removeItemByID(const LLUUID& id)
 {
 	if(mMessageList->removeItemByValue(id))
 	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
+		if (NULL != mSysWellChiclet)
+		{
+			mSysWellChiclet->updateWidget(isWindowEmpty());
+		}
 		reshapeWindow();
 	}
 	else
@@ -165,11 +156,6 @@ void LLSysWellWindow::setVisible(BOOL visible)
 		mChannel->updateShowToastsState();
 		mChannel->redrawToasts();
 	}
-
-	if (visible)
-	{
-		releaseNewMessagesState();
-	}
 }
 
 //---------------------------------------------------------------------------------
@@ -219,135 +205,12 @@ void LLSysWellWindow::reshapeWindow()
 	}
 }
 
-void LLSysWellWindow::releaseNewMessagesState()
-{
-	if (NULL != mSysWellChiclet)
-	{
-		mSysWellChiclet->setNewMessagesState(false);
-	}
-}
-
 //---------------------------------------------------------------------------------
 bool LLSysWellWindow::isWindowEmpty()
 {
 	return mMessageList->size() == 0;
 }
 
-/************************************************************************/
-/*         RowPanel implementation                                      */
-/************************************************************************/
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId,
-		S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId) :
-		LLPanel(LLPanel::Params()), mChiclet(NULL), mParent(parent)
-{
-	buildFromFile( "panel_activeim_row.xml");
-
-	// Choose which of the pre-created chiclets (IM/group) to use.
-	// The other one gets hidden.
-
-	LLIMChiclet::EType im_chiclet_type = LLIMChiclet::getIMSessionType(sessionId);
-	switch (im_chiclet_type)
-	{
-	case LLIMChiclet::TYPE_GROUP:
-		mChiclet = getChild<LLIMGroupChiclet>("group_chiclet");
-		break;
-	case LLIMChiclet::TYPE_AD_HOC:
-		mChiclet = getChild<LLAdHocChiclet>("adhoc_chiclet");		
-		break;
-	case LLIMChiclet::TYPE_UNKNOWN: // assign mChiclet a non-null value anyway
-	case LLIMChiclet::TYPE_IM:
-		mChiclet = getChild<LLIMP2PChiclet>("p2p_chiclet");
-		break;
-	}
-
-	// Initialize chiclet.
-	mChiclet->setChicletSizeChangedCallback(boost::bind(&LLIMWellWindow::RowPanel::onChicletSizeChanged, this, mChiclet, _2));
-	mChiclet->enableCounterControl(true);
-	mChiclet->setCounter(chicletCounter);
-	mChiclet->setSessionId(sessionId);
-	mChiclet->setIMSessionName(name);
-	mChiclet->setOtherParticipantId(otherParticipantId);
-	mChiclet->setVisible(true);
-
-	if (im_chiclet_type == LLIMChiclet::TYPE_IM)
-	{
-		LLAvatarNameCache::get(otherParticipantId,
-			boost::bind(&LLIMWellWindow::RowPanel::onAvatarNameCache,
-				this, _1, _2));
-	}
-	else
-	{
-		LLTextBox* contactName = getChild<LLTextBox>("contact_name");
-		contactName->setValue(name);
-	}
-
-	mCloseBtn = getChild<LLButton>("hide_btn");
-	mCloseBtn->setCommitCallback(boost::bind(&LLIMWellWindow::RowPanel::onClosePanel, this));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onAvatarNameCache(const LLUUID& agent_id,
-												 const LLAvatarName& av_name)
-{
-	LLTextBox* contactName = getChild<LLTextBox>("contact_name");
-	contactName->setValue( av_name.getCompleteName() );
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param)
-{
-	LLTextBox* text = getChild<LLTextBox>("contact_name");
-	S32 new_text_left = mChiclet->getRect().mRight + CHICLET_HPAD;
-	LLRect text_rect = text->getRect(); 
-	text_rect.mLeft = new_text_left;
-	text->setShape(text_rect);
-}
-
-//---------------------------------------------------------------------------------
-LLIMWellWindow::RowPanel::~RowPanel()
-{
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onClosePanel()
-{
-	gIMMgr->leaveSession(mChiclet->getSessionId());
-	// This row panel will be removed from the list in LLSysWellWindow::sessionRemoved().
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseEnter(S32 x, S32 y, MASK mask)
-{
-	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemSelected"));
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::RowPanel::onMouseLeave(S32 x, S32 y, MASK mask)
-{
-	setTransparentColor(LLUIColorTable::instance().getColor("SysWellItemUnselected"));
-}
-
-//---------------------------------------------------------------------------------
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	// Pass the mouse down event to the chiclet (EXT-596).
-	if (!mChiclet->pointInView(x, y) && !mCloseBtn->getRect().pointInRect(x, y)) // prevent double call of LLIMChiclet::onMouseDown()
-	{
-		mChiclet->onMouseDown();
-		return TRUE;
-	}
-
-	return LLPanel::handleMouseDown(x, y, mask);
-}
-
-// virtual
-BOOL LLIMWellWindow::RowPanel::handleRightMouseDown(S32 x, S32 y, MASK mask)
-{
-	return mChiclet->handleRightMouseDown(x, y, mask);
-}
 /************************************************************************/
 /*         ObjectRowPanel implementation                                */
 /************************************************************************/
@@ -433,13 +296,19 @@ BOOL LLIMWellWindow::ObjectRowPanel::handleRightMouseDown(S32 x, S32 y, MASK mas
 
 //////////////////////////////////////////////////////////////////////////
 // PUBLIC METHODS
+LLNotificationWellWindow::WellNotificationChannel::WellNotificationChannel(LLNotificationWellWindow* well_window)
+:	LLNotificationChannel(LLNotificationChannel::Params().name(well_window->getPathname())),
+	mWellWindow(well_window)
+{
+	connectToChannel("Notifications");
+	connectToChannel("Group Notifications");
+	connectToChannel("Offer");
+}
+
 LLNotificationWellWindow::LLNotificationWellWindow(const LLSD& key)
-: LLSysWellWindow(key)
+:	LLSysWellWindow(key)
 {
-	// init connections to the list's update events
-	connectListUpdaterToSignal("notify");
-	connectListUpdaterToSignal("groupnotify");
-	connectListUpdaterToSignal("offer");
+	mNotificationUpdates.reset(new WellNotificationChannel(this));
 }
 
 // static
@@ -481,7 +350,6 @@ void LLNotificationWellWindow::addItem(LLSysWellItem::Params p)
 	{
 		mSysWellChiclet->updateWidget(isWindowEmpty());
 		reshapeWindow();
-
 		new_item->setOnItemCloseCallback(boost::bind(&LLNotificationWellWindow::onItemClose, this, _1));
 		new_item->setOnItemClickCallback(boost::bind(&LLNotificationWellWindow::onItemClick, this, _1));
 	}
@@ -519,7 +387,7 @@ void LLNotificationWellWindow::initChannel()
 	LLSysWellWindow::initChannel();
 	if(mChannel)
 	{
-		mChannel->setOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
+		mChannel->addOnStoreToastCallback(boost::bind(&LLNotificationWellWindow::onStoreToast, this, _1, _2));
 	}
 }
 
@@ -546,20 +414,6 @@ void LLNotificationWellWindow::onStoreToast(LLPanel* info_panel, LLUUID id)
 	addItem(p);
 }
 
-void LLNotificationWellWindow::connectListUpdaterToSignal(std::string notification_type)
-{
-	LLNotificationsUI::LLNotificationManager* manager = LLNotificationsUI::LLNotificationManager::getInstance();
-	LLNotificationsUI::LLEventHandler* n_handler = manager->getHandlerForNotification(notification_type);
-	if(n_handler)
-	{
-		n_handler->setNotificationIDCallback(boost::bind(&LLNotificationWellWindow::removeItemByID, this, _1));
-	}
-	else
-	{
-		llwarns << "LLSysWellWindow::connectListUpdaterToSignal() - could not get a handler for '" << notification_type <<"' type of notifications" << llendl;
-	}
-}
-
 void LLNotificationWellWindow::onItemClick(LLSysWellItem* item)
 {
 	LLUUID id = item->getID();
@@ -574,7 +428,10 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
 		mChannel->killToastByNotificationID(id);
 }
 
-
+void LLNotificationWellWindow::onAdd( LLNotificationPtr notify )
+{
+	removeItemByID(notify->getID());
+}
 
 /************************************************************************/
 /*         LLIMWellWindow  implementation                               */
@@ -585,12 +442,10 @@ void LLNotificationWellWindow::onItemClose(LLSysWellItem* item)
 LLIMWellWindow::LLIMWellWindow(const LLSD& key)
 : LLSysWellWindow(key)
 {
-	LLIMMgr::getInstance()->addSessionObserver(this);
 }
 
 LLIMWellWindow::~LLIMWellWindow()
 {
-	LLIMMgr::getInstance()->removeSessionObserver(this);
 }
 
 // static
@@ -611,47 +466,11 @@ BOOL LLIMWellWindow::postBuild()
 	BOOL rv = LLSysWellWindow::postBuild();
 	setTitle(getString("title_im_well_window"));
 
-	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findIMChiclet, this, _1));
 	LLIMChiclet::sFindChicletsSignal.connect(boost::bind(&LLIMWellWindow::findObjectChiclet, this, _1));
 
 	return rv;
 }
 
-//virtual
-void LLIMWellWindow::sessionAdded(const LLUUID& session_id,
-								   const std::string& name, const LLUUID& other_participant_id)
-{
-	LLIMModel::LLIMSession* session = LLIMModel::getInstance()->findIMSession(session_id);
-	if (!session) return;
-
-	// no need to spawn chiclets for participants in P2P calls called through Avaline
-	if (session->isP2P() && session->isOtherParticipantAvaline()) return;
-
-	if (mMessageList->getItemByValue(session_id)) return;
-
-	addIMRow(session_id, 0, name, other_participant_id);	
-	reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionRemoved(const LLUUID& sessionId)
-{
-	delIMRow(sessionId);
-	reshapeWindow();
-}
-
-//virtual
-void LLIMWellWindow::sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id)
-{
-	//for outgoing ad-hoc and group im sessions only
-	LLChiclet* chiclet = findIMChiclet(old_session_id);
-	if (chiclet)
-	{
-		chiclet->setSessionId(new_session_id);
-		mMessageList->updateValue(old_session_id, new_session_id);
-	}
-}
-
 LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
 {
 	if (!mMessageList) return NULL;
@@ -668,85 +487,13 @@ LLChiclet* LLIMWellWindow::findObjectChiclet(const LLUUID& notification_id)
 
 //////////////////////////////////////////////////////////////////////////
 // PRIVATE METHODS
-LLChiclet* LLIMWellWindow::findIMChiclet(const LLUUID& sessionId)
-{
-	if (!mMessageList) return NULL;
-
-	LLChiclet* res = NULL;
-	RowPanel* panel = mMessageList->getTypedItemByValue<RowPanel>(sessionId);
-	if (panel != NULL)
-	{
-		res = panel->mChiclet;
-	}
-
-	return res;
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::addIMRow(const LLUUID& sessionId, S32 chicletCounter,
-							   const std::string& name, const LLUUID& otherParticipantId)
-{
-	RowPanel* item = new RowPanel(this, sessionId, chicletCounter, name, otherParticipantId);
-	if (mMessageList->addItem(item, sessionId))
-	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
-	}
-	else
-	{
-		llwarns << "Unable to add IM Row into the list, sessionID: " << sessionId
-			<< ", name: " << name
-			<< ", other participant ID: " << otherParticipantId
-			<< llendl;
-
-		item->die();
-	}
-}
-
-//---------------------------------------------------------------------------------
-void LLIMWellWindow::delIMRow(const LLUUID& sessionId)
-{
-	//fix for EXT-3252
-	//without this line LLIMWellWindow receive onFocusLost
-	//and hide itself. It was becaue somehow LLIMChicklet was in focus group for
-	//LLIMWellWindow...
-	//But I didn't find why this happen..
-	gFocusMgr.clearLastFocusForGroup(this);
-
-	if (mMessageList->removeItemByValue(sessionId))
-	{
-		mSysWellChiclet->updateWidget(isWindowEmpty());
-	}
-	else
-	{
-		llwarns << "Unable to remove IM Row from the list, sessionID: " << sessionId
-			<< llendl;
-	}
-
-	// remove all toasts that belong to this session from a screen
-	if(mChannel)
-		mChannel->removeToastsBySessionID(sessionId);
-
-	// hide chiclet window if there are no items left
-	if(isWindowEmpty())
-	{
-		setVisible(FALSE);
-	}
-	else
-	{
-		setFocus(true);
-	}
-}
 
 void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_message/* = false*/)
 {
 	if (mMessageList->getItemByValue(notification_id) == NULL)
 	{
 		ObjectRowPanel* item = new ObjectRowPanel(notification_id, new_message);
-		if (mMessageList->addItem(item, notification_id))
-		{
-			mSysWellChiclet->updateWidget(isWindowEmpty());
-		}
-		else
+		if (!mMessageList->addItem(item, notification_id))
 		{
 			llwarns << "Unable to add Object Row into the list, notificationID: " << notification_id << llendl;
 			item->die();
@@ -757,14 +504,7 @@ void LLIMWellWindow::addObjectRow(const LLUUID& notification_id, bool new_messag
 
 void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
 {
-	if (mMessageList->removeItemByValue(notification_id))
-	{
-		if (mSysWellChiclet)
-		{
-			mSysWellChiclet->updateWidget(isWindowEmpty());
-		}
-	}
-	else
+	if (!mMessageList->removeItemByValue(notification_id))
 	{
 		llwarns << "Unable to remove Object Row from the list, notificationID: " << notification_id << llendl;
 	}
@@ -777,21 +517,6 @@ void LLIMWellWindow::removeObjectRow(const LLUUID& notification_id)
 	}
 }
 
-
-void LLIMWellWindow::addIMRow(const LLUUID& session_id)
-{
-	if (hasIMRow(session_id)) return;
-
-	LLIMModel* im_model = LLIMModel::getInstance();
-	addIMRow(session_id, 0, im_model->getName(session_id), im_model->getOtherParticipantID(session_id));
-	reshapeWindow();
-}
-
-bool LLIMWellWindow::hasIMRow(const LLUUID& session_id)
-{
-	return mMessageList->getItemByValue(session_id);
-}
-
 void LLIMWellWindow::closeAll()
 {
 	// Generate an ignorable alert dialog if there is an active voice IM sesion
@@ -836,13 +561,6 @@ void LLIMWellWindow::closeAllImpl()
 	{
 		LLPanel* panel = mMessageList->getItemByValue(*iter);
 
-		RowPanel* im_panel = dynamic_cast <RowPanel*> (panel);
-		if (im_panel)
-		{
-			gIMMgr->leaveSession(*iter);
-			continue;
-		}
-
 		ObjectRowPanel* obj_panel = dynamic_cast <ObjectRowPanel*> (panel);
 		if (obj_panel)
 		{
@@ -867,4 +585,4 @@ bool LLIMWellWindow::confirmCloseAll(const LLSD& notification, const LLSD& respo
 	return false;
 }
 
-// EOF
+
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index 272e9cfcb1248044eb9282a3d6dc41863fae7151..cc5c057d8b395c8dd5ef17e260668eb12df72026 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -27,29 +27,26 @@
 #ifndef LL_LLSYSWELLWINDOW_H
 #define LL_LLSYSWELLWINDOW_H
 
+#include "llimview.h"
+#include "llnotifications.h"
+#include "llscreenchannel.h"
 #include "llsyswellitem.h"
-
 #include "lltransientdockablefloater.h"
-#include "llbutton.h"
-#include "llscreenchannel.h"
-#include "llscrollcontainer.h"
-#include "llimview.h"
-
-#include "boost/shared_ptr.hpp"
 
 class LLAvatarName;
-class LLFlatListView;
 class LLChiclet;
+class LLFlatListView;
 class LLIMChiclet;
 class LLScriptChiclet;
 class LLSysWellChiclet;
 
-
 class LLSysWellWindow : public LLTransientDockableFloater
 {
 public:
+	LOG_CLASS(LLSysWellWindow);
+
     LLSysWellWindow(const LLSD& key);
-    ~LLSysWellWindow();
+    virtual ~LLSysWellWindow();
 	BOOL postBuild();
 
 	// other interface functions
@@ -84,7 +81,6 @@ class LLSysWellWindow : public LLTransientDockableFloater
 	virtual const std::string& getAnchorViewName() = 0;
 
 	void reshapeWindow();
-	void releaseNewMessagesState();
 
 	// pointer to a corresponding channel's instance
 	LLNotificationsUI::LLScreenChannel*	mChannel;
@@ -111,7 +107,7 @@ class LLNotificationWellWindow : public LLSysWellWindow
 
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void setVisible(BOOL visible);
-
+	/*virtual*/ void onAdd(LLNotificationPtr notify);
 	// Operating with items
 	void addItem(LLSysWellItem::Params p);
 
@@ -119,6 +115,18 @@ class LLNotificationWellWindow : public LLSysWellWindow
 	void closeAll();
 
 protected:
+	struct WellNotificationChannel : public LLNotificationChannel
+	{
+		WellNotificationChannel(LLNotificationWellWindow*);
+		void onDelete(LLNotificationPtr notify)
+		{
+			mWellWindow->removeItemByID(notify->getID());
+		} 
+
+		LLNotificationWellWindow* mWellWindow;
+	};
+
+	LLNotificationChannelPtr mNotificationUpdates;
 	/*virtual*/ const std::string& getAnchorViewName() { return NOTIFICATION_WELL_ANCHOR_NAME; }
 
 private:
@@ -126,12 +134,8 @@ class LLNotificationWellWindow : public LLSysWellWindow
 	void initChannel();
 	void clearScreenChannels();
 
-
 	void onStoreToast(LLPanel* info_panel, LLUUID id);
 
-	// connect counter and list updaters to the corresponding signals
-	void connectListUpdaterToSignal(std::string notification_type);
-
 	// Handlers
 	void onItemClick(LLSysWellItem* item);
 	void onItemClose(LLSysWellItem* item);
@@ -146,7 +150,7 @@ class LLNotificationWellWindow : public LLSysWellWindow
  * 
  * It contains a list list of all active IM sessions.
  */
-class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<LLIMWellWindow>
+class LLIMWellWindow : public LLSysWellWindow, LLInitClass<LLIMWellWindow>
 {
 public:
 	LLIMWellWindow(const LLSD& key);
@@ -158,57 +162,19 @@ class LLIMWellWindow : public LLSysWellWindow, LLIMSessionObserver, LLInitClass<
 
 	/*virtual*/ BOOL postBuild();
 
-	// LLIMSessionObserver observe triggers
-	/*virtual*/ void sessionAdded(const LLUUID& session_id, const std::string& name, const LLUUID& other_participant_id);
-	/*virtual*/ void sessionRemoved(const LLUUID& session_id);
-	/*virtual*/ void sessionIDUpdated(const LLUUID& old_session_id, const LLUUID& new_session_id);
-
 	void addObjectRow(const LLUUID& notification_id, bool new_message = false);
 	void removeObjectRow(const LLUUID& notification_id);
-
-	void addIMRow(const LLUUID& session_id);
-	bool hasIMRow(const LLUUID& session_id);
-
 	void closeAll();
 
 protected:
 	/*virtual*/ const std::string& getAnchorViewName() { return IM_WELL_ANCHOR_NAME; }
 
 private:
-	LLChiclet * findIMChiclet(const LLUUID& sessionId);
 	LLChiclet* findObjectChiclet(const LLUUID& notification_id);
 
-	void addIMRow(const LLUUID& sessionId, S32 chicletCounter, const std::string& name, const LLUUID& otherParticipantId);
-	void delIMRow(const LLUUID& sessionId);
 	bool confirmCloseAll(const LLSD& notification, const LLSD& response);
 	void closeAllImpl();
 
-	/**
-	 * Scrolling row panel.
-	 */
-	class RowPanel: public LLPanel
-	{
-	public:
-		RowPanel(const LLSysWellWindow* parent, const LLUUID& sessionId, S32 chicletCounter,
-				const std::string& name, const LLUUID& otherParticipantId);
-		virtual ~RowPanel();
-		void onMouseEnter(S32 x, S32 y, MASK mask);
-		void onMouseLeave(S32 x, S32 y, MASK mask);
-		BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-		BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
-
-	private:
-		static const S32 CHICLET_HPAD = 10;
-		void onAvatarNameCache(const LLUUID& agent_id, const LLAvatarName& av_name);
-		void onChicletSizeChanged(LLChiclet* ctrl, const LLSD& param);
-		void onClosePanel();
-	public:
-		LLIMChiclet* mChiclet;
-	private:
-		LLButton*	mCloseBtn;
-		const LLSysWellWindow* mParent;
-	};
-
 	class ObjectRowPanel: public LLPanel
 	{
 	public:
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index ec36cf48c2fbf7974a18f279eca874cd97679a26..e2d0fdf3576579558378b1d947ad45019ccd992f 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -39,7 +39,7 @@
 #include "llfocusmgr.h"
 #include "llviewertexture.h"
 #include "llfolderview.h"
-#include "llfoldervieweventlistener.h"
+#include "llfolderviewmodel.h"
 #include "llinventory.h"
 #include "llinventoryfunctions.h"
 #include "llinventorymodelbackgroundfetch.h"
@@ -58,6 +58,7 @@
 #include "lltoolmgr.h"
 #include "lltoolpipette.h"
 #include "llfiltereditor.h"
+#include "llwindow.h"
 
 #include "lltool.h"
 #include "llviewerwindow.h"
@@ -186,7 +187,7 @@ class LLFloaterTexturePicker : public LLFloater
 	F32					mContextConeOpacity;
 	LLSaveFolderState	mSavedFolderState;
 	BOOL				mSelectedItemPinned;
-	
+
 	LLRadioGroup*		mModeSelector;
 	LLScrollListCtrl*	mLocalScrollCtrl;
 
@@ -372,7 +373,7 @@ BOOL LLFloaterTexturePicker::handleKeyHere(KEY key, MASK mask)
 		{
 			if (!root_folder->getCurSelectedItem())
 			{
-				LLFolderViewItem* itemp = root_folder->getItemByID(gInventory.getRootFolderID());
+				LLFolderViewItem* itemp =    mInventoryPanel->getItemByID(gInventory.getRootFolderID());
 				if (itemp)
 				{
 					root_folder->setSelection(itemp, FALSE, FALSE);
@@ -454,7 +455,7 @@ BOOL LLFloaterTexturePicker::postBuild()
 
 		// Commented out to scroll to currently selected texture. See EXT-5403.
 		// // store this filter as the default one
-		// mInventoryPanel->getRootFolder()->getFilter()->markDefault();
+		// mInventoryPanel->getRootFolder()->getFilter().markDefault();
 
 		// Commented out to stop opening all folders with textures
 		// mInventoryPanel->openDefaultFolderForType(LLFolderType::FT_TEXTURE);
@@ -570,8 +571,8 @@ void LLFloaterTexturePicker::draw()
 		mTexturep = NULL;
 		if(mImageAssetID.notNull())
 		{
-			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES);
-			mTexturep->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+			mTexturep = LLViewerTextureManager::getFetchedTexture(mImageAssetID);
+			mTexturep->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		}
 
 		if (mTentativeLabel)
@@ -637,11 +638,10 @@ void LLFloaterTexturePicker::draw()
 		LLFolderView* folder_view = mInventoryPanel->getRootFolder();
 		if (!folder_view) return;
 
-		LLInventoryFilter* filter = folder_view->getFilter();
-		if (!filter) return;
+		LLFolderViewFilter& filter = static_cast<LLFolderViewModelInventory*>(folder_view->getFolderViewModel())->getFilter();
 
-		bool is_filter_active = folder_view->getCompletedFilterGeneration() < filter->getCurrentGeneration() &&
-				filter->isNotDefault();
+		bool is_filter_active = folder_view->getViewModelItem()->getLastFilterGeneration() < filter.getCurrentGeneration() &&
+				filter.isNotDefault();
 
 		// After inventory panel filter is applied we have to update
 		// constraint rect for the selected item because of folder view
@@ -651,26 +651,12 @@ void LLFloaterTexturePicker::draw()
 		if (!is_filter_active && !mSelectedItemPinned)
 		{
 			folder_view->setPinningSelectedItem(mSelectedItemPinned);
-			folder_view->dirtyFilter();
-			folder_view->arrangeFromRoot();
-
+			folder_view->getViewModelItem()->dirtyFilter();
 			mSelectedItemPinned = TRUE;
 		}
 	}
 }
 
-// static
-/*
-void LLFloaterTexturePicker::onSaveAnotherCopyDialog( S32 option, void* userdata )
-{
-	LLFloaterTexturePicker* self = (LLFloaterTexturePicker*) userdata;
-	if( 0 == option )
-	{
-		self->copyToInventoryFinal();
-	}
-}
-*/
-
 const LLUUID& LLFloaterTexturePicker::findItemID(const LLUUID& asset_id, BOOL copyable_only)
 {
 	LLViewerInventoryCategory::cat_array_t cats;
@@ -815,7 +801,7 @@ void LLFloaterTexturePicker::onSelectionChange(const std::deque<LLFolderViewItem
 	if (items.size())
 	{
 		LLFolderViewItem* first_item = items.front();
-		LLInventoryItem* itemp = gInventory.getItem(first_item->getListener()->getUUID());
+		LLInventoryItem* itemp = gInventory.getItem(static_cast<LLFolderViewModelItemInventory*>(first_item->getViewModelItem())->getUUID());
 		mNoCopyTextureSelected = FALSE;
 		if (itemp)
 		{
@@ -1011,7 +997,7 @@ void LLFloaterTexturePicker::onFilterEdit(const std::string& search_string )
 	else if (mInventoryPanel->getFilterSubString().empty())
 	{
 		// first letter in search term, save existing folder open state
-		if (!mInventoryPanel->getRootFolder()->isFilterModified())
+		if (!mInventoryPanel->getFilter().isNotDefault())
 		{
 			mSavedFolderState.setApply(FALSE);
 			mInventoryPanel->getRootFolder()->applyFunctorRecursively(mSavedFolderState);
@@ -1325,7 +1311,7 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
 		// (i.e. op == TEXTURE_SELECT) or texture changes via DnD.
 		else if (mCommitOnSelection || op == TEXTURE_SELECT)
 			mViewModel->setDirty(); // *TODO: shouldn't we be using setValue() here?
-
+			
 		if(floaterp->isDirty() || id.notNull()) // mModelView->setDirty does not work.
 		{
 			setTentative( FALSE );
@@ -1337,10 +1323,10 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLUUID id)
 			}
 			else
 			{
-				mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
-				lldebugs << "mImageItemID: " << mImageItemID << llendl;
-				mImageAssetID = floaterp->getAssetID();
-				lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
+			mImageItemID = floaterp->findItemID(floaterp->getAssetID(), FALSE);
+			lldebugs << "mImageItemID: " << mImageItemID << llendl;
+			mImageAssetID = floaterp->getAssetID();
+			lldebugs << "mImageAssetID: " << mImageAssetID << llendl;
 			}
 
 			if (op == TEXTURE_SELECT && mOnSelectCallback)
@@ -1456,9 +1442,9 @@ void LLTextureCtrl::draw()
 	}
 	else if (!mImageAssetID.isNull())
 	{
-		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, MIPMAP_YES,LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+		LLPointer<LLViewerFetchedTexture> texture = LLViewerTextureManager::getFetchedTexture(mImageAssetID, FTT_DEFAULT, MIPMAP_YES,LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 		
-		texture->setBoostLevel(LLViewerTexture::BOOST_PREVIEW);
+		texture->setBoostLevel(LLGLTexture::BOOST_PREVIEW);
 		texture->forceToSaveRawImage(0) ;
 
 		mTexturep = texture;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 7de66b139f5886cbc6d2c6d27f0ec8cce2afccd3..be5fde9e2b020b31b88e4bbabb0955552270f1fb 100755
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -389,7 +389,8 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	virtual void onCompleted(LLCore::HttpHandle handle, LLCore::HttpResponse * response);
 	
 protected:
-	LLTextureFetchWorker(LLTextureFetch* fetcher, const std::string& url, const LLUUID& id, const LLHost& host,
+	LLTextureFetchWorker(LLTextureFetch* fetcher, FTType f_type,
+						 const std::string& url, const LLUUID& id, const LLHost& host,
 						 F32 priority, S32 discard, S32 size);
 
 private:
@@ -501,11 +502,13 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	};
 	static const char* sStateDescs[];
 	e_state mState;
+	void setState(e_state new_state);
 	e_write_to_cache_state mWriteToCacheState;
 	LLTextureFetch* mFetcher;
 	LLPointer<LLImageFormatted> mFormattedImage;
 	LLPointer<LLImageRaw> mRawImage;
 	LLPointer<LLImageRaw> mAuxImage;
+	FTType mFTType;
 	LLUUID mID;
 	LLHost mHost;
 	std::string mUrl;
@@ -827,6 +830,7 @@ volatile bool LLTextureFetch::svMetricsDataBreak(true);	// Start with a data bre
 // called from MAIN THREAD
 
 LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
+										   FTType f_type, // Fetched image type
 										   const std::string& url, // Optional URL
 										   const LLUUID& id,	// Image UUID
 										   const LLHost& host,	// Simulator host
@@ -838,6 +842,7 @@ LLTextureFetchWorker::LLTextureFetchWorker(LLTextureFetch* fetcher,
 	  mState(INIT),
 	  mWriteToCacheState(NOT_WRITE),
 	  mFetcher(fetcher),
+	  mFTType(f_type),
 	  mID(id),
 	  mHost(host),
 	  mUrl(url),
@@ -1024,7 +1029,7 @@ void LLTextureFetchWorker::setDesiredDiscard(S32 discard, S32 size)
 	mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE);
 	if ((prioritize && mState == INIT) || mState == DONE)
 	{
-		mState = INIT;
+		setState(INIT);
 		U32 work_priority = mWorkPriority | LLWorkerThread::PRIORITY_HIGH;
 		setPriority(work_priority);
 	}
@@ -1088,12 +1093,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if (mState == INIT || mState == LOAD_FROM_NETWORK || mState == LOAD_FROM_SIMULATOR)
 		{
+			LL_DEBUGS("Texture") << mID << " abort: mImagePriority < F_ALMOST_ZERO" << llendl;
 			return true; // abort
 		}
 	}
 	if(mState > CACHE_POST && !mCanUseNET && !mCanUseHTTP)
 	{
 		//nowhere to get data, abort.
+		LL_WARNS("Texture") << mID << " abort, nowhere to get data" << llendl;
 		return true ;
 	}
 
@@ -1136,7 +1143,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		clearPackets(); // TODO: Shouldn't be necessary
 		mCacheReadHandle = LLTextureCache::nullHandle();
 		mCacheWriteHandle = LLTextureCache::nullHandle();
-		mState = LOAD_FROM_TEXTURE_CACHE;
+		setState(LOAD_FROM_TEXTURE_CACHE);
 		mInCache = FALSE;
 		mDesiredSize = llmax(mDesiredSize, TEXTURE_CACHE_ENTRY_SIZE); // min desired size is TEXTURE_CACHE_ENTRY_SIZE
 		LL_DEBUGS("Texture") << mID << ": Priority: " << llformat("%8.0f",mImagePriority)
@@ -1153,7 +1160,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			S32 size = mDesiredSize - offset;
 			if (size <= 0)
 			{
-				mState = CACHE_POST;
+				setState(CACHE_POST);
 				return false;
 			}
 			mFileSize = 0;
@@ -1171,6 +1178,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 																		  offset, size, responder);
 				mCacheReadTimer.reset();
 			}
+/* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+/*			else if ((mUrl.empty()||mFTType==FTT_SERVER_BAKE) && mFetcher->canLoadFromCache()) */
 			else if (mUrl.empty() && mFetcher->canLoadFromCache())
 			{
 				setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
@@ -1183,18 +1192,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			else if(!mUrl.empty() && mCanUseHTTP)
 			{
-				if (!(mUrl.compare(0, 7, "http://") == 0))
-				{
-					// *TODO:?remove this warning
-					llwarns << "Unknown URL Type: " << mUrl << llendl;
-				}
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = WAIT_HTTP_RESOURCE;
+				setState(WAIT_HTTP_RESOURCE);
 			}
 			else
 			{
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = LOAD_FROM_NETWORK;
+				setState(LOAD_FROM_NETWORK);
 			}
 		}
 
@@ -1204,7 +1208,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			if (mFetcher->mTextureCache->readComplete(mCacheReadHandle, false))
 			{
 				mCacheReadHandle = LLTextureCache::nullHandle();
-				mState = CACHE_POST;
+				setState(CACHE_POST);
 				// fall through
 			}
 			else
@@ -1212,6 +1216,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				//
 				//This should never happen
 				//
+				LL_DEBUGS("Texture") << mID << " this should never happen" << llendl;
 				return false;
 			}
 		}
@@ -1230,7 +1235,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// we have enough data, decode it
 			llassert_always(mFormattedImage->getDataSize() > 0);
 			mLoadedDiscard = mDesiredDiscard;
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			mInCache = TRUE;
 			mWriteToCacheState = NOT_WRITE ;
 			LL_DEBUGS("Texture") << mID << ": Cached. Bytes: " << mFormattedImage->getDataSize()
@@ -1243,13 +1253,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			if (mUrl.compare(0, 7, "file://") == 0)
 			{
 				// failed to load local file, we're done.
+				LL_WARNS("Texture") << mID << ": abort, failed to load local file " << mUrl << LL_ENDL;
 				return true;
 			}
 			// need more data
 			else
 			{
 				LL_DEBUGS("Texture") << mID << ": Not in Cache" << LL_ENDL;
-				mState = LOAD_FROM_NETWORK;
+				setState(LOAD_FROM_NETWORK);
 			}
 			
 			// fall through
@@ -1290,9 +1301,15 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				mCanUseHTTP = false;
 			}
 		}
+#if 0 /* SH-3980 - disabling caching of server bakes until we can fix the blurring problems */
+		if (mFTType == FTT_SERVER_BAKE)
+		{
+			mWriteToCacheState = CAN_WRITE;
+		}
+#endif
 		if (mCanUseHTTP && !mUrl.empty())
 		{
-			mState = WAIT_HTTP_RESOURCE;
+			setState(WAIT_HTTP_RESOURCE);
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			if(mWriteToCacheState != NOT_WRITE)
 			{
@@ -1322,6 +1339,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			//mFetcher->addToNetworkQueue(this);
 			//recordTextureStart(false);
 			//setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
+
+			LL_DEBUGS("Texture") << mID << " does this happen?" << llendl;
 			return false;
 		}
 	}
@@ -1340,10 +1359,16 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			{
 				// processSimulatorPackets() failed
 // 				llwarns << "processSimulatorPackets() failed to load buffer" << llendl;
+				LL_WARNS("Texture") << mID << " processSimulatorPackets() failed to load buffer" << llendl;
 				return true; // failed
 			}
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			mWriteToCacheState = SHOULD_WRITE;
 			recordTextureDone(false);
 		}
@@ -1367,14 +1392,14 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		// Otherwise, advance into the HTTP states.
 		if (mFetcher->getHttpWaitersCount() || ! acquireHttpSemaphore())
 		{
-			mState = WAIT_HTTP_RESOURCE2;
+			setState(WAIT_HTTP_RESOURCE2);
 			setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
 			mFetcher->addHttpWaiter(this->mID);
 			++mResourceWaitCount;
 			return false;
 		}
 		
-		mState = SEND_HTTP_REQ;
+		setState(SEND_HTTP_REQ);
 		// *NOTE:  You must invoke releaseHttpSemaphore() if you transition
 		// to a state other than SEND_HTTP_REQ or WAIT_HTTP_REQ or abort
 		// the request.
@@ -1391,6 +1416,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (! mCanUseHTTP)
 		{
 			releaseHttpSemaphore();
+			LL_WARNS("Texture") << mID << " abort: SEND_HTTP_REQ but !mCanUseHTTP" << llendl;
 			return true; // abort
 		}
 
@@ -1407,13 +1433,19 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// We already have all the data, just decode it
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = DECODE_IMAGE;
+					if (mLoadedDiscard < 0)
+					{
+						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+											<< ", should be >=0" << llendl;
+					}
+					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
 					return false;
 				}
 				else
 				{
 					releaseHttpSemaphore();
+					LL_WARNS("Texture") << mID << " SEND_HTTP_REQ abort: cur_size " << cur_size << " <=0" << llendl;
 					return true; // abort.
 				}
 			}
@@ -1471,7 +1503,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		mFetcher->addToHTTPQueue(mID);
 		recordTextureStart(true);
 		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority);
-		mState = WAIT_HTTP_REQ;	
+		setState(WAIT_HTTP_REQ);	
 		
 		// fall through
 	}
@@ -1489,8 +1521,9 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					if(mWriteToCacheState == NOT_WRITE) //map tiles
 					{
-						mState = DONE;
+						setState(DONE);
 						releaseHttpSemaphore();
+						LL_DEBUGS("Texture") << mID << " abort: WAIT_HTTP_REQ not found" << llendl;
 						return true; // failed, means no map tile on the empty region.
 					}
 
@@ -1499,7 +1532,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// roll back to try UDP
 					if (mCanUseNET)
 					{
-						mState = INIT;
+						setState(INIT);
 						mCanUseHTTP = false;
 						mUrl.clear();
 						setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
@@ -1530,15 +1563,21 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					// Use available data
 					mLoadedDiscard = mFormattedImage->getDiscardLevel();
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = DECODE_IMAGE;
+					if (mLoadedDiscard < 0)
+					{
+						LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+											<< ", should be >=0" << llendl;
+					}
+					setState(DECODE_IMAGE);
 					releaseHttpSemaphore();
 					return false; 
 				}
 
 				// Fail harder
 				resetFormattedData();
-				mState = DONE;
+				setState(DONE);
 				releaseHttpSemaphore();
+				LL_WARNS("Texture") << mID << " abort: fail harder" << llendl;
 				return true; // failed
 			}
 			
@@ -1547,6 +1586,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			// next time the texture is requested, even if the data have already been fetched.
 			if(mWriteToCacheState != NOT_WRITE)
 			{
+				// Why do we want to keep url if NOT_WRITE - is this a proxy for map tiles?
 				mUrl.clear();
 			}
 			
@@ -1560,7 +1600,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				}
 
 				// abort.
-				mState = DONE;
+				setState(DONE);
+				LL_WARNS("Texture") << mID << " abort: no data received" << llendl;
 				releaseHttpSemaphore();
 				return true;
 			}
@@ -1578,7 +1619,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				{
 					LL_WARNS("Texture") << "Partial HTTP response produces break in image data for texture "
 										<< mID << ".  Aborting load."  << LL_ENDL;
-					mState = DONE;
+					setState(DONE);
 					releaseHttpSemaphore();
 					return true;
 				}
@@ -1626,7 +1667,12 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			mHttpReplyOffset = 0;
 			
 			mLoadedDiscard = mRequestedDiscard;
-			mState = DECODE_IMAGE;
+			if (mLoadedDiscard < 0)
+			{
+				LL_WARNS("Texture") << mID << " mLoadedDiscard is " << mLoadedDiscard
+									<< ", should be >=0" << llendl;
+			}
+			setState(DECODE_IMAGE);
 			if (mWriteToCacheState != NOT_WRITE)
 			{
 				mWriteToCacheState = SHOULD_WRITE ;
@@ -1657,31 +1703,34 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (textures_decode_disabled)
 		{
 			// for debug use, don't decode
-			mState = DONE;
+			setState(DONE);
 			return true;
 		}
 
 		if (mDesiredDiscard < 0)
 		{
 			// We aborted, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: desired discard " << mDesiredDiscard << "<0" << llendl;
 			return true;
 		}
 		
 		if (mFormattedImage->getDataSize() <= 0)
 		{
-			//llerrs << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
+			llwarns << "Decode entered with invalid mFormattedImage. ID = " << mID << llendl;
 			
 			//abort, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: (mFormattedImage->getDataSize() <= 0)" << llendl;
 			return true;
 		}
 		if (mLoadedDiscard < 0)
 		{
-			//llerrs << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
+			llwarns << "Decode entered with invalid mLoadedDiscard. ID = " << mID << llendl;
 
 			//abort, don't decode
-			mState = DONE;
+			setState(DONE);
+			LL_DEBUGS("Texture") << mID << " DECODE_IMAGE abort: mLoadedDiscard < 0" << llendl;
 			return true;
 		}
 
@@ -1691,7 +1740,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		S32 discard = mHaveAllData ? 0 : mLoadedDiscard;
 		U32 image_priority = LLWorkerThread::PRIORITY_NORMAL | mWorkPriority;
 		mDecoded  = FALSE;
-		mState = DECODE_IMAGE_UPDATE;
+		setState(DECODE_IMAGE_UPDATE);
 		LL_DEBUGS("Texture") << mID << ": Decoding. Bytes: " << mFormattedImage->getDataSize() << " Discard: " << discard
 				<< " All Data: " << mHaveAllData << LL_ENDL;
 		mDecodeHandle = mFetcher->mImageDecodeThread->decodeImage(mFormattedImage, image_priority, discard, mNeedsAux,
@@ -1719,13 +1768,13 @@ bool LLTextureFetchWorker::doWork(S32 param)
 					mFormattedImage = NULL;
 					++mRetryAttempt;
 					setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-					mState = INIT;
+					setState(INIT);
 					return false;
 				}
 				else
 				{
 // 					llwarns << "UNABLE TO LOAD TEXTURE: " << mID << " RETRIES: " << mRetryAttempt << llendl;
-					mState = DONE; // failed
+					setState(DONE); // failed
 				}
 			}
 			else
@@ -1734,7 +1783,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 				LL_DEBUGS("Texture") << mID << ": Decoded. Discard: " << mDecodedDiscard
 						<< " Raw Image: " << llformat("%dx%d",mRawImage->getWidth(),mRawImage->getHeight()) << LL_ENDL;
 				setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
-				mState = WRITE_TO_CACHE;
+				setState(WRITE_TO_CACHE);
 			}
 			// fall through
 		}
@@ -1750,7 +1799,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		{
 			// If we're in a local cache or we didn't actually receive any new data,
 			// or we failed to load anything, skip
-			mState = DONE;
+			setState(DONE);
 			return false;
 		}
 		S32 datasize = mFormattedImage->getDataSize();
@@ -1769,7 +1818,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		setPriority(LLWorkerThread::PRIORITY_LOW | mWorkPriority); // Set priority first since Responder may change it
 		U32 cache_priority = mWorkPriority;
 		mWritten = FALSE;
-		mState = WAIT_ON_WRITE;
+		setState(WAIT_ON_WRITE);
 		++mCacheWriteCount;
 		CacheWriteResponder* responder = new CacheWriteResponder(mFetcher, mID);
 		mCacheWriteHandle = mFetcher->mTextureCache->writeToCache(mID, cache_priority,
@@ -1782,7 +1831,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 	{
 		if (writeToCacheComplete())
 		{
-			mState = DONE;
+			setState(DONE);
 			// fall through
 		}
 		else
@@ -1803,7 +1852,10 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		if (mDecodedDiscard >= 0 && mDesiredDiscard < mDecodedDiscard)
 		{
 			// More data was requested, return to INIT
-			mState = INIT;
+			setState(INIT);
+			LL_DEBUGS("Texture") << mID << " more data requested, returning to INIT: " 
+								 << " mDecodedDiscard " << mDecodedDiscard << ">= 0 && mDesiredDiscard " << mDesiredDiscard
+								 << "<" << " mDecodedDiscard " << mDecodedDiscard << llendl;
 			setPriority(LLWorkerThread::PRIORITY_HIGH | mWorkPriority);
 			return false;
 		}
@@ -1843,10 +1895,10 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
 	bool partial = false;
 	LLCore::HttpStatus status(response->getStatus());
 	
-	lldebugs << "HTTP COMPLETE: " << mID
-			 << " status: " << status.toHex()
-			 << " '" << status.toString() << "'"
-			 << llendl;
+	LL_DEBUGS("Texture") << "HTTP COMPLETE: " << mID
+						 << " status: " << status.toHex()
+						 << " '" << status.toString() << "'"
+						 << llendl;
 //	unsigned int offset(0), length(0), full_length(0);
 //	response->getRange(&offset, &length, &full_length);
 // 	llwarns << "HTTP COMPLETE: " << mID << " handle: " << handle
@@ -2401,7 +2453,7 @@ LLTextureFetch::~LLTextureFetch()
 	// ~LLQueuedThread() called here
 }
 
-bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+bool LLTextureFetch::createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
 								   S32 w, S32 h, S32 c, S32 desired_discard, bool needs_aux, bool can_use_http)
 {
 	if(mFetcherLocked)
@@ -2430,6 +2482,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 	std::string exten = gDirUtilp->getExtension(url);
 	if (!url.empty() && (!exten.empty() && LLImageBase::getCodecFromExtension(exten) != IMG_CODEC_J2C))
 	{
+		LL_DEBUGS("Texture") << "full request for " << id << " exten is not J2C: " << exten << llendl;
 		// Only do partial requests for J2C at the moment
 		desired_size = MAX_IMAGE_DATA_SIZE;
 		desired_discard = 0;
@@ -2472,7 +2525,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 		worker->setCanUseHTTP(can_use_http) ;
 		if (!worker->haveWork())
 		{
-			worker->mState = LLTextureFetchWorker::INIT;
+			worker->setState(LLTextureFetchWorker::INIT);
 			worker->unlockWorkMutex();									// -Mw
 
 			worker->addWork(0, LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
@@ -2484,7 +2537,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 	}
 	else
 	{
-		worker = new LLTextureFetchWorker(this, url, id, host, priority, desired_discard, desired_size);
+		worker = new LLTextureFetchWorker(this, f_type, url, id, host, priority, desired_discard, desired_size);
 		lockQueue();													// +Mfq
 		mRequestMap[id] = worker;
 		unlockQueue();													// -Mfq
@@ -2496,7 +2549,7 @@ bool LLTextureFetch::createRequest(const std::string& url, const LLUUID& id, con
 		worker->unlockWorkMutex();										// -Mw
 	}
 	
-// 	llinfos << "REQUESTED: " << id << " Discard: " << desired_discard << llendl;
+ 	LL_DEBUGS("Texture") << "REQUESTED: " << id << " Discard: " << desired_discard << " size " << desired_size << llendl;
 	return true;
 }
 
@@ -3165,6 +3218,30 @@ bool LLTextureFetchWorker::insertPacket(S32 index, U8* data, S32 size)
 	return true;
 }
 
+void LLTextureFetchWorker::setState(e_state new_state)
+{
+	static const char* e_state_name[] =
+	{
+		"INVALID",
+		"INIT",
+		"LOAD_FROM_TEXTURE_CACHE",
+		"CACHE_POST",
+		"LOAD_FROM_NETWORK",
+		"LOAD_FROM_SIMULATOR",
+		"WAIT_HTTP_RESOURCE",
+		"WAIT_HTTP_RESOURCE2",
+		"SEND_HTTP_REQ",
+		"WAIT_HTTP_REQ",
+		"DECODE_IMAGE",
+		"DECODE_IMAGE_UPDATE",
+		"WRITE_TO_CACHE",
+		"WAIT_ON_WRITE",
+		"DONE"
+	};
+	LL_DEBUGS("Texture") << "id: " << mID << " FTType: " << mFTType << " disc: " << mDesiredDiscard << " sz: " << mDesiredSize << " state: " << e_state_name[mState] << " => " << e_state_name[new_state] << llendl;
+	mState = new_state;
+}
+
 // Threads:  T*
 bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8 codec, U16 packets, U32 totalbytes,
 										U16 data_size, U8* data)
@@ -3221,7 +3298,7 @@ bool LLTextureFetch::receiveImageHeader(const LLHost& host, const LLUUID& id, U8
 	llassert_always(data_size == FIRST_PACKET_SIZE || data_size == worker->mFileSize);
 	res = worker->insertPacket(0, data, data_size);
 	worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-	worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
+	worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	worker->unlockWorkMutex();											// -Mw
 	return res;
 }
@@ -3271,7 +3348,7 @@ bool LLTextureFetch::receiveImagePacket(const LLHost& host, const LLUUID& id, U1
 		(worker->mState == LLTextureFetchWorker::LOAD_FROM_NETWORK))
 	{
 		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
-		worker->mState = LLTextureFetchWorker::LOAD_FROM_SIMULATOR;
+		worker->setState(LLTextureFetchWorker::LOAD_FROM_SIMULATOR);
 	}
 	else
 	{
@@ -3534,7 +3611,7 @@ void LLTextureFetch::releaseHttpWaiters()
 			break;
 		}
 		
-		worker->mState = LLTextureFetchWorker::SEND_HTTP_REQ;
+		worker->setState(LLTextureFetchWorker::SEND_HTTP_REQ);
 		worker->setPriority(LLWorkerThread::PRIORITY_HIGH | worker->mWorkPriority);
 		worker->unlockWorkMutex();										// -Mw
 
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 5ea3c14e1a5da462d0178c0f2c661dddfcc1eba9..902a3d7a25431054b235e171fc1504fbebac0927 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -44,8 +44,8 @@
 #include "httpoptions.h"
 #include "httpheaders.h"
 #include "httphandler.h"
+#include "llviewertexture.h"
 
-class LLViewerTexture;
 class LLTextureFetchWorker;
 class LLImageDecodeThread;
 class LLHost;
@@ -77,7 +77,7 @@ class LLTextureFetch : public LLWorkerThread
 	void shutDownImageDecodeThread();
 
 	// Threads:  T* (but Tmain mostly)
-	bool createRequest(const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
+	bool createRequest(FTType f_type, const std::string& url, const LLUUID& id, const LLHost& host, F32 priority,
 					   S32 w, S32 h, S32 c, S32 discard, bool needs_aux, bool can_use_http);
 
 	// Requests that a fetch operation be deleted from the queue.
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 16c42dbd4330458dd3cc31fd4962788ab690af1b..e80136b286307082e3ae189988fd9f223fc73698 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -40,7 +40,7 @@
 #include "lltooltip.h"
 #include "llappviewer.h"
 #include "llselectmgr.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
 #include "lltexturecache.h"
 #include "lltexturefetch.h"
 #include "llviewercontrol.h"
@@ -170,7 +170,7 @@ void LLTextureBar::draw()
 	{
 		color = LLColor4::green4;
 	}
-	else if (mImagep->getBoostLevel() > LLViewerTexture::BOOST_NONE)
+	else if (mImagep->getBoostLevel() > LLGLTexture::BOOST_NONE)
 	{
 		color = LLColor4::magenta;
 	}
@@ -420,14 +420,14 @@ void LLAvatarTexBar::draw()
 	LLColor4 color;
 	
 	U32 line_num = 1;
-	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
-		const LLTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = avatarp->debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 
 		LLColor4 text_color = LLColor4::white;
diff --git a/indra/newview/lltoast.h b/indra/newview/lltoast.h
index e1d99b1bcba9afd2abde97820bf5a13b841e6443..ea62f758f87a3967da7f388a82fc02fc0c696571 100644
--- a/indra/newview/lltoast.h
+++ b/indra/newview/lltoast.h
@@ -169,6 +169,7 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast>
 	// get/set Toast's flags or states
 	// get information whether the notification corresponding to the toast is valid or not
 	bool isNotificationValid();
+
 	// get toast's Notification ID
 	const LLUUID getNotificationID() const { return mNotificationID;}
 	// get toast's Session ID
@@ -212,7 +213,7 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast>
 
 	//LLRootHandle<LLToast>	mHandle;
 		
-	LLPanel* mWrapperPanel;
+	LLPanel*	 mWrapperPanel;
 
 	// timer counts a lifetime of a toast
 	std::auto_ptr<LLToastLifeTimer> mTimer;
@@ -220,8 +221,8 @@ class LLToast : public LLModalDialog, public LLInstanceTracker<LLToast>
 	F32			mToastLifetime; // in seconds
 	F32			mToastFadingTime; // in seconds
 	
-	LLPanel*		mPanel;
-	LLButton*		mHideBtn;
+	LLPanel*	mPanel;
+	LLButton*	mHideBtn;
 
 	LLColor4	mBgColor;
 	bool		mCanFade;
diff --git a/indra/newview/lltoastgroupnotifypanel.cpp b/indra/newview/lltoastgroupnotifypanel.cpp
index 75178a6ef8a6fcaa8a560d795d90742be6084636..beb45e8179f8e946aac04f45c9ac183468bf8f4c 100644
--- a/indra/newview/lltoastgroupnotifypanel.cpp
+++ b/indra/newview/lltoastgroupnotifypanel.cpp
@@ -33,6 +33,7 @@
 #include "llbutton.h"
 #include "lliconctrl.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "llnotifications.h"
 #include "llviewertexteditor.h"
 
@@ -51,7 +52,7 @@
 
 const S32 LLToastGroupNotifyPanel::DEFAULT_MESSAGE_MAX_LINE_COUNT	= 7;
 
-LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification)
+LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(const LLNotificationPtr& notification)
 :	LLToastPanel(notification),
 	mInventoryOffer(NULL)
 {
@@ -69,10 +70,8 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 
 	//header title
 	std::string from_name = payload["sender_name"].asString();
-	if (LLAvatarNameCache::useDisplayNames())
-	{
-		from_name = LLCacheName::buildUsername(from_name);
-	}
+	from_name = LLCacheName::buildUsername(from_name);
+
 	std::stringstream from;
 	from << from_name << "/" << groupData.mName;
 	LLTextBox* pTitleText = getChild<LLTextBox>("title");
@@ -112,7 +111,7 @@ LLToastGroupNotifyPanel::LLToastGroupNotifyPanel(LLNotificationPtr& notification
 		style.font = date_font;
 	pMessageText->appendText(timeStr + "\n", TRUE, style);
 	
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//attachment
diff --git a/indra/newview/lltoastgroupnotifypanel.h b/indra/newview/lltoastgroupnotifypanel.h
index 7794ec9f635e117f8a7253ea80f1836da4496fdf..dfdc6ae55981b4e43fba051de007093176db0b79 100644
--- a/indra/newview/lltoastgroupnotifypanel.h
+++ b/indra/newview/lltoastgroupnotifypanel.h
@@ -47,13 +47,10 @@ class LLToastGroupNotifyPanel
 public:
 	void close();
 
-	static bool onNewNotification(const LLSD& notification);
-
-
 	// Non-transient messages.  You can specify non-default button
 	// layouts (like one for script dialogs) by passing various
 	// numbers in for "layout".
-	LLToastGroupNotifyPanel(LLNotificationPtr& notification);
+	LLToastGroupNotifyPanel(const LLNotificationPtr& notification);
 
 	/*virtual*/ ~LLToastGroupNotifyPanel();
 protected:
diff --git a/indra/newview/lltoastimpanel.cpp b/indra/newview/lltoastimpanel.cpp
index e0cb200ef5d15c3cbacb20839a907165245b1f75..75e6e3d13a4a3b07e24e6fa1b40d0fe6042442df 100644
--- a/indra/newview/lltoastimpanel.cpp
+++ b/indra/newview/lltoastimpanel.cpp
@@ -104,9 +104,9 @@ LLToastIMPanel::~LLToastIMPanel()
 }
 
 //virtual
-BOOL LLToastIMPanel::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLToastIMPanel::handleMouseUp(S32 x, S32 y, MASK mask)
 {
-	if (LLPanel::handleMouseDown(x,y,mask) == FALSE)
+	if (LLPanel::handleMouseUp(x,y,mask) == FALSE)
 	{
 		mNotification->respond(mNotification->getResponseTemplate());
 	}
diff --git a/indra/newview/lltoastimpanel.h b/indra/newview/lltoastimpanel.h
index a803387576c5076455537aa3a83555a76b8bcb04..3eb11fb3bc6e157c1004036c43afa0502927c7f4 100644
--- a/indra/newview/lltoastimpanel.h
+++ b/indra/newview/lltoastimpanel.h
@@ -41,18 +41,18 @@ class LLToastIMPanel: public LLToastPanel
 	struct Params
 	{
 		LLNotificationPtr	notification;
-		LLUUID				avatar_id;
-		LLUUID				session_id;
-		std::string			from;
-		std::string			time;
-		std::string			message;
+		LLUUID				avatar_id,
+							session_id;
+		std::string			from,
+							time,
+							message;
 
 		Params() {}
 	};
 
 	LLToastIMPanel(LLToastIMPanel::Params &p);
 	virtual ~LLToastIMPanel();
-	/*virtual*/ BOOL 	handleMouseDown(S32 x, S32 y, MASK mask);
+	/*virtual*/ BOOL 	handleMouseUp(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleToolTip(S32 x, S32 y, MASK mask);
 private:
 	void showInspector();
diff --git a/indra/newview/lltoastnotifypanel.cpp b/indra/newview/lltoastnotifypanel.cpp
index 602b924398d47e3217c71f083c857bb0cb36d3d2..8bfde2bcf1f9d59248fd09682e4bcfc8605d6e3c 100644
--- a/indra/newview/lltoastnotifypanel.cpp
+++ b/indra/newview/lltoastnotifypanel.cpp
@@ -40,11 +40,14 @@
 #include "lltrans.h"
 #include "llnotificationsutil.h"
 #include "llviewermessage.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 
 const S32 BOTTOM_PAD = VPAD * 3;
 const S32 IGNORE_BTN_TOP_DELTA = 3*VPAD;//additional ignore_btn padding
 S32 BUTTON_WIDTH = 90;
+// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
+const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 
+
 
 //static
 const LLFontGL* LLToastNotifyPanel::sFont = NULL;
@@ -52,172 +55,12 @@ const LLFontGL* LLToastNotifyPanel::sFontSmall = NULL;
 
 LLToastNotifyPanel::button_click_signal_t LLToastNotifyPanel::sButtonClickSignal;
 
-LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) :
-LLToastPanel(notification),
-mTextBox(NULL),
-mInfoPanel(NULL),
-mControlPanel(NULL),
-mNumOptions(0),
-mNumButtons(0),
-mAddedDefaultBtn(false),
-mCloseNotificationOnDestroy(true)
+LLToastNotifyPanel::LLToastNotifyPanel(const LLNotificationPtr& notification, const LLRect& rect, bool show_images) 
+:	LLToastPanel(notification),
+	LLInstanceTracker<LLToastNotifyPanel, LLUUID>(notification->getID())
 {
-	buildFromFile( "panel_notification.xml");
-	if(rect != LLRect::null)
-	{
-		this->setShape(rect);
-	}		 
-	mInfoPanel = getChild<LLPanel>("info_panel");
-	mControlPanel = getChild<LLPanel>("control_panel");
-	BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
-	// customize panel's attributes
-	// is it intended for displaying a tip?
-	mIsTip = notification->getType() == "notifytip";
-	// is it a script dialog?
-	mIsScriptDialog = (notification->getName() == "ScriptDialog" || notification->getName() == "ScriptDialogGroup");
-	// is it a caution?
-	//
-	// caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
-	// notify xml template specifies that it is a caution
-	// tip-style notification handle 'caution' differently -they display the tip in a different color
-	mIsCaution = notification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
-
-	// setup parameters
-	// get a notification message
-	mMessage = notification->getMessage();
-	// init font variables
-	if (!sFont)
-	{
-		sFont = LLFontGL::getFontSansSerif();
-		sFontSmall = LLFontGL::getFontSansSerifSmall();
-	}
-	// initialize
-	setFocusRoot(!mIsTip);
-	// get a form for the notification
-	LLNotificationFormPtr form(notification->getForm());
-	// get number of elements
-	mNumOptions = form->getNumElements();
-
-	// customize panel's outfit
-	// preliminary adjust panel's layout
-	//move to the end 
-	//mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
-
-	// adjust text options according to the notification type
-	// add a caution textbox at the top of a caution notification
-	if (mIsCaution && !mIsTip)
-	{
-		mTextBox = getChild<LLTextBox>("caution_text_box");
-	}
-	else
-	{
-		mTextBox = getChild<LLTextEditor>("text_editor_box"); 
-	}
-
-	// *TODO: magic numbers(???) - copied from llnotify.cpp(250)
-	const S32 MAX_LENGTH = 512 + 20 + DB_FIRST_NAME_BUF_SIZE + DB_LAST_NAME_BUF_SIZE + DB_INV_ITEM_NAME_BUF_SIZE; 
-
-	mTextBox->setMaxTextLength(MAX_LENGTH);
-	mTextBox->setVisible(TRUE);
-	mTextBox->setPlainText(!show_images);
-	mTextBox->setValue(notification->getMessage());
-
-	// add buttons for a script notification
-	if (mIsTip)
-	{
-		adjustPanelForTipNotice();
-	}
-	else
-	{
-		std::vector<index_button_pair_t> buttons;
-		buttons.reserve(mNumOptions);
-		S32 buttons_width = 0;
-		// create all buttons and accumulate they total width to reshape mControlPanel
-		for (S32 i = 0; i < mNumOptions; i++)
-		{
-			LLSD form_element = form->getElement(i);
-			if (form_element["type"].asString() != "button")
-			{
-				// not a button.
-				continue;
-			}
-			if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
-			{
-				// a textbox pretending to be a button.
-				continue;
-			}
-			LLButton* new_button = createButton(form_element, TRUE);
-			buttons_width += new_button->getRect().getWidth();
-			S32 index = form_element["index"].asInteger();
-			buttons.push_back(index_button_pair_t(index,new_button));
-		}
-		if (buttons.empty())
-		{
-			addDefaultButton();
-		}
-		else
-		{
-			const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
-			S32 button_panel_height = mControlPanel->getRect().getHeight();
-			//try get an average h_pad to spread out buttons
-			S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
-			if(h_pad < 2*HPAD)
-			{
-				/*
-				 * Probably it is a scriptdialog toast
-				 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
-				 * In last case set default h_pad to avoid heaping of buttons 
-				 */
-				S32 button_per_row = button_panel_width / BUTTON_WIDTH;
-				h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
-				if(h_pad < 2*HPAD) // still not enough space between buttons ?
-				{
-					h_pad = 2*HPAD;
-				}
-			}
-			if (mIsScriptDialog)
-			{
-				// we are using default width for script buttons so we can determinate button_rows
-				//to get a number of rows we divide the required width of the buttons to button_panel_width
-				S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
-				//S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
-				//reserve one row for the ignore_btn
-				button_rows++;
-				//calculate required panel height for scripdialog notification.
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
-			}
-			else
-			{
-				// in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
-				//S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
-				S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
-				//calculate required panel height 
-				button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
-			}
-		
-			// we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
-			adjustPanelForScriptNotice(button_panel_width, button_panel_height);
-			updateButtonsLayout(buttons, h_pad);
-			// save buttons for later use in disableButtons()
-			mButtons.assign(buttons.begin(), buttons.end());
-		}
+	init(rect, show_images);
 	}
-	// adjust panel's height to the text size
-	mInfoPanel->setFollowsAll();
-	snapToMessageHeight(mTextBox, MAX_LENGTH);
-
-	if(notification->isReusable())
-	{
-		mButtonClickConnection = sButtonClickSignal.connect(
-			boost::bind(&LLToastNotifyPanel::onToastPanelButtonClicked, this, _1, _2));
-
-		if(notification->isRespondedTo())
-		{
-			// User selected an option in toast, now disable required buttons in IM window
-			disableRespondedOptions(notification);
-		}
-	}
-}
 void LLToastNotifyPanel::addDefaultButton()
 {
 	LLSD form_element;
@@ -235,7 +78,6 @@ void LLToastNotifyPanel::addDefaultButton()
 }
 LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_option)
 {
-
 	InstanceAndS32* userdata = new InstanceAndS32;
 	userdata->mSelf = this;
 	userdata->mButtonName = is_option ? form_element["name"].asString() : "";
@@ -245,14 +87,15 @@ LLButton* LLToastNotifyPanel::createButton(const LLSD& form_element, BOOL is_opt
 	LLButton::Params p;
 	bool make_small_btn = form_element["index"].asInteger() == -1 || form_element["index"].asInteger() == -2;
 	const LLFontGL* font = make_small_btn ? sFontSmall: sFont; // for block and ignore buttons in script dialog
-	p.name(form_element["name"].asString());
-	p.label(form_element["text"].asString());
-	p.font(font);
+	p.name = form_element["name"].asString();
+	p.label = form_element["text"].asString();
+	p.font = font;
 	p.rect.height = BTN_HEIGHT;
 	p.click_callback.function(boost::bind(&LLToastNotifyPanel::onClickButton, userdata));
 	p.rect.width = BUTTON_WIDTH;
 	p.auto_resize = false;
 	p.follows.flags(FOLLOWS_LEFT | FOLLOWS_BOTTOM);
+	p.enabled = !form_element.has("enabled") || form_element["enabled"].asBoolean();
 	if (mIsCaution)
 	{
 		p.image_color(LLUIColorTable::instance().getColor("ButtonCautionImageColor"));
@@ -287,16 +130,11 @@ LLToastNotifyPanel::~LLToastNotifyPanel()
 	mButtonClickConnection.disconnect();
 
 	std::for_each(mBtnCallbackData.begin(), mBtnCallbackData.end(), DeletePointer());
-	if (mCloseNotificationOnDestroy && LLNotificationsUtil::find(mNotification->getID()) != NULL)
-	{
-		// let reusable notification be deleted
-		mNotification->setReusable(false);
-		if (!mNotification->isPersistent())
+	if (mIsTip)
 		{
 			LLNotifications::getInstance()->cancel(mNotification);
 		}
 	}
-}
 
 void LLToastNotifyPanel::updateButtonsLayout(const std::vector<index_button_pair_t>& buttons, S32 h_pad)
 {
@@ -369,8 +207,6 @@ void LLToastNotifyPanel::adjustPanelForScriptNotice(S32 button_panel_width, S32
 
 void LLToastNotifyPanel::adjustPanelForTipNotice()
 {
-	LLRect info_rect = mInfoPanel->getRect();
-	LLRect this_rect = getRect();
 	//we don't need display ControlPanel for tips because they doesn't contain any buttons. 
 	mControlPanel->setVisible(FALSE);
 	reshape(getRect().getWidth(), mInfoPanel->getRect().getHeight());
@@ -385,210 +221,278 @@ void LLToastNotifyPanel::adjustPanelForTipNotice()
 	}
 }
 
-typedef std::set<std::string> button_name_set_t;
-typedef std::map<std::string, button_name_set_t> disable_button_map_t;
-
-disable_button_map_t initUserGiveItemDisableButtonMap()
+// static
+void LLToastNotifyPanel::onClickButton(void* data)
 {
-	// see EXT-5905 for disable rules
-
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Show");
-	disable_map.insert(std::make_pair("Show", buttons));
+	InstanceAndS32* self_and_button = (InstanceAndS32*)data;
+	LLToastNotifyPanel* self = self_and_button->mSelf;
+	std::string button_name = self_and_button->mButtonName;
 
-	buttons.insert("Discard");
-	disable_map.insert(std::make_pair("Discard", buttons));
+	LLSD response = self->mNotification->getResponseTemplate();
+	if (!self->mAddedDefaultBtn && !button_name.empty())
+	{
+		response[button_name] = true;
+	}
 
-	buttons.insert("Mute");
-	disable_map.insert(std::make_pair("Mute", buttons));
+	// disable all buttons
+	self->mControlPanel->setEnabled(FALSE);
 
-	return disable_map;
+	// this might repost notification with new form data/enabled buttons
+	self->mNotification->respond(response);
 }
 
-disable_button_map_t initTeleportOfferedDisableButtonMap()
+void LLToastNotifyPanel::init( LLRect rect, bool show_images )
 {
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Teleport");
-	buttons.insert("Cancel");
-
-	disable_map.insert(std::make_pair("Teleport", buttons));
-	disable_map.insert(std::make_pair("Cancel", buttons));
+    deleteAllChildren();
+
+    mTextBox = NULL;
+    mInfoPanel = NULL;
+    mControlPanel = NULL;
+    mNumOptions = 0;
+    mNumButtons = 0;
+    mAddedDefaultBtn = false;
+
+	LLRect current_rect = getRect();
+
+	setXMLFilename("");
+	buildFromFile("panel_notification.xml");
+
+    if(rect != LLRect::null)
+    {
+        this->setShape(rect);
+    }
+    mInfoPanel = getChild<LLPanel>("info_panel");
+
+    mControlPanel = getChild<LLPanel>("control_panel");
+    BUTTON_WIDTH = gSavedSettings.getS32("ToastButtonWidth");
+    // customize panel's attributes
+    // is it intended for displaying a tip?
+    mIsTip = mNotification->getType() == "notifytip";
+    // is it a script dialog?
+    mIsScriptDialog = (mNotification->getName() == "ScriptDialog" || mNotification->getName() == "ScriptDialogGroup");
+    // is it a caution?
+    //
+    // caution flag can be set explicitly by specifying it in the notification payload, or it can be set implicitly if the
+    // notify xml template specifies that it is a caution
+    // tip-style notification handle 'caution' differently -they display the tip in a different color
+    mIsCaution = mNotification->getPriority() >= NOTIFICATION_PRIORITY_HIGH;
+
+    // setup parameters
+    // get a notification message
+    mMessage = mNotification->getMessage();
+    // init font variables
+    if (!sFont)
+    {
+        sFont = LLFontGL::getFontSansSerif();
+        sFontSmall = LLFontGL::getFontSansSerifSmall();
+    }
+    // initialize
+    setFocusRoot(!mIsTip);
+    // get a form for the notification
+    LLNotificationFormPtr form(mNotification->getForm());
+    // get number of elements
+    mNumOptions = form->getNumElements();
+
+    // customize panel's outfit
+    // preliminary adjust panel's layout
+    //move to the end 
+    //mIsTip ? adjustPanelForTipNotice() : adjustPanelForScriptNotice(form);
+
+    // adjust text options according to the notification type
+    // add a caution textbox at the top of a caution notification
+    if (mIsCaution && !mIsTip)
+    {
+        mTextBox = getChild<LLTextBox>("caution_text_box");
+    }
+    else
+    {
+        mTextBox = getChild<LLTextEditor>("text_editor_box"); 
+    }
+
+    mTextBox->setMaxTextLength(MAX_LENGTH);
+    mTextBox->setVisible(TRUE);
+    mTextBox->setPlainText(!show_images);
+    mTextBox->setValue(mNotification->getMessage());
+
+    // add buttons for a script notification
+    if (mIsTip)
+    {
+        adjustPanelForTipNotice();
+    }
+    else
+    {
+        std::vector<index_button_pair_t> buttons;
+        buttons.reserve(mNumOptions);
+        S32 buttons_width = 0;
+        // create all buttons and accumulate they total width to reshape mControlPanel
+        for (S32 i = 0; i < mNumOptions; i++)
+        {
+            LLSD form_element = form->getElement(i);
+            if (form_element["type"].asString() != "button")
+            {
+                // not a button.
+                continue;
+            }
+            if (form_element["name"].asString() == TEXTBOX_MAGIC_TOKEN)
+            {
+                // a textbox pretending to be a button.
+                continue;
+            }
+            LLButton* new_button = createButton(form_element, TRUE);
+            buttons_width += new_button->getRect().getWidth();
+            S32 index = form_element["index"].asInteger();
+            buttons.push_back(index_button_pair_t(index,new_button));
+        }
+        if (buttons.empty())
+        {
+            addDefaultButton();
+        }
+        else
+        {
+            const S32 button_panel_width = mControlPanel->getRect().getWidth();// do not change width of the panel
+            S32 button_panel_height = mControlPanel->getRect().getHeight();
+            //try get an average h_pad to spread out buttons
+            S32 h_pad = (button_panel_width - buttons_width) / (S32(buttons.size()));
+            if(h_pad < 2*HPAD)
+            {
+                /*
+                 * Probably it is a scriptdialog toast
+                 * for a scriptdialog toast h_pad can be < 2*HPAD if we have a lot of buttons.
+                 * In last case set default h_pad to avoid heaping of buttons 
+                 */
+                S32 button_per_row = button_panel_width / BUTTON_WIDTH;
+                h_pad = (button_panel_width % BUTTON_WIDTH) / (button_per_row - 1);// -1  because we do not need space after last button in a row   
+                if(h_pad < 2*HPAD) // still not enough space between buttons ?
+                {
+                    h_pad = 2*HPAD;
+                }
+            }
+            if (mIsScriptDialog)
+            {
+                // we are using default width for script buttons so we can determinate button_rows
+                //to get a number of rows we divide the required width of the buttons to button_panel_width
+                S32 button_rows = llceil(F32(buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width);
+                //S32 button_rows = (buttons.size() - 1) * (BUTTON_WIDTH + h_pad) / button_panel_width;
+                //reserve one row for the ignore_btn
+                button_rows++;
+                //calculate required panel height for scripdialog notification.
+                button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ IGNORE_BTN_TOP_DELTA + BOTTOM_PAD;
+            }
+            else
+            {
+                // in common case buttons can have different widths so we need to calculate button_rows according to buttons_width
+                //S32 button_rows = llceil(F32(buttons.size()) * (buttons_width + h_pad) / button_panel_width);
+                S32 button_rows = llceil(F32((buttons.size() - 1) * h_pad + buttons_width) / button_panel_width);
+                //calculate required panel height 
+                button_panel_height = button_rows * (BTN_HEIGHT + VPAD)	+ BOTTOM_PAD;
+            }
+
+            // we need to keep min width and max height to make visible all buttons, because width of the toast can not be changed
+            adjustPanelForScriptNotice(button_panel_width, button_panel_height);
+            updateButtonsLayout(buttons, h_pad);
+            // save buttons for later use in disableButtons()
+            //mButtons.assign(buttons.begin(), buttons.end());
+        }
+    }
+
+	//.xml file intially makes info panel only follow left/right/top. This is so that when control buttons are added the info panel 
+	//can shift upward making room for the buttons inside mControlPanel. After the buttons are added, the info panel can then be set to follow 'all'.
+	mInfoPanel->setFollowsAll();
+    snapToMessageHeight(mTextBox, MAX_LENGTH);
 
-	return disable_map;
+	// reshape the panel to its previous size
+	if (current_rect.notEmpty())
+	{
+		reshape(current_rect.getWidth(), current_rect.getHeight());
+	}
 }
 
-disable_button_map_t initFriendshipOfferedDisableButtonMap()
-{
-	disable_button_map_t disable_map;
-	button_name_set_t buttons;
-
-	buttons.insert("Accept");
-	buttons.insert("Decline");
-
-	disable_map.insert(std::make_pair("Accept", buttons));
-	disable_map.insert(std::make_pair("Decline", buttons));
+//////////////////////////////////////////////////////////////////////////
 
-	return disable_map;
+LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
+										   bool show_images /* = true */, LLTextBase* parent_text)
+:	mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images),
+	mParentText(parent_text)
+{
+	compactButtons();
 }
 
-button_name_set_t getButtonDisableList(const std::string& notification_name, const std::string& button_name)
+LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
 {
-	static disable_button_map_t user_give_item_disable_map = initUserGiveItemDisableButtonMap();
-	static disable_button_map_t teleport_offered_disable_map = initTeleportOfferedDisableButtonMap();
-	static disable_button_map_t friendship_offered_disable_map = initFriendshipOfferedDisableButtonMap();
-
-	disable_button_map_t::const_iterator it;
-	disable_button_map_t::const_iterator it_end;
-	disable_button_map_t search_map;
-
-	if("UserGiveItem" == notification_name)
-	{
-		search_map = user_give_item_disable_map;
-	}
-	else if(("TeleportOffered" == notification_name) || ("TeleportOffered_MaturityExceeded" == notification_name))
-	{
-		search_map = teleport_offered_disable_map;
-	}
-	else if("OfferFriendship" == notification_name)
-	{
-		search_map = friendship_offered_disable_map;
-	}
-
-	it = search_map.find(button_name);
-	it_end = search_map.end();
-
-	if(it_end != it)
-	{
-		return it->second;
-	}
-	return button_name_set_t();
 }
 
-void LLToastNotifyPanel::disableButtons(const std::string& notification_name, const std::string& selected_button)
+void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
 {
-	button_name_set_t buttons = getButtonDisableList(notification_name, selected_button);
-
-	std::vector<index_button_pair_t>::const_iterator it = mButtons.begin();
-	for ( ; it != mButtons.end(); it++)
-	{
-		LLButton* btn = it->second;
-		if(buttons.find(btn->getName()) != buttons.end())
-		{
-			btn->setEnabled(FALSE);
-		}
-	}
+	LLToastPanel::reshape(width, height, called_from_parent);
+	snapToMessageHeight();
 }
 
-// static
-void LLToastNotifyPanel::onClickButton(void* data)
+void LLIMToastNotifyPanel::snapToMessageHeight()
 {
-	InstanceAndS32* self_and_button = (InstanceAndS32*)data;
-	LLToastNotifyPanel* self = self_and_button->mSelf;
-	std::string button_name = self_and_button->mButtonName;
-
-	LLSD response = self->mNotification->getResponseTemplate();
-	if (!self->mAddedDefaultBtn && !button_name.empty())
-	{
-		response[button_name] = true;
-	}
-	
-	bool is_reusable = self->mNotification->isReusable();
-	// When we call respond(), LLOfferInfo will delete itself in inventory_offer_callback(), 
-	// lets copy it while it's still valid.
-	LLOfferInfo* old_info = static_cast<LLOfferInfo*>(self->mNotification->getResponder());
-	LLOfferInfo* new_info = NULL;
-	if(is_reusable && old_info)
+	if(!mTextBox)
 	{
-		new_info = new LLOfferInfo(*old_info);
-		self->mNotification->setResponder(new_info);
+		return;
 	}
 
-	self->mNotification->respond(response);
-
-	if(is_reusable)
-	{
-		sButtonClickSignal(self->mNotification->getID(), button_name);
-	}
-	else
+	//Add message height if it is visible
+	if (mTextBox->getVisible())
 	{
-		// disable all buttons
-		self->mControlPanel->setEnabled(FALSE);
-	}
-}
+		S32 new_panel_height = computeSnappedToMessageHeight(mTextBox, MAX_LENGTH);
 
-void LLToastNotifyPanel::onToastPanelButtonClicked(const LLUUID& notification_id, const std::string btn_name)
-{
-	if(mNotification->getID() == notification_id)
-	{
-		disableButtons(mNotification->getName(), btn_name);
+		//reshape the panel with new height
+		if (new_panel_height != getRect().getHeight())
+		{
+			LLToastNotifyPanel::reshape( getRect().getWidth(), new_panel_height);
+		}
 	}
 }
 
-void LLToastNotifyPanel::disableRespondedOptions(const LLNotificationPtr& notification)
+void LLIMToastNotifyPanel::compactButtons()
 {
-	LLSD response = notification->getResponse();
-	for (LLSD::map_const_iterator response_it = response.beginMap(); 
-		response_it != response.endMap(); ++response_it)
+	//we can't set follows in xml since it broke toasts behavior
+	setFollows(FOLLOWS_LEFT|FOLLOWS_RIGHT|FOLLOWS_TOP);
+
+	const child_list_t* children = getControlPanel()->getChildList();
+	S32 offset = 0;
+	// Children were added by addChild() which uses push_front to insert them into list,
+	// so to get buttons in correct order reverse iterator is used (EXT-5906) 
+	for (child_list_t::const_reverse_iterator it = children->rbegin(); it != children->rend(); it++)
 	{
-		if (response_it->second.isBoolean() && response_it->second.asBoolean())
+		LLButton * button = dynamic_cast<LLButton*> (*it);
+		if (button != NULL)
 		{
-			// that after multiple responses there can be many pressed buttons
-			// need to process them all
-			disableButtons(notification->getName(), response_it->first);
+			button->setOrigin( offset,button->getRect().mBottom);
+			button->setLeftHPad(2 * HPAD);
+			button->setRightHPad(2 * HPAD);
+			// set zero width before perform autoResize()
+			button->setRect(LLRect(button->getRect().mLeft,
+				button->getRect().mTop, 
+				button->getRect().mLeft,
+				button->getRect().mBottom));
+			button->setAutoResize(true);
+			button->autoResize();
+			offset += HPAD + button->getRect().getWidth();
+			button->setFollowsNone();
 		}
 	}
-}
-
 
-//////////////////////////////////////////////////////////////////////////
-
-LLIMToastNotifyPanel::LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect /* = LLRect::null */,
-										   bool show_images /* = true */)
- : mSessionID(session_id), LLToastNotifyPanel(pNotification, rect, show_images)
-{
-	mTextBox->setFollowsAll();
+	if (mParentText)
+	{
+		mParentText->needsReflow();
+	}
 }
 
-LLIMToastNotifyPanel::~LLIMToastNotifyPanel()
-{
-	// We shouldn't delete notification when IM floater exists
-	// since that notification will be reused by IM floater.
-	// This may happened when IM floater reloads messages, exactly when user
-	// changes layout of IM chat log(disable/enable plaintext mode).
-	// See EXT-6500
-	LLIMFloater* im_floater = LLIMFloater::findInstance(mSessionID);
-	if (im_floater != NULL && !im_floater->isDead())
+void LLIMToastNotifyPanel::updateNotification()
 	{
-		mCloseNotificationOnDestroy = false;
+	init(LLRect(), true);
 	}
-}
 
-void LLIMToastNotifyPanel::reshape(S32 width, S32 height, BOOL called_from_parent /* = TRUE */)
+void LLIMToastNotifyPanel::init( LLRect rect, bool show_images )
 {
-	S32 text_height = mTextBox->getTextBoundingRect().getHeight();
-	S32 widget_height = mTextBox->getRect().getHeight();
-	S32 delta = text_height - widget_height;
-	LLRect rc = getRect();
+	LLToastNotifyPanel::init(LLRect(), show_images);
 
-	rc.setLeftTopAndSize(rc.mLeft, rc.mTop, width, height + delta);
-	height = rc.getHeight();
-	width = rc.getWidth();
-
-	bool is_width_changed = width != getRect().getWidth();
-
-	LLToastPanel::reshape(width, height, called_from_parent);
-
-	// Notification height required to display the text message depends on
-	// the width of the text box thus if panel width is changed the text box
-	// width is also changed then reshape() is called to adjust proper height.
-	if (is_width_changed)
-	{
-		reshape(width, height, called_from_parent);
-	}
+	compactButtons();
 }
 
 // EOF
+
diff --git a/indra/newview/lltoastnotifypanel.h b/indra/newview/lltoastnotifypanel.h
index db517ec8581d8dfd189c55e09216860312b564bb..d02171b512c3bc91cfad83a7ad25436fa51d979a 100644
--- a/indra/newview/lltoastnotifypanel.h
+++ b/indra/newview/lltoastnotifypanel.h
@@ -47,7 +47,7 @@ class LLNotificationForm;
  * @deprecated this class will be removed after all toast panel types are
  *  implemented in separate classes.
  */
-class LLToastNotifyPanel: public LLToastPanel 
+class LLToastNotifyPanel: public LLToastPanel, public LLInstanceTracker<LLToastNotifyPanel, LLUUID>
 {
 public:
 	/**
@@ -61,10 +61,14 @@ class LLToastNotifyPanel: public LLToastPanel
 	 * implement right class for desired toast panel. @see LLGenericTipPanel as example.
 	 */
 	LLToastNotifyPanel(const LLNotificationPtr& pNotification, const LLRect& rect = LLRect::null, bool show_images = true);
+
+	virtual void init( LLRect rect, bool show_images );
+
 	virtual ~LLToastNotifyPanel();
 	LLPanel * getControlPanel() { return mControlPanel; }
 
-	void setCloseNotificationOnDestroy(bool close) { mCloseNotificationOnDestroy = close; }
+	virtual void updateNotification() {}
+
 protected:
 	LLButton* createButton(const LLSD& form_element, BOOL is_option);
 
@@ -76,8 +80,6 @@ class LLToastNotifyPanel: public LLToastPanel
 	};
 	std::vector<InstanceAndS32*> mBtnCallbackData;
 
-	bool mCloseNotificationOnDestroy;
-
 	typedef std::pair<int,LLButton*> index_button_pair_t; 
 	void adjustPanelForScriptNotice(S32 max_width, S32 max_height);
 	void adjustPanelForTipNotice();
@@ -93,9 +95,9 @@ class LLToastNotifyPanel: public LLToastPanel
 	/**
 	 * Disable specific button(s) based on notification name and clicked button
 	 */
-	void disableButtons(const std::string& notification_name, const std::string& selected_button);
+	//void disableButtons(const std::string& notification_name, const std::string& selected_button);
 
-	std::vector<index_button_pair_t> mButtons;
+	//std::vector<index_button_pair_t> mButtons;
 
 	// panel elements
 	LLTextBase*		mTextBox;
@@ -118,7 +120,7 @@ class LLToastNotifyPanel: public LLToastPanel
 	/**
 	 * Process response data. Will disable selected options
 	 */
-	void disableRespondedOptions(const LLNotificationPtr& notification);
+	//void disableRespondedOptions(const LLNotificationPtr& notification);
 
 	bool mIsTip;
 	bool mAddedDefaultBtn;
@@ -137,14 +139,27 @@ class LLIMToastNotifyPanel : public LLToastNotifyPanel
 {
 public:
 
-	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, const LLUUID& session_id, const LLRect& rect = LLRect::null, bool show_images = true);
+	LLIMToastNotifyPanel(LLNotificationPtr& pNotification, 
+						const LLUUID& session_id, 
+						const LLRect& rect = LLRect::null, 
+						bool show_images = true, 
+						LLTextBase* parent_text = NULL);
+
+	void compactButtons();
+
+	virtual void updateNotification();
+	virtual void init( LLRect rect, bool show_images );
 
 	~LLIMToastNotifyPanel();
 
 	/*virtual*/ void reshape(S32 width, S32 height, BOOL called_from_parent = TRUE);
 
 protected:
+	LLTextBase* mParentText;
 	LLUUID	mSessionID;
+
+private:
+	void snapToMessageHeight();
 };
 
 #endif /* LLTOASTNOTIFYPANEL_H_ */
diff --git a/indra/newview/lltoastpanel.cpp b/indra/newview/lltoastpanel.cpp
index c33fde99c59f4d3ffd9a4abfacde1b9ea7331acf..a30f8419806e89e1840f3d3fe4ccd858f3cf1c1d 100644
--- a/indra/newview/lltoastpanel.cpp
+++ b/indra/newview/lltoastpanel.cpp
@@ -58,6 +58,25 @@ const LLUUID& LLToastPanel::getID()
 	return mNotification->id();
 }
 
+S32 LLToastPanel::computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount)
+{
+	S32 heightDelta = 0;
+	S32 maxTextHeight = message->getFont()->getLineHeight() * maxLineCount;
+
+	LLRect messageRect = message->getRect();
+	S32 oldTextHeight = messageRect.getHeight();
+
+	//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
+	//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
+	S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
+	S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
+
+	heightDelta = newTextHeight - oldTextHeight;
+	S32 new_panel_height = llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT);
+
+	return new_panel_height;
+}
+
 //snap to the message height if it is visible
 void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 {
@@ -69,22 +88,13 @@ void LLToastPanel::snapToMessageHeight(LLTextBase* message, S32 maxLineCount)
 	//Add message height if it is visible
 	if (message->getVisible())
 	{
-		S32 heightDelta = 0;
-		S32 maxTextHeight = message->getDefaultFont()->getLineHeight() * maxLineCount;
-
-		LLRect messageRect = message->getRect();
-		S32 oldTextHeight = messageRect.getHeight();
-
-		//Knowing the height is set to max allowed, getTextPixelHeight returns needed text height
-		//Perhaps we need to pass maxLineCount as parameter to getTextPixelHeight to avoid previous reshape.
-		S32 requiredTextHeight = message->getTextBoundingRect().getHeight();
-		S32 newTextHeight = llmin(requiredTextHeight, maxTextHeight);
-
-		//Calculate last delta height deducting previous heightDelta 
-		heightDelta = newTextHeight - oldTextHeight - heightDelta;
+		S32 new_panel_height = computeSnappedToMessageHeight(message, maxLineCount);
 
 		//reshape the panel with new height
-		reshape( getRect().getWidth(), llmax(getRect().getHeight() + heightDelta, MIN_PANEL_HEIGHT));
+		if (new_panel_height != getRect().getHeight())
+		{
+			reshape( getRect().getWidth(), new_panel_height);
+		}
 	}
 }
 
@@ -98,7 +108,7 @@ LLToastPanel* LLToastPanel::buidPanelFromNotification(
 	if ("notifytip" == notification->getType())
 	{
 		// if it is online/offline notification
-		if ("FriendOffline" == notification->getName() || "FriendOnline" == notification->getName())
+		if ("FriendOnlineOffline" == notification->getName())
 		{
 			res = new LLPanelOnlineStatus(notification);
 		}
diff --git a/indra/newview/lltoastpanel.h b/indra/newview/lltoastpanel.h
index 346e014d7373641aacecc32f5c23cfd3142a8019..e4ab95007e521c104a1ca47f0839000112613a32 100644
--- a/indra/newview/lltoastpanel.h
+++ b/indra/newview/lltoastpanel.h
@@ -33,19 +33,13 @@
 
 #include <string>
 
-class LLToastPanelBase: public LLPanel 
-{
-public:
-	virtual void init(LLSD& data){};
-};
-
 /**
  * Base class for all panels that can be added to the toast.
  * All toast panels should contain necessary logic for representing certain notification
  * but shouldn't contain logic related to this panel lifetime control and positioning
  * on the parent view.
  */
-class LLToastPanel: public LLPanel {
+class LLToastPanel : public LLPanel {
 public:
 	LLToastPanel(const LLNotificationPtr&);
 	virtual ~LLToastPanel() = 0;
@@ -65,6 +59,7 @@ class LLToastPanel: public LLPanel {
 protected:
 	LLNotificationPtr mNotification;
 	void snapToMessageHeight(LLTextBase* message, S32 maxLineCount);
+	S32 computeSnappedToMessageHeight(LLTextBase* message, S32 maxLineCount);
 };
 
 #endif /* LL_TOASTPANEL_H */
diff --git a/indra/newview/lltoastscriptquestion.cpp b/indra/newview/lltoastscriptquestion.cpp
index feeb8ca77b7e72fac7b85f7305c6518ae9d0ccf6..91ba8c024777f65132303860936218e8a0f44c1f 100644
--- a/indra/newview/lltoastscriptquestion.cpp
+++ b/indra/newview/lltoastscriptquestion.cpp
@@ -66,8 +66,8 @@ void LLToastScriptQuestion::snapToMessageHeight()
 	if (mMessage->getVisible() && mFooter->getVisible())
 	{
 		S32 heightDelta = 0;
-		S32 maxTextHeight = (mMessage->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT)
-						  + (mFooter->getDefaultFont()->getLineHeight() * MAX_LINES_COUNT);
+		S32 maxTextHeight = (mMessage->getFont()->getLineHeight() * MAX_LINES_COUNT)
+						  + (mFooter->getFont()->getLineHeight() * MAX_LINES_COUNT);
 
 		LLRect messageRect = mMessage->getRect();
 		LLRect footerRect  = mFooter->getRect();
diff --git a/indra/newview/lltoastscripttextbox.cpp b/indra/newview/lltoastscripttextbox.cpp
index 2529ec865a9b937f6dd4c96a3c91bd7909d5cfca..45fbabad59ecfc2358c5be25f76620077c244ce8 100644
--- a/indra/newview/lltoastscripttextbox.cpp
+++ b/indra/newview/lltoastscripttextbox.cpp
@@ -65,7 +65,7 @@ LLToastScriptTextbox::LLToastScriptTextbox(const LLNotificationPtr& notification
 	pMessageText->clear();
 
 	LLStyle::Params style;
-	style.font = pMessageText->getDefaultFont();
+	style.font = pMessageText->getFont();
 	pMessageText->appendText(message, TRUE, style);
 
 	//submit button
diff --git a/indra/newview/lltoastscripttextbox.h b/indra/newview/lltoastscripttextbox.h
index 8e69d8834d8c6572050fdd75883de5594ed71612..7d334462483a317d09c9d5ed717115431b57c288 100644
--- a/indra/newview/lltoastscripttextbox.h
+++ b/indra/newview/lltoastscripttextbox.h
@@ -39,8 +39,6 @@ class LLToastScriptTextbox
 public:
 	void close();
 
-	static bool onNewNotification(const LLSD& notification);
-
 	// Non-transient messages.  You can specify non-default button
 	// layouts (like one for script dialogs) by passing various
 	// numbers in for "layout".
diff --git a/indra/newview/lltoolbarview.cpp b/indra/newview/lltoolbarview.cpp
index a29f58b319a92ac9cde7a283250caa1bc426fb94..b2318f9158e8273c0eee654ff5170291c657cca9 100644
--- a/indra/newview/lltoolbarview.cpp
+++ b/indra/newview/lltoolbarview.cpp
@@ -241,8 +241,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
 	LLXUIParser parser;
 	if (!err)
 	{
-	parser.readXUI(root, toolbar_set, toolbar_file);
+	    parser.readXUI(root, toolbar_set, toolbar_file);
 	}
+
 	if (!err && !toolbar_set.validateBlock())
 	{
 		llwarns << "Unable to validate toolbars from file: " << toolbar_file << llendl;
@@ -254,8 +255,9 @@ bool LLToolBarView::loadToolbars(bool force_default)
 		if (force_default)
 		{
 			llerrs << "Unable to load toolbars from default file : " << toolbar_file << llendl;
-		return false;
-	}
+		    return false;
+	    }
+
 		// Try to load the default toolbars
 		return loadToolbars(true);
 	}
@@ -605,7 +607,7 @@ BOOL LLToolBarView::handleDragTool( S32 x, S32 y, const LLUUID& uuid, LLAssetTyp
 BOOL LLToolBarView::handleDropTool( void* cargo_data, S32 x, S32 y, LLToolBar* toolbar)
 {
 	BOOL handled = FALSE;
-	LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data;
+	LLInventoryObject* inv_item = static_cast<LLInventoryObject*>(cargo_data);
 	
 	LLAssetType::EType type = inv_item->getType();
 	if (type == LLAssetType::AT_WIDGET)
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index aba43a971534def7c0b709438c1104522f0dd09c..08d82ea9cbce569070dda56f00ffc441bb1cd342 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -657,7 +657,7 @@ bool LLToolBrushLand::canTerraform(LLViewerRegion* regionp) const
 {
 	if (!regionp) return false;
 	if (regionp->canManageEstate()) return true;
-	return !(regionp->getRegionFlags() & REGION_FLAGS_BLOCK_TERRAFORM);
+	return !regionp->getRegionFlag(REGION_FLAGS_BLOCK_TERRAFORM);
 }
 
 // static
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 923fbecb1a2d3d2ee1f38bd7110c28fc7b461af2..5270c3d33ff12f83dca2d1d0a9b449225fab4aa1 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -471,7 +471,7 @@ BOOL LLToolCompCreate::handleMouseDown(S32 x, S32 y, MASK mask)
 	
 	mObjectPlacedOnMouseDown = TRUE;
 
-	return TRUE;
+	return handled;
 }
 
 void LLToolCompCreate::pickCallback(const LLPickInfo& pick_info)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index c69999981ce66c46e3ea2aed366558d21cdeb3bf..e085834326323ac3bc442434f0873c391fefc19a 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -58,7 +58,6 @@
 #include "llviewerwindow.h"
 #include "llvoavatarself.h"
 #include "llworld.h"
-#include "llclipboard.h"
 
 // syntactic sugar
 #define callMemberFunction(object,ptrToMember)  ((object).*(ptrToMember))
@@ -654,33 +653,41 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 		sOperationId++;
 	}
 
+	// For people drag and drop we don't need an actual inventory object,
+	// instead we need the current cargo id, which should be a person id.
+	bool is_uuid_dragged = (mSource == SOURCE_PEOPLE);
+
 	if (top_view)
 	{
 		handled = TRUE;
 
 		for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 		{
-			LLInventoryObject* cargo = locateInventory(item, cat);
+			S32 local_x, local_y;
+			top_view->screenPointToLocal( x, y, &local_x, &local_y );
+			EAcceptance item_acceptance = ACCEPT_NO;
 
+			LLInventoryObject* cargo = locateInventory(item, cat);
 			if (cargo)
 			{
-				S32 local_x, local_y;
-				top_view->screenPointToLocal( x, y, &local_x, &local_y );
-				EAcceptance item_acceptance = ACCEPT_NO;
 				handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
 													mCargoTypes[mCurItemIndex],
 													(void*)cargo,
 													&item_acceptance,
 													mToolTipMsg);
-				if (handled)
-				{
-					// use sort order to determine priority of acceptance
-					*acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
-				}
 			}
-			else
+			else if (is_uuid_dragged)
 			{
-				return;		
+				handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)&mCargoIDs[mCurItemIndex],
+													&item_acceptance,
+													mToolTipMsg);
+			}
+			if (handled)
+			{
+				// use sort order to determine priority of acceptance
+				*acceptance = (EAcceptance)llmin((U32)item_acceptance, (U32)*acceptance);
 			}
 		}
 
@@ -697,20 +704,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
-				LLInventoryObject* cargo = locateInventory(item, cat);
+				S32 local_x, local_y;
+				EAcceptance item_acceptance;
+				top_view->screenPointToLocal( x, y, &local_x, &local_y );
 
+				LLInventoryObject* cargo = locateInventory(item, cat);
 				if (cargo)
 				{
-					S32 local_x, local_y;
-
-					EAcceptance item_acceptance;
-					top_view->screenPointToLocal( x, y, &local_x, &local_y );
 					handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, TRUE,
 														mCargoTypes[mCurItemIndex],
 														(void*)cargo,
 														&item_acceptance,
 														mToolTipMsg);
 				}
+				else if (is_uuid_dragged)
+				{
+					handled = handled && top_view->handleDragAndDrop(local_x, local_y, mask, FALSE,
+														mCargoTypes[mCurItemIndex],
+														(void*)&mCargoIDs[mCurItemIndex],
+														&item_acceptance,
+														mToolTipMsg);
+				}
 			}
 		}
 		if (handled)
@@ -727,17 +741,27 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 		for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 		{
+			EAcceptance item_acceptance = ACCEPT_NO;
+
 			LLInventoryObject* cargo = locateInventory(item, cat);
 
 			// fix for EXT-3191
-			if (NULL == cargo) return;
-
-			EAcceptance item_acceptance = ACCEPT_NO;
-			handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
-												mCargoTypes[mCurItemIndex],
-												(void*)cargo,
-												&item_acceptance,
-												mToolTipMsg);
+			if (cargo)
+			{
+				handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)cargo,
+													&item_acceptance,
+													mToolTipMsg);
+			}
+			else if (is_uuid_dragged)
+			{
+				handled = handled && root_view->handleDragAndDrop(x, y, mask, FALSE,
+													mCargoTypes[mCurItemIndex],
+													(void*)&mCargoIDs[mCurItemIndex],
+													&item_acceptance,
+													mToolTipMsg);
+			}
 			if (handled)
 			{
 				// use sort order to determine priority of acceptance
@@ -757,17 +781,25 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 
 			for (mCurItemIndex = 0; mCurItemIndex < (S32)mCargoIDs.size(); mCurItemIndex++)
 			{
-				LLInventoryObject* cargo = locateInventory(item, cat);
+				EAcceptance item_acceptance;
 
+				LLInventoryObject* cargo = locateInventory(item, cat);
 				if (cargo)
 				{
-					EAcceptance item_acceptance;
 					handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
 											  mCargoTypes[mCurItemIndex],
 											  (void*)cargo,
 											  &item_acceptance,
 											  mToolTipMsg);
 				}
+				else if (is_uuid_dragged)
+				{
+					handled = handled && root_view->handleDragAndDrop(x, y, mask, TRUE,
+											  mCargoTypes[mCurItemIndex],
+											  (void*)&mCargoIDs[mCurItemIndex],
+											  &item_acceptance,
+											  mToolTipMsg);
+				}
 			}
 		}
 
@@ -780,7 +812,7 @@ void LLToolDragAndDrop::dragOrDrop( S32 x, S32 y, MASK mask, BOOL drop,
 	if (!handled)
 	{
 		// Disallow drag and drop to 3D from the outbox
-		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false, false);
+		const LLUUID outbox_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_OUTBOX, false);
 		if (outbox_id.notNull())
 		{
 			for (S32 item_index = 0; item_index < (S32)mCargoIDs.size(); item_index++)
@@ -1215,7 +1247,7 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
 	if (!item || !item->isFinished()) return;
 	
 	//if (regionp
-	//	&& (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+	//	&& (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
 	//{
 	//	LLFirstUse::useSandbox();
 	//}
@@ -1709,7 +1741,7 @@ EAcceptance LLToolDragAndDrop::dad3dRezAttachmentFromInv(
 	{
 		if(mSource == SOURCE_LIBRARY)
 		{
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(0);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, (LLViewerJointAttachment*)0));
 			copy_inventory_item(
 				gAgent.getID(),
 				item->getPermissions().getOwner(),
@@ -2062,7 +2094,7 @@ EAcceptance LLToolDragAndDrop::dad3dActivateGesture(
 			{
 				// create item based on that one, and put it on if that
 				// was a success.
-				LLPointer<LLInventoryCallback> cb = new ActivateGestureCallback();
+				LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(activate_gesture_cb);
 				copy_inventory_item(
 					gAgent.getID(),
 					item->getPermissions().getOwner(),
@@ -2509,7 +2541,13 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 {
 	item = NULL;
 	cat = NULL;
-	if(mCargoIDs.empty()) return NULL;
+
+	if (mCargoIDs.empty()
+		|| (mSource == SOURCE_PEOPLE)) ///< There is no inventory item for people drag and drop.
+	{
+		return NULL;
+	}
+
 	if((mSource == SOURCE_AGENT) || (mSource == SOURCE_LIBRARY))
 	{
 		// The object should be in user inventory.
@@ -2545,6 +2583,7 @@ LLInventoryObject* LLToolDragAndDrop::locateInventory(
 	{
 		item = (LLViewerInventoryItem*)gToolBarView->getDragItem();
 	}
+
 	if(item) return item;
 	if(cat) return cat;
 	return NULL;
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 41aee484dbc6dc3566b360d0cfacbb817946c68e..f17300a76ab25d238ca43702260dc4d20635acc1 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -67,7 +67,8 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 		SOURCE_WORLD,
 		SOURCE_NOTECARD,
 		SOURCE_LIBRARY,
-		SOURCE_VIEWER
+		SOURCE_VIEWER,
+		SOURCE_PEOPLE
 	};
 
 	void beginDrag(EDragAndDropType type,
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp
index a754d8ee7ee63c68307382fbdcf16ea7a240c147..857b0f07146555cb123c854d1008be66fa950650 100644
--- a/indra/newview/lltoolfocus.cpp
+++ b/indra/newview/lltoolfocus.cpp
@@ -314,8 +314,6 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 	S32 dx = gViewerWindow->getCurrentMouseDX();
 	S32 dy = gViewerWindow->getCurrentMouseDY();
 	
-	BOOL moved_outside_slop = FALSE;
-	
 	if (hasMouseCapture() && mValidClickPoint)
 	{
 		mAccumX += llabs(dx);
@@ -323,19 +321,11 @@ BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask)
 
 		if (mAccumX >= SLOP_RANGE)
 		{
-			if (!mOutsideSlopX)
-			{
-				moved_outside_slop = TRUE;
-			}
 			mOutsideSlopX = TRUE;
 		}
 
 		if (mAccumY >= SLOP_RANGE)
 		{
-			if (!mOutsideSlopY)
-			{
-				moved_outside_slop = TRUE;
-			}
 			mOutsideSlopY = TRUE;
 		}
 	}
diff --git a/indra/newview/lltoolgun.cpp b/indra/newview/lltoolgun.cpp
index 857d1053618a44fab58f872a52639f00efa86103..c1735adc9c799ceb941ad88065c6e1d17f116df9 100644
--- a/indra/newview/lltoolgun.cpp
+++ b/indra/newview/lltoolgun.cpp
@@ -42,7 +42,7 @@
 #include "llhudmanager.h"
 #include "lltoolmgr.h"
 #include "lltoolgrab.h"
-
+#include "lluiimage.h"
 // Linden library includes
 #include "llwindow.h"			// setMouseClipping()
 
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 0d5daf129fc51c471e59ef9242ea34111c4d62ef..148e5a015b199b4397c567cf7f36a6b4b2b3e4b5 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -34,6 +34,7 @@
 #include "llaudioengine.h"
 #include "llviewercontrol.h"
 #include "llfontgl.h"
+#include "llwearable.h"
 #include "sound_ids.h"
 #include "v3math.h"
 #include "v3color.h"
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index a0c12df834f436072149be4a5e18694a8aa19bfb..fc9a316759e45046c09d18f93c43390112746978 100644
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -791,14 +791,10 @@ BOOL LLToolPie::handleTooltipLand(std::string line, std::string tooltip_msg)
 	
 	LLParcel* hover_parcel = LLViewerParcelMgr::getInstance()->getHoverParcel();
 	LLUUID owner;
-	S32 width = 0;
-	S32 height = 0;
 	
 	if ( hover_parcel )
 	{
 		owner = hover_parcel->getOwnerID();
-		width = S32(LLViewerParcelMgr::getInstance()->getHoverParcelWidth());
-		height = S32(LLViewerParcelMgr::getInstance()->getHoverParcelHeight());
 	}
 	
 	// Line: "Land"
@@ -973,33 +969,16 @@ BOOL LLToolPie::handleTooltipObject( LLViewerObject* hover_object, std::string l
 			|| !existing_inspector->getVisible()
 			|| existing_inspector->getKey()["avatar_id"].asUUID() != hover_object->getID())
 		{
-			// IDEVO: try to get display name + username
+			// Try to get display name + username
 			std::string final_name;
-			std::string full_name;
-			if (!gCacheName->getFullName(hover_object->getID(), full_name))
-			{
-			LLNameValue* firstname = hover_object->getNVPair("FirstName");
-			LLNameValue* lastname =  hover_object->getNVPair("LastName");
-			if (firstname && lastname)
-			{
-					full_name = LLCacheName::buildFullName(
-						firstname->getString(), lastname->getString());
-				}
-				else
-				{
-					full_name = LLTrans::getString("TooltipPerson");
-				}
-			}
-
 			LLAvatarName av_name;
-			if (LLAvatarNameCache::useDisplayNames() && 
-				LLAvatarNameCache::get(hover_object->getID(), &av_name))
+			if (LLAvatarNameCache::get(hover_object->getID(), &av_name))
 			{
 				final_name = av_name.getCompleteName();
 			}
 			else
 			{
-				final_name = full_name;
+				final_name = LLTrans::getString("TooltipPerson");;
 			}
 
 			// *HACK: We may select this object, so pretend it was clicked
@@ -1610,9 +1589,6 @@ BOOL LLToolPie::handleRightClickPick()
 
 	// didn't click in any UI object, so must have clicked in the world
 	LLViewerObject *object = mPick.getObject();
-	LLViewerObject *parent = NULL;
-	if(object)
-		parent = object->getRootEdit();
 	
 	// Can't ignore children here.
 	LLToolSelect::handleObjectSelection(mPick, FALSE, TRUE);
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 93ba3b25587c79ecd6334255ccd5bec27a1b467e..641fbc50422e966a8dfa98b32fabb9e62faeea3f 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -182,7 +182,7 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
 		return FALSE;
 	}
 
-	if (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX)
+	if (regionp->getRegionFlag(REGION_FLAGS_SANDBOX))
 	{
 		//LLFirstUse::useSandbox();
 	}
@@ -485,7 +485,7 @@ BOOL LLToolPlacer::addDuplicate(S32 x, S32 y)
 										FALSE);				// select copy
 
 	if (regionp
-		&& (regionp->getRegionFlags() & REGION_FLAGS_SANDBOX))
+		&& (regionp->getRegionFlag(REGION_FLAGS_SANDBOX)))
 	{
 		//LLFirstUse::useSandbox();
 	}
diff --git a/indra/newview/lluploadfloaterobservers.cpp b/indra/newview/lluploadfloaterobservers.cpp
index 5a6a17fbca81a7b4b01dfe79100380643ed23372..1d777b3f7f380be2e6fc0e560a52d580dc900851 100644
--- a/indra/newview/lluploadfloaterobservers.cpp
+++ b/indra/newview/lluploadfloaterobservers.cpp
@@ -33,9 +33,10 @@ LLUploadModelPremissionsResponder::LLUploadModelPremissionsResponder(const LLHan
 {
 }
 
-void LLUploadModelPremissionsResponder::error(U32 status, const std::string& reason)
+void LLUploadModelPremissionsResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	llwarns << "LLUploadModelPremissionsResponder::error("<< status << ": " << reason << ")" << llendl;
+	llwarns << "LLUploadModelPremissionsResponder error [status:"
+			<< status << "]: " << content << llendl;
 
 	LLUploadPermissionsObserver* observer = mObserverHandle.get();
 
diff --git a/indra/newview/lluploadfloaterobservers.h b/indra/newview/lluploadfloaterobservers.h
index 79aad282d71329e0c1f01414bd2643b980ee439e..b43ddb44d95456e57c9e952a51153c4409675d39 100644
--- a/indra/newview/lluploadfloaterobservers.h
+++ b/indra/newview/lluploadfloaterobservers.h
@@ -86,7 +86,7 @@ class LLUploadModelPremissionsResponder : public LLHTTPClient::Responder
 
 	LLUploadModelPremissionsResponder(const LLHandle<LLUploadPermissionsObserver>& observer);
 
-	void error(U32 status, const std::string& reason);
+	void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 	void result(const LLSD& content);
 
diff --git a/indra/newview/llurlhistory.cpp b/indra/newview/llurlhistory.cpp
index edec30f8c45f9a8646bf43487a35341f66f7753b..dd17068be55b9a3ac68312d3a3daa64050ca3bf8 100644
--- a/indra/newview/llurlhistory.cpp
+++ b/indra/newview/llurlhistory.cpp
@@ -112,8 +112,6 @@ void LLURLHistory::addURL(const std::string& collection, const std::string& url)
 // static
 void LLURLHistory::removeURL(const std::string& collection, const std::string& url)
 {
-	LLSD::array_iterator iter = sHistorySD[collection].beginArray();
-	LLSD::array_iterator end = sHistorySD[collection].endArray();
 	for(int index = 0; index < sHistorySD[collection].size(); index++)
 	{
 		if(sHistorySD[collection].get(index).asString() == url)
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
old mode 100644
new mode 100755
index 4c59fd037195925fe656ac3d99a5085061381173..aaa81c57d42c53a74c08e31eb770b22f94cece11
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -160,9 +160,7 @@ LLViewerAssetStats::LLViewerAssetStats()
 
 LLViewerAssetStats::LLViewerAssetStats(const LLViewerAssetStats & src)
 	: mRegionHandle(src.mRegionHandle),
-	  mResetTimestamp(src.mResetTimestamp),
-	  mPhaseStats(src.mPhaseStats),
-	  mAvatarRezStates(src.mAvatarRezStates)
+	  mResetTimestamp(src.mResetTimestamp)
 {
 	const PerRegionContainer::const_iterator it_end(src.mRegionStats.end());
 	for (PerRegionContainer::const_iterator it(src.mRegionStats.begin()); it_end != it; ++it)
@@ -258,17 +256,6 @@ LLViewerAssetStats::recordFPS(F32 fps)
 	mCurRegionStats->mFPS.record(fps);
 }
 
-void
-LLViewerAssetStats::recordAvatarStats()
-{
-	std::vector<S32> rez_counts;
-	LLVOAvatar::getNearbyRezzedStats(rez_counts);
-	mAvatarRezStates = rez_counts;
-	mPhaseStats.clear();
-	mPhaseStats["cloud"] = LLViewerStats::PhaseMap::getPhaseStats("cloud");
-	mPhaseStats["cloud-or-gray"] = LLViewerStats::PhaseMap::getPhaseStats("cloud-or-gray");
-}
-
 LLSD
 LLViewerAssetStats::asLLSD(bool compact_output)
 {
@@ -299,11 +286,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
 	static const LLSD::String max_tag("max");
 	static const LLSD::String mean_tag("mean");
 
-	// Avatar sub-tags
-	static const LLSD::String avatar_tag("avatar");
-	static const LLSD::String avatar_nearby_tag("nearby");
-	static const LLSD::String avatar_phase_stats_tag("phase_stats");
-	
 	const duration_t now = LLViewerAssetStatsFF::get_timestamp();
 	mCurRegionStats->accumulateTime(now);
 
@@ -362,16 +344,6 @@ LLViewerAssetStats::asLLSD(bool compact_output)
 	LLSD ret = LLSD::emptyMap();
 	ret["regions"] = regions;
 	ret["duration"] = LLSD::Real((now - mResetTimestamp) * 1.0e-6);
-	LLSD avatar_info;
-	avatar_info[avatar_nearby_tag] = LLSD::emptyArray();
-	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat)
-	{
-		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
-		avatar_info[avatar_nearby_tag][rez_status_name] = mAvatarRezStates[rez_stat];
-	}
-	avatar_info[avatar_phase_stats_tag]["cloud"] = mPhaseStats["cloud"].getData();
-	avatar_info[avatar_phase_stats_tag]["cloud-or-gray"] = mPhaseStats["cloud-or-gray"].getData();
-	ret[avatar_tag] = avatar_info;
 	
 	return ret;
 }
@@ -470,15 +442,6 @@ record_fps_main(F32 fps)
 	gViewerAssetStatsMain->recordFPS(fps);
 }
 
-void
-record_avatar_stats()
-{
-	if (! gViewerAssetStatsMain)
-		return;
-
-	gViewerAssetStatsMain->recordAvatarStats();
-}
-
 // 'thread1' - should be for TextureFetch thread
 
 void
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
old mode 100644
new mode 100755
index 83197522306f2572ce64bec9e908354d1ab1f255..e4581d2120629c4e0695d59c41348b8e527557de
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -256,10 +256,6 @@ class LLViewerAssetStats
 
 	// Time of last reset
 	duration_t mResetTimestamp;
-
-	// Nearby avatar stats
-	std::vector<S32> mAvatarRezStates;
-	LLViewerStats::phase_stats_t mPhaseStats;
 };
 
 
@@ -318,8 +314,6 @@ void record_response_main(LLViewerAssetType::EType at, bool with_http, bool is_t
 
 void record_fps_main(F32 fps);
 
-void record_avatar_stats();
-
 /**
  * Region context, event and duration loggers for Thread 1.
  */
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index a4b1c2155ffe63359ecb49ad45cd15b910890860..08ba5a5f252cebade2b4399a5fda49e2a0f332c5 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -83,6 +83,8 @@ LLViewerAssetDictionary::LLViewerAssetDictionary()
 	
 	addEntry(LLViewerAssetType::AT_WIDGET, 				new ViewerAssetEntry(DAD_WIDGET));
 	
+	addEntry(LLViewerAssetType::AT_PERSON, 				new ViewerAssetEntry(DAD_PERSON));
+
 	addEntry(LLViewerAssetType::AT_NONE, 				new ViewerAssetEntry(DAD_NONE));
 };
 
diff --git a/indra/newview/llviewerattachmenu.cpp b/indra/newview/llviewerattachmenu.cpp
index db7dc3fea61615b24efa0dd6dd936610715d863a..3975292ed3a6e7871384b9d21cebbfbf39876008 100644
--- a/indra/newview/llviewerattachmenu.cpp
+++ b/indra/newview/llviewerattachmenu.cpp
@@ -121,7 +121,7 @@ void LLViewerAttachMenu::attachObjects(const uuid_vec_t& items, const std::strin
 		else if(item && item->isFinished())
 		{
 			// must be in library. copy it to our inventory and put it on.
-			LLPointer<LLInventoryCallback> cb = new RezAttachmentCallback(attachmentp);
+			LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(boost::bind(rez_attachment_cb, _1, attachmentp));
 			copy_inventory_item(gAgent.getID(),
 								item->getPermissions().getOwner(),
 								item->getUUID(),
diff --git a/indra/newview/llvieweraudio.cpp b/indra/newview/llvieweraudio.cpp
index f349eeac6350ed4e6040c5e8284cd632d6acb763..094694dc06164737928f2d762adc23d46b68aacd 100644
--- a/indra/newview/llvieweraudio.cpp
+++ b/indra/newview/llvieweraudio.cpp
@@ -30,6 +30,7 @@
 #include "llagent.h"
 #include "llagentcamera.h"
 #include "llappviewer.h"
+#include "lldeferredsounds.h"
 #include "llvieweraudio.h"
 #include "llviewercamera.h"
 #include "llviewercontrol.h"
@@ -405,6 +406,12 @@ void audio_update_volume(bool force_update)
 
 		gAudiop->setMuted(mute_audio || progress_view_visible);
 		
+		//Play any deferred sounds when unmuted
+		if(!gAudiop->getMuted())
+		{
+			LLDeferredSounds::instance().playdeferredSounds();
+		}
+
 		if (force_update)
 		{
 			audio_update_wind(true);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index a437a8b3b53624fbfc657507db888792291a474e..b5aa0ac92aa489b045999356310fc38de1211a5a 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -136,9 +136,6 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
 
 	mLastPointOfInterest = point_of_interest;
 
-	// constrain to max distance from avatar
-	LLVector3 camera_offset = center - gAgent.getPositionAgent();
-
 	LLViewerRegion * regp = gAgent.getRegion();
 	F32 water_height = (NULL != regp) ? regp->getWaterHeight() : 0.f;
 
@@ -318,7 +315,7 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 {
 	F32 fov_y, aspect;
 	fov_y = RAD_TO_DEG * getView();
-	BOOL z_default_near, z_default_far = FALSE;
+	BOOL z_default_far = FALSE;
 	if (z_far <= 0)
 	{
 		z_default_far = TRUE;
@@ -326,7 +323,6 @@ void LLViewerCamera::setPerspective(BOOL for_selection,
 	}
 	if (z_near <= 0)
 	{
-		z_default_near = TRUE;
 		z_near = getNear();
 	}
 	aspect = getAspect();
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index ffeea2f4df936aa827557f97016c393394a18b69..cf59e679551fbfaa939697420b40190b0ed35b97 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -1038,7 +1038,6 @@ void render_hud_attachments()
 	if (LLPipeline::sShowHUDAttachments && !gDisconnected && setup_hud_matrices())
 	{
 		LLCamera hud_cam = *LLViewerCamera::getInstance();
-		LLVector3 origin = hud_cam.getOrigin();
 		hud_cam.setOrigin(-1.f,0,0);
 		hud_cam.setAxes(LLVector3(1,0,0), LLVector3(0,1,0), LLVector3(0,0,1));
 		LLViewerCamera::updateFrustumPlanes(hud_cam, TRUE);
@@ -1425,7 +1424,7 @@ void render_ui_2d()
 		gGL.pushMatrix();
 		S32 half_width = (gViewerWindow->getWorldViewWidthScaled() / 2);
 		S32 half_height = (gViewerWindow->getWorldViewHeightScaled() / 2);
-		gGL.scalef(LLUI::sGLScaleFactor.mV[0], LLUI::sGLScaleFactor.mV[1], 1.f);
+		gGL.scalef(LLUI::getScaleFactor().mV[0], LLUI::getScaleFactor().mV[1], 1.f);
 		gGL.translatef((F32)half_width, (F32)half_height, 0.f);
 		F32 zoom = gAgentCamera.mHUDCurZoom;
 		gGL.scalef(zoom,zoom,1.f);
@@ -1463,10 +1462,10 @@ void render_ui_2d()
 				LLUI::sDirtyRect = last_rect;
 				last_rect = t_rect;
 			
-				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::sGLScaleFactor.mV[0]);
-				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::sGLScaleFactor.mV[1]);
-				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::sGLScaleFactor.mV[1]);
+				last_rect.mLeft = LLRect::tCoordType(last_rect.mLeft / LLUI::getScaleFactor().mV[0]);
+				last_rect.mRight = LLRect::tCoordType(last_rect.mRight / LLUI::getScaleFactor().mV[0]);
+				last_rect.mTop = LLRect::tCoordType(last_rect.mTop / LLUI::getScaleFactor().mV[1]);
+				last_rect.mBottom = LLRect::tCoordType(last_rect.mBottom / LLUI::getScaleFactor().mV[1]);
 
 				LLRect clip_rect(last_rect);
 				
diff --git a/indra/newview/llviewerdisplayname.cpp b/indra/newview/llviewerdisplayname.cpp
index 5741fab29ae7b5dba3681195573e74e55213c2f8..f81206ffecd27f57a1a3c8779c9b2d92f24ca94d 100644
--- a/indra/newview/llviewerdisplayname.cpp
+++ b/indra/newview/llviewerdisplayname.cpp
@@ -53,14 +53,17 @@ namespace LLViewerDisplayName
 		sNameChangedSignal.connect(cb); 
 	}
 
+	void doNothing() { }
 }
 
 class LLSetDisplayNameResponder : public LLHTTPClient::Responder
 {
 public:
 	// only care about errors
-	/*virtual*/ void error(U32 status, const std::string& reason)
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
+		llwarns << "LLSetDisplayNameResponder error [status:"
+				<< status << "]: " << content << llendl;
 		LLViewerDisplayName::sSetDisplayNameSignal(false, "", LLSD());
 		LLViewerDisplayName::sSetDisplayNameSignal.disconnect_all_slots();
 	}
@@ -97,7 +100,7 @@ void LLViewerDisplayName::set(const std::string& display_name, const set_name_sl
 
 	// People API expects array of [ "old value", "new value" ]
 	LLSD change_array = LLSD::emptyArray();
-	change_array.append(av_name.mDisplayName);
+	change_array.append(av_name.getDisplayName());
 	change_array.append(display_name);
 	
 	llinfos << "Set name POST to " << cap_url << llendl;
@@ -139,9 +142,9 @@ class LLSetDisplayNameReply : public LLHTTPNode
 			LLUUID agent_id = gAgent.getID();
 			// Flush stale data
 			LLAvatarNameCache::erase( agent_id );
-			// Queue request for new data
-			LLAvatarName ignored;
-			LLAvatarNameCache::get( agent_id, &ignored );
+			// Queue request for new data: nothing to do on callback though...
+			// Note: no need to disconnect the callback as it never gets out of scope
+			LLAvatarNameCache::get(agent_id, boost::bind(&LLViewerDisplayName::doNothing));
 			// Kill name tag, as it is wrong
 			LLVOAvatar::invalidateNameTag( agent_id );
 		}
@@ -189,8 +192,8 @@ class LLDisplayNameUpdate : public LLHTTPNode
 
 		LLSD args;
 		args["OLD_NAME"] = old_display_name;
-		args["SLID"] = av_name.mUsername;
-		args["NEW_NAME"] = av_name.mDisplayName;
+		args["SLID"] = av_name.getUserName();
+		args["NEW_NAME"] = av_name.getDisplayName();
 		LLNotificationsUtil::add("DisplayNameUpdate", args);
 		if (agent_id == gAgent.getID())
 		{
diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp
index 1f7cf0cdd449b9e6d76362e472d93866039dd7c8..c6b28b9e5e9fd7bd9e926b345b1e7c7fc9be09f5 100644
--- a/indra/newview/llviewerfloaterreg.cpp
+++ b/indra/newview/llviewerfloaterreg.cpp
@@ -32,7 +32,6 @@
 #include "llviewerfloaterreg.h"
 #include "llfloaterautoreplacesettings.h"
 #include "llcompilequeue.h"
-#include "llcallfloater.h"
 #include "llfasttimerview.h"
 #include "llfloaterabout.h"
 #include "llfloaterauction.h"
@@ -50,6 +49,9 @@
 #include "llfloaterbump.h"
 #include "llfloaterbvhpreview.h"
 #include "llfloatercamera.h"
+#include "llfloaterchatvoicevolume.h"
+#include "llfloaterconversationlog.h"
+#include "llfloaterconversationpreview.h"
 #include "llfloaterdeleteenvpreset.h"
 #include "llfloaterdisplayname.h"
 #include "llfloatereditdaycycle.h"
@@ -69,7 +71,7 @@
 #include "llfloatermediasettings.h"
 #include "llfloaterhud.h"
 #include "llfloaterimagepreview.h"
-#include "llimfloater.h"
+#include "llfloaterimsession.h"
 #include "llfloaterinspect.h"
 #include "llfloaterinventory.h"
 #include "llfloaterjoystick.h"
@@ -114,17 +116,18 @@
 #include "llfloatertranslationsettings.h"
 #include "llfloateruipreview.h"
 #include "llfloatervoiceeffect.h"
+#include "llfloatervoicevolume.h"
 #include "llfloaterwhitelistentry.h"
 #include "llfloaterwindowsize.h"
 #include "llfloaterworldmap.h"
-#include "llimfloatercontainer.h"
+#include "llfloaterimcontainer.h"
 #include "llinspectavatar.h"
 #include "llinspectgroup.h"
 #include "llinspectobject.h"
 #include "llinspectremoteobject.h"
 #include "llinspecttoast.h"
 #include "llmoveview.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llpanelblockedlist.h"
 #include "llpanelclassified.h"
 #include "llpreviewanim.h"
@@ -137,7 +140,6 @@
 #include "llscriptfloater.h"
 #include "llfloatermodelpreview.h"
 #include "llcommandhandler.h"
-#include "llnearbychatbar.h"
 
 // *NOTE: Please add files in alphabetical order to keep merges easy.
 
@@ -190,9 +192,10 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("bumps", "floater_bumps.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterBump>);
 
 	LLFloaterReg::add("camera", "floater_camera.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCamera>);
-	LLFloaterReg::add("chat_bar", "floater_chat_bar.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLNearbyChatBar>);
-
+	LLFloaterReg::add("chat_voice", "floater_voice_chat_volume.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterChatVoiceVolume>);
+	LLFloaterReg::add("nearby_chat", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterIMNearbyChat::buildFloater);
 	LLFloaterReg::add("compile_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterCompileQueue>);
+	LLFloaterReg::add("conversation", "floater_conversation_log.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationLog>);
 
 	LLFloaterReg::add("destinations", "floater_destinations.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterDestinations>);
 
@@ -214,8 +217,8 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("help_browser", "floater_help_browser.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHelpBrowser>);	
 	LLFloaterReg::add("hud", "floater_hud.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterHUD>);
 
-	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloater>);
-	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMFloaterContainer>);
+	LLFloaterReg::add("impanel", "floater_im_session.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMSession>);
+	LLFloaterReg::add("im_container", "floater_im_container.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterIMContainer>);
 	LLFloaterReg::add("im_well_window", "floater_sys_well.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIMWellWindow>);
 	LLFloaterReg::add("incoming_call", "floater_incoming_call.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLIncomingCallDialog>);
 	LLFloaterReg::add("inventory", "floater_my_inventory.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
@@ -224,6 +227,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLInspectGroupUtil::registerFloater();
 	LLInspectObjectUtil::registerFloater();
 	LLInspectRemoteObjectUtil::registerFloater();
+	LLFloaterVoiceVolumeUtil::registerFloater();
 	LLNotificationsUI::registerFloater();
 	LLFloaterDisplayNameUtil::registerFloater();
 	
@@ -268,6 +272,7 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("picks", "floater_picks.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSidePanelContainer>);
 	LLFloaterReg::add("pref_joystick", "floater_joystick.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterJoystick>);
 	LLFloaterReg::add("preview_anim", "floater_preview_animation.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewAnim>, "preview");
+	LLFloaterReg::add("preview_conversation", "floater_conversation_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterConversationPreview>);
 	LLFloaterReg::add("preview_gesture", "floater_preview_gesture.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewGesture>, "preview");
 	LLFloaterReg::add("preview_notecard", "floater_preview_notecard.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewNotecard>, "preview");
 	LLFloaterReg::add("preview_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLPreviewLSL>, "preview");
@@ -316,7 +321,6 @@ void LLViewerFloaterReg::registerFloaters()
 	LLFloaterReg::add("upload_script", "floater_script_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterScriptPreview>, "upload");
 	LLFloaterReg::add("upload_sound", "floater_sound_preview.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterSoundPreview>, "upload");
 
-	LLFloaterReg::add("voice_controls", "floater_voice_controls.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLCallFloater>);
 	LLFloaterReg::add("voice_effect", "floater_voice_effect.xml", (LLFloaterBuildFunc)&LLFloaterReg::build<LLFloaterVoiceEffect>);
 
 	LLFloaterReg::add("web_content", "floater_web_content.xml", (LLFloaterBuildFunc)&LLFloaterWebContent::create);	
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
old mode 100644
new mode 100755
diff --git a/indra/newview/llviewergesture.cpp b/indra/newview/llviewergesture.cpp
index a32a78cbf924c4f89a7505088a6357487c01fe6a..3f35a5001d5387199ed5fe450bc1075a756a121b 100644
--- a/indra/newview/llviewergesture.cpp
+++ b/indra/newview/llviewergesture.cpp
@@ -33,6 +33,7 @@
 #include "llviewerinventory.h"
 #include "sound_ids.h"		// for testing
 
+#include "llfloaterreg.h"
 #include "llkeyboard.h"		// for key shortcuts for testing
 #include "llinventorymodel.h"
 #include "llvoavatar.h"
@@ -40,7 +41,7 @@
 #include "llviewermessage.h" // send_guid_sound_trigger
 #include "llviewernetwork.h"
 #include "llagent.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 
 // Globals
 LLViewerGestureList gGestureList;
@@ -130,7 +131,8 @@ void LLViewerGesture::doTrigger( BOOL send_chat )
 	{
 		// Don't play nodding animation, since that might not blend
 		// with the gesture animation.
-		LLNearbyChatBar::getInstance()->sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
+		(LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->
+				sendChatFromViewer(mOutputString, CHAT_TYPE_NORMAL, FALSE);
 	}
 }
 
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index b47a41c44c9d891acafafd097d90388a8499b550..fff9821e86d0efa81fc939cd278529443f4be0b7 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -64,6 +64,11 @@
 #include "llavatarnamecache.h"
 #include "llavataractions.h"
 #include "lllogininstance.h"
+#include "llfavoritesbar.h"
+
+// Two do-nothing ops for use in callbacks.
+void no_op_inventory_func(const LLUUID&) {} 
+void no_op() {}
 
 ///----------------------------------------------------------------------------
 /// Helper class to store special inventory item names and their localized values.
@@ -588,7 +593,7 @@ void LLViewerInventoryCategory::copyViewerCategory(const LLViewerInventoryCatego
 {
 	copyCategory(other);
 	mOwnerID = other->mOwnerID;
-	mVersion = other->mVersion;
+	setVersion(other->getVersion());
 	mDescendentCount = other->mDescendentCount;
 	mDescendentsRequested = other->mDescendentsRequested;
 }
@@ -656,9 +661,19 @@ void LLViewerInventoryCategory::removeFromServer( void )
 	gAgent.sendReliableMessage();
 }
 
+S32 LLViewerInventoryCategory::getVersion() const
+{
+	return mVersion;
+}
+
+void LLViewerInventoryCategory::setVersion(S32 version)
+{
+	mVersion = version;
+}
+
 bool LLViewerInventoryCategory::fetch()
 {
-	if((VERSION_UNKNOWN == mVersion)
+	if((VERSION_UNKNOWN == getVersion())
 	   && mDescendentsRequested.hasExpired())	//Expired check prevents multiple downloads.
 	{
 		LL_DEBUGS("InventoryFetch") << "Fetching category children: " << mName << ", UUID: " << mUUID << LL_ENDL;
@@ -949,46 +964,7 @@ void LLInventoryCallbackManager::fire(U32 callback_id, const LLUUID& item_id)
 	}
 }
 
-void WearOnAvatarCallback::fire(const LLUUID& inv_item)
-{
-	if (inv_item.isNull())
-		return;
-
-	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
-	if (item)
-	{
-		LLAppearanceMgr::instance().wearItemOnAvatar(inv_item, true, mReplace);
-	}
-}
-
-void ModifiedCOFCallback::fire(const LLUUID& inv_item)
-{
-	LLAppearanceMgr::instance().updateAppearanceFromCOF();
-
-	// Start editing the item if previously requested.
-	gAgentWearables.editWearableIfRequested(inv_item);
-
-	// TODO: camera mode may not be changed if a debug setting is tweaked
-	if( gAgentCamera.cameraCustomizeAvatar() )
-	{
-		// If we're in appearance editing mode, the current tab may need to be refreshed
-		LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-		if (panel)
-		{
-			panel->showDefaultSubpart();
-		}
-	}
-}
-
-RezAttachmentCallback::RezAttachmentCallback(LLViewerJointAttachment *attachmentp)
-{
-	mAttach = attachmentp;
-}
-RezAttachmentCallback::~RezAttachmentCallback()
-{
-}
-
-void RezAttachmentCallback::fire(const LLUUID& inv_item)
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp)
 {
 	if (inv_item.isNull())
 		return;
@@ -996,11 +972,11 @@ void RezAttachmentCallback::fire(const LLUUID& inv_item)
 	LLViewerInventoryItem *item = gInventory.getItem(inv_item);
 	if (item)
 	{
-		rez_attachment(item, mAttach);
+		rez_attachment(item, attachmentp);
 	}
 }
 
-void ActivateGestureCallback::fire(const LLUUID& inv_item)
+void activate_gesture_cb(const LLUUID& inv_item)
 {
 	if (inv_item.isNull())
 		return;
@@ -1013,7 +989,7 @@ void ActivateGestureCallback::fire(const LLUUID& inv_item)
 	LLGestureMgr::instance().activateGesture(inv_item);
 }
 
-void CreateGestureCallback::fire(const LLUUID& inv_item)
+void create_gesture_cb(const LLUUID& inv_item)
 {
 	if (inv_item.isNull())
 		return;
@@ -1030,12 +1006,6 @@ void CreateGestureCallback::fire(const LLUUID& inv_item)
 	gFloaterView->adjustToFitScreen(preview, FALSE);
 }
 
-void AddFavoriteLandmarkCallback::fire(const LLUUID& inv_item_id)
-{
-	if (mTargetLandmarkId.isNull()) return;
-
-	gInventory.rearrangeFavoriteLandmarks(inv_item_id, mTargetLandmarkId);
-}
 
 LLInventoryCallbackManager gInventoryCallbacks;
 
@@ -1162,6 +1132,11 @@ void link_inventory_item(
 		}
 	}
 
+#if 1 // debugging stuff
+	LLViewerInventoryCategory* cat = gInventory.getCategory(parent_id);
+	lldebugs << "cat: " << cat << llendl;
+	
+#endif
 	LLMessageSystem* msg = gMessageSystem;
 	msg->newMessageFast(_PREHASH_LinkInventoryItem);
 	msg->nextBlock(_PREHASH_AgentData);
@@ -1288,7 +1263,7 @@ void create_new_item(const std::string& name,
 	
 	if (inv_type == LLInventoryType::IT_GESTURE)
 	{
-		LLPointer<LLInventoryCallback> cb = new CreateGestureCallback();
+		LLPointer<LLInventoryCallback> cb = new LLBoostFuncInventoryCallback(create_gesture_cb);
 		create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
 							  parent_id, LLTransactionID::tnull, name, desc, asset_type, inv_type,
 							  NOT_WEARABLE, next_owner_perm, cb);
@@ -1308,7 +1283,7 @@ const std::string NEW_NOTECARD_NAME = "New Note"; // *TODO:Translate? (probably
 const std::string NEW_GESTURE_NAME = "New Gesture"; // *TODO:Translate? (probably not)
 
 // ! REFACTOR ! Really need to refactor this so that it's not a bunch of if-then statements...
-void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
+void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, const LLSD& userdata, const LLUUID& default_parent_uuid)
 {
 	std::string type_name = userdata.asString();
 	
@@ -1332,7 +1307,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
 
 		LLUUID category = gInventory.createNewCategory(parent_id, preferred_type, LLStringUtil::null);
 		gInventory.notifyObservers();
-		root->setSelectionByID(category, TRUE);
+		panel->setSelectionByID(category, TRUE);
 	}
 	else if ("lsl" == type_name)
 	{
@@ -1375,7 +1350,7 @@ void menu_create_inventory_item(LLFolderView* root, LLFolderBridge *bridge, cons
 			llwarns << "Can't create unrecognized type " << type_name << llendl;
 		}
 	}
-	root->setNeedsAutoRename(TRUE);	
+	panel->getRootFolder()->setNeedsAutoRename(TRUE);	
 }
 
 LLAssetType::EType LLViewerInventoryItem::getType() const
@@ -1449,336 +1424,16 @@ const std::string& LLViewerInventoryItem::getName() const
 	return  LLInventoryItem::getName();
 }
 
-/**
- * Class to store sorting order of favorites landmarks in a local file. EXT-3985.
- * It replaced previously implemented solution to store sort index in landmark's name as a "<N>@" prefix.
- * Data are stored in user home directory.
- */
-class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
-	, public LLDestroyClass<LLFavoritesOrderStorage>
-{
-	LOG_CLASS(LLFavoritesOrderStorage);
-public:
-	/**
-	 * Sets sort index for specified with LLUUID favorite landmark
-	 */
-	void setSortIndex(const LLUUID& inv_item_id, S32 sort_index);
-
-	/**
-	 * Gets sort index for specified with LLUUID favorite landmark
-	 */
-	S32 getSortIndex(const LLUUID& inv_item_id);
-	void removeSortIndex(const LLUUID& inv_item_id);
-
-	void getSLURL(const LLUUID& asset_id);
-
-	/**
-	 * Implementation of LLDestroyClass. Calls cleanup() instance method.
-	 *
-	 * It is important this callback is called before gInventory is cleaned.
-	 * For now it is called from LLAppViewer::cleanup() -> LLAppViewer::disconnectViewer(),
-	 * Inventory is cleaned later from LLAppViewer::cleanup() after LLAppViewer::disconnectViewer() is called.
-	 * @see cleanup()
-	 */
-	static void destroyClass();
-
-	const static S32 NO_INDEX;
-private:
-	friend class LLSingleton<LLFavoritesOrderStorage>;
-	LLFavoritesOrderStorage() : mIsDirty(false) { load(); }
-	~LLFavoritesOrderStorage() { save(); }
-
-	/**
-	 * Removes sort indexes for items which are not in Favorites bar for now.
-	 */
-	void cleanup();
-
-	const static std::string SORTING_DATA_FILE_NAME;
-
-	void load();
-	void save();
-
-	void saveFavoritesSLURLs();
-
-	// Remove record of current user's favorites from file on disk.
-	void removeFavoritesRecordOfUser();
-
-	void onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark);
-	void storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl);
-
-	typedef std::map<LLUUID, S32> sort_index_map_t;
-	sort_index_map_t mSortIndexes;
-
-	typedef std::map<LLUUID, std::string> slurls_map_t;
-	slurls_map_t mSLURLs;
-
-	bool mIsDirty;
-
-	struct IsNotInFavorites
-	{
-		IsNotInFavorites(const LLInventoryModel::item_array_t& items)
-			: mFavoriteItems(items)
-		{
-
-		}
-
-		/**
-		 * Returns true if specified item is not found among inventory items
-		 */
-		bool operator()(const sort_index_map_t::value_type& id_index_pair) const
-		{
-			LLPointer<LLViewerInventoryItem> item = gInventory.getItem(id_index_pair.first);
-			if (item.isNull()) return true;
-
-			LLInventoryModel::item_array_t::const_iterator found_it =
-				std::find(mFavoriteItems.begin(), mFavoriteItems.end(), item);
-
-			return found_it == mFavoriteItems.end();
-		}
-	private:
-		LLInventoryModel::item_array_t mFavoriteItems;
-	};
-
-};
-
-const std::string LLFavoritesOrderStorage::SORTING_DATA_FILE_NAME = "landmarks_sorting.xml";
-const S32 LLFavoritesOrderStorage::NO_INDEX = -1;
-
-void LLFavoritesOrderStorage::setSortIndex(const LLUUID& inv_item_id, S32 sort_index)
-{
-	mSortIndexes[inv_item_id] = sort_index;
-	mIsDirty = true;
-}
-
-S32 LLFavoritesOrderStorage::getSortIndex(const LLUUID& inv_item_id)
-{
-	sort_index_map_t::const_iterator it = mSortIndexes.find(inv_item_id);
-	if (it != mSortIndexes.end())
-	{
-		return it->second;
-	}
-	return NO_INDEX;
-}
-
-void LLFavoritesOrderStorage::removeSortIndex(const LLUUID& inv_item_id)
-{
-	mSortIndexes.erase(inv_item_id);
-	mIsDirty = true;
-}
-
-void LLFavoritesOrderStorage::getSLURL(const LLUUID& asset_id)
-{
-	slurls_map_t::iterator slurl_iter = mSLURLs.find(asset_id);
-	if (slurl_iter != mSLURLs.end()) return; // SLURL for current landmark is already cached
-
-	LLLandmark* lm = gLandmarkList.getAsset(asset_id,
-			boost::bind(&LLFavoritesOrderStorage::onLandmarkLoaded, this, asset_id, _1));
-	if (lm)
-	{
-		onLandmarkLoaded(asset_id, lm);
-	}
-}
-
-// static
-void LLFavoritesOrderStorage::destroyClass()
-{
-	LLFavoritesOrderStorage::instance().cleanup();
-	if (gSavedPerAccountSettings.getBOOL("ShowFavoritesOnLogin"))
-	{
-		LLFavoritesOrderStorage::instance().saveFavoritesSLURLs();
-	}
-	else
-	{
-		LLFavoritesOrderStorage::instance().removeFavoritesRecordOfUser();
-	}
-}
-
-void LLFavoritesOrderStorage::load()
-{
-	// load per-resident sorting information
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-
-	LLSD settings_llsd;
-	llifstream file;
-	file.open(filename);
-	if (file.is_open())
-	{
-		LLSDSerialize::fromXML(settings_llsd, file);
-	}
-
-	for (LLSD::map_const_iterator iter = settings_llsd.beginMap();
-		iter != settings_llsd.endMap(); ++iter)
-	{
-		mSortIndexes.insert(std::make_pair(LLUUID(iter->first), (S32)iter->second.asInteger()));
-	}
-}
-
-void LLFavoritesOrderStorage::saveFavoritesSLURLs()
-{
-	// Do not change the file if we are not logged in yet.
-	if (!LLLoginInstance::getInstance()->authSuccess())
-	{
-		llwarns << "Cannot save favorites: not logged in" << llendl;
-		return;
-	}
-	
-	std::string user_dir = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "");
-	if (user_dir.empty())
-	{
-		llwarns << "Cannot save favorites: empty user dir name" << llendl;
-		return;
-	}
-
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
-	llifstream in_file;
-	in_file.open(filename);
-	LLSD fav_llsd;
-	if (in_file.is_open())
-	{
-		LLSDSerialize::fromXML(fav_llsd, in_file);
-	}
-
-	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
-	LLSD user_llsd;
-	for (LLInventoryModel::item_array_t::iterator it = items.begin(); it != items.end(); it++)
-	{
-		LLSD value;
-		value["name"] = (*it)->getName();
-		value["asset_id"] = (*it)->getAssetUUID();
-
-		slurls_map_t::iterator slurl_iter = mSLURLs.find(value["asset_id"]);
-		if (slurl_iter != mSLURLs.end())
-		{
-			lldebugs << "Saving favorite: idx=" << (*it)->getSortField() << ", SLURL=" <<  slurl_iter->second << ", value=" << value << llendl;
-			value["slurl"] = slurl_iter->second;
-			user_llsd[(*it)->getSortField()] = value;
-		}
-		else
-		{
-			llwarns << "Not saving favorite " << value["name"] << ": no matching SLURL" << llendl;
-		}
-	}
-
-	LLAvatarName av_name;
-	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Saved favorites for " << av_name.getLegacyName() << llendl;
-	fav_llsd[av_name.getLegacyName()] = user_llsd;
-
-	llofstream file;
-	file.open(filename);
-	LLSDSerialize::toPrettyXML(fav_llsd, file);
-}
-
-void LLFavoritesOrderStorage::removeFavoritesRecordOfUser()
-{
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS, "stored_favorites.xml");
-	LLSD fav_llsd;
-	llifstream file;
-	file.open(filename);
-	if (!file.is_open()) return;
-	LLSDSerialize::fromXML(fav_llsd, file);
-
-	LLAvatarName av_name;
-	LLAvatarNameCache::get( gAgentID, &av_name );
-	lldebugs << "Removed favorites for " << av_name.getLegacyName() << llendl;
-	if (fav_llsd.has(av_name.getLegacyName()))
-	{
-		fav_llsd.erase(av_name.getLegacyName());
-	}
-
-	llofstream out_file;
-	out_file.open(filename);
-	LLSDSerialize::toPrettyXML(fav_llsd, out_file);
-
-}
-
-void LLFavoritesOrderStorage::onLandmarkLoaded(const LLUUID& asset_id, LLLandmark* landmark)
-{
-	if (!landmark) return;
-
-	LLVector3d pos_global;
-	if (!landmark->getGlobalPos(pos_global))
-	{
-		// If global position was unknown on first getGlobalPos() call
-		// it should be set for the subsequent calls.
-		landmark->getGlobalPos(pos_global);
-	}
-
-	if (!pos_global.isExactlyZero())
-	{
-		LLLandmarkActions::getSLURLfromPosGlobal(pos_global,
-				boost::bind(&LLFavoritesOrderStorage::storeFavoriteSLURL, this, asset_id, _1));
-	}
-}
-
-void LLFavoritesOrderStorage::storeFavoriteSLURL(const LLUUID& asset_id, std::string& slurl)
-{
-	lldebugs << "Saving landmark SLURL: " << slurl << llendl;
-	mSLURLs[asset_id] = slurl;
-}
-
-void LLFavoritesOrderStorage::save()
-{
-	// nothing to save if clean
-	if (!mIsDirty) return;
-
-	// If we quit from the login screen we will not have an SL account
-	// name.  Don't try to save, otherwise we'll dump a file in
-	// C:\Program Files\SecondLife\ or similar. JC
-	std::string user_dir = gDirUtilp->getLindenUserDir();
-	if (!user_dir.empty())
-	{
-		std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_PER_SL_ACCOUNT, SORTING_DATA_FILE_NAME);
-		LLSD settings_llsd;
-
-		for(sort_index_map_t::const_iterator iter = mSortIndexes.begin(); iter != mSortIndexes.end(); ++iter)
-		{
-			settings_llsd[iter->first.asString()] = iter->second;
-		}
-
-		llofstream file;
-		file.open(filename);
-		LLSDSerialize::toPrettyXML(settings_llsd, file);
-	}
-}
-
-void LLFavoritesOrderStorage::cleanup()
-{
-	// nothing to clean
-	if (!mIsDirty) return;
-
-	const LLUUID fav_id = gInventory.findCategoryUUIDForType(LLFolderType::FT_FAVORITE);
-	LLInventoryModel::cat_array_t cats;
-	LLInventoryModel::item_array_t items;
-	gInventory.collectDescendents(fav_id, cats, items, LLInventoryModel::EXCLUDE_TRASH);
-
-	IsNotInFavorites is_not_in_fav(items);
-
-	sort_index_map_t  aTempMap;
-	//copy unremoved values from mSortIndexes to aTempMap
-	std::remove_copy_if(mSortIndexes.begin(), mSortIndexes.end(), 
-		inserter(aTempMap, aTempMap.begin()),
-		is_not_in_fav);
-
-	//Swap the contents of mSortIndexes and aTempMap
-	mSortIndexes.swap(aTempMap);
-}
-
-
 S32 LLViewerInventoryItem::getSortField() const
 {
 	return LLFavoritesOrderStorage::instance().getSortIndex(mUUID);
 }
 
-void LLViewerInventoryItem::setSortField(S32 sortField)
-{
-	LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
-	getSLURL();
-}
+//void LLViewerInventoryItem::setSortField(S32 sortField)
+//{
+//	LLFavoritesOrderStorage::instance().setSortIndex(mUUID, sortField);
+//	getSLURL();
+//}
 
 void LLViewerInventoryItem::getSLURL()
 {
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 7822ef4da6548d688f39fd5c9bd2ec188467eabc..61b1b8d84651ce46f6c54dbc722d0730c229e208 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -34,6 +34,7 @@
 
 #include <boost/signals2.hpp>	// boost::signals2::trackable
 
+class LLInventoryPanel;
 class LLFolderView;
 class LLFolderBridge;
 class LLViewerInventoryCategory;
@@ -61,7 +62,7 @@ class LLViewerInventoryItem : public LLInventoryItem, public boost::signals2::tr
 	virtual const LLUUID& getProtectedAssetUUID() const; // returns LLUUID::null if current agent does not have permission to expose this asset's UUID to the user
 	virtual const std::string& getName() const;
 	virtual S32 getSortField() const;
-	virtual void setSortField(S32 sortField);
+	//virtual void setSortField(S32 sortField);
 	virtual void getSLURL(); //Caches SLURL for landmark. //*TODO: Find a better way to do it and remove this method from here.
 	virtual const LLPermissions& getPermissions() const;
 	virtual const bool getIsFullPerm() const; // 'fullperm' in the popular sense: modify-ok & copy-ok & transfer-ok, no special god rules applied
@@ -205,13 +206,13 @@ class LLViewerInventoryCategory  : public LLInventoryCategory
 
 	// Version handling
 	enum { VERSION_UNKNOWN = -1, VERSION_INITIAL = 1 };
-	S32 getVersion() const { return mVersion; }
-	void setVersion(S32 version) { mVersion = version; }
+	S32 getVersion() const;
+	void setVersion(S32 version);
 
 	// Returns true if a fetch was issued.
 	bool fetch();
 
-	// used to help make cacheing more robust - for example, if
+	// used to help make caching more robust - for example, if
 	// someone is getting 4 packets but logs out after 3. the viewer
 	// may never know the cache is wrong.
 	enum { DESCENDENT_COUNT_UNKNOWN = -1 };
@@ -219,7 +220,7 @@ class LLViewerInventoryCategory  : public LLInventoryCategory
 	void setDescendentCount(S32 descendents) { mDescendentCount = descendents; }
 
 	// file handling on the viewer. These are not meant for anything
-	// other than cacheing.
+	// other than caching.
 	bool exportFileLocal(LLFILE* fp) const;
 	bool importFileLocal(LLFILE* fp);
 	void determineFolderType();
@@ -242,59 +243,60 @@ class LLInventoryCallback : public LLRefCount
 	virtual void fire(const LLUUID& inv_item) = 0;
 };
 
-class WearOnAvatarCallback : public LLInventoryCallback
-{
-public:
-	WearOnAvatarCallback(bool do_replace = false) : mReplace(do_replace) {}
-	
-	void fire(const LLUUID& inv_item);
+class LLViewerJointAttachment;
 
-protected:
-	bool mReplace;
-};
+void rez_attachment_cb(const LLUUID& inv_item, LLViewerJointAttachment *attachmentp);
 
-class ModifiedCOFCallback : public LLInventoryCallback
-{
-	void fire(const LLUUID& inv_item);
-};
+void activate_gesture_cb(const LLUUID& inv_item);
 
-class LLViewerJointAttachment;
+void create_gesture_cb(const LLUUID& inv_item);
 
-class RezAttachmentCallback : public LLInventoryCallback
+class AddFavoriteLandmarkCallback : public LLInventoryCallback
 {
 public:
-	RezAttachmentCallback(LLViewerJointAttachment *attachmentp);
-	void fire(const LLUUID& inv_item);
-
-protected:
-	~RezAttachmentCallback();
+	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
+	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
 
 private:
-	LLViewerJointAttachment* mAttach;
-};
-
-class ActivateGestureCallback : public LLInventoryCallback
-{
-public:
 	void fire(const LLUUID& inv_item);
-};
 
-class CreateGestureCallback : public LLInventoryCallback
-{
-public:
-	void fire(const LLUUID& inv_item);
+	LLUUID mTargetLandmarkId;
 };
 
-class AddFavoriteLandmarkCallback : public LLInventoryCallback
+typedef boost::function<void(const LLUUID&)> inventory_func_type;
+void no_op_inventory_func(const LLUUID&); // A do-nothing inventory_func
+
+typedef boost::function<void()> nullary_func_type;
+void no_op(); // A do-nothing nullary func.
+
+// Shim between inventory callback and boost function/callable
+class LLBoostFuncInventoryCallback: public LLInventoryCallback
 {
 public:
-	AddFavoriteLandmarkCallback() : mTargetLandmarkId(LLUUID::null) {}
-	void setTargetLandmarkId(const LLUUID& target_uuid) { mTargetLandmarkId = target_uuid; }
 
-private:
-	void fire(const LLUUID& inv_item);
+	LLBoostFuncInventoryCallback(inventory_func_type fire_func,
+								 nullary_func_type destroy_func = no_op):
+		mFireFunc(fire_func),
+		mDestroyFunc(destroy_func)
+	{
+	}
 
-	LLUUID mTargetLandmarkId;
+	// virtual
+	void fire(const LLUUID& item_id)
+	{
+		mFireFunc(item_id);
+	}
+
+	// virtual
+	~LLBoostFuncInventoryCallback()
+	{
+		mDestroyFunc();
+	}
+	
+
+private:
+	inventory_func_type mFireFunc;
+	nullary_func_type mDestroyFunc;
 };
 
 // misc functions
@@ -372,7 +374,7 @@ void copy_inventory_from_notecard(const LLUUID& destination_id,
 								  U32 callback_id = 0);
 
 
-void menu_create_inventory_item(LLFolderView* root,
+void menu_create_inventory_item(LLInventoryPanel* root,
 								LLFolderBridge* bridge,
 								const LLSD& userdata,
 								const LLUUID& default_parent_uuid = LLUUID::null);
diff --git a/indra/newview/llviewerjoint.cpp b/indra/newview/llviewerjoint.cpp
index a907f102f87f55a4680224c1d522b024b0577158..e46299f9d2d54ae2cf90c2aff73944100d9ceaa6 100644
--- a/indra/newview/llviewerjoint.cpp
+++ b/indra/newview/llviewerjoint.cpp
@@ -35,50 +35,26 @@
 #include "llrender.h"
 #include "llmath.h"
 #include "llglheaders.h"
-#include "llrendersphere.h"
 #include "llvoavatar.h"
 #include "pipeline.h"
 
-#define DEFAULT_LOD 0.0f
-
-const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
-
-//-----------------------------------------------------------------------------
-// Static Data
-//-----------------------------------------------------------------------------
-BOOL					LLViewerJoint::sDisableLOD = FALSE;
+static const S32 MIN_PIXEL_AREA_3PASS_HAIR = 64*64;
 
 //-----------------------------------------------------------------------------
 // LLViewerJoint()
-// Class Constructor
+// Class Constructors
 //-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint()
-	:       LLJoint()
-{
-	init();
-}
+LLViewerJoint::LLViewerJoint() :
+	LLAvatarJoint()
+{ }
 
+LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent) :
+	LLAvatarJoint(name, parent)
+{ }
 
-//-----------------------------------------------------------------------------
-// LLViewerJoint()
-// Class Constructor
-//-----------------------------------------------------------------------------
-LLViewerJoint::LLViewerJoint(const std::string &name, LLJoint *parent)
-	:	LLJoint(name, parent)
-{
-	init();
-}
-
-
-void LLViewerJoint::init()
-{
-	mValid = FALSE;
-	mComponents = SC_JOINT | SC_BONE | SC_AXES;
-	mMinPixelArea = DEFAULT_LOD;
-	mPickName = PN_DEFAULT;
-	mVisible = TRUE;
-	mMeshID = 0;
-}
+LLViewerJoint::LLViewerJoint(S32 joint_num) :
+	LLAvatarJoint(joint_num)
+{ }
 
 
 //-----------------------------------------------------------------------------
@@ -89,154 +65,6 @@ LLViewerJoint::~LLViewerJoint()
 {
 }
 
-
-//--------------------------------------------------------------------
-// setValid()
-//--------------------------------------------------------------------
-void LLViewerJoint::setValid( BOOL valid, BOOL recursive )
-{
-	//----------------------------------------------------------------
-	// set visibility for this joint
-	//----------------------------------------------------------------
-	mValid = valid;
-	
-	//----------------------------------------------------------------
-	// set visibility for children
-	//----------------------------------------------------------------
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setValid(valid, TRUE);
-		}
-	}
-
-}
-
-//--------------------------------------------------------------------
-// renderSkeleton()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::renderSkeleton(BOOL recursive)
-// {
-// 	F32 nc = 0.57735f;
-
-// 	//----------------------------------------------------------------
-// 	// push matrix stack
-// 	//----------------------------------------------------------------
-// 	gGL.pushMatrix();
-
-// 	//----------------------------------------------------------------
-// 	// render the bone to my parent
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_BONE)
-// 	{
-// 		drawBone();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// offset to joint position and 
-// 	// rotate to our orientation
-// 	//----------------------------------------------------------------
-// 	gGL.loadIdentity();
-// 	gGL.multMatrix( &getWorldMatrix().mMatrix[0][0] );
-
-// 	//----------------------------------------------------------------
-// 	// render joint axes
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_AXES)
-// 	{
-// 		gGL.begin(LLRender::LINES);
-// 		gGL.color3f( 1.0f, 0.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f,            0.0f, 0.0f );
-// 		gGL.vertex3f( 0.1f, 0.0f, 0.0f );
-
-// 		gGL.color3f( 0.0f, 1.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f,            0.0f );
-// 		gGL.vertex3f( 0.0f, 0.1f, 0.0f );
-
-// 		gGL.color3f( 0.0f, 0.0f, 1.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f, 0.0f );
-// 		gGL.vertex3f( 0.0f, 0.0f, 0.1f );
-// 		gGL.end();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// render the joint graphic
-// 	//----------------------------------------------------------------
-// 	if (mComponents & SC_JOINT)
-// 	{
-// 		gGL.color3f( 1.0f, 1.0f, 0.0f );
-
-// 		gGL.begin(LLRender::TRIANGLES);
-
-// 		// joint top half
-// 		glNormal3f(nc, nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(0.05f,       0.0f,       0.0f);
-// 		gGL.vertex3f(0.0f,       0.05f,       0.0f);
-
-// 		glNormal3f(-nc, nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(0.0f,       0.05f,       0.0f);
-// 		gGL.vertex3f(-0.05f,      0.0f,       0.0f);
-		
-// 		glNormal3f(-nc, -nc, nc);
-// 		gGL.vertex3f(0.0f,             0.0f, 0.05f);
-// 		gGL.vertex3f(-0.05f,      0.0f,      0.0f);
-// 		gGL.vertex3f(0.0f,      -0.05f,      0.0f);
-
-// 		glNormal3f(nc, -nc, nc);
-// 		gGL.vertex3f(0.0f,              0.0f, 0.05f);
-// 		gGL.vertex3f(0.0f,       -0.05f,       0.0f);
-// 		gGL.vertex3f(0.05f,        0.0f,       0.0f);
-		
-// 		// joint bottom half
-// 		glNormal3f(nc, nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f, -0.05f);
-// 		gGL.vertex3f(0.0f,       0.05f,        0.0f);
-// 		gGL.vertex3f(0.05f,       0.0f,        0.0f);
-
-// 		glNormal3f(-nc, nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f, -0.05f);
-// 		gGL.vertex3f(-0.05f,      0.0f,        0.0f);
-// 		gGL.vertex3f(0.0f,       0.05f,        0.0f);
-		
-// 		glNormal3f(-nc, -nc, -nc);
-// 		gGL.vertex3f(0.0f,              0.0f, -0.05f);
-// 		gGL.vertex3f(0.0f,       -0.05f,        0.0f);
-// 		gGL.vertex3f(-0.05f,       0.0f,        0.0f);
-
-// 		glNormal3f(nc, -nc, -nc);
-// 		gGL.vertex3f(0.0f,             0.0f,  -0.05f);
-// 		gGL.vertex3f(0.05f,       0.0f,         0.0f);
-// 		gGL.vertex3f(0.0f,      -0.05f,         0.0f);
-		
-// 		gGL.end();
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// render children
-// 	//----------------------------------------------------------------
-// 	if (recursive)
-// 	{
-// 		for (child_list_t::iterator iter = mChildren.begin();
-// 			 iter != mChildren.end(); ++iter)
-// 		{
-// 			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-// 			joint->renderSkeleton();
-// 		}
-// 	}
-
-// 	//----------------------------------------------------------------
-// 	// pop matrix stack
-// 	//----------------------------------------------------------------
-// 	gGL.popMatrix();
-// }
-
-
 //--------------------------------------------------------------------
 // render()
 //--------------------------------------------------------------------
@@ -317,13 +145,13 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	for (child_list_t::iterator iter = mChildren.begin();
 		 iter != mChildren.end(); ++iter)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
+		LLAvatarJoint* joint = dynamic_cast<LLAvatarJoint*>(*iter);
 		F32 jointLOD = joint->getLOD();
 		if (pixelArea >= jointLOD || sDisableLOD)
 		{
 			triangle_count += joint->render( pixelArea, TRUE, is_dummy );
 
-			if (jointLOD != DEFAULT_LOD)
+			if (jointLOD != DEFAULT_AVATAR_JOINT_LOD)
 			{
 				break;
 			}
@@ -333,72 +161,6 @@ U32 LLViewerJoint::render( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	return triangle_count;
 }
 
-
-//--------------------------------------------------------------------
-// drawBone()
-// DEBUG (UNUSED)
-//--------------------------------------------------------------------
-// void LLViewerJoint::drawBone()
-// {
-// 	if ( mParent == NULL )
-// 		return;
-
-// 	F32 boneSize = 0.02f;
-
-// 	// rotate to point to child (bone direction)
-// 	gGL.pushMatrix();
-
-// 	LLVector3 boneX = getPosition();
-// 	F32 length = boneX.normVec();
-
-// 	LLVector3 boneZ(1.0f, 0.0f, 1.0f);
-	
-// 	LLVector3 boneY = boneZ % boneX;
-// 	boneY.normVec();
-
-// 	boneZ = boneX % boneY;
-
-// 	LLMatrix4 rotateMat;
-// 	rotateMat.setFwdRow( boneX );
-// 	rotateMat.setLeftRow( boneY );
-// 	rotateMat.setUpRow( boneZ );
-// 	gGL.multMatrix( &rotateMat.mMatrix[0][0] );
-
-// 	// render the bone
-// 	gGL.color3f( 0.5f, 0.5f, 0.0f );
-
-// 	gGL.begin(LLRender::TRIANGLES);
-
-// 	gGL.vertex3f( length,     0.0f,       0.0f);
-// 	gGL.vertex3f( 0.0f,       boneSize,  0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,       boneSize);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        -boneSize);
-// 	gGL.vertex3f( 0.0f,       boneSize,   0.0f);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       -boneSize,  0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        -boneSize);
-
-// 	gGL.vertex3f( length,     0.0f,        0.0f);
-// 	gGL.vertex3f( 0.0f,       0.0f,        boneSize);
-// 	gGL.vertex3f( 0.0f,       -boneSize,  0.0f);
-
-// 	gGL.end();
-
-// 	// restore matrix
-// 	gGL.popMatrix();
-// }
-
-//--------------------------------------------------------------------
-// isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJoint::isTransparent()
-{
-	return FALSE;
-}
-
 //--------------------------------------------------------------------
 // drawShape()
 //--------------------------------------------------------------------
@@ -407,213 +169,4 @@ U32 LLViewerJoint::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy )
 	return 0;
 }
 
-//--------------------------------------------------------------------
-// setSkeletonComponents()
-//--------------------------------------------------------------------
-void LLViewerJoint::setSkeletonComponents( U32 comp, BOOL recursive )
-{
-	mComponents = comp;
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setSkeletonComponents(comp, recursive);
-		}
-	}
-}
-
-void LLViewerJoint::updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area)
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateFaceSizes(num_vertices, num_indices, pixel_area);
-	}
-}
-
-void LLViewerJoint::updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind, bool terse_update)
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateFaceData(face, pixel_area, damp_wind, terse_update);
-	}
-}
-
-void LLViewerJoint::updateJointGeometry()
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->updateJointGeometry();
-	}
-}
-
-
-BOOL LLViewerJoint::updateLOD(F32 pixel_area, BOOL activate)
-{
-	BOOL lod_changed = FALSE;
-	BOOL found_lod = FALSE;
-
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		F32 jointLOD = joint->getLOD();
-		
-		if (found_lod || jointLOD == DEFAULT_LOD)
-		{
-			// we've already found a joint to enable, so enable the rest as alternatives
-			lod_changed |= joint->updateLOD(pixel_area, TRUE);
-		}
-		else
-		{
-			if (pixel_area >= jointLOD || sDisableLOD)
-			{
-				lod_changed |= joint->updateLOD(pixel_area, TRUE);
-				found_lod = TRUE;
-			}
-			else
-			{
-				lod_changed |= joint->updateLOD(pixel_area, FALSE);
-			}
-		}
-	}
-	return lod_changed;
-}
-
-void LLViewerJoint::dump()
-{
-	for (child_list_t::iterator iter = mChildren.begin();
-		 iter != mChildren.end(); ++iter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-		joint->dump();
-	}
-}
-
-void LLViewerJoint::setVisible(BOOL visible, BOOL recursive)
-{
-	mVisible = visible;
-
-	if (recursive)
-	{
-		for (child_list_t::iterator iter = mChildren.begin();
-			 iter != mChildren.end(); ++iter)
-		{
-			LLViewerJoint* joint = (LLViewerJoint*)(*iter);
-			joint->setVisible(visible, recursive);
-		}
-	}
-}
-
-
-void LLViewerJoint::setMeshesToChildren()
-{
-	removeAllChildren();
-	for (std::vector<LLViewerJointMesh*>::iterator iter = mMeshParts.begin();
-		iter != mMeshParts.end(); iter++)
-	{
-		addChild((LLViewerJointMesh *) *iter);
-	}
-}
-//-----------------------------------------------------------------------------
-// LLViewerJointCollisionVolume()
-//-----------------------------------------------------------------------------
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume()
-{
-	mUpdateXform = FALSE;
-}
-
-LLViewerJointCollisionVolume::LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent) : LLViewerJoint(name, parent)
-{
-	
-}
-
-void LLViewerJointCollisionVolume::renderCollision()
-{
-	updateWorldMatrix();
-	
-	gGL.pushMatrix();
-	gGL.multMatrix( &mXform.getWorldMatrix().mMatrix[0][0] );
-
-	gGL.diffuseColor3f( 0.f, 0.f, 1.f );
-	
-	gGL.begin(LLRender::LINES);
-	
-	LLVector3 v[] = 
-	{
-		LLVector3(1,0,0),
-		LLVector3(-1,0,0),
-		LLVector3(0,1,0),
-		LLVector3(0,-1,0),
-
-		LLVector3(0,0,-1),
-		LLVector3(0,0,1),
-	};
-
-	//sides
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[2].mV);
-
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[3].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[2].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[3].mV);
-
-
-	//top
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[2].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-	gGL.vertex3fv(v[3].mV); 
-	gGL.vertex3fv(v[4].mV);
-
-
-	//bottom
-	gGL.vertex3fv(v[0].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[1].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[2].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.vertex3fv(v[3].mV); 
-	gGL.vertex3fv(v[5].mV);
-
-	gGL.end();
-
-	gGL.popMatrix();
-}
-
-LLVector3 LLViewerJointCollisionVolume::getVolumePos(LLVector3 &offset)
-{
-	mUpdateXform = TRUE;
-	
-	LLVector3 result = offset;
-	result.scaleVec(getScale());
-	result.rotVec(getWorldRotation());
-	result += getWorldPosition();
-
-	return result;
-}
-
 // End
diff --git a/indra/newview/llviewerjoint.h b/indra/newview/llviewerjoint.h
index 76e3833acbf4fcaff77dd3796abd77c1a2c9df7c..fd262b6e804793cfdc602545bd83dbd668ff2cd9 100644
--- a/indra/newview/llviewerjoint.h
+++ b/indra/newview/llviewerjoint.h
@@ -30,7 +30,8 @@
 //-----------------------------------------------------------------------------
 // Header Files
 //-----------------------------------------------------------------------------
-#include "lljoint.h"
+#include "llavatarjoint.h"
+#include "lljointpickname.h"
 
 class LLFace;
 class LLViewerJointMesh;
@@ -39,124 +40,25 @@ class LLViewerJointMesh;
 // class LLViewerJoint
 //-----------------------------------------------------------------------------
 class LLViewerJoint :
-	public LLJoint
+	public virtual LLAvatarJoint
 {
 public:
 	LLViewerJoint();
+	LLViewerJoint(S32 joint_num);
+	// *TODO: Only used for LLVOAvatarSelf::mScreenp.  *DOES NOT INITIALIZE mResetAfterRestoreOldXform*
 	LLViewerJoint(const std::string &name, LLJoint *parent = NULL);
 	virtual ~LLViewerJoint();
 
-	// Gets the validity of this joint
-	BOOL getValid() { return mValid; }
-
-	// Sets the validity of this joint
-	virtual void setValid( BOOL valid, BOOL recursive=FALSE );
-
-	// Primarily for debugging and character setup
-	// Derived classes may add text/graphic output.
-	// Draw skeleton graphic for debugging and character setup
- 	void renderSkeleton(BOOL recursive=TRUE); // debug only (unused)
-
-	// Draws a bone graphic to the parent joint.
-	// Derived classes may add text/graphic output.
-	// Called by renderSkeleton().
- 	void drawBone(); // debug only (unused)
-
 	// Render character hierarchy.
 	// Traverses the entire joint hierarchy, setting up
 	// transforms and calling the drawShape().
 	// Derived classes may add text/graphic output.
 	virtual U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );	// Returns triangle count
 
-	// Returns true if this object is transparent.
-	// This is used to determine in which order to draw objects.
-	virtual BOOL isTransparent();
-
-	// Returns true if this object should inherit scale modifiers from its immediate parent
-	virtual BOOL inheritScale() { return FALSE; }
-
 	// Draws the shape attached to a joint.
 	// Called by render().
 	virtual U32 drawShape( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE );
 	virtual void drawNormals() {}
-
-	enum Components
-	{
-		SC_BONE		= 1,
-		SC_JOINT	= 2,
-		SC_AXES		= 4
-	};
-
-	// Selects which skeleton components to draw
-	void setSkeletonComponents( U32 comp, BOOL recursive = TRUE );
-
-	// Returns which skeleton components are enables for drawing
-	U32 getSkeletonComponents() { return mComponents; }
-
-	// Sets the level of detail for this node as a minimum
-	// pixel area threshold.  If the current pixel area for this
-	// object is less than the specified threshold, the node is
-	// not traversed.  In addition, if a value is specified (not
-	// default of 0.0), and the pixel area is larger than the
-	// specified minimum, the node is rendered, but no other siblings
-	// of this node under the same parent will be.
-	F32 getLOD() { return mMinPixelArea; }
-	void setLOD( F32 pixelArea ) { mMinPixelArea = pixelArea; }
-	
-	// Sets the OpenGL selection stack name that is pushed and popped
-	// with this joint state.  The default value indicates that no name
-	// should be pushed/popped.
-	enum PickName
-	{
-		PN_DEFAULT = -1,
-		PN_0 = 0,
-		PN_1 = 1,
-		PN_2 = 2,
-		PN_3 = 3,
-		PN_4 = 4,
-		PN_5 = 5
-	};
-	void setPickName(PickName name) { mPickName = name; }
-	PickName getPickName() { return mPickName; }
-
-	virtual void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
-	virtual void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
-	virtual BOOL updateLOD(F32 pixel_area, BOOL activate);
-	virtual void updateJointGeometry();
-	virtual void dump();
-
-	void setVisible( BOOL visible, BOOL recursive );
-
-	// Takes meshes in mMeshParts and sets each one as a child joint
-	void setMeshesToChildren();
-
-public:
-	static BOOL	sDisableLOD;
-	std::vector<LLViewerJointMesh*> mMeshParts;
-	void setMeshID( S32 id ) {mMeshID = id;}
-
-protected:
-	void init();
-
-	BOOL		mValid;
-	U32			mComponents;
-	F32			mMinPixelArea;
-	PickName	mPickName;
-	BOOL		mVisible;
-	S32			mMeshID;
-};
-
-class LLViewerJointCollisionVolume : public LLViewerJoint
-{
-public:
-	LLViewerJointCollisionVolume();
-	LLViewerJointCollisionVolume(const std::string &name, LLJoint *parent = NULL);
-	virtual ~LLViewerJointCollisionVolume() {};
-
-	virtual BOOL inheritScale() { return TRUE; }
-
-	void renderCollision();
-	LLVector3 getVolumePos(LLVector3 &offset);
 };
 
 #endif // LL_LLVIEWERJOINT_H
diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp
index 5d1aa870a3165ee455c8d2dc4e90825cec78658a..64454a03d1a7e4b5bb92617eb60b0e69a054859c 100644
--- a/indra/newview/llviewerjointmesh.cpp
+++ b/indra/newview/llviewerjointmesh.cpp
@@ -42,7 +42,7 @@
 #include "llface.h"
 #include "llgldbg.h"
 #include "llglheaders.h"
-#include "lltexlayer.h"
+#include "llviewertexlayer.h"
 #include "llviewercamera.h"
 #include "llviewercontrol.h"
 #include "llviewertexturelist.h"
@@ -67,101 +67,20 @@ static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX |
 							   LLVertexBuffer::MAP_NORMAL |
 							   LLVertexBuffer::MAP_TEXCOORD0;
 
-
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::LLSkinJoint
-//-----------------------------------------------------------------------------
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::LLSkinJoint()
-{
-	mJoint       = NULL;
-}
-
-//-----------------------------------------------------------------------------
-// ~LLSkinJoint
-//-----------------------------------------------------------------------------
-LLSkinJoint::~LLSkinJoint()
-{
-	mJoint = NULL;
-}
-
-
-//-----------------------------------------------------------------------------
-// LLSkinJoint::setupSkinJoint()
-//-----------------------------------------------------------------------------
-BOOL LLSkinJoint::setupSkinJoint( LLViewerJoint *joint)
-{
-	// find the named joint
-	mJoint = joint;
-	if ( !mJoint )
-	{
-		llinfos << "Can't find joint" << llendl;
-	}
-
-	// compute the inverse root skin matrix
-	mRootToJointSkinOffset.clearVec();
-
-	LLVector3 rootSkinOffset;
-	while (joint)
-	{
-		rootSkinOffset += joint->getSkinOffset();
-		joint = (LLViewerJoint*)joint->getParent();
-	}
-
-	mRootToJointSkinOffset = -rootSkinOffset;
-	mRootToParentJointSkinOffset = mRootToJointSkinOffset;
-	mRootToParentJointSkinOffset += mJoint->getSkinOffset();
-
-	return TRUE;
-}
-
-
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 // LLViewerJointMesh
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
-BOOL LLViewerJointMesh::sPipelineRender = FALSE;
-EAvatarRenderPass LLViewerJointMesh::sRenderPass = AVATAR_RENDER_PASS_SINGLE;
-U32 LLViewerJointMesh::sClothingMaskImageName = 0;
-LLColor4 LLViewerJointMesh::sClothingInnerColor;
 
 //-----------------------------------------------------------------------------
 // LLViewerJointMesh()
 //-----------------------------------------------------------------------------
 LLViewerJointMesh::LLViewerJointMesh()
 	:
-	mTexture( NULL ),
-	mLayerSet( NULL ),
-	mTestImageName( 0 ),
-	mFaceIndexCount(0),
-	mIsTransparent(FALSE)
+	LLAvatarJointMesh()
 {
-
-	mColor[0] = 1.0f;
-	mColor[1] = 1.0f;
-	mColor[2] = 1.0f;
-	mColor[3] = 1.0f;
-	mShiny = 0.0f;
-	mCullBackFaces = TRUE;
-
-	mMesh = NULL;
-
-	mNumSkinJoints = 0;
-	mSkinJoints = NULL;
-
-	mFace = NULL;
-
-	mMeshID = 0;
-	mUpdateXform = FALSE;
-
-	mValid = FALSE;
 }
 
 
@@ -171,199 +90,6 @@ LLViewerJointMesh::LLViewerJointMesh()
 //-----------------------------------------------------------------------------
 LLViewerJointMesh::~LLViewerJointMesh()
 {
-	mMesh = NULL;
-	mTexture = NULL;
-	freeSkinData();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::allocateSkinData()
-//-----------------------------------------------------------------------------
-BOOL LLViewerJointMesh::allocateSkinData( U32 numSkinJoints )
-{
-	mSkinJoints = new LLSkinJoint[ numSkinJoints ];
-	mNumSkinJoints = numSkinJoints;
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::freeSkinData()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::freeSkinData()
-{
-	mNumSkinJoints = 0;
-	delete [] mSkinJoints;
-	mSkinJoints = NULL;
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha )
-{
-	*red   = mColor[0];
-	*green = mColor[1];
-	*blue  = mColor[2];
-	*alpha = mColor[3];
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setColor()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setColor( F32 red, F32 green, F32 blue, F32 alpha )
-{
-	mColor[0] = red;
-	mColor[1] = green;
-	mColor[2] = blue;
-	mColor[3] = alpha;
-}
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getTexture()
-//--------------------------------------------------------------------
-//LLViewerTexture *LLViewerJointMesh::getTexture()
-//{
-//	return mTexture;
-//}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setTexture()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setTexture( LLViewerTexture *texture )
-{
-	mTexture = texture;
-
-	// texture and dynamic_texture are mutually exclusive
-	if( texture )
-	{
-		mLayerSet = NULL;
-		//texture->bindTexture(0);
-		//texture->setClamp(TRUE, TRUE);
-	}
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::setLayerSet()
-// Sets the shape texture (takes precedence over normal texture)
-//--------------------------------------------------------------------
-void LLViewerJointMesh::setLayerSet( LLTexLayerSet* layer_set )
-{
-	mLayerSet = layer_set;
-	
-	// texture and dynamic_texture are mutually exclusive
-	if( layer_set )
-	{
-		mTexture = NULL;
-	}
-}
-
-
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::getMesh()
-//--------------------------------------------------------------------
-LLPolyMesh *LLViewerJointMesh::getMesh()
-{
-	return mMesh;
-}
-
-//-----------------------------------------------------------------------------
-// LLViewerJointMesh::setMesh()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setMesh( LLPolyMesh *mesh )
-{
-	// set the mesh pointer
-	mMesh = mesh;
-
-	// release any existing skin joints
-	freeSkinData();
-
-	if ( mMesh == NULL )
-	{
-		return;
-	}
-
-	// acquire the transform from the mesh object
-	setPosition( mMesh->getPosition() );
-	setRotation( mMesh->getRotation() );
-	setScale( mMesh->getScale() );
-
-	// create skin joints if necessary
-	if ( mMesh->hasWeights() && !mMesh->isLOD())
-	{
-		U32 numJointNames = mMesh->getNumJointNames();
-		
-		allocateSkinData( numJointNames );
-		std::string *jointNames = mMesh->getJointNames();
-
-		U32 jn;
-		for (jn = 0; jn < numJointNames; jn++)
-		{
-			//llinfos << "Setting up joint " << jointNames[jn] << llendl;
-			LLViewerJoint* joint = (LLViewerJoint*)(getRoot()->findJoint(jointNames[jn]) );
-			mSkinJoints[jn].setupSkinJoint( joint );
-		}
-	}
-
-	// setup joint array
-	if (!mMesh->isLOD())
-	{
-		setupJoint((LLViewerJoint*)getRoot());
-	}
-
-//	llinfos << "joint render entries: " << mMesh->mJointRenderData.count() << llendl;
-}
-
-//-----------------------------------------------------------------------------
-// setupJoint()
-//-----------------------------------------------------------------------------
-void LLViewerJointMesh::setupJoint(LLViewerJoint* current_joint)
-{
-//	llinfos << "Mesh: " << getName() << llendl;
-
-//	S32 joint_count = 0;
-	U32 sj;
-	for (sj=0; sj<mNumSkinJoints; sj++)
-	{
-		LLSkinJoint &js = mSkinJoints[sj];
-
-		if (js.mJoint != current_joint)
-		{
-			continue;
-		}
-
-		// we've found a skinjoint for this joint..
-
-		// is the last joint in the array our parent?
-		if(mMesh->mJointRenderData.count() && mMesh->mJointRenderData[mMesh->mJointRenderData.count() - 1]->mWorldMatrix == &current_joint->getParent()->getWorldMatrix())
-		{
-			// ...then just add ourselves
-			LLViewerJoint* jointp = js.mJoint;
-			mMesh->mJointRenderData.put(new LLJointRenderData(&jointp->getWorldMatrix(), &js));
-//			llinfos << "joint " << joint_count << js.mJoint->getName() << llendl;
-//			joint_count++;
-		}
-		// otherwise add our parent and ourselves
-		else
-		{
-			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getParent()->getWorldMatrix(), NULL));
-//			llinfos << "joint " << joint_count << current_joint->getParent()->getName() << llendl;
-//			joint_count++;
-			mMesh->mJointRenderData.put(new LLJointRenderData(&current_joint->getWorldMatrix(), &js));
-//			llinfos << "joint " << joint_count << current_joint->getName() << llendl;
-//			joint_count++;
-		}
-	}
-
-	// depth-first traversal
-	for (LLJoint::child_list_t::iterator iter = current_joint->mChildren.begin();
-		 iter != current_joint->mChildren.end(); ++iter)
-	{
-		LLViewerJoint* child_joint = (LLViewerJoint*)(*iter);
-		setupJoint(child_joint);
-	}
 }
 
 const S32 NUM_AXES = 3;
@@ -474,21 +200,6 @@ void LLViewerJointMesh::uploadJointMatrices()
 	}
 }
 
-//--------------------------------------------------------------------
-// LLViewerJointMesh::drawBone()
-//--------------------------------------------------------------------
-void LLViewerJointMesh::drawBone()
-{
-}
-
-//--------------------------------------------------------------------
-// LLViewerJointMesh::isTransparent()
-//--------------------------------------------------------------------
-BOOL LLViewerJointMesh::isTransparent()
-{
-	return mIsTransparent;
-}
-
 //--------------------------------------------------------------------
 // DrawElementsBLEND and utility code
 //--------------------------------------------------------------------
@@ -544,6 +255,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 	llassert( !(mTexture.notNull() && mLayerSet) );  // mutually exclusive
 
 	LLTexUnit::eTextureAddressMode old_mode = LLTexUnit::TAM_WRAP;
+	LLViewerTexLayerSet *layerset = dynamic_cast<LLViewerTexLayerSet*>(mLayerSet);
 	if (mTestImageName)
 	{
 		gGL.getTexUnit(diffuse_channel)->bindManual(LLTexUnit::TT_TEXTURE, mTestImageName);
@@ -558,11 +270,11 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy)
 			gGL.getTexUnit(diffuse_channel)->setTextureColorBlend(LLTexUnit::TBO_LERP_TEX_ALPHA, LLTexUnit::TBS_TEX_COLOR, LLTexUnit::TBS_PREV_COLOR);
 		}
 	}
-	else if( !is_dummy && mLayerSet )
+	else if( !is_dummy && layerset )
 	{
-		if(	mLayerSet->hasComposite() )
+		if(	layerset->hasComposite() )
 		{
-			gGL.getTexUnit(diffuse_channel)->bind(mLayerSet->getComposite());
+			gGL.getTexUnit(diffuse_channel)->bind(layerset->getViewerComposite());
 		}
 		else
 		{
diff --git a/indra/newview/llviewerjointmesh.h b/indra/newview/llviewerjointmesh.h
index dd5dae1dc1e997cd330ffcfbf9c6aa03e0eedbdd..0db2836e150b749e8e2c03e1a0fa34340deb1e48 100644
--- a/indra/newview/llviewerjointmesh.h
+++ b/indra/newview/llviewerjointmesh.h
@@ -1,6 +1,6 @@
 /** 
  * @file llviewerjointmesh.h
- * @brief Implementation of LLViewerJointMesh class
+ * @brief Declaration of LLViewerJointMesh class
  *
  * $LicenseInfo:firstyear=2001&license=viewerlgpl$
  * Second Life Viewer Source Code
@@ -29,64 +29,20 @@
 
 #include "llviewerjoint.h"
 #include "llviewertexture.h"
+#include "llavatarjointmesh.h"
 #include "llpolymesh.h"
 #include "v4color.h"
 
 class LLDrawable;
 class LLFace;
 class LLCharacter;
-class LLTexLayerSet;
-
-typedef enum e_avatar_render_pass
-{
-	AVATAR_RENDER_PASS_SINGLE,
-	AVATAR_RENDER_PASS_CLOTHING_INNER,
-	AVATAR_RENDER_PASS_CLOTHING_OUTER
-} EAvatarRenderPass;
-
-class LLSkinJoint
-{
-public:
-	LLSkinJoint();
-	~LLSkinJoint();
-	BOOL setupSkinJoint( LLViewerJoint *joint);
-
-	LLViewerJoint	*mJoint;
-	LLVector3		mRootToJointSkinOffset;
-	LLVector3		mRootToParentJointSkinOffset;
-};
+class LLViewerTexLayerSet;
 
 //-----------------------------------------------------------------------------
 // class LLViewerJointMesh
 //-----------------------------------------------------------------------------
-class LLViewerJointMesh : public LLViewerJoint
+class LLViewerJointMesh : public LLAvatarJointMesh, public LLViewerJoint
 {
-	friend class LLVOAvatar;
-protected:
-	LLColor4					mColor;			// color value
-// 	LLColor4					mSpecular;		// specular color (always white for now)
-	F32							mShiny;			// shiny value
-	LLPointer<LLViewerTexture>	mTexture;		// ptr to a global texture
-	LLTexLayerSet*				mLayerSet;		// ptr to a layer set owned by the avatar
-	U32 						mTestImageName;		// handle to a temporary texture for previewing uploads
-	LLPolyMesh*					mMesh;			// ptr to a global polymesh
-	BOOL						mCullBackFaces;	// true by default
-	LLFace*						mFace;			// ptr to a face w/ AGP copy of mesh
-
-	U32							mFaceIndexCount;
-	BOOL						mIsTransparent;
-
-	U32							mNumSkinJoints;
-	LLSkinJoint*				mSkinJoints;
-	S32							mMeshID;
-
-public:
-	static BOOL					sPipelineRender;
-	//RN: this is here for testing purposes
-	static U32					sClothingMaskImageName;
-	static EAvatarRenderPass	sRenderPass;
-	static LLColor4				sClothingInnerColor;
-
 public:
 	// Constructor
 	LLViewerJointMesh();
@@ -94,67 +50,28 @@ class LLViewerJointMesh : public LLViewerJoint
 	// Destructor
 	virtual ~LLViewerJointMesh();
 
-	// Gets the shape color
-	void getColor( F32 *red, F32 *green, F32 *blue, F32 *alpha );
-
-	// Sets the shape color
-	void setColor( F32 red, F32 green, F32 blue, F32 alpha );
-
-	// Sets the shininess
-	void setSpecular( const LLColor4& color, F32 shiny ) { /*mSpecular = color;*/ mShiny = shiny; };
-
-	// Sets the shape texture
-	void setTexture( LLViewerTexture *texture );
-
-	void setTestTexture( U32 name ) { mTestImageName = name; }
-
-	// Sets layer set responsible for a dynamic shape texture (takes precedence over normal texture)
-	void setLayerSet( LLTexLayerSet* layer_set );
-
-	// Gets the poly mesh
-	LLPolyMesh *getMesh();
-
-	// Sets the poly mesh
-	void setMesh( LLPolyMesh *mesh );
-
-	// Sets up joint matrix data for rendering
-	void setupJoint(LLViewerJoint* current_joint);
-
 	// Render time method to upload batches of joint matrices
 	void uploadJointMatrices();
 
-	// Sets ID for picking
-	void setMeshID( S32 id ) {mMeshID = id;}
-
-	// Gets ID for picking
-	S32 getMeshID() { return mMeshID; }	
-
 	// overloaded from base class
-	/*virtual*/ void drawBone();
-	/*virtual*/ BOOL isTransparent();
 	/*virtual*/ U32 drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy );
 
+	// necessary because MS's compiler warns on function inheritance via dominance in the diamond inheritance here.
+	// warns even though LLViewerJoint holds the only non virtual implementation.
+	/*virtual*/ U32 render( F32 pixelArea, BOOL first_pass = TRUE, BOOL is_dummy = FALSE ) { return LLViewerJoint::render(pixelArea,first_pass,is_dummy);}
+
 	/*virtual*/ void updateFaceSizes(U32 &num_vertices, U32& num_indices, F32 pixel_area);
 	/*virtual*/ void updateFaceData(LLFace *face, F32 pixel_area, BOOL damp_wind = FALSE, bool terse_update = false);
 	/*virtual*/ BOOL updateLOD(F32 pixel_area, BOOL activate);
 	/*virtual*/ void updateJointGeometry();
 	/*virtual*/ void dump();
 
-	void setIsTransparent(BOOL is_transparent) { mIsTransparent = is_transparent; }
-
 	/*virtual*/ BOOL isAnimatable() const { return FALSE; }
 	
 private:
 
 	//copy mesh into given face's vertex buffer, applying current animation pose
 	static void updateGeometry(LLFace* face, LLPolyMesh* mesh);
-
-private:
-	// Allocate skin data
-	BOOL allocateSkinData( U32 numSkinJoints );
-
-	// Free skin data
-	void freeSkinData();
 };
 
 #endif // LL_LLVIEWERJOINTMESH_H
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 1aa9fd8a45d5a52db01e09a736a06aa4cbcdc78b..4ecdc31e21e15c481585977da3ab601aad95cc5d 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -27,11 +27,12 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llappviewer.h"
+#include "llfloaterreg.h"
 #include "llviewerkeyboard.h"
 #include "llmath.h"
 #include "llagent.h"
 #include "llagentcamera.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 #include "llviewercontrol.h"
 #include "llfocusmgr.h"
 #include "llmorphview.h"
@@ -534,7 +535,7 @@ void stop_moving( EKeystate s )
 void start_chat( EKeystate s )
 {
 	// start chat
-	LLNearbyChatBar::startChat(NULL);
+	LLFloaterIMNearbyChat::startChat(NULL);
 }
 
 void start_gesture( EKeystate s )
@@ -543,15 +544,15 @@ void start_gesture( EKeystate s )
 	if (KEYSTATE_UP == s &&
 		! (focus_ctrlp && focus_ctrlp->acceptsTextInput()))
 	{
- 		if (LLNearbyChatBar::getInstance()->getCurrentChat().empty())
+ 		if ((LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat"))->getCurrentChat().empty())
  		{
  			// No existing chat in chat editor, insert '/'
- 			LLNearbyChatBar::startChat("/");
+ 			LLFloaterIMNearbyChat::startChat("/");
  		}
  		else
  		{
  			// Don't overwrite existing text in chat editor
- 			LLNearbyChatBar::startChat(NULL);
+ 			LLFloaterIMNearbyChat::startChat(NULL);
  		}
 	}
 }
diff --git a/indra/newview/llviewermediafocus.cpp b/indra/newview/llviewermediafocus.cpp
index 4543a1ba9a7933465401f2caf23aaff4762c8651..297906803bdd63846ea181c7b09d73b8ca879b13 100644
--- a/indra/newview/llviewermediafocus.cpp
+++ b/indra/newview/llviewermediafocus.cpp
@@ -406,11 +406,9 @@ void LLViewerMediaFocus::update()
 	LLViewerObject *viewer_object = getFocusedObject();
 	S32 face = mFocusedObjectFace;
 	LLVector3 normal = mFocusedObjectNormal;
-	bool focus = true;
 	
 	if(!media_impl || !viewer_object)
 	{
-		focus = false;
 		media_impl = getHoverMediaImpl();
 		viewer_object = getHoverObject();
 		face = mHoverObjectFace;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 93e4f4428a9336673121891ff48ebd0499a1b48c..beca08203fdd5aa3b85f59c84ad50e27dfdc5fa4 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -59,6 +59,7 @@
 #include "llbuycurrencyhtml.h"
 #include "llfloatergodtools.h"
 #include "llfloaterinventory.h"
+#include "llfloaterimcontainer.h"
 #include "llfloaterland.h"
 #include "llfloaterpathfindingcharacters.h"
 #include "llfloaterpathfindinglinksets.h"
@@ -107,6 +108,7 @@
 #include "llviewerparcelmgr.h"
 #include "llviewerstats.h"
 #include "llvoavatarself.h"
+#include "llvoicevivox.h"
 #include "llworldmap.h"
 #include "pipeline.h"
 #include "llviewerjoystick.h"
@@ -123,7 +125,7 @@
 #include "llpathfindingmanager.h"
 #include "boost/unordered_map.hpp"
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 typedef LLPointer<LLViewerObject> LLViewerObjectPtr;
 
@@ -178,9 +180,6 @@ LLContextMenu* gDetachPieMenu = NULL;
 LLContextMenu* gDetachScreenPieMenu = NULL;
 LLContextMenu* gDetachBodyPartPieMenus[8];
 
-LLMenuItemCallGL* gAFKMenu = NULL;
-LLMenuItemCallGL* gBusyMenu = NULL;
-
 //
 // Local prototypes
 
@@ -470,8 +469,6 @@ void init_menus()
 	gMenuHolder->childSetLabelArg("Upload Animation", "[COST]", upload_cost);
 	gMenuHolder->childSetLabelArg("Bulk Upload", "[COST]", upload_cost);
 	
-	gAFKMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Away", TRUE);
-	gBusyMenu = gMenuBarView->getChild<LLMenuItemCallGL>("Set Busy", TRUE);
 	gAttachSubMenu = gMenuBarView->findChildMenuByName("Attach Object", TRUE);
 	gDetachSubMenu = gMenuBarView->findChildMenuByName("Detach Object", TRUE);
 
@@ -1580,11 +1577,26 @@ class LLAdvancedEnableGrabBakedTexture : public view_listener_t
 ///////////////////////
 
 
+class LLAdvancedEnableAppearanceToXML : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+	}
+};
+
 class LLAdvancedAppearanceToXML : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLVOAvatar::dumpArchetypeXML(NULL);
+		std::string emptyname;
+		LLVOAvatar* avatar =
+			find_avatar_from_object( LLSelectMgr::getInstance()->getSelection()->getPrimaryObject() );
+		if (!avatar)
+		{
+			avatar = gAgentAvatarp;
+		}
+		avatar->dumpArchetypeXML(emptyname);
 		return true;
 	}
 };
@@ -2830,7 +2842,7 @@ class LLSelfRemoveAllAttachments : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		LLAgentWearables::userRemoveAllAttachments();
+		LLAppearanceMgr::instance().removeAllAttachmentsFromAvatar();
 		return true;
 	}
 };
@@ -3295,15 +3307,6 @@ bool enable_freeze_eject(const LLSD& avatar_id)
 	return new_value;
 }
 
-
-void login_done(S32 which, void *user)
-{
-	llinfos << "Login done " << which << llendl;
-
-	LLPanelLogin::closePanel();
-}
-
-
 bool callback_leave_group(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
@@ -3521,7 +3524,8 @@ class LLTogglePanelPeopleTab : public view_listener_t
 
 		if (   panel_name == "friends_panel"
 			|| panel_name == "groups_panel"
-			|| panel_name == "nearby_panel")
+			|| panel_name == "nearby_panel"
+			|| panel_name == "blocked_panel")
 		{
 			return togglePeoplePanel(panel_name, param);
 		}
@@ -5568,16 +5572,6 @@ void toggle_debug_menus(void*)
 // 	gExportDialog = LLUploadDialog::modalUploadDialog("Exporting selected objects...");
 // }
 //
-
-class LLCommunicateBlockList : public view_listener_t
-{
-	bool handleEvent(const LLSD& userdata)
-	{
-		LLFloaterSidePanelContainer::showPanel("people", "panel_block_list_sidetray", LLSD());
-		return true;
-	}
-};
-
 class LLWorldSetHomeLocation : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -5651,18 +5645,18 @@ class LLWorldSetAway : public view_listener_t
 	}
 };
 
-class LLWorldSetBusy : public view_listener_t
+class LLWorldSetDoNotDisturb : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
 	{
-		if (gAgent.getBusy())
+		if (gAgent.isDoNotDisturb())
 		{
-			gAgent.clearBusy();
+			gAgent.setDoNotDisturb(false);
 		}
 		else
 		{
-			gAgent.setBusy();
-			LLNotificationsUtil::add("BusyModeSet");
+			gAgent.setDoNotDisturb(true);
+			LLNotificationsUtil::add("DoNotDisturbModeSet");
 		}
 		return true;
 	}
@@ -5824,7 +5818,7 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	if (option == 0)
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	LLViewerObject* objectp = selection->getPrimaryObject();
@@ -5857,12 +5851,12 @@ bool complete_give_money(const LLSD& notification, const LLSD& response, LLObjec
 
 void handle_give_money_dialog()
 {
-	LLNotification::Params params("BusyModePay");
+	LLNotification::Params params("DoNotDisturbModePay");
 	params.functor.function(boost::bind(complete_give_money, _1, _2, LLSelectMgr::getInstance()->getSelection()));
 
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
-		// warn users of being in busy mode during a transaction
+		// warn users of being in do not disturb mode during a transaction
 		LLNotifications::instance().add(params);
 	}
 	else
@@ -6458,23 +6452,21 @@ class LLAttachmentDetachFromPoint : public view_listener_t
 {
 	bool handleEvent(const LLSD& user_data)
 	{
+		uuid_vec_t ids_to_remove;
 		const LLViewerJointAttachment *attachment = get_if_there(gAgentAvatarp->mAttachmentPoints, user_data.asInteger(), (LLViewerJointAttachment*)NULL);
 		if (attachment->getNumObjects() > 0)
 		{
-			gMessageSystem->newMessage("ObjectDetach");
-			gMessageSystem->nextBlockFast(_PREHASH_AgentData);
-			gMessageSystem->addUUIDFast(_PREHASH_AgentID, gAgent.getID() );
-			gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			
 			for (LLViewerJointAttachment::attachedobjs_vec_t::const_iterator iter = attachment->mAttachedObjects.begin();
 				 iter != attachment->mAttachedObjects.end();
 				 iter++)
 			{
 				LLViewerObject *attached_object = (*iter);
-				gMessageSystem->nextBlockFast(_PREHASH_ObjectData);
-				gMessageSystem->addU32Fast(_PREHASH_ObjectLocalID, attached_object->getLocalID());
+				ids_to_remove.push_back(attached_object->getAttachmentItemID());
 			}
-			gMessageSystem->sendReliable( gAgent.getRegionHost() );
+		}
+		if (!ids_to_remove.empty())
+		{
+			LLAppearanceMgr::instance().removeItemsFromAvatar(ids_to_remove);
 		}
 		return true;
 	}
@@ -6547,17 +6539,8 @@ class LLAttachmentDetach : public view_listener_t
 			return true;
 		}
 
-		// The sendDetach() method works on the list of selected
-		// objects.  Thus we need to clear the list, make sure it only
-		// contains the object the user clicked, send the message,
-		// then clear the list.
-		// We use deselectAll to update the simulator's notion of what's
-		// selected, and removeAll just to change things locally.
-		//RN: I thought it was more useful to detach everything that was selected
-		if (LLSelectMgr::getInstance()->getSelection()->isAttachment())
-		{
-			LLSelectMgr::getInstance()->sendDetach();
-		}
+		LLAppearanceMgr::instance().removeItemFromAvatar(object->getAttachmentItemID());
+
 		return true;
 	}
 };
@@ -7412,7 +7395,7 @@ void handle_grab_baked_texture(void* data)
 	if(folder_id.notNull())
 	{
 		std::string name;
-		name = "Baked " + LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
+		name = "Baked " + LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_tex_index)->mNameCapitalized + " Texture";
 
 		LLUUID item_id;
 		item_id.generate();
@@ -7634,6 +7617,20 @@ void handle_web_content_test(const LLSD& param)
 	LLWeb::loadURLInternal(url);
 }
 
+void handle_show_url(const LLSD& param)
+{
+	std::string url = param.asString();
+	if(gSavedSettings.getBOOL("UseExternalBrowser"))
+	{
+		LLWeb::loadURLExternal(url);
+	}
+	else
+	{
+		LLWeb::loadURLInternal(url);
+	}
+
+}
+
 void handle_buy_currency_test(void*)
 {
 	std::string url =
@@ -7657,6 +7654,10 @@ void handle_rebake_textures(void*)
 	// Slam pending upload count to "unstick" things
 	bool slam_for_debug = true;
 	gAgentAvatarp->forceBakeAllTextures(slam_for_debug);
+	if (gAgent.getRegion() && gAgent.getRegion()->getCentralBakeVersion())
+	{
+		LLAppearanceMgr::instance().requestServerAppearanceUpdate();
+	}
 }
 
 void toggle_visibility(void* user_data)
@@ -7887,6 +7888,22 @@ class LLViewCheckRenderType : public view_listener_t
 	}
 };
 
+class LLViewStatusAway : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return (gAgent.isInitialized() && gAgent.getAFK());
+	}
+};
+
+class LLViewStatusDoNotDisturb : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		return (gAgent.isInitialized() && gAgent.isDoNotDisturb());
+	}
+};
+
 class LLViewShowHUDAttachments : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -7923,7 +7940,7 @@ class LLEditTakeOff : public view_listener_t
 	{
 		std::string clothing = userdata.asString();
 		if (clothing == "all")
-			LLWearableBridge::removeAllClothesFromAvatar();
+			LLAppearanceMgr::instance().removeAllClothesFromAvatar();
 		else
 		{
 			LLWearableType::EType type = LLWearableType::typeNameToType(clothing);
@@ -7933,8 +7950,8 @@ class LLEditTakeOff : public view_listener_t
 			{
 				// MULTI-WEARABLES: assuming user wanted to remove top shirt.
 				U32 wearable_index = gAgentWearables.getWearableCount(type) - 1;
-				LLViewerInventoryItem *item = dynamic_cast<LLViewerInventoryItem*>(gAgentWearables.getWearableInventoryItem(type,wearable_index));
-				LLWearableBridge::removeItemFromAvatar(item);
+				LLUUID item_id = gAgentWearables.getWearableItemID(type,wearable_index);
+				LLAppearanceMgr::instance().removeItemFromAvatar(item_id);
 			}
 				
 		}
@@ -8113,11 +8130,7 @@ class LLWorldPostProcess : public view_listener_t
 
 void handle_flush_name_caches()
 {
-	// Toggle display names on and off to flush
-	bool use_display_names = LLAvatarNameCache::useDisplayNames();
-	LLAvatarNameCache::setUseDisplayNames(!use_display_names);
-	LLAvatarNameCache::setUseDisplayNames(use_display_names);
-
+	LLAvatarNameCache::cleanupClass();
 	if (gCacheName) gCacheName->clear();
 }
 
@@ -8142,6 +8155,11 @@ class LLUploadCostCalculator : public view_listener_t
 	}
 };
 
+void handle_voice_morphing_subscribe()
+{
+	LLWeb::loadURLExternal(LLTrans::getString("voice_morphing_url"));
+}
+
 class LLToggleUIHints : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8273,8 +8291,7 @@ void initialize_menus()
 
 	view_listener_t::addEnable(new LLUploadCostCalculator(), "Upload.CalculateCosts");
 
-
-	commit.add("Inventory.NewWindow", boost::bind(&LLFloaterInventory::showAgentInventory));
+	enable.add("Conversation.IsConversationLoggingAllowed", boost::bind(&LLFloaterIMContainer::isConversationLoggingAllowed));
 
 	// Agent
 	commit.add("Agent.toggleFlying", boost::bind(&LLAgent::toggleFlying));
@@ -8320,14 +8337,21 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLViewCheckShowHoverTips(), "View.CheckShowHoverTips");
 	view_listener_t::addMenu(new LLViewCheckHighlightTransparent(), "View.CheckHighlightTransparent");
 	view_listener_t::addMenu(new LLViewCheckRenderType(), "View.CheckRenderType");
+	view_listener_t::addMenu(new LLViewStatusAway(), "View.Status.CheckAway");
+	view_listener_t::addMenu(new LLViewStatusDoNotDisturb(), "View.Status.CheckDoNotDisturb");
 	view_listener_t::addMenu(new LLViewCheckHUDAttachments(), "View.CheckHUDAttachments");
-
+	
 	// Me > Movement
 	view_listener_t::addMenu(new LLAdvancedAgentFlyingInfo(), "Agent.getFlying");
-	
-	// Communicate
-	view_listener_t::addMenu(new LLCommunicateBlockList(), "Communicate.BlockList");
-	
+
+	// Communicate > Voice morphing > Subscribe...
+	commit.add("Communicate.VoiceMorphing.Subscribe", boost::bind(&handle_voice_morphing_subscribe));
+	LLVivoxVoiceClient * voice_clientp = LLVivoxVoiceClient::getInstance();
+	enable.add("Communicate.VoiceMorphing.NoVoiceMorphing.Check"
+		, boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+	commit.add("Communicate.VoiceMorphing.NoVoiceMorphing.Click"
+		, boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, voice_clientp, "NoVoiceMorphing"));
+
 	// World menu
 	view_listener_t::addMenu(new LLWorldAlwaysRun(), "World.AlwaysRun");
 	view_listener_t::addMenu(new LLWorldCreateLandmark(), "World.CreateLandmark");
@@ -8335,7 +8359,7 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLWorldSetHomeLocation(), "World.SetHomeLocation");
 	view_listener_t::addMenu(new LLWorldTeleportHome(), "World.TeleportHome");
 	view_listener_t::addMenu(new LLWorldSetAway(), "World.SetAway");
-	view_listener_t::addMenu(new LLWorldSetBusy(), "World.SetBusy");
+	view_listener_t::addMenu(new LLWorldSetDoNotDisturb(), "World.SetDoNotDisturb");
 
 	view_listener_t::addMenu(new LLWorldEnableCreateLandmark(), "World.EnableCreateLandmark");
 	view_listener_t::addMenu(new LLWorldEnableSetHomeLocation(), "World.EnableSetHomeLocation");
@@ -8451,6 +8475,7 @@ void initialize_menus()
 	// Advanced > UI
 	commit.add("Advanced.WebBrowserTest", boost::bind(&handle_web_browser_test,	_2));	// sigh! this one opens the MEDIA browser
 	commit.add("Advanced.WebContentTest", boost::bind(&handle_web_content_test, _2));	// this one opens the Web Content floater
+	commit.add("Advanced.ShowURL", boost::bind(&handle_show_url, _2));
 	view_listener_t::addMenu(new LLAdvancedBuyCurrencyTest(), "Advanced.BuyCurrencyTest");
 	view_listener_t::addMenu(new LLAdvancedDumpSelectMgr(), "Advanced.DumpSelectMgr");
 	view_listener_t::addMenu(new LLAdvancedDumpInventory(), "Advanced.DumpInventory");
@@ -8484,6 +8509,7 @@ void initialize_menus()
 
 	// Advanced > Character > Character Tests
 	view_listener_t::addMenu(new LLAdvancedAppearanceToXML(), "Advanced.AppearanceToXML");
+	view_listener_t::addMenu(new LLAdvancedEnableAppearanceToXML(), "Advanced.EnableAppearanceToXML");
 	view_listener_t::addMenu(new LLAdvancedToggleCharacterGeometry(), "Advanced.ToggleCharacterGeometry");
 
 	view_listener_t::addMenu(new LLAdvancedTestMale(), "Advanced.TestMale");
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 2eb458fa0237e1ea9233db1adf5f75971731b7db..143420e2274971e814ee97484d0293651ef1be8e 100644
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLVIEWERMENU_H
 #define LL_LLVIEWERMENU_H
 
-#include "llmenugl.h"
+#include "../llui/llmenugl.h"
 #include "llsafehandle.h"
 
 class LLMessageSystem;
@@ -138,6 +138,11 @@ bool handle_go_to();
 // Export to XML or Collada
 void handle_export_selected( void * );
 
+// Convert strings to internal types
+U32 render_type_from_string(std::string render_type);
+U32 feature_from_string(std::string feature);
+U32 info_display_from_string(std::string info_display);
+
 class LLViewerMenuHolderGL : public LLMenuHolderGL
 {
 public:
@@ -184,8 +189,6 @@ extern LLContextMenu* gDetachPieMenu;
 extern LLContextMenu* gAttachBodyPartPieMenus[8];
 extern LLContextMenu* gDetachBodyPartPieMenus[8];
 
-extern LLMenuItemCallGL* gAFKMenu;
-extern LLMenuItemCallGL* gBusyMenu;
 extern LLMenuItemCallGL* gMutePieMenu;
 extern LLMenuItemCallGL* gMuteObjectPieMenu;
 extern LLMenuItemCallGL* gBuyPassPieMenu;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index a897eec55198d87fe75f62e5aad999b1fac41733..3c0d6189ac170d30f46646a23ad3565a8023a0d7 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -65,10 +65,11 @@
 #include "llfloatersnapshot.h"
 #include "llhudeffecttrail.h"
 #include "llhudmanager.h"
+#include "llimview.h"
 #include "llinventoryfunctions.h"
 #include "llinventoryobserver.h"
 #include "llinventorypanel.h"
-#include "llnearbychat.h"
+#include "llfloaterimnearbychat.h"
 #include "llnotifications.h"
 #include "llnotificationsutil.h"
 #include "llpanelgrouplandmoney.h"
@@ -120,6 +121,8 @@
 #pragma warning (disable:4702)
 #endif
 
+extern void on_new_message(const LLSD& msg);
+
 //
 // Constants
 //
@@ -184,78 +187,82 @@ bool friendship_offer_callback(const LLSD& notification, const LLSD& response)
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
 	LLMessageSystem* msg = gMessageSystem;
 	const LLSD& payload = notification["payload"];
-
-	// add friend to recent people list
-	LLRecentPeople::instance().add(payload["from_id"]);
-
-	switch(option)
-	{
-	case 0:
-	{
-		// accept
-		LLAvatarTracker::formFriendship(payload["from_id"]);
-
-		const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
-
-		// This will also trigger an onlinenotification if the user is online
-		msg->newMessageFast(_PREHASH_AcceptFriendship);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->nextBlockFast(_PREHASH_TransactionBlock);
-		msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-		msg->nextBlockFast(_PREHASH_FolderData);
-		msg->addUUIDFast(_PREHASH_FolderID, fid);
-		msg->sendReliable(LLHost(payload["sender"].asString()));
-
-		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
-		LLNotificationsUtil::add("FriendshipAcceptedByMe",
-				notification["substitutions"], payload);
-		break;
-	}
-	case 1: // Decline
-	{
-		LLSD payload = notification["payload"];
-		payload["SUPPRESS_TOAST"] = true;
-		LLNotificationsUtil::add("FriendshipDeclinedByMe",
-				notification["substitutions"], payload);
-	}
-	// fall-through
-	case 2: // Send IM - decline and start IM session
-		{
-			// decline
-			// We no longer notify other viewers, but we DO still send
-			// the rejection to the simulator to delete the pending userop.
-			msg->newMessageFast(_PREHASH_DeclineFriendship);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->nextBlockFast(_PREHASH_TransactionBlock);
-			msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
-			msg->sendReliable(LLHost(payload["sender"].asString()));
-
-			// start IM session
-			if(2 == option)
-			{
-				LLAvatarActions::startIM(payload["from_id"].asUUID());
-			}
-	}
-	default:
-		// close button probably, possibly timed out
-		break;
-	}
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+    // this will be skipped if the user offering friendship is blocked
+    if (notification_ptr)
+    {
+	    // add friend to recent people list
+	    LLRecentPeople::instance().add(payload["from_id"]);
+
+	    switch(option)
+	    {
+	    case 0:
+	    {
+		    // accept
+		    LLAvatarTracker::formFriendship(payload["from_id"]);
+
+		    const LLUUID fid = gInventory.findCategoryUUIDForType(LLFolderType::FT_CALLINGCARD);
+
+		    // This will also trigger an onlinenotification if the user is online
+		    msg->newMessageFast(_PREHASH_AcceptFriendship);
+		    msg->nextBlockFast(_PREHASH_AgentData);
+		    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+		    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+		    msg->nextBlockFast(_PREHASH_TransactionBlock);
+		    msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+		    msg->nextBlockFast(_PREHASH_FolderData);
+		    msg->addUUIDFast(_PREHASH_FolderID, fid);
+		    msg->sendReliable(LLHost(payload["sender"].asString()));
+
+		    LLSD payload = notification["payload"];
+		    LLNotificationsUtil::add("FriendshipAcceptedByMe",
+				    notification["substitutions"], payload);
+		    break;
+	    }
+	    case 1: // Decline
+	    {
+		    LLSD payload = notification["payload"];
+		    LLNotificationsUtil::add("FriendshipDeclinedByMe",
+				    notification["substitutions"], payload);
+	    }
+	    // fall-through
+	    case 2: // Send IM - decline and start IM session
+		    {
+			    // decline
+			    // We no longer notify other viewers, but we DO still send
+			    // the rejection to the simulator to delete the pending userop.
+			    msg->newMessageFast(_PREHASH_DeclineFriendship);
+			    msg->nextBlockFast(_PREHASH_AgentData);
+			    msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+			    msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+			    msg->nextBlockFast(_PREHASH_TransactionBlock);
+			    msg->addUUIDFast(_PREHASH_TransactionID, payload["session_id"]);
+			    msg->sendReliable(LLHost(payload["sender"].asString()));
+
+			    // start IM session
+			    if(2 == option)
+			    {
+				    LLAvatarActions::startIM(payload["from_id"].asUUID());
+			    }
+	    }
+	    default:
+		    // close button probably, possibly timed out
+		    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();
+    }
 
 	return false;
 }
 static LLNotificationFunctorRegistration friendship_offer_callback_reg("OfferFriendship", friendship_offer_callback);
 static LLNotificationFunctorRegistration friendship_offer_callback_reg_nm("OfferFriendshipNoMessage", friendship_offer_callback);
 
-//const char BUSY_AUTO_RESPONSE[] =	"The Resident you messaged is in 'busy mode' which means they have "
-//									"requested not to be disturbed. Your message will still be shown in their IM "
-//									"panel for later viewing.";
-
-//
 // Functions
 //
 
@@ -626,7 +633,6 @@ void send_sound_trigger(const LLUUID& sound_id, F32 gain)
 bool join_group_response(const LLSD& notification, const LLSD& response)
 {
 	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
-	BOOL delete_context_data = TRUE;
 	bool accept_invite = false;
 
 	LLUUID group_id = notification["payload"]["group_id"].asUUID();
@@ -655,7 +661,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
 		}
 		else
 		{
-			delete_context_data = FALSE;
 			LLSD args;
 			args["NAME"] = name;
 			LLNotificationsUtil::add("JoinedTooManyGroupsMember", args, notification["payload"]);
@@ -668,7 +673,6 @@ bool join_group_response(const LLSD& notification, const LLSD& response)
 		// sure the user is sure they want to join.
 		if (fee > 0)
 		{
-			delete_context_data = FALSE;
 			LLSD args;
 			args["COST"] = llformat("%d", fee);
 			// Set the fee for next time to 0, so that we don't keep
@@ -726,7 +730,7 @@ static void highlight_inventory_objects_in_panel(const std::vector<LLUUID>& item
 		LLFolderView* fv = inventory_panel->getRootFolder();
 		if (fv)
 		{
-			LLFolderViewItem* fv_item = fv->getItemByID(item_id);
+			LLFolderViewItem* fv_item = inventory_panel->getItemByID(item_id);
 			if (fv_item)
 			{
 				LLFolderViewItem* fv_folder = fv_item->getParentFolder();
@@ -814,7 +818,13 @@ class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetO
 		mSelectedItems.clear();
 		if (LLInventoryPanel::getActiveInventoryPanel())
 		{
-			mSelectedItems = LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+			std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+			for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end();
+				it != end_it;
+				++it)
+			{
+				mSelectedItems.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+			}
 		}
 		mSelectedItems.erase(mMoveIntoFolderID);
 	}
@@ -849,7 +859,15 @@ class LLViewerInventoryMoveFromWorldObserver : public LLInventoryAddItemByAssetO
 		}
 
 		// get selected items (without destination folder)
-		selected_items_t selected_items = active_panel->getRootFolder()->getSelectionList();
+		selected_items_t selected_items;
+ 		
+ 		std::set<LLFolderViewItem*> selection =    LLInventoryPanel::getActiveInventoryPanel()->getRootFolder()->getSelectionList();
+		for (std::set<LLFolderViewItem*>::iterator it = selection.begin(),    end_it = selection.end();
+			it != end_it;
+			++it)
+		{
+			selected_items.insert(static_cast<LLFolderViewModelItemInventory*>((*it)->getViewModelItem())->getUUID());
+		}
 		selected_items.erase(mMoveIntoFolderID);
 
 		// compare stored & current sets of selected items
@@ -1155,7 +1173,7 @@ bool check_offer_throttle(const std::string& from_name, bool check_only)
 		}
 	}
 }
-
+ 
 // Return "true" if we have a preview method for that asset type, "false" otherwise
 bool check_asset_previewable(const LLAssetType::EType asset_type)
 {
@@ -1344,6 +1362,8 @@ void inventory_offer_mute_callback(const LLUUID& blocked_id,
 			gSavedSettings.getString("NotificationChannelUUID")), OfferMatcher(blocked_id));
 }
 
+std::string LLOfferInfo::mResponderType = "offer_info";
+
 LLOfferInfo::LLOfferInfo()
  : LLNotificationResponderInterface()
  , mFromGroup(FALSE)
@@ -1389,6 +1409,7 @@ LLOfferInfo::LLOfferInfo(const LLOfferInfo& info)
 LLSD LLOfferInfo::asLLSD()
 {
 	LLSD sd;
+    sd["responder_type"] = mResponderType;
 	sd["im_type"] = mIM;
 	sd["from_id"] = mFromID;
 	sd["from_group"] = mFromGroup;
@@ -1478,16 +1499,15 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 		itemp = (LLViewerInventoryItem*)gInventory.getItem(mObjectID);
 	}
 	 
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+	
 	// For muting, we need to add the mute, then decline the offer.
 	// This must be done here because:
 	// * callback may be called immediately,
 	// * adding the mute sends a message,
 	// * we can't build two messages at once.
-	if (2 == button) // Block
+	if (IOR_MUTE == button) // Block
 	{
-		LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
-
-		llassert(notification_ptr != NULL);
 		if (notification_ptr != NULL)
 		{
 			gCacheName->get(mFromID, mFromGroup, boost::bind(&inventory_offer_mute_callback, _1, _2, _3));
@@ -1500,8 +1520,8 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	// TODO: when task inventory offers can also be handled the new way, migrate the code that sets these strings here:
 	from_string = chatHistory_string = mFromName;
 	
-	bool busy = gAgent.getBusy();
-	
+	LLNotificationFormPtr modified_form(notification_ptr ? new LLNotificationForm(*notification_ptr->getForm()) : new LLNotificationForm());
+
 	switch(button)
 	{
 	case IOR_SHOW:
@@ -1545,6 +1565,11 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			LL_WARNS("Messaging") << "inventory_offer_callback: unknown offer type" << LL_ENDL;
 			break;
 		}
+
+		if (modified_form != NULL)
+		{
+			modified_form->setElementEnabled("Show", false);
+		}
 		break;
 		// end switch (mIM)
 			
@@ -1557,9 +1582,14 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			args["MESSAGE"] = log_message;
 			LLNotificationsUtil::add("SystemMessageTip", args);
 		}
+
 		break;
 
 	case IOR_MUTE:
+		if (modified_form != NULL)
+		{
+			modified_form->setElementEnabled("Mute", false);
+		}
 		// MUTE falls through to decline
 	case IOR_DECLINE:
 		{
@@ -1589,12 +1619,13 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 			{
 				opener = discard_agent_offer;
 			}
-			
-			
-			if (busy &&	(!mFromGroup && !mFromObject))
+
+			if (modified_form != NULL)
 			{
-				busy_message(gMessageSystem, mFromID);
+				modified_form->setElementEnabled("Show", false);
+				modified_form->setElementEnabled("Discard", false);
 			}
+
 			break;
 		}
 	default:
@@ -1614,6 +1645,7 @@ bool LLOfferInfo::inventory_offer_callback(const LLSD& notification, const LLSD&
 	{
 		delete this;
 	}
+
 	return false;
 }
 
@@ -1704,7 +1736,7 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 		from_string = chatHistory_string = mFromName;
 	}
 	
-	bool busy = gAgent.getBusy();
+	bool is_do_not_disturb = gAgent.isDoNotDisturb();
 	
 	switch(button)
 	{
@@ -1777,9 +1809,9 @@ bool LLOfferInfo::inventory_task_offer_callback(const LLSD& notification, const
 				LLNotificationsUtil::add("SystemMessageTip", args);
 			}
 			
-			if (busy &&	(!mFromGroup && !mFromObject))
+			if (is_do_not_disturb &&	(!mFromGroup && !mFromObject))
 			{
-				busy_message(msg,mFromID);
+				send_do_not_disturb_message(msg,mFromID);
 			}
 			break;
 	}
@@ -1931,6 +1963,7 @@ void inventory_offer_handler(LLOfferInfo* info)
 		p.substitutions(args).payload(payload).functor.responder(LLNotificationResponderPtr(info));
 		info->mPersist = true;
 		p.name = "UserGiveItem";
+		p.offer_from_agent = true;
 		
 		// Prefetch the item into your local inventory.
 		LLInventoryFetchItemsObserver* fetch_item = new LLInventoryFetchItemsObserver(info->mObjectID);
@@ -1947,6 +1980,11 @@ void inventory_offer_handler(LLOfferInfo* info)
 		// In viewer 2 we're now auto receiving inventory offers and messaging as such (not sending reject messages).
 		info->send_auto_receive_response();
 
+        if (gAgent.isDoNotDisturb()) 
+        {
+            send_do_not_disturb_message(gMessageSystem, info->mFromID);
+        }
+
 		// Inform user that there is a script floater via toast system
 		{
 			payload["give_inventory_notification"] = TRUE;
@@ -1991,6 +2029,18 @@ bool lure_callback(const LLSD& notification, const LLSD& response)
 					   lure_id);
 		break;
 	}
+
+	LLNotificationPtr notification_ptr = LLNotifications::instance().find(notification["id"].asUUID());
+
+	if (notification_ptr)
+	{
+		LLNotificationFormPtr modified_form(new LLNotificationForm(*notification_ptr->getForm()));
+		modified_form->setElementEnabled("Teleport", false);
+		modified_form->setElementEnabled("Cancel", false);
+		notification_ptr->updateForm(modified_form);
+		notification_ptr->repost();
+	}
+
 	return false;
 }
 static LLNotificationFunctorRegistration lure_callback_reg("TeleportOffered", lure_callback);
@@ -2152,7 +2202,7 @@ static std::string clean_name_from_im(const std::string& name, EInstantMessage t
 	case IM_SESSION_SEND:
 	case IM_SESSION_LEAVE:
 	//IM_FROM_TASK
-	case IM_BUSY_AUTO_RESPONSE:
+	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
 	case IM_CONSOLE_AND_CHAT_HISTORY:
 	case IM_LURE_USER:
 	case IM_LURE_ACCEPTED:
@@ -2193,16 +2243,7 @@ static std::string clean_name_from_task_im(const std::string& msg,
 		// Don't try to clean up group names
 		if (!from_group)
 		{
-			if (LLAvatarNameCache::useDisplayNames())
-			{
-				// ...just convert to username
-				final += LLCacheName::buildUsername(name);
-			}
-			else
-			{
-				// ...strip out legacy "Resident" name
-				final += LLCacheName::cleanFullName(name);
-			}
+			final += LLCacheName::buildUsername(name);
 		}
 		final += match[3].str();
 		return final;
@@ -2210,13 +2251,13 @@ static std::string clean_name_from_task_im(const std::string& msg,
 	return msg;
 }
 
-void notification_display_name_callback(const LLUUID& id,
+static void notification_display_name_callback(const LLUUID& id,
 					  const LLAvatarName& av_name,
 					  const std::string& name, 
 					  LLSD& substitutions, 
 					  const LLSD& payload)
 {
-	substitutions["NAME"] = av_name.mDisplayName;
+	substitutions["NAME"] = av_name.getDisplayName();
 	LLNotificationsUtil::add(name, substitutions, payload);
 }
 
@@ -2234,7 +2275,7 @@ class LLPostponedIMSystemTipNotification: public LLPostponedNotification
 };
 
 // Callback for name resolution of a god/estate message
-void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
+static void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string message)
 {	
 	LLSD args;
 	args["NAME"] = av_name.getCompleteName();
@@ -2244,12 +2285,11 @@ void god_message_name_cb(const LLAvatarName& av_name, LLChat chat, std::string m
 	// Treat like a system message and put in chat history.
 	chat.mText = av_name.getCompleteName() + ": " + message;
 
-	LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
-	if(nearby_chat)
+	LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+	if (nearby_chat)
 	{
 		nearby_chat->addMessage(chat);
 	}
-
 }
 
 void process_improved_im(LLMessageSystem *msg, void **user_data)
@@ -2302,16 +2342,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	// IDEVO convert new-style "Resident" names for display
 	name = clean_name_from_im(name, dialog);
 
-	BOOL is_busy = gAgent.getBusy();
+	BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 	BOOL is_muted = LLMuteList::getInstance()->isMuted(from_id, name, LLMute::flagTextChat)
 		// object IMs contain sender object id in session_id (STORM-1209)
 		|| dialog == IM_FROM_TASK && LLMuteList::getInstance()->isMuted(session_id);
-	BOOL is_linden = LLMuteList::getInstance()->isLinden(name);
 	BOOL is_owned_by_me = FALSE;
 	BOOL is_friend = (LLAvatarTracker::instance().getBuddyInfo(from_id) == NULL) ? false : true;
 	BOOL accept_im_from_only_friend = gSavedSettings.getBOOL("VoiceCallsFriendsOnly");
 	
-	chat.mMuted = is_muted && !is_linden;
+	chat.mMuted = is_muted;
 	chat.mFromID = from_id;
 	chat.mFromName = name;
 	chat.mSourceType = (from_id.isNull() || (name == std::string(SYSTEM_FROM))) ? CHAT_SOURCE_SYSTEM : CHAT_SOURCE_AGENT;
@@ -2329,7 +2368,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	LLNotification::Params params;
 
 	switch(dialog)
-	{
+	{ 
 	case IM_CONSOLE_AND_CHAT_HISTORY:
 		args["MESSAGE"] = message;
 		payload["from_id"] = from_id;
@@ -2340,7 +2379,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	    LLPostponedNotification::add<LLPostponedIMSystemTipNotification>(params, from_id, false);
 		break;
 
-	case IM_NOTHING_SPECIAL: 
+	case IM_NOTHING_SPECIAL:	// p2p IM
 		// Don't show dialog, just do IM
 		if (!gAgent.isGodlike()
 				&& gAgent.getRegion()->isPrelude() 
@@ -2349,29 +2388,18 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			// do nothing -- don't distract newbies in
 			// Prelude with global IMs
 		}
-		else if (offline == IM_ONLINE && !is_linden && is_busy && name != SYSTEM_FROM)
+		else if (offline == IM_ONLINE 
+					&& is_do_not_disturb
+					&& from_id.notNull() //not a system message
+					&& to_id.notNull()) //not global message
 		{
-			// return a standard "busy" message, but only do it to online IM 
+			// return a standard "do not disturb" message, but only do it to online IM 
 			// (i.e. not other auto responses and not store-and-forward IM)
 			if (!gIMMgr->hasSession(session_id))
 			{
 				// if there is not a panel for this conversation (i.e. it is a new IM conversation
 				// initiated by the other party) then...
-				std::string my_name;
-				LLAgentUI::buildFullname(my_name);
-				std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
-				pack_instant_message(
-					gMessageSystem,
-					gAgent.getID(),
-					FALSE,
-					gAgent.getSessionID(),
-					from_id,
-					my_name,
-					response,
-					IM_ONLINE,
-					IM_BUSY_AUTO_RESPONSE,
-					session_id);
-				gAgent.sendReliableMessage();
+				send_do_not_disturb_message(msg, from_id, session_id);
 			}
 
 			// now store incoming IM in chat history
@@ -2386,6 +2414,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				from_id,
 				name,
 				buffer,
+				IM_OFFLINE == offline,
 				LLStringUtil::null,
 				dialog,
 				parent_estate_id,
@@ -2420,24 +2449,25 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
 
 			bool mute_im = is_muted;
-			if (accept_im_from_only_friend && !is_friend)
+			if(accept_im_from_only_friend&&!is_friend)
 			{
 				if (!gIMMgr->isNonFriendSessionNotified(session_id))
 				{
 					std::string message = LLTrans::getString("IM_unblock_only_groups_friends");
-					gIMMgr->addMessage(session_id, from_id, name, message);
+					gIMMgr->addMessage(session_id, from_id, name, message, IM_OFFLINE == offline);
 					gIMMgr->addNotifiedNonFriendSessionID(session_id);
 				}
 
 				mute_im = true;
 			}
-			if (!mute_im || is_linden) 
+			if (!mute_im) 
 			{
 				gIMMgr->addMessage(
 					session_id,
 					from_id,
 					name,
 					buffer,
+					IM_OFFLINE == offline,
 					LLStringUtil::null,
 					dialog,
 					parent_estate_id,
@@ -2582,7 +2612,10 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				payload["sender_name"] = name;
 				payload["group_id"] = group_id;
 				payload["inventory_name"] = item_name;
-				payload["inventory_offer"] = info ? info->asLLSD() : LLSD();
+				if(info && info->asLLSD())
+				{
+					payload["inventory_offer"] = info->asLLSD();
+				}
 
 				LLSD args;
 				args["SUBJECT"] = subj;
@@ -2604,11 +2637,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 		break;
 	case IM_GROUP_INVITATION:
 		{
-			//if (!is_linden && (is_busy || is_muted))
-			if ((is_busy || is_muted))
+			if (is_do_not_disturb || is_muted)
 			{
-				LLMessageSystem *msg = gMessageSystem;
-				busy_message(msg,from_id);
+				send_do_not_disturb_message(msg, from_id);
 			}
 			else
 			{
@@ -2691,7 +2722,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			info->mFromName = name;
 			info->mDesc = message;
 			info->mHost = msg->getSender();
-			//if (((is_busy && !is_owned_by_me) || is_muted))
+			//if (((is_do_not_disturb && !is_owned_by_me) || is_muted))
 			if (is_muted)
 			{
 				// Prefetch the offered item so that it can be discarded by the appropriate observer. (EXT-4331)
@@ -2702,9 +2733,11 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				// Same as closing window
 				info->forceResponse(IOR_DECLINE);
 			}
-			else if (is_busy && dialog != IM_TASK_INVENTORY_OFFERED) // busy mode must not affect interaction with objects (STORM-565)
+			// old logic: busy mode must not affect interaction with objects (STORM-565)
+			// new logic: inventory offers from in-world objects should be auto-declined (CHUI-519)
+			else if (is_do_not_disturb && dialog == IM_TASK_INVENTORY_OFFERED)
 			{
-				// Until throttling is implemented, busy mode should reject inventory instead of silently
+				// Until throttling is implemented, do not disturb mode should reject inventory instead of silently
 				// accepting it.  SEE SL-39554
 				info->forceResponse(IOR_DECLINE);
 			}
@@ -2747,49 +2780,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 	break;
 	
-	case IM_SESSION_SEND:
-	{
-		if (is_busy)
-		{
-			return;
-		}
-
-		// Only show messages if we have a session open (which
-		// should happen after you get an "invitation"
-		if ( !gIMMgr->hasSession(session_id) )
-		{
-			return;
-		}
-
-		// standard message, not from system
-		std::string saved;
-		if(offline == IM_OFFLINE)
-		{
-			saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
-		}
-		buffer = saved + message;
-		BOOL is_this_agent = FALSE;
-		if(from_id == gAgentID)
-		{
-			is_this_agent = TRUE;
-		}
-		gIMMgr->addMessage(
-			session_id,
-			from_id,
-			name,
-			buffer,
-			ll_safe_string((char*)binary_bucket),
-			IM_SESSION_INVITE,
-			parent_estate_id,
-			region_id,
-			position,
-			true);
-	}
-	break;
-
 	case IM_FROM_TASK:
 		{
-			if (is_busy && !is_owned_by_me)
+			if (is_do_not_disturb && !is_owned_by_me)
 			{
 				return;
 			}
@@ -2841,13 +2834,12 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 
 			// Note: lie to Nearby Chat, pretending that this is NOT an IM, because
 			// IMs from obejcts don't open IM sessions.
-			LLNearbyChat* nearby_chat = LLNearbyChat::getInstance();
+			LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::getTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
 			if(!chat_from_system && nearby_chat)
 			{
 				chat.mOwnerID = from_id;
 				LLSD args;
 				args["slurl"] = location;
-				args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
 
 				// Look for IRC-style emotes here so object name formatting is correct
 				std::string prefix = message.substr(0, 4);
@@ -2886,8 +2878,78 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			LLPostponedNotification::add<LLPostponedServerObjectNotification>(params, from_id, from_group);
 		}
 		break;
+
+	case IM_SESSION_SEND:		// ad-hoc or group IMs
+
+		// Only show messages if we have a session open (which
+		// should happen after you get an "invitation"
+		if ( !gIMMgr->hasSession(session_id) )
+		{
+			return;
+		}
+
+		else if (offline == IM_ONLINE && is_do_not_disturb)
+		{
+
+			// return a standard "do not disturb" message, but only do it to online IM 
+			// (i.e. not other auto responses and not store-and-forward IM)
+			if (!gIMMgr->hasSession(session_id))
+			{
+				// if there is not a panel for this conversation (i.e. it is a new IM conversation
+				// initiated by the other party) then...
+				send_do_not_disturb_message(msg, from_id, session_id);
+			}
+
+			// now store incoming IM in chat history
+
+			buffer = message;
+	
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			// add to IM panel, but do not bother the user
+			gIMMgr->addMessage(
+				session_id,
+				from_id,
+				name,
+				buffer,
+				IM_OFFLINE == offline,
+				ll_safe_string((char*)binary_bucket),
+				IM_SESSION_INVITE,
+				parent_estate_id,
+				region_id,
+				position,
+				true);
+		}
+		else
+		{
+			// standard message, not from system
+			std::string saved;
+			if(offline == IM_OFFLINE)
+			{
+				saved = llformat("(Saved %s) ", formatted_time(timestamp).c_str());
+			}
+
+			buffer = saved + message;
+
+			LL_INFOS("Messaging") << "process_improved_im: session_id( " << session_id << " ), from_id( " << from_id << " )" << LL_ENDL;
+
+			gIMMgr->addMessage(
+				session_id,
+				from_id,
+				name,
+				buffer,
+				IM_OFFLINE == offline,
+				ll_safe_string((char*)binary_bucket),
+				IM_SESSION_INVITE,
+				parent_estate_id,
+				region_id,
+				position,
+				true);
+		}
+		break;
+
 	case IM_FROM_TASK_AS_ALERT:
-		if (is_busy && !is_owned_by_me)
+		if (is_do_not_disturb && !is_owned_by_me)
 		{
 			return;
 		}
@@ -2898,17 +2960,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			LLNotificationsUtil::add("ObjectMessage", args);
 		}
 		break;
-	case IM_BUSY_AUTO_RESPONSE:
+	case IM_DO_NOT_DISTURB_AUTO_RESPONSE:
 		if (is_muted)
 		{
-			LL_DEBUGS("Messaging") << "Ignoring busy response from " << from_id << LL_ENDL;
+			LL_DEBUGS("Messaging") << "Ignoring do-not-disturb response from " << from_id << LL_ENDL;
 			return;
 		}
 		else
 		{
-			// TODO: after LLTrans hits release, get "busy response" into translatable file
-			buffer = llformat("%s (%s): %s", name.c_str(), "busy response", message.c_str());
-			gIMMgr->addMessage(session_id, from_id, name, buffer);
+			gIMMgr->addMessage(session_id, from_id, name, message);
 		}
 		break;
 		
@@ -2918,9 +2978,9 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			{ 
 				return;
 			}
-			else if (is_busy) 
+			else if (is_do_not_disturb) 
 			{
-				busy_message(msg,from_id);
+				send_do_not_disturb_message(msg, from_id);
 			}
 			else
 			{
@@ -3141,17 +3201,16 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			payload["online"] = (offline == IM_ONLINE);
 			payload["sender"] = msg->getSender().getIPandPort();
 
-			if (is_busy)
-			{
-				busy_message(msg, from_id);
-				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
-			}
-			else if (is_muted)
+			if (is_muted)
 			{
 				LLNotifications::instance().forceResponse(LLNotification::Params("OfferFriendship").payload(payload), 1);
 			}
 			else
 			{
+				if (is_do_not_disturb)
+				{
+					send_do_not_disturb_message(msg, from_id);
+				}
 				args["NAME_SLURL"] = LLSLURL("agent", from_id, "about").getSLURLString();
 				if(message.empty())
 				{
@@ -3184,12 +3243,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 			args["NAME"] = name;
 			LLSD payload;
 			payload["from_id"] = from_id;
-			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,
-														 _1,
-														 _2,
-														 "FriendshipAccepted",
-														 args,
-														 payload));
+			LLAvatarNameCache::get(from_id, boost::bind(&notification_display_name_callback,_1,_2,"FriendshipAccepted",args,payload));
 		}
 		break;
 
@@ -3207,15 +3261,15 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	}
 }
 
-void busy_message (LLMessageSystem* msg, LLUUID from_id) 
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id)
 {
-	if (gAgent.getBusy())
+	if (gAgent.isDoNotDisturb())
 	{
 		std::string my_name;
 		LLAgentUI::buildFullname(my_name);
-		std::string response = gSavedPerAccountSettings.getString("BusyModeResponse");
+		std::string response = gSavedPerAccountSettings.getString("DoNotDisturbModeResponse");
 		pack_instant_message(
-			gMessageSystem,
+			msg,
 			gAgent.getID(),
 			FALSE,
 			gAgent.getSessionID(),
@@ -3223,7 +3277,8 @@ void busy_message (LLMessageSystem* msg, LLUUID from_id)
 			my_name,
 			response,
 			IM_ONLINE,
-			IM_BUSY_AUTO_RESPONSE);
+			IM_DO_NOT_DISTURB_AUTO_RESPONSE,
+			session_id);
 		gAgent.sendReliableMessage();
 	}
 }
@@ -3258,7 +3313,7 @@ bool callingcard_offer_callback(const LLSD& notification, const LLSD& response)
 		msg->nextBlockFast(_PREHASH_TransactionBlock);
 		msg->addUUIDFast(_PREHASH_TransactionID, notification["payload"]["transaction_id"].asUUID());
 		msg->sendReliable(LLHost(notification["payload"]["sender"].asString()));
-		busy_message(msg, notification["payload"]["source_id"].asUUID());
+		send_do_not_disturb_message(msg, notification["payload"]["source_id"].asUUID());
 		break;
 	default:
 		// close button probably, possibly timed out
@@ -3300,7 +3355,7 @@ void process_offer_callingcard(LLMessageSystem* msg, void**)
 
 	if(!source_name.empty())
 	{
-		if (gAgent.getBusy() 
+		if (gAgent.isDoNotDisturb() 
 			|| LLMuteList::getInstance()->isMuted(source_id, source_name, LLMute::flagTextChat))
 		{
 			// automatically decline offer
@@ -3386,7 +3441,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 	LLColor4	color(1.0f, 1.0f, 1.0f, 1.0f);
 	LLUUID		from_id;
 	LLUUID		owner_id;
-	BOOL		is_owned_by_me = FALSE;
 	LLViewerObject*	chatter;
 
 	msg->getString("ChatData", "FromName", from_name);
@@ -3417,7 +3471,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		LLAvatarName av_name;
 		if (LLAvatarNameCache::get(from_id, &av_name))
 		{
-			chat.mFromName = av_name.mDisplayName;
+			chat.mFromName = av_name.getDisplayName();
 		}
 		else
 		{
@@ -3429,7 +3483,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		chat.mFromName = from_name;
 	}
 
-	BOOL is_busy = gAgent.getBusy();
+	BOOL is_do_not_disturb = gAgent.isDoNotDisturb();
 
 	BOOL is_muted = FALSE;
 	BOOL is_linden = FALSE;
@@ -3463,7 +3517,7 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 
 		// record last audible utterance
 		if (is_audible
-			&& (is_linden || (!is_muted && !is_busy)))
+			&& (is_linden || (!is_muted && !is_do_not_disturb)))
 		{
 			if (chat.mChatType != CHAT_TYPE_START 
 				&& chat.mChatType != CHAT_TYPE_STOP)
@@ -3471,13 +3525,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 				gAgent.heardChat(chat.mFromID);
 			}
 		}
-
-		is_owned_by_me = chatter->permYouOwner();
 	}
 
 	if (is_audible)
 	{
-		BOOL visible_in_chat_bubble = FALSE;
+		//BOOL visible_in_chat_bubble = FALSE;
 
 		color.setVec(1.f,1.f,1.f,1.f);
 		msg->getStringFast(_PREHASH_ChatData, _PREHASH_Message, mesg);
@@ -3558,9 +3610,9 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 			LLLocalSpeakerMgr::getInstance()->setSpeakerTyping(from_id, FALSE);
 			((LLVOAvatar*)chatter)->stopTyping();
 			
-			if (!is_muted && !is_busy)
+			if (!is_muted && !is_do_not_disturb)
 			{
-				visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
+				//visible_in_chat_bubble = gSavedSettings.getBOOL("UseChatBubbles");
 				std::string formated_msg = "";
 				LLViewerChat::formatChatMsg(chat, formated_msg);
 				LLChat chat_bubble = chat;
@@ -3591,7 +3643,6 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		// pass owner_id to chat so that we can display the remote
 		// object inspect for an object that is chatting with you
 		LLSD args;
-		args["type"] = LLNotificationsUI::NT_NEARBYCHAT;
 		chat.mOwnerID = owner_id;
 
 		if (gSavedSettings.getBOOL("TranslateChat") && chat.mSourceType != CHAT_SOURCE_SYSTEM)
@@ -3610,6 +3661,11 @@ void process_chat_from_simulator(LLMessageSystem *msg, void **user_data)
 		{
 			LLNotificationsUI::LLNotificationManager::instance().onChat(chat, args);
 		}
+
+		LLSD msg_notify = LLSD(LLSD::emptyMap());
+		msg_notify["session_id"] = LLUUID();
+        msg_notify["from_id"] = chat.mFromID;
+        on_new_message(msg_notify);
 	}
 }
 
@@ -4097,14 +4153,14 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 		gAgent.setFlying(gAgent.canFly());
 	}
 
-	// force simulator to recognize busy state
-	if (gAgent.getBusy())
+	// force simulator to recognize do not disturb state
+	if (gAgent.isDoNotDisturb())
 	{
-		gAgent.setBusy();
+		gAgent.setDoNotDisturb(true);
 	}
 	else
 	{
-		gAgent.clearBusy();
+		gAgent.setDoNotDisturb(false);
 	}
 
 	if (isAgentAvatarValid())
@@ -4896,9 +4952,19 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
 	// Various hacks that aren't statistics, but are being handled here.
 	//
 	U32 max_tasks_per_region;
-	U32 region_flags;
+	U64 region_flags;
 	msg->getU32("Region", "ObjectCapacity", max_tasks_per_region);
-	msg->getU32("Region", "RegionFlags", region_flags);
+
+	if (msg->has(_PREHASH_RegionInfo))
+	{
+		msg->getU64("RegionInfo", "RegionFlagsExtended", region_flags);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32("Region", "RegionFlags", flags);
+		region_flags = flags;
+	}
 
 	LLViewerRegion* regionp = gAgent.getRegion();
 	if (regionp)
@@ -5614,11 +5680,9 @@ static void process_money_balance_reply_extended(LLMessageSystem* msg)
 									_1, _2, _3,
 									notification, final_args, payload));
 	}
-	else {
-		LLAvatarNameCache::get(name_id,
-							   boost::bind(&money_balance_avatar_notify,
-										   _1, _2,
-										   notification, final_args, payload));										   
+	else 
+	{
+		LLAvatarNameCache::get(name_id, boost::bind(&money_balance_avatar_notify, _1, _2, notification, final_args, payload));										   
 	}
 }
 
@@ -6794,7 +6858,6 @@ bool handle_lure_callback(const LLSD& notification, const LLSD& response)
 				
 				//*TODO please rewrite all keys to the same case, lower or upper
 				payload["from_id"] = target_id;
-				payload["SUPPRESS_TOAST"] = true;
 				LLNotificationsUtil::add("TeleportOfferSent", args, payload);
 
 				// Add the recepient to the recent people list.
@@ -6915,7 +6978,7 @@ void process_user_info_reply(LLMessageSystem* msg, void**)
 	std::string dir_visibility;
 	msg->getString( "UserData", "DirectoryVisibility", dir_visibility);
 
-	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email, email);
+	LLFloaterPreference::updateUserInfo(dir_visibility, im_via_email);
 	LLFloaterSnapshot::setAgentEmail(email);
 }
 
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index 594c22ed9ca842a5d672e3c7a5c89f752d1c4f4b..3237f3fbdddca44e8b90c301592aa2cfba8eee67 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -67,7 +67,6 @@ enum InventoryOfferResponse
 BOOL can_afford_transaction(S32 cost);
 void give_money(const LLUUID& uuid, LLViewerRegion* region, S32 amount, BOOL is_group = FALSE,
 				S32 trx_type = TRANS_GIFT, const std::string& desc = LLStringUtil::null);
-void busy_message (LLMessageSystem* msg, LLUUID from_id);
 
 void process_logout_reply(LLMessageSystem* msg, void**);
 void process_layer_data(LLMessageSystem *mesgsys, void **user_data);
@@ -153,6 +152,8 @@ void send_group_notice(const LLUUID& group_id,
 					   const std::string& message,
 					   const LLInventoryItem* item);
 
+void send_do_not_disturb_message (LLMessageSystem* msg, const LLUUID& from_id, const LLUUID& session_id = LLUUID::null);
+
 void handle_lure(const LLUUID& invitee);
 void handle_lure(const uuid_vec_t& ids);
 
@@ -228,6 +229,7 @@ class LLOfferInfo : public LLNotificationResponderInterface
 
 	void forceResponse(InventoryOfferResponse response);
 
+    static std::string mResponderType;
 	EInstantMessage mIM;
 	LLUUID mFromID;
 	BOOL mFromGroup;
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index b1a60197a2cbfbc997e2c58edef9953b08e4afd8..fcf5af76ff4c32eb191c8bf1e078f1c18fe852e1 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -3266,14 +3266,14 @@ void LLViewerObject::boostTexturePriority(BOOL boost_children /* = TRUE */)
 	S32 tex_count = getNumTEs();
 	for (i = 0; i < tex_count; i++)
 	{
- 		getTEImage(i)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+ 		getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
 	}
 
 	if (isSculpted() && !isMesh())
 	{
 		LLSculptParams *sculpt_params = (LLSculptParams *)getParameterEntry(LLNetworkData::PARAMS_SCULPT);
 		LLUUID sculpt_id = sculpt_params->getSculptTexture();
-		LLViewerTextureManager::getFetchedTexture(sculpt_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLViewerTexture::BOOST_SELECTED);
+		LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED);
 	}
 	
 	if (boost_children)
@@ -4016,7 +4016,7 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry)
 //	if (mDrawable.notNull() && mDrawable->isVisible())
 //	{
 		const LLUUID& image_id = getTE(te)->getID();
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 //	}
 }
 
@@ -4034,15 +4034,15 @@ void LLViewerObject::setTEImage(const U8 te, LLViewerTexture *imagep)
 	}
 }
 
-
-S32 LLViewerObject::setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host)
+S32 LLViewerObject::setTETextureCore(const U8 te, LLViewerTexture *image)
 {
+	const LLUUID& uuid = image->getID();
 	S32 retval = 0;
 	if (uuid != getTE(te)->getID() ||
 		uuid == LLUUID::null)
 	{
 		retval = LLPrimitive::setTETexture(te, uuid);
-		mTEImages[te] = LLViewerTextureManager::getFetchedTexture(uuid, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+		mTEImages[te] = image;
 		setChanged(TEXTURE);
 		if (mDrawable.notNull())
 		{
@@ -4065,7 +4065,9 @@ void LLViewerObject::changeTEImage(S32 index, LLViewerTexture* new_image)
 S32 LLViewerObject::setTETexture(const U8 te, const LLUUID& uuid)
 {
 	// Invalid host == get from the agent's sim
-	return setTETextureCore(te, uuid, LLHost::invalid);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(
+		uuid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, LLHost::invalid);
+	return setTETextureCore(te,image);
 }
 
 
diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h
index 97cf0a4850c7d236ca546eeeff8a515b670b800d..728d279c39b1282c6e277e5a756ef73680c7b942 100644
--- a/indra/newview/llviewerobject.h
+++ b/indra/newview/llviewerobject.h
@@ -301,7 +301,7 @@ class LLViewerObject : public LLPrimitive, public LLRefCount, public LLGLUpdate
 	/*virtual*/	void	setNumTEs(const U8 num_tes);
 	/*virtual*/	void	setTE(const U8 te, const LLTextureEntry &texture_entry);
 	/*virtual*/ S32		setTETexture(const U8 te, const LLUUID &uuid);
-	S32 setTETextureCore(const U8 te, const LLUUID& uuid, LLHost host);
+	S32 				setTETextureCore(const U8 te, LLViewerTexture *image);
 	/*virtual*/ S32		setTEColor(const U8 te, const LLColor3 &color);
 	/*virtual*/ S32		setTEColor(const U8 te, const LLColor4 &color);
 	/*virtual*/ S32		setTEScale(const U8 te, const F32 s, const F32 t);
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 6b9d6bbc688db257d0853ca8c4d51c8eed1d6cab..11d34ad0841a4b48c32b66c1a7cb6b8d8fad6ccb 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -284,7 +284,6 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 {
 	LLFastTimer t(FTM_PROCESS_OBJECTS);	
 	
-	LLVector3d camera_global = gAgentCamera.getCameraPositionGlobal();
 	LLViewerObject *objectp;
 	S32			num_objects;
 	U32			local_id;
@@ -303,6 +302,7 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 	{
 		//llinfos << "TEST: !cached && !compressed && update_type != OUT_FULL" << llendl;
 		gTerseObjectUpdates += num_objects;
+		/*
 		S32 size;
 		if (mesgsys->getReceiveCompressedSize())
 		{
@@ -312,10 +312,12 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 		{
 			size = mesgsys->getReceiveSize();
 		}
-		//llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		llinfos << "Received terse " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		*/
 	}
 	else
 	{
+		/*
 		S32 size;
 		if (mesgsys->getReceiveCompressedSize())
 		{
@@ -326,7 +328,8 @@ void LLViewerObjectList::processObjectUpdate(LLMessageSystem *mesgsys,
 			size = mesgsys->getReceiveSize();
 		}
 
-		// llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		llinfos << "Received " << num_objects << " in " << size << " byte (" << size/num_objects << ")" << llendl;
+		*/
 		gFullObjectUpdates += num_objects;
 	}
 
@@ -688,12 +691,12 @@ class LLObjectCostResponder : public LLCurl::Responder
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		llwarns
 			<< "Transport error requesting object cost "
-			<< "HTTP status: " << statusNum << ", reason: "
-			<< reason << "." << llendl;
+			<< "[status: " << statusNum << "]: "
+			<< content << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
@@ -777,12 +780,12 @@ class LLPhysicsFlagsResponder : public LLCurl::Responder
 		}
 	}
 
-	void error(U32 statusNum, const std::string& reason)
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
 	{
 		llwarns
 			<< "Transport error requesting object physics flags "
-			<< "HTTP status: " << statusNum << ", reason: "
-			<< reason << "." << llendl;
+			<< "[status: " << statusNum << "]: "
+			<< content << llendl;
 
 		// TODO*: Error message to user
 		// For now just clear the request from the pending list
@@ -953,14 +956,14 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
 			llassert(objectp->isActive());
 			objectp->idleUpdate(agent, world, frame_time);
 
-		}
+			}
 
 		//update flexible objects
 		LLVolumeImplFlexible::updateClass();
 
 		//update animated textures
 		LLViewerTextureAnim::updateClass();
-	}
+			}
 
 
 
diff --git a/indra/newview/llviewerparcelmedia.cpp b/indra/newview/llviewerparcelmedia.cpp
index 90fbc41daa8f38477b50ff77981ac8277045eb60..386b2fd4001a4807f086322a7386c5e604430247 100644
--- a/indra/newview/llviewerparcelmedia.cpp
+++ b/indra/newview/llviewerparcelmedia.cpp
@@ -85,7 +85,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 			}
 
 			// we're in a parcel
-			bool new_parcel = false;
 			S32 parcelid = parcel->getLocalID();						
 
 			LLUUID regionid = gAgent.getRegion()->getRegionID();
@@ -94,7 +93,6 @@ void LLViewerParcelMedia::update(LLParcel* parcel)
 				LL_DEBUGS("Media") << "New parcel, parcel id = " << parcelid << ", region id = " << regionid << LL_ENDL;
 				sMediaParcelLocalID = parcelid;
 				sMediaRegionID = regionid;
-				new_parcel = true;
 			}
 
 			std::string mediaUrl = std::string ( parcel->getMediaURL () );
diff --git a/indra/newview/llviewerparcelmgr.cpp b/indra/newview/llviewerparcelmgr.cpp
index 77e382b8c71956ca3c1b35130c30645183a899c4..4cdb568d17de14beabfd8355f6294ee9b77f66fc 100644
--- a/indra/newview/llviewerparcelmgr.cpp
+++ b/indra/newview/llviewerparcelmgr.cpp
@@ -696,8 +696,8 @@ bool LLViewerParcelMgr::allowAgentScripts(const LLViewerRegion* region, const LL
 	// This mirrors the traditional menu bar parcel icon code, but is not
 	// technically correct.
 	return region
-		&& !(region->getRegionFlags() & REGION_FLAGS_SKIP_SCRIPTS)
-		&& !(region->getRegionFlags() & REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
+		&& !region->getRegionFlag(REGION_FLAGS_SKIP_SCRIPTS)
+		&& !region->getRegionFlag(REGION_FLAGS_ESTATE_SKIP_SCRIPTS)
 		&& parcel
 		&& parcel->getAllowOtherScripts();
 }
@@ -2057,7 +2057,7 @@ void LLViewerParcelMgr::startReleaseLand()
 		return;
 	}
 /*
-	if ((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+	if (region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
 		&& !gAgent.isGodlike())
 	{
 		LLSD args;
@@ -2302,7 +2302,7 @@ void LLViewerParcelMgr::startDeedLandToGroup()
 	/*
 	if(!gAgent.isGodlike())
 	{
-		if((region->getRegionFlags() & REGION_FLAGS_BLOCK_LAND_RESELL)
+		if(region->getRegionFlag(REGION_FLAGS_BLOCK_LAND_RESELL)
 			&& (mCurrentParcel->getOwnerID() != region->getOwner()))
 		{
 			LLSD args;
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index e4234a538d19c8402ba5d917d0a08d1e17ce4cc9..b8b53aa6e45f9cc83ea75b4d187313a0f170cb3a 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -142,7 +142,8 @@ class LLViewerRegionImpl {
 	LLUUID mCacheID;
 
 	CapabilityMap mCapabilities;
-	
+	CapabilityMap mSecondCapabilitiesTracker; 
+
 	LLEventPoll* mEventPoll;
 
 	S32 mSeedCapMaxAttempts;
@@ -209,9 +210,9 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 	virtual ~BaseCapabilitiesComplete()
 	{ }
 
-    void error(U32 statusNum, const std::string& reason)
+    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
     {
-		LL_WARNS2("AppInit", "Capabilities") << statusNum << ": " << reason << LL_ENDL;
+		LL_WARNS2("AppInit", "Capabilities") << "[status:" << statusNum << ":] " << content << LL_ENDL;
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if (regionp)
 		{
@@ -219,7 +220,7 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 		}
     }
 
-    void result(const LLSD& content)
+   void result(const LLSD& content)
     {
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
 		if(!regionp) //region was removed
@@ -237,6 +238,7 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
 		{
 			regionp->setCapability(iter->first, iter->second);
+			
 			LL_DEBUGS2("AppInit", "Capabilities") << "got capability for " 
 				<< iter->first << LL_ENDL;
 
@@ -265,6 +267,62 @@ class BaseCapabilitiesComplete : public LLHTTPClient::Responder
 	S32 mID;
 };
 
+class BaseCapabilitiesCompleteTracker :  public LLHTTPClient::Responder
+{
+	LOG_CLASS(BaseCapabilitiesCompleteTracker);
+public:
+	BaseCapabilitiesCompleteTracker( U64 region_handle)
+	: mRegionHandle(region_handle)
+	{ }
+	
+	virtual ~BaseCapabilitiesCompleteTracker()
+	{ }
+
+	void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
+	{
+		llwarns << "BaseCapabilitiesCompleteTracker error [status:"
+				<< statusNum << "]: " << content << llendl;
+	}
+
+	void result(const LLSD& content)
+	{
+		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(mRegionHandle);
+		if( !regionp ) 
+		{
+			return ;
+		}		
+		LLSD::map_const_iterator iter;
+		for(iter = content.beginMap(); iter != content.endMap(); ++iter)
+		{
+			regionp->setCapabilityDebug(iter->first, iter->second);	
+			//llinfos<<"BaseCapabilitiesCompleteTracker New Caps "<<iter->first<<" "<< iter->second<<llendl;
+		}
+		
+		if ( regionp->getRegionImpl()->mCapabilities.size() != regionp->getRegionImpl()->mSecondCapabilitiesTracker.size() )
+		{
+			llinfos<<"BaseCapabilitiesCompleteTracker "<<"Sim sent duplicate seed caps that differs in size - most likely content."<<llendl;			
+			//todo#add cap debug versus original check?
+			/*CapabilityMap::const_iterator iter = regionp->getRegionImpl()->mCapabilities.begin();
+			while (iter!=regionp->getRegionImpl()->mCapabilities.end() )
+			{
+				llinfos<<"BaseCapabilitiesCompleteTracker Original "<<iter->first<<" "<< iter->second<<llendl;
+				++iter;
+			}
+			*/
+			regionp->getRegionImplNC()->mSecondCapabilitiesTracker.clear();
+		}
+
+	}
+
+	static BaseCapabilitiesCompleteTracker* build( U64 region_handle )
+	{
+		return new BaseCapabilitiesCompleteTracker( region_handle );
+	}
+
+private:
+	U64 mRegionHandle;	
+};
+
 
 LLViewerRegion::LLViewerRegion(const U64 &handle,
 							   const LLHost &host,
@@ -278,9 +336,11 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mZoning(""),
 	mIsEstateManager(FALSE),
 	mRegionFlags( REGION_FLAGS_DEFAULT ),
+	mRegionProtocols( 0 ),
 	mSimAccess( SIM_ACCESS_MIN ),
 	mBillableFactor(1.0),
 	mMaxTasks(DEFAULT_MAX_REGION_WIDE_PRIM_COUNT),
+	mCentralBakeVersion(0),
 	mClassID(0),
 	mCPURatio(0),
 	mColoName("unknown"),
@@ -453,18 +513,6 @@ void LLViewerRegion::sendReliableMessage()
 	gMessageSystem->sendReliable(mImpl->mHost);
 }
 
-void LLViewerRegion::setFlags(BOOL b, U32 flags)
-{
-	if (b)
-	{
-		mRegionFlags |=  flags;
-	}
-	else
-	{
-		mRegionFlags &= ~flags;
-	}
-}
-
 void LLViewerRegion::setWaterHeight(F32 water_level)
 {
 	mImpl->mLandp->setWaterHeight(water_level);
@@ -477,10 +525,10 @@ F32 LLViewerRegion::getWaterHeight() const
 
 BOOL LLViewerRegion::isVoiceEnabled() const
 {
-	return (getRegionFlags() & REGION_FLAGS_ALLOW_VOICE);
+	return getRegionFlag(REGION_FLAGS_ALLOW_VOICE);
 }
 
-void LLViewerRegion::setRegionFlags(U32 flags)
+void LLViewerRegion::setRegionFlags(U64 flags)
 {
 	mRegionFlags = flags;
 }
@@ -573,7 +621,7 @@ std::string LLViewerRegion::getLocalizedSimProductName() const
 }
 
 // static
-std::string LLViewerRegion::regionFlagsToString(U32 flags)
+std::string LLViewerRegion::regionFlagsToString(U64 flags)
 {
 	std::string result;
 
@@ -1388,7 +1436,8 @@ void LLViewerRegion::unpackRegionHandshake()
 {
 	LLMessageSystem *msg = gMessageSystem;
 
-	U32 region_flags;
+	U64 region_flags = 0;
+	U64 region_protocols = 0;
 	U8 sim_access;
 	std::string sim_name;
 	LLUUID sim_owner;
@@ -1397,7 +1446,6 @@ void LLViewerRegion::unpackRegionHandshake()
 	F32 billable_factor;
 	LLUUID cache_id;
 
-	msg->getU32		("RegionInfo", "RegionFlags", region_flags);
 	msg->getU8		("RegionInfo", "SimAccess", sim_access);
 	msg->getString	("RegionInfo", "SimName", sim_name);
 	msg->getUUID	("RegionInfo", "SimOwner", sim_owner);
@@ -1406,7 +1454,20 @@ void LLViewerRegion::unpackRegionHandshake()
 	msg->getF32		("RegionInfo", "BillableFactor", billable_factor);
 	msg->getUUID	("RegionInfo", "CacheID", cache_id );
 
+	if (msg->has(_PREHASH_RegionInfo4))
+	{
+		msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionFlagsExtended, region_flags);
+		msg->getU64Fast(_PREHASH_RegionInfo4, _PREHASH_RegionProtocols, region_protocols);
+	}
+	else
+	{
+		U32 flags = 0;
+		msg->getU32Fast(_PREHASH_RegionInfo, _PREHASH_RegionFlags, flags);
+		region_flags = flags;
+	}
+
 	setRegionFlags(region_flags);
+	setRegionProtocols(region_protocols);
 	setSimAccess(sim_access);
 	setRegionNameAndZone(sim_name);
 	setOwner(sim_owner);
@@ -1445,6 +1506,8 @@ void LLViewerRegion::unpackRegionHandshake()
 		mProductName = productName;
 	}
 
+
+	mCentralBakeVersion = region_protocols & 1; // was (S32)gSavedSettings.getBOOL("UseServerTextureBaking");
 	LLVLComposition *compp = getComposition();
 	if (compp)
 	{
@@ -1524,11 +1587,12 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("EventQueueGet");
 
 	if (gSavedSettings.getBOOL("UseHTTPInventory"))
-	{
+	{	
 		capabilityNames.append("FetchLib2");
 		capabilityNames.append("FetchLibDescendents2");
 		capabilityNames.append("FetchInventory2");
 		capabilityNames.append("FetchInventoryDescendents2");
+		capabilityNames.append("IncrementCOFVersion");
 	}
 
 	capabilityNames.append("GetDisplayNames");
@@ -1542,7 +1606,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("LandResources");
 	capabilityNames.append("MapLayer");
 	capabilityNames.append("MapLayerGod");
-	capabilityNames.append("MeshUploadFlag");
+	capabilityNames.append("MeshUploadFlag");	
 	capabilityNames.append("NavMeshGenerationStatus");
 	capabilityNames.append("NewFileAgentInventory");
 	capabilityNames.append("ObjectMedia");
@@ -1571,6 +1635,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("UntrustedSimulatorMessage");
 	capabilityNames.append("UpdateAgentInformation");
 	capabilityNames.append("UpdateAgentLanguage");
+	capabilityNames.append("UpdateAvatarAppearance");
 	capabilityNames.append("UpdateGestureAgentInventory");
 	capabilityNames.append("UpdateGestureTaskInventory");
 	capabilityNames.append("UpdateNotecardAgentInventory");
@@ -1581,7 +1646,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
-	
+
 	// Please add new capabilities alphabetically to reduce
 	// merge conflicts.
 }
@@ -1589,8 +1654,14 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 void LLViewerRegion::setSeedCapability(const std::string& url)
 {
 	if (getCapability("Seed") == url)
-    {
-		// llwarns << "Ignoring duplicate seed capability" << llendl;
+    {	
+		//llwarns << "Ignoring duplicate seed capability" << llendl;
+		//Instead of just returning we build up a second set of seed caps and compare them 
+		//to the "original" seed cap received and determine why there is problem!
+		LLSD capabilityNames = LLSD::emptyArray();
+		mImpl->buildCapabilityNames( capabilityNames );
+		LLHTTPClient::post( url, capabilityNames, BaseCapabilitiesCompleteTracker::build(getHandle() ),
+							LLSD(), CAP_REQUEST_TIMEOUT );
 		return;
     }
 	
@@ -1663,9 +1734,9 @@ class SimulatorFeaturesReceived : public LLHTTPClient::Responder
     { }
 	
 	
-    void error(U32 statusNum, const std::string& reason)
+    void errorWithContent(U32 statusNum, const std::string& reason, const LLSD& content)
     {
-		LL_WARNS2("AppInit", "SimulatorFeatures") << statusNum << ": " << reason << LL_ENDL;
+		LL_WARNS2("AppInit", "SimulatorFeatures") << "[status:" << statusNum << "]: " << content << LL_ENDL;
 		retry();
     }
 
@@ -1726,6 +1797,11 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
 	}
 }
 
+void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::string& url)
+{
+	mImpl->mSecondCapabilitiesTracker[name] = url;
+}
+
 bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
 {
 	return name == "EventQueueGet" || name == "UntrustedSimulatorMessage";
@@ -1733,6 +1809,11 @@ bool LLViewerRegion::isSpecialCapabilityName(const std::string &name)
 
 std::string LLViewerRegion::getCapability(const std::string& name) const
 {
+	if (!capabilitiesReceived() && (name!=std::string("Seed")) && (name!=std::string("ObjectMedia")))
+	{
+		llwarns << "getCapability called before caps received" << llendl;
+	}
+	
 	CapabilityMap::const_iterator iter = mImpl->mCapabilities.find(name);
 	if(iter == mImpl->mCapabilities.end())
 	{
@@ -1792,7 +1873,7 @@ LLSpatialPartition* LLViewerRegion::getSpatialPartition(U32 type)
 
 // the viewer can not yet distinquish between normal- and estate-owned objects
 // so we collapse these two bits and enable the UI if either are set
-const U32 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
+const U64 ALLOW_RETURN_ENCROACHING_OBJECT = REGION_FLAGS_ALLOW_RETURN_ENCROACHING_OBJECT
 											| REGION_FLAGS_ALLOW_RETURN_ENCROACHING_ESTATE_OBJECT;
 
 bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<LLBBox>& boxes) const
@@ -1800,7 +1881,7 @@ bool LLViewerRegion::objectIsReturnable(const LLVector3& pos, const std::vector<
 	return (mParcelOverlay != NULL)
 		&& (mParcelOverlay->isOwnedSelf(pos)
 			|| mParcelOverlay->isOwnedGroup(pos)
-			|| ((mRegionFlags & ALLOW_RETURN_ENCROACHING_OBJECT)
+			|| (getRegionFlag(ALLOW_RETURN_ENCROACHING_OBJECT)
 				&& mParcelOverlay->encroachesOwned(boxes)) );
 }
 
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index c9fffaf30e4abff15de3dbc7f31bddf8bef0cbbe..b5fe4677b76111471b3d870ad068e5ea88359e67 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -109,13 +109,13 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	//void setAgentOffset(const LLVector3d &offset);
 	void updateRenderMatrix();
 
-	void setAllowDamage(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DAMAGE); }
-	void setAllowLandmark(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_LANDMARK); }
-	void setAllowSetHome(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_SET_HOME); }
-	void setResetHomeOnTeleport(BOOL b) { setFlags(b, REGION_FLAGS_RESET_HOME_ON_TELEPORT); }
-	void setSunFixed(BOOL b) { setFlags(b, REGION_FLAGS_SUN_FIXED); }
-	void setBlockFly(BOOL b) { setFlags(b, REGION_FLAGS_BLOCK_FLY); }
-	void setAllowDirectTeleport(BOOL b) { setFlags(b, REGION_FLAGS_ALLOW_DIRECT_TELEPORT); }
+	void setAllowDamage(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DAMAGE, b); }
+	void setAllowLandmark(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_LANDMARK, b); }
+	void setAllowSetHome(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_SET_HOME, b); }
+	void setResetHomeOnTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_RESET_HOME_ON_TELEPORT, b); }
+	void setSunFixed(BOOL b) { setRegionFlag(REGION_FLAGS_SUN_FIXED, b); }
+	void setBlockFly(BOOL b) { setRegionFlag(REGION_FLAGS_BLOCK_FLY, b); }
+	void setAllowDirectTeleport(BOOL b) { setRegionFlag(REGION_FLAGS_ALLOW_DIRECT_TELEPORT, b); }
 
 
 	inline BOOL getAllowDamage()			const;
@@ -156,8 +156,15 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLViewerParcelOverlay *getParcelOverlay() const
 			{ return mParcelOverlay; }
 
-	void setRegionFlags(U32 flags);
-	U32 getRegionFlags() const					{ return mRegionFlags; }
+	inline void setRegionFlag(U64 flag, BOOL on);
+	inline BOOL getRegionFlag(U64 flag) const;
+	void setRegionFlags(U64 flags);
+	U64 getRegionFlags() const					{ return mRegionFlags; }
+
+	inline void setRegionProtocol(U64 protocol, BOOL on);
+	BOOL getRegionProtocol(U64 protocol) const;
+	void setRegionProtocols(U64 protocols)			{ mRegionProtocols = protocols; }
+	U64 getRegionProtocols() const					{ return mRegionProtocols; }
 
 	void setTimeDilation(F32 time_dilation);
 	F32  getTimeDilation() const				{ return mTimeDilation; }
@@ -195,7 +202,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	std::string getLocalizedSimProductName() const;
 
 	// Returns "Sandbox", "Expensive", etc.
-	static std::string regionFlagsToString(U32 flags);
+	static std::string regionFlagsToString(U64 flags);
 
 	// Returns translated version of "Mature", "PG", "Adult", etc.
 	static std::string accessToString(U8 sim_access);
@@ -234,6 +241,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	void failedSeedCapability();
 	S32 getNumSeedCapRetries();
 	void setCapability(const std::string& name, const std::string& url);
+	void setCapabilityDebug(const std::string& name, const std::string& url);
 	// implements LLCapabilityProvider
     virtual std::string getCapability(const std::string& name) const;
 
@@ -278,6 +286,8 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	F32 getLandHeightRegion(const LLVector3& region_pos);
 
+	U8 getCentralBakeVersion() { return mCentralBakeVersion; }
+
 	void getInfo(LLSD& info);
 	
 	bool meshRezEnabled() const;
@@ -330,7 +340,9 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 
 	void getNeighboringRegions( std::vector<LLViewerRegion*>& uniqueRegions );
 	void getNeighboringRegionsStatus( std::vector<S32>& regions );
-	
+	const LLViewerRegionImpl * getRegionImpl() const { return mImpl; }
+	LLViewerRegionImpl * getRegionImplNC() { return mImpl; }
+
 public:
 	struct CompareDistance
 	{
@@ -345,7 +357,6 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 protected:
 	void disconnectAllNeighbors();
 	void initStats();
-	void setFlags(BOOL b, U32 flags);
 
 public:
 	LLWind  mWind;
@@ -390,11 +401,13 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	U32		mPingDelay;
 	F32		mDeltaTime;				// Time since last measurement of lastPackets, Bits, etc
 
-	U32		mRegionFlags;			// includes damage flags
+	U64		mRegionFlags;			// includes damage flags
+	U64		mRegionProtocols;		// protocols supported by this region
 	U8		mSimAccess;
 	F32 	mBillableFactor;
 	U32		mMaxTasks;				// max prim count
 	F32		mCameraDistanceSquared;	// updated once per frame
+	U8		mCentralBakeVersion;
 	
 	// Information for Homestead / CR-53
 	S32 mClassID;
@@ -423,6 +436,40 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	LLSD mSimulatorFeatures;
 };
 
+inline BOOL LLViewerRegion::getRegionProtocol(U64 protocol) const
+{
+	return ((mRegionProtocols & protocol) != 0);
+}
+
+inline void LLViewerRegion::setRegionProtocol(U64 protocol, BOOL on)
+{
+	if (on)
+	{
+		mRegionProtocols |= protocol;
+	}
+	else
+	{
+		mRegionProtocols &= ~protocol;
+	}
+}
+
+inline BOOL LLViewerRegion::getRegionFlag(U64 flag) const
+{
+	return ((mRegionFlags & flag) != 0);
+}
+
+inline void LLViewerRegion::setRegionFlag(U64 flag, BOOL on)
+{
+	if (on)
+	{
+		mRegionFlags |= flag;
+	}
+	else
+	{
+		mRegionFlags &= ~flag;
+	}
+}
+
 inline BOOL LLViewerRegion::getAllowDamage() const
 {
 	return ((mRegionFlags & REGION_FLAGS_ALLOW_DAMAGE) !=0);
diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h
index d6dd645e8cc483473a986febaf52dc00be10a24a..e3d28f2f5c21f42d51f641274e62d211e96a624d 100644
--- a/indra/newview/llviewershadermgr.h
+++ b/indra/newview/llviewershadermgr.h
@@ -229,7 +229,6 @@ extern LLGLSLShader			gSplatTextureRectProgram;
 extern LLGLSLShader			gGlowCombineFXAAProgram;
 extern LLGLSLShader			gDebugProgram;
 extern LLGLSLShader			gClipProgram;
-extern LLGLSLShader			gAlphaMaskProgram;
 
 //output tex0[tc0] + tex1[tc1]
 extern LLGLSLShader			gTwoTextureAddProgram;
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 35839ae45912ef4c693ae3bd9bfd2fc5cda049f8..35bba4184e63f342776ebe6f2d244d265626e44f 100644
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -752,25 +752,6 @@ void LLViewerStats::PhaseMap::startPhase(const std::string& phase_name)
 	timer.unpause();
 }
 
-void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
-{
-	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
-	if (iter != mPhaseMap.end())
-	{
-		if (iter->second.getStarted())
-		{
-			// Going from started to paused state - record stats.
-			recordPhaseStat(phase_name,iter->second.getElapsedTimeF32());
-		}
-		lldebugs << "stopPhase " << phase_name << llendl;
-		iter->second.pause();
-	}
-	else
-	{
-		lldebugs << "stopPhase " << phase_name << " is not started, no-op" << llendl;
-	}
-}
-
 void LLViewerStats::PhaseMap::stopAllPhases()
 {
 	for (phase_map_t::iterator iter = mPhaseMap.begin();
@@ -814,6 +795,19 @@ LLViewerStats::PhaseMap::PhaseMap()
 {
 }
 
+
+void LLViewerStats::PhaseMap::stopPhase(const std::string& phase_name)
+{
+	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+	if (iter != mPhaseMap.end())
+	{
+		if (iter->second.getStarted())
+		{
+			// Going from started to stopped state - record stats.
+			iter->second.stop();
+		}
+	}
+}
 // static
 LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
 {
@@ -833,3 +827,18 @@ void LLViewerStats::PhaseMap::recordPhaseStat(const std::string& phase_name, F32
 	stats.push(value);
 }
 
+
+bool LLViewerStats::PhaseMap::getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed)
+{
+	phase_map_t::iterator iter = mPhaseMap.find(phase_name);
+	if (iter != mPhaseMap.end())
+	{
+		elapsed =  iter->second.getElapsedTimeF32();
+		completed = !iter->second.getStarted();
+		return true;
+	}
+	else
+	{
+		return false;
+	}
+}
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index e02a4ccdc70756bc1a913509ebabd228ed77796a..6b2461be41fb51fd9eca307590412fa09de80ad2 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -289,6 +289,7 @@ class LLViewerStats : public LLSingleton<LLViewerStats>
 	public:
 		PhaseMap();
 		LLFrameTimer& 	getPhaseTimer(const std::string& phase_name);
+		bool 			getPhaseValues(const std::string& phase_name, F32& elapsed, bool& completed);
 		void			startPhase(const std::string& phase_name);
 		void			stopPhase(const std::string& phase_name);
 		void			stopAllPhases();
@@ -296,8 +297,11 @@ class LLViewerStats : public LLSingleton<LLViewerStats>
 		LLSD			dumpPhases();
 		static StatsAccumulator& getPhaseStats(const std::string& phase_name);
 		static void recordPhaseStat(const std::string& phase_name, F32 value);
+		phase_map_t::iterator begin() { return mPhaseMap.begin(); }
+		phase_map_t::iterator end() { return mPhaseMap.end(); }
 	};
 
+
 private:
 	F64	mStats[ST_COUNT];
 
diff --git a/indra/newview/llviewertexlayer.cpp b/indra/newview/llviewertexlayer.cpp
new file mode 100755
index 0000000000000000000000000000000000000000..777e1f9c76a6d6e7240b6b18cd0d09b1466bb086
--- /dev/null
+++ b/indra/newview/llviewertexlayer.cpp
@@ -0,0 +1,748 @@
+/** 
+ * @file llviewertexlayer.cpp
+ * @brief Viewer texture layer. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llviewertexlayer.h"
+
+#include "llagent.h"
+#include "llimagej2c.h"
+#include "llnotificationsutil.h"
+#include "llvfile.h"
+#include "llvfs.h"
+#include "llviewerregion.h"
+#include "llglslshader.h"
+#include "llvoavatarself.h"
+#include "pipeline.h"
+#include "llassetuploadresponders.h"
+#include "llviewercontrol.h"
+
+static const S32 BAKE_UPLOAD_ATTEMPTS = 7;
+static const F32 BAKE_UPLOAD_RETRY_DELAY = 2.f; // actual delay grows by power of 2 each attempt
+
+// runway consolidate
+extern std::string self_av_string();
+
+
+//-----------------------------------------------------------------------------
+// LLBakedUploadData()
+//-----------------------------------------------------------------------------
+LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
+									 LLViewerTexLayerSet* layerset,
+									 const LLUUID& id,
+									 bool highest_res) :
+	mAvatar(avatar),
+	mTexLayerSet(layerset),
+	mID(id),
+	mStartTime(LLFrameTimer::getTotalTime()),		// Record starting time
+	mIsHighestRes(highest_res)
+{ 
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSetBuffer
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
+//-----------------------------------------------------------------------------
+
+// static
+S32 LLViewerTexLayerSetBuffer::sGLByteCount = 0;
+
+LLViewerTexLayerSetBuffer::LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, 
+										 S32 width, S32 height) :
+	// ORDER_LAST => must render these after the hints are created.
+	LLTexLayerSetBuffer(owner),
+	LLViewerDynamicTexture( width, height, 4, LLViewerDynamicTexture::ORDER_LAST, TRUE ), 
+	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
+	mNeedsUpload(FALSE),
+	mNumLowresUploads(0),
+	mUploadFailCount(0),
+	mNeedsUpdate(TRUE),
+	mNumLowresUpdates(0)
+{
+	LLViewerTexLayerSetBuffer::sGLByteCount += getSize();
+	mNeedsUploadTimer.start();
+	mNeedsUpdateTimer.start();
+}
+
+LLViewerTexLayerSetBuffer::~LLViewerTexLayerSetBuffer()
+{
+	LLViewerTexLayerSetBuffer::sGLByteCount -= getSize();
+	destroyGLTexture();
+	for( S32 order = 0; order < ORDER_COUNT; order++ )
+	{
+		LLViewerDynamicTexture::sInstances[order].erase(this);  // will fail in all but one case.
+	}
+}
+
+//virtual 
+S8 LLViewerTexLayerSetBuffer::getType() const 
+{
+	return LLViewerDynamicTexture::LL_TEX_LAYER_SET_BUFFER ;
+}
+
+//virtual 
+void LLViewerTexLayerSetBuffer::restoreGLTexture() 
+{	
+	LLViewerDynamicTexture::restoreGLTexture() ;
+}
+
+//virtual 
+void LLViewerTexLayerSetBuffer::destroyGLTexture() 
+{
+	LLViewerDynamicTexture::destroyGLTexture() ;
+}
+
+// static
+void LLViewerTexLayerSetBuffer::dumpTotalByteCount()
+{
+	llinfos << "Composite System GL Buffers: " << (LLViewerTexLayerSetBuffer::sGLByteCount/1024) << "KB" << llendl;
+}
+
+void LLViewerTexLayerSetBuffer::requestUpdate()
+{
+	restartUpdateTimer();
+	mNeedsUpdate = TRUE;
+	mNumLowresUpdates = 0;
+	// If we're in the middle of uploading a baked texture, we don't care about it any more.
+	// When it's downloaded, ignore it.
+	mUploadID.setNull();
+}
+
+void LLViewerTexLayerSetBuffer::requestUpload()
+{
+	conditionalRestartUploadTimer();
+	mNeedsUpload = TRUE;
+	mNumLowresUploads = 0;
+	mUploadPending = TRUE;
+}
+
+void LLViewerTexLayerSetBuffer::conditionalRestartUploadTimer()
+{
+	// If we requested a new upload but haven't even uploaded
+	// a low res version of our last upload request, then
+	// keep the timer ticking instead of resetting it.
+	if (mNeedsUpload && (mNumLowresUploads == 0))
+	{
+		mNeedsUploadTimer.unpause();
+	}
+	else
+	{
+		mNeedsUploadTimer.reset();
+		mNeedsUploadTimer.start();
+	}
+}
+
+void LLViewerTexLayerSetBuffer::restartUpdateTimer()
+{
+	mNeedsUpdateTimer.reset();
+	mNeedsUpdateTimer.start();
+}
+
+void LLViewerTexLayerSetBuffer::cancelUpload()
+{
+	mNeedsUpload = FALSE;
+	mUploadPending = FALSE;
+	mNeedsUploadTimer.pause();
+	mUploadRetryTimer.reset();
+}
+
+// virtual
+BOOL LLViewerTexLayerSetBuffer::needsRender()
+{
+	llassert(mTexLayerSet->getAvatarAppearance() == gAgentAvatarp);
+	if (!isAgentAvatarValid()) return FALSE;
+
+	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+	// Don't render if we don't want to (or aren't ready to) upload or update.
+	if (!(update_now || upload_now))
+	{
+		return FALSE;
+	}
+
+	// Don't render if we're animating our appearance.
+	if (gAgentAvatarp->getIsAppearanceAnimating())
+	{
+		return FALSE;
+	}
+
+	// Don't render if we are trying to create a shirt texture but aren't wearing a skirt.
+	if (gAgentAvatarp->getBakedTE(getViewerTexLayerSet()) == LLAvatarAppearanceDefines::TEX_SKIRT_BAKED && 
+		!gAgentAvatarp->isWearingWearableType(LLWearableType::WT_SKIRT))
+	{
+		cancelUpload();
+		return FALSE;
+	}
+
+	// Render if we have at least minimal level of detail for each local texture.
+	return getViewerTexLayerSet()->isLocalTextureDataAvailable();
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::preRenderTexLayerSet()
+{
+	LLTexLayerSetBuffer::preRenderTexLayerSet();
+	
+	// keep depth buffer, we don't need to clear it
+	LLViewerDynamicTexture::preRender(FALSE);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::postRenderTexLayerSet(BOOL success)
+{
+
+	LLTexLayerSetBuffer::postRenderTexLayerSet(success);
+	LLViewerDynamicTexture::postRender(success);
+}
+
+// virtual
+void LLViewerTexLayerSetBuffer::midRenderTexLayerSet(BOOL success)
+{
+	// do we need to upload, and do we have sufficient data to create an uploadable composite?
+	// TODO: When do we upload the texture if gAgent.mNumPendingQueries is non-zero?
+	const BOOL upload_now = mNeedsUpload && isReadyToUpload();
+	const BOOL update_now = mNeedsUpdate && isReadyToUpdate();
+
+	if(upload_now)
+	{
+		if (!success)
+		{
+			llinfos << "Failed attempt to bake " << mTexLayerSet->getBodyRegionName() << llendl;
+			mUploadPending = FALSE;
+		}
+		else
+		{
+			LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+			if (layer_set->isVisible())
+			{
+				layer_set->getAvatar()->debugBakedTextureUpload(layer_set->getBakedTexIndex(), FALSE); // FALSE for start of upload, TRUE for finish.
+				doUpload();
+			}
+			else
+			{
+				mUploadPending = FALSE;
+				mNeedsUpload = FALSE;
+				mNeedsUploadTimer.pause();
+				layer_set->getAvatar()->setNewBakedTexture(layer_set->getBakedTexIndex(),IMG_INVISIBLE);
+			}
+		}
+	}
+	
+	if (update_now)
+	{
+		doUpdate();
+	}
+
+	// *TODO: Old logic does not check success before setGLTextureCreated
+	// we have valid texture data now
+	mGLTexturep->setGLTextureCreated(true);
+}
+
+BOOL LLViewerTexLayerSetBuffer::isInitialized(void) const
+{
+	return mGLTexturep.notNull() && mGLTexturep->isGLTextureCreated();
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadPending() const
+{
+	return mUploadPending;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadNeeded() const
+{
+	return mNeedsUpload;
+}
+
+BOOL LLViewerTexLayerSetBuffer::uploadInProgress() const
+{
+	return !mUploadID.isNull();
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpload() const
+{
+	if (!gAgentQueryManager.hasNoPendingQueries()) return FALSE; // Can't upload if there are pending queries.
+	if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance()) return FALSE; // Don't upload if avatar is being edited.
+
+	BOOL ready = FALSE;
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal())
+	{
+		// If we requested an upload and have the final LOD ready, upload (or wait a while if this is a retry)
+		if (mUploadFailCount == 0)
+		{
+			ready = TRUE;
+		}
+		else
+		{
+			ready = mUploadRetryTimer.getElapsedTimeF32() >= BAKE_UPLOAD_RETRY_DELAY * (1 << (mUploadFailCount - 1));
+		}
+	}
+	else
+	{
+		// Upload if we've hit a timeout.  Upload is a pretty expensive process so we need to make sure
+		// we aren't doing uploads too frequently.
+		const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureUploadTimeout");
+		if (texture_timeout != 0)
+		{
+			// The timeout period increases exponentially between every lowres upload in order to prevent
+			// spamming the server with frequent uploads.
+			const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
+
+			// If we hit our timeout and have textures available at even lower resolution, then upload.
+			const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
+			const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+			ready = has_lower_lod && is_upload_textures_timeout;
+		}
+	}
+
+	return ready;
+}
+
+BOOL LLViewerTexLayerSetBuffer::isReadyToUpdate() const
+{
+	// If we requested an update and have the final LOD ready, then update.
+	if (getViewerTexLayerSet()->isLocalTextureDataFinal()) return TRUE;
+
+	// If we haven't done an update yet, then just do one now regardless of state of textures.
+	if (mNumLowresUpdates == 0) return TRUE;
+
+	// Update if we've hit a timeout.  Unlike for uploads, we can make this timeout fairly small
+	// since render unnecessarily doesn't cost much.
+	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedLocalTextureUpdateTimeout");
+	if (texture_timeout != 0)
+	{
+		// If we hit our timeout and have textures available at even lower resolution, then update.
+		const BOOL is_update_textures_timeout = mNeedsUpdateTimer.getElapsedTimeF32() >= texture_timeout;
+		const BOOL has_lower_lod = getViewerTexLayerSet()->isLocalTextureDataAvailable();
+		if (has_lower_lod && is_update_textures_timeout) return TRUE; 
+	}
+
+	return FALSE;
+}
+
+BOOL LLViewerTexLayerSetBuffer::requestUpdateImmediate()
+{
+	mNeedsUpdate = TRUE;
+	BOOL result = FALSE;
+
+	if (needsRender())
+	{
+		preRender(FALSE);
+		result = render();
+		postRender(result);
+	}
+
+	return result;
+}
+
+// Create the baked texture, send it out to the server, then wait for it to come
+// back so we can switch to using it.
+void LLViewerTexLayerSetBuffer::doUpload()
+{
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	LL_DEBUGS("Avatar") << "Uploading baked " << layer_set->getBodyRegionName() << llendl;
+	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+
+	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
+	// until this image is sent to the server and the Avatar Appearance message is received.)
+	layer_set->deleteCaches();
+
+	// Get the COLOR information from our texture
+	U8* baked_color_data = new U8[ mFullWidth * mFullHeight * 4 ];
+	glReadPixels(mOrigin.mX, mOrigin.mY, mFullWidth, mFullHeight, GL_RGBA, GL_UNSIGNED_BYTE, baked_color_data );
+	stop_glerror();
+
+	// Get the MASK information from our texture
+	LLGLSUIDefault gls_ui;
+	LLPointer<LLImageRaw> baked_mask_image = new LLImageRaw(mFullWidth, mFullHeight, 1 );
+	U8* baked_mask_data = baked_mask_image->getData(); 
+	layer_set->gatherMorphMaskAlpha(baked_mask_data,
+									mOrigin.mX, mOrigin.mY,
+									mFullWidth, mFullHeight);
+
+
+	// Create the baked image from our color and mask information
+	const S32 baked_image_components = 5; // red green blue [bump] clothing
+	LLPointer<LLImageRaw> baked_image = new LLImageRaw( mFullWidth, mFullHeight, baked_image_components );
+	U8* baked_image_data = baked_image->getData();
+	S32 i = 0;
+	for (S32 u=0; u < mFullWidth; u++)
+	{
+		for (S32 v=0; v < mFullHeight; v++)
+		{
+			baked_image_data[5*i + 0] = baked_color_data[4*i + 0];
+			baked_image_data[5*i + 1] = baked_color_data[4*i + 1];
+			baked_image_data[5*i + 2] = baked_color_data[4*i + 2];
+			baked_image_data[5*i + 3] = baked_color_data[4*i + 3]; // alpha should be correct for eyelashes.
+			baked_image_data[5*i + 4] = baked_mask_data[i];
+			i++;
+		}
+	}
+	
+	LLPointer<LLImageJ2C> compressedImage = new LLImageJ2C;
+	const char* comment_text = LINDEN_J2C_COMMENT_PREFIX "RGBHM"; // writes into baked_color_data. 5 channels (rgb, heightfield/alpha, mask)
+	if (compressedImage->encode(baked_image, comment_text))
+	{
+		LLTransactionID tid;
+		tid.generate();
+		const LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+		if (LLVFile::writeFile(compressedImage->getData(), compressedImage->getDataSize(),
+							   gVFS, asset_id, LLAssetType::AT_TEXTURE))
+		{
+			// Read back the file and validate.
+			BOOL valid = FALSE;
+			LLPointer<LLImageJ2C> integrity_test = new LLImageJ2C;
+			S32 file_size = 0;
+			LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE);
+			file_size = file.getSize();
+			U8* data = integrity_test->allocateData(file_size);
+			file.read(data, file_size);
+			if (data)
+			{
+				valid = integrity_test->validate(data, file_size); // integrity_test will delete 'data'
+			}
+			else
+			{
+				integrity_test->setLastError("Unable to read entire file");
+			}
+			
+			if (valid)
+			{
+				const bool highest_lod = layer_set->isLocalTextureDataFinal();
+				// Baked_upload_data is owned by the responder and deleted after the request completes.
+				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
+																			 layer_set, 
+																			 asset_id,
+																			 highest_lod);
+				// upload ID is used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
+				mUploadID = asset_id;
+
+				// Upload the image
+				const std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
+				if(!url.empty()
+					&& !LLPipeline::sForceOldBakedUpload // toggle debug setting UploadBakedTexOld to change between the new caps method and old method
+					&& (mUploadFailCount < (BAKE_UPLOAD_ATTEMPTS - 1))) // Try last ditch attempt via asset store if cap upload is failing.
+				{
+					LLSD body = LLSD::emptyMap();
+					// The responder will call LLViewerTexLayerSetBuffer::onTextureUploadComplete()
+					LLHTTPClient::post(url, body, new LLSendTexLayerResponder(body, mUploadID, LLAssetType::AT_TEXTURE, baked_upload_data));
+					llinfos << "Baked texture upload via capability of " << mUploadID << " to " << url << llendl;
+				} 
+				else
+				{
+					gAssetStorage->storeAssetData(tid,
+												  LLAssetType::AT_TEXTURE,
+												  LLViewerTexLayerSetBuffer::onTextureUploadComplete,
+												  baked_upload_data,
+												  TRUE,		// temp_file
+												  TRUE,		// is_priority
+												  TRUE);	// store_local
+					llinfos << "Baked texture upload via Asset Store." <<  llendl;
+				}
+
+				if (highest_lod)
+				{
+					// Sending the final LOD for the baked texture.  All done, pause 
+					// the upload timer so we know how long it took.
+					mNeedsUpload = FALSE;
+					mNeedsUploadTimer.pause();
+				}
+				else
+				{
+					// Sending a lower level LOD for the baked texture.  Restart the upload timer.
+					mNumLowresUploads++;
+					mNeedsUploadTimer.unpause();
+					mNeedsUploadTimer.reset();
+				}
+
+				// Print out notification that we uploaded this texture.
+				if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+				{
+					const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+					LLSD args;
+					args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+					args["TIME"] = llformat("%d",(U32)mNeedsUploadTimer.getElapsedTimeF32());
+					args["BODYREGION"] = layer_set->getBodyRegionName();
+					args["RESOLUTION"] = lod_str;
+					LLNotificationsUtil::add("AvatarRezSelfBakedTextureUploadNotification",args);
+					LL_DEBUGS("Avatar") << self_av_string() << "Uploading [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+				}
+			}
+			else
+			{
+				// The read back and validate operation failed.  Remove the uploaded file.
+				mUploadPending = FALSE;
+				LLVFile file(gVFS, asset_id, LLAssetType::AT_TEXTURE, LLVFile::WRITE);
+				file.remove();
+				llinfos << "Unable to create baked upload file (reason: corrupted)." << llendl;
+			}
+		}
+	}
+	else
+	{
+		// The VFS write file operation failed.
+		mUploadPending = FALSE;
+		llinfos << "Unable to create baked upload file (reason: failed to write file)" << llendl;
+	}
+
+	delete [] baked_color_data;
+}
+
+// Mostly bookkeeping; don't need to actually "do" anything since
+// render() will actually do the update.
+void LLViewerTexLayerSetBuffer::doUpdate()
+{
+	LLViewerTexLayerSet* layer_set = getViewerTexLayerSet();
+	const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+	if (highest_lod)
+	{
+		mNeedsUpdate = FALSE;
+	}
+	else
+	{
+		mNumLowresUpdates++;
+	}
+
+	restartUpdateTimer();
+
+	// need to switch to using this layerset if this is the first update
+	// after getting the lowest LOD
+	layer_set->getAvatar()->updateMeshTextures();
+	
+	// Print out notification that we updated this texture.
+	if (gSavedSettings.getBOOL("DebugAvatarRezTime"))
+	{
+		const BOOL highest_lod = layer_set->isLocalTextureDataFinal();
+		const std::string lod_str = highest_lod ? "HighRes" : "LowRes";
+		LLSD args;
+		args["EXISTENCE"] = llformat("%d",(U32)layer_set->getAvatar()->debugGetExistenceTimeElapsedF32());
+		args["TIME"] = llformat("%d",(U32)mNeedsUpdateTimer.getElapsedTimeF32());
+		args["BODYREGION"] = layer_set->getBodyRegionName();
+		args["RESOLUTION"] = lod_str;
+		LLNotificationsUtil::add("AvatarRezSelfBakedTextureUpdateNotification",args);
+		LL_DEBUGS("Avatar") << self_av_string() << "Locally updating [ name: " << layer_set->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUpdateTimer.getElapsedTimeF32() << " ]" << LL_ENDL;
+	}
+}
+
+// static
+void LLViewerTexLayerSetBuffer::onTextureUploadComplete(const LLUUID& uuid,
+												  void* userdata,
+												  S32 result,
+												  LLExtStat ext_status) // StoreAssetData callback (not fixed)
+{
+	LLBakedUploadData* baked_upload_data = (LLBakedUploadData*)userdata;
+
+	if (isAgentAvatarValid() &&
+		!gAgentAvatarp->isDead() &&
+		(baked_upload_data->mAvatar == gAgentAvatarp) && // Sanity check: only the user's avatar should be uploading textures.
+		(baked_upload_data->mTexLayerSet->hasComposite()))
+	{
+		LLViewerTexLayerSetBuffer* layerset_buffer = baked_upload_data->mTexLayerSet->getViewerComposite();
+		S32 failures = layerset_buffer->mUploadFailCount;
+		layerset_buffer->mUploadFailCount = 0;
+
+		if (layerset_buffer->mUploadID.isNull())
+		{
+			// The upload got canceled, we should be in the
+			// process of baking a new texture so request an
+			// upload with the new data
+
+			// BAP: does this really belong in this callback, as
+			// opposed to where the cancellation takes place?
+			// suspect this does nothing.
+			layerset_buffer->requestUpload();
+		}
+		else if (baked_upload_data->mID == layerset_buffer->mUploadID)
+		{
+			// This is the upload we're currently waiting for.
+			layerset_buffer->mUploadID.setNull();
+			const std::string name(baked_upload_data->mTexLayerSet->getBodyRegionName());
+			const std::string resolution = baked_upload_data->mIsHighestRes ? " full res " : " low res ";
+			if (result >= 0)
+			{
+				layerset_buffer->mUploadPending = FALSE; // Allows sending of AgentSetAppearance later
+				LLAvatarAppearanceDefines::ETextureIndex baked_te = gAgentAvatarp->getBakedTE(layerset_buffer->getViewerTexLayerSet());
+				// Update baked texture info with the new UUID
+				U64 now = LLFrameTimer::getTotalTime();		// Record starting time
+				llinfos << "Baked" << resolution << "texture upload for " << name << " took " << (S32)((now - baked_upload_data->mStartTime) / 1000) << " ms" << llendl;
+				gAgentAvatarp->setNewBakedTexture(baked_te, uuid);
+			}
+			else
+			{	
+				++failures;
+				S32 max_attempts = baked_upload_data->mIsHighestRes ? BAKE_UPLOAD_ATTEMPTS : 1; // only retry final bakes
+				llwarns << "Baked" << resolution << "texture upload for " << name << " failed (attempt " << failures << "/" << max_attempts << ")" << llendl;
+				if (failures < max_attempts)
+				{
+					layerset_buffer->mUploadFailCount = failures;
+					layerset_buffer->mUploadRetryTimer.start();
+					layerset_buffer->requestUpload();
+				}
+			}
+		}
+		else
+		{
+			llinfos << "Received baked texture out of date, ignored." << llendl;
+		}
+
+		gAgentAvatarp->dirtyMesh();
+	}
+	else
+	{
+		// Baked texture failed to upload (in which case since we
+		// didn't set the new baked texture, it means that they'll try
+		// and rebake it at some point in the future (after login?)),
+		// or this response to upload is out of date, in which case a
+		// current response should be on the way or already processed.
+		llwarns << "Baked upload failed" << llendl;
+	}
+
+	delete baked_upload_data;
+}
+
+//-----------------------------------------------------------------------------
+// LLViewerTexLayerSet
+// An ordered set of texture layers that get composited into a single texture.
+//-----------------------------------------------------------------------------
+
+LLViewerTexLayerSet::LLViewerTexLayerSet(LLAvatarAppearance* const appearance) :
+	LLTexLayerSet(appearance),
+	mUpdatesEnabled( FALSE )
+{
+}
+
+// virtual
+LLViewerTexLayerSet::~LLViewerTexLayerSet()
+{
+}
+
+// Returns TRUE if at least one packet of data has been received for each of the textures that this layerset depends on.
+BOOL LLViewerTexLayerSet::isLocalTextureDataAvailable() const
+{
+	if (!mAvatarAppearance->isSelf()) return FALSE;
+	return getAvatar()->isLocalTextureDataAvailable(this);
+}
+
+
+// Returns TRUE if all of the data for the textures that this layerset depends on have arrived.
+BOOL LLViewerTexLayerSet::isLocalTextureDataFinal() const
+{
+	if (!mAvatarAppearance->isSelf()) return FALSE;
+	return getAvatar()->isLocalTextureDataFinal(this);
+}
+
+// virtual
+void LLViewerTexLayerSet::requestUpdate()
+{
+	if( mUpdatesEnabled )
+	{
+		createComposite();
+		getViewerComposite()->requestUpdate(); 
+	}
+}
+
+void LLViewerTexLayerSet::requestUpload()
+{
+	createComposite();
+	getViewerComposite()->requestUpload();
+}
+
+void LLViewerTexLayerSet::cancelUpload()
+{
+	if(mComposite)
+	{
+		getViewerComposite()->cancelUpload();
+	}
+}
+
+void LLViewerTexLayerSet::updateComposite()
+{
+	createComposite();
+	getViewerComposite()->requestUpdateImmediate();
+}
+
+// virtual
+void LLViewerTexLayerSet::createComposite()
+{
+	if(!mComposite)
+	{
+		S32 width = mInfo->getWidth();
+		S32 height = mInfo->getHeight();
+		// Composite other avatars at reduced resolution
+		if( !mAvatarAppearance->isSelf() )
+		{
+			llerrs << "composites should not be created for non-self avatars!" << llendl;
+		}
+		mComposite = new LLViewerTexLayerSetBuffer( this, width, height );
+	}
+}
+
+void LLViewerTexLayerSet::setUpdatesEnabled( BOOL b )
+{
+	mUpdatesEnabled = b; 
+}
+
+LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar()
+{
+	return dynamic_cast<LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+const LLVOAvatarSelf* LLViewerTexLayerSet::getAvatar() const
+{
+	return dynamic_cast<const LLVOAvatarSelf*> (mAvatarAppearance);
+}
+
+LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite()
+{
+	return dynamic_cast<LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+const LLViewerTexLayerSetBuffer* LLViewerTexLayerSet::getViewerComposite() const
+{
+	return dynamic_cast<const LLViewerTexLayerSetBuffer*> (getComposite());
+}
+
+
+const std::string LLViewerTexLayerSetBuffer::dumpTextureInfo() const
+{
+	if (!isAgentAvatarValid()) return "";
+
+	const BOOL is_high_res = !mNeedsUpload;
+	const U32 num_low_res = mNumLowresUploads;
+	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
+	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(getViewerTexLayerSet());
+
+	std::string status 				= "CREATING ";
+	if (!uploadNeeded()) status 	= "DONE     ";
+	if (uploadInProgress()) status 	= "UPLOADING";
+
+	std::string text = llformat("[%s] [HiRes:%d LoRes:%d] [Elapsed:%d] %s",
+								status.c_str(),
+								is_high_res, num_low_res,
+								upload_time, 
+								local_texture_info.c_str());
+	return text;
+}
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
new file mode 100644
index 0000000000000000000000000000000000000000..959c883da86d9789427e18b89e6d3e5068545749
--- /dev/null
+++ b/indra/newview/llviewertexlayer.h
@@ -0,0 +1,180 @@
+/** 
+ * @file llviewertexlayer.h
+ * @brief Viewer Texture layer classes. Used for avatars.
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWER_TEXLAYER_H
+#define LL_VIEWER_TEXLAYER_H
+
+#include "lldynamictexture.h"
+#include "llextendedstatus.h"
+#include "lltexlayer.h"
+
+class LLVOAvatarSelf;
+class LLViewerTexLayerSetBuffer;
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSet
+//
+// An ordered set of texture layers that gets composited into a single texture.
+// Only exists for llavatarappearanceself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSet : public LLTexLayerSet
+{
+public:
+	LLViewerTexLayerSet(LLAvatarAppearance* const appearance);
+	virtual ~LLViewerTexLayerSet();
+
+	/*virtual*/void				requestUpdate();
+	void						requestUpload();
+	void						cancelUpload();
+	BOOL						isLocalTextureDataAvailable() const;
+	BOOL						isLocalTextureDataFinal() const;
+	void						updateComposite();
+	/*virtual*/void				createComposite();
+	void						setUpdatesEnabled(BOOL b);
+	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
+
+	LLVOAvatarSelf*				getAvatar();
+	const LLVOAvatarSelf*		getAvatar()	const;
+	LLViewerTexLayerSetBuffer*	getViewerComposite();
+	const LLViewerTexLayerSetBuffer*	getViewerComposite() const;
+
+private:
+	BOOL						mUpdatesEnabled;
+
+};
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLViewerTexLayerSetBuffer
+//
+// The composite image that a LLViewerTexLayerSet writes to.  Each LLViewerTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+class LLViewerTexLayerSetBuffer : public LLTexLayerSetBuffer, public LLViewerDynamicTexture
+{
+	LOG_CLASS(LLViewerTexLayerSetBuffer);
+
+public:
+	LLViewerTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
+	virtual ~LLViewerTexLayerSetBuffer();
+
+public:
+	/*virtual*/ S8          getType() const;
+	BOOL					isInitialized(void) const;
+	static void				dumpTotalByteCount();
+	const std::string		dumpTextureInfo() const;
+	virtual void 			restoreGLTexture();
+	virtual void 			destroyGLTexture();
+private:
+	LLViewerTexLayerSet*	getViewerTexLayerSet() 
+		{ return dynamic_cast<LLViewerTexLayerSet*> (mTexLayerSet); }
+	const LLViewerTexLayerSet*	getViewerTexLayerSet() const
+		{ return dynamic_cast<const LLViewerTexLayerSet*> (mTexLayerSet); }
+	static S32				sGLByteCount;
+
+	//--------------------------------------------------------------------
+	// Tex Layer Render
+	//--------------------------------------------------------------------
+	virtual void			preRenderTexLayerSet();
+	virtual void			midRenderTexLayerSet(BOOL success);
+	virtual void			postRenderTexLayerSet(BOOL success);
+	virtual S32				getCompositeOriginX() const { return getOriginX(); }
+	virtual S32				getCompositeOriginY() const { return getOriginY(); }
+	virtual S32				getCompositeWidth() const { return getFullWidth(); }
+	virtual S32				getCompositeHeight() const { return getFullHeight(); }
+
+	//--------------------------------------------------------------------
+	// Dynamic Texture Interface
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/ BOOL		needsRender();
+protected:
+	// Pass these along for tex layer rendering.
+	virtual void			preRender(BOOL clear_depth) { preRenderTexLayerSet(); }
+	virtual void			postRender(BOOL success) { postRenderTexLayerSet(success); }
+	virtual BOOL			render() { return renderTexLayerSet(); }
+	
+	//--------------------------------------------------------------------
+	// Uploads
+	//--------------------------------------------------------------------
+public:
+	void					requestUpload();
+	void					cancelUpload();
+	BOOL					uploadNeeded() const; 			// We need to upload a new texture
+	BOOL					uploadInProgress() const; 		// We have started uploading a new texture and are awaiting the result
+	BOOL					uploadPending() const; 			// We are expecting a new texture to be uploaded at some point
+	static void				onTextureUploadComplete(const LLUUID& uuid,
+													void* userdata,
+													S32 result, LLExtStat ext_status);
+protected:
+	BOOL					isReadyToUpload() const;
+	void					doUpload(); 					// Does a read back and upload.
+	void					conditionalRestartUploadTimer();
+private:
+	BOOL					mNeedsUpload; 					// Whether we need to send our baked textures to the server
+	U32						mNumLowresUploads; 				// Number of times we've sent a lowres version of our baked textures to the server
+	BOOL					mUploadPending; 				// Whether we have received back the new baked textures
+	LLUUID					mUploadID; 						// The current upload process (null if none).
+	LLFrameTimer    		mNeedsUploadTimer; 				// Tracks time since upload was requested and performed.
+	S32						mUploadFailCount;				// Number of consecutive upload failures
+	LLFrameTimer    		mUploadRetryTimer; 				// Tracks time since last upload failure.
+
+	//--------------------------------------------------------------------
+	// Updates
+	//--------------------------------------------------------------------
+public:
+	void					requestUpdate();
+	BOOL					requestUpdateImmediate();
+protected:
+	BOOL					isReadyToUpdate() const;
+	void					doUpdate();
+	void					restartUpdateTimer();
+private:
+	BOOL					mNeedsUpdate; 					// Whether we need to locally update our baked textures
+	U32						mNumLowresUpdates; 				// Number of times we've locally updated with lowres version of our baked textures
+	LLFrameTimer    		mNeedsUpdateTimer; 				// Tracks time since update was requested and performed.
+};
+
+
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLBakedUploadData
+//
+// Used by LLTexLayerSetBuffer for a callback.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LLBakedUploadData
+{
+	LLBakedUploadData(const LLVOAvatarSelf* avatar,
+					  LLViewerTexLayerSet* layerset, 
+					  const LLUUID& id,
+					  bool highest_res);
+	~LLBakedUploadData() {}
+	const LLUUID				mID;
+	const LLVOAvatarSelf*		mAvatar; // note: backlink only; don't LLPointer 
+	LLViewerTexLayerSet*		mTexLayerSet;
+   	const U64					mStartTime;	// for measuring baked texture upload time
+   	const bool					mIsHighestRes; // whether this is a "final" bake, or intermediate low res
+};
+
+#endif  // LL_VIEWER_TEXLAYER_H
+
diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp
index 122d8f4a961e46fbb0091822ee8feccc673ddba9..8036a4e2585996cbbf934b820d73bd40052b65c1 100644
--- a/indra/newview/llviewertexteditor.cpp
+++ b/indra/newview/llviewertexteditor.cpp
@@ -1052,8 +1052,6 @@ void LLViewerTextEditor::findEmbeddedItemSegments(S32 start, S32 end)
 {
 	LLWString text = getWText();
 
-	LLColor4 text_color = ( mReadOnly ? mReadOnlyFgColor.get() : mFgColor.get()  );
-
 	// Start with i just after the first embedded item
 	for(S32 idx = start; idx < end; idx++ )
 	{
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 08fcb60d035e628b7705fc11a820583deb813e2d..eb6c453e765d74bbcc984d12006fc5587be1aa10 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -58,6 +58,7 @@
 #include "lltextureatlas.h"
 #include "lltextureatlasmanager.h"
 #include "lltextureentry.h"
+#include "lltexturemanagerbridge.h"
 #include "llmediaentry.h"
 #include "llvovolume.h"
 #include "llviewermedia.h"
@@ -231,7 +232,7 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(BOOL usemipma
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
@@ -241,14 +242,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLUUID&
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
 LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const LLImageRaw* raw, BOOL usemipmaps) 
 {
 	LLPointer<LLViewerTexture> tex = new LLViewerTexture(raw, usemipmaps) ;
-	tex->setCategory(LLViewerTexture::LOCAL) ;
+	tex->setCategory(LLGLTexture::LOCAL) ;
 	return tex ;
 }
 LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex) 
@@ -257,13 +258,14 @@ LLPointer<LLViewerTexture> LLViewerTextureManager::getLocalTexture(const U32 wid
 	if(generate_gl_tex)
 	{
 		tex->generateGLTexture() ;
-		tex->setCategory(LLViewerTexture::LOCAL) ;
+		tex->setCategory(LLGLTexture::LOCAL) ;
 	}
 	return tex ;
 }
 
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
 	                                               const LLUUID &image_id,											       
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -271,11 +273,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(
 												   LLGLenum primary_format,
 												   LLHost request_from_host)
 {
-	return gTextureList.getImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+	return gTextureList.getImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
 }
 	
 LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
-	                                               const std::string& filename,												   
+	                                               const std::string& filename,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -283,11 +286,12 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromFile(
 												   LLGLenum primary_format, 
 												   const LLUUID& force_id)
 {
-	return gTextureList.getImageFromFile(filename, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+	return gTextureList.getImageFromFile(filename, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
 }
 
 //static 
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,									 
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string& url,
+									 FTType f_type,
 									 BOOL usemipmaps,
 									 LLViewerTexture::EBoostLevel boost_priority,
 									 S8 texture_type,
@@ -296,14 +300,34 @@ LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const s
 									 const LLUUID& force_id
 									 )
 {
-	return gTextureList.getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
+	return gTextureList.getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id) ;
 }
 
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) 
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) 
 {
-	return gTextureList.getImageFromHost(image_id, host) ;
+	return gTextureList.getImageFromHost(image_id, f_type, host) ;
 }
 
+// Create a bridge to the viewer texture manager.
+class LLViewerTextureManagerBridge : public LLTextureManagerBridge
+{
+	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(BOOL usemipmaps = TRUE, BOOL generate_gl_tex = TRUE)
+	{
+		return LLViewerTextureManager::getLocalTexture(usemipmaps, generate_gl_tex);
+	}
+
+	/*virtual*/ LLPointer<LLGLTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE)
+	{
+		return LLViewerTextureManager::getLocalTexture(width, height, components, usemipmaps, generate_gl_tex);
+	}
+
+	/*virtual*/ LLGLTexture* getFetchedTexture(const LLUUID &image_id)
+	{
+		return LLViewerTextureManager::getFetchedTexture(image_id);
+	}
+};
+
+
 void LLViewerTextureManager::init()
 {
 	{
@@ -349,12 +373,12 @@ void LLViewerTextureManager::init()
 	imagep->setCachedRawImage(0, image_raw) ;
 	image_raw = NULL;
 #else
- 	LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+ 	LLViewerFetchedTexture::sDefaultImagep = LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 #endif
 	LLViewerFetchedTexture::sDefaultImagep->dontDiscard();
-	LLViewerFetchedTexture::sDefaultImagep->setCategory(LLViewerTexture::OTHER) ;
+	LLViewerFetchedTexture::sDefaultImagep->setCategory(LLGLTexture::OTHER) ;
 
- 	LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, TRUE, LLViewerTexture::BOOST_UI);
+ 	LLViewerFetchedTexture::sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	LLViewerFetchedTexture::sSmokeImagep->setNoDelete() ;
 
 	image_raw = new LLImageRaw(32,32,3);
@@ -373,6 +397,9 @@ void LLViewerTextureManager::init()
 	LLViewerTexture::sCheckerBoardImagep = LLViewerTextureManager::getLocalTexture(image_raw.get(), TRUE);
 
 	LLViewerTexture::initClass() ;
+	
+	// Create a texture manager bridge.
+	gTextureManagerBridgep = new LLViewerTextureManagerBridge;
 
 	if (LLMetricPerformanceTesterBasic::isMetricLogRequested(sTesterName) && !LLMetricPerformanceTesterBasic::getTester(sTesterName))
 	{
@@ -389,6 +416,7 @@ void LLViewerTextureManager::cleanup()
 {
 	stop_glerror();
 
+	delete gTextureManagerBridgep;
 	LLImageGL::sDefaultGLTexture = NULL ;
 	LLViewerTexture::sNullImagep = NULL;
 	LLViewerTexture::sBlackImagep = NULL;
@@ -416,25 +444,6 @@ void LLViewerTexture::initClass()
 	}
 }
 
-// static
-S32 LLViewerTexture::getTotalNumOfCategories() 
-{
-	return MAX_GL_IMAGE_CATEGORY - (BOOST_HIGH - BOOST_SCULPTED) + 2 ;
-}
-
-// static
-//index starts from zero.
-S32 LLViewerTexture::getIndexFromCategory(S32 category) 
-{
-	return (category < BOOST_HIGH) ? category : category - (BOOST_HIGH - BOOST_SCULPTED) + 1 ;
-}
-
-//static 
-S32 LLViewerTexture::getCategoryFromIndex(S32 index)
-{
-	return (index < BOOST_HIGH) ? index : index + (BOOST_HIGH - BOOST_SCULPTED) - 1 ;
-}
-
 // tuning params
 const F32 discard_bias_delta = .25f;
 const F32 discard_delta_time = 0.5f;
@@ -571,70 +580,54 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 //-------------------------------------------------------------------------------------------
 const U32 LLViewerTexture::sCurrentFileVersion = 1;
 
-LLViewerTexture::LLViewerTexture(BOOL usemipmaps)
+LLViewerTexture::LLViewerTexture(BOOL usemipmaps) :
+	LLGLTexture(usemipmaps)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
 
 	mID.generate();
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps)
-	: mID(id)
+LLViewerTexture::LLViewerTexture(const LLUUID& id, BOOL usemipmaps) :
+	LLGLTexture(usemipmaps),
+	mID(id)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
 	
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps) 
+LLViewerTexture::LLViewerTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps)  :
+	LLGLTexture(width, height, components, usemipmaps)
 {
 	init(true);
 
-	mFullWidth = width ;
-	mFullHeight = height ;
-	mUseMipMaps = usemipmaps ;
-	mComponents = components ;
-	setTexelsPerImage();
-
 	mID.generate();
 	sImageCount++;
 }
 
-LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps)	
+LLViewerTexture::LLViewerTexture(const LLImageRaw* raw, BOOL usemipmaps) :
+	LLGLTexture(raw, usemipmaps)
 {
 	init(true);
-	mUseMipMaps = usemipmaps ;
-	mGLTexturep = new LLImageGL(raw, usemipmaps) ;
 	
-	// Create an empty image of the specified size and width
 	mID.generate();
 	sImageCount++;
 }
 
 LLViewerTexture::~LLViewerTexture()
 {
+	// LL_DEBUGS("Avatar") << mID << llendl;
 	cleanup();
 	sImageCount--;
 }
 
+// virtual
 void LLViewerTexture::init(bool firstinit)
 {
-	mBoostLevel = LLViewerTexture::BOOST_NONE;
 	mSelectedTime = 0.f;
-
-	mFullWidth = 0;
-	mFullHeight = 0;
-	mTexelsPerImage = 0 ;
-	mUseMipMaps = FALSE ;
-	mComponents = 0 ;
-
-	mTextureState = NO_DELETE ;
-	mDontDiscard = FALSE;
 	mMaxVirtualSize = 0.f;
-	mNeedsGLTexture = FALSE ;
 	mMaxVirtualSizeResetInterval = 1;
 	mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval ;
 	mAdditionalDecodePriority = 0.f ;	
@@ -655,19 +648,12 @@ void LLViewerTexture::cleanup()
 {
 	mFaceList.clear() ;
 	mVolumeList.clear();
-	if(mGLTexturep)
-	{
-		mGLTexturep->cleanup();
-	}
 }
 
 // virtual
 void LLViewerTexture::dump()
 {
-	if(mGLTexturep)
-	{
-		mGLTexturep->dump();
-	}
+	LLGLTexture::dump();
 
 	llinfos << "LLViewerTexture"
 			<< " mID " << mID
@@ -690,10 +676,8 @@ void LLViewerTexture::setBoostLevel(S32 level)
 	{
 		mSelectedTime = gFrameTimeSeconds;
 	}
-
 }
 
-
 bool LLViewerTexture::bindDefaultImage(S32 stage) 
 {
 	if (stage < 0) return false;
@@ -886,294 +870,18 @@ void LLViewerTexture::reorganizeVolumeList()
 	mVolumeList.erase(mVolumeList.begin() + mNumVolumes, mVolumeList.end());
 }
 
-
-
 //virtual
 void LLViewerTexture::switchToCachedImage()
 {
 	//nothing here.
 }
 
-void LLViewerTexture::forceActive()
-{
-	mTextureState = ACTIVE ; 
-}
-
-void LLViewerTexture::setActive() 
-{ 
-	if(mTextureState != NO_DELETE)
-	{
-		mTextureState = ACTIVE ; 
-	}
-}
-
-//set the texture to stay in memory
-void LLViewerTexture::setNoDelete() 
-{ 
-	mTextureState = NO_DELETE ;
-}
-
-void LLViewerTexture::generateGLTexture() 
-{	
-	if(mGLTexturep.isNull())
-	{
-		mGLTexturep = new LLImageGL(mFullWidth, mFullHeight, mComponents, mUseMipMaps) ;
-	}
-}
-
-LLImageGL* LLViewerTexture::getGLTexture() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep ;
-}
-
-BOOL LLViewerTexture::createGLTexture() 
-{
-	if(mGLTexturep.isNull())
-	{
-		generateGLTexture() ;
-	}
-
-	return mGLTexturep->createGLTexture() ;
-}
-
-BOOL LLViewerTexture::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename, BOOL to_create, S32 category)
-{
-	llassert(mGLTexturep.notNull()) ;	
-
-	BOOL ret = mGLTexturep->createGLTexture(discard_level, imageraw, usename, to_create, category) ;
-
-	if(ret)
-	{
-		mFullWidth = mGLTexturep->getCurrentWidth() ;
-		mFullHeight = mGLTexturep->getCurrentHeight() ; 
-		mComponents = mGLTexturep->getComponents() ;	
-		setTexelsPerImage();
-	}
-
-	return ret ;
-}
-
 //virtual
 void LLViewerTexture::setCachedRawImage(S32 discard_level, LLImageRaw* imageraw)
 {
 	//nothing here.
 }
 
-void LLViewerTexture::setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format, BOOL swap_bytes)
-{
-	llassert(mGLTexturep.notNull()) ;
-	
-	mGLTexturep->setExplicitFormat(internal_format, primary_format, type_format, swap_bytes) ;
-}
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode mode)
-{
-	llassert(mGLTexturep.notNull()) ;
-	mGLTexturep->setAddressMode(mode) ;
-}
-void LLViewerTexture::setFilteringOption(LLTexUnit::eTextureFilterOptions option)
-{
-	llassert(mGLTexturep.notNull()) ;
-	mGLTexturep->setFilteringOption(option) ;
-}
-
-//virtual
-S32	LLViewerTexture::getWidth(S32 discard_level) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getWidth(discard_level) ;
-}
-
-//virtual
-S32	LLViewerTexture::getHeight(S32 discard_level) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getHeight(discard_level) ;
-}
-
-S32 LLViewerTexture::getMaxDiscardLevel() const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getMaxDiscardLevel() ;
-}
-S32 LLViewerTexture::getDiscardLevel() const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getDiscardLevel() ;
-}
-S8  LLViewerTexture::getComponents() const 
-{ 
-	llassert(mGLTexturep.notNull()) ;
-	
-	return mGLTexturep->getComponents() ;
-}
-
-LLGLuint LLViewerTexture::getTexName() const 
-{ 
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexName() ; 
-}
-
-BOOL LLViewerTexture::hasGLTexture() const 
-{
-	if(mGLTexturep.notNull())
-	{
-		return mGLTexturep->getHasGLTexture() ;
-	}
-	return FALSE ;
-}
-
-BOOL LLViewerTexture::getBoundRecently() const
-{
-	if(mGLTexturep.notNull())
-	{
-		return mGLTexturep->getBoundRecently() ;
-	}
-	return FALSE ;
-}
-
-LLTexUnit::eTextureType LLViewerTexture::getTarget(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-	return mGLTexturep->getTarget() ;
-}
-
-BOOL LLViewerTexture::setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->setSubImage(imageraw, x_pos, y_pos, width, height) ;
-}
-
-BOOL LLViewerTexture::setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->setSubImage(datap, data_width, data_height, x_pos, y_pos, width, height) ;
-}
-
-void LLViewerTexture::setGLTextureCreated (bool initialized)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	mGLTexturep->setGLTextureCreated (initialized) ;
-}
-
-void  LLViewerTexture::setCategory(S32 category) 
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	mGLTexturep->setCategory(category) ;
-}
-
-LLTexUnit::eTextureAddressMode LLViewerTexture::getAddressMode(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getAddressMode() ;
-}
-
-S32 LLViewerTexture::getTextureMemory() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->mTextureMemory ;
-}
-
-LLGLenum LLViewerTexture::getPrimaryFormat() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getPrimaryFormat() ;
-}
-
-BOOL LLViewerTexture::getIsAlphaMask() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getIsAlphaMask() ;
-}
-
-BOOL LLViewerTexture::getMask(const LLVector2 &tc)
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getMask(tc) ;
-}
-
-F32 LLViewerTexture::getTimePassedSinceLastBound()
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTimePassedSinceLastBound() ;
-}
-BOOL LLViewerTexture::getMissed() const 
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getMissed() ;
-}
-
-BOOL LLViewerTexture::isJustBound() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->isJustBound() ;
-}
-
-void LLViewerTexture::forceUpdateBindStats(void) const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->forceUpdateBindStats() ;
-}
-
-U32 LLViewerTexture::getTexelsInAtlas() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexelsInAtlas() ;
-}
-
-U32 LLViewerTexture::getTexelsInGLTexture() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getTexelsInGLTexture() ;
-}
-
-BOOL LLViewerTexture::isGLTextureCreated() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->isGLTextureCreated() ;
-}
-
-S32  LLViewerTexture::getDiscardLevelInAtlas() const
-{
-	llassert(mGLTexturep.notNull()) ;
-
-	return mGLTexturep->getDiscardLevelInAtlas() ;
-}
-
-void LLViewerTexture::destroyGLTexture() 
-{
-	if(mGLTexturep.notNull() && mGLTexturep->getHasGLTexture())
-	{
-		mGLTexturep->destroyGLTexture() ;
-		mTextureState = DELETED ;	
-	}	
-}
-
-void LLViewerTexture::setTexelsPerImage()
-{
-	S32 fullwidth = llmin(mFullWidth,(S32)MAX_IMAGE_SIZE_DEFAULT);
-	S32 fullheight = llmin(mFullHeight,(S32)MAX_IMAGE_SIZE_DEFAULT);
-	mTexelsPerImage = (F32)fullwidth * fullheight;
-}
-
 BOOL LLViewerTexture::isLargeImage()
 {
 	return  (S32)mTexelsPerImage > LLViewerTexture::sMinLargeImageSize ;
@@ -1197,25 +905,32 @@ void LLViewerTexture::updateBindStatsForTester()
 //start of LLViewerFetchedTexture
 //----------------------------------------------------------------------------------------------
 
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
 	: LLViewerTexture(id, usemipmaps),
 	mTargetHost(host)
 {
 	init(TRUE) ;
+	mFTType = f_type;
+	if (mFTType == FTT_HOST_BAKE)
+	{
+		mCanUseHTTP = false;
+	}
 	generateGLTexture() ;
 }
 	
-LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps)
 	: LLViewerTexture(raw, usemipmaps)
 {
 	init(TRUE) ;
+	mFTType = f_type;
 }
 	
-LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
+LLViewerFetchedTexture::LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
 	: LLViewerTexture(id, usemipmaps),
 	mUrl(url)
 {
 	init(TRUE) ;
+	mFTType = f_type;
 	generateGLTexture() ;
 }
 
@@ -1281,6 +996,8 @@ void LLViewerFetchedTexture::init(bool firstinit)
 	mLastCallBackActiveTime = 0.f;
 
 	mInDebug = FALSE;
+
+	mFTType = FTT_UNKNOWN;
 }
 
 LLViewerFetchedTexture::~LLViewerFetchedTexture()
@@ -1301,6 +1018,11 @@ S8 LLViewerFetchedTexture::getType() const
 	return LLViewerTexture::FETCHED_TEXTURE ;
 }
 
+FTType LLViewerFetchedTexture::getFTType() const
+{
+	return mFTType;
+}
+
 void LLViewerFetchedTexture::cleanup()
 {
 	for(callback_list_t::iterator iter = mLoadedCallbackList.begin();
@@ -1345,6 +1067,7 @@ void LLViewerFetchedTexture::loadFromFastCache()
 		{ 
 			//discard all oversized textures.
 			destroyRawImage();
+			llwarns << "oversized, setting as missing" << llendl;
 			setIsMissingAsset();
 			mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
 		}
@@ -1454,7 +1177,8 @@ void LLViewerFetchedTexture::destroyTexture()
 	{
 		return ;
 	}
-	
+
+	//LL_DEBUGS("Avatar") << mID << llendl;
 	destroyGLTexture() ;
 	mFullyLoaded = FALSE ;
 }
@@ -1610,6 +1334,7 @@ BOOL LLViewerFetchedTexture::createTexture(S32 usename/*= 0*/)
 		// An inappropriately-sized image was uploaded (through a non standard client)
 		// We treat these images as missing assets which causes them to
 		// be renderd as 'missing image' and to stop requesting data
+		llwarns << "!size_ok, setting as missing" << llendl;
 		setIsMissingAsset();
 		destroyRawImage();
 		return FALSE;
@@ -1757,7 +1482,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 		// Don't decode anything we don't need
 		priority = -4.0f;
 	}
-	else if ((mBoostLevel == LLViewerTexture::BOOST_UI || mBoostLevel == LLViewerTexture::BOOST_ICON) && !have_all_data)
+	else if ((mBoostLevel == LLGLTexture::BOOST_UI || mBoostLevel == LLGLTexture::BOOST_ICON) && !have_all_data)
 	{
 		priority = 1.f;
 	}
@@ -2068,6 +1793,7 @@ bool LLViewerFetchedTexture::updateFetch()
 				{ 
 					//discard all oversized textures.
 					destroyRawImage();
+					llwarns << "oversize, setting as missing" << llendl;
 					setIsMissingAsset();
 					mRawDiscardLevel = INVALID_DISCARD_LEVEL ;
 					mIsFetching = FALSE ;
@@ -2097,6 +1823,10 @@ bool LLViewerFetchedTexture::updateFetch()
 				// We finished but received no data
 				if (current_discard < 0)
 				{
+					llwarns << "!mIsFetching, setting as missing, decode_priority " << decode_priority
+							<< " mRawDiscardLevel " << mRawDiscardLevel
+							<< " current_discard " << current_discard
+							<< llendl;
 					setIsMissingAsset();
 					desired_discard = -1;
 				}
@@ -2164,7 +1894,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		// Load the texture progressively: we try not to rush to the desired discard too fast.
 		// If the camera is not moving, we do not tweak the discard level notch by notch but go to the desired discard with larger boosted steps
 		// This mitigates the "textures stay blurry" problem when loading while not killing the texture memory while moving around
-		S32 delta_level = (mBoostLevel > LLViewerTexture::BOOST_NONE) ? 2 : 1 ; 
+		S32 delta_level = (mBoostLevel > LLGLTexture::BOOST_NONE) ? 2 : 1 ; 
 		if (current_discard < 0)
 		{
 			desired_discard = llmax(desired_discard, getMaxDiscardLevel() - delta_level);
@@ -2212,7 +1942,7 @@ bool LLViewerFetchedTexture::updateFetch()
 		
 		// bypass texturefetch directly by pulling from LLTextureCache
 		bool fetch_request_created = false;
-		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mUrl, getID(),getTargetHost(), decode_priority,
+		fetch_request_created = LLAppViewer::getTextureFetch()->createRequest(mFTType, mUrl, getID(), getTargetHost(), decode_priority,
 																			  w, h, c, desired_discard, needsAux(), mCanUseHTTP);
 		
 		if (fetch_request_created)
@@ -2229,11 +1959,13 @@ bool LLViewerFetchedTexture::updateFetch()
 	}
 	else if (mHasFetcher && !mIsFetching)
 	{
-		// Only delete requests that haven't receeived any network data for a while
+		// Only delete requests that haven't received any network data
+		// for a while.  Note - this is the normal mechanism for
+		// deleting requests, not just a place to handle timeouts.
 		const F32 FETCH_IDLE_TIME = 5.f;
 		if (mLastPacketTimer.getElapsedTimeF32() > FETCH_IDLE_TIME)
 		{
-// 			llinfos << "Deleting request: " << getID() << " Discard: " << current_discard << " <= min:" << mMinDiscardLevel << " or priority == 0: " << decode_priority << llendl;
+ 			LL_DEBUGS("Texture") << "exceeded idle time " << FETCH_IDLE_TIME << ", deleting request: " << getID() << llendl;
 			LLAppViewer::getTextureFetch()->deleteRequest(getID(), true);
 			mHasFetcher = FALSE;
 		}
@@ -2281,8 +2013,10 @@ void LLViewerFetchedTexture::setIsMissingAsset()
 	}
 	else
 	{
-		//it is normal no map tile on an empty region.
-		//llwarns << mUrl << ": Marking image as missing" << llendl;
+		// This may or may not be an error - it is normal to have no
+		// map tile on an empty region, but bad if we're failing on a
+		// server bake texture.
+		llwarns << mUrl << ": Marking image as missing" << llendl;
 	}
 	if (mHasFetcher)
 	{
@@ -2415,7 +2149,7 @@ void LLViewerFetchedTexture::deleteCallbackEntry(const LLLoadedCallbackEntry::so
 			destroySavedRawImage() ;
 		}
 	}
-	else if(needsToSaveRawImage() && mBoostLevel != LLViewerTexture::BOOST_PREVIEW)
+	else if(needsToSaveRawImage() && mBoostLevel != LLGLTexture::BOOST_PREVIEW)
 	{
 		if(desired_raw_discard != INVALID_DISCARD_LEVEL)
 		{
@@ -2873,7 +2607,7 @@ void LLViewerFetchedTexture::setCachedRawImage()
 		S32 h = mRawImage->getHeight() ;
 
 		S32 max_size = MAX_CACHED_RAW_IMAGE_AREA ;
-		if(LLViewerTexture::BOOST_TERRAIN == mBoostLevel)
+		if(LLGLTexture::BOOST_TERRAIN == mBoostLevel)
 		{
 			max_size = MAX_CACHED_RAW_TERRAIN_IMAGE_AREA ;
 		}		
@@ -3197,14 +2931,14 @@ BOOL LLViewerFetchedTexture::insertToAtlas()
 //----------------------------------------------------------------------------------------------
 //start of LLViewerLODTexture
 //----------------------------------------------------------------------------------------------
-LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, const LLHost& host, BOOL usemipmaps)
-	: LLViewerFetchedTexture(id, host, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host, BOOL usemipmaps)
+	: LLViewerFetchedTexture(id, f_type, host, usemipmaps)
 {
 	init(TRUE) ;
 }
 
-LLViewerLODTexture::LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps)
-	: LLViewerFetchedTexture(url, id, usemipmaps)
+LLViewerLODTexture::LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps)
+	: LLViewerFetchedTexture(url, f_type, id, usemipmaps)
 {
 	init(TRUE) ;
 }
@@ -3246,7 +2980,7 @@ void LLViewerLODTexture::processTextureStats()
 		if (mFullWidth > MAX_IMAGE_SIZE_DEFAULT || mFullHeight > MAX_IMAGE_SIZE_DEFAULT)
 			mDesiredDiscardLevel = 1; // MAX_IMAGE_SIZE_DEFAULT = 1024 and max size ever is 2048
 	}
-	else if (mBoostLevel < LLViewerTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
+	else if (mBoostLevel < LLGLTexture::BOOST_HIGH && mMaxVirtualSize <= 10.f)
 	{
 		// If the image has not been significantly visible in a while, we don't want it
 		mDesiredDiscardLevel = llmin(mMinDesiredDiscardLevel, (S8)(MAX_DISCARD_LEVEL + 1));
@@ -3296,7 +3030,7 @@ void LLViewerLODTexture::processTextureStats()
 				mCalculatedDiscardLevel = discard_level;
 			}
 		}
-		if (mBoostLevel < LLViewerTexture::BOOST_SCULPTED)
+		if (mBoostLevel < LLGLTexture::BOOST_SCULPTED)
 		{
 			discard_level += sDesiredDiscardBias;
 			discard_level *= sDesiredDiscardScale; // scale
@@ -3322,7 +3056,7 @@ void LLViewerLODTexture::processTextureStats()
 		//
 
 		S32 current_discard = getDiscardLevel();
-		if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLViewerTexture::BOOST_SCULPTED && current_discard >= 0)
+		if (sDesiredDiscardBias > 0.0f && mBoostLevel < LLGLTexture::BOOST_SCULPTED && current_discard >= 0)
 		{
 			if(desired_discard_bias_max <= sDesiredDiscardBias && !mForceToSaveRawImage)
 			{
@@ -3465,7 +3199,7 @@ LLViewerMediaTexture::LLViewerMediaTexture(const LLUUID& id, BOOL usemipmaps, LL
 
 	setMediaImpl() ;
 
-	setCategory(LLViewerTexture::MEDIA) ;
+	setCategory(LLGLTexture::MEDIA) ;
 	
 	LLViewerTexture* tex = gTextureList.findImage(mID) ;
 	if(tex) //this media is a parcel media for tex.
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index 2e7949e9a38f84d42ef8b42feba503d09baba45e..f2e1a90713afade6a10f4ed4432648eac3c8395e 100644
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -27,7 +27,7 @@
 #ifndef LL_LLVIEWERTEXTURE_H					
 #define LL_LLVIEWERTEXTURE_H
 
-#include "lltexture.h"
+#include "llgltexture.h"
 #include "lltimer.h"
 #include "llframetimer.h"
 #include "llhost.h"
@@ -88,14 +88,9 @@ class LLLoadedCallbackEntry
 
 class LLTextureBar;
 
-class LLViewerTexture : public LLTexture
+class LLViewerTexture : public LLGLTexture
 {
 public:
-	enum
-	{
-		MAX_IMAGE_SIZE_DEFAULT = 1024,
-		INVALID_DISCARD_LEVEL = 0x7fff
-	};
 	enum
 	{
 		LOCAL_TEXTURE,		
@@ -107,43 +102,6 @@ class LLViewerTexture : public LLTexture
 		INVALID_TEXTURE_TYPE
 	};
 
-	enum EBoostLevel
-	{
-		BOOST_NONE 			= 0,
-		BOOST_AVATAR_BAKED	,
-		BOOST_AVATAR		,
-		BOOST_CLOUDS		,
-		BOOST_SCULPTED      ,
-		
-		BOOST_HIGH 			= 10,
-		BOOST_BUMP          ,
-		BOOST_TERRAIN		, // has to be high priority for minimap / low detail
-		BOOST_SELECTED		,		
-		BOOST_AVATAR_BAKED_SELF	,
-		BOOST_AVATAR_SELF	, // needed for baking avatar
-		BOOST_SUPER_HIGH    , //textures higher than this need to be downloaded at the required resolution without delay.
-		BOOST_HUD			,
-		BOOST_ICON			,
-		BOOST_UI			,
-		BOOST_PREVIEW		,
-		BOOST_MAP			,
-		BOOST_MAP_VISIBLE	,		
-		BOOST_MAX_LEVEL,
-
-		//other texture Categories
-		LOCAL = BOOST_MAX_LEVEL,
-		AVATAR_SCRATCH_TEX,
-		DYNAMIC_TEX,
-		MEDIA,
-		ATLAS,
-		OTHER,
-		MAX_GL_IMAGE_CATEGORY
-	};
-
-	static S32 getTotalNumOfCategories() ;
-	static S32 getIndexFromCategory(S32 category) ;
-	static S32 getCategoryFromIndex(S32 index) ;
-
 	typedef std::vector<LLFace*> ll_face_list_t;
 	typedef std::vector<LLVOVolume*> ll_volume_list_t;
 
@@ -168,8 +126,7 @@ class LLViewerTexture : public LLTexture
 	/*virtual*/ bool bindDefaultImage(const S32 stage = 0) ;
 	/*virtual*/ void forceImmediateUpdate() ;
 	
-	const LLUUID& getID() const { return mID; }
-	
+	/*virtual*/ const LLUUID& getID() const { return mID; }
 	void setBoostLevel(S32 level);
 	S32  getBoostLevel() { return mBoostLevel; }
 
@@ -177,13 +134,12 @@ class LLViewerTexture : public LLTexture
 	void resetTextureStats();	
 	void setMaxVirtualSizeResetInterval(S32 interval)const {mMaxVirtualSizeResetInterval = interval;}
 	void resetMaxVirtualSizeResetCounter()const {mMaxVirtualSizeResetCounter = mMaxVirtualSizeResetInterval;}
+	S32 getMaxVirtualSizeResetCounter() const { return mMaxVirtualSizeResetCounter; }
 
 	virtual F32  getMaxVirtualSize() ;
 
 	LLFrameTimer* getLastReferencedTimer() {return &mLastReferencedTimer ;}
 	
-	S32 getFullWidth() const { return mFullWidth; }
-	S32 getFullHeight() const { return mFullHeight; }	
 	/*virtual*/ void setKnownDrawSize(S32 width, S32 height);
 
 	virtual void addFace(LLFace* facep) ;
@@ -196,60 +152,8 @@ class LLViewerTexture : public LLTexture
 	S32 getNumVolumes() const;
 	const ll_volume_list_t* getVolumeList() const { return &mVolumeList; }
 
-	void generateGLTexture() ;
-	void destroyGLTexture() ;
 	
-	//---------------------------------------------------------------------------------------------
-	//functions to access LLImageGL
-	//---------------------------------------------------------------------------------------------
-	/*virtual*/S32	       getWidth(S32 discard_level = -1) const;
-	/*virtual*/S32	       getHeight(S32 discard_level = -1) const;
-	
-	BOOL       hasGLTexture() const ;
-	LLGLuint   getTexName() const ;		
-	BOOL       createGLTexture() ;
-	BOOL       createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename = 0, BOOL to_create = TRUE, S32 category = LLViewerTexture::OTHER);
 	virtual void setCachedRawImage(S32 discard_level, LLImageRaw* imageraw) ;
-
-	void       setFilteringOption(LLTexUnit::eTextureFilterOptions option);
-	void       setExplicitFormat(LLGLint internal_format, LLGLenum primary_format, LLGLenum type_format = 0, BOOL swap_bytes = FALSE);
-	void       setAddressMode(LLTexUnit::eTextureAddressMode mode);
-	BOOL       setSubImage(const LLImageRaw* imageraw, S32 x_pos, S32 y_pos, S32 width, S32 height);
-	BOOL       setSubImage(const U8* datap, S32 data_width, S32 data_height, S32 x_pos, S32 y_pos, S32 width, S32 height);
-	void       setGLTextureCreated (bool initialized);
-	void       setCategory(S32 category) ;
-
-	LLTexUnit::eTextureAddressMode getAddressMode(void) const ;
-	S32        getMaxDiscardLevel() const;
-	S32        getDiscardLevel() const;
-	S8		   getComponents() const ;		
-	BOOL       getBoundRecently() const;
-	S32        getTextureMemory() const ;
-	LLGLenum   getPrimaryFormat() const;
-	BOOL       getIsAlphaMask() const ;
-	LLTexUnit::eTextureType getTarget(void) const ;
-	BOOL       getMask(const LLVector2 &tc);
-	F32        getTimePassedSinceLastBound();
-	BOOL       getMissed() const ;
-	BOOL       isJustBound()const ;
-	void       forceUpdateBindStats(void) const;
-
-	U32        getTexelsInAtlas() const ;
-	U32        getTexelsInGLTexture() const ;
-	BOOL       isGLTextureCreated() const ;
-	S32        getDiscardLevelInAtlas() const ;
-	//---------------------------------------------------------------------------------------------
-	//end of functions to access LLImageGL
-	//---------------------------------------------------------------------------------------------
-
-	//-----------------
-	/*virtual*/ void setActive() ;
-	void forceActive() ;
-	void setNoDelete() ;
-	void dontDiscard() { mDontDiscard = 1; mTextureState = NO_DELETE; }
-	BOOL getDontDiscard() const { return mDontDiscard; }
-	//-----------------	
-	
 	BOOL isLargeImage() ;	
 	
 	void setParcelMedia(LLViewerMediaTexture* media) {mParcelMedia = media;}
@@ -262,36 +166,22 @@ class LLViewerTexture : public LLTexture
 	void init(bool firstinit) ;	
 	void reorganizeFaceList() ;
 	void reorganizeVolumeList() ;
-	void setTexelsPerImage();
 private:
 	friend class LLBumpImageList;
 	friend class LLUIImageList;
 
-	//note: do not make this function public.
-	/*virtual*/ LLImageGL* getGLTexture() const ;
 	virtual void switchToCachedImage();
 	
 	static bool isMemoryForTextureLow() ;
 protected:
 	LLUUID mID;
-	S32 mBoostLevel;				// enum describing priority level
 	F32 mSelectedTime;				// time texture was last selected
-	S32 mFullWidth;
-	S32 mFullHeight;
-	BOOL  mUseMipMaps ;
-	S8  mComponents;
-	F32 mTexelsPerImage;			// Texels per image.
-	mutable S8  mNeedsGLTexture;
 	mutable F32 mMaxVirtualSize;	// The largest virtual size of the image, in pixels - how much data to we need?	
 	mutable S32  mMaxVirtualSizeResetCounter ;
 	mutable S32  mMaxVirtualSizeResetInterval;
 	mutable F32 mAdditionalDecodePriority;  // priority add to mDecodePriority.
 	LLFrameTimer mLastReferencedTimer;	
 
-	//GL texture
-	LLPointer<LLImageGL> mGLTexturep ;
-	S8 mDontDiscard;			// Keep full res version of this image (for UI, etc)
-
 	ll_face_list_t    mFaceList ; //reverse pointer pointing to the faces using this image as texture
 	U32               mNumFaces ;
 	LLFrameTimer      mLastFaceListUpdateTimer ;
@@ -303,17 +193,6 @@ class LLViewerTexture : public LLTexture
 	//do not use LLPointer here.
 	LLViewerMediaTexture* mParcelMedia ;
 
-protected:
-	typedef enum 
-	{
-		DELETED = 0,         //removed from memory
-		DELETION_CANDIDATE,  //ready to be removed from memory
-		INACTIVE,            //not be used for the last certain period (i.e., 30 seconds).
-		ACTIVE,              //just being used, can become inactive if not being used for a certain time (10 seconds).
-		NO_DELETE = 99       //stay in memory, can not be removed.
-	} LLGLTextureState;
-	LLGLTextureState  mTextureState ;
-
 	static F32 sTexelPixelRatio;
 public:
 	static const U32 sCurrentFileVersion;	
@@ -353,6 +232,16 @@ class LLViewerTexture : public LLTexture
 };
 
 
+enum FTType
+{
+	FTT_UNKNOWN = -1,
+	FTT_DEFAULT = 0, // standard texture fetched by id.
+	FTT_SERVER_BAKE, // texture produced by appearance service and fetched from there.
+	FTT_HOST_BAKE, // old-style baked texture uploaded by viewer and fetched from avatar's host.
+	FTT_MAP_TILE, // tiles are fetched from map server directly.
+	FTT_LOCAL_FILE // fetch directly from a local file.
+};
+
 //
 //textures are managed in gTextureList.
 //raw image data is fetched from remote or local cache
@@ -366,9 +255,9 @@ class LLViewerFetchedTexture : public LLViewerTexture
 protected:
 	/*virtual*/ ~LLViewerFetchedTexture();
 public:
-	LLViewerFetchedTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
-	LLViewerFetchedTexture(const LLImageRaw* raw, BOOL usemipmaps);
-	LLViewerFetchedTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+	LLViewerFetchedTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+	LLViewerFetchedTexture(const LLImageRaw* raw, FTType f_type, BOOL usemipmaps);
+	LLViewerFetchedTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 
 public:
 	static F32 maxDecodePriority();
@@ -393,6 +282,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 
 public:
 	/*virtual*/ S8 getType() const ;
+	FTType getFTType() const;
 	/*virtual*/ void forceImmediateUpdate() ;
 	/*virtual*/ void dump() ;
 
@@ -428,6 +318,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	// the priority list, and cause horrible things to happen.
 	void setDecodePriority(F32 priority = -1.0f);
 	F32 getDecodePriority() const { return mDecodePriority; };
+	F32 getAdditionalDecodePriority() const { return mAdditionalDecodePriority; };
 
 	void setAdditionalDecodePriority(F32 priority) ;
 	
@@ -509,7 +400,7 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S32 getCurrentDiscardLevelForFetching() ;
 
 private:
-	void init(bool firstinit) ;
+	void init(bool firstinit) ;	
 	void cleanup() ;
 
 	void saveRawImage() ;
@@ -556,7 +447,8 @@ class LLViewerFetchedTexture : public LLViewerTexture
 	S8  mHasFetcher;				// We've made a fecth request
 	S8  mIsFetching;				// Fetch request is active
 	bool mCanUseHTTP ;              //This texture can be fetched through http if true.
-	
+
+	FTType mFTType; // What category of image is this - map tile, server bake, etc?
 	mutable S8 mIsMissingAsset;		// True if we know that there is no image asset with this image id in the database.		
 
 	typedef std::list<LLLoadedCallbackEntry*> callback_list_t;
@@ -616,8 +508,8 @@ class LLViewerLODTexture : public LLViewerFetchedTexture
 	/*virtual*/ ~LLViewerLODTexture(){}
 
 public:
-	LLViewerLODTexture(const LLUUID& id, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
-	LLViewerLODTexture(const std::string& url, const LLUUID& id, BOOL usemipmaps = TRUE);
+	LLViewerLODTexture(const LLUUID& id, FTType f_type, const LLHost& host = LLHost::invalid, BOOL usemipmaps = TRUE);
+	LLViewerLODTexture(const std::string& url, FTType f_type, const LLUUID& id, BOOL usemipmaps = TRUE);
 
 	/*virtual*/ S8 getType() const;
 	// Process image stats to determine priority/quality requirements.
@@ -731,8 +623,9 @@ class LLViewerTextureManager
 	static LLPointer<LLViewerTexture> getLocalTexture(const U32 width, const U32 height, const U8 components, BOOL usemipmaps, BOOL generate_gl_tex = TRUE) ;
 
 	static LLViewerFetchedTexture* getFetchedTexture(const LLUUID &image_id,									 
+									 FTType f_type = FTT_DEFAULT,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -740,8 +633,9 @@ class LLViewerTextureManager
 									 );
 	
 	static LLViewerFetchedTexture* getFetchedTextureFromFile(const std::string& filename,									 
+									 FTType f_type = FTT_LOCAL_FILE,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -749,15 +643,16 @@ class LLViewerTextureManager
 									 );
 
 	static LLViewerFetchedTexture* getFetchedTextureFromUrl(const std::string& url,									 
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
 									 const LLUUID& force_id = LLUUID::null
 									 );
 
-	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, LLHost host) ;
+	static LLViewerFetchedTexture* getFetchedTextureFromHost(const LLUUID& image_id, FTType f_type, LLHost host) ;
 
 	static void init() ;
 	static void cleanup() ;
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index b9f5c432d09544430a5e7d4b1c2bf54afde2bb95..d2af48f5286d78a95ee1eb1bd18168cddc757883 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -112,10 +112,10 @@ void LLViewerTextureList::doPreloadImages()
 	llassert_always(mUUIDMap.empty()) ;
 
 	// Set the "missing asset" image
-	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerFetchedTexture::sMissingAssetImagep = LLViewerTextureManager::getFetchedTextureFromFile("missing_asset.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
 	
 	// Set the "white" image
-	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerFetchedTexture::sWhiteImagep = LLViewerTextureManager::getFetchedTextureFromFile("white.tga", FTT_LOCAL_FILE, MIPMAP_NO, LLViewerFetchedTexture::BOOST_UI);
 	LLTexUnit::sWhiteTexture = LLViewerFetchedTexture::sWhiteImagep->getTexName();
 	LLUIImageList* image_list = LLUIImageList::getInstance();
 
@@ -130,33 +130,33 @@ void LLViewerTextureList::doPreloadImages()
 	//uv_test->setMipFilterNearest(TRUE, TRUE);
 
 	// prefetch specific UUIDs
-	LLViewerTextureManager::getFetchedTexture(IMG_SHOT, TRUE);
-	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF, TRUE);
-	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	LLViewerTextureManager::getFetchedTexture(IMG_SHOT);
+	LLViewerTextureManager::getFetchedTexture(IMG_SMOKE_POOF);
+	LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTextureFromFile("silhouette.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);	
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTextureFromFile("world/NoEntryPassLines.png", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
+	image = LLViewerTextureManager::getFetchedTexture(DEFAULT_WATER_NORMAL, FTT_DEFAULT, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI);
 	if (image) 
 	{
 		image->setAddressMode(LLTexUnit::TAM_WRAP);	
 		mImagePreloads.insert(image);
 	}
-	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
+	image = LLViewerTextureManager::getFetchedTextureFromFile("transparent.j2c", FTT_LOCAL_FILE, MIPMAP_YES, LLViewerFetchedTexture::BOOST_UI, LLViewerTexture::FETCHED_TEXTURE,
 		0,0,LLUUID("8dcd4a48-2d37-4909-9f78-f7a9eb4ef903"));
 	if (image) 
 	{
@@ -198,7 +198,7 @@ void LLViewerTextureList::doPrefetchImages()
 
 		if(LLViewerTexture::FETCHED_TEXTURE == texture_type || LLViewerTexture::LOD_TEXTURE == texture_type)
 		{
-			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, MIPMAP_TRUE, LLViewerTexture::BOOST_NONE, texture_type);
+			LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture(uuid, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_NONE, texture_type);
 			if (image)
 			{
 				image->addTextureStats((F32)pixel_area);
@@ -228,7 +228,9 @@ void LLViewerTextureList::shutdown()
 		if (!image->hasGLTexture() ||
 			!image->getUseDiscard() ||
 			image->needsAux() ||
-			image->getTargetHost() != LLHost::invalid)
+			image->getTargetHost() != LLHost::invalid ||
+			!image->getUrl().empty()
+			)
 		{
 			continue; // avoid UI, baked, and other special images
 		}
@@ -322,7 +324,8 @@ void LLViewerTextureList::restoreGL()
 
 ///////////////////////////////////////////////////////////////////////////////
 
-LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,												   
+LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string& filename,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -339,15 +342,16 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromFile(const std::string&
 	if (full_path.empty())
 	{
 		llwarns << "Failed to find local image file: " << filename << llendl;
-		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI);
+		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	}
 
 	std::string url = "file://" + full_path;
 
-	return getImageFromUrl(url, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
+	return getImageFromUrl(url, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, force_id);
 }
 
 LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string& url,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -372,16 +376,33 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 	}
 
 	LLPointer<LLViewerFetchedTexture> imagep = findImage(new_id);
-	
+
+	if (!imagep.isNull())
+	{
+		LLViewerFetchedTexture *texture = imagep.get();
+		if (texture->getUrl().empty())
+		{
+			llwarns << "Requested texture " << new_id << " already exists but does not have a URL" << llendl;
+		}
+		else if (texture->getUrl() != url)
+		{
+			// This is not an error as long as the images really match -
+			// e.g. could be two avatars wearing the same outfit.
+			LL_DEBUGS("Avatar") << "Requested texture " << new_id
+								<< " already exists with a different url, requested: " << url
+								<< " current: " << texture->getUrl() << llendl;
+		}
+		
+	}
 	if (imagep.isNull())
 	{
 		switch(texture_type)
 		{
 		case LLViewerTexture::FETCHED_TEXTURE:
-			imagep = new LLViewerFetchedTexture(url, new_id, usemipmaps);
+			imagep = new LLViewerFetchedTexture(url, f_type, new_id, usemipmaps);
 			break ;
 		case LLViewerTexture::LOD_TEXTURE:
-			imagep = new LLViewerLODTexture(url, new_id, usemipmaps);
+			imagep = new LLViewerLODTexture(url, f_type, new_id, usemipmaps);
 			break ;
 		default:
 			llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -411,7 +432,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImageFromUrl(const std::string&
 }
 
 
-LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,											       
+LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -430,14 +452,34 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 	
 	if ((&image_id == NULL) || image_id.isNull())
 	{
-		return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, TRUE, LLViewerTexture::BOOST_UI));
+		return (LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI));
 	}
 	
 	LLPointer<LLViewerFetchedTexture> imagep = findImage(image_id);
-	
+	if (!imagep.isNull())
+	{
+		LLViewerFetchedTexture *texture = imagep.get();
+		if (request_from_host.isOk() &&
+			!texture->getTargetHost().isOk())
+		{
+			llwarns << "Requested texture " << image_id << " already exists but does not have a host" << llendl;
+		}
+		else if (request_from_host.isOk() &&
+				 texture->getTargetHost().isOk() &&
+				 request_from_host != texture->getTargetHost())
+		{
+			llwarns << "Requested texture " << image_id << " already exists with a different target host, requested: " 
+					<< request_from_host << " current: " << texture->getTargetHost() << llendl;
+		}
+		if (f_type != FTT_DEFAULT && imagep->getFTType() != f_type)
+		{
+			llwarns << "FTType mismatch: requested " << f_type << " image has " << imagep->getFTType() << llendl;
+		}
+		
+	}
 	if (imagep.isNull())
 	{
-		imagep = createImage(image_id, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
+		imagep = createImage(image_id, f_type, usemipmaps, boost_priority, texture_type, internal_format, primary_format, request_from_host) ;
 	}
 
 	imagep->setGLTextureCreated(true);
@@ -446,7 +488,8 @@ LLViewerFetchedTexture* LLViewerTextureList::getImage(const LLUUID &image_id,
 }
 
 //when this function is called, there is no such texture in the gTextureList with image_id.
-LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,											       
+LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
+												   FTType f_type,
 												   BOOL usemipmaps,
 												   LLViewerTexture::EBoostLevel boost_priority,
 												   S8 texture_type,
@@ -460,10 +503,10 @@ LLViewerFetchedTexture* LLViewerTextureList::createImage(const LLUUID &image_id,
 	switch(texture_type)
 	{
 	case LLViewerTexture::FETCHED_TEXTURE:
-		imagep = new LLViewerFetchedTexture(image_id, request_from_host, usemipmaps);
+		imagep = new LLViewerFetchedTexture(image_id, f_type, request_from_host, usemipmaps);
 		break ;
 	case LLViewerTexture::LOD_TEXTURE:
-		imagep = new LLViewerLODTexture(image_id, request_from_host, usemipmaps);
+		imagep = new LLViewerLODTexture(image_id, f_type, request_from_host, usemipmaps);
 		break ;
 	default:
 		llerrs << "Invalid texture type " << texture_type << llendl ;
@@ -1353,7 +1396,7 @@ void LLViewerTextureList::receiveImageHeader(LLMessageSystem *msg, void **user_d
 	U8 *data = new U8[data_size];
 	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
 	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	if (!image)
 	{
 		delete [] data;
@@ -1425,7 +1468,7 @@ void LLViewerTextureList::receiveImagePacket(LLMessageSystem *msg, void **user_d
 	U8 *data = new U8[data_size];
 	msg->getBinaryDataFast(_PREHASH_ImageData, _PREHASH_Data, data, data_size);
 	
-	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	LLViewerFetchedTexture *image = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	if (!image)
 	{
 		delete [] data;
@@ -1456,6 +1499,7 @@ void LLViewerTextureList::processImageNotInDatabase(LLMessageSystem *msg,void **
 	LLViewerFetchedTexture* image = gTextureList.findImage( image_id );
 	if( image )
 	{
+		llwarns << "not in db" << llendl;
 		image->setIsMissingAsset();
 	}
 }
@@ -1525,22 +1569,22 @@ LLUIImagePtr LLUIImageList::getUIImage(const std::string& image_name, S32 priori
 LLUIImagePtr LLUIImageList::loadUIImageByName(const std::string& name, const std::string& filename,
 											  BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority )
 {
-	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	if (boost_priority == LLGLTexture::BOOST_NONE)
 	{
-		boost_priority = LLViewerTexture::BOOST_UI;
+		boost_priority = LLGLTexture::BOOST_UI;
 	}
-	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, MIPMAP_NO, boost_priority);
+	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTextureFromFile(filename, FTT_LOCAL_FILE, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, name, use_mips, scale_rect, clip_rect);
 }
 
 LLUIImagePtr LLUIImageList::loadUIImageByID(const LLUUID& id,
 											BOOL use_mips, const LLRect& scale_rect, const LLRect& clip_rect, LLViewerTexture::EBoostLevel boost_priority)
 {
-	if (boost_priority == LLViewerTexture::BOOST_NONE)
+	if (boost_priority == LLGLTexture::BOOST_NONE)
 	{
-		boost_priority = LLViewerTexture::BOOST_UI;
+		boost_priority = LLGLTexture::BOOST_UI;
 	}
-	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, MIPMAP_NO, boost_priority);
+	LLViewerFetchedTexture* imagep = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, MIPMAP_NO, boost_priority);
 	return loadUIImage(imagep, id.asString(), use_mips, scale_rect, clip_rect);
 }
 
@@ -1563,7 +1607,7 @@ LLUIImagePtr LLUIImageList::loadUIImage(LLViewerFetchedTexture* imagep, const st
 	//Note:
 	//Some other textures such as ICON also through this flow to be fetched.
 	//But only UI textures need to set this callback.
-	if(imagep->getBoostLevel() == LLViewerTexture::BOOST_UI)
+	if(imagep->getBoostLevel() == LLGLTexture::BOOST_UI)
 	{
 		LLUIImageLoadData* datap = new LLUIImageLoadData;
 		datap->mImageName = name;
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index 3dda973d3fa98edf01d20a9c573c8cd514e2589f..136042620d5e193718d1c3ad042a64861d85603a 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -130,8 +130,9 @@ class LLViewerTextureList
 	void removeImageFromList(LLViewerFetchedTexture *image);
 
 	LLViewerFetchedTexture * getImage(const LLUUID &image_id,									 
+									 FTType f_type = FTT_DEFAULT,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -139,8 +140,9 @@ class LLViewerTextureList
 									 );
 	
 	LLViewerFetchedTexture * getImageFromFile(const std::string& filename,									 
+									 FTType f_type = FTT_LOCAL_FILE,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -148,8 +150,9 @@ class LLViewerTextureList
 									 );
 	
 	LLViewerFetchedTexture* getImageFromUrl(const std::string& url,
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -157,8 +160,9 @@ class LLViewerTextureList
 									 );
 
 	LLViewerFetchedTexture* createImage(const LLUUID &image_id,
+									 FTType f_type,
 									 BOOL usemipmap = TRUE,
-									 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
+									 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_NONE,		// Get the requested level immediately upon creation.
 									 S8 texture_type = LLViewerTexture::FETCHED_TEXTURE,
 									 LLGLint internal_format = 0,
 									 LLGLenum primary_format = 0,
@@ -167,8 +171,8 @@ class LLViewerTextureList
 	
 	// Request image from a specific host, used for baked avatar textures.
 	// Implemented in header in case someone changes default params above. JC
-	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, LLHost host)
-	{ return getImage(image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	
+	LLViewerFetchedTexture* getImageFromHost(const LLUUID& image_id, FTType f_type, LLHost host)
+	{ return getImage(image_id, f_type, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host); }	
 
 public:
 	typedef std::set<LLPointer<LLViewerFetchedTexture> > image_list_t;	
@@ -233,11 +237,11 @@ class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIIm
 	LLPointer<LLUIImage> loadUIImageByName(const std::string& name, const std::string& filename,
 		                           BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
 								   const LLRect& clip_rect = LLRect::null,
-		                           LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+		                           LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
 	LLPointer<LLUIImage> loadUIImageByID(const LLUUID& id,
 								 BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, 
 								 const LLRect& clip_rect = LLRect::null,
-								 LLViewerTexture::EBoostLevel boost_priority = LLViewerTexture::BOOST_UI);
+								 LLViewerTexture::EBoostLevel boost_priority = LLGLTexture::BOOST_UI);
 
 	LLPointer<LLUIImage> loadUIImage(LLViewerFetchedTexture* imagep, const std::string& name, BOOL use_mips = FALSE, const LLRect& scale_rect = LLRect::null, const LLRect& clip_rect = LLRect::null);
 
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e8425dc76a1d5eb77c94ac8a4fdb9a9a6e36cbc0
--- /dev/null
+++ b/indra/newview/llviewerwearable.cpp
@@ -0,0 +1,656 @@
+/** 
+ * @file llviewerwearable.cpp
+ * @brief LLViewerWearable class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+
+#include "llagent.h"
+#include "llagentcamera.h"
+#include "llagentwearables.h"
+#include "llfloatersidepanelcontainer.h"
+#include "llnotificationsutil.h"
+#include "llsidepanelappearance.h"
+#include "lltextureentry.h"
+#include "llviewertexlayer.h"
+#include "llvoavatarself.h"
+#include "llavatarappearancedefines.h"
+#include "llviewerwearable.h"
+#include "llviewercontrol.h"
+#include "llviewerregion.h"
+
+using namespace LLAvatarAppearanceDefines;
+
+// support class - remove for 2.1 (hackity hack hack)
+class LLOverrideBakedTextureUpdate
+{
+public:
+	LLOverrideBakedTextureUpdate(bool temp_state)
+	{
+		U32 num_bakes = (U32) LLAvatarAppearanceDefines::BAKED_NUM_INDICES;
+		for( U32 index = 0; index < num_bakes; ++index )
+		{
+			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
+		}
+		gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
+	}
+
+	~LLOverrideBakedTextureUpdate()
+	{
+		U32 num_bakes = (U32)LLAvatarAppearanceDefines::BAKED_NUM_INDICES;		
+		for( U32 index = 0; index < num_bakes; ++index )
+		{
+			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
+		}
+	}
+private:
+	bool composite_enabled[LLAvatarAppearanceDefines::BAKED_NUM_INDICES];
+};
+
+// Private local functions
+static std::string asset_id_to_filename(const LLUUID &asset_id);
+
+LLViewerWearable::LLViewerWearable(const LLTransactionID& transaction_id) :
+	LLWearable()
+{
+	mTransactionID = transaction_id;
+	mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
+}
+
+LLViewerWearable::LLViewerWearable(const LLAssetID& asset_id) :
+	LLWearable()
+{
+	mAssetID = asset_id;
+	mTransactionID.setNull();
+}
+
+// virtual
+LLViewerWearable::~LLViewerWearable()
+{
+}
+
+// virtual
+LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
+{
+	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
+	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
+	LLOverrideBakedTextureUpdate stop_bakes(false);
+
+	LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);
+	if (LLWearable::FAILURE == result) return result;
+	if (LLWearable::BAD_HEADER == result)
+	{
+		// Shouldn't really log the asset id for security reasons, but
+		// we need it in this case.
+		llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
+		//gVFS->dumpMap();
+		return result;
+	}
+
+	LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
+	LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
+
+	te_map_t::const_iterator iter = mTEMap.begin();
+	te_map_t::const_iterator end = mTEMap.end();
+	for (; iter != end; ++iter)
+	{
+		S32 te = iter->first;
+		LLLocalTextureObject* lto = iter->second;
+		LLUUID textureid = LLUUID::null;
+		if (lto)
+		{
+			textureid = lto->getID();
+		}
+
+		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( textureid );
+		if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
+		{
+			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(textureid, (LLAvatarAppearanceDefines::ETextureIndex)te), NULL);
+		}
+	}
+
+	return result;
+}
+
+
+// Avatar parameter and texture definitions can change over time.
+// This function returns true if parameters or textures have been added or removed
+// since this wearable was created.
+BOOL LLViewerWearable::isOldVersion() const
+{
+	if (!isAgentAvatarValid()) return FALSE;
+
+	if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
+	{
+		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
+		llassert(0);
+	}
+
+	if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
+	{
+		return TRUE;
+	}
+
+	S32 param_count = 0;
+	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) && (param->isTweakable() ) )
+		{
+			param_count++;
+			if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
+			{
+				return TRUE;
+			}
+		}
+	}
+	if( param_count != mVisualParamIndexMap.size() )
+	{
+		return TRUE;
+	}
+
+
+	S32 te_count = 0;
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_count++;
+			if( !is_in_map(mTEMap, te ) )
+			{
+				return TRUE;
+			}
+		}
+	}
+	if( te_count != mTEMap.size() )
+	{
+		return TRUE;
+	}
+
+	return FALSE;
+}
+
+// Avatar parameter and texture definitions can change over time.
+// * If parameters or textures have been REMOVED since the wearable was created,
+// they're just ignored, so we consider the wearable clean even though isOldVersion()
+// will return true. 
+// * If parameters or textures have been ADDED since the wearable was created,
+// they are taken to have default values, so we consider the wearable clean
+// only if those values are the same as the defaults.
+BOOL LLViewerWearable::isDirty() const
+{
+	if (!isAgentAvatarValid()) return FALSE;
+
+	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) 
+			&& (param->isTweakable() ) 
+			&& !param->getCrossWearable())
+		{
+			F32 current_weight = getVisualParamWeight(param->getID());
+			current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
+			F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
+			saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+			
+			U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
+			U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
+			if( a != b  )
+			{
+				return TRUE;
+			}
+		}
+	}
+
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator current_iter = mTEMap.find(te);
+			if(current_iter != mTEMap.end())
+			{
+ 				const LLUUID& current_image_id = current_iter->second->getID();
+				te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
+				if(saved_iter != mSavedTEMap.end())
+				{
+					const LLUUID& saved_image_id = saved_iter->second->getID();
+					if (saved_image_id != current_image_id)
+					{
+						// saved vs current images are different, wearable is dirty
+						return TRUE;
+					}
+				}
+				else
+				{
+					// image found in current image list but not saved image list
+					return TRUE;
+				}
+			}
+		}
+	}
+
+	return FALSE;
+}
+
+
+void LLViewerWearable::setParamsToDefaults()
+{
+	if (!isAgentAvatarValid()) return;
+
+	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
+		{
+			setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
+		}
+	}
+}
+
+void LLViewerWearable::setTexturesToDefaults()
+{
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			LLUUID id = getDefaultTextureImageID((ETextureIndex) te);
+			LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
+			if( mTEMap.find(te) == mTEMap.end() )
+			{
+				mTEMap[te] = new LLLocalTextureObject(image, id);
+				createLayers(te, gAgentAvatarp);
+			}
+			else
+			{
+				// Local Texture Object already created, just set image and UUID
+				LLLocalTextureObject *lto = mTEMap[te];
+				lto->setID(id);
+				lto->setImage(image);
+			}
+		}
+	}
+}
+
+
+// virtual
+LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
+{
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+	const std::string &default_image_name = texture_dict->mDefaultImageName;
+	if (default_image_name == "")
+	{
+		return IMG_DEFAULT_AVATAR;
+	}
+	else
+	{
+		return LLUUID(gSavedSettings.getString(default_image_name));
+	}
+}
+
+
+// Updates the user's avatar's appearance
+//virtual
+void LLViewerWearable::writeToAvatar(LLAvatarAppearance *avatarp)
+{
+	LLVOAvatarSelf* viewer_avatar = dynamic_cast<LLVOAvatarSelf*>(avatarp);
+
+	if (!avatarp || !viewer_avatar) return;
+
+	if (!viewer_avatar->isValid()) return;
+
+#if 0
+	// FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+	// Ideally would avoid calling this func in the first place.
+	if (viewer_avatar->isUsingServerBakes() &&
+		!viewer_avatar->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+
+	ESex old_sex = avatarp->getSex();
+
+	LLWearable::writeToAvatar(avatarp);
+
+
+	// Pull texture entries
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = mTEMap.find(te);
+			LLUUID image_id;
+			if(iter != mTEMap.end())
+			{
+				image_id = iter->second->getID();
+			}
+			else
+			{	
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+			}
+			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
+			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
+			viewer_avatar->setLocalTextureTE(te, image, 0);
+		}
+	}
+
+	ESex new_sex = avatarp->getSex();
+	if( old_sex != new_sex )
+	{
+		viewer_avatar->updateSexDependentLayerSets( FALSE );
+	}	
+	
+//	if( upload_bake )
+//	{
+//		gAgent.sendAgentSetAppearance();
+//	}
+}
+
+
+// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
+// static 
+void LLViewerWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
+{
+	if (!isAgentAvatarValid()) return;
+
+	// You can't just remove body parts.
+	if( (type == LLWearableType::WT_SHAPE) ||
+		(type == LLWearableType::WT_SKIN) ||
+		(type == LLWearableType::WT_HAIR) ||
+		(type == LLWearableType::WT_EYES) )
+	{
+		return;
+	}
+
+	// Pull params
+	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
+		{
+			S32 param_id = param->getID();
+			gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
+		}
+	}
+
+	if(gAgentCamera.cameraCustomizeAvatar())
+	{
+		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
+	}
+
+	gAgentAvatarp->updateVisualParams();
+	gAgentAvatarp->wearableUpdated(type, FALSE);
+
+//	if( upload_bake )
+//	{
+//		gAgent.sendAgentSetAppearance();
+//	}
+}
+
+// Does not copy mAssetID.
+// Definition version is current: removes obsolete enties and creates default values for new ones.
+void LLViewerWearable::copyDataFrom(const LLViewerWearable* src)
+{
+	if (!isAgentAvatarValid()) return;
+
+	mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
+
+	mName = src->mName;
+	mDescription = src->mDescription;
+	mPermissions = src->mPermissions;
+	mSaleInfo = src->mSaleInfo;
+
+	setType(src->mType, gAgentAvatarp);
+
+	mSavedVisualParamMap.clear();
+	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
+	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
+		param;
+		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
+	{
+		if( (param->getWearableType() == mType) )
+		{
+			S32 id = param->getID();
+			F32 weight = src->getVisualParamWeight(id);
+			mSavedVisualParamMap[id] = weight;
+		}
+	}
+
+	destroyTextures();
+	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+	for (S32 te = 0; te < TEX_NUM_INDICES; te++)
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = src->mTEMap.find(te);
+			LLUUID image_id;
+			LLViewerFetchedTexture *image = NULL;
+			if(iter != src->mTEMap.end())
+			{
+				image = dynamic_cast<LLViewerFetchedTexture*> (src->getLocalTextureObject(te)->getImage());
+				image_id = src->getLocalTextureObject(te)->getID();
+				mTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
+				mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
+			}
+			else
+			{
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+				image = LLViewerTextureManager::getFetchedTexture( image_id );
+				mTEMap[te] = new LLLocalTextureObject(image, image_id);
+				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
+			}
+			createLayers(te, gAgentAvatarp);
+		}
+	}
+
+	// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
+	// to be the same as the saved values (which were loaded from src at param->cloneParam(this))
+	revertValues();
+}
+
+void LLViewerWearable::setItemID(const LLUUID& item_id)
+{
+	mItemID = item_id;
+}
+
+void LLViewerWearable::revertValues()
+{
+#if 0
+	// DRANO avoid overwrite when not in local appearance
+	if (isAgentAvatarValid() && gAgentAvatarp->isUsingServerBakes() && !gAgentAvatarp->isUsingLocalAppearance())
+	{
+		return;
+	}
+#endif
+	LLWearable::revertValues();
+
+
+	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+	if( panel )
+	{
+		panel->updateScrollingPanelList();
+	}
+}
+
+void LLViewerWearable::saveValues()
+{
+	LLWearable::saveValues();
+
+	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
+	if( panel )
+	{
+		panel->updateScrollingPanelList();
+	}
+}
+
+// virtual
+void LLViewerWearable::setUpdated() const
+{ 
+	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
+}
+
+void LLViewerWearable::refreshName()
+{
+	LLUUID item_id = getItemID();
+	LLInventoryItem* item = gInventory.getItem(item_id);
+	if( item )
+	{
+		mName = item->getName();
+	}
+}
+
+// virtual
+void LLViewerWearable::addToBakedTextureHash(LLMD5& hash) const
+{
+	LLUUID asset_id = getAssetID();
+	hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+}
+
+struct LLWearableSaveData
+{
+	LLWearableType::EType mType;
+};
+
+void LLViewerWearable::saveNewAsset() const
+{
+//	llinfos << "LLViewerWearable::saveNewAsset() type: " << getTypeName() << llendl;
+	//llinfos << *this << llendl;
+
+	const std::string filename = asset_id_to_filename(mAssetID);
+	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
+	BOOL successful_save = FALSE;
+	if(fp && exportFile(fp))
+	{
+		successful_save = TRUE;
+	}
+	if(fp)
+	{
+		fclose(fp);
+		fp = NULL;
+	}
+	if(!successful_save)
+	{
+		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
+		llwarns << buffer << llendl;
+		
+		LLSD args;
+		args["NAME"] = mName;
+		LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
+		return;
+	}
+
+	// save it out to database
+	if( gAssetStorage )
+	{
+		 /*
+		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
+		if (!url.empty())
+		{
+			llinfos << "Update Agent Inventory via capability" << llendl;
+			LLSD body;
+			body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
+			body["asset_type"] = LLAssetType::lookup(getAssetType());
+			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
+			body["name"] = getName();
+			body["description"] = getDescription();
+			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
+		}
+		else
+		{
+		}
+		 */
+		 LLWearableSaveData* data = new LLWearableSaveData;
+		 data->mType = mType;
+		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
+                                     &LLViewerWearable::onSaveNewAssetComplete,
+                                     (void*)data);
+	}
+}
+
+// static
+void LLViewerWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
+{
+	LLWearableSaveData* data = (LLWearableSaveData*)userdata;
+	const std::string& type_name = LLWearableType::getTypeName(data->mType);
+	if(0 == status)
+	{
+		// Success
+		llinfos << "Saved wearable " << type_name << llendl;
+	}
+	else
+	{
+		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
+		llwarns << buffer << " Status: " << status << llendl;
+		LLSD args;
+		args["NAME"] = type_name;
+		LLNotificationsUtil::add("CannotSaveToAssetStore", args);
+	}
+
+	// Delete temp file
+	const std::string src_filename = asset_id_to_filename(new_asset_id);
+	LLFile::remove(src_filename);
+
+	// delete the context data
+	delete data;
+
+}
+
+std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w)
+{
+	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
+	s << "    Name: " << w.mName << "\n";
+	s << "    Desc: " << w.mDescription << "\n";
+	//w.mPermissions
+	//w.mSaleInfo
+
+	s << "    Params:" << "\n";
+	for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
+		 iter != w.mVisualParamIndexMap.end(); ++iter)
+	{
+		S32 param_id = iter->first;
+		LLVisualParam *wearable_param = iter->second;
+		F32 param_weight = wearable_param->getWeight();
+		s << "        " << param_id << " " << param_weight << "\n";
+	}
+
+	s << "    Textures:" << "\n";
+	for (LLViewerWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
+		 iter != w.mTEMap.end(); ++iter)
+	{
+		S32 te = iter->first;
+		const LLUUID& image_id = iter->second->getID();
+		s << "        " << te << " " << image_id << "\n";
+	}
+	return s;
+}
+
+std::string asset_id_to_filename(const LLUUID &asset_id)
+{
+	std::string asset_id_string;
+	asset_id.toString(asset_id_string);
+	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";	
+	return filename;
+}
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
new file mode 100644
index 0000000000000000000000000000000000000000..65566f23a5a9981d6b3a5dc7ecac34a5d8d12a6e
--- /dev/null
+++ b/indra/newview/llviewerwearable.h
@@ -0,0 +1,104 @@
+/** 
+ * @file llviewerwearable.h
+ * @brief LLViewerWearable class header file
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2010, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_VIEWER_WEARABLE_H
+#define LL_VIEWER_WEARABLE_H
+
+#include "llwearable.h"
+#include "llavatarappearancedefines.h"
+
+class LLVOAvatar;
+
+class LLViewerWearable : public LLWearable
+{
+	friend class LLWearableList;
+
+	//--------------------------------------------------------------------
+	// Constructors and destructors
+	//--------------------------------------------------------------------
+private:
+	// Private constructors used by LLViewerWearableList
+	LLViewerWearable(const LLTransactionID& transactionID);
+	LLViewerWearable(const LLAssetID& assetID);
+public:
+	virtual ~LLViewerWearable();
+
+	//--------------------------------------------------------------------
+	// Accessors
+	//--------------------------------------------------------------------
+public:
+	const LLUUID&				getItemID() const { return mItemID; }
+	const LLAssetID&			getAssetID() const { return mAssetID; }
+	const LLTransactionID&		getTransactionID() const { return mTransactionID; }
+	void						setItemID(const LLUUID& item_id);
+
+public:
+
+	BOOL				isDirty() const;
+	BOOL				isOldVersion() const;
+
+	/*virtual*/ void	writeToAvatar(LLAvatarAppearance *avatarp);
+	void				removeFromAvatar( BOOL upload_bake )	{ LLViewerWearable::removeFromAvatar( mType, upload_bake ); }
+	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); 
+
+	/*virtual*/ EImportResult	importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
+	
+	void				setParamsToDefaults();
+	void				setTexturesToDefaults();
+
+	/*virtual*/ LLUUID	getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
+
+	void				saveNewAsset() const;
+	static void			onSaveNewAssetComplete( const LLUUID& asset_uuid, void* user_data, S32 status, LLExtStat ext_status );
+
+	void				copyDataFrom(const LLViewerWearable* src);
+
+	friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w);
+
+	/*virtual*/ void	revertValues();
+	/*virtual*/ void	saveValues();
+
+	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
+	/*virtual*/void		setUpdated() const;
+
+	// the wearable was worn. make sure the name of the wearable object matches the LLViewerInventoryItem,
+	// not the wearable asset itself.
+	void				refreshName();
+
+	// Update the baked texture hash.
+	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const;
+
+protected:
+	LLAssetID			mAssetID;
+	LLTransactionID		mTransactionID;
+
+	LLUUID				mItemID;  // ID of the inventory item in the agent's inventory	
+};
+
+
+#endif  // LL_VIEWER_WEARABLE_H
+
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 48a69129ebfd6951018c467769689ca35d70db99..0910b7536d40698e60d652c8d4aa38161b05f76a 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -37,8 +37,10 @@
 
 #include "llagent.h"
 #include "llagentcamera.h"
+#include "llcommunicationchannel.h"
 #include "llfloaterreg.h"
 #include "llmeshrepository.h"
+#include "llnotificationhandler.h"
 #include "llpanellogin.h"
 #include "llviewerkeyboard.h"
 #include "llviewermenu.h"
@@ -56,6 +58,7 @@
 
 // linden library includes
 #include "llaudioengine.h"		// mute on minimize
+#include "llchatentry.h"
 #include "indra_constants.h"
 #include "llassetstorage.h"
 #include "llerrorcontrol.h"
@@ -128,6 +131,7 @@
 #include "llmorphview.h"
 #include "llmoveview.h"
 #include "llnavigationbar.h"
+#include "llnotificationhandler.h"
 #include "llpaneltopinfobar.h"
 #include "llpopupview.h"
 #include "llpreviewtexture.h"
@@ -188,7 +192,7 @@
 #include "llviewerjoystick.h"
 #include "llviewernetwork.h"
 #include "llpostprocess.h"
-#include "llnearbychatbar.h"
+#include "llfloaterimnearbychat.h"
 #include "llagentui.h"
 #include "llwearablelist.h"
 
@@ -198,7 +202,6 @@
 
 #include "llfloaternotificationsconsole.h"
 
-#include "llnearbychat.h"
 #include "llwindowlistener.h"
 #include "llviewerwindowlistener.h"
 #include "llpaneltopinfobar.h"
@@ -380,7 +383,7 @@ class LLDebugText
 
 			if (isAgentAvatarValid())
 			{
-				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot.getWorldPosition());
+				tvector = gAgent.getPosGlobalFromAgent(gAgentAvatarp->mRoot->getWorldPosition());
 				agent_root_center_text = llformat("AgentRootCenter %f %f %f",
 												  (F32)(tvector.mdV[VX]), (F32)(tvector.mdV[VY]), (F32)(tvector.mdV[VZ]));
 			}
@@ -1552,16 +1555,17 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	// boost::lambda::var() constructs such a functor on the fly.
 	mWindowListener.reset(new LLWindowListener(this, boost::lambda::var(gKeyboard)));
 	mViewerWindowListener.reset(new LLViewerWindowListener(this));
-	LLNotificationChannel::buildChannel("VW_alerts", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alert"));
-	LLNotificationChannel::buildChannel("VW_alertmodal", "Visible", LLNotificationFilters::filterBy<std::string>(&LLNotification::getType, "alertmodal"));
 
-	LLNotifications::instance().getChannel("VW_alerts")->connectChanged(&LLViewerWindow::onAlert);
-	LLNotifications::instance().getChannel("VW_alertmodal")->connectChanged(&LLViewerWindow::onAlert);
+	mSystemChannel.reset(new LLNotificationChannel("System", "Visible", LLNotificationFilters::includeEverything));
+	mCommunicationChannel.reset(new LLCommunicationChannel("Communication", "Visible"));
+	mAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alerts", "alert"));
+	mModalAlertsChannel.reset(new LLNotificationsUI::LLViewerAlertHandler("VW_alertmodal", "alertmodal"));
+
 	bool ignore = gSavedSettings.getBOOL("IgnoreAllNotifications");
 	LLNotifications::instance().setIgnoreAllNotifications(ignore);
 	if (ignore)
 	{
-		llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
+	llinfos << "NOTE: ALL NOTIFICATIONS THAT OCCUR WILL GET ADDED TO IGNORE LIST FOR LATER RUNS." << llendl;
 	}
 
 	// Default to application directory.
@@ -1569,6 +1573,16 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	LLViewerWindow::sMovieBaseName = "SLmovie";
 	resetSnapshotLoc();
 
+
+	/*
+	LLWindowCallbacks* callbacks,
+	const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height, U32 flags,
+	BOOL fullscreen, 
+	BOOL clearBg,
+	BOOL disable_vsync,
+	BOOL ignore_pixel_depth,
+	U32 fsaa_samples)
+	*/
 	// create window
 	mWindow = LLWindowManager::createWindow(this,
 		p.title, p.name, p.x, p.y, p.width, p.height, 0,
@@ -1825,8 +1839,8 @@ void LLViewerWindow::initBase()
 	gDebugView->init();
 	gToolTipView = getRootView()->getChild<LLToolTipView>("tooltip view");
 
-	// Initialize busy response message when logged in
-	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initBusyResponse));
+	// Initialize do not disturb response message when logged in
+	LLAppViewer::instance()->setOnLoginCompletedCallback(boost::bind(&LLFloaterPreference::initDoNotDisturbResponse));
 
 	// Add the progress bar view (startup view), which overrides everything
 	mProgressView = getRootView()->findChild<LLProgressView>("progress_view");
@@ -2143,7 +2157,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 
 		calcDisplayScale();
 	
-		BOOL display_scale_changed = mDisplayScale != LLUI::sGLScaleFactor;
+		BOOL display_scale_changed = mDisplayScale != LLUI::getScaleFactor();
 		LLUI::setScaleFactor(mDisplayScale);
 
 		// update our window rectangle
@@ -2349,7 +2363,7 @@ void LLViewerWindow::draw()
 		// scale view by UI global scale factor and aspect ratio correction factor
 		gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f);
 
-		LLVector2 old_scale_factor = LLUI::sGLScaleFactor;
+		LLVector2 old_scale_factor = LLUI::getScaleFactor();
 		// apply camera zoom transform (for high res screenshots)
 		F32 zoom_factor = LLViewerCamera::getInstance()->getZoomFactor();
 		S16 sub_region = LLViewerCamera::getInstance()->getZoomSubRegion();
@@ -2363,7 +2377,7 @@ void LLViewerWindow::draw()
 						(F32)getWindowHeightScaled() * -(F32)pos_y, 
 						0.f);
 			gGL.scalef(zoom_factor, zoom_factor, 1.f);
-			LLUI::sGLScaleFactor *= zoom_factor;
+			LLUI::getScaleFactor() *= zoom_factor;
 		}
 
 		// Draw tool specific overlay on world
@@ -2411,7 +2425,7 @@ void LLViewerWindow::draw()
 				LLFontGL::HCENTER, LLFontGL::TOP);
 		}
 
-		LLUI::sGLScaleFactor = old_scale_factor;
+		LLUI::setScaleFactor(old_scale_factor);
 	}
 	LLUI::popMatrix();
 	gGL.popMatrix();
@@ -2500,26 +2514,20 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 		return TRUE;
 	}
 
-	// Traverses up the hierarchy
+	LLFloater* focused_floaterp = gFloaterView->getFocusedFloater();
+	std::string focusedFloaterName = (focused_floaterp ? focused_floaterp->getInstanceName() : "");
+
 	if( keyboard_focus )
 	{
-		LLNearbyChatBar* nearby_chat = LLFloaterReg::findTypedInstance<LLNearbyChatBar>("chat_bar");
-
-		if (nearby_chat)
-		{
-			LLLineEditor* chat_editor = nearby_chat->getChatBox();
-		
-		// arrow keys move avatar while chatting hack
-		if (chat_editor && chat_editor->hasFocus())
+		if ((focusedFloaterName == "nearby_chat") || (focusedFloaterName == "im_container") || (focusedFloaterName == "impanel"))
 		{
-			// If text field is empty, there's no point in trying to move
-			// cursor with arrow keys, so allow movement
-			if (chat_editor->getText().empty() 
-				|| gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
+			if (gSavedSettings.getBOOL("ArrowKeysAlwaysMove"))
 			{
 				// let Control-Up and Control-Down through for chat line history,
 				if (!(key == KEY_UP && mask == MASK_CONTROL)
-					&& !(key == KEY_DOWN && mask == MASK_CONTROL))
+					&& !(key == KEY_DOWN && mask == MASK_CONTROL)
+					&& !(key == KEY_UP && mask == MASK_ALT)
+					&& !(key == KEY_DOWN && mask == MASK_ALT))
 				{
 					switch(key)
 					{
@@ -2537,9 +2545,9 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 						break;
 					}
 				}
-			}
 		}
 		}
+
 		if (keyboard_focus->handleKey(key, mask, FALSE))
 		{
 			return TRUE;
@@ -2570,11 +2578,19 @@ BOOL LLViewerWindow::handleKey(KEY key, MASK mask)
 	if ( gSavedSettings.getS32("LetterKeysFocusChatBar") && !gAgentCamera.cameraMouselook() && 
 		!keyboard_focus && key < 0x80 && (mask == MASK_NONE || mask == MASK_SHIFT) )
 	{
-		LLLineEditor* chat_editor = LLFloaterReg::getTypedInstance<LLNearbyChatBar>("chat_bar")->getChatBox();
+		// Initialize nearby chat if it's missing
+		LLFloaterIMNearbyChat* nearby_chat = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat");
+		if (!nearby_chat)
+		{	
+			LLSD name("im_container");
+			LLFloaterReg::toggleInstanceOrBringToFront(name);
+		}
+
+		LLChatEntry* chat_editor = LLFloaterReg::findTypedInstance<LLFloaterIMNearbyChat>("nearby_chat")->getChatBox();
 		if (chat_editor)
 		{
 			// passing NULL here, character will be added later when it is handled by character handler.
-			LLNearbyChatBar::getInstance()->startChat(NULL);
+			nearby_chat->startChat(NULL);
 			return TRUE;
 		}
 	}
@@ -2603,7 +2619,10 @@ BOOL LLViewerWindow::handleUnicodeChar(llwchar uni_char, MASK mask)
 	if ((uni_char == 13 && mask != MASK_CONTROL)
 		|| (uni_char == 3 && mask == MASK_NONE))
 	{
-		return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+		if (mask != MASK_ALT)
+		{
+			return gViewerKeyboard.handleKey(KEY_RETURN, mask, gKeyboard->getKeyRepeated(KEY_RETURN));
+		}
 	}
 
 	// let menus handle navigation (jump) keys
@@ -2818,7 +2837,6 @@ void LLViewerWindow::updateUI()
 
 	BOOL handled = FALSE;
 
-	BOOL handled_by_top_ctrl = FALSE;
 	LLUICtrl* top_ctrl = gFocusMgr.getTopCtrl();
 	LLMouseHandler* mouse_captor = gFocusMgr.getMouseCapture();
 	LLView* captor_view = dynamic_cast<LLView*>(mouse_captor);
@@ -3003,7 +3021,6 @@ void LLViewerWindow::updateUI()
 				S32 local_x, local_y;
 				top_ctrl->screenPointToLocal( x, y, &local_x, &local_y );
 				handled = top_ctrl->pointInView(local_x, local_y) && top_ctrl->handleHover(local_x, local_y, mask);
-				handled_by_top_ctrl = TRUE;
 			}
 
 			if ( !handled )
@@ -3211,8 +3228,8 @@ void LLViewerWindow::updateLayout()
 
 void LLViewerWindow::updateMouseDelta()
 {
-	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::sGLScaleFactor.mV[VX]);
-	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::sGLScaleFactor.mV[VY]);
+	S32 dx = lltrunc((F32) (mCurrentMousePoint.mX - mLastMousePoint.mX) * LLUI::getScaleFactor().mV[VX]);
+	S32 dy = lltrunc((F32) (mCurrentMousePoint.mY - mLastMousePoint.mY) * LLUI::getScaleFactor().mV[VY]);
 
 	//RN: fix for asynchronous notification of mouse leaving window not working
 	LLCoordWindow mouse_pos;
@@ -4777,7 +4794,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
 		gResizeScreenTexture = TRUE;
 		gWindowResized = TRUE;
 
-		if (isAgentAvatarValid() && !gAgentAvatarp->isUsingBakedTextures())
+		if (isAgentAvatarValid() && gAgentAvatarp->isEditingAppearance())
 		{
 			LLVisualParamHint::requestHintUpdates();
 		}
@@ -5037,25 +5054,6 @@ LLRect LLViewerWindow::getChatConsoleRect()
 //----------------------------------------------------------------------------
 
 
-//static 
-bool LLViewerWindow::onAlert(const LLSD& notify)
-{
-	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
-
-	if (gHeadlessClient)
-	{
-		llinfos << "Alert: " << notification->getName() << llendl;
-	}
-
-	// If we're in mouselook, the mouse is hidden and so the user can't click 
-	// the dialog buttons.  In that case, change to First Person instead.
-	if( gAgentCamera.cameraMouselook() )
-	{
-		gAgentCamera.changeCameraToDefault();
-	}
-	return false;
-}
-
 void LLViewerWindow::setUIVisibility(bool visible)
 {
 	mUIVisible = visible;
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 5f475fe145b2a79bf32a8b904cb578d0e3dd06c9..b33488fd785568195eef95dc5c3192c6225aaea0 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -42,6 +42,7 @@
 #include "llwindowcallbacks.h"
 #include "lltimer.h"
 #include "llmousehandler.h"
+#include "llnotifications.h"
 #include "llhandle.h"
 #include "llinitparam.h"
 
@@ -400,7 +401,6 @@ class LLViewerWindow : public LLWindowCallbacks
 
 private:
 	bool                    shouldShowToolTipFor(LLMouseHandler *mh);
-	static bool onAlert(const LLSD& notify);
 
 	void			switchToolByMask(MASK mask);
 	void			destroyWindow();
@@ -417,6 +417,11 @@ class LLViewerWindow : public LLWindowCallbacks
 	bool			mActive;
 	bool			mUIVisible;
 
+	LLNotificationChannelPtr mSystemChannel;
+	LLNotificationChannelPtr mCommunicationChannel;
+	LLNotificationChannelPtr mAlertsChannel;
+	LLNotificationChannelPtr mModalAlertsChannel;
+
 	LLRect			mWindowRectRaw;				// whole window, including UI
 	LLRect			mWindowRectScaled;			// whole window, scaled by UI size
 	LLRect			mWorldViewRectRaw;			// area of screen for 3D world
diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp
index abb515348068ace099458dd50e717898cd6f5b17..94760e3c8351ce1ec50bb40b707f2f8a0e6c89b6 100644
--- a/indra/newview/llvlcomposition.cpp
+++ b/indra/newview/llvlcomposition.cpp
@@ -223,7 +223,7 @@ BOOL LLVLComposition::generateComposition()
 	{
 		if (mDetailTextures[i]->getDiscardLevel() < 0)
 		{
-			mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+			mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
 			mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE);
 			return FALSE;
 		}
@@ -240,7 +240,7 @@ BOOL LLVLComposition::generateComposition()
 				ddiscard++;
 				min_dim /= 2;
 			}
-			mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_TERRAIN); // in case we are at low detail
+			mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail
 			mDetailTextures[i]->setMinDiscardLevel(ddiscard);
 			return FALSE;
 		}
@@ -376,9 +376,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 	LLPointer<LLImageRaw> raw = new LLImageRaw(tex_width, tex_height, tex_comps);
 	U8 *rawp = raw->getData();
 
-	F32 tex_width_inv = 1.f/tex_width;
-	F32 tex_height_inv = 1.f/tex_height;
-
 	F32 st_x_stride, st_y_stride;
 	st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width);
 	st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height);
@@ -413,11 +410,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 			tex1 = tex0 + 1;
 			tex1 = llclamp(tex1, 0, 3);
 
-			F32 xy_int_i, xy_int_j;
-
-			xy_int_i = i * tex_width_inv;
-			xy_int_j = j * tex_height_inv;
-
 			st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps;
 			for (U32 k = 0; k < tex_comps; k++)
 			{
@@ -461,7 +453,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y,
 	for (S32 i = 0; i < 4; i++)
 	{
 		// Un-boost detatil textures (will get re-boosted if rendering in high detail)
-		mDetailTextures[i]->setBoostLevel(LLViewerTexture::BOOST_NONE);
+		mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE);
 		mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1);
 	}
 	
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
old mode 100644
new mode 100755
index 62e93b7a53b79a50f5f398a75dd53aaff5adab16..0475e9fc8922c490d1efa5c94589663ec497a193
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -24,18 +24,13 @@
  * $/LicenseInfo$
  */
 
-#if LL_MSVC
-// disable warning about boost::lexical_cast returning uninitialized data
-// when it fails to parse the string
-#pragma warning (disable:4701)
-#endif
-
 #include "llviewerprecompiledheaders.h"
 
 #include "llvoavatar.h"
 
 #include <stdio.h>
 #include <ctype.h>
+#include <sstream>
 
 #include "llaudioengine.h"
 #include "noise.h"
@@ -53,6 +48,7 @@
 #include "llcallingcard.h"		// IDEVO for LLAvatarTracker
 #include "lldrawpoolavatar.h"
 #include "lldriverparam.h"
+#include "llpolyskeletaldistortion.h"
 #include "lleditingmotion.h"
 #include "llemote.h"
 //#include "llfirstuse.h"
@@ -62,6 +58,7 @@
 #include "llhudmanager.h"
 #include "llhudnametag.h"
 #include "llhudtext.h"				// for mText/mDebugText
+#include "llinitparam.h"
 #include "llkeyframefallmotion.h"
 #include "llkeyframestandmotion.h"
 #include "llkeyframewalkmotion.h"
@@ -77,15 +74,16 @@
 #include "llselectmgr.h"
 #include "llsprite.h"
 #include "lltargetingmotion.h"
-#include "lltexlayer.h"
 #include "lltoolmorph.h"
 #include "llviewercamera.h"
+#include "llviewertexlayer.h"
 #include "llviewertexturelist.h"
 #include "llviewermenu.h"
 #include "llviewerobjectlist.h"
 #include "llviewerparcelmgr.h"
 #include "llviewershadermgr.h"
 #include "llviewerstats.h"
+#include "llviewerwearable.h"
 #include "llvoavatarself.h"
 #include "llvovolume.h"
 #include "llworld.h"
@@ -102,22 +100,17 @@
 
 #include "lldebugmessagebox.h"
 #include "llsdutil.h"
+#include "llsdserialize.h"
 
 extern F32 SPEED_ADJUST_MAX;
 extern F32 SPEED_ADJUST_MAX_SEC;
 extern F32 ANIM_SPEED_MAX;
 extern F32 ANIM_SPEED_MIN;
 
-#if LL_MSVC
-// disable boost::lexical_cast warning
-#pragma warning (disable:4702)
-#endif
-
-#include <boost/lexical_cast.hpp>
 
 // #define OUTPUT_BREAST_DATA
 
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 //-----------------------------------------------------------------------------
 // Global constants
@@ -138,7 +131,6 @@ const LLUUID ANIM_AGENT_PHYSICS_MOTION = LLUUID("7360e029-3cb8-ebc4-863e-212df44
 //-----------------------------------------------------------------------------
 // Constants
 //-----------------------------------------------------------------------------
-const std::string AVATAR_DEFAULT_CHAR = "avatar";
 
 const S32 MIN_PIXEL_AREA_FOR_COMPOSITE = 1024;
 const F32 SHADOW_OFFSET_AMT = 0.03f;
@@ -191,8 +183,9 @@ const S32 MAX_BUBBLE_CHAT_LENGTH = DB_CHAT_MSG_STR_LEN;
 const S32 MAX_BUBBLE_CHAT_UTTERANCES = 12;
 const F32 CHAT_FADE_TIME = 8.0;
 const F32 BUBBLE_CHAT_TIME = CHAT_FADE_TIME * 3.f;
-
-const LLColor4 DUMMY_COLOR = LLColor4(0.5,0.5,0.5,1.0);
+const F32 NAMETAG_UPDATE_THRESHOLD = 0.3f;
+const F32 NAMETAG_VERTICAL_SCREEN_OFFSET = 25.f;
+const F32 NAMETAG_VERT_OFFSET_WEIGHT = 0.17f;
 
 enum ERenderName
 {
@@ -222,57 +215,86 @@ struct LLTextureMaskData
  **/
 
 //------------------------------------------------------------------------
-// LLVOBoneInfo
+// LLVOAvatarBoneInfo
 // Trans/Scale/Rot etc. info about each avatar bone.  Used by LLVOAvatarSkeleton.
 //------------------------------------------------------------------------
-class LLVOAvatarBoneInfo
+struct LLVOAvatarCollisionVolumeInfo : public LLInitParam::Block<LLVOAvatarCollisionVolumeInfo>
 {
-	friend class LLVOAvatar;
-	friend class LLVOAvatarSkeletonInfo;
-public:
-	LLVOAvatarBoneInfo() : mIsJoint(FALSE) {}
-	~LLVOAvatarBoneInfo()
+	LLVOAvatarCollisionVolumeInfo() 
+	:	name("name"),
+		pos("pos"),
+		rot("rot"),
+		scale("scale")
+	{}
+
+	Mandatory<std::string>	name;
+	Mandatory<LLVector3>	pos,
+							rot,
+							scale;
+};
+
+struct LLAppearanceMessageContents
+{
+	LLAppearanceMessageContents():
+		mAppearanceVersion(-1),
+		mParamAppearanceVersion(-1),
+		mCOFVersion(LLViewerInventoryCategory::VERSION_UNKNOWN)
 	{
-		std::for_each(mChildList.begin(), mChildList.end(), DeletePointer());
 	}
-	BOOL parseXml(LLXmlTreeNode* node);
+	LLTEContents mTEContents;
+	S32 mAppearanceVersion;
+	S32 mParamAppearanceVersion;
+	S32 mCOFVersion;
+	// For future use:
+	//U32 appearance_flags = 0;
+	std::vector<F32> mParamWeights;
+	std::vector<LLVisualParam*> mParams;
+};
+
+struct LLVOAvatarChildJoint : public LLInitParam::ChoiceBlock<LLVOAvatarChildJoint>
+	{
+	Alternative<Lazy<struct LLVOAvatarBoneInfo, IS_A_BLOCK> >	bone;
+	Alternative<LLVOAvatarCollisionVolumeInfo>		collision_volume;
 	
-private:
-	std::string mName;
-	BOOL mIsJoint;
-	LLVector3 mPos;
-	LLVector3 mRot;
-	LLVector3 mScale;
-	LLVector3 mPivot;
-	typedef std::vector<LLVOAvatarBoneInfo*> child_list_t;
-	child_list_t mChildList;
+	LLVOAvatarChildJoint()
+	:	bone("bone"),
+		collision_volume("collision_volume")
+	{}
+};
+
+	
+
+struct LLVOAvatarBoneInfo : public LLInitParam::Block<LLVOAvatarBoneInfo, LLVOAvatarCollisionVolumeInfo>
+{
+	LLVOAvatarBoneInfo() 
+	:	pivot("pivot")
+	{}
+	
+	Mandatory<LLVector3>					pivot;
+	Multiple<LLVOAvatarChildJoint>			children;
 };
 
 //------------------------------------------------------------------------
 // LLVOAvatarSkeletonInfo
 // Overall avatar skeleton
 //------------------------------------------------------------------------
-class LLVOAvatarSkeletonInfo
+struct LLVOAvatarSkeletonInfo : public LLInitParam::Block<LLVOAvatarSkeletonInfo>
 {
-	friend class LLVOAvatar;
-public:
-	LLVOAvatarSkeletonInfo() :
-		mNumBones(0), mNumCollisionVolumes(0) {}
-	~LLVOAvatarSkeletonInfo()
-	{
-		std::for_each(mBoneInfoList.begin(), mBoneInfoList.end(), DeletePointer());
-	}
-	BOOL parseXml(LLXmlTreeNode* node);
-	S32 getNumBones() const { return mNumBones; }
-	S32 getNumCollisionVolumes() const { return mNumCollisionVolumes; }
+	LLVOAvatarSkeletonInfo()
+	:	skeleton_root(""),
+		num_bones("num_bones"),
+		num_collision_volumes("num_collision_volumes"),
+		version("version")
+	{}
 	
-private:
-	S32 mNumBones;
-	S32 mNumCollisionVolumes;
-	typedef std::vector<LLVOAvatarBoneInfo*> bone_info_list_t;
-	bone_info_list_t mBoneInfoList;
+	Mandatory<std::string>			version;
+	Mandatory<S32>					num_bones,
+									num_collision_volumes;
+	Mandatory<LLVOAvatarChildJoint>	skeleton_root;
 };
 
+
+
 //-----------------------------------------------------------------------------
 // class LLBodyNoiseMotion
 //-----------------------------------------------------------------------------
@@ -594,11 +616,7 @@ class LLPelvisFixMotion :
 //-----------------------------------------------------------------------------
 // Static Data
 //-----------------------------------------------------------------------------
-LLXmlTree LLVOAvatar::sXMLTree;
-LLXmlTree LLVOAvatar::sSkeletonXMLTree;
-LLVOAvatarSkeletonInfo* LLVOAvatar::sAvatarSkeletonInfo = NULL;
-LLVOAvatar::LLVOAvatarXmlInfo* LLVOAvatar::sAvatarXmlInfo = NULL;
-LLVOAvatarDictionary *LLVOAvatar::sAvatarDictionary = NULL;
+LLAvatarAppearanceDictionary *LLVOAvatar::sAvatarDictionary = NULL;
 S32 LLVOAvatar::sFreezeCounter = 0;
 U32 LLVOAvatar::sMaxVisible = 12;
 F32 LLVOAvatar::sRenderDistance = 256.f;
@@ -645,15 +663,13 @@ static F32 calc_bouncy_animation(F32 x);
 LLVOAvatar::LLVOAvatar(const LLUUID& id,
 					   const LLPCode pcode,
 					   LLViewerRegion* regionp) :
+	LLAvatarAppearance(&gAgentWearables),
 	LLViewerObject(id, pcode, regionp),
-	mIsDummy(FALSE),
 	mSpecialRenderMode(0),
 	mAttachmentGeometryBytes(0),
 	mAttachmentSurfaceArea(0.f),
 	mTurning(FALSE),
-	mPelvisToFoot(0.f),
 	mLastSkeletonSerialNum( 0 ),
-	mHeadOffset(),
 	mIsSitting(FALSE),
 	mTimeVisible(),
 	mTyping(FALSE),
@@ -664,10 +680,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mBelowWater(FALSE),
 	mLastAppearanceBlendTime(0.f),
 	mAppearanceAnimating(FALSE),
-	mNameString(),
+    mNameIsSet(false),
 	mTitle(),
 	mNameAway(false),
-	mNameBusy(false),
+	mNameDoNotDisturb(false),
 	mNameMute(false),
 	mNameAppearance(false),
 	mNameFriend(false),
@@ -678,9 +694,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mFirstAppearanceMessageReceived( FALSE ),
 	mCulled( FALSE ),
 	mVisibilityRank(0),
-	mTexSkinColor( NULL ),
-	mTexHairColor( NULL ),
-	mTexEyeColor( NULL ),
 	mNeedsSkin(FALSE),
 	mLastSkinTime(0.f),
 	mUpdatePeriod(1),
@@ -688,12 +701,15 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 	mFullyLoaded(FALSE),
 	mPreviousFullyLoaded(FALSE),
 	mFullyLoadedInitialized(FALSE),
-	mSupportsAlphaLayers(FALSE),
 	mLoadedCallbacksPaused(FALSE),
 	mHasPelvisOffset( FALSE ),
 	mRenderUnloadedAvatar(LLCachedControl<bool>(gSavedSettings, "RenderUnloadedAvatar")),
-	mLastRezzedStatus(-1)
-
+	mLastRezzedStatus(-1),
+	mIsEditingAppearance(FALSE),
+	mUseLocalAppearance(FALSE),
+	mUseServerBakes(FALSE), // FIXME DRANO consider using boost::optional, defaulting to unknown.
+	mLastUpdateRequestCOFVersion(-1),
+	mLastUpdateReceivedCOFVersion(-1)
 {
 	//VTResume();  // VTune
 	
@@ -705,28 +721,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 
 	mPelvisp = NULL;
 
-	mBakedTextureDatas.resize(BAKED_NUM_INDICES);
-	for (U32 i = 0; i < mBakedTextureDatas.size(); i++ )
-	{
-		mBakedTextureDatas[i].mLastTextureIndex = IMG_DEFAULT_AVATAR;
-		mBakedTextureDatas[i].mTexLayerSet = NULL;
-		mBakedTextureDatas[i].mIsLoaded = false;
-		mBakedTextureDatas[i].mIsUsed = false;
-		mBakedTextureDatas[i].mMaskTexName = 0;
-		mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
-	}
-
 	mDirtyMesh = 2;	// Dirty geometry, need to regenerate.
 	mMeshTexturesDirty = FALSE;
 	mHeadp = NULL;
 
-	mIsBuilt = FALSE;
-
-	mNumJoints = 0;
-	mSkeleton = NULL;
-
-	mNumCollisionVolumes = 0;
-	mCollisionVolumes = NULL;
 
 	// set up animation variables
 	mSpeed = 0.f;
@@ -804,59 +802,22 @@ void LLVOAvatar::debugAvatarRezTime(std::string notification_name, std::string c
 //------------------------------------------------------------------------
 LLVOAvatar::~LLVOAvatar()
 {
-	if (!mFullyLoaded)
-	{
+		if (!mFullyLoaded)
+		{
 		debugAvatarRezTime("AvatarRezLeftCloudNotification","left after ruth seconds as cloud");
-	}
-	else
-	{
+		}
+		else
+		{
 		debugAvatarRezTime("AvatarRezLeftNotification","left sometime after declouding");
-	}
+		}
 
+	logPendingPhases();
+	
 	lldebugs << "LLVOAvatar Destructor (0x" << this << ") id:" << mID << llendl;
 
-	mRoot.removeAllChildren();
-	mJointMap.clear();
-
-	deleteAndClearArray(mSkeleton);
-	deleteAndClearArray(mCollisionVolumes);
-
-	mNumJoints = 0;
-
-	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
-	{
-		deleteAndClear(mBakedTextureDatas[i].mTexLayerSet);
-		mBakedTextureDatas[i].mMeshes.clear();
-
-		for (morph_list_t::iterator iter2 = mBakedTextureDatas[i].mMaskedMorphs.begin();
-			 iter2 != mBakedTextureDatas[i].mMaskedMorphs.end(); iter2++)
-		{
-			LLMaskedMorph* masked_morph = (*iter2);
-			delete masked_morph;
-		}
-	}
-
 	std::for_each(mAttachmentPoints.begin(), mAttachmentPoints.end(), DeletePairedPointer());
 	mAttachmentPoints.clear();
 
-	deleteAndClear(mTexSkinColor);
-	deleteAndClear(mTexHairColor);
-	deleteAndClear(mTexEyeColor);
-
-	std::for_each(mMeshes.begin(), mMeshes.end(), DeletePairedPointer());
-	mMeshes.clear();
-
-	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
-		 jointIter != mMeshLOD.end(); 
-		 ++jointIter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint *) *jointIter;
-		std::for_each(joint->mMeshParts.begin(), joint->mMeshParts.end(), DeletePointer());
-		joint->mMeshParts.clear();
-	}
-	std::for_each(mMeshLOD.begin(), mMeshLOD.end(), DeletePointer());
-	mMeshLOD.clear();
-	
 	mDead = TRUE;
 	
 	mAnimationSources.clear();
@@ -901,7 +862,7 @@ BOOL LLVOAvatar::isFullyTextured() const
 {
 	for (S32 i = 0; i < mMeshLOD.size(); i++)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*) mMeshLOD[i];
+		LLAvatarJoint* joint = mMeshLOD[i];
 		if (i==MESH_ID_SKIRT && !isWearingWearableType(LLWearableType::WT_SKIRT))
 		{
 			continue; // don't care about skirt textures if we're not wearing one.
@@ -910,19 +871,19 @@ BOOL LLVOAvatar::isFullyTextured() const
 		{
 			continue; // nonexistent LOD OK.
 		}
-		std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
+		avatar_joint_mesh_list_t::iterator meshIter = joint->mMeshParts.begin();
 		if (meshIter != joint->mMeshParts.end())
 		{
-			LLViewerJointMesh *mesh = (LLViewerJointMesh *) *meshIter;
+			LLAvatarJointMesh *mesh = (*meshIter);
 			if (!mesh)
 			{
 				continue; // nonexistent mesh OK
 			}
-			if (mesh->mTexture.notNull() && mesh->mTexture->hasGLTexture())
+			if (mesh->hasGLTexture())
 			{
 				continue; // Mesh exists and has a baked texture.
 			}
-			if (mesh->mLayerSet && mesh->mLayerSet->hasComposite())
+			if (mesh->hasComposite())
 			{
 				continue; // Mesh exists and has a composite texture.
 			}
@@ -941,6 +902,7 @@ BOOL LLVOAvatar::hasGray() const
 S32 LLVOAvatar::getRezzedStatus() const
 {
 	if (getIsCloud()) return 0;
+	if (isFullyTextured() && allBakedTexturesCompletelyDownloaded()) return 3;
 	if (isFullyTextured()) return 2;
 	llassert(hasGray());
 	return 1; // gray
@@ -996,7 +958,7 @@ BOOL LLVOAvatar::areAllNearbyInstancesBaked(S32& grey_avatars)
 void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
 {
 	counts.clear();
-	counts.resize(3);
+	counts.resize(4);
 	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
 		 iter != LLCharacter::sInstances.end(); ++iter)
 	{
@@ -1014,6 +976,7 @@ std::string LLVOAvatar::rezStatusToString(S32 rez_status)
 	if (rez_status==0) return "cloud";
 	if (rez_status==1) return "gray";
 	if (rez_status==2) return "textured";
+	if (rez_status==3) return "textured_and_downloaded";
 	return "unknown";
 }
 
@@ -1075,15 +1038,15 @@ void LLVOAvatar::dumpBakedStatus()
 		{
 			llcont << " Unbaked (";
 			
-			for (LLVOAvatarDictionary::BakedTextures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+			for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 				 ++iter)
 			{
-				const LLVOAvatarDictionary::BakedEntry *baked_dict = iter->second;
+				const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = iter->second;
 				const ETextureIndex index = baked_dict->mTextureIndex;
 				if (!inst->isTextureDefined(index))
 				{
-					llcont << " " << LLVOAvatarDictionary::getInstance()->getTexture(index)->mName;
+					llcont << " " << LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mName;
 				}
 			}
 			llcont << " ) " << inst->getUnbakedPixelAreaRank();
@@ -1104,7 +1067,7 @@ void LLVOAvatar::restoreGL()
 	gAgentAvatarp->setCompositeUpdatesEnabled(TRUE);
 	for (U32 i = 0; i < gAgentAvatarp->mBakedTextureDatas.size(); i++)
 	{
-		gAgentAvatarp->invalidateComposite(gAgentAvatarp->mBakedTextureDatas[i].mTexLayerSet, FALSE);
+		gAgentAvatarp->invalidateComposite(gAgentAvatarp->getTexLayerSet(i), FALSE);
 	}
 	gAgentAvatarp->updateMeshTextures();
 }
@@ -1131,7 +1094,7 @@ void LLVOAvatar::resetImpostors()
 // static
 void LLVOAvatar::deleteCachedImages(bool clearAll)
 {	
-	if (LLTexLayerSet::sHasCaches)
+	if (LLViewerTexLayerSet::sHasCaches)
 	{
 		lldebugs << "Deleting layer set caches" << llendl;
 		for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
@@ -1140,7 +1103,7 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
 			LLVOAvatar* inst = (LLVOAvatar*) *iter;
 			inst->deleteLayerSetCaches(clearAll);
 		}
-		LLTexLayerSet::sHasCaches = FALSE;
+		LLViewerTexLayerSet::sHasCaches = FALSE;
 	}
 	LLVOAvatarSelf::deleteScratchTextures();
 	LLTexLayerStaticImageList::getInstance()->deleteCachedImages();
@@ -1153,109 +1116,6 @@ void LLVOAvatar::deleteCachedImages(bool clearAll)
 //------------------------------------------------------------------------
 void LLVOAvatar::initClass()
 { 
-	std::string xmlFile;
-
-	xmlFile = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,AVATAR_DEFAULT_CHAR) + "_lad.xml";
-	BOOL success = sXMLTree.parseFile( xmlFile, FALSE );
-	if (!success)
-	{
-		llerrs << "Problem reading avatar configuration file:" << xmlFile << llendl;
-	}
-
-	// now sanity check xml file
-	LLXmlTreeNode* root = sXMLTree.getRoot();
-	if (!root) 
-	{
-		llerrs << "No root node found in avatar configuration file: " << xmlFile << llendl;
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// <linden_avatar version="1.0"> (root)
-	//-------------------------------------------------------------------------
-	if( !root->hasName( "linden_avatar" ) )
-	{
-		llerrs << "Invalid avatar file header: " << xmlFile << llendl;
-	}
-	
-	std::string version;
-	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
-	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
-	{
-		llerrs << "Invalid avatar file version: " << version << " in file: " << xmlFile << llendl;
-	}
-
-	S32 wearable_def_version = 1;
-	static LLStdStringHandle wearable_definition_version_string = LLXmlTree::addAttributeString("wearable_definition_version");
-	root->getFastAttributeS32( wearable_definition_version_string, wearable_def_version );
-	LLWearable::setCurrentDefinitionVersion( wearable_def_version );
-
-	std::string mesh_file_name;
-
-	LLXmlTreeNode* skeleton_node = root->getChildByName( "skeleton" );
-	if (!skeleton_node)
-	{
-		llerrs << "No skeleton in avatar configuration file: " << xmlFile << llendl;
-		return;
-	}
-	
-	std::string skeleton_file_name;
-	static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
-	if (!skeleton_node->getFastAttributeString(file_name_string, skeleton_file_name))
-	{
-		llerrs << "No file name in skeleton node in avatar config file: " << xmlFile << llendl;
-	}
-	
-	std::string skeleton_path;
-	skeleton_path = gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,skeleton_file_name);
-	if (!parseSkeletonFile(skeleton_path))
-	{
-		llerrs << "Error parsing skeleton file: " << skeleton_path << llendl;
-	}
-
-	// Process XML data
-
-	// avatar_skeleton.xml
-	if (sAvatarSkeletonInfo)
-	{ //this can happen if a login attempt failed
-		delete sAvatarSkeletonInfo;
-	}
-	sAvatarSkeletonInfo = new LLVOAvatarSkeletonInfo;
-	if (!sAvatarSkeletonInfo->parseXml(sSkeletonXMLTree.getRoot()))
-	{
-		llerrs << "Error parsing skeleton XML file: " << skeleton_path << llendl;
-	}
-	// parse avatar_lad.xml
-	if (sAvatarXmlInfo)
-	{ //this can happen if a login attempt failed
-		deleteAndClear(sAvatarXmlInfo);
-	}
-	sAvatarXmlInfo = new LLVOAvatarXmlInfo;
-	if (!sAvatarXmlInfo->parseXmlSkeletonNode(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlMeshNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlColorNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlLayerNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlDriverNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-	if (!sAvatarXmlInfo->parseXmlMorphNodes(root))
-	{
-		llerrs << "Error parsing skeleton node in avatar XML file: " << skeleton_path << llendl;
-	}
-
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BODY_NOISE,"body_noise");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_BREATHE_ROT,"breathe_rot");
 	gAnimLibrary.animStateSetString(ANIM_AGENT_PHYSICS_MOTION,"physics_motion");
@@ -1272,91 +1132,18 @@ void LLVOAvatar::initClass()
 
 void LLVOAvatar::cleanupClass()
 {
-	deleteAndClear(sAvatarXmlInfo);
-	sSkeletonXMLTree.cleanup();
-	sXMLTree.cleanup();
 }
 
+// virtual
 void LLVOAvatar::initInstance(void)
 {
-	//-------------------------------------------------------------------------
-	// initialize joint, mesh and shape members
-	//-------------------------------------------------------------------------
-	mRoot.setName( "mRoot" );
-	
-	for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-		 ++iter)
-	{
-		const EMeshIndex mesh_index = iter->first;
-		const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
-		LLViewerJoint* joint = new LLViewerJoint();
-		joint->setName(mesh_dict->mName);
-		joint->setMeshID(mesh_index);
-		mMeshLOD.push_back(joint);
-		
-		/* mHairLOD.setName("mHairLOD");
-		   mHairMesh0.setName("mHairMesh0");
-		   mHairMesh0.setMeshID(MESH_ID_HAIR);
-		   mHairMesh1.setName("mHairMesh1"); */
-		for (U32 lod = 0; lod < mesh_dict->mLOD; lod++)
-		{
-			LLViewerJointMesh* mesh = new LLViewerJointMesh();
-			std::string mesh_name = "m" + mesh_dict->mName + boost::lexical_cast<std::string>(lod);
-			// We pre-pended an m - need to capitalize first character for camelCase
-			mesh_name[1] = toupper(mesh_name[1]);
-			mesh->setName(mesh_name);
-			mesh->setMeshID(mesh_index);
-			mesh->setPickName(mesh_dict->mPickName);
-			mesh->setIsTransparent(FALSE);
-			switch((int)mesh_index)
-			{
-				case MESH_ID_HAIR:
-					mesh->setIsTransparent(TRUE);
-					break;
-				case MESH_ID_SKIRT:
-					mesh->setIsTransparent(TRUE);
-					break;
-				case MESH_ID_EYEBALL_LEFT:
-				case MESH_ID_EYEBALL_RIGHT:
-					mesh->setSpecular( LLColor4( 1.0f, 1.0f, 1.0f, 1.0f ), 1.f );
-					break;
-			}
-			
-			joint->mMeshParts.push_back(mesh);
-		}
-	}
-	
-	//-------------------------------------------------------------------------
-	// associate baked textures with meshes
-	//-------------------------------------------------------------------------
-	for (LLVOAvatarDictionary::Meshes::const_iterator iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-		 ++iter)
-	{
-		const EMeshIndex mesh_index = iter->first;
-		const LLVOAvatarDictionary::MeshEntry *mesh_dict = iter->second;
-		const EBakedTextureIndex baked_texture_index = mesh_dict->mBakedID;
-		// Skip it if there's no associated baked texture.
-		if (baked_texture_index == BAKED_NUM_INDICES) continue;
-		
-		for (std::vector<LLViewerJointMesh* >::iterator iter = mMeshLOD[mesh_index]->mMeshParts.begin();
-			 iter != mMeshLOD[mesh_index]->mMeshParts.end(); 
-			 ++iter)
-		{
-			LLViewerJointMesh* mesh = (LLViewerJointMesh*) *iter;
-			mBakedTextureDatas[(int)baked_texture_index].mMeshes.push_back(mesh);
-		}
-	}
-	
-	
 	//-------------------------------------------------------------------------
 	// register motions
 	//-------------------------------------------------------------------------
 	if (LLCharacter::sInstances.size() == 1)
 	{
 		LLKeyframeMotion::setVFS(gStaticVFS);
-		registerMotion( ANIM_AGENT_BUSY,					LLNullMotion::create );
+		registerMotion( ANIM_AGENT_DO_NOT_DISTURB,					LLNullMotion::create );
 		registerMotion( ANIM_AGENT_CROUCH,					LLKeyframeStandMotion::create );
 		registerMotion( ANIM_AGENT_CROUCHWALK,				LLKeyframeWalkMotion::create );
 		registerMotion( ANIM_AGENT_EXPRESS_AFRAID,			LLEmote::create );
@@ -1408,10 +1195,9 @@ void LLVOAvatar::initInstance(void)
 		registerMotion( ANIM_AGENT_SIT_FEMALE,				LLKeyframeMotion::create );
 		registerMotion( ANIM_AGENT_TARGET,					LLTargetingMotion::create );
 		registerMotion( ANIM_AGENT_WALK_ADJUST,				LLWalkAdjustMotion::create );
-		
 	}
-	
-	buildCharacter();
+
+	LLAvatarAppearance::initInstance();
 	
 	// preload specific motions here
 	createMotion( ANIM_AGENT_CUSTOMIZE);
@@ -1420,7 +1206,30 @@ void LLVOAvatar::initInstance(void)
 	//VTPause();  // VTune
 	
 	mVoiceVisualizer->setVoiceEnabled( LLVoiceClient::getInstance()->getVoiceEnabled( mID ) );
+}
+
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint()
+{
+	return new LLViewerJoint();
+}
+
+// virtual
+LLAvatarJoint* LLVOAvatar::createAvatarJoint(S32 joint_num)
+{
+	return new LLViewerJoint(joint_num);
+}
+
+// virtual
+LLAvatarJointMesh* LLVOAvatar::createAvatarJointMesh()
+{
+	return new LLViewerJointMesh();
+}
 
+// virtual
+LLTexLayerSet* LLVOAvatar::createTexLayerSet()
+{
+	return new LLViewerTexLayerSet(this);
 }
 
 const LLVector3 LLVOAvatar::getRenderPosition() const
@@ -1495,7 +1304,7 @@ void LLVOAvatar::getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
 	float max_attachment_span = get_default_max_prim_scale() * 5.0f;
 	
 	//stretch bounding box by joint positions
-	for (polymesh_map_t::iterator i = mMeshes.begin(); i != mMeshes.end(); ++i)
+	for (polymesh_map_t::iterator i = mPolyMeshes.begin(); i != mPolyMeshes.end(); ++i)
 	{
 		LLPolyMesh* mesh = i->second;
 		for (S32 joint_num = 0; joint_num < mesh->mJointRenderData.count(); joint_num++)
@@ -1733,154 +1542,7 @@ LLViewerObject* LLVOAvatar::lineSegmentIntersectRiggedAttachments(const LLVector
 	return hit;
 }
 
-//-----------------------------------------------------------------------------
-// parseSkeletonFile()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::parseSkeletonFile(const std::string& filename)
-{
-	//-------------------------------------------------------------------------
-	// parse the file
-	//-------------------------------------------------------------------------
-	BOOL parsesuccess = sSkeletonXMLTree.parseFile( filename, FALSE );
-
-	if (!parsesuccess)
-	{
-		llerrs << "Can't parse skeleton file: " << filename << llendl;
-		return FALSE;
-	}
-
-	// now sanity check xml file
-	LLXmlTreeNode* root = sSkeletonXMLTree.getRoot();
-	if (!root) 
-	{
-		llerrs << "No root node found in avatar skeleton file: " << filename << llendl;
-		return FALSE;
-	}
-
-	if( !root->hasName( "linden_skeleton" ) )
-	{
-		llerrs << "Invalid avatar skeleton file header: " << filename << llendl;
-		return FALSE;
-	}
-
-	std::string version;
-	static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
-	if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
-	{
-		llerrs << "Invalid avatar skeleton file version: " << version << " in file: " << filename << llendl;
-		return FALSE;
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// setupBone()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &volume_num, S32 &joint_num)
-{
-	LLViewerJoint* joint = NULL;
-
-	if (info->mIsJoint)
-	{
-		joint = (LLViewerJoint*)getCharacterJoint(joint_num);
-		if (!joint)
-		{
-			llwarns << "Too many bones" << llendl;
-			return FALSE;
-		}
-		joint->setName( info->mName );
-	}
-	else // collision volume
-	{
-		if (volume_num >= (S32)mNumCollisionVolumes)
-		{
-			llwarns << "Too many bones" << llendl;
-			return FALSE;
-		}
-		joint = (LLViewerJoint*)(&mCollisionVolumes[volume_num]);
-		joint->setName( info->mName );
-	}
-
-	// add to parent
-	if (parent)
-	{
-		parent->addChild( joint );
-	}
-
-	joint->setPosition(info->mPos);
-	joint->setRotation(mayaQ(info->mRot.mV[VX], info->mRot.mV[VY],
-							 info->mRot.mV[VZ], LLQuaternion::XYZ));
-	joint->setScale(info->mScale);
-
-	joint->setDefaultFromCurrentXform();
-	
-	if (info->mIsJoint)
-	{
-		joint->setSkinOffset( info->mPivot );
-		joint_num++;
-	}
-	else // collision volume
-	{
-		volume_num++;
-	}
-
-	// setup children
-	LLVOAvatarBoneInfo::child_list_t::const_iterator iter;
-	for (iter = info->mChildList.begin(); iter != info->mChildList.end(); ++iter)
-	{
-		LLVOAvatarBoneInfo *child_info = *iter;
-		if (!setupBone(child_info, joint, volume_num, joint_num))
-		{
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// buildSkeleton()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::buildSkeleton(const LLVOAvatarSkeletonInfo *info)
-{
-	//-------------------------------------------------------------------------
-	// allocate joints
-	//-------------------------------------------------------------------------
-	if (!allocateCharacterJoints(info->mNumBones))
-	{
-		llerrs << "Can't allocate " << info->mNumBones << " joints" << llendl;
-		return FALSE;
-	}
 	
-	//-------------------------------------------------------------------------
-	// allocate volumes
-	//-------------------------------------------------------------------------
-	if (info->mNumCollisionVolumes)
-	{
-		if (!allocateCollisionVolumes(info->mNumCollisionVolumes))
-		{
-			llerrs << "Can't allocate " << info->mNumCollisionVolumes << " collision volumes" << llendl;
-			return FALSE;
-		}
-	}
-
-	S32 current_joint_num = 0;
-	S32 current_volume_num = 0;
-	LLVOAvatarSkeletonInfo::bone_info_list_t::const_iterator iter;
-	for (iter = info->mBoneInfoList.begin(); iter != info->mBoneInfoList.end(); ++iter)
-	{
-		LLVOAvatarBoneInfo *info = *iter;
-		if (!setupBone(info, NULL, current_volume_num, current_joint_num))
-		{
-			llerrs << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
 LLVOAvatar* LLVOAvatar::asAvatar()
 {
 	return this;
@@ -1912,123 +1574,24 @@ void LLVOAvatar::startDefaultMotions()
 // LLVOAvatar::buildCharacter()
 // Deferred initialization and rebuild of the avatar.
 //-----------------------------------------------------------------------------
+// virtual
 void LLVOAvatar::buildCharacter()
 {
-	//-------------------------------------------------------------------------
-	// remove all references to our existing skeleton
-	// so we can rebuild it
-	//-------------------------------------------------------------------------
-	flushAllMotions();
+	LLAvatarAppearance::buildCharacter();
 
-	//-------------------------------------------------------------------------
-	// remove all of mRoot's children
-	//-------------------------------------------------------------------------
-	mRoot.removeAllChildren();
-	mJointMap.clear();
+	// Not done building yet; more to do.
 	mIsBuilt = FALSE;
 
 	//-------------------------------------------------------------------------
-	// clear mesh data
+	// set head offset from pelvis
 	//-------------------------------------------------------------------------
-	for (std::vector<LLViewerJoint*>::iterator jointIter = mMeshLOD.begin();
-		 jointIter != mMeshLOD.end(); ++jointIter)
-	{
-		LLViewerJoint* joint = (LLViewerJoint*) *jointIter;
-		for (std::vector<LLViewerJointMesh*>::iterator meshIter = joint->mMeshParts.begin();
-			 meshIter != joint->mMeshParts.end(); ++meshIter)
-		{
-			LLViewerJointMesh * mesh = (LLViewerJointMesh *) *meshIter;
-			mesh->setMesh(NULL);
-		}
-	}
+	updateHeadOffset();
 
 	//-------------------------------------------------------------------------
-	// (re)load our skeleton and meshes
+	// initialize lip sync morph pointers
 	//-------------------------------------------------------------------------
-	LLTimer timer;
-
-	BOOL status = loadAvatar();
-	stop_glerror();
-
-// 	gPrintMessagesThisFrame = TRUE;
-	lldebugs << "Avatar load took " << timer.getElapsedTimeF32() << " seconds." << llendl;
-
-	if (!status)
-	{
-		if (isSelf())
-		{
-			llerrs << "Unable to load user's avatar" << llendl;
-		}
-		else
-		{
-			llwarns << "Unable to load other's avatar" << llendl;
-		}
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// initialize "well known" joint pointers
-	//-------------------------------------------------------------------------
-	mPelvisp		= (LLViewerJoint*)mRoot.findJoint("mPelvis");
-	mTorsop			= (LLViewerJoint*)mRoot.findJoint("mTorso");
-	mChestp			= (LLViewerJoint*)mRoot.findJoint("mChest");
-	mNeckp			= (LLViewerJoint*)mRoot.findJoint("mNeck");
-	mHeadp			= (LLViewerJoint*)mRoot.findJoint("mHead");
-	mSkullp			= (LLViewerJoint*)mRoot.findJoint("mSkull");
-	mHipLeftp		= (LLViewerJoint*)mRoot.findJoint("mHipLeft");
-	mHipRightp		= (LLViewerJoint*)mRoot.findJoint("mHipRight");
-	mKneeLeftp		= (LLViewerJoint*)mRoot.findJoint("mKneeLeft");
-	mKneeRightp		= (LLViewerJoint*)mRoot.findJoint("mKneeRight");
-	mAnkleLeftp		= (LLViewerJoint*)mRoot.findJoint("mAnkleLeft");
-	mAnkleRightp	= (LLViewerJoint*)mRoot.findJoint("mAnkleRight");
-	mFootLeftp		= (LLViewerJoint*)mRoot.findJoint("mFootLeft");
-	mFootRightp		= (LLViewerJoint*)mRoot.findJoint("mFootRight");
-	mWristLeftp		= (LLViewerJoint*)mRoot.findJoint("mWristLeft");
-	mWristRightp	= (LLViewerJoint*)mRoot.findJoint("mWristRight");
-	mEyeLeftp		= (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
-	mEyeRightp		= (LLViewerJoint*)mRoot.findJoint("mEyeRight");
-
-	//-------------------------------------------------------------------------
-	// Make sure "well known" pointers exist
-	//-------------------------------------------------------------------------
-	if (!(mPelvisp && 
-		  mTorsop &&
-		  mChestp &&
-		  mNeckp &&
-		  mHeadp &&
-		  mSkullp &&
-		  mHipLeftp &&
-		  mHipRightp &&
-		  mKneeLeftp &&
-		  mKneeRightp &&
-		  mAnkleLeftp &&
-		  mAnkleRightp &&
-		  mFootLeftp &&
-		  mFootRightp &&
-		  mWristLeftp &&
-		  mWristRightp &&
-		  mEyeLeftp &&
-		  mEyeRightp))
-	{
-		llerrs << "Failed to create avatar." << llendl;
-		return;
-	}
-
-	//-------------------------------------------------------------------------
-	// initialize the pelvis
-	//-------------------------------------------------------------------------
-	mPelvisp->setPosition( LLVector3(0.0f, 0.0f, 0.0f) );
-	
-	//-------------------------------------------------------------------------
-	// set head offset from pelvis
-	//-------------------------------------------------------------------------
-	updateHeadOffset();
-
-	//-------------------------------------------------------------------------
-	// initialize lip sync morph pointers
-	//-------------------------------------------------------------------------
-	mOohMorph     = getVisualParam( "Lipsync_Ooh" );
-	mAahMorph     = getVisualParam( "Lipsync_Aah" );
+	mOohMorph     = getVisualParam( "Lipsync_Ooh" );
+	mAahMorph     = getVisualParam( "Lipsync_Aah" );
 
 	// If we don't have the Ooh morph, use the Kiss morph
 	if (!mOohMorph)
@@ -2071,11 +1634,11 @@ void LLVOAvatar::releaseMeshData()
 	//llinfos << "Releasing" << llendl;
 
 	// cleanup mesh data
-	for (std::vector<LLViewerJoint*>::iterator iter = mMeshLOD.begin();
+	for (avatar_joint_list_t::iterator iter = mMeshLOD.begin();
 		 iter != mMeshLOD.end(); 
 		 ++iter)
 	{
-		LLViewerJoint* joint = (LLViewerJoint*) *iter;
+		LLAvatarJoint* joint = (*iter);
 		joint->setValid(FALSE, TRUE);
 	}
 
@@ -2085,15 +1648,15 @@ void LLVOAvatar::releaseMeshData()
 		LLFace* facep = mDrawable->getFace(0);
 		if (facep)
 		{
-			facep->setSize(0, 0);
-			for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
-			{
-				facep = mDrawable->getFace(i);
+		facep->setSize(0, 0);
+		for(S32 i = mNumInitFaces ; i < mDrawable->getNumFaces(); i++)
+		{
+			facep = mDrawable->getFace(i);
 				if (facep)
 				{
-					facep->setSize(0, 0);
-				}
-			}
+			facep->setSize(0, 0);
+		}
+	}
 		}
 	}
 	
@@ -2164,7 +1727,11 @@ void LLVOAvatar::updateMeshData()
 				last_v_num = num_vertices ;
 				last_i_num = num_indices ;
 
-				mMeshLOD[part_index++]->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+				LLViewerJoint* part_mesh = getViewerJoint(part_index++);
+				if (part_mesh)
+				{
+					part_mesh->updateFaceSizes(num_vertices, num_indices, mAdjustedPixelArea);
+				}
 			}
 			if(num_vertices < 1)//skip empty meshes
 			{
@@ -2238,7 +1805,11 @@ void LLVOAvatar::updateMeshData()
 					rigid = true;
 				}
 				
-				mMeshLOD[k]->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+				LLViewerJoint* mesh = getViewerJoint(k);
+				if (mesh)
+				{
+					mesh->updateFaceData(facep, mAdjustedPixelArea, k == MESH_ID_HAIR, terse_update && !rigid);
+				}
 			}
 
 			stop_glerror();
@@ -2258,72 +1829,6 @@ void LLVOAvatar::updateMeshData()
 
 //------------------------------------------------------------------------
 
-//------------------------------------------------------------------------
-// The viewer can only suggest a good size for the agent,
-// the simulator will keep it inside a reasonable range.
-void LLVOAvatar::computeBodySize() 
-{
-	LLVector3 pelvis_scale = mPelvisp->getScale();
-
-	// some of the joints have not been cached
-	LLVector3 skull = mSkullp->getPosition();
-	LLVector3 skull_scale = mSkullp->getScale();
-
-	LLVector3 neck = mNeckp->getPosition();
-	LLVector3 neck_scale = mNeckp->getScale();
-
-	LLVector3 chest = mChestp->getPosition();
-	LLVector3 chest_scale = mChestp->getScale();
-
-	// the rest of the joints have been cached
-	LLVector3 head = mHeadp->getPosition();
-	LLVector3 head_scale = mHeadp->getScale();
-
-	LLVector3 torso = mTorsop->getPosition();
-	LLVector3 torso_scale = mTorsop->getScale();
-
-	LLVector3 hip = mHipLeftp->getPosition();
-	LLVector3 hip_scale = mHipLeftp->getScale();
-
-	LLVector3 knee = mKneeLeftp->getPosition();
-	LLVector3 knee_scale = mKneeLeftp->getScale();
-
-	LLVector3 ankle = mAnkleLeftp->getPosition();
-	LLVector3 ankle_scale = mAnkleLeftp->getScale();
-
-	LLVector3 foot  = mFootLeftp->getPosition();
-
-	mPelvisToFoot = hip.mV[VZ] * pelvis_scale.mV[VZ] -
-				 	knee.mV[VZ] * hip_scale.mV[VZ] -
-				 	ankle.mV[VZ] * knee_scale.mV[VZ] -
-				 	foot.mV[VZ] * ankle_scale.mV[VZ];
-
-	LLVector3 new_body_size;
-	new_body_size.mV[VZ] = mPelvisToFoot +
-					   // the sqrt(2) correction below is an approximate
-					   // correction to get to the top of the head
-					   F_SQRT2 * (skull.mV[VZ] * head_scale.mV[VZ]) + 
-					   head.mV[VZ] * neck_scale.mV[VZ] + 
-					   neck.mV[VZ] * chest_scale.mV[VZ] + 
-					   chest.mV[VZ] * torso_scale.mV[VZ] + 
-					   torso.mV[VZ] * pelvis_scale.mV[VZ]; 
-
-	// TODO -- measure the real depth and width
-	new_body_size.mV[VX] = DEFAULT_AGENT_DEPTH;
-	new_body_size.mV[VY] = DEFAULT_AGENT_WIDTH;
-
-	if (new_body_size != mBodySize)
-	{
-		mBodySize = new_body_size;
-
-		if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
-		{	// notify simulator of change in size
-			// but not if we are in the middle of updating appearance
-			gAgent.sendAgentSetAppearance();
-		}
-	}
-}
-
 //------------------------------------------------------------------------
 // LLVOAvatar::processUpdateMessage()
 //------------------------------------------------------------------------
@@ -2332,18 +1837,17 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
 									 U32 block_num, const EObjectUpdateType update_type,
 									 LLDataPacker *dp)
 {
-	LLVector3 old_vel = getVelocity();
 	const BOOL has_name = !getNVPair("FirstName");
 
 	// Do base class updates...
 	U32 retval = LLViewerObject::processUpdateMessage(mesgsys, user_data, block_num, update_type, dp);
 
 	// Print out arrival information once we have name of avatar.
-	if (has_name && getNVPair("FirstName"))
-	{
-		mDebugExistenceTimer.reset();
+		if (has_name && getNVPair("FirstName"))
+		{
+			mDebugExistenceTimer.reset();
 		debugAvatarRezTime("AvatarRezArrivedNotification","avatar arrived");
-	}
+		}
 
 	if(retval & LLViewerObject::INVALID_UPDATE)
 	{
@@ -2360,20 +1864,50 @@ U32 LLVOAvatar::processUpdateMessage(LLMessageSystem *mesgsys,
 	return retval;
 }
 
-// virtual
-S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+LLViewerFetchedTexture *LLVOAvatar::getBakedTextureImage(const U8 te, const LLUUID& uuid)
 {
-	// The core setTETexture() method requests images, so we need
-	// to redirect certain avatar texture requests to different sims.
-	if (isIndexBakedTexture((ETextureIndex)te))
+	LLViewerFetchedTexture *result = NULL;
+
+	if (uuid == IMG_DEFAULT_AVATAR ||
+		uuid == IMG_DEFAULT ||
+		uuid == IMG_INVISIBLE)
 	{
-		LLHost target_host = getObjectHost();
-		return setTETextureCore(te, uuid, target_host);
+		// Should already exist, don't need to find it on sim or baked-texture host.
+		result = gTextureList.findImage(uuid);
 	}
-	else
+
+	if (!result)
+	{
+		const std::string url = getImageURL(te,uuid);
+		if (!url.empty())
+		{
+			LL_DEBUGS("Avatar") << avString() << "from URL " << url << llendl;
+			result = LLViewerTextureManager::getFetchedTextureFromUrl(
+				url, FTT_SERVER_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, uuid);
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << avString() << "from host " << uuid << llendl;
+			LLHost host = getObjectHost();
+			result = LLViewerTextureManager::getFetchedTexture(
+				uuid, FTT_HOST_BAKE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE, 0, 0, host);
+		}
+	}
+	return result;
+}
+
+// virtual
+S32 LLVOAvatar::setTETexture(const U8 te, const LLUUID& uuid)
+{
+	if (!isIndexBakedTexture((ETextureIndex)te))
 	{
-		return setTETextureCore(te, uuid, LLHost::invalid);
+		// Sim still sends some uuids for non-baked slots sometimes - ignore.
+		return LLViewerObject::setTETexture(te, LLUUID::null);
 	}
+
+	LLViewerFetchedTexture *image = getBakedTextureImage(te,uuid);
+	llassert(image);
+	return setTETextureCore(te, image);
 }
 
 static LLFastTimer::DeclareTimer FTM_AVATAR_UPDATE("Avatar Update");
@@ -2419,7 +1953,8 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 		return;
 	}	
 
- 	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR)))
+	if (!(gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_AVATAR))
+		&& !(gSavedSettings.getBOOL("DisableAllRenderTypes")))
 	{
 		return;
 	}
@@ -2484,7 +2019,7 @@ void LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 	
 	// animate the character
 	// store off last frame's root position to be consistent with camera position
-	LLVector3 root_pos_last = mRoot.getWorldPosition();
+	LLVector3 root_pos_last = mRoot->getWorldPosition();
 	BOOL detailed_update = updateCharacter(agent);
 
 	static LLUICachedControl<bool> visualizers_in_calls("ShowVoiceVisualizersInCalls", false);
@@ -2603,11 +2138,11 @@ void LLVOAvatar::idleUpdateVoiceVisualizer(bool voice_enabled)
 		if ( mIsSitting )
 		{
 			LLVector3 headOffset = LLVector3( 0.0f, 0.0f, mHeadOffset.mV[2] );
-			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot.getWorldPosition() + headOffset );
+			mVoiceVisualizer->setVoiceSourceWorldPosition( mRoot->getWorldPosition() + headOffset );
 		}
 		else 
 		{
-			LLVector3 tagPos = mRoot.getWorldPosition();
+			LLVector3 tagPos = mRoot->getWorldPosition();
 			tagPos[VZ] -= mPelvisToFoot;
 			tagPos[VZ] += ( mBodySize[VZ] + 0.125f );
 			mVoiceVisualizer->setVoiceSourceWorldPosition( tagPos );
@@ -2851,8 +2386,8 @@ void LLVOAvatar::idleUpdateLoadingEffect()
 		{
 			LL_INFOS("Avatar") << avString() << "self isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
 			mFirstFullyVisible = FALSE;
-			LLAppearanceMgr::instance().onFirstFullyVisible();
-		}
+				LLAppearanceMgr::instance().onFirstFullyVisible();
+			}
 		if (isFullyLoaded() && mFirstFullyVisible && !isSelf())
 		{
 			LL_INFOS("Avatar") << avString() << "other isFullyLoaded, mFirstFullyVisible" << LL_ENDL;
@@ -3006,7 +2541,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		mVisibleChat = visible_chat;
 		new_name = TRUE;
 	}
-		
+
 	if (sRenderGroupTitles != mRenderGroupTitles)
 	{
 		mRenderGroupTitles = sRenderGroupTitles;
@@ -3049,7 +2584,7 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 	if (!mNameText)
 	{
 		mNameText = static_cast<LLHUDNameTag*>( LLHUDObject::addHUDObject(
-													LLHUDObject::LL_HUD_NAME_TAG) );
+			LLHUDObject::LL_HUD_NAME_TAG) );
 		//mNameText->setMass(10.f);
 		mNameText->setSourceObject(this);
 		mNameText->setVertAlignment(LLHUDNameTag::ALIGN_VERT_TOP);
@@ -3058,10 +2593,9 @@ void LLVOAvatar::idleUpdateNameTag(const LLVector3& root_pos_last)
 		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS, 5.f);
 		sNumVisibleChatBubbles++;
 		new_name = TRUE;
-	}
+    }
 				
-	LLVector3 name_position = idleUpdateNameTagPosition(root_pos_last);
-	mNameText->setPositionAgent(name_position);				
+	idleUpdateNameTagPosition(root_pos_last);
 	idleUpdateNameTagText(new_name);			
 	idleUpdateNameTagAlpha(new_name, alpha);
 }
@@ -3076,7 +2610,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 	if (!firstname || !lastname) return;
 
 	bool is_away = mSignaledAnimations.find(ANIM_AGENT_AWAY)  != mSignaledAnimations.end();
-	bool is_busy = mSignaledAnimations.find(ANIM_AGENT_BUSY) != mSignaledAnimations.end();
+	bool is_do_not_disturb = mSignaledAnimations.find(ANIM_AGENT_DO_NOT_DISTURB) != mSignaledAnimations.end();
 	bool is_appearance = mSignaledAnimations.find(ANIM_AGENT_CUSTOMIZE) != mSignaledAnimations.end();
 	bool is_muted;
 	if (isSelf())
@@ -3103,12 +2637,12 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 	}
 
 	// Rebuild name tag if state change detected
-	if (mNameString.empty()
+	if (!mNameIsSet
 		|| new_name
 		|| (!title && !mTitle.empty())
 		|| (title && mTitle != title->getString())
 		|| is_away != mNameAway 
-		|| is_busy != mNameBusy 
+		|| is_do_not_disturb != mNameDoNotDisturb 
 		|| is_muted != mNameMute
 		|| is_appearance != mNameAppearance 
 		|| is_friend != mNameFriend
@@ -3118,7 +2652,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 
 		clearNameTag();
 
-		if (is_away || is_muted || is_busy || is_appearance)
+		if (is_away || is_muted || is_do_not_disturb || is_appearance)
 		{
 			std::string line;
 			if (is_away)
@@ -3126,9 +2660,9 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 				line += LLTrans::getString("AvatarAway");
 				line += ", ";
 			}
-			if (is_busy)
+			if (is_do_not_disturb)
 			{
-				line += LLTrans::getString("AvatarBusy");
+				line += LLTrans::getString("AvatarDoNotDisturb");
 				line += ", ";
 			}
 			if (is_muted)
@@ -3149,7 +2683,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			// trim last ", "
 			line.resize( line.length() - 2 );
 			addNameTagLine(line, name_tag_color, LLFontGL::NORMAL,
-						   LLFontGL::getFontSansSerifSmall());
+				LLFontGL::getFontSansSerifSmall());
 		}
 
 		if (sRenderGroupTitles
@@ -3158,48 +2692,46 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			std::string title_str = title->getString();
 			LLStringFn::replace_ascii_controlchars(title_str,LL_UNKNOWN_CHAR);
 			addNameTagLine(title_str, name_tag_color, LLFontGL::NORMAL,
-						   LLFontGL::getFontSansSerifSmall());
+				LLFontGL::getFontSansSerifSmall());
 		}
 
 		static LLUICachedControl<bool> show_display_names("NameTagShowDisplayNames");
 		static LLUICachedControl<bool> show_usernames("NameTagShowUsernames");
 
-		if (LLAvatarNameCache::useDisplayNames())
+		if (LLAvatarName::useDisplayNames())
 		{
 			LLAvatarName av_name;
 			if (!LLAvatarNameCache::get(getID(), &av_name))
 			{
-				// ...call this function back when the name arrives
-				// and force a rebuild
-				LLAvatarNameCache::get(getID(),
-									   boost::bind(&LLVOAvatar::clearNameTag, this));
+				// Force a rebuild at next idle
+				// Note: do not connect a callback on idle().
+				clearNameTag();
 			}
 
 			// Might be blank if name not available yet, that's OK
 			if (show_display_names)
 			{
-				addNameTagLine(av_name.mDisplayName, name_tag_color, LLFontGL::NORMAL,
-							   LLFontGL::getFontSansSerif());
+				addNameTagLine(av_name.getDisplayName(), name_tag_color, LLFontGL::NORMAL,
+					LLFontGL::getFontSansSerif());
 			}
 			// Suppress SLID display if display name matches exactly (ugh)
-			if (show_usernames && !av_name.mIsDisplayNameDefault)
+			if (show_usernames && !av_name.isDisplayNameDefault())
 			{
 				// *HACK: Desaturate the color
 				LLColor4 username_color = name_tag_color * 0.83f;
-				addNameTagLine(av_name.mUsername, username_color, LLFontGL::NORMAL,
-							   LLFontGL::getFontSansSerifSmall());
+				addNameTagLine(av_name.getUserName(), username_color, LLFontGL::NORMAL,
+					LLFontGL::getFontSansSerifSmall());
 			}
 		}
 		else
 		{
 			const LLFontGL* font = LLFontGL::getFontSansSerif();
-			std::string full_name =
-				LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
+			std::string full_name = LLCacheName::buildFullName( firstname->getString(), lastname->getString() );
 			addNameTagLine(full_name, name_tag_color, LLFontGL::NORMAL, font);
 		}
 
 		mNameAway = is_away;
-		mNameBusy = is_busy;
+		mNameDoNotDisturb = is_do_not_disturb;
 		mNameMute = is_muted;
 		mNameAppearance = is_appearance;
 		mNameFriend = is_friend;
@@ -3214,9 +2746,7 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 		mNameText->setFont(LLFontGL::getFontSansSerif());
 		mNameText->setTextAlignment(LLHUDNameTag::ALIGN_TEXT_LEFT);
 		mNameText->setFadeDistance(CHAT_NORMAL_RADIUS * 2.f, 5.f);
-			
-		char line[MAX_STRING];		/* Flawfinder: ignore */
-		line[0] = '\0';
+
 		std::deque<LLChat>::iterator chat_iter = mChats.begin();
 		mNameText->clearString();
 
@@ -3234,13 +2764,13 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			LLFontGL::StyleFlags style;
 			switch(chat_iter->mChatType)
 			{
-				case CHAT_TYPE_WHISPER:
+			case CHAT_TYPE_WHISPER:
 				style = LLFontGL::ITALIC;
 				break;
-				case CHAT_TYPE_SHOUT:
+			case CHAT_TYPE_SHOUT:
 				style = LLFontGL::BOLD;
 				break;
-				default:
+			default:
 				style = LLFontGL::NORMAL;
 				break;
 			}
@@ -3267,13 +2797,13 @@ void LLVOAvatar::idleUpdateNameTagText(BOOL new_name)
 			S32 dot_count = (llfloor(mTypingTimer.getElapsedTimeF32() * 3.f) + 2) % 3 + 1;
 			switch(dot_count)
 			{
-				case 1:
+			case 1:
 				mNameText->addLine(".", new_chat);
 				break;
-				case 2:
+			case 2:
 				mNameText->addLine("..", new_chat);
 				break;
-				case 3:
+			case 3:
 				mNameText->addLine("...", new_chat);
 				break;
 			}
@@ -3300,18 +2830,18 @@ void LLVOAvatar::addNameTagLine(const std::string& line, const LLColor4& color,
 	{
 		mNameText->addLine(line, color, (LLFontGL::StyleFlags)style, font);
 	}
-	mNameString += line;
-	mNameString += '\n';
+    mNameIsSet |= !line.empty();
 }
 
 void LLVOAvatar::clearNameTag()
 {
-	mNameString.clear();
+    mNameIsSet = false;
 	if (mNameText)
 	{
 		mNameText->setLabel("");
-		mNameText->setString( "" );
+		mNameText->setString("");
 	}
+	mTimeVisible.reset();
 }
 
 //static
@@ -3337,34 +2867,45 @@ void LLVOAvatar::invalidateNameTags()
 		if (avatar->isDead()) continue;
 
 		avatar->clearNameTag();
-
 	}
 }
 
 // Compute name tag position during idle update
-LLVector3 LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
+void LLVOAvatar::idleUpdateNameTagPosition(const LLVector3& root_pos_last)
 {
-	LLQuaternion root_rot = mRoot.getWorldRotation();
+	LLQuaternion root_rot = mRoot->getWorldRotation();
+	LLQuaternion inv_root_rot = ~root_rot;
 	LLVector3 pixel_right_vec;
 	LLVector3 pixel_up_vec;
 	LLViewerCamera::getInstance()->getPixelVectors(root_pos_last, pixel_up_vec, pixel_right_vec);
 	LLVector3 camera_to_av = root_pos_last - LLViewerCamera::getInstance()->getOrigin();
 	camera_to_av.normalize();
-	LLVector3 local_camera_at = camera_to_av * ~root_rot;
+	LLVector3 local_camera_at = camera_to_av * inv_root_rot;
 	LLVector3 local_camera_up = camera_to_av % LLViewerCamera::getInstance()->getLeftAxis();
 	local_camera_up.normalize();
-	local_camera_up = local_camera_up * ~root_rot;
+	local_camera_up = local_camera_up * inv_root_rot;
+
+	LLVector3 avatar_ellipsoid(mBodySize.mV[VX] * 0.4f,
+								mBodySize.mV[VY] * 0.4f,
+								mBodySize.mV[VZ] * NAMETAG_VERT_OFFSET_WEIGHT);
+
+	local_camera_up.scaleVec(avatar_ellipsoid);
+	local_camera_at.scaleVec(avatar_ellipsoid);
 
-	local_camera_up.scaleVec(mBodySize * 0.5f);
-	local_camera_at.scaleVec(mBodySize * 0.5f);
+	LLVector3 head_offset = (mHeadp->getLastWorldPosition() - mRoot->getLastWorldPosition()) * inv_root_rot;
+
+	if (dist_vec(head_offset, mTargetRootToHeadOffset) > NAMETAG_UPDATE_THRESHOLD)
+	{
+		mTargetRootToHeadOffset = head_offset;
+	}
+	
+	mCurRootToHeadOffset = lerp(mCurRootToHeadOffset, mTargetRootToHeadOffset, LLCriticalDamp::getInterpolant(0.2f));
 
-	LLVector3 name_position = mRoot.getWorldPosition();
-	name_position[VZ] -= mPelvisToFoot;
-	name_position[VZ] += (mBodySize[VZ]* 0.55f);
+	LLVector3 name_position = mRoot->getLastWorldPosition() + (mCurRootToHeadOffset * root_rot);
 	name_position += (local_camera_up * root_rot) - (projected_vec(local_camera_at * root_rot, camera_to_av));	
-	name_position += pixel_up_vec * 15.f;
+	name_position += pixel_up_vec * NAMETAG_VERTICAL_SCREEN_OFFSET;
 
-	return name_position;
+	mNameText->setPositionAgent(name_position);				
 }
 
 void LLVOAvatar::idleUpdateNameTagAlpha(BOOL new_name, F32 alpha)
@@ -3387,20 +2928,18 @@ LLColor4 LLVOAvatar::getNameTagColor(bool is_friend)
 	{
 		color_name = "NameTagFriend";
 	}
-	else if (LLAvatarNameCache::useDisplayNames())
+	else if (LLAvatarName::useDisplayNames())
 	{
-		// ...color based on whether username "matches" a computed display
-		// name
+		// ...color based on whether username "matches" a computed display name
 		LLAvatarName av_name;
-		if (LLAvatarNameCache::get(getID(), &av_name)
-			&& av_name.mIsDisplayNameDefault)
+		if (LLAvatarNameCache::get(getID(), &av_name) && av_name.isDisplayNameDefault())
 		{
 			color_name = "NameTagMatch";
 		}
 		else
 		{
 			color_name = "NameTagMismatch";
-	}
+		}
 	}
 	else
 	{
@@ -3423,13 +2962,13 @@ void LLVOAvatar::idleUpdateBelowWater()
 void LLVOAvatar::slamPosition()
 {
 	gAgent.setPositionAgent(getPositionAgent());
-	mRoot.setWorldPosition(getPositionAgent()); // teleport
+	mRoot->setWorldPosition(getPositionAgent()); // teleport
 	setChanged(TRANSLATED);
 	if (mDrawable.notNull())
 	{
 		gPipeline.updateMoveNormalAsync(mDrawable);
 	}
-	mRoot.updateWorldMatrixChildren();
+	mRoot->updateWorldMatrixChildren();
 }
 
 bool LLVOAvatar::isVisuallyMuted() const
@@ -3437,9 +2976,9 @@ bool LLVOAvatar::isVisuallyMuted() const
 	static LLCachedControl<U32> max_attachment_bytes(gSavedSettings, "RenderAutoMuteByteLimit");
 	static LLCachedControl<F32> max_attachment_area(gSavedSettings, "RenderAutoMuteSurfaceAreaLimit");
 	
-	return LLMuteList::getInstance()->isMuted(getID()) ||
-			(mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) ||
-			(mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
+	return LLMuteList::getInstance()->isMuted(getID()) 
+			|| (mAttachmentGeometryBytes > max_attachment_bytes && max_attachment_bytes > 0) 
+			|| (mAttachmentSurfaceArea > max_attachment_area && max_attachment_area > 0.f);
 }
 
 //------------------------------------------------------------------------
@@ -3450,6 +2989,47 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 {
 	// clear debug text
 	mDebugText.clear();
+
+	if (gSavedSettings.getBOOL("DebugAvatarAppearanceMessage"))
+	{
+		S32 central_bake_version = -1;
+		if (getRegion())
+		{
+			central_bake_version = getRegion()->getCentralBakeVersion();
+		}
+		bool all_baked_downloaded = allBakedTexturesCompletelyDownloaded();
+		bool all_local_downloaded = allLocalTexturesCompletelyDownloaded();
+		std::string debug_line = llformat("%s%s - mLocal: %d, mEdit: %d, mUSB: %d, CBV: %d",
+										  isSelf() ? (all_local_downloaded ? "L" : "l") : "-",
+										  all_baked_downloaded ? "B" : "b",
+										  mUseLocalAppearance, mIsEditingAppearance,
+										  mUseServerBakes, central_bake_version);
+		std::string origin_string = bakedTextureOriginInfo();
+		debug_line += " [" + origin_string + "]";
+		S32 curr_cof_version = LLAppearanceMgr::instance().getCOFVersion();
+		S32 last_request_cof_version = mLastUpdateRequestCOFVersion;
+		S32 last_received_cof_version = mLastUpdateReceivedCOFVersion;
+		if (isSelf())
+		{
+			debug_line += llformat(" - cof: %d req: %d rcv:%d",
+								   curr_cof_version, last_request_cof_version, last_received_cof_version);
+			if (gSavedSettings.getBOOL("DebugForceAppearanceRequestFailure"))
+			{
+				debug_line += " FORCING ERRS";
+			}
+		}
+		else
+		{
+			debug_line += llformat(" - cof rcv:%d", last_received_cof_version);
+		}
+		addDebugText(debug_line);
+	}
+	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+	{
+		if (!mBakedTextureDebugText.empty())
+			addDebugText(mBakedTextureDebugText);
+	}
+				 
 	if (LLVOAvatar::sShowAnimationDebug)
 	{
 		for (LLMotionController::motion_list_t::iterator iter = mMotionController.getActiveMotions().begin();
@@ -3478,8 +3058,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	LLVector3d root_pos_global;
-
 	if (!mIsBuilt)
 	{
 		return FALSE;
@@ -3494,7 +3072,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		mTimeVisible.reset();
 	}
 
-	
 	//--------------------------------------------------------------------
 	// the rest should only be done occasionally for far away avatars
 	//--------------------------------------------------------------------
@@ -3589,8 +3166,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 	xyVel.mV[VZ] = 0.0f;
 	speed = xyVel.length();
 
-	BOOL throttle = TRUE;
-
 	if (!(mIsSitting && getParent()))
 	{
 		//--------------------------------------------------------------------
@@ -3601,11 +3176,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		if (mTimeLast == 0.0f)
 		{
 			mTimeLast = animation_time;
-			throttle = FALSE;
 
 			// put the pelvis at slaved position/mRotation
-			mRoot.setWorldPosition( getPositionAgent() ); // first frame
-			mRoot.setWorldRotation( getRotation() );
+			mRoot->setWorldPosition( getPositionAgent() ); // first frame
+			mRoot->setWorldRotation( getRotation() );
 		}
 	
 		//--------------------------------------------------------------------
@@ -3630,6 +3204,8 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 
 		root_pos = gAgent.getPosGlobalFromAgent(getRenderPosition());
+		root_pos.mdV[VZ] += getVisualParamWeight(AVATAR_HOVER);
+
 
 		resolveHeightGlobal(root_pos, ground_under_pelvis, normal);
 		F32 foot_to_ground = (F32) (root_pos.mdV[VZ] - mPelvisToFoot - ground_under_pelvis.mdV[VZ]);				
@@ -3648,10 +3224,10 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		
 		LLVector3 newPosition = gAgent.getPosAgentFromGlobal(root_pos);
 
-		if (newPosition != mRoot.getXform()->getWorldPosition())
+		if (newPosition != mRoot->getXform()->getWorldPosition())
 		{		
-			mRoot.touch();
-			mRoot.setWorldPosition( newPosition ); // regular update				
+			mRoot->touch();
+			mRoot->setWorldPosition( newPosition ); // regular update				
 		}
 
 
@@ -3712,7 +3288,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 				
 			}
 
-			LLQuaternion root_rotation = mRoot.getWorldMatrix().quaternion();
+			LLQuaternion root_rotation = mRoot->getWorldMatrix().quaternion();
 			F32 root_roll, root_pitch, root_yaw;
 			root_rotation.getEulerAngles(&root_roll, &root_pitch, &root_yaw);
 
@@ -3721,7 +3297,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 			// and head turn.  Once in motion, it must conform however.
 			BOOL self_in_mouselook = isSelf() && gAgentCamera.cameraMouselook();
 
-			LLVector3 pelvisDir( mRoot.getWorldMatrix().getFwdRow4().mV );
+			LLVector3 pelvisDir( mRoot->getWorldMatrix().getFwdRow4().mV );
 
 			static LLCachedControl<F32> s_pelvis_rot_threshold_slow(gSavedSettings, "AvatarRotateThresholdSlow");
 			static LLCachedControl<F32> s_pelvis_rot_threshold_fast(gSavedSettings, "AvatarRotateThresholdFast");
@@ -3807,14 +3383,14 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 			F32 u = llclamp((deltaTime / pelvis_lag_time), 0.0f, 1.0f);	
 
-			mRoot.setWorldRotation( slerp(u, mRoot.getWorldRotation(), wQv) );
+			mRoot->setWorldRotation( slerp(u, mRoot->getWorldRotation(), wQv) );
 			
 		}
 	}
 	else if (mDrawable.notNull())
 	{
-		mRoot.setPosition(mDrawable->getPosition());
-		mRoot.setRotation(mDrawable->getRotation());
+		mRoot->setPosition(mDrawable->getPosition());
+		mRoot->setRotation(mDrawable->getRotation());
 	}
 	
 	//-------------------------------------------------------------------------
@@ -3897,10 +3473,6 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 
 		if ( playSound )
 		{
-//			F32 gain = clamp_rescale( mSpeedAccum,
-//							AUDIO_STEP_LO_SPEED, AUDIO_STEP_HI_SPEED,
-//							AUDIO_STEP_LO_GAIN, AUDIO_STEP_HI_GAIN );
-
 			const F32 STEP_VOLUME = 0.1f;
 			const LLUUID& step_sound_id = getStepSound();
 
@@ -3914,7 +3486,7 @@ BOOL LLVOAvatar::updateCharacter(LLAgent &agent)
 		}
 	}
 
-	mRoot.updateWorldMatrixChildren();
+	mRoot->updateWorldMatrixChildren();
 
 	if (!mDebugText.size() && mText.notNull())
 	{
@@ -3938,7 +3510,7 @@ void LLVOAvatar::updateHeadOffset()
 {
 	// since we only care about Z, just grab one of the eyes
 	LLVector3 midEyePt = mEyeLeftp->getWorldPosition();
-	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot.getWorldPosition();
+	midEyePt -= mDrawable.notNull() ? mDrawable->getWorldPosition() : mRoot->getWorldPosition();
 	midEyePt.mV[VZ] = llmax(-mPelvisToFoot + LLViewerCamera::getInstance()->getNear(), midEyePt.mV[VZ]);
 
 	if (mDrawable.notNull())
@@ -3976,8 +3548,8 @@ void LLVOAvatar::setPelvisOffset( bool hasOffset, const LLVector3& offsetAmount,
 void LLVOAvatar::postPelvisSetRecalc( void )
 {	
 	computeBodySize(); 
-	mRoot.touch();
-	mRoot.updateWorldMatrixChildren();	
+	mRoot->touch();
+	mRoot->updateWorldMatrixChildren();	
 	dirtyMesh();
 	updateHeadOffset();
 }
@@ -4117,13 +3689,6 @@ void LLVOAvatar::updateVisibility()
 		{
 			releaseMeshData();
 		}
-		// this breaks off-screen chat bubbles
-		//if (mNameText)
-		//{
-		//	mNameText->markDead();
-		//	mNameText = NULL;
-		//	sNumVisibleChatBubbles--;
-		//}
 	}
 
 	mVisible = visible;
@@ -4132,53 +3697,13 @@ void LLVOAvatar::updateVisibility()
 // private
 bool LLVOAvatar::shouldAlphaMask()
 {
-	const bool should_alpha_mask = mSupportsAlphaLayers && !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
+	const bool should_alpha_mask = !LLDrawPoolAlpha::sShowDebugAlpha // Don't alpha mask if "Highlight Transparent" checked
 							&& !LLDrawPoolAvatar::sSkipTransparent;
 
 	return should_alpha_mask;
 
 }
 
-U32 LLVOAvatar::renderSkinnedAttachments()
-{
-	/*U32 num_indices = 0;
-	
-	const U32 data_mask =	LLVertexBuffer::MAP_VERTEX | 
-							LLVertexBuffer::MAP_NORMAL | 
-							LLVertexBuffer::MAP_TEXCOORD0 |
-							LLVertexBuffer::MAP_COLOR |
-							LLVertexBuffer::MAP_WEIGHT4;
-
-	for (attachment_map_t::const_iterator iter = mAttachmentPoints.begin(); 
-		 iter != mAttachmentPoints.end();
-		 ++iter)
-	{
-		LLViewerJointAttachment* attachment = iter->second;
-		for (LLViewerJointAttachment::attachedobjs_vec_t::iterator attachment_iter = attachment->mAttachedObjects.begin();
-			 attachment_iter != attachment->mAttachedObjects.end();
-			 ++attachment_iter)
-		{
-			const LLViewerObject* attached_object = (*attachment_iter);
-			if (attached_object && !attached_object->isHUDAttachment())
-			{
-				const LLDrawable* drawable = attached_object->mDrawable;
-				if (drawable)
-				{
-					for (S32 i = 0; i < drawable->getNumFaces(); ++i)
-					{
-						LLFace* face = drawable->getFace(i);
-						if (face->isState(LLFace::RIGGED))
-						{
-							
-				}
-			}
-		}
-	}
-
-	return num_indices;*/
-	return 0;
-}
-
 //-----------------------------------------------------------------------------
 // renderSkinned()
 //-----------------------------------------------------------------------------
@@ -4199,11 +3724,11 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 	{	//LOD changed or new mesh created, allocate new vertex buffer if needed
 		if (needs_rebuild || mDirtyMesh >= 2 || mVisibilityRank <= 4)
 		{
-			updateMeshData();
+		updateMeshData();
 			mDirtyMesh = 0;
-			mNeedsSkin = TRUE;
-			mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
-		}
+		mNeedsSkin = TRUE;
+		mDrawable->clearState(LLDrawable::REBUILD_GEOMETRY);
+	}
 	}
 
 	if (LLViewerShaderMgr::instance()->getVertexShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) <= 0)
@@ -4211,19 +3736,44 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 		if (mNeedsSkin)
 		{
 			//generate animated mesh
-			mMeshLOD[MESH_ID_LOWER_BODY]->updateJointGeometry();
-			mMeshLOD[MESH_ID_UPPER_BODY]->updateJointGeometry();
+			LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+			LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+			LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+			LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+
+			if(upper_mesh)
+			{
+				upper_mesh->updateJointGeometry();
+			}
+			if (lower_mesh)
+			{
+				lower_mesh->updateJointGeometry();
+			}
 
 			if( isWearingWearableType( LLWearableType::WT_SKIRT ) )
 			{
-				mMeshLOD[MESH_ID_SKIRT]->updateJointGeometry();
+				if(skirt_mesh)
+				{
+					skirt_mesh->updateJointGeometry();
+				}
 			}
 
 			if (!isSelf() || gAgent.needsRenderHead() || LLPipeline::sShadowRender)
 			{
-				mMeshLOD[MESH_ID_EYELASH]->updateJointGeometry();
-				mMeshLOD[MESH_ID_HEAD]->updateJointGeometry();
-				mMeshLOD[MESH_ID_HAIR]->updateJointGeometry();
+				if(eyelash_mesh)
+				{
+					eyelash_mesh->updateJointGeometry();
+				}
+				if(head_mesh)
+				{
+					head_mesh->updateJointGeometry();
+				}
+				if(hair_mesh)
+				{
+					hair_mesh->updateJointGeometry();
+				}
 			}
 			mNeedsSkin = FALSE;
 			mLastSkinTime = gFrameTimeSeconds;
@@ -4232,13 +3782,13 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			if (face)
 			{
 				LLVertexBuffer* vb = face->getVertexBuffer();
-				if (vb)
-				{
-					vb->flush();
-				}
+			if (vb)
+			{
+				vb->flush();
 			}
 		}
 	}
+	}
 	else
 	{
 		mNeedsSkin = FALSE;
@@ -4340,19 +3890,31 @@ U32 LLVOAvatar::renderSkinned(EAvatarRenderPass pass)
 			{
 				if (isTextureVisible(TEX_HEAD_BAKED) || mIsDummy)
 				{
-					num_indices += mMeshLOD[MESH_ID_HEAD]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+					LLViewerJoint* head_mesh = getViewerJoint(MESH_ID_HEAD);
+					if (head_mesh)
+					{
+						num_indices += head_mesh->render(mAdjustedPixelArea, TRUE, mIsDummy);
+					}
 					first_pass = FALSE;
 				}
 			}
 			if (isTextureVisible(TEX_UPPER_BAKED) || mIsDummy)
 			{
-				num_indices += mMeshLOD[MESH_ID_UPPER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				LLViewerJoint* upper_mesh = getViewerJoint(MESH_ID_UPPER_BODY);
+				if (upper_mesh)
+				{
+					num_indices += upper_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				}
 				first_pass = FALSE;
 			}
 			
 			if (isTextureVisible(TEX_LOWER_BAKED) || mIsDummy)
 			{
-				num_indices += mMeshLOD[MESH_ID_LOWER_BODY]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				LLViewerJoint* lower_mesh = getViewerJoint(MESH_ID_LOWER_BODY);
+				if (lower_mesh)
+				{
+					num_indices += lower_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+				}
 				first_pass = FALSE;
 			}
 		}
@@ -4385,7 +3947,11 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 	if( isWearingWearableType( LLWearableType::WT_SKIRT ) && (mIsDummy || isTextureVisible(TEX_SKIRT_BAKED)) )
 	{
 		gGL.setAlphaRejectSettings(LLRender::CF_GREATER, 0.25f);
-		num_indices += mMeshLOD[MESH_ID_SKIRT]->render(mAdjustedPixelArea, FALSE);
+		LLViewerJoint* skirt_mesh = getViewerJoint(MESH_ID_SKIRT);
+		if (skirt_mesh)
+		{
+			num_indices += skirt_mesh->render(mAdjustedPixelArea, FALSE);
+		}
 		first_pass = FALSE;
 		gGL.setAlphaRejectSettings(LLRender::CF_DEFAULT);
 	}
@@ -4399,16 +3965,23 @@ U32 LLVOAvatar::renderTransparent(BOOL first_pass)
 		
 		if (isTextureVisible(TEX_HEAD_BAKED))
 		{
-			num_indices += mMeshLOD[MESH_ID_EYELASH]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			LLViewerJoint* eyelash_mesh = getViewerJoint(MESH_ID_EYELASH);
+			if (eyelash_mesh)
+			{
+				num_indices += eyelash_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			}
 			first_pass = FALSE;
 		}
 		// Can't test for baked hair being defined, since that won't always be the case (not all viewers send baked hair)
 		// TODO: 1.25 will be able to switch this logic back to calling isTextureVisible();
-
-		if ( getImage(TEX_HAIR_BAKED, 0)
-			&& getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)
+		if ( getImage(TEX_HAIR_BAKED, 0) && 
+		     getImage(TEX_HAIR_BAKED, 0)->getID() != IMG_INVISIBLE || LLDrawPoolAlpha::sShowDebugAlpha)		
 		{
-			num_indices += mMeshLOD[MESH_ID_HAIR]->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			LLViewerJoint* hair_mesh = getViewerJoint(MESH_ID_HAIR);
+			if (hair_mesh)
+			{
+				num_indices += hair_mesh->render(mAdjustedPixelArea, first_pass, mIsDummy);
+			}
 			first_pass = FALSE;
 		}
 		if (LLPipeline::sImpostorRender)
@@ -4452,8 +4025,16 @@ U32 LLVOAvatar::renderRigid()
 
 	if (isTextureVisible(TEX_EYES_BAKED)  || mIsDummy)
 	{
-		num_indices += mMeshLOD[MESH_ID_EYEBALL_LEFT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
-		num_indices += mMeshLOD[MESH_ID_EYEBALL_RIGHT]->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		LLViewerJoint* eyeball_left = getViewerJoint(MESH_ID_EYEBALL_LEFT);
+		LLViewerJoint* eyeball_right = getViewerJoint(MESH_ID_EYEBALL_RIGHT);
+		if (eyeball_left)
+		{
+			num_indices += eyeball_left->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		}
+		if(eyeball_right)
+		{
+			num_indices += eyeball_right->render(mAdjustedPixelArea, TRUE, mIsDummy);
+		}
 	}
 
 	if (should_alpha_mask && !LLGLSLShader::sNoFixedFunction)
@@ -4500,58 +4081,271 @@ U32 LLVOAvatar::renderImpostor(LLColor4U color, S32 diffuse_channel)
 	return 6;
 }
 
-//------------------------------------------------------------------------
-// LLVOAvatar::updateTextures()
-//------------------------------------------------------------------------
-void LLVOAvatar::updateTextures()
+bool LLVOAvatar::allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const
 {
-	BOOL render_avatar = TRUE;
-
-	if (mIsDummy)
+	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
 	{
-		return;
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		if (imagep && imagep->getDiscardLevel()!=0)
+		{
+			return false;
+		}
 	}
+	return true;
+}
 
-	if( isSelf() )
-	{
-		render_avatar = TRUE;
-	}
-	else
+bool LLVOAvatar::allLocalTexturesCompletelyDownloaded() const
+{
+	std::set<LLUUID> local_ids;
+	collectLocalTextureUUIDs(local_ids);
+	return allTexturesCompletelyDownloaded(local_ids);
+}
+
+bool LLVOAvatar::allBakedTexturesCompletelyDownloaded() const
+{
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
+	return allTexturesCompletelyDownloaded(baked_ids);
+}
+
+void LLVOAvatar::bakedTextureOriginCounts(S32 &sb_count, // server-bake, has origin URL.
+										  S32 &host_count, // host-based bake, has host.
+										  S32 &both_count, // error - both host and URL set.
+										  S32 &neither_count) // error - neither set.
+{
+	sb_count = host_count = both_count = neither_count = 0;
+	
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
+	for (std::set<LLUUID>::const_iterator it = baked_ids.begin(); it != baked_ids.end(); ++it)
 	{
-		if(!isVisible())
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		bool has_url = false, has_host = false;
+		if (!imagep->getUrl().empty())
 		{
-			return ;//do not update for invisible avatar.
+			has_url = true;
 		}
-
-		render_avatar = !mCulled; //visible and not culled.
+		if (imagep->getTargetHost().isOk())
+		{
+			has_host = true;
+		}
+		if (has_url && !has_host) sb_count++;
+		else if (has_host && !has_url) host_count++;
+		else if (has_host && has_url) both_count++;
+		else if (!has_host && !has_url) neither_count++;
 	}
+}
 
-	std::vector<BOOL> layer_baked;
-	// GL NOT ACTIVE HERE - *TODO
+std::string LLVOAvatar::bakedTextureOriginInfo()
+{
+	std::string result;
+	
+	std::set<LLUUID> baked_ids;
+	collectBakedTextureUUIDs(baked_ids);
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex));
-		// bind the texture so that they'll be decoded slightly 
-		// inefficient, we can short-circuit this if we have to
-		if (render_avatar && !gGLManager.mIsDisabled)
+		ETextureIndex texture_index = mBakedTextureDatas[i].mTextureIndex;
+		LLViewerFetchedTexture *imagep =
+			LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+		if (!imagep ||
+			imagep->getID() == IMG_DEFAULT ||
+			imagep->getID() == IMG_DEFAULT_AVATAR)
+			
 		{
-			if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded)
+			result += "-";
+		}
+		else
+		{
+			bool has_url = false, has_host = false;
+			if (!imagep->getUrl().empty())
 			{
-				gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ));
+				has_url = true;
+			}
+			if (imagep->getTargetHost().isOk())
+			{
+				has_host = true;
+			}
+			S32 discard = imagep->getDiscardLevel();
+			if (has_url && !has_host) result += discard ? "u" : "U"; // server-bake texture with url 
+			else if (has_host && !has_url) result += discard ? "h" : "H"; // old-style texture on sim
+			else if (has_host && has_url) result += discard ? "x" : "X"; // both origins?
+			else if (!has_host && !has_url) result += discard ? "n" : "N"; // no origin?
+			if (discard != 0)
+			{
+				result += llformat("(%d/%d)",discard,imagep->getDesiredDiscardLevel());
 			}
 		}
+
 	}
+	return result;
+}
 
-	mMaxPixelArea = 0.f;
-	mMinPixelArea = 99999999.f;
-	mHasGrey = FALSE; // debug
+S32 LLVOAvatar::totalTextureMemForUUIDS(std::set<LLUUID>& ids)
+{
+	S32 result = 0;
+	for (std::set<LLUUID>::const_iterator it = ids.begin(); it != ids.end(); ++it)
+	{
+		LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+		if (imagep)
+		{
+			result += imagep->getTextureMemory();
+		}
+	}
+	return result;
+}
+	
+void LLVOAvatar::collectLocalTextureUUIDs(std::set<LLUUID>& ids) const
+{
 	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
 	{
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType((ETextureIndex)texture_index);
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
 		U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
-		const LLTextureEntry *te = getTE(texture_index);
 
-		// getTE can return 0.
+		LLViewerFetchedTexture *imagep = NULL;
+		for (U32 wearable_index = 0; wearable_index < num_wearables; wearable_index++)
+		{
+			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
+			if (imagep)
+			{
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+				if (texture_dict->mIsLocalTexture)
+				{
+					ids.insert(imagep->getID());
+				}
+			}
+		}
+	}
+	ids.erase(IMG_DEFAULT);
+	ids.erase(IMG_DEFAULT_AVATAR);
+	ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectBakedTextureUUIDs(std::set<LLUUID>& ids) const
+{
+	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+	{
+		LLViewerFetchedTexture *imagep = NULL;
+		if (isIndexBakedTexture((ETextureIndex) texture_index))
+		{
+			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index,0), TRUE);
+			if (imagep)
+			{
+				ids.insert(imagep->getID());
+			}
+		}
+	}
+	ids.erase(IMG_DEFAULT);
+	ids.erase(IMG_DEFAULT_AVATAR);
+	ids.erase(IMG_INVISIBLE);
+}
+
+void LLVOAvatar::collectTextureUUIDs(std::set<LLUUID>& ids)
+{
+	collectLocalTextureUUIDs(ids);
+	collectBakedTextureUUIDs(ids);
+}
+
+void LLVOAvatar::releaseOldTextures()
+{
+	S32 current_texture_mem = 0;
+	
+	// Any textures that we used to be using but are no longer using should no longer be flagged as "NO_DELETE"
+	std::set<LLUUID> baked_texture_ids;
+	collectBakedTextureUUIDs(baked_texture_ids);
+	S32 new_baked_mem = totalTextureMemForUUIDS(baked_texture_ids);
+
+	std::set<LLUUID> local_texture_ids;
+	collectLocalTextureUUIDs(local_texture_ids);
+	//S32 new_local_mem = totalTextureMemForUUIDS(local_texture_ids);
+
+	std::set<LLUUID> new_texture_ids;
+	new_texture_ids.insert(baked_texture_ids.begin(),baked_texture_ids.end());
+	new_texture_ids.insert(local_texture_ids.begin(),local_texture_ids.end());
+	S32 new_total_mem = totalTextureMemForUUIDS(new_texture_ids);
+
+	//S32 old_total_mem = totalTextureMemForUUIDS(mTextureIDs);
+	//LL_DEBUGS("Avatar") << getFullname() << " old_total_mem: " << old_total_mem << " new_total_mem (L/B): " << new_total_mem << " (" << new_local_mem <<", " << new_baked_mem << ")" << llendl;  
+	if (!isSelf() && new_total_mem > new_baked_mem)
+	{
+			llwarns << "extra local textures stored for non-self av" << llendl;
+	}
+	for (std::set<LLUUID>::iterator it = mTextureIDs.begin(); it != mTextureIDs.end(); ++it)
+	{
+		if (new_texture_ids.find(*it) == new_texture_ids.end())
+		{
+			LLViewerFetchedTexture *imagep = gTextureList.findImage(*it);
+			if (imagep)
+			{
+				current_texture_mem += imagep->getTextureMemory();
+				if (imagep->getTextureState() == LLGLTexture::NO_DELETE)
+				{
+					// This will allow the texture to be deleted if not in use.
+					imagep->forceActive();
+
+					// This resets the clock to texture being flagged
+					// as unused, preventing the texture from being
+					// deleted immediately. If other avatars or
+					// objects are using it, it can still be flagged
+					// no-delete by them.
+					imagep->forceUpdateBindStats();
+				}
+			}
+		}
+	}
+	mTextureIDs = new_texture_ids;
+}
+
+void LLVOAvatar::updateTextures()
+{
+	releaseOldTextures();
+	
+	BOOL render_avatar = TRUE;
+
+	if (mIsDummy)
+	{
+		return;
+	}
+
+	if( isSelf() )
+	{
+		render_avatar = TRUE;
+	}
+	else
+	{
+		if(!isVisible())
+		{
+			return ;//do not update for invisible avatar.
+		}
+
+		render_avatar = !mCulled; //visible and not culled.
+	}
+
+	std::vector<BOOL> layer_baked;
+	// GL NOT ACTIVE HERE - *TODO
+	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
+	{
+		layer_baked.push_back(isTextureDefined(mBakedTextureDatas[i].mTextureIndex));
+		// bind the texture so that they'll be decoded slightly 
+		// inefficient, we can short-circuit this if we have to
+		if (render_avatar && !gGLManager.mIsDisabled)
+		{
+			if (layer_baked[i] && !mBakedTextureDatas[i].mIsLoaded)
+			{
+				gGL.getTexUnit(0)->bind(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ));
+			}
+		}
+	}
+
+	mMaxPixelArea = 0.f;
+	mMinPixelArea = 99999999.f;
+	mHasGrey = FALSE; // debug
+	for (U32 texture_index = 0; texture_index < getNumTEs(); texture_index++)
+	{
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)texture_index);
+		U32 num_wearables = gAgentWearables.getWearableCount(wearable_type);
+		const LLTextureEntry *te = getTE(texture_index);
+
+		// getTE can return 0.
 		// Not sure yet why it does, but of course it crashes when te->mScale? gets used.
 		// Put safeguard in place so this corner case get better handling and does not result in a crash.
 		F32 texel_area_ratio = 1.0f;
@@ -4570,11 +4364,11 @@ void LLVOAvatar::updateTextures()
 			imagep = LLViewerTextureManager::staticCastToFetchedTexture(getImage(texture_index, wearable_index), TRUE);
 			if (imagep)
 			{
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)texture_index);
 				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
 				if (texture_dict->mIsLocalTexture)
 				{
-					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, layer_baked[baked_index]);
+					addLocalTextureStats((ETextureIndex)texture_index, imagep, texel_area_ratio, render_avatar, mBakedTextureDatas[baked_index].mIsUsed);
 				}
 			}
 		}
@@ -4586,6 +4380,7 @@ void LLVOAvatar::updateTextures()
 			if (isIndexBakedTexture((ETextureIndex)texture_index)
 				&& imagep->getID() != IMG_DEFAULT_AVATAR
 				&& imagep->getID() != IMG_INVISIBLE
+				&& !isUsingServerBakes() 
 				&& !imagep->getTargetHost().isOk())
 			{
 				LL_WARNS_ONCE("Texture") << "LLVOAvatar::updateTextures No host for texture "
@@ -4606,7 +4401,7 @@ void LLVOAvatar::updateTextures()
 
 
 void LLVOAvatar::addLocalTextureStats( ETextureIndex idx, LLViewerFetchedTexture* imagep,
-									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+									   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
 {
 	// No local texture stats for non-self avatars
 	return;
@@ -4680,7 +4475,6 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
 	//the texture pipeline will stop fetching this texture.
 
 	imagep->resetTextureStats();
-	imagep->setCanUseHTTP(false) ; //turn off http fetching for baked textures.
 	imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
 	imagep->resetMaxVirtualSizeResetCounter() ;
 
@@ -4689,7 +4483,7 @@ void LLVOAvatar::addBakedTextureStats( LLViewerFetchedTexture* imagep, F32 pixel
 	imagep->addTextureStats(pixel_area / texel_area_ratio);
 	imagep->setBoostLevel(boost_level);
 	
-	if(boost_level != LLViewerTexture::BOOST_AVATAR_BAKED_SELF)
+	if(boost_level != LLGLTexture::BOOST_AVATAR_BAKED_SELF)
 	{
 		imagep->setAdditionalDecodePriority(ADDITIONAL_PRI) ;
 	}
@@ -4722,6 +4516,30 @@ void LLVOAvatar::setTexEntry(const U8 index, const LLTextureEntry &te)
 	setTE(index, te);
 }
 
+const std::string LLVOAvatar::getImageURL(const U8 te, const LLUUID &uuid)
+{
+	llassert(isIndexBakedTexture(ETextureIndex(te)));
+	std::string url = "";
+	if (isUsingServerBakes())
+	{
+		const std::string& appearance_service_url = LLAppearanceMgr::instance().getAppearanceServiceURL();
+		if (appearance_service_url.empty())
+		{
+			// Probably a server-side issue if we get here:
+			llwarns << "AgentAppearanceServiceURL not set - Baked texture requests will fail" << llendl;
+			return url;
+		}
+	
+		const LLAvatarAppearanceDictionary::TextureEntry* texture_entry = LLAvatarAppearanceDictionary::getInstance()->getTexture((ETextureIndex)te);
+		if (texture_entry != NULL)
+		{
+			url = appearance_service_url + "texture/" + getID().asString() + "/" + texture_entry->mDefaultImageName + "/" + uuid.asString();
+			//llinfos << "baked texture url: " << url << llendl;
+		}
+	}
+	return url;
+}
+
 //-----------------------------------------------------------------------------
 // resolveHeight()
 //-----------------------------------------------------------------------------
@@ -5062,48 +4880,6 @@ void LLVOAvatar::stopMotionFromSource(const LLUUID& source_id)
 {
 }
 
-//-----------------------------------------------------------------------------
-// getVolumePos()
-//-----------------------------------------------------------------------------
-LLVector3 LLVOAvatar::getVolumePos(S32 joint_index, LLVector3& volume_offset)
-{
-	if (joint_index > mNumCollisionVolumes)
-	{
-		return LLVector3::zero;
-	}
-
-	return mCollisionVolumes[joint_index].getVolumePos(volume_offset);
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-LLJoint* LLVOAvatar::findCollisionVolume(U32 volume_id)
-{
-	if ((S32)volume_id > mNumCollisionVolumes)
-	{
-		return NULL;
-	}
-	
-	return &mCollisionVolumes[volume_id];
-}
-
-//-----------------------------------------------------------------------------
-// findCollisionVolume()
-//-----------------------------------------------------------------------------
-S32 LLVOAvatar::getCollisionVolumeID(std::string &name)
-{
-	for (S32 i = 0; i < mNumCollisionVolumes; i++)
-	{
-		if (mCollisionVolumes[i].getName() == name)
-		{
-			return i;
-		}
-	}
-
-	return -1;
-}
-
 //-----------------------------------------------------------------------------
 // addDebugText()
 //-----------------------------------------------------------------------------
@@ -5133,7 +4909,7 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
 
 	if (iter == mJointMap.end() || iter->second == NULL)
 	{ //search for joint and cache found joint in lookup table
-		jointp = mRoot.findJoint(name);
+		jointp = mRoot->findJoint(name);
 		mJointMap[name] = jointp;
 	}
 	else
@@ -5149,10 +4925,12 @@ LLJoint *LLVOAvatar::getJoint( const std::string &name )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetJointPositions( void )
 {
-	for(S32 i = 0; i < (S32)mNumJoints; ++i)
+	avatar_joint_list_t::iterator iter = mSkeleton.begin();
+	avatar_joint_list_t::iterator end  = mSkeleton.end();
+	for (; iter != end; ++iter)
 	{
-		mSkeleton[i].restoreOldXform();
-		mSkeleton[i].setId( LLUUID::null );
+		(*iter)->restoreOldXform();
+		(*iter)->setId( LLUUID::null );
 	}
 	mHasPelvisOffset = false;
 	mPelvisFixup	 = mLastPelvisFixup;
@@ -5162,7 +4940,7 @@ void LLVOAvatar::resetJointPositions( void )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
 {
-	LLJoint* pJoint = mRoot.findJoint( name );
+	LLJoint* pJoint = mRoot->findJoint( name );
 	
 	if ( pJoint  && pJoint->doesJointNeedToBeReset() )
 	{
@@ -5184,16 +4962,17 @@ void LLVOAvatar::resetSpecificJointPosition( const std::string& name )
 //-----------------------------------------------------------------------------
 void LLVOAvatar::resetJointPositionsToDefault( void )
 {
-
 	//Subsequent joints are relative to pelvis
-	for( S32 i = 0; i < (S32)mNumJoints; ++i )
+	avatar_joint_list_t::iterator iter = mSkeleton.begin();
+	avatar_joint_list_t::iterator end  = mSkeleton.end();
+	for (; iter != end; ++iter)
 	{
-		LLJoint* pJoint = (LLJoint*)&mSkeleton[i];
+		LLJoint* pJoint = (*iter);
 		if ( pJoint->doesJointNeedToBeReset() )
 		{
-
 			pJoint->setId( LLUUID::null );
 			//restore joints to default positions, however skip over the pelvis
+			// *TODO: How does this pointer check skip over pelvis?
 			if ( pJoint )
 			{
 				pJoint->restoreOldXform();
@@ -5292,23 +5071,6 @@ F32 LLVOAvatar::getPixelArea() const
 }
 
 
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getHeadMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh*	LLVOAvatar::getHeadMesh()
-{
-	return mMeshLOD[MESH_ID_HEAD]->mMeshParts[0]->getMesh();
-}
-
-
-//-----------------------------------------------------------------------------
-// LLVOAvatar::getUpperBodyMesh()
-//-----------------------------------------------------------------------------
-LLPolyMesh*	LLVOAvatar::getUpperBodyMesh()
-{
-	return mMeshLOD[MESH_ID_UPPER_BODY]->mMeshParts[0]->getMesh();
-}
-
 
 //-----------------------------------------------------------------------------
 // LLVOAvatar::getPosGlobalFromAgent()
@@ -5326,520 +5088,136 @@ LLVector3	LLVOAvatar::getPosAgentFromGlobal(const LLVector3d &position)
 	return gAgent.getPosAgentFromGlobal(position);
 }
 
+
 //-----------------------------------------------------------------------------
-// allocateCharacterJoints()
+// requestStopMotion()
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCharacterJoints( U32 num )
+// virtual
+void LLVOAvatar::requestStopMotion( LLMotion* motion )
 {
-	deleteAndClearArray(mSkeleton);
-	mNumJoints = 0;
+	// Only agent avatars should handle the stop motion notifications.
+}
 
-	mSkeleton = new LLViewerJoint[num];
-	
-	for(S32 joint_num = 0; joint_num < (S32)num; joint_num++)
+//-----------------------------------------------------------------------------
+// loadSkeletonNode(): loads <skeleton> node from XML tree
+//-----------------------------------------------------------------------------
+//virtual
+BOOL LLVOAvatar::loadSkeletonNode ()
+{
+	if (!LLAvatarAppearance::loadSkeletonNode())
 	{
-		mSkeleton[joint_num].setJointNum(joint_num);
+		return FALSE;
 	}
 
-	if (!mSkeleton)
+	// ATTACHMENTS
 	{
-		return FALSE;
+		LLAvatarXmlInfo::attachment_info_list_t::iterator iter;
+		for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
+			 iter != sAvatarXmlInfo->mAttachmentInfoList.end(); 
+			 ++iter)
+		{
+			LLAvatarXmlInfo::LLAvatarAttachmentInfo *info = *iter;
+			if (!isSelf() && info->mJointName == "mScreen")
+			{ //don't process screen joint for other avatars
+				continue;
+			}
+
+			LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
+
+			attachment->setName(info->mName);
+			LLJoint *parentJoint = getJoint(info->mJointName);
+			if (!parentJoint)
+			{
+				llwarns << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << llendl;
+				delete attachment;
+				continue;
+			}
+
+			if (info->mHasPosition)
+			{
+				attachment->setOriginalPosition(info->mPosition);
+			}
+
+			if (info->mHasRotation)
+			{
+				LLQuaternion rotation;
+				rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD,
+								 info->mRotationEuler.mV[VY] * DEG_TO_RAD,
+								 info->mRotationEuler.mV[VZ] * DEG_TO_RAD);
+				attachment->setRotation(rotation);
+			}
+
+			int group = info->mGroup;
+			if (group >= 0)
+			{
+				if (group < 0 || group >= 9)
+				{
+					llwarns << "Invalid group number (" << group << ") for attachment point " << info->mName << llendl;
+				}
+				else
+				{
+					attachment->setGroup(group);
+				}
+			}
+
+			S32 attachmentID = info->mAttachmentID;
+			if (attachmentID < 1 || attachmentID > 255)
+			{
+				llwarns << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << llendl;
+				delete attachment;
+				continue;
+			}
+			if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end())
+			{
+				llwarns << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << llendl;
+				delete attachment;
+				continue;
+			}
+
+			attachment->setPieSlice(info->mPieMenuSlice);
+			attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson);
+			attachment->setIsHUDAttachment(info->mIsHUDAttachment);
+
+			mAttachmentPoints[attachmentID] = attachment;
+
+			// now add attachment joint
+			parentJoint->addChild(attachment);
+		}
 	}
 
-	mNumJoints = num;
 	return TRUE;
 }
 
 //-----------------------------------------------------------------------------
-// allocateCollisionVolumes()
+// updateVisualParams()
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatar::allocateCollisionVolumes( U32 num )
+void LLVOAvatar::updateVisualParams()
 {
-	deleteAndClearArray(mCollisionVolumes);
-	mNumCollisionVolumes = 0;
+	setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
+
+	LLCharacter::updateVisualParams();
 
-	mCollisionVolumes = new LLViewerJointCollisionVolume[num];
-	if (!mCollisionVolumes)
+	if (mLastSkeletonSerialNum != mSkeletonSerialNum)
 	{
-		return FALSE;
+		computeBodySize();
+		mLastSkeletonSerialNum = mSkeletonSerialNum;
+		mRoot->updateWorldMatrixChildren();
 	}
 
-	mNumCollisionVolumes = num;
-	return TRUE;
+	dirtyMesh();
+	updateHeadOffset();
 }
 
-
 //-----------------------------------------------------------------------------
-// getCharacterJoint()
+// isActive()
 //-----------------------------------------------------------------------------
-LLJoint *LLVOAvatar::getCharacterJoint( U32 num )
+BOOL LLVOAvatar::isActive() const
 {
-	if ((S32)num >= mNumJoints 
-	    || (S32)num < 0)
-	{
-		return NULL;
-	}
-	return (LLJoint*)&mSkeleton[num];
+	return TRUE;
 }
 
 //-----------------------------------------------------------------------------
-// requestStopMotion()
-//-----------------------------------------------------------------------------
-// virtual
-void LLVOAvatar::requestStopMotion( LLMotion* motion )
-{
-	// Only agent avatars should handle the stop motion notifications.
-}
-
-//-----------------------------------------------------------------------------
-// loadAvatar()
-//-----------------------------------------------------------------------------
-static LLFastTimer::DeclareTimer FTM_LOAD_AVATAR("Load Avatar");
-
-BOOL LLVOAvatar::loadAvatar()
-{
-// 	LLFastTimer t(FTM_LOAD_AVATAR);
-	
-	// avatar_skeleton.xml
-	if( !buildSkeleton(sAvatarSkeletonInfo) )
-	{
-		llwarns << "avatar file: buildSkeleton() failed" << llendl;
-		return FALSE;
-	}
-
-	// avatar_lad.xml : <skeleton>
-	if( !loadSkeletonNode() )
-	{
-		llwarns << "avatar file: loadNodeSkeleton() failed" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <mesh>
-	if( !loadMeshNodes() )
-	{
-		llwarns << "avatar file: loadNodeMesh() failed" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <global_color>
-	if( sAvatarXmlInfo->mTexSkinColorInfo )
-	{
-		mTexSkinColor = new LLTexGlobalColor( this );
-		if( !mTexSkinColor->setInfo( sAvatarXmlInfo->mTexSkinColorInfo ) )
-		{
-			llwarns << "avatar file: mTexSkinColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"skin_color\" not found" << llendl;
-		return FALSE;
-	}
-	if( sAvatarXmlInfo->mTexHairColorInfo )
-	{
-		mTexHairColor = new LLTexGlobalColor( this );
-		if( !mTexHairColor->setInfo( sAvatarXmlInfo->mTexHairColorInfo ) )
-		{
-			llwarns << "avatar file: mTexHairColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"hair_color\" not found" << llendl;
-		return FALSE;
-	}
-	if( sAvatarXmlInfo->mTexEyeColorInfo )
-	{
-		mTexEyeColor = new LLTexGlobalColor( this );
-		if( !mTexEyeColor->setInfo( sAvatarXmlInfo->mTexEyeColorInfo ) )
-		{
-			llwarns << "avatar file: mTexEyeColor->setInfo() failed" << llendl;
-			return FALSE;
-		}
-	}
-	else
-	{
-		llwarns << "<global_color> name=\"eye_color\" not found" << llendl;
-		return FALSE;
-	}
-	
-	// avatar_lad.xml : <layer_set>
-	if (sAvatarXmlInfo->mLayerInfoList.empty())
-	{
-		llwarns << "avatar file: missing <layer_set> node" << llendl;
-		return FALSE;
-	}
-
-	if (sAvatarXmlInfo->mMorphMaskInfoList.empty())
-	{
-		llwarns << "avatar file: missing <morph_masks> node" << llendl;
-		return FALSE;
-	}
-
-	// avatar_lad.xml : <morph_masks>
-	for (LLVOAvatarXmlInfo::morph_info_list_t::iterator iter = sAvatarXmlInfo->mMorphMaskInfoList.begin();
-		 iter != sAvatarXmlInfo->mMorphMaskInfoList.end();
-		 ++iter)
-	{
-		LLVOAvatarXmlInfo::LLVOAvatarMorphInfo *info = *iter;
-
-		EBakedTextureIndex baked = LLVOAvatarDictionary::findBakedByRegionName(info->mRegion); 
-		if (baked != BAKED_NUM_INDICES)
-		{
-			LLPolyMorphTarget *morph_param;
-			const std::string *name = &info->mName;
-			morph_param = (LLPolyMorphTarget *)(getVisualParam(name->c_str()));
-			if (morph_param)
-			{
-				BOOL invert = info->mInvert;
-				addMaskedMorph(baked, morph_param, invert, info->mLayer);
-			}
-		}
-
-	}
-
-	loadLayersets();	
-	
-	// avatar_lad.xml : <driver_parameters>
-	for (LLVOAvatarXmlInfo::driver_info_list_t::iterator iter = sAvatarXmlInfo->mDriverInfoList.begin();
-		 iter != sAvatarXmlInfo->mDriverInfoList.end(); 
-		 ++iter)
-	{
-		LLDriverParamInfo *info = *iter;
-		LLDriverParam* driver_param = new LLDriverParam( this );
-		if (driver_param->setInfo(info))
-		{
-			addVisualParam( driver_param );
-			LLVisualParam*(LLVOAvatar::*avatar_function)(S32)const = &LLVOAvatar::getVisualParam; 
-			if( !driver_param->linkDrivenParams(boost::bind(avatar_function,(LLVOAvatar*)this,_1 ), false))
-			{
-				llwarns << "could not link driven params for avatar " << this->getFullname() << " id: " << driver_param->getID() << llendl;
-				continue;
-			}
-		}
-		else
-		{
-			delete driver_param;
-			llwarns << "avatar file: driver_param->parseData() failed" << llendl;
-			return FALSE;
-		}
-	}
-
-	
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// loadSkeletonNode(): loads <skeleton> node from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadSkeletonNode ()
-{
-	mRoot.addChild( &mSkeleton[0] );
-
-	for (std::vector<LLViewerJoint *>::iterator iter = mMeshLOD.begin();
-		 iter != mMeshLOD.end(); 
-		 ++iter)
-	{
-		LLViewerJoint *joint = (LLViewerJoint *) *iter;
-		joint->mUpdateXform = FALSE;
-		joint->setMeshesToChildren();
-	}
-
-	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
-	mRoot.addChild(mMeshLOD[MESH_ID_EYELASH]);
-	mRoot.addChild(mMeshLOD[MESH_ID_UPPER_BODY]);
-	mRoot.addChild(mMeshLOD[MESH_ID_LOWER_BODY]);
-	mRoot.addChild(mMeshLOD[MESH_ID_SKIRT]);
-	mRoot.addChild(mMeshLOD[MESH_ID_HEAD]);
-
-	LLViewerJoint *skull = (LLViewerJoint*)mRoot.findJoint("mSkull");
-	if (skull)
-	{
-		skull->addChild(mMeshLOD[MESH_ID_HAIR] );
-	}
-
-	LLViewerJoint *eyeL = (LLViewerJoint*)mRoot.findJoint("mEyeLeft");
-	if (eyeL)
-	{
-		eyeL->addChild( mMeshLOD[MESH_ID_EYEBALL_LEFT] );
-	}
-
-	LLViewerJoint *eyeR = (LLViewerJoint*)mRoot.findJoint("mEyeRight");
-	if (eyeR)
-	{
-		eyeR->addChild( mMeshLOD[MESH_ID_EYEBALL_RIGHT] );
-	}
-
-	// SKELETAL DISTORTIONS
-	{
-		LLVOAvatarXmlInfo::skeletal_distortion_info_list_t::iterator iter;
-		for (iter = sAvatarXmlInfo->mSkeletalDistortionInfoList.begin();
-			 iter != sAvatarXmlInfo->mSkeletalDistortionInfoList.end(); 
-			 ++iter)
-		{
-			LLPolySkeletalDistortionInfo *info = *iter;
-			LLPolySkeletalDistortion *param = new LLPolySkeletalDistortion(this);
-			if (!param->setInfo(info))
-			{
-				delete param;
-				return FALSE;
-			}
-			else
-			{
-				addVisualParam(param);
-			}				
-		}
-	}
-	
-	// ATTACHMENTS
-	{
-		LLVOAvatarXmlInfo::attachment_info_list_t::iterator iter;
-		for (iter = sAvatarXmlInfo->mAttachmentInfoList.begin();
-			 iter != sAvatarXmlInfo->mAttachmentInfoList.end(); 
-			 ++iter)
-		{
-			LLVOAvatarXmlInfo::LLVOAvatarAttachmentInfo *info = *iter;
-			if (!isSelf() && info->mJointName == "mScreen")
-			{ //don't process screen joint for other avatars
-				continue;
-			}
-
-			LLViewerJointAttachment* attachment = new LLViewerJointAttachment();
-
-			attachment->setName(info->mName);
-			LLJoint *parentJoint = getJoint(info->mJointName);
-			if (!parentJoint)
-			{
-				llwarns << "No parent joint by name " << info->mJointName << " found for attachment point " << info->mName << llendl;
-				delete attachment;
-				continue;
-			}
-
-			if (info->mHasPosition)
-			{
-				attachment->setOriginalPosition(info->mPosition);
-			}
-
-			if (info->mHasRotation)
-			{
-				LLQuaternion rotation;
-				rotation.setQuat(info->mRotationEuler.mV[VX] * DEG_TO_RAD,
-								 info->mRotationEuler.mV[VY] * DEG_TO_RAD,
-								 info->mRotationEuler.mV[VZ] * DEG_TO_RAD);
-				attachment->setRotation(rotation);
-			}
-
-			int group = info->mGroup;
-			if (group >= 0)
-			{
-				if (group < 0 || group >= 9)
-				{
-					llwarns << "Invalid group number (" << group << ") for attachment point " << info->mName << llendl;
-				}
-				else
-				{
-					attachment->setGroup(group);
-				}
-			}
-
-			S32 attachmentID = info->mAttachmentID;
-			if (attachmentID < 1 || attachmentID > 255)
-			{
-				llwarns << "Attachment point out of range [1-255]: " << attachmentID << " on attachment point " << info->mName << llendl;
-				delete attachment;
-				continue;
-			}
-			if (mAttachmentPoints.find(attachmentID) != mAttachmentPoints.end())
-			{
-				llwarns << "Attachment point redefined with id " << attachmentID << " on attachment point " << info->mName << llendl;
-				delete attachment;
-				continue;
-			}
-
-			attachment->setPieSlice(info->mPieMenuSlice);
-			attachment->setVisibleInFirstPerson(info->mVisibleFirstPerson);
-			attachment->setIsHUDAttachment(info->mIsHUDAttachment);
-
-			mAttachmentPoints[attachmentID] = attachment;
-
-			// now add attachment joint
-			parentJoint->addChild(attachment);
-		}
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// loadMeshNodes(): loads <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadMeshNodes()
-{
-	for (LLVOAvatarXmlInfo::mesh_info_list_t::const_iterator meshinfo_iter = sAvatarXmlInfo->mMeshInfoList.begin();
-		 meshinfo_iter != sAvatarXmlInfo->mMeshInfoList.end(); 
-		 ++meshinfo_iter)
-	{
-		const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo *info = *meshinfo_iter;
-		const std::string &type = info->mType;
-		S32 lod = info->mLOD;
-
-		LLViewerJointMesh* mesh = NULL;
-		U8 mesh_id = 0;
-		BOOL found_mesh_id = FALSE;
-
-		/* if (type == "hairMesh")
-			switch(lod)
-			  case 0:
-				mesh = &mHairMesh0; */
-		for (LLVOAvatarDictionary::Meshes::const_iterator mesh_iter = LLVOAvatarDictionary::getInstance()->getMeshes().begin();
-			 mesh_iter != LLVOAvatarDictionary::getInstance()->getMeshes().end();
-			 ++mesh_iter)
-		{
-			const EMeshIndex mesh_index = mesh_iter->first;
-			const LLVOAvatarDictionary::MeshEntry *mesh_dict = mesh_iter->second;
-			if (type.compare(mesh_dict->mName) == 0)
-			{
-				mesh_id = mesh_index;
-				found_mesh_id = TRUE;
-				break;
-			}
-		}
-
-		if (found_mesh_id)
-		{
-			if (lod < (S32)mMeshLOD[mesh_id]->mMeshParts.size())
-			{
-				mesh = mMeshLOD[mesh_id]->mMeshParts[lod];
-			}
-			else
-			{
-				llwarns << "Avatar file: <mesh> has invalid lod setting " << lod << llendl;
-				return FALSE;
-			}
-		}
-		else 
-		{
-			llwarns << "Ignoring unrecognized mesh type: " << type << llendl;
-			return FALSE;
-		}
-
-		//	llinfos << "Parsing mesh data for " << type << "..." << llendl;
-
-		// If this isn't set to white (1.0), avatars will *ALWAYS* be darker than their surroundings.
-		// Do not touch!!!
-		mesh->setColor( 1.0f, 1.0f, 1.0f, 1.0f );
-
-		LLPolyMesh *poly_mesh = NULL;
-
-		if (!info->mReferenceMeshName.empty())
-		{
-			polymesh_map_t::const_iterator polymesh_iter = mMeshes.find(info->mReferenceMeshName);
-			if (polymesh_iter != mMeshes.end())
-			{
-				poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName, polymesh_iter->second);
-				poly_mesh->setAvatar(this);
-			}
-			else
-			{
-				// This should never happen
-				LL_WARNS("Avatar") << "Could not find avatar mesh: " << info->mReferenceMeshName << LL_ENDL;
-			}
-		}
-		else
-		{
-			poly_mesh = LLPolyMesh::getMesh(info->mMeshFileName);
-			poly_mesh->setAvatar(this);
-		}
-
-		if( !poly_mesh )
-		{
-			llwarns << "Failed to load mesh of type " << type << llendl;
-			return FALSE;
-		}
-
-		// Multimap insert
-		mMeshes.insert(std::make_pair(info->mMeshFileName, poly_mesh));
-	
-		mesh->setMesh( poly_mesh );
-		mesh->setLOD( info->mMinPixelArea );
-
-		for (LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_list_t::const_iterator xmlinfo_iter = info->mPolyMorphTargetInfoList.begin();
-			 xmlinfo_iter != info->mPolyMorphTargetInfoList.end(); 
-			 ++xmlinfo_iter)
-		{
-			const LLVOAvatarXmlInfo::LLVOAvatarMeshInfo::morph_info_pair_t *info_pair = &(*xmlinfo_iter);
-			LLPolyMorphTarget *param = new LLPolyMorphTarget(mesh->getMesh());
-			if (!param->setInfo(info_pair->first))
-			{
-				delete param;
-				return FALSE;
-			}
-			else
-			{
-				if (info_pair->second)
-				{
-					addSharedVisualParam(param);
-				}
-				else
-				{
-					addVisualParam(param);
-				}
-			}				
-		}
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// loadLayerSets()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::loadLayersets()
-{
-	BOOL success = TRUE;
-	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator layerset_iter = sAvatarXmlInfo->mLayerInfoList.begin();
-		 layerset_iter != sAvatarXmlInfo->mLayerInfoList.end(); 
-		 ++layerset_iter)
-	{
-		// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
-		LLTexLayerSetInfo *layerset_info = *layerset_iter;
-		layerset_info->createVisualParams(this);
-	}
-	return success;
-}
-
-//-----------------------------------------------------------------------------
-// updateVisualParams()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::updateVisualParams()
-{
-	setSex( (getVisualParamWeight( "male" ) > 0.5f) ? SEX_MALE : SEX_FEMALE );
-
-	LLCharacter::updateVisualParams();
-
-	if (mLastSkeletonSerialNum != mSkeletonSerialNum)
-	{
-		computeBodySize();
-		mLastSkeletonSerialNum = mSkeletonSerialNum;
-		mRoot.updateWorldMatrixChildren();
-	}
-
-	dirtyMesh();
-	updateHeadOffset();
-}
-
-//-----------------------------------------------------------------------------
-// isActive()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::isActive() const
-{
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// setPixelAreaAndAngle()
+// setPixelAreaAndAngle()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::setPixelAreaAndAngle(LLAgent &agent)
 {
@@ -5888,7 +5266,6 @@ BOOL LLVOAvatar::updateJointLODs()
 	F32 avatar_num_factor = clamp_rescale((F32)sNumVisibleAvatars, 8, 25, 1.f, avatar_num_min_factor);
 	F32 area_scale = 0.16f;
 
-	{
 		if (isSelf())
 		{
 			if(gAgentCamera.cameraCustomizeAvatar() || gAgentCamera.cameraMouselook())
@@ -5911,14 +5288,18 @@ BOOL LLVOAvatar::updateJointLODs()
 		}
 
 		// now select meshes to render based on adjusted pixel area
-		BOOL res = mRoot.updateLOD(mAdjustedPixelArea, TRUE);
+		LLViewerJoint* root = dynamic_cast<LLViewerJoint*>(mRoot);
+		BOOL res = FALSE;
+		if (root)
+		{
+			res = root->updateLOD(mAdjustedPixelArea, TRUE);
+		}
  		if (res)
 		{
 			sNumLODChangesThisFrame++;
 			dirtyMesh(2);
 			return TRUE;
 		}
-	}
 
 	return FALSE;
 }
@@ -6001,6 +5382,15 @@ void LLVOAvatar::dirtyMesh(S32 priority)
 {
 	mDirtyMesh = llmax(mDirtyMesh, priority);
 }
+
+//-----------------------------------------------------------------------------
+// getViewerJoint()
+//-----------------------------------------------------------------------------
+LLViewerJoint*	LLVOAvatar::getViewerJoint(S32 idx)
+{
+	return dynamic_cast<LLViewerJoint*>(mMeshLOD[idx]);
+}
+
 //-----------------------------------------------------------------------------
 // hideSkirt()
 //-----------------------------------------------------------------------------
@@ -6207,14 +5597,9 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 		if ( pVObj )
 		{
 			const LLMeshSkinInfo* pSkinData = gMeshRepo.getSkinInfo( pVObj->getVolume()->getParams().getSculptID(), pVObj );
-			if ( pSkinData )
-			{
-				const int jointCnt = pSkinData->mJointNames.size();
-				bool fullRig = ( jointCnt>=20 ) ? true : false;
-				if ( fullRig )
-				{
-					const int bindCnt = pSkinData->mAlternateBindMatrix.size();							
-					if ( bindCnt > 0 )
+			if (pSkinData 
+				&& pSkinData->mJointNames.size() > 20				// full rig
+				&& pSkinData->mAlternateBindMatrix.size() > 0)
 					{
 						LLVOAvatar::resetJointPositionsToDefault();
 						//Need to handle the repositioning of the cam, updating rig data etc during outfit editing 
@@ -6229,8 +5614,6 @@ void LLVOAvatar::cleanupAttachedMesh( LLViewerObject* pVO )
 				}
 			}				
 		}
-	}	
-}
 //-----------------------------------------------------------------------------
 // detachObject()
 //-----------------------------------------------------------------------------
@@ -6314,9 +5697,9 @@ void LLVOAvatar::sitOnObject(LLViewerObject *sit_object)
 	// Notice that removing sitDown() from here causes avatars sitting on
 	// objects to be not rendered for new arrivals. See EXT-6835 and EXT-1655.
 	sitDown(TRUE);
-	mRoot.getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
-	mRoot.setPosition(getPosition());
-	mRoot.updateWorldMatrixChildren();
+	mRoot->getXform()->setParent(&sit_object->mDrawable->mXform); // LLVOAvatar::sitOnObject
+	mRoot->setPosition(getPosition());
+	mRoot->updateWorldMatrixChildren();
 
 	stopMotion(ANIM_AGENT_BODY_NOISE);
 
@@ -6362,10 +5745,10 @@ void LLVOAvatar::getOffObject()
 
 	sitDown(FALSE);
 
-	mRoot.getXform()->setParent(NULL); // LLVOAvatar::getOffObject
-	mRoot.setPosition(cur_position_world);
-	mRoot.setRotation(cur_rotation_world);
-	mRoot.getXform()->update();
+	mRoot->getXform()->setParent(NULL); // LLVOAvatar::getOffObject
+	mRoot->setPosition(cur_position_world);
+	mRoot->setRotation(cur_rotation_world);
+	mRoot->getXform()->update();
 
 	startMotion(ANIM_AGENT_BODY_NOISE);
 
@@ -6379,11 +5762,7 @@ void LLVOAvatar::getOffObject()
 		at_axis.mV[VZ] = 0.f;
 		at_axis.normalize();
 		gAgent.resetAxes(at_axis);
-
-		//reset orientation
-//		mRoot.setRotation(avWorldRot);
 		gAgentCamera.setThirdPersonHeadOffset(LLVector3(0.f, 0.f, 1.f));
-
 		gAgentCamera.setSitCamera(LLUUID::null);
 	}
 }
@@ -6417,27 +5796,53 @@ S32 LLVOAvatar::getAttachmentCount()
 	return count;
 }
 
-LLColor4 LLVOAvatar::getGlobalColor( const std::string& color_name ) const
+BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
 {
-	if (color_name=="skin_color" && mTexSkinColor)
-	{
-		return mTexSkinColor->getColor();
-	}
-	else if(color_name=="hair_color" && mTexHairColor)
+	if (mIsDummy) return TRUE;
+
+	if (isSelf())
 	{
-		return mTexHairColor->getColor();
+		return LLAvatarAppearance::isWearingWearableType(type);
 	}
-	if(color_name=="eye_color" && mTexEyeColor)
+
+	switch(type)
 	{
-		return mTexEyeColor->getColor();
+		case LLWearableType::WT_SHAPE:
+		case LLWearableType::WT_SKIN:
+		case LLWearableType::WT_HAIR:
+		case LLWearableType::WT_EYES:
+			return TRUE;  // everyone has all bodyparts
+		default:
+			break; // Do nothing
 	}
-	else
+
+	/* switch(type)
+		case LLWearableType::WT_SHIRT:
+			indicator_te = TEX_UPPER_SHIRT; */
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator tex_iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 tex_iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
+		 ++tex_iter)
 	{
-//		return LLColor4( .5f, .5f, .5f, .5f );
-		return LLColor4( 0.f, 1.f, 1.f, 1.f ); // good debugging color
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = tex_iter->second;
+		if (texture_dict->mWearableType == type)
+		{
+			// Thus, you must check to see if the corresponding baked texture is defined.
+			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
+			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
+			// gets baked into a texture that always exists (upper or lower).
+			if (texture_dict->mIsUsedByBakedTexture)
+			{
+				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+				return isTextureDefined(LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
+			}
+			return FALSE;
+		}
 	}
+	return FALSE;
 }
 
+
+
 // virtual
 void LLVOAvatar::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
 {
@@ -6447,6 +5852,7 @@ void LLVOAvatar::invalidateAll()
 {
 }
 
+// virtual
 void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake )
 {
 	if (global_color == mTexSkinColor)
@@ -6465,9 +5871,15 @@ void LLVOAvatar::onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL
 		if (!isTextureDefined(mBakedTextureDatas[BAKED_HAIR].mTextureIndex))
 		{
 			LLColor4 color = mTexHairColor->getColor();
-			for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setColor( color );
+				}
 			}
 		}
 	} 
@@ -6510,42 +5922,167 @@ BOOL LLVOAvatar::getIsCloud() const
 
 void LLVOAvatar::updateRezzedStatusTimers()
 {
-	// State machine for rezzed status. Statuses are 0 = cloud, 1 = gray, 2 = textured.
-	// Purpose is to collect time data for each period of cloud or cloud+gray.
+	// State machine for rezzed status. Statuses are -1 on startup, 0
+	// = cloud, 1 = gray, 2 = textured, 3 = textured_and_downloaded.
+	// Purpose is to collect time data for each it takes avatar to reach
+	// various loading landmarks: gray, textured (partial), textured fully.
+
 	S32 rez_status = getRezzedStatus();
 	if (rez_status != mLastRezzedStatus)
 	{
 		LL_DEBUGS("Avatar") << avString() << "rez state change: " << mLastRezzedStatus << " -> " << rez_status << LL_ENDL;
-		bool is_cloud_or_gray = (rez_status==0 || rez_status==1);
-		bool was_cloud_or_gray = (mLastRezzedStatus==0 || mLastRezzedStatus==1);
-		bool is_cloud = (rez_status==0);
-		bool was_cloud = (mLastRezzedStatus==0);
 
-		// Non-cloud to cloud
-		if (is_cloud && !was_cloud)
+		if (mLastRezzedStatus == -1 && rez_status != -1)
+		{
+			// First time initialization, start all timers.
+			for (S32 i = 1; i < 4; i++)
+			{
+				startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+				startPhase("first_load_" + LLVOAvatar::rezStatusToString(i));
+			}
+		}
+		if (rez_status < mLastRezzedStatus)
+		{
+			// load level has decreased. start phase timers for higher load levels.
+			for (S32 i = rez_status+1; i <= mLastRezzedStatus; i++)
+			{
+				startPhase("load_" + LLVOAvatar::rezStatusToString(i));
+			}
+		}
+		else if (rez_status > mLastRezzedStatus)
+		{
+			// load level has increased. stop phase timers for lower and equal load levels.
+			for (S32 i = llmax(mLastRezzedStatus+1,1); i <= rez_status; i++)
+			{
+				stopPhase("load_" + LLVOAvatar::rezStatusToString(i));
+				stopPhase("first_load_" + LLVOAvatar::rezStatusToString(i), false);
+			}
+			if (rez_status == 3)
+			{
+				// "fully loaded", mark any pending appearance change complete.
+				selfStopPhase("update_appearance_from_cof");
+				selfStopPhase("wear_inventory_category", false);
+				selfStopPhase("process_initial_wearables_update", false);
+			}
+		}
+
+		mLastRezzedStatus = rez_status;
+	}
+}
+
+void LLVOAvatar::clearPhases()
+{
+	getPhases().clearPhases();
+}
+
+void LLVOAvatar::startPhase(const std::string& phase_name)
+{
+	F32 elapsed;
+	bool completed;
+	if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+	{
+		if (!completed)
+		{
+			LL_DEBUGS("Avatar") << avString() << "no-op, start when started already for " << phase_name << llendl;
+			return;
+		}
+	}
+	LL_DEBUGS("Avatar") << "started phase " << phase_name << llendl;
+	getPhases().startPhase(phase_name);
+}
+
+void LLVOAvatar::stopPhase(const std::string& phase_name, bool err_check)
+{
+	F32 elapsed;
+	bool completed;
+	if (getPhases().getPhaseValues(phase_name, elapsed, completed))
+	{
+		if (!completed)
+		{
+			getPhases().stopPhase(phase_name);
+			completed = true;
+			logMetricsTimerRecord(phase_name, elapsed, completed);
+			LL_DEBUGS("Avatar") << avString() << "stopped phase " << phase_name << " elapsed " << elapsed << llendl;
+		}
+		else
 		{
-			// start cloud timer.
-			getPhases().startPhase("cloud");
+			if (err_check)
+			{
+				LL_DEBUGS("Avatar") << "no-op, stop when stopped already for " << phase_name << llendl;
+			}
 		}
-		else if (was_cloud && !is_cloud)
+	}
+	else
+	{
+		if (err_check)
 		{
-			// stop cloud timer, which will capture stats.
-			getPhases().stopPhase("cloud");
+			LL_DEBUGS("Avatar") << "no-op, stop when not started for " << phase_name << llendl;
 		}
+	}
+}
 
-		// Non-cloud-or-gray to cloud-or-gray
-		if (is_cloud_or_gray && !was_cloud_or_gray)
+void LLVOAvatar::logPendingPhases()
+{
+	for (LLViewerStats::phase_map_t::iterator it = getPhases().begin();
+		 it != getPhases().end();
+		 ++it)
+	{
+		const std::string& phase_name = it->first;
+		F32 elapsed;
+		bool completed;
+		if (getPhases().getPhaseValues(phase_name, elapsed, completed))
 		{
-			// start cloud-or-gray timer.
-			getPhases().startPhase("cloud-or-gray");
+			if (!completed)
+			{
+				logMetricsTimerRecord(phase_name, elapsed, completed);
+			}
 		}
-		else if (was_cloud_or_gray && !is_cloud_or_gray)
+	}
+}
+
+//static
+void LLVOAvatar::logPendingPhasesAllAvatars()
+{
+	for (std::vector<LLCharacter*>::iterator iter = LLCharacter::sInstances.begin();
+		 iter != LLCharacter::sInstances.end(); ++iter)
+	{
+		LLVOAvatar* inst = (LLVOAvatar*) *iter;
+		if( inst->isDead() )
 		{
-			// stop cloud-or-gray timer, which will capture stats.
-			getPhases().stopPhase("cloud-or-gray");
+			continue;
 		}
-		
-		mLastRezzedStatus = rez_status;
+		inst->logPendingPhases();
+	}
+}
+
+void LLVOAvatar::logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed)
+{
+	LLSD record;
+	record["timer_name"] = phase_name;
+	record["avatar_id"] = getID();
+	record["elapsed"] = elapsed;
+	record["completed"] = completed;
+	U32 grid_x(0), grid_y(0);
+	if (getRegion())
+	{
+		record["central_bake_version"] = LLSD::Integer(getRegion()->getCentralBakeVersion());
+		grid_from_region_handle(getRegion()->getHandle(), &grid_x, &grid_y);
+	}
+	record["grid_x"] = LLSD::Integer(grid_x);
+	record["grid_y"] = LLSD::Integer(grid_y);
+	record["is_using_server_bakes"] = ((bool) isUsingServerBakes());
+	record["is_self"] = isSelf();
+	
+
+#if 0 // verbose logging
+	std::ostringstream ostr;
+	ostr << LLSDNotationStreamer(record);
+	LL_DEBUGS("Avatar") << "record\n" << ostr.str() << llendl;
+#endif
+
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->addMetricsTimerRecord(record);
 	}
 }
 
@@ -6598,8 +6135,8 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
 	
 	mFullyLoaded = (mFullyLoadedTimer.getElapsedTimeF32() > PAUSE);
 
-	if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
-	{
+		if (!mPreviousFullyLoaded && !loading && mFullyLoaded)
+		{
 		debugAvatarRezTime("AvatarRezNotification","fully loaded");
 	}
 
@@ -6642,24 +6179,49 @@ LLMotion* LLVOAvatar::findMotion(const LLUUID& id) const
 	return mMotionController.findMotion(id);
 }
 
+// This is a semi-deprecated debugging tool - meshes will not show as
+// colorized if using deferred rendering.
+void LLVOAvatar::debugColorizeSubMeshes(U32 i, const LLColor4& color)
+{
+	if (gSavedSettings.getBOOL("DebugAvatarCompositeBaked"))
+	{
+		avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+		avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+		for (; iter != end; ++iter)
+		{
+			LLAvatarJointMesh* mesh = (*iter);
+			if (mesh)
+			{
+				{
+					mesh->setColor(color);
+				}
+			}
+		}
+	}
+}
+
 //-----------------------------------------------------------------------------
 // updateMeshTextures()
 // Uses the current TE values to set the meshes' and layersets' textures.
 //-----------------------------------------------------------------------------
+// virtual
 void LLVOAvatar::updateMeshTextures()
 {
-    // llinfos << "updateMeshTextures" << llendl;
+	static S32 update_counter = 0;
+	mBakedTextureDebugText.clear();
+	
 	// if user has never specified a texture, assign the default
 	for (U32 i=0; i < getNumTEs(); i++)
 	{
 		const LLViewerTexture* te_image = getImage(i, 0);
 		if(!te_image || te_image->getID().isNull() || (te_image->getID() == IMG_DEFAULT))
 		{
-			setImage(i, LLViewerTextureManager::getFetchedTexture(i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR), 0); // IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+			// IMG_DEFAULT_AVATAR = a special texture that's never rendered.
+			const LLUUID& image_id = (i == TEX_HAIR ? IMG_DEFAULT : IMG_DEFAULT_AVATAR);
+			setImage(i, LLViewerTextureManager::getFetchedTexture(image_id), 0); 
 		}
 	}
 
-	const BOOL self_customizing = isSelf() && gAgentCamera.cameraCustomizeAvatar(); // During face edit mode, we don't use baked textures
 	const BOOL other_culled = !isSelf() && mCulled;
 	LLLoadedCallbackEntry::source_callback_list_t* src_callback_list = NULL ;
 	BOOL paused = FALSE;
@@ -6675,71 +6237,97 @@ void LLVOAvatar::updateMeshTextures()
 	std::vector<BOOL> use_lkg_baked_layer; // lkg = "last known good"
 	use_lkg_baked_layer.resize(mBakedTextureDatas.size(), false);
 
+	mBakedTextureDebugText += llformat("%06d\n",update_counter++);
+	mBakedTextureDebugText += "indx layerset linvld ltda ilb ulkg ltid\n";
 	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
 	{
 		is_layer_baked[i] = isTextureDefined(mBakedTextureDatas[i].mTextureIndex);
-
+		LLViewerTexLayerSet* layerset = NULL;
+		bool layerset_invalid = false;
 		if (!other_culled)
 		{
 			// When an avatar is changing clothes and not in Appearance mode,
-			// use the last-known good baked texture until it finish the first
+			// use the last-known good baked texture until it finishes the first
 			// render of the new layerset.
-			const BOOL layerset_invalid = mBakedTextureDatas[i].mTexLayerSet 
-										  && ( !mBakedTextureDatas[i].mTexLayerSet->getComposite()->isInitialized()
-										  || !mBakedTextureDatas[i].mTexLayerSet->isLocalTextureDataAvailable() );
+			layerset = getTexLayerSet(i);
+			layerset_invalid = layerset && ( !layerset->getViewerComposite()->isInitialized()
+											 || !layerset->isLocalTextureDataAvailable() );
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
-									  && (mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR) 
+									  && (mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR) 
 									  && layerset_invalid);
 			if (use_lkg_baked_layer[i])
 			{
-				mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
+				layerset->setUpdatesEnabled(TRUE);
 			}
 		}
 		else
 		{
 			use_lkg_baked_layer[i] = (!is_layer_baked[i] 
-									  && mBakedTextureDatas[i].mLastTextureIndex != IMG_DEFAULT_AVATAR);
-			if (mBakedTextureDatas[i].mTexLayerSet)
-			{
-				mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
-			}
+									  && mBakedTextureDatas[i].mLastTextureID != IMG_DEFAULT_AVATAR);
 		}
 
-	}
-
-	// Turn on alpha masking correctly for yourself and other avatars on 1.23+
-	mSupportsAlphaLayers = isSelf() || is_layer_baked[BAKED_HAIR];
-
-	// Baked textures should be requested from the sim this avatar is on. JC
-	const LLHost target_host = getObjectHost();
-	if (!target_host.isOk())
-	{
-		llwarns << "updateMeshTextures: invalid host for object: " << getID() << llendl;
+		std::string last_id_string;
+		if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT_AVATAR)
+			last_id_string = "A";
+		else if (mBakedTextureDatas[i].mLastTextureID == IMG_DEFAULT)
+			last_id_string = "D";
+		else if (mBakedTextureDatas[i].mLastTextureID == IMG_INVISIBLE)
+			last_id_string = "I";
+		else
+			last_id_string = "*";
+		bool is_ltda = layerset
+			&& layerset->getViewerComposite()->isInitialized()
+			&& layerset->isLocalTextureDataAvailable();
+		mBakedTextureDebugText += llformat("%4d   %4s     %4d %4d %4d %4d %4s\n",
+										   i,
+										   (layerset?"*":"0"),
+										   layerset_invalid,
+										   is_ltda,
+										   is_layer_baked[i],
+										   use_lkg_baked_layer[i],
+										   last_id_string.c_str());
 	}
 	
 	for (U32 i=0; i < mBakedTextureDatas.size(); i++)
 	{
-		if (use_lkg_baked_layer[i] && !self_customizing )
+		debugColorizeSubMeshes(i, LLColor4::white);
+
+		LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+		if (use_lkg_baked_layer[i] && !isUsingLocalAppearance() )
 		{
-			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTextureFromHost( mBakedTextureDatas[i].mLastTextureIndex, target_host );
+			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[i].mLastTextureID);
 			mBakedTextureDatas[i].mIsUsed = TRUE;
-			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			debugColorizeSubMeshes(i,LLColor4::red);
+
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setTexture( baked_img );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setTexture( baked_img );
+				}
 			}
 		}
-		else if (!self_customizing && is_layer_baked[i])
+		else if (!isUsingLocalAppearance() && is_layer_baked[i])
 		{
-			LLViewerFetchedTexture* baked_img = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
-			if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureIndex )
+			LLViewerFetchedTexture* baked_img =
+				LLViewerTextureManager::staticCastToFetchedTexture(
+					getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
+			if( baked_img->getID() == mBakedTextureDatas[i].mLastTextureID )
 			{
-				// Even though the file may not be finished loading, we'll consider it loaded and use it (rather than doing compositing).
+				// Even though the file may not be finished loading,
+				// we'll consider it loaded and use it (rather than
+				// doing compositing).
 				useBakedTexture( baked_img->getID() );
 			}
 			else
 			{
 				mBakedTextureDatas[i].mIsLoaded = FALSE;
-				if ( (baked_img->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
+				if ( (baked_img->getID() != IMG_INVISIBLE) &&
+					 ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
 				{			
 					baked_img->setLoadedCallback(onBakedTextureMasksLoaded, MORPH_MASK_REQUESTED_DISCARD, TRUE, TRUE, new LLTextureMaskData( mID ), 
 						src_callback_list, paused);	
@@ -6748,40 +6336,59 @@ void LLVOAvatar::updateMeshTextures()
 					src_callback_list, paused );
 			}
 		}
-		else if (mBakedTextureDatas[i].mTexLayerSet 
-				 && !other_culled) 
+		else if (layerset && isUsingLocalAppearance())
 		{
-			mBakedTextureDatas[i].mTexLayerSet->createComposite();
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled( TRUE );
+			debugColorizeSubMeshes(i,LLColor4::yellow );
+
+			layerset->createComposite();
+			layerset->setUpdatesEnabled( TRUE );
 			mBakedTextureDatas[i].mIsUsed = FALSE;
-			for (U32 k=0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+			avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+			for (; iter != end; ++iter)
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setLayerSet( mBakedTextureDatas[i].mTexLayerSet );
+				LLAvatarJointMesh* mesh = (*iter);
+				if (mesh)
+				{
+					mesh->setLayerSet( layerset );
+				}
 			}
 		}
+		else
+		{
+			debugColorizeSubMeshes(i,LLColor4::blue);
+		}
 	}
 
 	// set texture and color of hair manually if we are not using a baked image.
 	// This can happen while loading hair for yourself, or for clients that did not
 	// bake a hair texture. Still needed for yourself after 1.22 is depricated.
-	if (!is_layer_baked[BAKED_HAIR] || self_customizing)
+	if (!is_layer_baked[BAKED_HAIR] || isEditingAppearance())
 	{
 		const LLColor4 color = mTexHairColor ? mTexHairColor->getColor() : LLColor4(1,1,1,1);
 		LLViewerTexture* hair_img = getImage( TEX_HAIR, 0 );
-		for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+		avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.begin();
+		avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[BAKED_HAIR].mJointMeshes.end();
+		for (; iter != end; ++iter)
 		{
-			mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( color.mV[VX], color.mV[VY], color.mV[VZ], color.mV[VW] );
-			mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setTexture( hair_img );
+			LLAvatarJointMesh* mesh = (*iter);
+			if (mesh)
+			{
+				mesh->setColor( color );
+				mesh->setTexture( hair_img );
+			}
 		}
 	} 
 	
 	
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+			 LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 		
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
@@ -6809,7 +6416,7 @@ void LLVOAvatar::setLocalTexture( ETextureIndex type, LLViewerTexture* in_tex, B
 }
 
 //virtual 
-void LLVOAvatar::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatar::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
 {
 	// invalid for anyone but self
 	llassert(0);
@@ -6844,18 +6451,30 @@ void LLVOAvatar::clearChat()
 	mChats.clear();
 }
 
-// adds a morph mask to the appropriate baked texture structure
-void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer)
+
+void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index)
 {
-	if (index < BAKED_NUM_INDICES)
+	if (index >= BAKED_NUM_INDICES)
+	{
+		llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
+		return;
+	}
+
+	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
+		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
 	{
-		LLMaskedMorph *morph = new LLMaskedMorph(morph_target, invert, layer);
-		mBakedTextureDatas[index].mMaskedMorphs.push_front(morph);
+		const LLMaskedMorph* maskedMorph = (*iter);
+		LLPolyMorphTarget* morph_target = dynamic_cast<LLPolyMorphTarget*>(maskedMorph->mMorphTarget);
+		if (morph_target)
+		{
+			morph_target->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
+		}
 	}
 }
 
+
 // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
-BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index)
+BOOL LLVOAvatar::morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index)
 {
 	if (index >= BAKED_NUM_INDICES)
 	{
@@ -6866,7 +6485,7 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
 	{
 		if (isSelf())
 		{
-			LLTexLayerSet *layer_set = mBakedTextureDatas[index].mTexLayerSet;
+			LLViewerTexLayerSet *layer_set = getTexLayerSet(index);
 			if (layer_set)
 			{
 				return !layer_set->isMorphValid();
@@ -6881,23 +6500,6 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
 	return FALSE;
 }
 
-void LLVOAvatar::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index)
-{
-	if (index >= BAKED_NUM_INDICES)
-	{
-		llwarns << "invalid baked texture index passed to applyMorphMask" << llendl;
-		return;
-	}
-
-	for (morph_list_t::const_iterator iter = mBakedTextureDatas[index].mMaskedMorphs.begin();
-		 iter != mBakedTextureDatas[index].mMaskedMorphs.end(); ++iter)
-	{
-		const LLMaskedMorph* maskedMorph = (*iter);
-		maskedMorph->mMorphTarget->applyMask(tex_data, width, height, num_components, maskedMorph->mInvert);
-	}
-}
-
-
 //-----------------------------------------------------------------------------
 // releaseComponentTextures()
 // release any component texture UUIDs for which we have a baked texture
@@ -6920,7 +6522,7 @@ void LLVOAvatar::releaseComponentTextures()
 
 	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 	{
-		const LLVOAvatarDictionary::BakedEntry * bakedDicEntry = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+		const LLAvatarAppearanceDictionary::BakedEntry * bakedDicEntry = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
 		// skip if this is a skirt and av is not wearing one, or if we don't have a baked texture UUID
 		if (!isTextureDefined(bakedDicEntry->mTextureIndex)
 			&& ( (baked_index != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT) ))
@@ -6936,185 +6538,37 @@ void LLVOAvatar::releaseComponentTextures()
 	}
 }
 
-//static
-BOOL LLVOAvatar::teToColorParams( ETextureIndex te, U32 *param_name )
-{
-	switch( te )
-	{
-		case TEX_UPPER_SHIRT:
-			param_name[0] = 803; //"shirt_red";
-			param_name[1] = 804; //"shirt_green";
-			param_name[2] = 805; //"shirt_blue";
-			break;
-
-		case TEX_LOWER_PANTS:
-			param_name[0] = 806; //"pants_red";
-			param_name[1] = 807; //"pants_green";
-			param_name[2] = 808; //"pants_blue";
-			break;
-
-		case TEX_LOWER_SHOES:
-			param_name[0] = 812; //"shoes_red";
-			param_name[1] = 813; //"shoes_green";
-			param_name[2] = 817; //"shoes_blue";
-			break;
-
-		case TEX_LOWER_SOCKS:
-			param_name[0] = 818; //"socks_red";
-			param_name[1] = 819; //"socks_green";
-			param_name[2] = 820; //"socks_blue";
-			break;
-
-		case TEX_UPPER_JACKET:
-		case TEX_LOWER_JACKET:
-			param_name[0] = 834; //"jacket_red";
-			param_name[1] = 835; //"jacket_green";
-			param_name[2] = 836; //"jacket_blue";
-			break;
-
-		case TEX_UPPER_GLOVES:
-			param_name[0] = 827; //"gloves_red";
-			param_name[1] = 829; //"gloves_green";
-			param_name[2] = 830; //"gloves_blue";
-			break;
-
-		case TEX_UPPER_UNDERSHIRT:
-			param_name[0] = 821; //"undershirt_red";
-			param_name[1] = 822; //"undershirt_green";
-			param_name[2] = 823; //"undershirt_blue";
-			break;
-	
-		case TEX_LOWER_UNDERPANTS:
-			param_name[0] = 824; //"underpants_red";
-			param_name[1] = 825; //"underpants_green";
-			param_name[2] = 826; //"underpants_blue";
-			break;
-
-		case TEX_SKIRT:
-			param_name[0] = 921; //"skirt_red";
-			param_name[1] = 922; //"skirt_green";
-			param_name[2] = 923; //"skirt_blue";
-			break;
-
-		case TEX_HEAD_TATTOO:
-		case TEX_LOWER_TATTOO:
-		case TEX_UPPER_TATTOO:
-			param_name[0] = 1071; //"tattoo_red";
-			param_name[1] = 1072; //"tattoo_green";
-			param_name[2] = 1073; //"tattoo_blue";
-			break;	
-
-		default:
-			llassert(0);
-			return FALSE;
-	}
-
-	return TRUE;
-}
-
-void LLVOAvatar::setClothesColor( ETextureIndex te, const LLColor4& new_color, BOOL upload_bake )
-{
-	U32 param_name[3];
-	if( teToColorParams( te, param_name ) )
-	{
-		setVisualParamWeight( param_name[0], new_color.mV[VX], upload_bake );
-		setVisualParamWeight( param_name[1], new_color.mV[VY], upload_bake );
-		setVisualParamWeight( param_name[2], new_color.mV[VZ], upload_bake );
-	}
-}
-
-LLColor4 LLVOAvatar::getClothesColor( ETextureIndex te )
-{
-	LLColor4 color;
-	U32 param_name[3];
-	if( teToColorParams( te, param_name ) )
-	{
-		color.mV[VX] = getVisualParamWeight( param_name[0] );
-		color.mV[VY] = getVisualParamWeight( param_name[1] );
-		color.mV[VZ] = getVisualParamWeight( param_name[2] );
-	}
-	return color;
-}
-
-// static
-LLColor4 LLVOAvatar::getDummyColor()
-{
-	return DUMMY_COLOR;
-}
-
 void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
 {	
 	LL_DEBUGS("Avatar") << avString() << (isSelf() ? "Self: " : "Other: ") << context << LL_ENDL;
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		// TODO: MULTI-WEARABLE: handle multiple textures for self
 		const LLViewerTexture* te_image = getImage(iter->first,0);
 		if( !te_image )
 		{
-			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null ptr" << LL_ENDL;
-		}
-		else if( te_image->getID().isNull() )
-		{
-			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null UUID" << LL_ENDL;
-		}
-		else if( te_image->getID() == IMG_DEFAULT )
-		{
-			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;
-		}
-		else if( te_image->getID() == IMG_DEFAULT_AVATAR )
-		{
-			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;
-		}
-		else
-		{
-			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;
-		}
-	}
-}
-
-// Unlike most wearable functions, this works for both self and other.
-BOOL LLVOAvatar::isWearingWearableType(LLWearableType::EType type) const
-{
-	if (mIsDummy) return TRUE;
-
-	switch(type)
-	{
-		case LLWearableType::WT_SHAPE:
-		case LLWearableType::WT_SKIN:
-		case LLWearableType::WT_HAIR:
-		case LLWearableType::WT_EYES:
-			return TRUE;  // everyone has all bodyparts
-		default:
-			break; // Do nothing
-	}
-
-	/* switch(type)
-		case LLWearableType::WT_SHIRT:
-			indicator_te = TEX_UPPER_SHIRT; */
-	for (LLVOAvatarDictionary::Textures::const_iterator tex_iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 tex_iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
-		 ++tex_iter)
-	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = tex_iter->second;
-		if (texture_dict->mWearableType == type)
+			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null ptr" << LL_ENDL;
+		}
+		else if( te_image->getID().isNull() )
 		{
-			// If you're checking another avatar's clothing, you don't have component textures.
-			// Thus, you must check to see if the corresponding baked texture is defined.
-			// NOTE: this is a poor substitute if you actually want to know about individual pieces of clothing
-			// this works for detecting a skirt (most important), but is ineffective at any piece of clothing that
-			// gets baked into a texture that always exists (upper or lower).
-			if (texture_dict->mIsUsedByBakedTexture)
-			{
-				const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-				return isTextureDefined(LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex);
-			}
-			return FALSE;
+			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": null UUID" << LL_ENDL;
+		}
+		else if( te_image->getID() == IMG_DEFAULT )
+		{
+			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT" << LL_ENDL;
+		}
+		else if( te_image->getID() == IMG_DEFAULT_AVATAR )
+		{
+			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": IMG_DEFAULT_AVATAR" << LL_ENDL;
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << avString() << "       " << texture_dict->mName << ": " << te_image->getID() << LL_ENDL;
 		}
 	}
-	return FALSE;
 }
 
 //-----------------------------------------------------------------------------
@@ -7192,16 +6646,12 @@ LLBBox LLVOAvatar::getHUDBBox() const
 	return bbox;
 }
 
-void LLVOAvatar::rebuildHUD()
-{
-}
-
 //-----------------------------------------------------------------------------
 // onFirstTEMessageReceived()
 //-----------------------------------------------------------------------------
 void LLVOAvatar::onFirstTEMessageReceived()
 {
-	LL_INFOS("Avatar") << avString() << LL_ENDL;
+	LL_DEBUGS("Avatar") << avString() << LL_ENDL;
 	if( !mFirstTEMessageReceived )
 	{
 		mFirstTEMessageReceived = TRUE;
@@ -7223,7 +6673,7 @@ void LLVOAvatar::onFirstTEMessageReceived()
 			if (layer_baked)
 			{
 				LLViewerFetchedTexture* image = LLViewerTextureManager::staticCastToFetchedTexture(getImage( mBakedTextureDatas[i].mTextureIndex, 0 ), TRUE) ;
-				mBakedTextureDatas[i].mLastTextureIndex = image->getID();
+				mBakedTextureDatas[i].mLastTextureID = image->getID();
 				// If we have more than one texture for the other baked layers, we'll want to call this for them too.
 				if ( (image->getID() != IMG_INVISIBLE) && ((i == BAKED_HEAD) || (i == BAKED_UPPER) || (i == BAKED_LOWER)) )
 				{
@@ -7275,82 +6725,106 @@ bool LLVOAvatar::visualParamWeightsAreDefault()
 	return rtn;
 }
 
-
-//-----------------------------------------------------------------------------
-// processAvatarAppearance()
-//-----------------------------------------------------------------------------
-void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value)
 {
-	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
+	std::string type_string = "unknown";
+	if (dynamic_cast<LLTexLayerParamAlpha*>(viewer_param))
+		type_string = "param_alpha";
+	if (dynamic_cast<LLTexLayerParamColor*>(viewer_param))
+		type_string = "param_color";
+	if (dynamic_cast<LLDriverParam*>(viewer_param))
+		type_string = "param_driver";
+	if (dynamic_cast<LLPolyMorphTarget*>(viewer_param))
+		type_string = "param_morph";
+	if (dynamic_cast<LLPolySkeletalDistortion*>(viewer_param))
+		type_string = "param_skeleton";
+	S32 wtype = -1;
+	LLViewerVisualParam *vparam = dynamic_cast<LLViewerVisualParam*>(viewer_param);
+	if (vparam)
 	{
-		llwarns << "Blocking AvatarAppearance message" << llendl;
-		return;
+		wtype = vparam->getWearableType();
 	}
-	
-	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
-	mFirstAppearanceMessageReceived = TRUE;
+	S32 u8_value = F32_to_U8(value,viewer_param->getMinWeight(),viewer_param->getMaxWeight());
+	apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\" u8=\"%d\" type=\"%s\" wearable=\"%s\"/>\n",
+					viewer_param->getID(), viewer_param->getName().c_str(), value, u8_value, type_string.c_str(),
+					LLWearableType::getTypeName(LLWearableType::EType(wtype)).c_str()
+//					param_location_name(vparam->getParamLocation()).c_str()
+		);
+}
 
-	LL_INFOS("Avatar") << avString() << "processAvatarAppearance start " << mID
-			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
 
+void LLVOAvatar::dumpAppearanceMsgParams( const std::string& dump_prefix,
+	const LLAppearanceMessageContents& contents)
+{
+	std::string outfilename = get_sequential_numbered_file_name(dump_prefix,".xml");
+	const std::vector<F32>& params_for_dump = contents.mParamWeights;
+	const LLTEContents& tec = contents.mTEContents;
 
-	if( isSelf() )
+	LLAPRFile outfile;
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
 	{
-		llwarns << avString() << "Received AvatarAppearance for self" << llendl;
-		if( mFirstTEMessageReceived )
-		{
-//			llinfos << "processAvatarAppearance end  " << mID << llendl;
-			return;
-		}
+		return;
+	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "dumping appearance message to " << fullpath << llendl;
 	}
 
-	ESex old_sex = getSex();
-
-//	llinfos << "LLVOAvatar::processAvatarAppearance()" << llendl;
-//	dumpAvatarTEs( "PRE  processAvatarAppearance()" );
-	unpackTEMessage(mesgsys, _PREHASH_ObjectData);
-//	dumpAvatarTEs( "POST processAvatarAppearance()" );
+	apr_file_printf(file, "<header>\n");
+	apr_file_printf(file, "\t\t<cof_version %i />\n", contents.mCOFVersion);
+	apr_file_printf(file, "\t\t<appearance_version %i />\n", contents.mAppearanceVersion);
+	apr_file_printf(file, "</header>\n");
 
-	// prevent the overwriting of valid baked textures with invalid baked textures
-	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
+	apr_file_printf(file, "\n<params>\n");
+	LLVisualParam* param = getFirstVisualParam();
+	for (S32 i = 0; i < params_for_dump.size(); i++)
 	{
-		if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) 
-			&& mBakedTextureDatas[baked_index].mLastTextureIndex != IMG_DEFAULT
-			&& baked_index != BAKED_SKIRT)
+		while( param && (param->getGroup() != VISUAL_PARAM_GROUP_TWEAKABLE) ) // should not be any of group VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
 		{
-			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
-				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureIndex, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+			param = getNextVisualParam();
 		}
+		LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+		F32 value = params_for_dump[i];
+		dump_visual_param(file, viewer_param, value);
+		param = getNextVisualParam();
 	}
+	apr_file_printf(file, "</params>\n");
 
-
-	// runway - was
-	// if (!is_first_appearance_message )
-	// which means it would be called on second appearance message - probably wrong.
-	if (is_first_appearance_message )
+	apr_file_printf(file, "\n<textures>\n");
+	for (U32 i = 0; i < tec.face_count; i++)
 	{
-		onFirstTEMessageReceived();
+		std::string uuid_str;
+		((LLUUID*)tec.image_data)[i].toString(uuid_str);
+		apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", i, uuid_str.c_str());
 	}
+	apr_file_printf(file, "</textures>\n");
+}
 
-	setCompositeUpdatesEnabled( FALSE );
-	mMeshTexturesDirty = TRUE;
-	gPipeline.markGLRebuild(this);
+void LLVOAvatar::parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& contents)
+{
+	parseTEMessage(mesgsys, _PREHASH_ObjectData, -1, contents.mTEContents);
 
-	// ! BACKWARDS COMPATIBILITY !
-	// Non-self avatars will no longer have component textures
-	if (!isSelf())
+	// Parse the AppearanceData field, if any.
+	if (mesgsys->has(_PREHASH_AppearanceData))
 	{
-		releaseComponentTextures();
+		U8 av_u8;
+		mesgsys->getU8Fast(_PREHASH_AppearanceData, _PREHASH_AppearanceVersion, av_u8, 0);
+		contents.mAppearanceVersion = av_u8;
+		LL_DEBUGS("Avatar") << "appversion set by AppearanceData field: " << contents.mAppearanceVersion << llendl;
+		mesgsys->getS32Fast(_PREHASH_AppearanceData, _PREHASH_CofVersion, contents.mCOFVersion, 0);
+		// For future use:
+		//mesgsys->getU32Fast(_PREHASH_AppearanceData, _PREHASH_Flags, appearance_flags, 0);
 	}
-	
-	// parse visual params
+
+	// Parse visual params, if any.
 	S32 num_blocks = mesgsys->getNumberOfBlocksFast(_PREHASH_VisualParam);
 	bool drop_visual_params_debug = gSavedSettings.getBOOL("BlockSomeAvatarAppearanceVisualParams") && (ll_rand(2) == 0); // pretend that ~12% of AvatarAppearance messages arrived without a VisualParam block, for testing
 	if( num_blocks > 1 && !drop_visual_params_debug)
 	{
 		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_blocks " << num_blocks << LL_ENDL;
-		BOOL params_changed = FALSE;
-		BOOL interp_params = FALSE;
 		
 		LLVisualParam* param = getFirstVisualParam();
 		llassert(param); // if this ever fires, we should do the same as when num_blocks<=1
@@ -7376,21 +6850,9 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 				U8 value;
 				mesgsys->getU8Fast(_PREHASH_VisualParam, _PREHASH_ParamValue, value, i);
 				F32 newWeight = U8_to_F32(value, param->getMinWeight(), param->getMaxWeight());
+				contents.mParamWeights.push_back(newWeight);
+				contents.mParams.push_back(param);
 
-				if (is_first_appearance_message || (param->getWeight() != newWeight))
-				{
-					//llinfos << "Received update for param " << param->getDisplayName() << " at value " << newWeight << llendl;
-					params_changed = TRUE;
-					if(is_first_appearance_message)
-					{
-						param->setWeight(newWeight, FALSE);
-					}
-					else
-					{
-						interp_params = TRUE;
-						param->setAnimationTarget(newWeight, FALSE);
-					}
-				}
 				param = getNextVisualParam();
 			}
 		}
@@ -7398,7 +6860,210 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
 		if (num_blocks != expected_tweakable_count)
 		{
-			llinfos << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
+			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_blocks << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
+		}
+	}
+	else
+	{
+		if (drop_visual_params_debug)
+		{
+			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl;
+		}
+		else
+		{
+			LL_DEBUGS("Avatar") << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
+		}
+	}
+
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	if (appearance_version_param)
+	{
+		std::vector<LLVisualParam*>::iterator it = std::find(contents.mParams.begin(), contents.mParams.end(),appearance_version_param);
+		if (it != contents.mParams.end())
+		{
+			S32 index = it - contents.mParams.begin();
+			contents.mParamAppearanceVersion = llround(contents.mParamWeights[index]);
+			LL_DEBUGS("Avatar") << "appversion req by appearance_version param: " << contents.mParamAppearanceVersion << llendl;
+		}
+	}
+}
+
+bool resolve_appearance_version(const LLAppearanceMessageContents& contents, S32& appearance_version)
+{
+	appearance_version = -1;
+	
+	if ((contents.mAppearanceVersion) >= 0 &&
+		(contents.mParamAppearanceVersion >= 0) &&
+		(contents.mAppearanceVersion != contents.mParamAppearanceVersion))
+	{
+		llwarns << "inconsistent appearance_version settings - field: " <<
+			contents.mAppearanceVersion << ", param: " <<  contents.mParamAppearanceVersion << llendl;
+		return false;
+	}
+	if (contents.mParamAppearanceVersion >= 0) // use visual param if available.
+	{
+		appearance_version = contents.mParamAppearanceVersion;
+	}
+	if (contents.mAppearanceVersion >= 0)
+	{
+		appearance_version = contents.mAppearanceVersion;
+	}
+	if (appearance_version < 0) // still not set, go with 0.
+	{
+		appearance_version = 0;
+	}
+	LL_DEBUGS("Avatar") << "appearance version info - field " << contents.mAppearanceVersion
+						<< " param: " << contents.mParamAppearanceVersion
+						<< " final: " << appearance_version << llendl;
+	return true;
+}
+
+//-----------------------------------------------------------------------------
+// processAvatarAppearance()
+//-----------------------------------------------------------------------------
+void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
+{
+	LL_DEBUGS("Avatar") << "starts" << llendl;
+	
+	bool enable_verbose_dumps = gSavedSettings.getBOOL("DebugAvatarAppearanceMessage");
+	std::string dump_prefix = getFullname() + "_" + (isSelf()?"s":"o") + "_";
+	if (gSavedSettings.getBOOL("BlockAvatarAppearanceMessages"))
+	{
+		llwarns << "Blocking AvatarAppearance message" << llendl;
+		return;
+	}
+
+	ESex old_sex = getSex();
+
+	LLAppearanceMessageContents contents;
+	parseAppearanceMessage(mesgsys, contents);
+	if (enable_verbose_dumps)
+	{
+		dumpAppearanceMsgParams(dump_prefix + "appearance_msg", contents);
+	}
+
+	S32 appearance_version;
+	if (!resolve_appearance_version(contents, appearance_version))
+	{
+		llwarns << "bad appearance version info, discarding" << llendl;
+		return;
+	}
+	S32 this_update_cof_version = contents.mCOFVersion;
+	S32 last_update_request_cof_version = mLastUpdateRequestCOFVersion;
+
+	// Only now that we have result of appearance_version can we decide whether to bail out.
+	if( isSelf() )
+	{
+		LL_DEBUGS("Avatar") << "this_update_cof_version " << this_update_cof_version
+				<< " last_update_request_cof_version " << last_update_request_cof_version
+				<<  " my_cof_version " << LLAppearanceMgr::instance().getCOFVersion() << llendl;
+
+		if (getRegion() && (getRegion()->getCentralBakeVersion()==0))
+		{
+			llwarns << avString() << "Received AvatarAppearance message for self in non-server-bake region" << llendl;
+		}
+		if( mFirstTEMessageReceived && (appearance_version == 0))
+		{
+			return;
+		}
+	}
+	else
+	{
+		LL_DEBUGS("Avatar") << "appearance message received" << llendl;
+	}
+
+	// Check for stale update.
+	if (isSelf()
+		&& (appearance_version>0)
+		&& (this_update_cof_version < last_update_request_cof_version))
+	{
+		llwarns << "Stale appearance update, wanted version " << last_update_request_cof_version
+				<< ", got " << this_update_cof_version << llendl;
+		return;
+	}
+
+	if (isSelf() && isEditingAppearance())
+	{
+		LL_DEBUGS("Avatar") << "ignoring appearance message while in appearance edit" << llendl;
+		return;
+	}
+
+	S32 num_params = contents.mParamWeights.size();
+	if (num_params <= 1)
+	{
+		// In this case, we have no reliable basis for knowing
+		// appearance version, which may cause us to look for baked
+		// textures in the wrong place and flag them as missing
+		// assets.
+		LL_DEBUGS("Avatar") << "ignoring appearance message due to lack of params" << llendl;
+		return;
+	}
+
+	mLastUpdateReceivedCOFVersion = this_update_cof_version;
+		
+	setIsUsingServerBakes(appearance_version > 0);
+
+	applyParsedTEMessage(contents.mTEContents);
+
+	// prevent the overwriting of valid baked textures with invalid baked textures
+	for (U8 baked_index = 0; baked_index < mBakedTextureDatas.size(); baked_index++)
+	{
+		if (!isTextureDefined(mBakedTextureDatas[baked_index].mTextureIndex) 
+			&& mBakedTextureDatas[baked_index].mLastTextureID != IMG_DEFAULT
+			&& baked_index != BAKED_SKIRT)
+		{
+			setTEImage(mBakedTextureDatas[baked_index].mTextureIndex, 
+				LLViewerTextureManager::getFetchedTexture(mBakedTextureDatas[baked_index].mLastTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+		}
+	}
+
+	// runway - was
+	// if (!is_first_appearance_message )
+	// which means it would be called on second appearance message - probably wrong.
+	BOOL is_first_appearance_message = !mFirstAppearanceMessageReceived;
+	mFirstAppearanceMessageReceived = TRUE;
+
+	LL_DEBUGS("Avatar") << avString() << "processAvatarAppearance start " << mID
+			<< " first? " << is_first_appearance_message << " self? " << isSelf() << LL_ENDL;
+
+	if (is_first_appearance_message )
+	{
+		onFirstTEMessageReceived();
+	}
+
+	setCompositeUpdatesEnabled( FALSE );
+	gPipeline.markGLRebuild(this);
+
+	// Apply visual params
+	if( num_params > 1)
+	{
+		LL_DEBUGS("Avatar") << avString() << " handle visual params, num_params " << num_params << LL_ENDL;
+		BOOL params_changed = FALSE;
+		BOOL interp_params = FALSE;
+		
+		for( S32 i = 0; i < num_params; i++ )
+		{
+			LLVisualParam* param = contents.mParams[i];
+			F32 newWeight = contents.mParamWeights[i];
+
+			if (is_first_appearance_message || (param->getWeight() != newWeight))
+			{
+				params_changed = TRUE;
+				if(is_first_appearance_message)
+				{
+					param->setWeight(newWeight, FALSE);
+				}
+				else
+				{
+					interp_params = TRUE;
+					param->setAnimationTarget(newWeight, FALSE);
+				}
+			}
+		}
+		const S32 expected_tweakable_count = getVisualParamCountInGroup(VISUAL_PARAM_GROUP_TWEAKABLE); // don't worry about VISUAL_PARAM_GROUP_TWEAKABLE_NO_TRANSMIT
+		if (num_params != expected_tweakable_count)
+		{
+			LL_DEBUGS("Avatar") << "Number of params in AvatarAppearance msg (" << num_params << ") does not match number of tweakable params in avatar xml file (" << expected_tweakable_count << ").  Processing what we can.  object: " << getID() << llendl;
 		}
 
 		if (params_changed)
@@ -7422,14 +7087,6 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 	{
 		// AvatarAppearance message arrived without visual params
 		LL_DEBUGS("Avatar") << avString() << "no visual params" << LL_ENDL;
-		if (drop_visual_params_debug)
-		{
-			llinfos << "Debug-faked lack of parameters on AvatarAppearance for object: "  << getID() << llendl;
-		}
-		else
-		{
-			llinfos << "AvatarAppearance msg received without any parameters, object: " << getID() << llendl;
-		}
 
 		const F32 LOADING_TIMEOUT_SECONDS = 60.f;
 		// this isn't really a problem if we already have a non-default shape
@@ -7452,7 +7109,14 @@ void LLVOAvatar::processAvatarAppearance( LLMessageSystem* mesgsys )
 	// If all of the avatars are completely baked, release the global image caches to conserve memory.
 	LLVOAvatar::cullAvatarsByPixelArea();
 
-//	llinfos << "processAvatarAppearance end " << mID << llendl;
+	if (isSelf())
+	{
+		mUseLocalAppearance = false;
+	}
+
+	updateMeshTextures();
+
+	//if (enable_verbose_dumps) dumpArchetypeXML(dump_prefix + "process_end");
 }
 
 // static
@@ -7482,6 +7146,7 @@ void LLVOAvatar::getAnimNames( LLDynamicArray<std::string>* names )
 	names->put( "enter_away_from_keyboard_state" );
 }
 
+// static
 void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata )
 {
 	if (!userdata) return;
@@ -7500,7 +7165,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 		{
 			if (!aux_src->getData())
 			{
-				llerrs << "No auxiliary source data for onBakedTextureMasksLoaded" << llendl;
+				llerrs << "No auxiliary source (morph mask) data for image id " << id << llendl;
 				return;
 			}
 
@@ -7525,12 +7190,12 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 					 self->mBakedTextureDatas[BAKED_HEAD].mTexLayerSet->applyMorphMask(aux_src->getData(), aux_src->getWidth(), aux_src->getHeight(), 1);
 					 maskData->mLastDiscardLevel = discard_level; */
 			BOOL found_texture_id = false;
-			for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-				 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+			for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+				 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 				 ++iter)
 			{
 
-				const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+				const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 				if (texture_dict->mIsUsedByBakedTexture)
 				{
 					const ETextureIndex texture_index = iter->first;
@@ -7552,7 +7217,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 			}
 			if (!found_texture_id)
 			{
-				llinfos << "onBakedTextureMasksLoaded(): unexpected image id: " << id << llendl;
+				llinfos << "unexpected image id: " << id << llendl;
 			}
 			self->dirtyMesh();
 		}
@@ -7560,7 +7225,7 @@ void LLVOAvatar::onBakedTextureMasksLoaded( BOOL success, LLViewerFetchedTexture
 		{
             // this can happen when someone uses an old baked texture possibly provided by 
             // viewer-side baked texture caching
-			llwarns << "Masks loaded callback but NO aux source!" << llendl;
+			llwarns << "Masks loaded callback but NO aux source, id " << id << llendl;
 		}
 	}
 
@@ -7577,7 +7242,7 @@ void LLVOAvatar::onInitialBakedTextureLoaded( BOOL success, LLViewerFetchedTextu
 	
 	LLUUID *avatar_idp = (LLUUID *)userdata;
 	LLVOAvatar *selfp = (LLVOAvatar *)gObjectList.findObject(*avatar_idp);
-	
+
 	if (selfp)
 	{
 		LL_DEBUGS("Avatar") << selfp->avString() << "discard_level " << discard_level << " success " << success << " final " << final << LL_ENDL;
@@ -7598,7 +7263,7 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success,
 									  LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src,
 									  S32 discard_level, BOOL final, void* userdata)
 {
-	//llinfos << "onBakedTextureLoaded: " << src_vi->getID() << llendl;
+	LL_DEBUGS("Avatar") << "onBakedTextureLoaded: " << src_vi->getID() << LL_ENDL;
 
 	LLUUID id = src_vi->getID();
 	LLUUID *avatar_idp = (LLUUID *)userdata;
@@ -7628,13 +7293,6 @@ void LLVOAvatar::onBakedTextureLoaded(BOOL success,
 // Called when baked texture is loaded and also when we start up with a baked texture
 void LLVOAvatar::useBakedTexture( const LLUUID& id )
 {
-
-	
-	/* if(id == head_baked->getID())
-		 mHeadBakedLoaded = TRUE;
-		 mLastHeadBakedID = id;
-		 mHeadMesh0.setTexture( head_baked );
-		 mHeadMesh1.setTexture( head_baked ); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		LLViewerTexture* image_baked = getImage( mBakedTextureDatas[i].mTextureIndex, 0 );
@@ -7642,17 +7300,31 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 		{
 			LL_DEBUGS("Avatar") << avString() << " i " << i << " id " << id << LL_ENDL;
 			mBakedTextureDatas[i].mIsLoaded = true;
-			mBakedTextureDatas[i].mLastTextureIndex = id;
+			mBakedTextureDatas[i].mLastTextureID = id;
 			mBakedTextureDatas[i].mIsUsed = true;
-			for (U32 k = 0; k < mBakedTextureDatas[i].mMeshes.size(); k++)
+
+			if (isUsingLocalAppearance())
 			{
-				mBakedTextureDatas[i].mMeshes[k]->setTexture( image_baked );
+				llinfos << "not changing to baked texture while isUsingLocalAppearance" << llendl;
 			}
-			if (mBakedTextureDatas[i].mTexLayerSet)
+			else
 			{
-				//mBakedTextureDatas[i].mTexLayerSet->destroyComposite();
+				debugColorizeSubMeshes(i,LLColor4::green);
+
+				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+				for (; iter != end; ++iter)
+				{
+					LLAvatarJointMesh* mesh = (*iter);
+					if (mesh)
+					{
+						mesh->setTexture( image_baked );
+					}
+				}
 			}
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+			
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict =
+				LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
@@ -7665,9 +7337,15 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 			// This is paired with similar code in updateMeshTextures that sets hair mesh color.
 			if (i == BAKED_HAIR)
 			{
-				for (U32 i = 0; i < mBakedTextureDatas[BAKED_HAIR].mMeshes.size(); i++)
+				avatar_joint_mesh_list_t::iterator iter = mBakedTextureDatas[i].mJointMeshes.begin();
+				avatar_joint_mesh_list_t::iterator end  = mBakedTextureDatas[i].mJointMeshes.end();
+				for (; iter != end; ++iter)
 				{
-					mBakedTextureDatas[BAKED_HAIR].mMeshes[i]->setColor( 1.f, 1.f, 1.f, 1.f );
+					LLAvatarJointMesh* mesh = (*iter);
+					if (mesh)
+					{
+						mesh->setColor( LLColor4::white );
+					}
 				}
 			}
 		}
@@ -7676,11 +7354,39 @@ void LLVOAvatar::useBakedTexture( const LLUUID& id )
 	dirtyMesh();
 }
 
-// static
-void LLVOAvatar::dumpArchetypeXML( void* )
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+											  const std::string& suffix)
+{
+	typedef std::map<std::string,S32> file_num_type;
+	static  file_num_type file_nums;
+	file_num_type::iterator it = file_nums.find(prefix);
+	S32 num = 0;
+	if (it != file_nums.end())
+	{
+		num = it->second;
+	}
+	file_nums[prefix] = num+1;
+	std::string outfilename = prefix + " " + llformat("%04d",num) + ".xml";
+	std::replace(outfilename.begin(),outfilename.end(),' ','_');
+	return outfilename;
+}
+
+void LLVOAvatar::dumpArchetypeXML(const std::string& prefix, bool group_by_wearables )
 {
+	std::string outprefix(prefix);
+	if (outprefix.empty())
+	{
+		outprefix = getFullname() + (isSelf()?"_s":"_o");
+	}
+	if (outprefix.empty())
+	{
+		outprefix = std::string("new_archetype");
+	}
+	std::string outfilename = get_sequential_numbered_file_name(outprefix,".xml");
+	
 	LLAPRFile outfile;
-	outfile.open(gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml"), LL_APR_WB );
+	std::string fullpath = gDirUtilp->getExpandedFilename(LL_PATH_LOGS,outfilename);
+	outfile.open(fullpath, LL_APR_WB );
 	apr_file_t* file = outfile.getFileHandle();
 	if (!file)
 	{
@@ -7688,36 +7394,60 @@ void LLVOAvatar::dumpArchetypeXML( void* )
 	}
 	else
 	{
-		llinfos << "xmlfile write handle obtained : " << gDirUtilp->getExpandedFilename(LL_PATH_USER_SETTINGS,"new archetype.xml") << llendl;
+		llinfos << "xmlfile write handle obtained : " << fullpath << llendl;
 	}
 
 	apr_file_printf( file, "<?xml version=\"1.0\" encoding=\"US-ASCII\" standalone=\"yes\"?>\n" );
 	apr_file_printf( file, "<linden_genepool version=\"1.0\">\n" );
 	apr_file_printf( file, "\n\t<archetype name=\"???\">\n" );
 
-	// only body parts, not clothing.
-	for (S32 type = LLWearableType::WT_SHAPE; type <= LLWearableType::WT_EYES; type++)
+	if (group_by_wearables)
+	{
+		for (S32 type = LLWearableType::WT_SHAPE; type < LLWearableType::WT_COUNT; type++)
+		{
+			const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+			apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
+
+			for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
+			{
+				LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
+				if( (viewer_param->getWearableType() == type) && 
+					(viewer_param->isTweakable() ) )
+				{
+					dump_visual_param(file, viewer_param, viewer_param->getWeight());
+				}
+			}
+
+			for (U8 te = 0; te < TEX_NUM_INDICES; te++)
+			{
+				if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex)te) == type)
+				{
+					// MULTIPLE_WEARABLES: extend to multiple wearables?
+					LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
+					if( te_image )
+					{
+						std::string uuid_str;
+						te_image->getID().toString( uuid_str );
+						apr_file_printf( file, "\t\t<texture te=\"%i\" uuid=\"%s\"/>\n", te, uuid_str.c_str());
+					}
+				}
+			}
+		}
+	}
+	else 
 	{
-		const std::string& wearable_name = LLWearableType::getTypeName((LLWearableType::EType)type);
-		apr_file_printf( file, "\n\t\t<!-- wearable: %s -->\n", wearable_name.c_str() );
-
-		for (LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam())
+		// Just dump all params sequentially.
+		for (LLVisualParam* param = getFirstVisualParam(); param; param = getNextVisualParam())
 		{
 			LLViewerVisualParam* viewer_param = (LLViewerVisualParam*)param;
-			if( (viewer_param->getWearableType() == type) && 
-				(viewer_param->isTweakable() ) )
-			{
-				apr_file_printf(file, "\t\t<param id=\"%d\" name=\"%s\" value=\"%.3f\"/>\n",
-								viewer_param->getID(), viewer_param->getName().c_str(), viewer_param->getWeight());
-			}
+			dump_visual_param(file, viewer_param, viewer_param->getWeight());
 		}
 
 		for (U8 te = 0; te < TEX_NUM_INDICES; te++)
 		{
-			if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex)te) == type)
 			{
 				// MULTIPLE_WEARABLES: extend to multiple wearables?
-				LLViewerTexture* te_image = ((LLVOAvatar *)(gAgentAvatarp))->getImage((ETextureIndex)te, 0);
+				LLViewerTexture* te_image = getImage((ETextureIndex)te, 0);
 				if( te_image )
 				{
 					std::string uuid_str;
@@ -7726,14 +7456,18 @@ void LLVOAvatar::dumpArchetypeXML( void* )
 				}
 			}
 		}
+
 	}
 	apr_file_printf( file, "\t</archetype>\n" );
 	apr_file_printf( file, "\n</linden_genepool>\n" );
-	//explictly close the file if it is still open which it should be
-	if (file)
+
+	bool ultra_verbose = false;
+	if (isSelf() && ultra_verbose)
 	{
-		outfile.close();
+		// show the cloned params inside the wearables as well.
+		gAgentAvatarp->dumpWearableInfo(outfile);
 	}
+	// File will close when handle goes out of scope
 }
 
 
@@ -7815,15 +7549,9 @@ void LLVOAvatar::cullAvatarsByPixelArea()
 		}
 	}
 
-	// runway - this doesn't detect gray/grey state.
-	// think we just need to be checking self av since it's the only
-	// one with lltexlayer stuff.
+	// runway - this doesn't really detect gray/grey state.
 	S32 grey_avatars = 0;
-	if (LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
-	{
-		LLVOAvatar::deleteCachedImages(false);
-	}
-	else
+	if (!LLVOAvatar::areAllNearbyInstancesBaked(grey_avatars))
 	{
 		if (gFrameTimeSeconds != sUnbakedUpdateTime) // only update once per frame
 		{
@@ -7851,501 +7579,44 @@ void LLVOAvatar::startAppearanceAnimation()
 	}
 }
 
-// virtual
-void LLVOAvatar::removeMissingBakedTextures()
-{	
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarXmlInfo
-//-----------------------------------------------------------------------------
-
-LLVOAvatar::LLVOAvatarXmlInfo::LLVOAvatarXmlInfo()
-	: mTexSkinColorInfo(0), mTexHairColorInfo(0), mTexEyeColorInfo(0)
-{
-}
-
-LLVOAvatar::LLVOAvatarXmlInfo::~LLVOAvatarXmlInfo()
-{
-	std::for_each(mMeshInfoList.begin(), mMeshInfoList.end(), DeletePointer());
-	std::for_each(mSkeletalDistortionInfoList.begin(), mSkeletalDistortionInfoList.end(), DeletePointer());		
-	std::for_each(mAttachmentInfoList.begin(), mAttachmentInfoList.end(), DeletePointer());
-	deleteAndClear(mTexSkinColorInfo);
-	deleteAndClear(mTexHairColorInfo);
-	deleteAndClear(mTexEyeColorInfo);
-	std::for_each(mLayerInfoList.begin(), mLayerInfoList.end(), DeletePointer());		
-	std::for_each(mDriverInfoList.begin(), mDriverInfoList.end(), DeletePointer());
-	std::for_each(mMorphMaskInfoList.begin(), mMorphMaskInfoList.end(), DeletePointer());
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarBoneInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarBoneInfo::parseXml(LLXmlTreeNode* node)
-{
-	if (node->hasName("bone"))
-	{
-		mIsJoint = TRUE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			llwarns << "Bone without name" << llendl;
-			return FALSE;
-		}
-	}
-	else if (node->hasName("collision_volume"))
-	{
-		mIsJoint = FALSE;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!node->getFastAttributeString(name_string, mName))
-		{
-			mName = "Collision Volume";
-		}
-	}
-	else
-	{
-		llwarns << "Invalid node " << node->getName() << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle pos_string = LLXmlTree::addAttributeString("pos");
-	if (!node->getFastAttributeVector3(pos_string, mPos))
-	{
-		llwarns << "Bone without position" << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle rot_string = LLXmlTree::addAttributeString("rot");
-	if (!node->getFastAttributeVector3(rot_string, mRot))
-	{
-		llwarns << "Bone without rotation" << llendl;
-		return FALSE;
-	}
-	
-	static LLStdStringHandle scale_string = LLXmlTree::addAttributeString("scale");
-	if (!node->getFastAttributeVector3(scale_string, mScale))
-	{
-		llwarns << "Bone without scale" << llendl;
-		return FALSE;
-	}
-
-	if (mIsJoint)
-	{
-		static LLStdStringHandle pivot_string = LLXmlTree::addAttributeString("pivot");
-		if (!node->getFastAttributeVector3(pivot_string, mPivot))
-		{
-			llwarns << "Bone without pivot" << llendl;
-			return FALSE;
-		}
-	}
-
-	// parse children
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *child_info = new LLVOAvatarBoneInfo;
-		if (!child_info->parseXml(child))
-		{
-			delete child_info;
-			return FALSE;
-		}
-		mChildList.push_back(child_info);
-	}
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// LLVOAvatarSkeletonInfo::parseXml()
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatarSkeletonInfo::parseXml(LLXmlTreeNode* node)
-{
-	static LLStdStringHandle num_bones_string = LLXmlTree::addAttributeString("num_bones");
-	if (!node->getFastAttributeS32(num_bones_string, mNumBones))
-	{
-		llwarns << "Couldn't find number of bones." << llendl;
-		return FALSE;
-	}
-
-	static LLStdStringHandle num_collision_volumes_string = LLXmlTree::addAttributeString("num_collision_volumes");
-	node->getFastAttributeS32(num_collision_volumes_string, mNumCollisionVolumes);
-
-	LLXmlTreeNode* child;
-	for( child = node->getFirstChild(); child; child = node->getNextChild() )
-	{
-		LLVOAvatarBoneInfo *info = new LLVOAvatarBoneInfo;
-		if (!info->parseXml(child))
-		{
-			delete info;
-			llwarns << "Error parsing bone in skeleton file" << llendl;
-			return FALSE;
-		}
-		mBoneInfoList.push_back(info);
-	}
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlSkeletonNode(): parses <skeleton> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlSkeletonNode(LLXmlTreeNode* root)
-{
-	LLXmlTreeNode* node = root->getChildByName( "skeleton" );
-	if( !node )
-	{
-		llwarns << "avatar file: missing <skeleton>" << llendl;
-		return FALSE;
-	}
-
-	LLXmlTreeNode* child;
-
-	// SKELETON DISTORTIONS
-	for (child = node->getChildByName( "param" );
-		 child;
-		 child = node->getNextNamedChild())
-	{
-		if (!child->getChildByName("param_skeleton"))
-		{
-			if (child->getChildByName("param_morph"))
-			{
-				llwarns << "Can't specify morph param in skeleton definition." << llendl;
-			}
-			else
-			{
-				llwarns << "Unknown param type." << llendl;
-			}
-			continue;
-		}
-		
-		LLPolySkeletalDistortionInfo *info = new LLPolySkeletalDistortionInfo;
-		if (!info->parseXml(child))
-		{
-			delete info;
-			return FALSE;
-		}
-
-		mSkeletalDistortionInfoList.push_back(info);
-	}
-
-	// ATTACHMENT POINTS
-	for (child = node->getChildByName( "attachment_point" );
-		 child;
-		 child = node->getNextNamedChild())
-	{
-		LLVOAvatarAttachmentInfo* info = new LLVOAvatarAttachmentInfo();
-
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (!child->getFastAttributeString(name_string, info->mName))
-		{
-			llwarns << "No name supplied for attachment point." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle joint_string = LLXmlTree::addAttributeString("joint");
-		if (!child->getFastAttributeString(joint_string, info->mJointName))
-		{
-			llwarns << "No bone declared in attachment point " << info->mName << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle position_string = LLXmlTree::addAttributeString("position");
-		if (child->getFastAttributeVector3(position_string, info->mPosition))
-		{
-			info->mHasPosition = TRUE;
-		}
-
-		static LLStdStringHandle rotation_string = LLXmlTree::addAttributeString("rotation");
-		if (child->getFastAttributeVector3(rotation_string, info->mRotationEuler))
-		{
-			info->mHasRotation = TRUE;
-		}
-		 static LLStdStringHandle group_string = LLXmlTree::addAttributeString("group");
-		if (child->getFastAttributeS32(group_string, info->mGroup))
-		{
-			if (info->mGroup == -1)
-				info->mGroup = -1111; // -1 = none parsed, < -1 = bad value
-		}
-
-		static LLStdStringHandle id_string = LLXmlTree::addAttributeString("id");
-		if (!child->getFastAttributeS32(id_string, info->mAttachmentID))
-		{
-			llwarns << "No id supplied for attachment point " << info->mName << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle slot_string = LLXmlTree::addAttributeString("pie_slice");
-		child->getFastAttributeS32(slot_string, info->mPieMenuSlice);
-			
-		static LLStdStringHandle visible_in_first_person_string = LLXmlTree::addAttributeString("visible_in_first_person");
-		child->getFastAttributeBOOL(visible_in_first_person_string, info->mVisibleFirstPerson);
-
-		static LLStdStringHandle hud_attachment_string = LLXmlTree::addAttributeString("hud");
-		child->getFastAttributeBOOL(hud_attachment_string, info->mIsHUDAttachment);
-
-		mAttachmentInfoList.push_back(info);
-	}
-
-	return TRUE;
-}
-
-//-----------------------------------------------------------------------------
-// parseXmlMeshNodes(): parses <mesh> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMeshNodes(LLXmlTreeNode* root)
+//virtual
+void LLVOAvatar::bodySizeChanged()
 {
-	for (LLXmlTreeNode* node = root->getChildByName( "mesh" );
-		 node;
-		 node = root->getNextNamedChild())
-	{
-		LLVOAvatarMeshInfo *info = new LLVOAvatarMeshInfo;
-
-		// attribute: type
-		static LLStdStringHandle type_string = LLXmlTree::addAttributeString("type");
-		if( !node->getFastAttributeString( type_string, info->mType ) )
-		{
-			llwarns << "Avatar file: <mesh> is missing type attribute.  Ignoring element. " << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-		
-		static LLStdStringHandle lod_string = LLXmlTree::addAttributeString("lod");
-		if (!node->getFastAttributeS32( lod_string, info->mLOD ))
-		{
-			llwarns << "Avatar file: <mesh> is missing lod attribute.  Ignoring element. " << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-
-		static LLStdStringHandle file_name_string = LLXmlTree::addAttributeString("file_name");
-		if( !node->getFastAttributeString( file_name_string, info->mMeshFileName ) )
-		{
-			llwarns << "Avatar file: <mesh> is missing file_name attribute.  Ignoring: " << info->mType << llendl;
-			delete info;
-			return FALSE;  // Ignore this element
-		}
-
-		static LLStdStringHandle reference_string = LLXmlTree::addAttributeString("reference");
-		node->getFastAttributeString( reference_string, info->mReferenceMeshName );
-		
-		// attribute: min_pixel_area
-		static LLStdStringHandle min_pixel_area_string = LLXmlTree::addAttributeString("min_pixel_area");
-		static LLStdStringHandle min_pixel_width_string = LLXmlTree::addAttributeString("min_pixel_width");
-		if (!node->getFastAttributeF32( min_pixel_area_string, info->mMinPixelArea ))
-		{
-			F32 min_pixel_area = 0.1f;
-			if (node->getFastAttributeF32( min_pixel_width_string, min_pixel_area ))
-			{
-				// this is square root of pixel area (sensible to use linear space in defining lods)
-				min_pixel_area = min_pixel_area * min_pixel_area;
-			}
-			info->mMinPixelArea = min_pixel_area;
-		}
-		
-		// Parse visual params for this node only if we haven't already
-		for (LLXmlTreeNode* child = node->getChildByName( "param" );
-			 child;
-			 child = node->getNextNamedChild())
-		{
-			if (!child->getChildByName("param_morph"))
-			{
-				if (child->getChildByName("param_skeleton"))
-				{
-					llwarns << "Can't specify skeleton param in a mesh definition." << llendl;
-				}
-				else
-				{
-					llwarns << "Unknown param type." << llendl;
-				}
-				continue;
-			}
-
-			LLPolyMorphTargetInfo *morphinfo = new LLPolyMorphTargetInfo();
-			if (!morphinfo->parseXml(child))
-			{
-				delete morphinfo;
-				delete info;
-				return -1;
-			}
-			BOOL shared = FALSE;
-			static LLStdStringHandle shared_string = LLXmlTree::addAttributeString("shared");
-			child->getFastAttributeBOOL(shared_string, shared);
-
-			info->mPolyMorphTargetInfoList.push_back(LLVOAvatarMeshInfo::morph_info_pair_t(morphinfo, shared));
-		}
-
-		mMeshInfoList.push_back(info);
+	if (isSelf() && !LLAppearanceMgr::instance().isInUpdateAppearanceFromCOF())
+	{	// notify simulator of change in size
+		// but not if we are in the middle of updating appearance
+		gAgent.sendAgentSetAppearance();
 	}
-	return TRUE;
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlColorNodes(): parses <global_color> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlColorNodes(LLXmlTreeNode* root)
+BOOL LLVOAvatar::isUsingServerBakes() const
 {
-	for (LLXmlTreeNode* color_node = root->getChildByName( "global_color" );
-		 color_node;
-		 color_node = root->getNextNamedChild())
+#if 1
+	// Sanity check - visual param for appearance version should match mUseServerBakes
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	llassert(appearance_version_param);
+	F32 wt = appearance_version_param->getWeight();
+	F32 expect_wt = mUseServerBakes ? 1.0 : 0.0;
+	if (!is_approx_equal(wt,expect_wt))
 	{
-		std::string global_color_name;
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("name");
-		if (color_node->getFastAttributeString( name_string, global_color_name ) )
-		{
-			if( global_color_name == "skin_color" )
-			{
-				if (mTexSkinColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of skin_color" << llendl;
-					return FALSE;
-				}
-				mTexSkinColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexSkinColorInfo->parseXml( color_node ) )
-				{
-					deleteAndClear(mTexSkinColorInfo);
-					llwarns << "avatar file: mTexSkinColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-			else if( global_color_name == "hair_color" )
-			{
-				if (mTexHairColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of hair_color" << llendl;
-					return FALSE;
-				}
-				mTexHairColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexHairColorInfo->parseXml( color_node ) )
-				{
-					deleteAndClear(mTexHairColorInfo);
-					llwarns << "avatar file: mTexHairColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-			else if( global_color_name == "eye_color" )
-			{
-				if (mTexEyeColorInfo)
-				{
-					llwarns << "avatar file: multiple instances of eye_color" << llendl;
-					return FALSE;
-				}
-				mTexEyeColorInfo = new LLTexGlobalColorInfo;
-				if( !mTexEyeColorInfo->parseXml( color_node ) )
-				{
-					llwarns << "avatar file: mTexEyeColor->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-		}
+		llwarns << "wt " << wt << " differs from expected " << expect_wt << llendl;
 	}
-	return TRUE;
-}
+#endif
 
-//-----------------------------------------------------------------------------
-// parseXmlLayerNodes(): parses <layer_set> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlLayerNodes(LLXmlTreeNode* root)
-{
-	for (LLXmlTreeNode* layer_node = root->getChildByName( "layer_set" );
-		 layer_node;
-		 layer_node = root->getNextNamedChild())
-	{
-		LLTexLayerSetInfo* layer_info = new LLTexLayerSetInfo();
-		if( layer_info->parseXml( layer_node ) )
-		{
-			mLayerInfoList.push_back(layer_info);
-		}
-		else
-		{
-			delete layer_info;
-			llwarns << "avatar file: layer_set->parseXml() failed" << llendl;
-			return FALSE;
-		}
-	}
-	return TRUE;
+	return mUseServerBakes;
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlDriverNodes(LLXmlTreeNode* root)
+void LLVOAvatar::setIsUsingServerBakes(BOOL newval)
 {
-	LLXmlTreeNode* driver = root->getChildByName( "driver_parameters" );
-	if( driver )
-	{
-		for (LLXmlTreeNode* grand_child = driver->getChildByName( "param" );
-			 grand_child;
-			 grand_child = driver->getNextNamedChild())
-		{
-			if( grand_child->getChildByName( "param_driver" ) )
-			{
-				LLDriverParamInfo* driver_info = new LLDriverParamInfo();
-				if( driver_info->parseXml( grand_child ) )
-				{
-					mDriverInfoList.push_back(driver_info);
-				}
-				else
-				{
-					delete driver_info;
-					llwarns << "avatar file: driver_param->parseXml() failed" << llendl;
-					return FALSE;
-				}
-			}
-		}
-	}
-	return TRUE;
+	mUseServerBakes = newval;
+	LLVisualParam* appearance_version_param = getVisualParam(11000);
+	llassert(appearance_version_param);
+	appearance_version_param->setWeight(newval ? 1.0 : 0.0, false);
 }
 
-//-----------------------------------------------------------------------------
-// parseXmlDriverNodes(): parses <driver_parameters> nodes from XML tree
-//-----------------------------------------------------------------------------
-BOOL LLVOAvatar::LLVOAvatarXmlInfo::parseXmlMorphNodes(LLXmlTreeNode* root)
-{
-	LLXmlTreeNode* masks = root->getChildByName( "morph_masks" );
-	if( !masks )
-	{
-		return FALSE;
-	}
-
-	for (LLXmlTreeNode* grand_child = masks->getChildByName( "mask" );
-		 grand_child;
-		 grand_child = masks->getNextNamedChild())
-	{
-		LLVOAvatarMorphInfo* info = new LLVOAvatarMorphInfo();
-
-		static LLStdStringHandle name_string = LLXmlTree::addAttributeString("morph_name");
-		if (!grand_child->getFastAttributeString(name_string, info->mName))
-		{
-			llwarns << "No name supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle region_string = LLXmlTree::addAttributeString("body_region");
-		if (!grand_child->getFastAttributeString(region_string, info->mRegion))
-		{
-			llwarns << "No region supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		static LLStdStringHandle layer_string = LLXmlTree::addAttributeString("layer");
-		if (!grand_child->getFastAttributeString(layer_string, info->mLayer))
-		{
-			llwarns << "No layer supplied for morph mask." << llendl;
-			delete info;
-			continue;
-		}
-
-		// optional parameter. don't throw a warning if not present.
-		static LLStdStringHandle invert_string = LLXmlTree::addAttributeString("invert");
-		grand_child->getFastAttributeBOOL(invert_string, info->mInvert);
-
-		mMorphMaskInfoList.push_back(info);
-	}
-
-	return TRUE;
+// virtual
+void LLVOAvatar::removeMissingBakedTextures()
+{	
 }
 
 //virtual
@@ -8521,7 +7792,7 @@ void LLVOAvatar::idleUpdateRenderCost()
 
 	for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)baked_index);
 		ETextureIndex tex_index = baked_dict->mTextureIndex;
 		if ((tex_index != TEX_SKIRT_BAKED) || (isWearingWearableType(LLWearableType::WT_SKIRT)))
 		{
@@ -8601,11 +7872,11 @@ void LLVOAvatar::idleUpdateRenderCost()
 		}
 
 		// print any avatar textures we didn't already know about
-		for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-			 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+		for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+			 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 			 ++iter)
 		{
-			const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+			const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 			// TODO: MULTI-WEARABLE: handle multiple textures for self
 			const LLViewerTexture* te_image = getImage(iter->first,0);
 			if (!te_image)
@@ -8634,26 +7905,26 @@ void LLVOAvatar::idleUpdateRenderCost()
 BOOL LLVOAvatar::isIndexLocalTexture(ETextureIndex index)
 {
 	if (index < 0 || index >= TEX_NUM_INDICES) return false;
-	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
+	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsLocalTexture;
 }
 
 // static
 BOOL LLVOAvatar::isIndexBakedTexture(ETextureIndex index)
 {
 	if (index < 0 || index >= TEX_NUM_INDICES) return false;
-	return LLVOAvatarDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
+	return LLAvatarAppearanceDictionary::getInstance()->getTexture(index)->mIsBakedTexture;
 }
 
 const std::string LLVOAvatar::getBakedStatusForPrintout() const
 {
 	std::string line;
 
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (texture_dict->mIsBakedTexture)
 		{
 			line += texture_dict->mName;
@@ -8685,7 +7956,7 @@ F32 calc_bouncy_animation(F32 x)
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index ) const
+BOOL LLVOAvatar::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex te, U32 index ) const
 {
 	if (isIndexLocalTexture(te)) 
 	{
@@ -8703,7 +7974,7 @@ BOOL LLVOAvatar::isTextureDefined(LLVOAvatarDefines::ETextureIndex te, U32 index
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (isIndexLocalTexture(type))
 	{
@@ -8719,9 +7990,11 @@ BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 ind
 }
 
 //virtual
-BOOL LLVOAvatar::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
 {
 	// non-self avatars don't have wearables
 	return FALSE;
 }
 
+
+
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
old mode 100644
new mode 100755
index 1adb6809625ef16385e38874a1b142d661559eab..85f6f25009644fd924decf48af9f1fcdc279dcfe
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -25,8 +25,8 @@
  * $/LicenseInfo$
  */
 
-#ifndef LL_LLVOAVATAR_H
-#define LL_LLVOAVATAR_H
+#ifndef LL_VOAVATAR_H
+#define LL_VOAVATAR_H
 
 #include <map>
 #include <deque>
@@ -36,6 +36,7 @@
 #include <boost/signals2.hpp>
 
 #include "imageids.h"			// IMG_INVISIBLE
+#include "llavatarappearance.h"
 #include "llchat.h"
 #include "lldrawpoolalpha.h"
 #include "llviewerobject.h"
@@ -44,9 +45,10 @@
 #include "llviewerjointmesh.h"
 #include "llviewerjointattachment.h"
 #include "llrendertarget.h"
-#include "llvoavatardefines.h"
+#include "llavatarappearancedefines.h"
 #include "lltexglobalcolor.h"
 #include "lldriverparam.h"
+#include "llviewertexlayer.h"
 #include "material_codes.h"		// LL_MCODE_END
 #include "llviewerstats.h"
 
@@ -62,30 +64,30 @@ extern const LLUUID ANIM_AGENT_PELVIS_FIX;
 extern const LLUUID ANIM_AGENT_TARGET;
 extern const LLUUID ANIM_AGENT_WALK_ADJUST;
 
-class LLTexLayerSet;
+class LLViewerWearable;
 class LLVoiceVisualizer;
 class LLHUDNameTag;
 class LLHUDEffectSpiral;
 class LLTexGlobalColor;
-class LLVOAvatarBoneInfo;
-class LLVOAvatarSkeletonInfo;
+struct LLVOAvatarBoneInfo;
+struct LLVOAvatarChildJoint;
+//class LLViewerJoint;
+struct LLAppearanceMessageContents;
+struct LLVOAvatarSkeletonInfo;
 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLVOAvatar
 // 
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLVOAvatar :
+	public LLAvatarAppearance,
 	public LLViewerObject,
-	public LLCharacter,
 	public boost::signals2::trackable
 {
 	LOG_CLASS(LLVOAvatar);
 
 public:
 	friend class LLVOAvatarSelf;
-protected:
-	struct LLVOAvatarXmlInfo;
-	struct LLMaskedMorph;
 
 /********************************************************************************
  **                                                                            **
@@ -110,9 +112,6 @@ class LLVOAvatar :
 	virtual void 		initInstance(); // Called after construction to initialize the class.
 protected:
 	virtual				~LLVOAvatar();
-	BOOL				loadSkeletonNode();
-	BOOL				loadMeshNodes();
-	virtual BOOL		loadLayersets();
 
 /**                    Initialization
  **                                                                            **
@@ -127,31 +126,43 @@ class LLVOAvatar :
 	// LLViewerObject interface and related
 	//--------------------------------------------------------------------
 public:
-	virtual void			updateGL();
-	virtual	LLVOAvatar*		asAvatar();
-	virtual U32    	 	 	processUpdateMessage(LLMessageSystem *mesgsys,
+	/*virtual*/ void			updateGL();
+	/*virtual*/ LLVOAvatar*		asAvatar();
+	virtual U32    	 	 		processUpdateMessage(LLMessageSystem *mesgsys,
 													 void **user_data,
 													 U32 block_num,
 													 const EObjectUpdateType update_type,
 													 LLDataPacker *dp);
-	virtual void   	 	 	idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
-	virtual BOOL   	 	 	updateLOD();
-	BOOL  	 	 	 	 	updateJointLODs();
-	void					updateLODRiggedAttachments( void );
-	virtual BOOL   	 	 	isActive() const; // Whether this object needs to do an idleUpdate.
-	virtual void   	 	 	updateTextures();
-	virtual S32    	 	 	setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
-	virtual void   	 	 	onShift(const LLVector4a& shift_vector);
-	virtual U32    	 	 	getPartitionType() const;
-	virtual const  	 	 	LLVector3 getRenderPosition() const;
-	virtual void   	 	 	updateDrawable(BOOL force_damped);
-	virtual LLDrawable* 	createDrawable(LLPipeline *pipeline);
-	virtual BOOL   	 	 	updateGeometry(LLDrawable *drawable);
-	virtual void   	 	 	setPixelAreaAndAngle(LLAgent &agent);
-	virtual void   	 	 	updateRegion(LLViewerRegion *regionp);
-	virtual void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
-	virtual void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
-	virtual BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
+	virtual void   	 	 		idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time);
+	/*virtual*/ BOOL   	 	 	updateLOD();
+	BOOL  	 	 	 	 		updateJointLODs();
+	void						updateLODRiggedAttachments( void );
+	/*virtual*/ BOOL   	 	 	isActive() const; // Whether this object needs to do an idleUpdate.
+	S32 						totalTextureMemForUUIDS(std::set<LLUUID>& ids);
+	bool 						allTexturesCompletelyDownloaded(std::set<LLUUID>& ids) const;
+	bool 						allLocalTexturesCompletelyDownloaded() const;
+	bool 						allBakedTexturesCompletelyDownloaded() const;
+	void 						bakedTextureOriginCounts(S32 &sb_count, S32 &host_count,
+														 S32 &both_count, S32 &neither_count);
+	std::string 				bakedTextureOriginInfo();
+	void 						collectLocalTextureUUIDs(std::set<LLUUID>& ids) const;
+	void 						collectBakedTextureUUIDs(std::set<LLUUID>& ids) const;
+	void 						collectTextureUUIDs(std::set<LLUUID>& ids);
+	void						releaseOldTextures();
+	/*virtual*/ void   	 	 	updateTextures();
+	LLViewerFetchedTexture*		getBakedTextureImage(const U8 te, const LLUUID& uuid);
+	/*virtual*/ S32    	 	 	setTETexture(const U8 te, const LLUUID& uuid); // If setting a baked texture, need to request it from a non-local sim.
+	/*virtual*/ void   	 	 	onShift(const LLVector4a& shift_vector);
+	/*virtual*/ U32    	 	 	getPartitionType() const;
+	/*virtual*/ const  	 	 	LLVector3 getRenderPosition() const;
+	/*virtual*/ void   	 	 	updateDrawable(BOOL force_damped);
+	/*virtual*/ LLDrawable* 	createDrawable(LLPipeline *pipeline);
+	/*virtual*/ BOOL   	 	 	updateGeometry(LLDrawable *drawable);
+	/*virtual*/ void   	 	 	setPixelAreaAndAngle(LLAgent &agent);
+	/*virtual*/ void   	 	 	updateRegion(LLViewerRegion *regionp);
+	/*virtual*/ void   	 	 	updateSpatialExtents(LLVector4a& newMin, LLVector4a &newMax);
+	/*virtual*/ void   	 	 	getSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
+	/*virtual*/ BOOL   	 	 	lineSegmentIntersect(const LLVector3& start, const LLVector3& end,
 												 S32 face = -1,                    // which face to check, -1 = ALL_SIDES
 												 BOOL pick_transparent = FALSE,
 												 S32* face_hit = NULL,             // which face was hit
@@ -172,16 +183,14 @@ class LLVOAvatar :
 	// LLCharacter interface and related
 	//--------------------------------------------------------------------
 public:
-	virtual LLVector3    	getCharacterPosition();
-	virtual LLQuaternion 	getCharacterRotation();
-	virtual LLVector3    	getCharacterVelocity();
-	virtual LLVector3    	getCharacterAngularVelocity();
-	virtual LLJoint*		getCharacterJoint(U32 num);
-	virtual BOOL			allocateCharacterJoints(U32 num);
-
-	virtual LLUUID			remapMotionID(const LLUUID& id);
-	virtual BOOL			startMotion(const LLUUID& id, F32 time_offset = 0.f);
-	virtual BOOL			stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
+	/*virtual*/ LLVector3    	getCharacterPosition();
+	/*virtual*/ LLQuaternion 	getCharacterRotation();
+	/*virtual*/ LLVector3    	getCharacterVelocity();
+	/*virtual*/ LLVector3    	getCharacterAngularVelocity();
+
+	/*virtual*/ LLUUID			remapMotionID(const LLUUID& id);
+	/*virtual*/ BOOL			startMotion(const LLUUID& id, F32 time_offset = 0.f);
+	/*virtual*/ BOOL			stopMotion(const LLUUID& id, BOOL stop_immediate = FALSE);
 	virtual void			stopMotionFromSource(const LLUUID& source_id);
 	virtual void			requestStopMotion(LLMotion* motion);
 	LLMotion*				findMotion(const LLUUID& id) const;
@@ -189,25 +198,18 @@ class LLVOAvatar :
 	void					dumpAnimationState();
 
 	virtual LLJoint*		getJoint(const std::string &name);
-	virtual LLJoint*     	getRootJoint() { return &mRoot; }
 	
 	void					resetJointPositions( void );
 	void					resetJointPositionsToDefault( void );
 	void					resetSpecificJointPosition( const std::string& name );
 	
-	virtual const char*		getAnimationPrefix() { return "avatar"; }
-	virtual const LLUUID&   getID() const;
-	virtual LLVector3		getVolumePos(S32 joint_index, LLVector3& volume_offset);
-	virtual LLJoint*		findCollisionVolume(U32 volume_id);
-	virtual S32				getCollisionVolumeID(std::string &name);
-	virtual void			addDebugText(const std::string& text);
-	virtual F32          	getTimeDilation();
-	virtual void			getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
-	virtual F32				getPixelArea() const;
-	virtual LLPolyMesh*		getHeadMesh();
-	virtual LLPolyMesh*		getUpperBodyMesh();
-	virtual LLVector3d		getPosGlobalFromAgent(const LLVector3 &position);
-	virtual LLVector3		getPosAgentFromGlobal(const LLVector3d &position);
+	/*virtual*/ const LLUUID&	getID() const;
+	/*virtual*/ void			addDebugText(const std::string& text);
+	/*virtual*/ F32				getTimeDilation();
+	/*virtual*/ void			getGround(const LLVector3 &inPos, LLVector3 &outPos, LLVector3 &outNorm);
+	/*virtual*/ F32				getPixelArea() const;
+	/*virtual*/ LLVector3d		getPosGlobalFromAgent(const LLVector3 &position);
+	/*virtual*/ LLVector3		getPosAgentFromGlobal(const LLVector3d &position);
 	virtual void			updateVisualParams();
 
 
@@ -222,14 +224,10 @@ class LLVOAvatar :
 
 public:
 	virtual bool 	isSelf() const { return false; } // True if this avatar is for this viewer's agent
-	bool isBuilt() const { return mIsBuilt; }
 
 private: //aligned members
 	LL_ALIGN_16(LLVector4a	mImpostorExtents[2]);
 
-private:
-	BOOL			mSupportsAlphaLayers; // For backwards compatibility, TRUE for 1.23+ clients
-
 	//--------------------------------------------------------------------
 	// Updates
 	//--------------------------------------------------------------------
@@ -243,7 +241,7 @@ class LLVOAvatar :
 	void 			idleUpdateWindEffect();
 	void 			idleUpdateNameTag(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagText(BOOL new_name);
-	LLVector3		idleUpdateNameTagPosition(const LLVector3& root_pos_last);
+	void			idleUpdateNameTagPosition(const LLVector3& root_pos_last);
 	void			idleUpdateNameTagAlpha(BOOL new_name, F32 alpha);
 	LLColor4		getNameTagColor(bool is_friend);
 	void			clearNameTag();
@@ -292,17 +290,21 @@ class LLVOAvatar :
 	virtual BOOL	getIsCloud() const;
 	BOOL			isFullyTextured() const;
 	BOOL			hasGray() const; 
-	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = fully textured.
+	S32				getRezzedStatus() const; // 0 = cloud, 1 = gray, 2 = textured, 3 = textured and fully downloaded.
 	void			updateRezzedStatusTimers();
 
 	S32				mLastRezzedStatus;
 
-	LLViewerStats::PhaseMap& getPhases()
-	{
-		return mPhases;
-	}
+	
+	void 			startPhase(const std::string& phase_name);
+	void 			stopPhase(const std::string& phase_name, bool err_check = true);
+	void			clearPhases();
+	void 			logPendingPhases();
+	static void 	logPendingPhasesAllAvatars();
+	void 			logMetricsTimerRecord(const std::string& phase_name, F32 elapsed, bool completed);
 
 protected:
+	LLViewerStats::PhaseMap& getPhases() { return mPhases; }
 	BOOL			updateIsFullyLoaded();
 	BOOL			processFullyLoadedChange(bool loading);
 	void			updateRuthTimer(bool loading);
@@ -317,24 +319,6 @@ class LLVOAvatar :
 	LLFrameTimer	mFullyLoadedTimer;
 	LLFrameTimer	mRuthTimer;
 
-public:
-	class ScopedPhaseSetter
-	{
-	public:
-		ScopedPhaseSetter(LLVOAvatar *avatarp, std::string phase_name):
-			mAvatar(avatarp), mPhaseName(phase_name)
-		{
-			if (mAvatar) { mAvatar->getPhases().startPhase(mPhaseName); }
-		}
-		~ScopedPhaseSetter()
-		{
-			if (mAvatar) { mAvatar->getPhases().stopPhase(mPhaseName); }
-		}
-	private:
-		std::string mPhaseName;
-		LLVOAvatar* mAvatar;
-	};
-
 private:
 	LLViewerStats::PhaseMap mPhases;
 
@@ -344,82 +328,35 @@ class LLVOAvatar :
 /**                    State
  **                                                                            **
  *******************************************************************************/
-
 /********************************************************************************
  **                                                                            **
  **                    SKELETON
  **/
 
+protected:
+	/*virtual*/ LLAvatarJoint*	createAvatarJoint(); // Returns LLViewerJoint
+	/*virtual*/ LLAvatarJoint*	createAvatarJoint(S32 joint_num); // Returns LLViewerJoint
+	/*virtual*/ LLAvatarJointMesh*	createAvatarJointMesh(); // Returns LLViewerJointMesh
 public:
 	void				updateHeadOffset();
-	F32					getPelvisToFoot() const { return mPelvisToFoot; }
 	void				setPelvisOffset( bool hasOffset, const LLVector3& translation, F32 offset ) ;
 	bool				hasPelvisOffset( void ) { return mHasPelvisOffset; }
 	void				postPelvisSetRecalc( void );
 	void				setPelvisOffset( F32 pelvixFixupAmount );
 
+	/*virtual*/ BOOL	loadSkeletonNode();
+	/*virtual*/ void	buildCharacter();
+
 	bool				mHasPelvisOffset;
 	LLVector3			mPelvisOffset;
 	F32					mLastPelvisToFoot;
 	F32					mPelvisFixup;
 	F32					mLastPelvisFixup;
+	LLVector3			mCurRootToHeadOffset;
+	LLVector3			mTargetRootToHeadOffset;
 
-	LLVector3			mHeadOffset; // current head position
-	LLViewerJoint		mRoot;
-
-	typedef std::map<std::string, LLJoint*> joint_map_t;
-	joint_map_t			mJointMap;
-
-protected:
-	static BOOL			parseSkeletonFile(const std::string& filename);
-	void				buildCharacter();
-	virtual BOOL		loadAvatar();
-
-	BOOL				setupBone(const LLVOAvatarBoneInfo* info, LLViewerJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
-	BOOL				buildSkeleton(const LLVOAvatarSkeletonInfo *info);
-private:
-	BOOL				mIsBuilt; // state of deferred character building
-	S32					mNumJoints;
-	LLViewerJoint*		mSkeleton;
-	
-	//--------------------------------------------------------------------
-	// Pelvis height adjustment members.
-	//--------------------------------------------------------------------
-public:
-	LLVector3			mBodySize;
 	S32					mLastSkeletonSerialNum;
-private:
-	F32					mPelvisToFoot;
 
-	//--------------------------------------------------------------------
-	// Cached pointers to well known joints
-	//--------------------------------------------------------------------
-public:
-	LLViewerJoint* 		mPelvisp;
-	LLViewerJoint* 		mTorsop;
-	LLViewerJoint* 		mChestp;
-	LLViewerJoint* 		mNeckp;
-	LLViewerJoint* 		mHeadp;
-	LLViewerJoint* 		mSkullp;
-	LLViewerJoint* 		mEyeLeftp;
-	LLViewerJoint* 		mEyeRightp;
-	LLViewerJoint* 		mHipLeftp;
-	LLViewerJoint* 		mHipRightp;
-	LLViewerJoint* 		mKneeLeftp;
-	LLViewerJoint* 		mKneeRightp;
-	LLViewerJoint* 		mAnkleLeftp;
-	LLViewerJoint* 		mAnkleRightp;
-	LLViewerJoint* 		mFootLeftp;
-	LLViewerJoint* 		mFootRightp;
-	LLViewerJoint* 		mWristLeftp;
-	LLViewerJoint* 		mWristRightp;
-
-	//--------------------------------------------------------------------
-	// XML parse tree
-	//--------------------------------------------------------------------
-private:
-	static LLXmlTree 	sXMLTree; // avatar config file
-	static LLXmlTree 	sSkeletonXMLTree; // avatar skeleton file
 
 /**                    Skeleton
  **                                                                            **
@@ -437,13 +374,11 @@ class LLVOAvatar :
 	U32 		renderRigid();
 	U32 		renderSkinned(EAvatarRenderPass pass);
 	F32			getLastSkinTime() { return mLastSkinTime; }
-	U32			renderSkinnedAttachments();
 	U32 		renderTransparent(BOOL first_pass);
 	void 		renderCollisionVolumes();
 	static void	deleteCachedImages(bool clearAll=true);
 	static void	destroyGL();
 	static void	restoreGL();
-	BOOL 		mIsDummy; // for special views
 	S32			mSpecialRenderMode; // special lighting
 	U32			mAttachmentGeometryBytes; //number of bytes in attached geometry
 	F32			mAttachmentSurfaceArea; //estimated surface area of attachments
@@ -461,9 +396,15 @@ class LLVOAvatar :
 	// Morph masks
 	//--------------------------------------------------------------------
 public:
-	BOOL 		morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
-	void 		addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
-	void 		applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
+	/*virtual*/ void	applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+	BOOL 		morphMaskNeedsUpdate(LLAvatarAppearanceDefines::EBakedTextureIndex index = LLAvatarAppearanceDefines::BAKED_NUM_INDICES);
+
+	
+	//--------------------------------------------------------------------
+	// Global colors
+	//--------------------------------------------------------------------
+public:
+	/*virtual*/void onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -546,10 +487,10 @@ class LLVOAvatar :
 	// Constants
 	//--------------------------------------------------------------------
 public:
-	virtual LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR; }
-	virtual LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED; }
+	virtual LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR; }
+	virtual LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED; }
 	virtual S32 						getTexImageSize() const;
-	virtual S32 						getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
+	/*virtual*/ S32						getTexImageArea() const { return getTexImageSize()*getTexImageSize(); }
 
 /**                    Rendering
  **                                                                            **
@@ -564,9 +505,9 @@ class LLVOAvatar :
 	// Loading status
 	//--------------------------------------------------------------------
 public:
-	virtual BOOL    isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	virtual BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+	virtual BOOL    isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	virtual BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	virtual BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
 
 	BOOL			isFullyBaked();
 	static BOOL		areAllNearbyInstancesBaked(S32& grey_avatars);
@@ -577,6 +518,7 @@ class LLVOAvatar :
 	// Baked textures
 	//--------------------------------------------------------------------
 public:
+	/*virtual*/ LLTexLayerSet*	createTexLayerSet(); // Return LLViewerTexLayerSet
 	void			releaseComponentTextures(); // ! BACKWARDS COMPATIBILITY !
 protected:
 	static void		onBakedTextureMasksLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -584,32 +526,20 @@ class LLVOAvatar :
 	static void		onBakedTextureLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 	virtual void	removeMissingBakedTextures();
 	void			useBakedTexture(const LLUUID& id);
+	LLViewerTexLayerSet*  getTexLayerSet(const U32 index) const { return dynamic_cast<LLViewerTexLayerSet*>(mBakedTextureDatas[index].mTexLayerSet);	}
+
 
-	typedef std::deque<LLMaskedMorph *> 	morph_list_t;
-	struct BakedTextureData
-	{
-		LLUUID								mLastTextureIndex;
-		LLTexLayerSet* 						mTexLayerSet; // Only exists for self
-		bool								mIsLoaded;
-		bool								mIsUsed;
-		LLVOAvatarDefines::ETextureIndex 	mTextureIndex;
-		U32									mMaskTexName;
-		// Stores pointers to the joint meshes that this baked texture deals with
-		std::vector< LLViewerJointMesh * > 	mMeshes;  // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
-		morph_list_t						mMaskedMorphs;
-	};
-	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;
-	bakedtexturedata_vec_t 					mBakedTextureDatas;
 	LLLoadedCallbackEntry::source_callback_list_t mCallbackTextureList ; 
 	BOOL mLoadedCallbacksPaused;
+	std::set<LLUUID>	mTextureIDs;
 	//--------------------------------------------------------------------
 	// Local Textures
 	//--------------------------------------------------------------------
 protected:
-	virtual void	setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
-	virtual void	addLocalTextureStats(LLVOAvatarDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index = 0);
+	virtual void	setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index = 0);
+	virtual void	addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
 	// MULTI-WEARABLE: make self-only?
-	virtual void	setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
+	virtual void	setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index = 0);
 
 	//--------------------------------------------------------------------
 	// Texture accessors
@@ -617,6 +547,7 @@ class LLVOAvatar :
 private:
 	virtual	void				setImage(const U8 te, LLViewerTexture *imagep, const U32 index); 
 	virtual LLViewerTexture*	getImage(const U8 te, const U32 index) const;
+	const std::string 			getImageURL(const U8 te, const LLUUID &uuid);
 
 	virtual const LLTextureEntry* getTexEntry(const U8 te_num) const;
 	virtual void setTexEntry(const U8 index, const LLTextureEntry &te);
@@ -643,13 +574,11 @@ class LLVOAvatar :
 	// Static texture/mesh/baked dictionary
 	//--------------------------------------------------------------------
 public:
-	static BOOL 	isIndexLocalTexture(LLVOAvatarDefines::ETextureIndex i);
-	static BOOL 	isIndexBakedTexture(LLVOAvatarDefines::ETextureIndex i);
+	static BOOL 	isIndexLocalTexture(LLAvatarAppearanceDefines::ETextureIndex i);
+	static BOOL 	isIndexBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i);
 private:
-	static const LLVOAvatarDefines::LLVOAvatarDictionary *getDictionary() { return sAvatarDictionary; }
-	static LLVOAvatarDefines::LLVOAvatarDictionary* sAvatarDictionary;
-	static LLVOAvatarSkeletonInfo* 					sAvatarSkeletonInfo;
-	static LLVOAvatarXmlInfo* 						sAvatarXmlInfo;
+	static const LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary *getDictionary() { return sAvatarDictionary; }
+	static LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary* sAvatarDictionary;
 
 	//--------------------------------------------------------------------
 	// Messaging
@@ -670,22 +599,20 @@ class LLVOAvatar :
  **/
 
 public:
-	void 			updateMeshTextures();
+	void			debugColorizeSubMeshes(U32 i, const LLColor4& color);
+	virtual void 	updateMeshTextures();
 	void 			updateSexDependentLayerSets(BOOL upload_bake);
-	void 			dirtyMesh(); // Dirty the avatar mesh
+	virtual void	dirtyMesh(); // Dirty the avatar mesh
 	void 			updateMeshData();
 protected:
 	void 			releaseMeshData();
 	virtual void restoreMeshData();
 private:
-	void 			dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+	virtual void	dirtyMesh(S32 priority); // Dirty the avatar mesh, with priority
+	LLViewerJoint*	getViewerJoint(S32 idx);
 	S32 			mDirtyMesh; // 0 -- not dirty, 1 -- morphed, 2 -- LOD
 	BOOL			mMeshTexturesDirty;
 
-	typedef std::multimap<std::string, LLPolyMesh*> polymesh_map_t;
-	polymesh_map_t 									mMeshes;
-	std::vector<LLViewerJoint *> 					mMeshLOD;
-
 	//--------------------------------------------------------------------
 	// Destroy invisible mesh
 	//--------------------------------------------------------------------
@@ -703,38 +630,42 @@ class LLVOAvatar :
  **/
 
 public:
+	void 			parseAppearanceMessage(LLMessageSystem* mesgsys, LLAppearanceMessageContents& msg);
 	void 			processAvatarAppearance(LLMessageSystem* mesgsys);
 	void 			hideSkirt();
 	void			startAppearanceAnimation();
+	/*virtual*/ void bodySizeChanged();
 	
 	//--------------------------------------------------------------------
 	// Appearance morphing
 	//--------------------------------------------------------------------
 public:
 	BOOL			getIsAppearanceAnimating() const { return mAppearanceAnimating; }
+
+	// True if we are computing our appearance via local compositing
+	// instead of baked textures, as for example during wearable
+	// editing or when waiting for a subsequent server rebake.
+	/*virtual*/ BOOL	isUsingLocalAppearance() const { return mUseLocalAppearance; }
+
+	// True if this avatar should fetch its baked textures via the new
+	// appearance mechanism.
+	BOOL				isUsingServerBakes() const;
+	void 				setIsUsingServerBakes(BOOL newval);
+
+
+	// True if we are currently in appearance editing mode. Often but
+	// not always the same as isUsingLocalAppearance().
+	/*virtual*/ BOOL	isEditingAppearance() const { return mIsEditingAppearance; }
+
+	// FIXME review isUsingLocalAppearance uses, some should be isEditing instead.
+
 private:
 	BOOL			mAppearanceAnimating;
 	LLFrameTimer	mAppearanceMorphTimer;
 	F32				mLastAppearanceBlendTime;
-
-	//--------------------------------------------------------------------
-	// Clothing colors (convenience functions to access visual parameters)
-	//--------------------------------------------------------------------
-public:
-	void			setClothesColor(LLVOAvatarDefines::ETextureIndex te, const LLColor4& new_color, BOOL upload_bake);
-	LLColor4		getClothesColor(LLVOAvatarDefines::ETextureIndex te);
-	static BOOL			teToColorParams(LLVOAvatarDefines::ETextureIndex te, U32 *param_name);
-
-	//--------------------------------------------------------------------
-	// Global colors
-	//--------------------------------------------------------------------
-public:
-	LLColor4		getGlobalColor(const std::string& color_name ) const;
-	void			onGlobalColorChanged(const LLTexGlobalColor* global_color, BOOL upload_bake);
-private:
-	LLTexGlobalColor* mTexSkinColor;
-	LLTexGlobalColor* mTexHairColor;
-	LLTexGlobalColor* mTexEyeColor;
+	BOOL			mIsEditingAppearance; // flag for if we're actively in appearance editing mode
+	BOOL			mUseLocalAppearance; // flag for if we're using a local composite
+	BOOL			mUseServerBakes; // flag for if baked textures should be fetched from baking service (false if they're temporary uploads)
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -744,7 +675,6 @@ class LLVOAvatar :
 	void			setVisibilityRank(U32 rank);
 	U32				getVisibilityRank()  const { return mVisibilityRank; } // unused
 	static S32 		sNumVisibleAvatars; // Number of instances of this class
-	static LLColor4 getDummyColor();
 /**                    Appearance
  **                                                                            **
  *******************************************************************************/
@@ -754,9 +684,6 @@ class LLVOAvatar :
  **                    WEARABLES
  **/
 
-public:
-	virtual BOOL			isWearingWearableType(LLWearableType::EType type ) const;
-	
 	//--------------------------------------------------------------------
 	// Attachments
 	//--------------------------------------------------------------------
@@ -766,6 +693,7 @@ class LLVOAvatar :
 	virtual BOOL 		detachObject(LLViewerObject *viewer_object);
 	void				cleanupAttachedMesh( LLViewerObject* pVO );
 	static LLVOAvatar*  findAvatarFromAttachment(LLViewerObject* obj);
+	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type ) const;
 protected:
 	LLViewerJointAttachment* getTargetAttachmentPoint(LLViewerObject* viewer_object);
 	void 				lazyAttach();
@@ -786,7 +714,6 @@ class LLVOAvatar :
 public:
 	BOOL 				hasHUDAttachment() const;
 	LLBBox 				getHUDBBox() const;
-	void 				rebuildHUD();
 	void 				resetHUDAttachments();
 	BOOL				canAttachMoreObjects() const;
 	BOOL				canAttachMoreObjects(U32 n) const;
@@ -867,15 +794,6 @@ class LLVOAvatar :
 	BOOL 		mTurning; // controls hysteresis on avatar rotation
 	F32			mSpeed; // misc. animation repeated state
 
-	//--------------------------------------------------------------------
-	// Collision volumes
-	//--------------------------------------------------------------------
-public:
-  	S32			mNumCollisionVolumes;
-	LLViewerJointCollisionVolume* mCollisionVolumes;
-protected:
-	BOOL		allocateCollisionVolumes(U32 num);
-
 	//--------------------------------------------------------------------
 	// Dimensions
 	//--------------------------------------------------------------------
@@ -886,7 +804,6 @@ class LLVOAvatar :
 	void 		resolveRayCollisionAgent(const LLVector3d start_pt, const LLVector3d end_pt, LLVector3d &out_pos, LLVector3 &out_norm);
 	void 		slamPosition(); // Slam position to transmitted position (for teleport);
 protected:
-	void 		computeBodySize();
 
 	//--------------------------------------------------------------------
 	// Material being stepped on
@@ -906,9 +823,9 @@ class LLVOAvatar :
  **/
 
 public:
-	virtual BOOL 	setParent(LLViewerObject* parent);
-	virtual void 	addChild(LLViewerObject *childp);
-	virtual void 	removeChild(LLViewerObject *childp);
+	/*virtual*/ BOOL 	setParent(LLViewerObject* parent);
+	/*virtual*/ void 	addChild(LLViewerObject *childp);
+	/*virtual*/ void 	removeChild(LLViewerObject *childp);
 
 	//--------------------------------------------------------------------
 	// Sitting
@@ -938,10 +855,10 @@ class LLVOAvatar :
 	static void		getAnimLabels(LLDynamicArray<std::string>* labels);
 	static void		getAnimNames(LLDynamicArray<std::string>* names);	
 private:
-	std::string		mNameString;		// UTF-8 title + name + status
+    bool            mNameIsSet;
 	std::string  	mTitle;
 	bool	  		mNameAway;
-	bool	  		mNameBusy;
+	bool	  		mNameDoNotDisturb;
 	bool	  		mNameMute;
 	bool      		mNameAppearance;
 	bool			mNameFriend;
@@ -1012,7 +929,9 @@ class LLVOAvatar :
 	// General
 	//--------------------------------------------------------------------
 public:
-	static void			dumpArchetypeXML(void*);
+	void				dumpArchetypeXML(const std::string& prefix, bool group_by_wearables = false);
+	void 				dumpAppearanceMsgParams( const std::string& dump_prefix,
+												 const LLAppearanceMessageContents& contents);
 	static void			dumpBakedStatus();
 	const std::string 	getBakedStatusForPrintout() const;
 	void				dumpAvatarTEs(const std::string& context) const;
@@ -1029,6 +948,7 @@ class LLVOAvatar :
 	F32					mMaxPixelArea;
 	F32					mAdjustedPixelArea;
 	std::string  		mDebugText;
+	std::string			mBakedTextureDebugText;
 
 
 	//--------------------------------------------------------------------
@@ -1042,6 +962,17 @@ class LLVOAvatar :
 	LLFrameTimer	mRuthDebugTimer; // For tracking how long it takes for av to rez
 	LLFrameTimer	mDebugExistenceTimer; // Debugging for how long the avatar has been in memory.
 
+	//--------------------------------------------------------------------
+	// COF monitoring
+	//--------------------------------------------------------------------
+
+public:
+	// COF version of last viewer-initiated appearance update request. For non-self avs, this will remain at default.
+	S32 mLastUpdateRequestCOFVersion;
+
+	// COF version of last appearance message received for this av.
+	S32 mLastUpdateReceivedCOFVersion;
+
 /**                    Diagnostics
  **                                                                            **
  *******************************************************************************/
@@ -1053,105 +984,6 @@ class LLVOAvatar :
 
 protected: // Shared with LLVOAvatarSelf
 
-	struct LLVOAvatarXmlInfo
-	{
-		LLVOAvatarXmlInfo();
-		~LLVOAvatarXmlInfo();
-
-		BOOL 	parseXmlSkeletonNode(LLXmlTreeNode* root);
-		BOOL 	parseXmlMeshNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlColorNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlLayerNodes(LLXmlTreeNode* root);
-		BOOL 	parseXmlDriverNodes(LLXmlTreeNode* root);
-		BOOL	parseXmlMorphNodes(LLXmlTreeNode* root);
-
-		struct LLVOAvatarMeshInfo
-		{
-			typedef std::pair<LLPolyMorphTargetInfo*,BOOL> morph_info_pair_t;
-			typedef std::vector<morph_info_pair_t> morph_info_list_t;
-
-			LLVOAvatarMeshInfo() : mLOD(0), mMinPixelArea(.1f) {}
-			~LLVOAvatarMeshInfo()
-			{
-				morph_info_list_t::iterator iter;
-				for (iter = mPolyMorphTargetInfoList.begin(); iter != mPolyMorphTargetInfoList.end(); iter++)
-				{
-					delete iter->first;
-				}
-				mPolyMorphTargetInfoList.clear();
-			}
-
-			std::string mType;
-			S32			mLOD;
-			std::string	mMeshFileName;
-			std::string	mReferenceMeshName;
-			F32			mMinPixelArea;
-			morph_info_list_t mPolyMorphTargetInfoList;
-		};
-		typedef std::vector<LLVOAvatarMeshInfo*> mesh_info_list_t;
-		mesh_info_list_t mMeshInfoList;
-
-		typedef std::vector<LLPolySkeletalDistortionInfo*> skeletal_distortion_info_list_t;
-		skeletal_distortion_info_list_t mSkeletalDistortionInfoList;
-	
-		struct LLVOAvatarAttachmentInfo
-		{
-			LLVOAvatarAttachmentInfo()
-				: mGroup(-1), mAttachmentID(-1), mPieMenuSlice(-1), mVisibleFirstPerson(FALSE),
-				  mIsHUDAttachment(FALSE), mHasPosition(FALSE), mHasRotation(FALSE) {}
-			std::string mName;
-			std::string mJointName;
-			LLVector3 mPosition;
-			LLVector3 mRotationEuler;
-			S32 mGroup;
-			S32 mAttachmentID;
-			S32 mPieMenuSlice;
-			BOOL mVisibleFirstPerson;
-			BOOL mIsHUDAttachment;
-			BOOL mHasPosition;
-			BOOL mHasRotation;
-		};
-		typedef std::vector<LLVOAvatarAttachmentInfo*> attachment_info_list_t;
-		attachment_info_list_t mAttachmentInfoList;
-	
-		LLTexGlobalColorInfo *mTexSkinColorInfo;
-		LLTexGlobalColorInfo *mTexHairColorInfo;
-		LLTexGlobalColorInfo *mTexEyeColorInfo;
-
-		typedef std::vector<LLTexLayerSetInfo*> layer_info_list_t;
-		layer_info_list_t mLayerInfoList;
-
-		typedef std::vector<LLDriverParamInfo*> driver_info_list_t;
-		driver_info_list_t mDriverInfoList;
-
-		struct LLVOAvatarMorphInfo
-		{
-			LLVOAvatarMorphInfo()
-				: mInvert(FALSE) {}
-			std::string mName;
-			std::string mRegion;
-			std::string mLayer;
-			BOOL mInvert;
-		};
-
-		typedef std::vector<LLVOAvatarMorphInfo*> morph_info_list_t;
-		morph_info_list_t	mMorphMaskInfoList;
-	};
-
-	struct LLMaskedMorph
-	{
-		LLMaskedMorph(LLPolyMorphTarget *morph_target, BOOL invert, std::string layer) :
-			mMorphTarget(morph_target), 
-			mInvert(invert),
-			mLayer(layer)
-		{
-			morph_target->addPendingMorphMask();
-		}
-	
-		LLPolyMorphTarget	*mMorphTarget;
-		BOOL				mInvert;
-		std::string			mLayer;
-	};
 
 /**                    Support classes
  **                                                                            **
@@ -1161,4 +993,9 @@ class LLVOAvatar :
 extern const F32 SELF_ADDITIONAL_PRI;
 extern const S32 MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL;
 
-#endif // LL_VO_AVATAR_H
+std::string get_sequential_numbered_file_name(const std::string& prefix,
+											  const std::string& suffix);
+void dump_visual_param(apr_file_t* file, LLVisualParam* viewer_param, F32 value);
+
+#endif // LL_VOAVATAR_H
+
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
old mode 100644
new mode 100755
index e32fd3c3c896958b770534d9cb8821f8e3770e3c..d54eb5f0400c6f812f23cb1f484e1051de25cdc4
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -55,11 +55,14 @@
 #include "llviewerobjectlist.h"
 #include "llviewerstats.h"
 #include "llviewerregion.h"
+#include "llviewertexlayer.h"
+#include "llviewerwearable.h"
 #include "llappearancemgr.h"
 #include "llmeshrepository.h"
 #include "llvovolume.h"
 #include "llsdutil.h"
 #include "llstartup.h"
+#include "llsdserialize.h"
 
 #if LL_MSVC
 // disable boost::lexical_cast warning
@@ -72,24 +75,22 @@ LLPointer<LLVOAvatarSelf> gAgentAvatarp = NULL;
 
 BOOL isAgentAvatarValid()
 {
-	return (gAgentAvatarp.notNull() &&
-			(gAgentAvatarp->getRegion() != NULL) &&
-			(!gAgentAvatarp->isDead()));
+	return (gAgentAvatarp.notNull() && gAgentAvatarp->isValid());
 }
 
 void selfStartPhase(const std::string& phase_name)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().startPhase(phase_name);
+		gAgentAvatarp->startPhase(phase_name);
 	}
 }
 
-void selfStopPhase(const std::string& phase_name)
+void selfStopPhase(const std::string& phase_name, bool err_check)
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().stopPhase(phase_name);
+		gAgentAvatarp->stopPhase(phase_name, err_check);
 	}
 }
 
@@ -97,20 +98,11 @@ void selfClearPhases()
 {
 	if (isAgentAvatarValid())
 	{
-		gAgentAvatarp->getPhases().clearPhases();
-		gAgentAvatarp->mLastRezzedStatus = -1;
+		gAgentAvatarp->clearPhases();
 	}
 }
 
-void selfStopAllPhases()
-{
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->getPhases().stopAllPhases();
-	}
-}
-
-using namespace LLVOAvatarDefines;
+using namespace LLAvatarAppearanceDefines;
 
 /*********************************************************************************
  **                                                                             **
@@ -176,6 +168,35 @@ LLVOAvatarSelf::LLVOAvatarSelf(const LLUUID& id,
 	lldebugs << "Marking avatar as self " << id << llendl;
 }
 
+// Called periodically for diagnostics, return true when done.
+bool output_self_av_texture_diagnostics()
+{
+	if (!isAgentAvatarValid())
+		return true; // done checking
+
+	gAgentAvatarp->outputRezDiagnostics();
+
+	return false;
+}
+
+bool update_avatar_rez_metrics()
+{
+	if (!isAgentAvatarValid())
+		return true;
+	
+	gAgentAvatarp->updateAvatarRezMetrics(false);
+	return false;
+}
+
+bool check_for_unsupported_baked_appearance()
+{
+	if (!isAgentAvatarValid())
+		return true;
+
+	gAgentAvatarp->checkForUnsupportedServerBakeAppearance();
+	return false;
+}
+
 void LLVOAvatarSelf::initInstance()
 {
 	BOOL status = TRUE;
@@ -188,7 +209,7 @@ void LLVOAvatarSelf::initInstance()
 	llinfos << "Self avatar object created. Starting timer." << llendl;
 	mDebugSelfLoadTimer.reset();
 	// clear all times to -1 for debugging
-	for (U32 i =0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+	for (U32 i =0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
 	{
 		for (U32 j = 0; j <= MAX_DISCARD_LEVEL; ++j)
 		{
@@ -196,7 +217,7 @@ void LLVOAvatarSelf::initInstance()
 		}
 	}
 
-	for (U32 i =0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+	for (U32 i =0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
 	{
 		mDebugBakedTextureTimes[i][0] = -1.0f;
 		mDebugBakedTextureTimes[i][1] = -1.0f;
@@ -209,6 +230,10 @@ void LLVOAvatarSelf::initInstance()
 		llerrs << "Unable to load user's avatar" << llendl;
 		return;
 	}
+
+	//doPeriodically(output_self_av_texture_diagnostics, 30.0);
+	doPeriodically(update_avatar_rez_metrics, 5.0);
+	doPeriodically(check_for_unsupported_baked_appearance, 120.0);
 }
 
 // virtual
@@ -249,13 +274,11 @@ BOOL LLVOAvatarSelf::loadAvatarSelf()
 		llwarns << "avatar file: buildSkeleton() failed" << llendl;
 		return FALSE;
 	}
-	// TODO: make loadLayersets() called only by self.
-	//success &= loadLayersets();
 
 	return success;
 }
 
-BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info)
+BOOL LLVOAvatarSelf::buildSkeletonSelf(const LLAvatarSkeletonInfo *info)
 {
 	// add special-purpose "screen" joint
 	mScreenp = new LLViewerJoint("mScreen", NULL);
@@ -341,7 +364,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 		}
 		else
 		{
-			BOOL attachment_found = FALSE;
 			for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
 				 iter != mAttachmentPoints.end();
 				 ++iter)
@@ -369,7 +391,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 
 					gAttachPieMenu->addChild(item);
 
-					attachment_found = TRUE;
 					break;
 
 				}
@@ -382,7 +403,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 		}
 		else
 		{
-			BOOL attachment_found = FALSE;
 			for (attachment_map_t::iterator iter = mAttachmentPoints.begin(); 
 				 iter != mAttachmentPoints.end();
 				 ++iter)
@@ -409,7 +429,6 @@ BOOL LLVOAvatarSelf::buildMenus()
 
 					gDetachPieMenu->addChild(item);
 						
-					attachment_found = TRUE;
 					break;
 				}
 			}
@@ -583,70 +602,6 @@ LLVOAvatarSelf::~LLVOAvatarSelf()
  **                                                                             **
  *********************************************************************************/
 
-//virtual
-BOOL LLVOAvatarSelf::loadLayersets()
-{
-	BOOL success = TRUE;
-	for (LLVOAvatarXmlInfo::layer_info_list_t::const_iterator iter = sAvatarXmlInfo->mLayerInfoList.begin();
-		 iter != sAvatarXmlInfo->mLayerInfoList.end(); 
-		 ++iter)
-	{
-		// Construct a layerset for each one specified in avatar_lad.xml and initialize it as such.
-		const LLTexLayerSetInfo *info = *iter;
-		LLTexLayerSet* layer_set = new LLTexLayerSet( this );
-		
-		if (!layer_set->setInfo(info))
-		{
-			stop_glerror();
-			delete layer_set;
-			llwarns << "avatar file: layer_set->parseData() failed" << llendl;
-			return FALSE;
-		}
-
-		// scan baked textures and associate the layerset with the appropriate one
-		EBakedTextureIndex baked_index = BAKED_NUM_INDICES;
-		for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-			 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
-			 ++baked_iter)
-		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
-			if (layer_set->isBodyRegion(baked_dict->mName))
-			{
-				baked_index = baked_iter->first;
-				// ensure both structures are aware of each other
-				mBakedTextureDatas[baked_index].mTexLayerSet = layer_set;
-				layer_set->setBakedTexIndex(baked_index);
-				break;
-			}
-		}
-		// if no baked texture was found, warn and cleanup
-		if (baked_index == BAKED_NUM_INDICES)
-		{
-			llwarns << "<layer_set> has invalid body_region attribute" << llendl;
-			delete layer_set;
-			return FALSE;
-		}
-
-		// scan morph masks and let any affected layers know they have an associated morph
-		for (LLVOAvatar::morph_list_t::const_iterator morph_iter = mBakedTextureDatas[baked_index].mMaskedMorphs.begin();
-			morph_iter != mBakedTextureDatas[baked_index].mMaskedMorphs.end();
-			 ++morph_iter)
-		{
-			LLMaskedMorph *morph = *morph_iter;
-			LLTexLayerInterface* layer = layer_set->findLayerByName(morph->mLayer);
-			if (layer)
-			{
-				layer->setHasMorph(TRUE);
-			}
-			else
-			{
-				llwarns << "Could not find layer named " << morph->mLayer << " to set morph flag" << llendl;
-				success = FALSE;
-			}
-		}
-	}
-	return success;
-}
 // virtual
 BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 {
@@ -663,10 +618,16 @@ BOOL LLVOAvatarSelf::updateCharacter(LLAgent &agent)
 	return LLVOAvatar::updateCharacter(agent);
 }
 
+// virtual
+BOOL LLVOAvatarSelf::isValid() const
+{
+	return ((getRegion() != NULL) && !isDead());
+}
+
 // virtual
 void LLVOAvatarSelf::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
 {
-	if (isAgentAvatarValid())
+	if (isValid())
 	{
 		LLVOAvatar::idleUpdate(agent, world, time);
 		idleUpdateTractorBeam();
@@ -689,7 +650,7 @@ void LLVOAvatarSelf::resetJointPositions( void )
 	return LLVOAvatar::resetJointPositions();
 }
 // virtual
-BOOL LLVOAvatarSelf::setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake )
 {
 	if (!which_param)
 	{
@@ -717,20 +678,28 @@ BOOL LLVOAvatarSelf::setVisualParamWeight(S32 index, F32 weight, BOOL upload_bak
 	return setParamWeight(param,weight,upload_bake);
 }
 
-BOOL LLVOAvatarSelf::setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
+BOOL LLVOAvatarSelf::setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake )
 {
 	if (!param)
 	{
 		return FALSE;
 	}
 
+#if 0
+	// FIXME DRANO - kludgy way to avoid overwriting avatar state from wearables.
+	if (isUsingServerBakes() && !isUsingLocalAppearance())
+	{
+		return FALSE;
+	}
+#endif
+
 	if (param->getCrossWearable())
 	{
 		LLWearableType::EType type = (LLWearableType::EType)param->getWearableType();
 		U32 size = gAgentWearables.getWearableCount(type);
 		for (U32 count = 0; count < size; ++count)
 		{
-			LLWearable *wearable = gAgentWearables.getWearable(type,count);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(type,count);
 			if (wearable)
 			{
 				wearable->setVisualParamWeight(param->getID(), weight, upload_bake);
@@ -759,7 +728,7 @@ void LLVOAvatarSelf::idleUpdateAppearanceAnimation()
 		LLWearable *wearable = gAgentWearables.getTopWearable((LLWearableType::EType)type);
 		if (wearable)
 		{
-			wearable->writeToAvatar();
+			wearable->writeToAvatar(this);
 		}
 	}
 
@@ -802,18 +771,30 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
 {
 	U32 retval = LLVOAvatar::processUpdateMessage(mesgsys,user_data,block_num,update_type,dp);
 
-	if (mInitialBakesLoaded == false && retval == 0x0)
+#if 0
+	// DRANO - it's not clear this does anything useful. If we wait
+	// until an appearance message has been received, we already have
+	// the texture ids. If we don't wait, we don't yet know where to
+	// look for baked textures, because we haven't received the
+	// appearance version data from the appearance message. This looks
+	// like an old optimization that's incompatible with server-side
+	// texture baking.
+	
+	// FIXME DRANO - skipping in the case of !mFirstAppearanceMessageReceived prevents us from trying to
+	// load textures before we know where they come from (ie, from baking service or not);
+	// unknown impact on performance.
+	if (mInitialBakesLoaded == false && retval == 0x0 && mFirstAppearanceMessageReceived)
 	{
 		// call update textures to force the images to be created
 		updateMeshTextures();
 
 		// unpack the texture UUIDs to the texture slots
-		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+		retval = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
 
 		// need to trigger a few operations to get the avatar to use the new bakes
 		for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 		{
-			const LLVOAvatarDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
+			const LLAvatarAppearanceDefines::ETextureIndex te = mBakedTextureDatas[i].mTextureIndex;
 			LLUUID texture_id = getTEImage(te)->getID();
 			setNewBakedTexture(te, texture_id);
 			mInitialBakeIDs[i] = texture_id;
@@ -823,6 +804,7 @@ U32  LLVOAvatarSelf::processUpdateMessage(LLMessageSystem *mesgsys,
 
 		mInitialBakesLoaded = true;
 	}
+#endif
 
 	return retval;
 }
@@ -877,11 +859,15 @@ void LLVOAvatarSelf::removeMissingBakedTextures()
 	{
 		for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 		{
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(TRUE);
-			invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, FALSE);
+			LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+			layerset->setUpdatesEnabled(TRUE);
+			invalidateComposite(layerset, FALSE);
 		}
 		updateMeshTextures();
-		requestLayerSetUploads();
+		if (getRegion() && !getRegion()->getCentralBakeVersion())
+		{
+			requestLayerSetUploads();
+		}
 	}
 }
 
@@ -938,7 +924,7 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 void LLVOAvatarSelf::idleUpdateTractorBeam()
 {
 	// This is only done for yourself (maybe it should be in the agent?)
-	if (!needsRenderBeam() || !mIsBuilt)
+	if (!needsRenderBeam() || !isBuilt())
 	{
 		mBeam = NULL;
 	}
@@ -1051,11 +1037,6 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
 	}
 }
 
-/*virtual*/ BOOL LLVOAvatarSelf::isWearingWearableType(LLWearableType::EType type ) const
-{
-	return gAgentWearables.getWearableCount(type) > 0;
-}
-
 //-----------------------------------------------------------------------------
 // updatedWearable( LLWearableType::EType type )
 // forces an update to any baked textures relevant to type.
@@ -1063,26 +1044,27 @@ void LLVOAvatarSelf::updateAttachmentVisibility(U32 camera_mode)
 //-----------------------------------------------------------------------------
 void LLVOAvatarSelf::wearableUpdated( LLWearableType::EType type, BOOL upload_result )
 {
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
-		const LLVOAvatarDefines::EBakedTextureIndex index = baked_iter->first;
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+		const LLAvatarAppearanceDefines::EBakedTextureIndex index = baked_iter->first;
 
 		if (baked_dict)
 		{
-			for (LLVOAvatarDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
+			for (LLAvatarAppearanceDefines::wearables_vec_t::const_iterator type_iter = baked_dict->mWearables.begin();
 				type_iter != baked_dict->mWearables.end();
 				 ++type_iter)
 			{
 				const LLWearableType::EType comp_type = *type_iter;
 				if (comp_type == type)
 				{
-					if (mBakedTextureDatas[index].mTexLayerSet)
+					LLViewerTexLayerSet *layerset = getLayerSet(index);
+					if (layerset)
 					{
-						mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled(true);
-						invalidateComposite(mBakedTextureDatas[index].mTexLayerSet, upload_result);
+						layerset->setUpdatesEnabled(true);
+						invalidateComposite(layerset, upload_result);
 					}
 					break;
 				}
@@ -1246,7 +1228,7 @@ BOOL LLVOAvatarSelf::detachObject(LLViewerObject *viewer_object)
 		// Make sure the inventory is in sync with the avatar.
 
 		// Update COF contents, don't trigger appearance update.
-		if (!isAgentAvatarValid())
+		if (!isValid())
 		{
 			llinfos << "removeItemLinks skipped, avatar is under destruction" << llendl;
 		}
@@ -1287,7 +1269,7 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
 			const LLViewerObject *attached_obj = gAgentAvatarp->getWornAttachment(item_id);
 			if (!attached_obj)
 			{
-				LLAppearanceMgr::instance().removeCOFItemLinks(item_id, false);
+				LLAppearanceMgr::instance().removeCOFItemLinks(item_id);
 			}
 		}
 		return TRUE;
@@ -1295,9 +1277,9 @@ BOOL LLVOAvatarSelf::detachAttachmentIntoInventory(const LLUUID &item_id)
 	return FALSE;
 }
 
-U32 LLVOAvatarSelf::getNumWearables(LLVOAvatarDefines::ETextureIndex i) const
+U32 LLVOAvatarSelf::getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const
 {
-	LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
+	LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
 	return gAgentWearables.getWearableCount(type);
 }
 
@@ -1328,11 +1310,8 @@ void LLVOAvatarSelf::localTextureLoaded(BOOL success, LLViewerFetchedTexture *sr
 			discard_level < local_tex_obj->getDiscard())
 		{
 			local_tex_obj->setDiscard(discard_level);
-			if (isUsingBakedTextures())
-			{
-				requestLayerSetUpdate(index);
-			}
-			else
+			requestLayerSetUpdate(index);
+			if (isEditingAppearance())
 			{
 				LLVisualParamHint::requestHintUpdates();
 			}
@@ -1366,11 +1345,11 @@ BOOL LLVOAvatarSelf::getLocalTextureGL(ETextureIndex type, LLViewerTexture** tex
 	{
 		return FALSE;
 	}
-	*tex_pp = local_tex_obj->getImage();
+	*tex_pp = dynamic_cast<LLViewerTexture*> (local_tex_obj->getImage());
 	return TRUE;
 }
 
-LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (!isIndexLocalTexture(type))
 	{
@@ -1386,7 +1365,7 @@ LLViewerFetchedTexture* LLVOAvatarSelf::getLocalTextureGL(LLVOAvatarDefines::ETe
 	{
 		return LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR);
 	}
-	return local_tex_obj->getImage();
+	return dynamic_cast<LLViewerFetchedTexture*> (local_tex_obj->getImage());
 }
 
 const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) const
@@ -1407,29 +1386,30 @@ const LLUUID& LLVOAvatarSelf::getLocalTextureID(ETextureIndex type, U32 index) c
 // Returns true if at least the lowest quality discard level exists for every texture
 // in the layerset.
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const
 {
 	/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
 	   return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
 		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
 		{
 			BOOL ret = true;
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 				{
-					ret &= (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+					BOOL tex_avail = (getLocalDiscardLevel(tex_index, wearable_index) >= 0);
+					ret &= tex_avail;
 				}
 			}
 			return ret;
@@ -1445,7 +1425,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataAvailable(const LLTexLayerSet* layerset)
 // Returns true if the highest quality discard level exists for every texture
 // in the layerset.
 //-----------------------------------------------------------------------------
-BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) const
+BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const
 {
 	const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); 
 	// const U32 desired_tex_discard_level = 0; // hack to not bake textures on lower discard levels.
@@ -1454,17 +1434,19 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
 	{
 		if (layerset == mBakedTextureDatas[i].mTexLayerSet)
 		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 				{
-					if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+					S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+					if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+						(local_discard_level < 0 ))
 					{
 						return FALSE;
 					}
@@ -1477,6 +1459,7 @@ BOOL LLVOAvatarSelf::isLocalTextureDataFinal(const LLTexLayerSet* layerset) cons
 	return FALSE;
 }
 
+
 BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 {
 	const U32 desired_tex_discard_level = gSavedSettings.getU32("TextureDiscardLevel"); 
@@ -1484,17 +1467,19 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
 			 ++local_tex_iter)
 		{
 			const ETextureIndex tex_index = *local_tex_iter;
-			const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+			const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 			const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 			for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 			{
-				if (getLocalDiscardLevel(*local_tex_iter, wearable_index) > (S32)(desired_tex_discard_level))
+				S32 local_discard_level = getLocalDiscardLevel(*local_tex_iter, wearable_index);
+				if ((local_discard_level > (S32)(desired_tex_discard_level)) ||
+					(local_discard_level < 0 ))
 				{
 					return FALSE;
 				}
@@ -1504,22 +1489,22 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 	return TRUE;
 }
 
-BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const
+BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const
 {
-	const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet;
+	const LLViewerTexLayerSet *layerset = getLayerSet(index);
 	if (!layerset) return FALSE;
-	const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+	const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 	if (!layerset_buffer) return FALSE;
 	return !layerset_buffer->uploadNeeded();
 }
 
-BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	LLUUID id;
 	BOOL isDefined = TRUE;
 	if (isIndexLocalTexture(type))
 	{
-		const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(type);
+		const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(type);
 		const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 		if (index >= wearable_count)
 		{
@@ -1546,7 +1531,7 @@ BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32
 }
 
 //virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const
 {
 	if (isIndexBakedTexture(type))
 	{
@@ -1559,7 +1544,7 @@ BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32
 }
 
 //virtual
-BOOL LLVOAvatarSelf::isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const
+BOOL LLVOAvatarSelf::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const
 {
 	if (isIndexBakedTexture(type))
 	{
@@ -1582,13 +1567,14 @@ void LLVOAvatarSelf::requestLayerSetUploads()
 	}
 }
 
-void LLVOAvatarSelf::requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i)
+void LLVOAvatarSelf::requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i)
 {
 	ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
 	const BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
-	if (!layer_baked && mBakedTextureDatas[i].mTexLayerSet)
+	LLViewerTexLayerSet *layerset = getLayerSet(i);
+	if (!layer_baked && layerset)
 	{
-		mBakedTextureDatas[i].mTexLayerSet->requestUpload();
+		layerset->requestUpload();
 	}
 }
 
@@ -1602,8 +1588,8 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		LLTexLayerSet* layerset = mBakedTextureDatas[i].mTexLayerSet;
-		if (layerset && layerset->getComposite() && layerset->getComposite()->uploadPending())
+		LLViewerTexLayerSet* layerset = getTexLayerSet(i);
+		if (layerset && layerset->getViewerComposite() && layerset->getViewerComposite()->uploadPending())
 		{
 			return true;
 		}
@@ -1613,22 +1599,23 @@ bool LLVOAvatarSelf::hasPendingBakedUploads() const
 
 void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL upload_result )
 {
-	if( !layerset || !layerset->getUpdatesEnabled() )
+	LLViewerTexLayerSet *layer_set = dynamic_cast<LLViewerTexLayerSet*>(layerset);
+	if( !layer_set || !layer_set->getUpdatesEnabled() )
 	{
 		return;
 	}
 	// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegionName() << llendl;
 
-	layerset->requestUpdate();
-	layerset->invalidateMorphMasks();
+	layer_set->requestUpdate();
+	layer_set->invalidateMorphMasks();
 
-	if( upload_result )
+	if( upload_result  && (getRegion() && !getRegion()->getCentralBakeVersion()))
 	{
 		llassert(isSelf());
 
-		ETextureIndex baked_te = getBakedTE( layerset );
+		ETextureIndex baked_te = getBakedTE( layer_set );
 		setTEImage( baked_te, LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT_AVATAR) );
-		layerset->requestUpload();
+		layer_set->requestUpload();
 		updateMeshTextures();
 	}
 }
@@ -1637,7 +1624,8 @@ void LLVOAvatarSelf::invalidateAll()
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		invalidateComposite(mBakedTextureDatas[i].mTexLayerSet, TRUE);
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		invalidateComposite(layerset, TRUE);
 	}
 	//mDebugSelfLoadTimer.reset();
 }
@@ -1655,17 +1643,19 @@ void LLVOAvatarSelf::setCompositeUpdatesEnabled( bool b )
 
 void LLVOAvatarSelf::setCompositeUpdatesEnabled(U32 index, bool b)
 {
-	if (mBakedTextureDatas[index].mTexLayerSet )
+	LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+	if (layerset )
 	{
-		mBakedTextureDatas[index].mTexLayerSet->setUpdatesEnabled( b );
+		layerset->setUpdatesEnabled( b );
 	}
 }
 
 bool LLVOAvatarSelf::isCompositeUpdateEnabled(U32 index)
 {
-	if (mBakedTextureDatas[index].mTexLayerSet)
+	LLViewerTexLayerSet *layerset = getTexLayerSet(index);
+	if (layerset)
 	{
-		return mBakedTextureDatas[index].mTexLayerSet->getUpdatesEnabled();
+		return layerset->getUpdatesEnabled();
 	}
 	return false;
 }
@@ -1676,9 +1666,10 @@ void LLVOAvatarSelf::setupComposites()
 	{
 		ETextureIndex tex_index = mBakedTextureDatas[i].mTextureIndex;
 		BOOL layer_baked = isTextureDefined(tex_index, gAgentWearables.getWearableCount(tex_index));
-		if (mBakedTextureDatas[i].mTexLayerSet)
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if (layerset)
 		{
-			mBakedTextureDatas[i].mTexLayerSet->setUpdatesEnabled(!layer_baked);
+			layerset->setUpdatesEnabled(!layer_baked);
 		}
 	}
 }
@@ -1687,10 +1678,11 @@ void LLVOAvatarSelf::updateComposites()
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		if (mBakedTextureDatas[i].mTexLayerSet 
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if (layerset 
 			&& ((i != BAKED_SKIRT) || isWearingWearableType(LLWearableType::WT_SKIRT)))
 		{
-			mBakedTextureDatas[i].mTexLayerSet->updateComposite();
+			layerset->updateComposite();
 		}
 	}
 }
@@ -1703,11 +1695,12 @@ S32 LLVOAvatarSelf::getLocalDiscardLevel(ETextureIndex type, U32 wearable_index)
 	const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type, wearable_index);
 	if (local_tex_obj)
 	{
+		const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 		if (type >= 0
 			&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR
-			&& !local_tex_obj->getImage()->isMissingAsset())
+			&& !image->isMissingAsset())
 		{
-			return local_tex_obj->getImage()->getDiscardLevel();
+			return image->getDiscardLevel();
 		}
 		else
 		{
@@ -1732,7 +1725,7 @@ void LLVOAvatarSelf::getLocalTextureByteCount(S32* gl_bytes) const
 			const LLLocalTextureObject *local_tex_obj = getLocalTextureObject((ETextureIndex) type, num);
 			if (local_tex_obj)
 			{
-				const LLViewerFetchedTexture* image_gl = local_tex_obj->getImage();
+				const LLViewerFetchedTexture* image_gl = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 				if (image_gl)
 				{
 					S32 bytes = (S32)image_gl->getWidth() * image_gl->getHeight() * image_gl->getComponents();
@@ -1767,8 +1760,8 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 			llerrs << "Tried to set local texture with invalid type: (" << (U32) type << ", " << index << ")" << llendl;
 			return;
 		}
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getInstance()->getTEWearableType(type);
-		if (!gAgentWearables.getWearable(wearable_type,index))
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(type);
+		if (!gAgentWearables.getViewerWearable(wearable_type,index))
 		{
 			// no wearable is loaded, cannot set the texture.
 			return;
@@ -1781,10 +1774,10 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 			return;
 		}
 		
-		LLTexLayerSet *layer_set = getLayerSet(type);
+		LLViewerTexLayerSet *layer_set = getLayerSet(type);
 		if (layer_set)
 		{
-			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getWearable(wearable_type,index));
+			layer_set->cloneTemplates(local_tex_obj, type, gAgentWearables.getViewerWearable(wearable_type,index));
 		}
 
 	}
@@ -1803,17 +1796,14 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 				{
 					local_tex_obj->setDiscard(tex_discard);
 					if (isSelf())
-					{
-						if (gAgentAvatarp->isUsingBakedTextures())
 					{
 						requestLayerSetUpdate(type);
-					}
-						else
-					{
-						LLVisualParamHint::requestHintUpdates();
+						if (isEditingAppearance())
+						{
+							LLVisualParamHint::requestHintUpdates();
+						}
 					}
 				}
-				}
 				else
 				{					
 					tex->setLoadedCallback(onLocalTextureLoaded, desired_discard, TRUE, FALSE, new LLAvatarTexData(getID(), type), NULL);
@@ -1826,8 +1816,9 @@ void LLVOAvatarSelf::setLocalTexture(ETextureIndex type, LLViewerTexture* src_te
 	local_tex_obj->setID(tex->getID());
 	setBakedReady(type,baked_version_ready,index);
 }
+
 //virtual
-void LLVOAvatarSelf::setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
+void LLVOAvatarSelf::setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index)
 {
 	if (!isIndexLocalTexture(type)) return;
 	LLLocalTextureObject *local_tex_obj = getLocalTextureObject(type,index);
@@ -1846,16 +1837,16 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 	/* ETextureIndex baked_equiv[] = {
 	   TEX_UPPER_BAKED,
 	   if (isTextureDefined(baked_equiv[i])) */
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
 			continue;
 
 		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-		const ETextureIndex baked_equiv = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
+		const ETextureIndex baked_equiv = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index)->mTextureIndex;
 
 		const std::string &name = texture_dict->mName;
 		const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(iter->first, 0);
@@ -1878,7 +1869,7 @@ void LLVOAvatarSelf::dumpLocalTextures() const
 			}
 			else
 			{
-				const LLViewerFetchedTexture* image = local_tex_obj->getImage();
+				const LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
 
 				llinfos << "LocTex " << name << ": "
 						<< "Discard " << image->getDiscardLevel() << ", "
@@ -1955,35 +1946,63 @@ void LLVOAvatarSelf::dumpTotalLocalTextureByteCount()
 
 BOOL LLVOAvatarSelf::getIsCloud() const
 {
+	// Let people know why they're clouded without spamming them into oblivion.
+	bool do_warn = false;
+	static LLTimer time_since_notice;
+	F32 update_freq = 30.0;
+	if (time_since_notice.getElapsedTimeF32() > update_freq)
+	{
+		time_since_notice.reset();
+		do_warn = true;
+	}
+	
 	// do we have our body parts?
-	if (gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_HAIR) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_EYES) == 0 ||
-		gAgentWearables.getWearableCount(LLWearableType::WT_SKIN) == 0)	
+	S32 shape_count = gAgentWearables.getWearableCount(LLWearableType::WT_SHAPE);
+	S32 hair_count = gAgentWearables.getWearableCount(LLWearableType::WT_HAIR);
+	S32 eye_count = gAgentWearables.getWearableCount(LLWearableType::WT_EYES);
+	S32 skin_count = gAgentWearables.getWearableCount(LLWearableType::WT_SKIN);
+	if (!shape_count || !hair_count || !eye_count || !skin_count)
 	{
-		lldebugs << "No body parts" << llendl;
+		if (do_warn)
+		{
+			llinfos << "Self is clouded due to missing one or more required body parts: "
+					<< (shape_count ? "" : "SHAPE ")
+					<< (hair_count ? "" : "HAIR ")
+					<< (eye_count ? "" : "EYES ")
+					<< (skin_count ? "" : "SKIN ")
+					<< llendl;
+		}
 		return TRUE;
 	}
 
 	if (!isTextureDefined(TEX_HAIR, 0))
 	{
-		lldebugs << "No hair texture" << llendl;
+		if (do_warn)
+		{
+			llinfos << "Self is clouded because of no hair texture" << llendl;
+		}
 		return TRUE;
 	}
 
 	if (!mPreviousFullyLoaded)
 	{
-		if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_LOWER].mTexLayerSet) &&
+		if (!isLocalTextureDataAvailable(getLayerSet(BAKED_LOWER)) &&
 			(!isTextureDefined(TEX_LOWER_BAKED, 0)))
 		{
-			lldebugs << "Lower textures not baked" << llendl;
+			if (do_warn)
+			{
+				llinfos << "Self is clouded because lower textures not baked" << llendl;
+			}
 			return TRUE;
 		}
 
-		if (!isLocalTextureDataAvailable(mBakedTextureDatas[BAKED_UPPER].mTexLayerSet) &&
+		if (!isLocalTextureDataAvailable(getLayerSet(BAKED_UPPER)) &&
 			(!isTextureDefined(TEX_UPPER_BAKED, 0)))
 		{
-			lldebugs << "Upper textures not baked" << llendl;
+			if (do_warn)
+			{
+				llinfos << "Self is clouded because upper textures not baked" << llendl;
+			}
 			return TRUE;
 		}
 
@@ -2000,7 +2019,11 @@ BOOL LLVOAvatarSelf::getIsCloud() const
 			const LLViewerTexture* baked_img = getImage( texture_data.mTextureIndex, 0 );
 			if (!baked_img || !baked_img->hasGLTexture())
 			{
-				lldebugs << "Texture at index " << i << " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+				if (do_warn)
+				{
+					llinfos << "Self is clouded because texture at index " << i
+							<< " (texture index is " << texture_data.mTextureIndex << ") is not loaded" << llendl;
+				}
 				return TRUE;
 			}
 		}
@@ -2051,7 +2074,85 @@ void LLVOAvatarSelf::debugBakedTextureUpload(EBakedTextureIndex index, BOOL fini
 	mDebugBakedTextureTimes[index][done] = mDebugSelfLoadTimer.getElapsedTimeF32();
 }
 
-const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const
+const std::string LLVOAvatarSelf::verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
+{
+	std::ostringstream outbuf;
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter =
+			 LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const EBakedTextureIndex baked_index = baked_iter->first;
+		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
+		{
+			outbuf << "baked_index: " << baked_index << "\n";
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
+			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
+				 local_tex_iter != baked_dict->mLocalTextures.end();
+				 ++local_tex_iter)
+			{
+				const ETextureIndex tex_index = *local_tex_iter;
+				const std::string tex_name = LLAvatarAppearanceDictionary::getInstance()->getTexture(tex_index)->mName;
+				outbuf << "  tex_index " << (S32) tex_index << " name " << tex_name << "\n";
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
+				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
+				if (wearable_count > 0)
+				{
+					for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
+					{
+						outbuf << "    " << LLWearableType::getTypeName(wearable_type) << " " << wearable_index << ":";
+						const LLLocalTextureObject *local_tex_obj = getLocalTextureObject(tex_index, wearable_index);
+						if (local_tex_obj)
+						{
+							LLViewerFetchedTexture* image = dynamic_cast<LLViewerFetchedTexture*>( local_tex_obj->getImage() );
+							if (tex_index >= 0
+								&& local_tex_obj->getID() != IMG_DEFAULT_AVATAR
+								&& !image->isMissingAsset())
+							{
+								outbuf << " id: " << image->getID()
+									   << " refs: " << image->getNumRefs()
+									   << " glocdisc: " << getLocalDiscardLevel(tex_index, wearable_index)
+									   << " discard: " << image->getDiscardLevel()
+									   << " desired: " << image->getDesiredDiscardLevel()
+									   << " decode: " << image->getDecodePriority()
+									   << " addl: " << image->getAdditionalDecodePriority()
+									   << " ts: " << image->getTextureState()
+									   << " bl: " << image->getBoostLevel()
+									   << " fl: " << image->isFullyLoaded() // this is not an accessor for mFullyLoaded - see comment there.
+									   << " cl: " << (image->isFullyLoaded() && image->getDiscardLevel()==0) // "completely loaded"
+									   << " mvs: " << image->getMaxVirtualSize()
+									   << " mvsc: " << image->getMaxVirtualSizeResetCounter()
+									   << " mem: " << image->getTextureMemory();
+							}
+						}
+						outbuf << "\n";
+					}
+				}
+			}
+			break;
+		}
+	}
+	return outbuf.str();
+}
+
+void LLVOAvatarSelf::dumpAllTextures() const
+{
+	std::string vd_text = "Local textures per baked index and wearable:\n";
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
+		 ++baked_iter)
+	{
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
+		if (!layerset) continue;
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
+		if (!layerset_buffer) continue;
+		vd_text += verboseDebugDumpLocalTextureDataInfo(layerset);
+	}
+	LL_DEBUGS("Avatar") << vd_text << llendl;
+}
+
+const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const
 {
 	std::string text="";
 
@@ -2059,21 +2160,21 @@ const std::string LLVOAvatarSelf::debugDumpLocalTextureDataInfo(const LLTexLayer
 
 	/* if (layerset == mBakedTextureDatas[BAKED_HEAD].mTexLayerSet)
 	   return getLocalDiscardLevel(TEX_HEAD_BODYPAINT) >= 0; */
-	for (LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
 		const EBakedTextureIndex baked_index = baked_iter->first;
 		if (layerset == mBakedTextureDatas[baked_index].mTexLayerSet)
 		{
-			const LLVOAvatarDictionary::BakedEntry *baked_dict = baked_iter->second;
+			const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = baked_iter->second;
 			text += llformat("%d-%s ( ",baked_index, baked_dict->mName.c_str());
 			for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 				 local_tex_iter != baked_dict->mLocalTextures.end();
 				 ++local_tex_iter)
 			{
 				const ETextureIndex tex_index = *local_tex_iter;
-				const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+				const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 				const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 				if (wearable_count > 0)
 				{
@@ -2100,14 +2201,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
 
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
+		const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture((EBakedTextureIndex)i);
 		BOOL is_texture_final = TRUE;
 		for (texture_vec_t::const_iterator local_tex_iter = baked_dict->mLocalTextures.begin();
 			 local_tex_iter != baked_dict->mLocalTextures.end();
 			 ++local_tex_iter)
 		{
 			const ETextureIndex tex_index = *local_tex_iter;
-			const LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(tex_index);
+			const LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(tex_index);
 			const U32 wearable_count = gAgentWearables.getWearableCount(wearable_type);
 			for (U32 wearable_index = 0; wearable_index < wearable_count; wearable_index++)
 			{
@@ -2119,20 +2220,14 @@ const std::string LLVOAvatarSelf::debugDumpAllLocalTextureDataInfo() const
 	return text;
 }
 
+
+#if 0
 // Dump avatar metrics data.
 LLSD LLVOAvatarSelf::metricsData()
 {
 	// runway - add region info
 	LLSD result;
 	result["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
-	std::vector<S32> rez_counts;
-	LLVOAvatar::getNearbyRezzedStats(rez_counts);
-	result["nearby"] = LLSD::emptyMap();
-	for (S32 i=0; i<rez_counts.size(); ++i)
-	{
-		std::string rez_status_name = LLVOAvatar::rezStatusToString(i);
-		result["nearby"][rez_status_name] = rez_counts[i];
-	}
 	result["timers"]["debug_existence"] = mDebugExistenceTimer.getElapsedTimeF32();
 	result["timers"]["ruth_debug"] = mRuthDebugTimer.getElapsedTimeF32();
 	result["timers"]["ruth"] = mRuthTimer.getElapsedTimeF32();
@@ -2142,6 +2237,7 @@ LLSD LLVOAvatarSelf::metricsData()
 	
 	return result;
 }
+#endif
 
 class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 {
@@ -2159,6 +2255,7 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 						   const std::string& reason,
 						   const LLSD& content)
 	{
+		gPendingMetricsUploads--; // if we add retry, this should be moved to the isGoodStatus case.
 		if (isGoodStatus(status))
 		{
 			LL_DEBUGS("Avatar") << "OK" << LL_ENDL;
@@ -2167,15 +2264,10 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 		else
 		{
 			LL_WARNS("Avatar") << "Failed " << status << " reason " << reason << LL_ENDL;
-			error(status,reason);
+			errorWithContent(status,reason,content);
 		}
 	}
 
-	// virtual
-	void error(U32 status_num, const std::string & reason)
-	{
-	}
-
 	// virtual
 	void result(const LLSD & content)
 	{
@@ -2191,19 +2283,121 @@ class ViewerAppearanceChangeMetricsResponder: public LLCurl::Responder
 	volatile bool & mReportingStarted;
 };
 
-void LLVOAvatarSelf::sendAppearanceChangeMetrics()
+bool LLVOAvatarSelf::updateAvatarRezMetrics(bool force_send)
+{
+	const F32 AV_METRICS_INTERVAL_QA = 30.0;
+	F32 send_period = 300.0;
+	if (gSavedSettings.getBOOL("QAModeMetrics"))
+	{
+		send_period = AV_METRICS_INTERVAL_QA;
+	}
+
+	if (force_send || mTimeSinceLastRezMessage.getElapsedTimeF32() > send_period)
+	{
+		// Stats for completed phases have been getting logged as they
+		// complete.  This will give us stats for any timers that
+		// haven't finished as of the metric's being sent.
+		
+		if (force_send)
+		{
+			LLVOAvatar::logPendingPhasesAllAvatars();
+		}
+		sendViewerAppearanceChangeMetrics();
+	}
+
+	return false;
+}
+
+void LLVOAvatarSelf::addMetricsTimerRecord(const LLSD& record)
+{
+	mPendingTimerRecords.push_back(record);
+}
+
+bool operator<(const LLSD& a, const LLSD& b)
+{
+	std::ostringstream aout, bout;
+	aout << LLSDNotationStreamer(a);
+	bout << LLSDNotationStreamer(b);
+	std::string astring = aout.str();
+	std::string bstring = bout.str();
+
+	return astring < bstring;
+
+}
+
+// Given a vector of LLSD records, return an LLSD array of bucketed stats for val_field.
+LLSD summarize_by_buckets(std::vector<LLSD> in_records,
+						  std::vector<std::string> by_fields,
+						  std::string val_field)
+{
+	LLSD result = LLSD::emptyArray();
+	std::map<LLSD,LLViewerStats::StatsAccumulator> accum;
+	for (std::vector<LLSD>::iterator in_record_iter = in_records.begin();
+		 in_record_iter != in_records.end(); ++in_record_iter)
+	{
+		LLSD& record = *in_record_iter;
+		LLSD key;
+		for (std::vector<std::string>::iterator field_iter = by_fields.begin();
+			 field_iter != by_fields.end(); ++field_iter)
+		{
+			const std::string& field = *field_iter;
+			key[field] = record[field];
+		}
+		LLViewerStats::StatsAccumulator& stats = accum[key];
+		F32 value = record[val_field].asReal();
+		stats.push(value);
+	}
+	for (std::map<LLSD,LLViewerStats::StatsAccumulator>::iterator accum_it = accum.begin();
+		 accum_it != accum.end(); ++accum_it)
+	{
+		LLSD out_record = accum_it->first;
+		out_record["stats"] = accum_it->second.getData();
+		result.append(out_record);
+	}
+	return result;
+}
+
+void LLVOAvatarSelf::sendViewerAppearanceChangeMetrics()
 {
 	// gAgentAvatarp->stopAllPhases();
 	static volatile bool reporting_started(false);
 	static volatile S32 report_sequence(0);
 
-	LLSD msg = metricsData();
+	LLSD msg; // = metricsData();
 	msg["message"] = "ViewerAppearanceChangeMetrics";
 	msg["session_id"] = gAgentSessionID;
 	msg["agent_id"] = gAgentID;
 	msg["sequence"] = report_sequence;
 	msg["initial"] = !reporting_started;
 	msg["break"] = false;
+	msg["duration"] = mTimeSinceLastRezMessage.getElapsedTimeF32();
+
+	// Status of our own rezzing.
+	msg["rez_status"] = LLVOAvatar::rezStatusToString(getRezzedStatus());
+
+	// Status of all nearby avs including ourself.
+	msg["nearby"] = LLSD::emptyArray();
+	std::vector<S32> rez_counts;
+	LLVOAvatar::getNearbyRezzedStats(rez_counts);
+	for (S32 rez_stat=0; rez_stat < rez_counts.size(); ++rez_stat)
+	{
+		std::string rez_status_name = LLVOAvatar::rezStatusToString(rez_stat);
+		msg["nearby"][rez_status_name] = rez_counts[rez_stat];
+	}
+
+	//	std::vector<std::string> bucket_fields("timer_name","is_self","grid_x","grid_y","is_using_server_bake");
+	std::vector<std::string> by_fields;
+	by_fields.push_back("timer_name");
+	by_fields.push_back("completed");
+	by_fields.push_back("grid_x");
+	by_fields.push_back("grid_y");
+	by_fields.push_back("is_using_server_bakes");
+	by_fields.push_back("is_self");
+	by_fields.push_back("central_bake_version");
+	LLSD summary = summarize_by_buckets(mPendingTimerRecords, by_fields, std::string("elapsed"));
+	msg["timers"] = summary;
+
+	mPendingTimerRecords.clear();
 
 	// Update sequence number
 	if (S32_MAX == ++report_sequence)
@@ -2218,20 +2412,79 @@ void LLVOAvatarSelf::sendAppearanceChangeMetrics()
 	}
 	if (!caps_url.empty())
 	{
+		gPendingMetricsUploads++;
 		LLCurlRequest::headers_t headers;
 		LLHTTPClient::post(caps_url,
 						   msg,
 						   new ViewerAppearanceChangeMetricsResponder(report_sequence,
 																	  report_sequence,
 																	  reporting_started));
+		mTimeSinceLastRezMessage.reset();
 	}
 }
 
+class CheckAgentAppearanceServiceResponder: public LLHTTPClient::Responder
+{
+public:
+	CheckAgentAppearanceServiceResponder()
+	{
+	}
+	
+	virtual ~CheckAgentAppearanceServiceResponder()
+	{
+	}
+
+	/* virtual */ void result(const LLSD& content)
+	{
+		LL_DEBUGS("Avatar") << "status OK" << llendl;
+	}
+
+	// Error
+	/*virtual*/ void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
+	{
+		if (isAgentAvatarValid())
+		{
+			LL_DEBUGS("Avatar") << "failed, will rebake [status:"
+					<< status << "]: " << content << llendl;
+			forceAppearanceUpdate();
+		}
+	}	
+
+	static void forceAppearanceUpdate()
+	{
+		// Trying to rebake immediately after crossing region boundary
+		// seems to be failure prone; adding a delay factor. Yes, this
+		// fix is ad-hoc and not guaranteed to work in all cases.
+		doAfterInterval(boost::bind(&LLVOAvatarSelf::forceBakeAllTextures,
+									gAgentAvatarp.get(), true), 5.0);
+	}
+};
+
+void LLVOAvatarSelf::checkForUnsupportedServerBakeAppearance()
+{
+	// Need to check only if we have a server baked appearance and are
+	// in a non-baking region.
+	if (!gAgentAvatarp->isUsingServerBakes())
+		return;
+	if (!gAgent.getRegion() || gAgent.getRegion()->getCentralBakeVersion()!=0)
+		return;
+
+	// if baked image service is unknown, need to refresh.
+	if (LLAppearanceMgr::instance().getAppearanceServiceURL().empty())
+	{
+		CheckAgentAppearanceServiceResponder::forceAppearanceUpdate();
+	}
+	// query baked image service to check status.
+	std::string image_url = gAgentAvatarp->getImageURL(TEX_HEAD_BAKED,
+													   getTE(TEX_HEAD_BAKED)->getID());
+	LLHTTPClient::head(image_url, new CheckAgentAppearanceServiceResponder);
+}
+
 const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) const
 {
 	if (canGrabBakedTexture(baked_index))
 	{
-		ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+		ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
 		if (tex_index == TEX_NUM_INDICES)
 		{
 			return LLUUID::null;
@@ -2243,7 +2496,7 @@ const LLUUID& LLVOAvatarSelf::grabBakedTexture(EBakedTextureIndex baked_index) c
 
 BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 {
-	ETextureIndex tex_index = LLVOAvatarDictionary::bakedToLocalTextureIndex(baked_index);
+	ETextureIndex tex_index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(baked_index);
 	if (tex_index == TEX_NUM_INDICES)
 	{
 		return FALSE;
@@ -2262,19 +2515,19 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 	// baked texture.  We don't want people copying people's
 	// work via baked textures.
 
-	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
+	const LLAvatarAppearanceDictionary::BakedEntry *baked_dict = LLAvatarAppearanceDictionary::getInstance()->getBakedTexture(baked_index);
 	for (texture_vec_t::const_iterator iter = baked_dict->mLocalTextures.begin();
 		 iter != baked_dict->mLocalTextures.end();
 		 ++iter)
 	{
 		const ETextureIndex t_index = (*iter);
-		LLWearableType::EType wearable_type = LLVOAvatarDictionary::getTEWearableType(t_index);
+		LLWearableType::EType wearable_type = LLAvatarAppearanceDictionary::getTEWearableType(t_index);
 		U32 count = gAgentWearables.getWearableCount(wearable_type);
 		lldebugs << "Checking index " << (U32) t_index << " count: " << count << llendl;
 		
 		for (U32 wearable_index = 0; wearable_index < count; ++wearable_index)
 		{
-			LLWearable *wearable = gAgentWearables.getWearable(wearable_type, wearable_index);
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable(wearable_type, wearable_index);
 			if (wearable)
 			{
 				const LLLocalTextureObject *texture = wearable->getLocalTextureObject((S32)t_index);
@@ -2316,26 +2569,34 @@ BOOL LLVOAvatarSelf::canGrabBakedTexture(EBakedTextureIndex baked_index) const
 }
 
 void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTexture* imagep,
-										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked, U32 index )
+										   F32 texel_area_ratio, BOOL render_avatar, BOOL covered_by_baked)
 {
 	if (!isIndexLocalTexture(type)) return;
 
-	if (!covered_by_baked)
+	// Sunshine - ignoring covered_by_baked will force local textures
+	// to always load.  Fix for SH-4001 and many related issues.  Do
+	// not restore this without some more targetted fix for the local
+	// textures failing to load issue.
+	//if (!covered_by_baked)
 	{
-		if (getLocalTextureID(type, index) != IMG_DEFAULT_AVATAR && imagep->getDiscardLevel() != 0)
+		if (imagep->getID() != IMG_DEFAULT_AVATAR)
 		{
-			F32 desired_pixels;
-			desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
-			imagep->setBoostLevel(getAvatarBoostLevel());
-
-			imagep->resetTextureStats();
-			imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
-			imagep->addTextureStats( desired_pixels / texel_area_ratio );
-			imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
-			imagep->forceUpdateBindStats() ;
-			if (imagep->getDiscardLevel() < 0)
+			imagep->setNoDelete();
+			if (imagep->getDiscardLevel() != 0)
 			{
-				mHasGrey = TRUE; // for statistics gathering
+				F32 desired_pixels;
+				desired_pixels = llmin(mPixelArea, (F32)getTexImageArea());
+				
+				imagep->setBoostLevel(getAvatarBoostLevel());
+				imagep->setAdditionalDecodePriority(SELF_ADDITIONAL_PRI) ;
+				imagep->resetTextureStats();
+				imagep->setMaxVirtualSizeResetInterval(MAX_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL);
+				imagep->addTextureStats( desired_pixels / texel_area_ratio );
+				imagep->forceUpdateBindStats() ;
+				if (imagep->getDiscardLevel() < 0)
+				{
+					mHasGrey = TRUE; // for statistics gathering
+				}
 			}
 		}
 		else
@@ -2346,10 +2607,10 @@ void LLVOAvatarSelf::addLocalTextureStats( ETextureIndex type, LLViewerFetchedTe
 	}
 }
 
-LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 wearable_index) const
+LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 wearable_index) const
 {
-	LLWearableType::EType type = LLVOAvatarDictionary::getInstance()->getTEWearableType(i);
-	LLWearable* wearable = gAgentWearables.getWearable(type, wearable_index);
+	LLWearableType::EType type = LLAvatarAppearanceDictionary::getInstance()->getTEWearableType(i);
+	LLViewerWearable* wearable = gAgentWearables.getViewerWearable(type, wearable_index);
 	if (wearable)
 	{
 		return wearable->getLocalTextureObject(i);
@@ -2362,7 +2623,7 @@ LLLocalTextureObject* LLVOAvatarSelf::getLocalTextureObject(LLVOAvatarDefines::E
 // getBakedTE()
 // Used by the LayerSet.  (Layer sets don't in general know what textures depend on them.)
 //-----------------------------------------------------------------------------
-ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
+ETextureIndex LLVOAvatarSelf::getBakedTE( const LLViewerTexLayerSet* layerset ) const
 {
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
@@ -2376,9 +2637,9 @@ ETextureIndex LLVOAvatarSelf::getBakedTE( const LLTexLayerSet* layerset ) const
 }
 
 
-void LLVOAvatarSelf::setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid)
+void LLVOAvatarSelf::setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid)
 {
-	ETextureIndex index = LLVOAvatarDictionary::bakedToLocalTextureIndex(i);
+	ETextureIndex index = LLAvatarAppearanceDictionary::bakedToLocalTextureIndex(i);
 	setNewBakedTexture(index, uuid);
 }
 
@@ -2391,7 +2652,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
 {
 	// Baked textures live on other sims.
 	LLHost target_host = getObjectHost();	
-	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, target_host ) );
+	setTEImage( te, LLViewerTextureManager::getFetchedTextureFromHost( uuid, FTT_HOST_BAKE, target_host ) );
 	updateMeshTextures();
 	dirtyMesh();
 
@@ -2400,7 +2661,7 @@ void LLVOAvatarSelf::setNewBakedTexture( ETextureIndex te, const LLUUID& uuid )
 	/* switch(te)
 		case TEX_HEAD_BAKED:
 			llinfos << "New baked texture: HEAD" << llendl; */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(te);
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(te);
 	if (texture_dict->mIsBakedTexture)
 	{
 		debugBakedTextureUpload(texture_dict->mBakedTextureIndex, TRUE); // FALSE for start of upload, TRUE for finish.
@@ -2465,7 +2726,7 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud: " << (S32)mDebugTimeAvatarVisible << llendl;
 	LL_DEBUGS("Avatar") << "\t Time from avatar creation to de-cloud for others: " << (S32)final_time << llendl;
 	LL_DEBUGS("Avatar") << "\t Load time for each texture: " << llendl;
-	for (U32 i = 0; i < LLVOAvatarDefines::TEX_NUM_INDICES; ++i)
+	for (U32 i = 0; i < LLAvatarAppearanceDefines::TEX_NUM_INDICES; ++i)
 	{
 		std::stringstream out;
 		out << "\t\t (" << i << ") ";
@@ -2493,27 +2754,29 @@ void LLVOAvatarSelf::outputRezDiagnostics() const
 		}
 	}
 	LL_DEBUGS("Avatar") << "\t Time points for each upload (start / finish)" << llendl;
-	for (U32 i = 0; i < LLVOAvatarDefines::BAKED_NUM_INDICES; ++i)
+	for (U32 i = 0; i < LLAvatarAppearanceDefines::BAKED_NUM_INDICES; ++i)
 	{
 		LL_DEBUGS("Avatar") << "\t\t (" << i << ") \t" << (S32)mDebugBakedTextureTimes[i][0] << " / " << (S32)mDebugBakedTextureTimes[i][1] << llendl;
 	}
 
-	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
-		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
+	for (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::BakedTextures::const_iterator baked_iter = LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().begin();
+		 baked_iter != LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
 	{
-		const LLVOAvatarDefines::EBakedTextureIndex baked_index = baked_iter->first;
-		const LLTexLayerSet *layerset = debugGetLayerSet(baked_index);
+		const LLAvatarAppearanceDefines::EBakedTextureIndex baked_index = baked_iter->first;
+		const LLViewerTexLayerSet *layerset = debugGetLayerSet(baked_index);
 		if (!layerset) continue;
-		const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+		const LLViewerTexLayerSetBuffer *layerset_buffer = layerset->getViewerComposite();
 		if (!layerset_buffer) continue;
 		LL_DEBUGS("Avatar") << layerset_buffer->dumpTextureInfo() << llendl;
 	}
+
+	dumpAllTextures();
 }
 
 void LLVOAvatarSelf::outputRezTiming(const std::string& msg) const
 {
-	LL_INFOS("Avatar")
+	LL_DEBUGS("Avatar")
 		<< avString()
 		<< llformat("%s. Time from avatar creation: %.2f", msg.c_str(), mDebugSelfLoadTimer.getElapsedTimeF32())
 		<< LL_ENDL;
@@ -2538,7 +2801,8 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
 				mHeadLayerSet->cancelUpload(); */
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
-		if ( mBakedTextureDatas[i].mTextureIndex == te && mBakedTextureDatas[i].mTexLayerSet)
+		LLViewerTexLayerSet *layerset = getTexLayerSet(i);
+		if ( mBakedTextureDatas[i].mTextureIndex == te && layerset)
 		{
 			if (mInitialBakeIDs[i] != LLUUID::null)
 			{
@@ -2552,7 +2816,7 @@ void LLVOAvatarSelf::setCachedBakedTexture( ETextureIndex te, const LLUUID& uuid
 				}
 				mInitialBakeIDs[i] = LLUUID::null;
 			}
-			mBakedTextureDatas[i].mTexLayerSet->cancelUpload();
+			layerset->cancelUpload();
 		}
 	}
 }
@@ -2571,17 +2835,17 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
 	/* ETextureIndex baked_texture_indices[BAKED_NUM_INDICES] =
 			TEX_HEAD_BAKED,
 			TEX_UPPER_BAKED, */
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (texture_dict->mIsBakedTexture)
 		{
 			if (texture_id == gAgentAvatarp->getTEImage(index)->getID())
 			{
-				LLTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
+				LLViewerTexLayerSet* layer_set = gAgentAvatarp->getLayerSet(index);
 				if (layer_set)
 				{
 					llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
@@ -2605,15 +2869,6 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
 	}
 }
 
-BOOL LLVOAvatarSelf::isUsingBakedTextures() const
-{
-	// Composite textures are used during appearance mode.
-	if (gAgentCamera.cameraCustomizeAvatar())
-		return FALSE;
-
-	return TRUE;
-}
-
 
 void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 {
@@ -2622,7 +2877,7 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 	for (U32 i = 0; i < mBakedTextureDatas.size(); i++)
 	{
 		ETextureIndex baked_index = mBakedTextureDatas[i].mTextureIndex;
-		LLTexLayerSet* layer_set = getLayerSet(baked_index);
+		LLViewerTexLayerSet* layer_set = getLayerSet(baked_index);
 		if (layer_set)
 		{
 			if (slam_for_debug)
@@ -2654,7 +2909,7 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
 		case LOCTEX_UPPER_SHIRT:
 			if( mUpperBodyLayerSet )
 				mUpperBodyLayerSet->requestUpdate(); */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
+	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
 	if (!texture_dict->mIsLocalTexture || !texture_dict->mIsUsedByBakedTexture)
 		return;
 	const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
@@ -2664,22 +2919,22 @@ void LLVOAvatarSelf::requestLayerSetUpdate(ETextureIndex index )
 	}
 }
 
-LLTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(ETextureIndex index) const
 {
-	/* switch(index)
-		case TEX_HEAD_BAKED:
-		case TEX_HEAD_BODYPAINT:
-			return mHeadLayerSet; */
-	const LLVOAvatarDictionary::TextureEntry *texture_dict = LLVOAvatarDictionary::getInstance()->getTexture(index);
-	if (texture_dict->mIsUsedByBakedTexture)
-	{
-		const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
-		return mBakedTextureDatas[baked_index].mTexLayerSet;
-	}
-	return NULL;
+       /* switch(index)
+               case TEX_HEAD_BAKED:
+               case TEX_HEAD_BODYPAINT:
+                       return mHeadLayerSet; */
+       const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
+       if (texture_dict->mIsUsedByBakedTexture)
+       {
+               const EBakedTextureIndex baked_index = texture_dict->mBakedTextureIndex;
+               return getLayerSet(baked_index);
+       }
+       return NULL;
 }
 
-LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
+LLViewerTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
 {
        /* switch(index)
                case TEX_HEAD_BAKED:
@@ -2687,26 +2942,60 @@ LLTexLayerSet* LLVOAvatarSelf::getLayerSet(EBakedTextureIndex baked_index) const
                        return mHeadLayerSet; */
        if (baked_index >= 0 && baked_index < BAKED_NUM_INDICES)
        {
-                       return mBakedTextureDatas[baked_index].mTexLayerSet;
+		   return  getTexLayerSet(baked_index);
        }
        return NULL;
 }
 
 
+
+
 // static
-void LLVOAvatarSelf::onCustomizeStart()
+void LLVOAvatarSelf::onCustomizeStart(bool disable_camera_switch)
 {
-	// We're no longer doing any baking or invalidating on entering 
-	// appearance editing mode. Leaving function in place in case 
-	// further changes require us to do something at this point - Nyx
+	if (isAgentAvatarValid())
+	{
+		gAgentAvatarp->mIsEditingAppearance = true;
+		gAgentAvatarp->mUseLocalAppearance = true;
+
+		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+		{
+			gAgentCamera.changeCameraToCustomizeAvatar();
+		}
+
+#if 0
+		gAgentAvatarp->clearVisualParamWeights();
+		gAgentAvatarp->idleUpdateAppearanceAnimation();
+#endif
+		
+		gAgentAvatarp->invalidateAll(); // mark all bakes as dirty, request updates
+		gAgentAvatarp->updateMeshTextures(); // make sure correct textures are applied to the avatar mesh.
+		gAgentAvatarp->updateTextures(); // call updateTextureStats
+	}
 }
 
 // static
-void LLVOAvatarSelf::onCustomizeEnd()
+void LLVOAvatarSelf::onCustomizeEnd(bool disable_camera_switch)
 {
+
 	if (isAgentAvatarValid())
 	{
+		gAgentAvatarp->mIsEditingAppearance = false;
+		if (gAgentAvatarp->getRegion() && !gAgentAvatarp->getRegion()->getCentralBakeVersion())
+		{
+			// FIXME DRANO - move to sendAgentSetAppearance, make conditional on upload complete.
+			gAgentAvatarp->mUseLocalAppearance = false;
+		}
+
 		gAgentAvatarp->invalidateAll();
+
+		if (gSavedSettings.getBOOL("AppearanceCameraMovement") && !disable_camera_switch)
+		{
+			gAgentCamera.changeCameraToDefault();
+			gAgentCamera.resetView();
+		}
+	
+		LLAppearanceMgr::instance().updateAppearanceFromCOF();	
 	}
 }
 
@@ -2719,12 +3008,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 {
 	LLUUID texture_id[TEX_NUM_INDICES];
 	// pack away current TEs to make sure we don't send them out
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsBakedTexture)
 		{
 			LLTextureEntry* entry = getTE((U8) index);
@@ -2736,12 +3025,12 @@ bool LLVOAvatarSelf::sendAppearanceMessage(LLMessageSystem *mesgsys) const
 	bool success = packTEMessage(mesgsys);
 
 	// unpack TEs to make sure we don't re-trigger a bake
-	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
-		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+	for (LLAvatarAppearanceDictionary::Textures::const_iterator iter = LLAvatarAppearanceDictionary::getInstance()->getTextures().begin();
+		 iter != LLAvatarAppearanceDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const ETextureIndex index = iter->first;
-		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+		const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = iter->second;
 		if (!texture_dict->mIsBakedTexture)
 		{
 			LLTextureEntry* entry = getTE((U8) index);
@@ -2797,3 +3086,36 @@ void LLVOAvatarSelf::dumpScratchTextureByteCount()
 {
 	llinfos << "Scratch Texture GL: " << (sScratchTexBytes/1024) << "KB" << llendl;
 }
+
+void LLVOAvatarSelf::dumpWearableInfo(LLAPRFile& outfile)
+{
+	apr_file_t* file = outfile.getFileHandle();
+	if (!file)
+	{
+		return;
+	}
+
+	
+	apr_file_printf( file, "\n<wearable_info>\n" );
+
+	LLWearableData *wd = getWearableData();
+	for (S32 type = 0; type < LLWearableType::WT_COUNT; type++)
+	{
+		const std::string& type_name = LLWearableType::getTypeName((LLWearableType::EType)type);
+		for (U32 j=0; j< wd->getWearableCount((LLWearableType::EType)type); j++)
+		{
+			LLViewerWearable *wearable = gAgentWearables.getViewerWearable((LLWearableType::EType)type,j);
+			apr_file_printf( file, "\n\t    <wearable type=\"%s\" name=\"%s\"/>\n",
+							 type_name.c_str(), wearable->getName().c_str() );
+			LLWearable::visual_param_vec_t v_params;
+			wearable->getVisualParams(v_params);
+			for (LLWearable::visual_param_vec_t::iterator it = v_params.begin();
+				 it != v_params.end(); ++it)
+			{
+				LLVisualParam *param = *it;
+				dump_visual_param(file, param, param->getWeight());
+			}
+		}
+	}
+	apr_file_printf( file, "\n</wearable_info>\n" );
+}
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index 7bd0c0bf93428af3743a90d030b4dab725f577d4..3b7b6bac64a07ed801ef9aa9b4f5905cc687ff02 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -67,9 +67,8 @@ class LLVOAvatarSelf :
 protected:
 	/*virtual*/ BOOL		loadAvatar();
 	BOOL					loadAvatarSelf();
-	BOOL					buildSkeletonSelf(const LLVOAvatarSkeletonInfo *info);
+	BOOL					buildSkeletonSelf(const LLAvatarSkeletonInfo *info);
 	BOOL					buildMenus();
-	/*virtual*/ BOOL		loadLayersets();
 
 /**                    Initialization
  **                                                                            **
@@ -97,7 +96,7 @@ class LLVOAvatarSelf :
 	
 				void		resetJointPositions( void );
 	
-	/*virtual*/ BOOL setVisualParamWeight(LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
+	/*virtual*/ BOOL setVisualParamWeight(const LLVisualParam *which_param, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ BOOL setVisualParamWeight(const char* param_name, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ BOOL setVisualParamWeight(S32 index, F32 weight, BOOL upload_bake = FALSE );
 	/*virtual*/ void updateVisualParams();
@@ -111,7 +110,7 @@ class LLVOAvatarSelf :
 
 private:
 	// helper function. Passed in param is assumed to be in avatar's parameter list.
-	BOOL setParamWeight(LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
+	BOOL setParamWeight(const LLViewerVisualParam *param, F32 weight, BOOL upload_bake = FALSE );
 
 
 
@@ -131,6 +130,7 @@ class LLVOAvatarSelf :
 
 public:
 	/*virtual*/ bool 	isSelf() const { return true; }
+	/*virtual*/ BOOL	isValid() const;
 
 	//--------------------------------------------------------------------
 	// Updates
@@ -177,8 +177,8 @@ class LLVOAvatarSelf :
 	// LLVOAvatar Constants
 	//--------------------------------------------------------------------
 public:
-	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_SELF; }
-	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLViewerTexture::BOOST_AVATAR_BAKED_SELF; }
+	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBoostLevel() const { return LLGLTexture::BOOST_AVATAR_SELF; }
+	/*virtual*/ LLViewerTexture::EBoostLevel 	getAvatarBakedBoostLevel() const { return LLGLTexture::BOOST_AVATAR_BAKED_SELF; }
 	/*virtual*/ S32 						getTexImageSize() const { return LLVOAvatar::getTexImageSize()*4; }
 
 /**                    Rendering
@@ -195,32 +195,32 @@ class LLVOAvatarSelf :
 	//--------------------------------------------------------------------
 public:
 	/*virtual*/ bool	hasPendingBakedUploads() const;
-	S32					getLocalDiscardLevel(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+	S32					getLocalDiscardLevel(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
 	bool				areTexturesCurrent() const;
-	BOOL				isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
-	BOOL				isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
-	BOOL				isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const;
+	BOOL				isLocalTextureDataAvailable(const LLViewerTexLayerSet* layerset) const;
+	BOOL				isLocalTextureDataFinal(const LLViewerTexLayerSet* layerset) const;
+	BOOL				isBakedTextureFinal(const LLAvatarAppearanceDefines::EBakedTextureIndex index) const;
 	// If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index
-	/*virtual*/ BOOL    isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
-	/*virtual*/ BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
-	/*virtual*/ BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, LLWearable *wearable) const;
+	/*virtual*/ BOOL    isTextureDefined(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+	/*virtual*/ BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, U32 index = 0) const;
+	/*virtual*/ BOOL	isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerWearable *wearable) const;
 
 
 	//--------------------------------------------------------------------
 	// Local Textures
 	//--------------------------------------------------------------------
 public:
-	BOOL				getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
-	LLViewerFetchedTexture*	getLocalTextureGL(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
-	const LLUUID&		getLocalTextureID(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
+	BOOL				getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture** image_gl_pp, U32 index) const;
+	LLViewerFetchedTexture*	getLocalTextureGL(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
+	const LLUUID&		getLocalTextureID(LLAvatarAppearanceDefines::ETextureIndex type, U32 index) const;
 	void				setLocalTextureTE(U8 te, LLViewerTexture* image, U32 index);
-	/*virtual*/ void	setLocalTexture(LLVOAvatarDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
+	/*virtual*/ void	setLocalTexture(LLAvatarAppearanceDefines::ETextureIndex type, LLViewerTexture* tex, BOOL baked_version_exits, U32 index);
 protected:
-	/*virtual*/ void	setBakedReady(LLVOAvatarDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
+	/*virtual*/ void	setBakedReady(LLAvatarAppearanceDefines::ETextureIndex type, BOOL baked_version_exists, U32 index);
 	void				localTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 	void				getLocalTextureByteCount(S32* gl_byte_count) const;
-	/*virtual*/ void	addLocalTextureStats(LLVOAvatarDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked, U32 index);
-	LLLocalTextureObject* getLocalTextureObject(LLVOAvatarDefines::ETextureIndex i, U32 index) const;
+	/*virtual*/ void	addLocalTextureStats(LLAvatarAppearanceDefines::ETextureIndex i, LLViewerFetchedTexture* imagep, F32 texel_area_ratio, BOOL rendered, BOOL covered_by_baked);
+	LLLocalTextureObject* getLocalTextureObject(LLAvatarAppearanceDefines::ETextureIndex i, U32 index) const;
 
 private:
 	static void			onLocalTextureLoaded(BOOL succcess, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
@@ -233,13 +233,12 @@ class LLVOAvatarSelf :
 	// Baked textures
 	//--------------------------------------------------------------------
 public:
-	LLVOAvatarDefines::ETextureIndex getBakedTE(const LLTexLayerSet* layerset ) const;
-	void				setNewBakedTexture(LLVOAvatarDefines::EBakedTextureIndex i, const LLUUID &uuid);
-	void				setNewBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
-	void				setCachedBakedTexture(LLVOAvatarDefines::ETextureIndex i, const LLUUID& uuid);
+	LLAvatarAppearanceDefines::ETextureIndex getBakedTE(const LLViewerTexLayerSet* layerset ) const;
+	void				setNewBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex i, const LLUUID &uuid);
+	void				setNewBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
+	void				setCachedBakedTexture(LLAvatarAppearanceDefines::ETextureIndex i, const LLUUID& uuid);
 	void				forceBakeAllTextures(bool slam_for_debug = false);
 	static void			processRebakeAvatarTextures(LLMessageSystem* msg, void**);
-	BOOL				isUsingBakedTextures() const; // e.g. false if in appearance edit mode
 protected:
 	/*virtual*/ void	removeMissingBakedTextures();
 
@@ -248,10 +247,11 @@ class LLVOAvatarSelf :
 	//--------------------------------------------------------------------
 public:
 	void 				requestLayerSetUploads();
-	void				requestLayerSetUpload(LLVOAvatarDefines::EBakedTextureIndex i);
-	void				requestLayerSetUpdate(LLVOAvatarDefines::ETextureIndex i);
-	LLTexLayerSet*		getLayerSet(LLVOAvatarDefines::ETextureIndex index) const;
-	LLTexLayerSet* 		getLayerSet(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
+	void				requestLayerSetUpload(LLAvatarAppearanceDefines::EBakedTextureIndex i);
+	void				requestLayerSetUpdate(LLAvatarAppearanceDefines::ETextureIndex i);
+	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+	LLViewerTexLayerSet* getLayerSet(LLAvatarAppearanceDefines::ETextureIndex index) const;
+
 	
 	//--------------------------------------------------------------------
 	// Composites
@@ -265,8 +265,8 @@ class LLVOAvatarSelf :
 	void				setupComposites();
 	void				updateComposites();
 
-	const LLUUID&		grabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
-	BOOL				canGrabBakedTexture(LLVOAvatarDefines::EBakedTextureIndex baked_index) const;
+	const LLUUID&		grabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
+	BOOL				canGrabBakedTexture(LLAvatarAppearanceDefines::EBakedTextureIndex baked_index) const;
 
 
 	//--------------------------------------------------------------------
@@ -300,10 +300,9 @@ class LLVOAvatarSelf :
  **/
 
 public:
-	/*virtual*/ BOOL	isWearingWearableType(LLWearableType::EType type) const;
 	void				wearableUpdated(LLWearableType::EType type, BOOL upload_result);
 protected:
-	U32 getNumWearables(LLVOAvatarDefines::ETextureIndex i) const;
+	U32 getNumWearables(LLAvatarAppearanceDefines::ETextureIndex i) const;
 
 	//--------------------------------------------------------------------
 	// Attachments
@@ -340,8 +339,8 @@ class LLVOAvatarSelf :
  **/
 
 public:
-	static void		onCustomizeStart();
-	static void		onCustomizeEnd();
+	static void		onCustomizeStart(bool disable_camera_switch = false);
+	static void		onCustomizeEnd(bool disable_camera_switch = false);
 
 	//--------------------------------------------------------------------
 	// Visibility
@@ -365,6 +364,7 @@ class LLVOAvatarSelf :
 	static void		dumpTotalLocalTextureByteCount();
 	void			dumpLocalTextures() const;
 	static void		dumpScratchTextureByteCount();
+	void			dumpWearableInfo(LLAPRFile& outfile);
 
 	//--------------------------------------------------------------------
 	// Avatar Rez Metrics
@@ -372,34 +372,43 @@ class LLVOAvatarSelf :
 public:	
 	struct LLAvatarTexData
 	{
-		LLAvatarTexData(const LLUUID& id, LLVOAvatarDefines::ETextureIndex index) : 
+		LLAvatarTexData(const LLUUID& id, LLAvatarAppearanceDefines::ETextureIndex index) : 
 			mAvatarID(id), 
 			mIndex(index) 
 		{}
 		LLUUID			mAvatarID;
-		LLVOAvatarDefines::ETextureIndex	mIndex;
+		LLAvatarAppearanceDefines::ETextureIndex	mIndex;
 	};
+
+	LLTimer					mTimeSinceLastRezMessage;
+	bool					updateAvatarRezMetrics(bool force_send);
+
+	std::vector<LLSD>		mPendingTimerRecords;
+	void 					addMetricsTimerRecord(const LLSD& record);
+	
 	void 					debugWearablesLoaded() { mDebugTimeWearablesLoaded = mDebugSelfLoadTimer.getElapsedTimeF32(); }
 	void 					debugAvatarVisible() { mDebugTimeAvatarVisible = mDebugSelfLoadTimer.getElapsedTimeF32(); }
 	void 					outputRezDiagnostics() const;
 	void					outputRezTiming(const std::string& msg) const;
 	void					reportAvatarRezTime() const;
-	void 					debugBakedTextureUpload(LLVOAvatarDefines::EBakedTextureIndex index, BOOL finished);
+	void 					debugBakedTextureUpload(LLAvatarAppearanceDefines::EBakedTextureIndex index, BOOL finished);
 	static void				debugOnTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
 	BOOL					isAllLocalTextureDataFinal() const;
 
-	const LLTexLayerSet*  	debugGetLayerSet(LLVOAvatarDefines::EBakedTextureIndex index) const { return mBakedTextureDatas[index].mTexLayerSet; }
-	const std::string		debugDumpLocalTextureDataInfo(const LLTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+	const LLViewerTexLayerSet*	debugGetLayerSet(LLAvatarAppearanceDefines::EBakedTextureIndex index) const { return (LLViewerTexLayerSet*)(mBakedTextureDatas[index].mTexLayerSet); }
+	const std::string		verboseDebugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
+	void					dumpAllTextures() const;
+	const std::string		debugDumpLocalTextureDataInfo(const LLViewerTexLayerSet* layerset) const; // Lists out state of this particular baked texture layer
 	const std::string		debugDumpAllLocalTextureDataInfo() const; // Lists out which baked textures are at highest LOD
-	LLSD					metricsData();
-	void					sendAppearanceChangeMetrics(); // send data associated with completing a change.
+	void					sendViewerAppearanceChangeMetrics(); // send data associated with completing a change.
+	void 					checkForUnsupportedServerBakeAppearance();
 private:
 	LLFrameTimer    		mDebugSelfLoadTimer;
 	F32						mDebugTimeWearablesLoaded;
 	F32 					mDebugTimeAvatarVisible;
-	F32 					mDebugTextureLoadTimes[LLVOAvatarDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
-	F32 					mDebugBakedTextureTimes[LLVOAvatarDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
+	F32 					mDebugTextureLoadTimes[LLAvatarAppearanceDefines::TEX_NUM_INDICES][MAX_DISCARD_LEVEL+1]; // load time for each texture at each discard level
+	F32 					mDebugBakedTextureTimes[LLAvatarAppearanceDefines::BAKED_NUM_INDICES][2]; // time to start upload and finish upload of each baked texture
 	void					debugTimingLocalTexLoaded(BOOL success, LLViewerFetchedTexture *src_vi, LLImageRaw* src, LLImageRaw* aux_src, S32 discard_level, BOOL final, void* userdata);
 
 /**                    Diagnostics
@@ -413,8 +422,7 @@ extern LLPointer<LLVOAvatarSelf> gAgentAvatarp;
 BOOL isAgentAvatarValid();
 
 void selfStartPhase(const std::string& phase_name);
-void selfStopPhase(const std::string& phase_name);
-void selfStopAllPhases();
+void selfStopPhase(const std::string& phase_name, bool err_check = true);
 void selfClearPhases();
 
 #endif // LL_VO_AVATARSELF_H
diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp
index 4dca87652da8d7135ceadeb01acc6a0df8d579d7..6a25b765cf86a4c43492a086481a1d817040aea0 100644
--- a/indra/newview/llvograss.cpp
+++ b/indra/newview/llvograss.cpp
@@ -102,7 +102,7 @@ void LLVOGrass::updateSpecies()
 		SpeciesMap::const_iterator it = sSpeciesTable.begin();
 		mSpecies = (*it).first;
 	}
-	setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
+	setTEImage(0, LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE));
 }
 
 
diff --git a/indra/newview/llvoicechannel.cpp b/indra/newview/llvoicechannel.cpp
index bd12328a6bceaa950a3d1fda6d3ceb75b1d60eec..ac2a34ba1e90fdc399a0fd9278a394db58ca2c58 100644
--- a/indra/newview/llvoicechannel.cpp
+++ b/indra/newview/llvoicechannel.cpp
@@ -56,7 +56,8 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder
 public:
 	LLVoiceCallCapResponder(const LLUUID& session_id) : mSessionID(session_id) {};
 
-	virtual void error(U32 status, const std::string& reason);	// called with bad status codes
+	// called with bad status codes
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 
 private:
@@ -64,11 +65,10 @@ class LLVoiceCallCapResponder : public LLHTTPClient::Responder
 };
 
 
-void LLVoiceCallCapResponder::error(U32 status, const std::string& reason)
+void LLVoiceCallCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_WARNS("Voice") << "LLVoiceCallCapResponder::error("
-		<< status << ": " << reason << ")"
-		<< LL_ENDL;
+	LL_WARNS("Voice") << "LLVoiceCallCapResponder error [status:"
+		<< status << "]: " << content << LL_ENDL;
 	LLVoiceChannel* channelp = LLVoiceChannel::getChannelByID(mSessionID);
 	if ( channelp )
 	{
@@ -414,7 +414,7 @@ void LLVoiceChannel::doSetState(const EState& new_state)
 	mState = new_state;
 
 	if (!mStateChangedCallback.empty())
-		mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent);
+		mStateChangedCallback(old_state, mState, mCallDirection, mCallEndedByAgent, mSessionID);
 }
 
 //static
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index b8597ee5cb34007dac7f1dd5864dd86bd361b6e8..fed44974fdee8d60548b086ca0327e465f831bc7 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -52,7 +52,7 @@ class LLVoiceChannel : public LLVoiceClientStatusObserver
 		OUTGOING_CALL
 	} EDirection;
 
-	typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent)> state_changed_signal_t;
+	typedef boost::signals2::signal<void(const EState& old_state, const EState& new_state, const EDirection& direction, bool ended_by_agent, const LLUUID& session_id)> state_changed_signal_t;
 
 	// on current channel changed signal
 	typedef boost::function<void(const LLUUID& session_id)> channel_changed_callback_t;
diff --git a/indra/newview/llvoiceclient.cpp b/indra/newview/llvoiceclient.cpp
index 730f022c501e2dd6bb1eca6f0b9f3ee00911c5c4..b46c55321c691fe70a29c63dc92477900c1e5ecd 100644
--- a/indra/newview/llvoiceclient.cpp
+++ b/indra/newview/llvoiceclient.cpp
@@ -541,6 +541,7 @@ void LLVoiceClient::setMuteMic(bool muted)
 {
 	mMuteMic = muted;
 	updateMicMuteLogic();
+	mMicroChangedSignal();
 }
 
 
@@ -551,6 +552,7 @@ void LLVoiceClient::setUserPTTState(bool ptt)
 {
 	mUserPTTState = ptt;
 	updateMicMuteLogic();
+	mMicroChangedSignal();
 }
 
 bool LLVoiceClient::getUserPTTState()
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index c9aeea35a95c1ea234bfeb7dc47af424013b88d4..714dd6a9f27fa1b7d827e7e175b5cb29a55c93b7 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -303,6 +303,9 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 	LLVoiceClient();	
 	~LLVoiceClient();
 
+	typedef boost::signals2::signal<void(void)> micro_changed_signal_t;
+	micro_changed_signal_t mMicroChangedSignal;
+
 	void init(LLPumpIO *pump);	// Call this once at application startup (creates connector)
 	void terminate();	// Call this to clean up during shutdown
 	
@@ -401,6 +404,8 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 	void keyUp(KEY key, MASK mask);
 	void middleMouseState(bool down);
 	
+	boost::signals2::connection MicroChangedCallback(const micro_changed_signal_t::slot_type& cb ) { return mMicroChangedSignal.connect(cb); }
+
 	
 	/////////////////////////////
 	// Accessors for data related to nearby speakers
@@ -456,6 +461,7 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
 	LLVoiceModuleInterface* mVoiceModule;
 	LLPumpIO *m_servicePump;
 
+
 	LLCachedControl<bool> mVoiceEffectEnabled;
 	LLCachedControl<std::string> mVoiceEffectDefault;
 
diff --git a/indra/newview/llvoicevisualizer.cpp b/indra/newview/llvoicevisualizer.cpp
index 47060720e75f28fc8726aaa04f2f91198a5ac8bd..9281334d813146ad4e1738084fc27e65385e1d1a 100644
--- a/indra/newview/llvoicevisualizer.cpp
+++ b/indra/newview/llvoicevisualizer.cpp
@@ -73,17 +73,6 @@ const F32 DEFAULT_MAXIMUM_GESTICULATION_AMPLITUDE	= 1.0f;
 const F32 ONE_HALF = 1.0f; // to clarify intent and reduce magic numbers in the code. 
 const LLVector3 WORLD_UPWARD_DIRECTION = LLVector3( 0.0f, 0.0f, 1.0f ); // Z is up in SL
 
-
-//------------------------------------------------------------------
-// handles parameter updates
-//------------------------------------------------------------------
-static bool handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
-{
-	// Note: Ignore the specific event value, we look up the ones we want
-	LLVoiceVisualizer::setPreferences();
-	return true;
-}
-
 //------------------------------------------------------------------
 // Initialize the statics
 //------------------------------------------------------------------
@@ -106,7 +95,7 @@ F32	 LLVoiceVisualizer::sAahPowerTransfersf = 0.0f;
 // constructor
 //-----------------------------------------------
 LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
-:LLHUDEffect( type )
+	: LLHUDEffect(type)
 {
 	mCurrentTime					= mTimer.getTotalSeconds();
 	mPreviousTime					= mCurrentTime;
@@ -136,7 +125,7 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 	for (int i=0; i<NUM_VOICE_SYMBOL_WAVES; i++)
 	{
 		mSoundSymbol.mWaveFadeOutStartTime	[i] = mCurrentTime;
-		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FALSE, LLViewerTexture::BOOST_UI);
+		mSoundSymbol.mTexture				[i] = LLViewerTextureManager::getFetchedTextureFromFile(sound_level_img[i], FTT_LOCAL_FILE, FALSE, LLGLTexture::BOOST_UI);
 		mSoundSymbol.mWaveActive			[i] = false;
 		mSoundSymbol.mWaveOpacity			[i] = 1.0f;
 		mSoundSymbol.mWaveExpansion			[i] = 1.0f;
@@ -150,12 +139,12 @@ LLVoiceVisualizer::LLVoiceVisualizer( const U8 type )
 		setPreferences();
        
 		// Set up our listener to get updates on all prefs values we care about.
-		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
-		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncEnabled")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohAahRate")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOoh")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAah")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncOohPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
+		gSavedSettings.getControl("LipSyncAahPowerTransfer")->getSignal()->connect(boost::bind(&LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged, _2));
 		
 		sPrefsInitialized = true;
 	}
@@ -217,6 +206,15 @@ void LLVoiceVisualizer::setSpeakingAmplitude( F32 a )
 	
 }//---------------------------------------------------
 
+//------------------------------------------------------------------
+// handles parameter updates
+//------------------------------------------------------------------
+bool LLVoiceVisualizer::handleVoiceVisualizerPrefsChanged(const LLSD& newvalue)
+{
+	// Note: Ignore the specific event value, we look up the ones we want
+	LLVoiceVisualizer::setPreferences();
+	return true;
+}
 
 //---------------------------------------------------
 void LLVoiceVisualizer::setPreferences( )
@@ -526,10 +524,6 @@ void LLVoiceVisualizer::render()
 
 }//---------------------------------------------------
 
-
-
-
-
 //---------------------------------------------------
 void LLVoiceVisualizer::setVoiceSourceWorldPosition( const LLVector3 &p )
 {
@@ -615,11 +609,3 @@ void LLVoiceVisualizer::markDead()
 
 	LLHUDEffect::markDead();
 }//------------------------------------------------------------------
-
-
-
-
-
-
-
-
diff --git a/indra/newview/llvoicevisualizer.h b/indra/newview/llvoicevisualizer.h
index e434c7f3f1596424400c78da33e565ee430ffa14..36c78252d13556c5fc72a0904ee1d996b0bc271f 100644
--- a/indra/newview/llvoicevisualizer.h
+++ b/indra/newview/llvoicevisualizer.h
@@ -71,10 +71,8 @@ class LLVoiceVisualizer : public LLHUDEffect
 	// public methods 
 	//---------------------------------------------------
 	public:
-		LLVoiceVisualizer ( const U8 type );	//constructor
+		LLVoiceVisualizer( const U8 type );	//constructor
 		~LLVoiceVisualizer();					//destructor
-		
-		friend class LLHUDObject;
 
 		void					setVoiceSourceWorldPosition( const LLVector3 &p );		// this should be the position of the speaking avatar's head
 		void					setMinGesticulationAmplitude( F32 );					// the lower range of meaningful amplitude for setting gesticulation level 
@@ -85,8 +83,6 @@ class LLVoiceVisualizer : public LLHUDEffect
 		void					setStopSpeaking();										// tell me when the av stops speaking
 		bool					getCurrentlySpeaking();									// the get for the above set
 		VoiceGesticulationLevel	getCurrentGesticulationLevel();							// based on voice amplitude, I'll give you the current "energy level" of avatar speech
-		static void				setPreferences( );
-		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
 		void					lipSyncOohAah( F32& ooh, F32& aah );
 		void					render();												// inherited from HUD Effect
 		void 					packData(LLMessageSystem *mesgsys);						// inherited from HUD Effect
@@ -108,7 +104,10 @@ class LLVoiceVisualizer : public LLHUDEffect
 	// private members 
 	//---------------------------------------------------
 	private:
-	
+		static bool				handleVoiceVisualizerPrefsChanged(const LLSD& newvalue);
+		static void				setPreferences( );
+		static void				lipStringToF32s ( std::string& in_string, F32*& out_F32s, U32& count_F32s ); // convert a string of digits to an array of floats
+
 		struct SoundSymbol
 		{
 			F32						mWaveExpansion			[ NUM_VOICE_SYMBOL_WAVES ];
diff --git a/indra/newview/llvoicevivox.cpp b/indra/newview/llvoicevivox.cpp
index 820d1d73e149434cddde9f7f8bd9bc72b6baf63c..9b5d981aa5ccfc7cf5a62cfd119474a2bfdb5a96 100644
--- a/indra/newview/llvoicevivox.cpp
+++ b/indra/newview/llvoicevivox.cpp
@@ -34,6 +34,7 @@
 #include "llvoavatarself.h"
 #include "llbufferstream.h"
 #include "llfile.h"
+#include "llmenugl.h"
 #ifdef LL_STANDALONE
 # include "expat.h"
 #else
@@ -70,6 +71,9 @@
 
 #define USE_SESSION_GROUPS 0
 
+extern LLMenuBarGL* gMenuBarView;
+extern void handle_voice_morphing_subscribe();
+
 const F32 VOLUME_SCALE_VIVOX = 0.01f;
 
 const F32 SPEAKING_TIMEOUT = 1.f;
@@ -126,17 +130,18 @@ class LLVivoxVoiceAccountProvisionResponder :
 		mRetries = retries;
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
+		LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, "
+			<<  ( (mRetries > 0) ? "retrying" : "too many retries (giving up)" )
+			<< status << "]: " << content << LL_ENDL;
+
 		if ( mRetries > 0 )
 		{
-			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, retrying.  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
-			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(
-				mRetries - 1);
+			LLVivoxVoiceClient::getInstance()->requestVoiceAccountProvision(mRetries - 1);
 		}
 		else
 		{
-			LL_WARNS("Voice") << "ProvisionVoiceAccountRequest returned an error, too many retries (giving up).  status = " << status << ", reason = \"" << reason << "\"" << LL_ENDL;
 			LLVivoxVoiceClient::getInstance()->giveUp();
 		}
 	}
@@ -195,18 +200,18 @@ class LLVivoxVoiceClientCapResponder : public LLHTTPClient::Responder
 public:
 	LLVivoxVoiceClientCapResponder(LLVivoxVoiceClient::state requesting_state) : mRequestingState(requesting_state) {};
 
-	virtual void error(U32 status, const std::string& reason);	// called with bad status codes
+	// called with bad status codes
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 	virtual void result(const LLSD& content);
 
 private:
 	LLVivoxVoiceClient::state mRequestingState;  // state 
 };
 
-void LLVivoxVoiceClientCapResponder::error(U32 status, const std::string& reason)
+void LLVivoxVoiceClientCapResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder::error("
-		<< status << ": " << reason << ")"
-		<< LL_ENDL;
+	LL_WARNS("Voice") << "LLVivoxVoiceClientCapResponder error [status:"
+		<< status << "]: " << content << LL_ENDL;
 	LLVivoxVoiceClient::getInstance()->sessionTerminate();
 }
 
@@ -291,6 +296,7 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mCaptureDeviceDirty(false),
 	mRenderDeviceDirty(false),
 	mSpatialCoordsDirty(false),
+	mIsInitialized(false),
 
 	mMuteMic(false),
 	mMuteMicDirty(false),
@@ -315,7 +321,9 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 	mCaptureBufferRecording(false),
 	mCaptureBufferRecorded(false),
 	mCaptureBufferPlaying(false),
-	mPlayRequestCount(0)
+	mPlayRequestCount(0),
+
+	mAvatarNameCacheConnection()
 {	
 	mSpeakerVolume = scale_speaker_volume(0);
 
@@ -348,6 +356,10 @@ LLVivoxVoiceClient::LLVivoxVoiceClient() :
 
 LLVivoxVoiceClient::~LLVivoxVoiceClient()
 {
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
 }
 
 //---------------------------------------------------
@@ -520,7 +532,7 @@ void LLVivoxVoiceClient::requestVoiceAccountProvision(S32 retries)
 {
 	LLViewerRegion *region = gAgent.getRegion();
 	
-	if ( region && mVoiceEnabled )
+	if ( region && (mVoiceEnabled || !mIsInitialized))
 	{
 		std::string url = 
 		region->getCapability("ProvisionVoiceAccountRequest");
@@ -691,7 +703,7 @@ void LLVivoxVoiceClient::stateMachine()
 		setVoiceEnabled(false);
 	}
 	
-	if(mVoiceEnabled)
+	if(mVoiceEnabled || !mIsInitialized)
 	{
 		updatePosition();
 	}
@@ -736,7 +748,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateDisabled
 		case stateDisabled:
-			if(mTuningMode || (mVoiceEnabled && !mAccountName.empty()))
+			if(mTuningMode || ((mVoiceEnabled || !mIsInitialized) && !mAccountName.empty()))
 			{
 				setState(stateStart);
 			}
@@ -891,7 +903,7 @@ void LLVivoxVoiceClient::stateMachine()
 				mTuningExitState = stateIdle;
 				setState(stateMicTuningStart);
 			}
-			else if(!mVoiceEnabled)
+			else if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We never started up the connector.  This will shut down the daemon.
 				setState(stateConnectorStopped);
@@ -1085,7 +1097,7 @@ void LLVivoxVoiceClient::stateMachine()
 
 			//MARK: stateConnectorStart
 		case stateConnectorStart:
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We were never logged in.  This will shut down the connector.
 				setState(stateLoggedOut);
@@ -1103,7 +1115,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateConnectorStarted
 		case stateConnectorStarted:		// connector handle received
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// We were never logged in.  This will shut down the connector.
 				setState(stateLoggedOut);
@@ -1247,7 +1259,7 @@ void LLVivoxVoiceClient::stateMachine()
 		
 		//MARK: stateCreatingSessionGroup
 		case stateCreatingSessionGroup:
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
 			{
 				// *TODO: Question: is this the right way out of this state
 				setState(stateSessionTerminated);
@@ -1263,7 +1275,7 @@ void LLVivoxVoiceClient::stateMachine()
 		//MARK: stateRetrievingParcelVoiceInfo
 		case stateRetrievingParcelVoiceInfo: 
 			// wait until parcel voice info is received.
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
 			{
 				// if a terminate request has been received,
 				// bail and go to the stateSessionTerminated
@@ -1283,7 +1295,7 @@ void LLVivoxVoiceClient::stateMachine()
 			// Otherwise, if you log in but don't join a proximal channel (such as when your login location has voice disabled), your friends list won't sync.
 			sendFriendsListUpdates();
 			
-			if(mSessionTerminateRequested || !mVoiceEnabled)
+			if(mSessionTerminateRequested || (!mVoiceEnabled && mIsInitialized))
 			{
 				// TODO: Question: Is this the right way out of this state?
 				setState(stateSessionTerminated);
@@ -1364,7 +1376,7 @@ void LLVivoxVoiceClient::stateMachine()
 		    }
 			
 			// joinedAudioSession() will transition from here to stateSessionJoined.
-			if(!mVoiceEnabled)
+			if(!mVoiceEnabled && mIsInitialized)
 			{
 				// User bailed out during connect -- jump straight to teardown.
 				setState(stateSessionTerminated);
@@ -1411,7 +1423,7 @@ void LLVivoxVoiceClient::stateMachine()
 				notifyStatusObservers(LLVoiceClientStatusObserver::STATUS_JOINED);
 
 			}
-			else if(!mVoiceEnabled)
+			else if(!mVoiceEnabled && mIsInitialized)
 			{
 				// User bailed out during connect -- jump straight to teardown.
 				setState(stateSessionTerminated);
@@ -1431,7 +1443,7 @@ void LLVivoxVoiceClient::stateMachine()
 		//MARK: stateRunning
 		case stateRunning:				// steady state
 			// Disabling voice or disconnect requested.
-			if(!mVoiceEnabled || mSessionTerminateRequested)
+			if((!mVoiceEnabled && mIsInitialized) || mSessionTerminateRequested)
 			{
 				leaveAudioSession();
 			}
@@ -1478,6 +1490,8 @@ void LLVivoxVoiceClient::stateMachine()
 					mUpdateTimer.setTimerExpirySec(UPDATE_THROTTLE_SECONDS);
 					sendPositionalUpdate();
 				}
+
+				mIsInitialized = true;
 			}
 		break;
 		
@@ -1511,7 +1525,7 @@ void LLVivoxVoiceClient::stateMachine()
 			// Always reset the terminate request flag when we get here.
 			mSessionTerminateRequested = false;
 
-			if(mVoiceEnabled && !mRelogRequested)
+			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
 			{				
 				// Just leaving a channel, go back to stateNoChannel (the "logged in but have no channel" state).
 				setState(stateNoChannel);
@@ -1539,7 +1553,7 @@ void LLVivoxVoiceClient::stateMachine()
 			mAccountHandle.clear();
 			cleanUp();
 
-			if(mVoiceEnabled && !mRelogRequested)
+			if((mVoiceEnabled || !mIsInitialized) && !mRelogRequested)
 			{
 				// User was logged out, but wants to be logged in.  Send a new login request.
 				setState(stateNeedsLogin);
@@ -2236,7 +2250,8 @@ void LLVivoxVoiceClient::giveUp()
 
 static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVector3d &pos, LLVector3 &vel)
 {
-	F32 nat[3], nup[3], nl[3], nvel[3]; // the new at, up, left vectors and the  new position and velocity
+	F32 nat[3], nup[3], nl[3]; // the new at, up, left vectors and the  new position and velocity
+//	F32 nvel[3]; 
 	F64 npos[3];
 	
 	// The original XML command was sent like this:
@@ -2286,9 +2301,9 @@ static void oldSDKTransform (LLVector3 &left, LLVector3 &up, LLVector3 &at, LLVe
 	npos[1] = pos.mdV[VZ];
 	npos[2] = pos.mdV[VY];
 
-	nvel[0] = vel.mV[VX];
-	nvel[1] = vel.mV[VZ];
-	nvel[2] = vel.mV[VY];
+//	nvel[0] = vel.mV[VX];
+//	nvel[1] = vel.mV[VZ];
+//	nvel[2] = vel.mV[VY];
 
 	for(int i=0;i<3;++i) {
 		at.mV[i] = nat[i];
@@ -2658,33 +2673,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
 {
 	buddyListEntry *buddy = findBuddy(id);
 
-	// Make sure we don't add a name before it's been looked up.
+	// Make sure we don't add a name before it's been looked up in the avatar name cache
 	LLAvatarName av_name;
-	if(LLAvatarNameCache::get(id, &av_name))
+	if (LLAvatarNameCache::get(id, &av_name))
 	{
-		// *NOTE: For now, we feed legacy names to Vivox because I don't know
-		// if their service can support a mix of new and old clients with
-		// different sorts of names.
-		std::string name = av_name.getLegacyName();
-
-		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
-		bool canSeeMeOnline = false;
-		if(relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS))
-			canSeeMeOnline = true;
-		
-		// When we get here, mNeedsSend is true and mInSLFriends is false.  Change them as necessary.
+		// *NOTE: We feed legacy names to Vivox because we don't know if their service
+		// can support a mix of new and old clients with different sorts of names.
+		std::string name = av_name.getAccountName();
 		
-		if(buddy)
+		if (buddy)
 		{
-			// This buddy is already in both lists.
-
-			if(name != buddy->mDisplayName)
-			{
-				// The buddy is in the list with the wrong name.  Update it with the correct name.
-				LL_WARNS("Voice") << "Buddy " << id << " has wrong name (\"" << buddy->mDisplayName << "\" should be \"" << name << "\"), updating."<< LL_ENDL;
-				buddy->mDisplayName = name;
-				buddy->mNeedsNameUpdate = true;		// This will cause the buddy to be resent.
-			}
+			// This buddy is already in both lists (vivox buddies and avatar cache).
+            // Trust the avatar cache more for the display name (vivox display name are notoriously wrong)
+            buddy->mDisplayName = name;
 		}
 		else
 		{
@@ -2693,20 +2694,19 @@ void LLVivoxVoiceClient::checkFriend(const LLUUID& id)
 			buddy->mUUID = id;
 		}
 		
-		// In all the above cases, the buddy is in the SL friends list (which is how we got here).
-		buddy->mInSLFriends = true;
-		buddy->mCanSeeMeOnline = canSeeMeOnline;
+		const LLRelationship* relationInfo = LLAvatarTracker::instance().getBuddyInfo(id);
+		buddy->mCanSeeMeOnline = (relationInfo && relationInfo->isRightGrantedTo(LLRelationship::GRANT_ONLINE_STATUS));
+		// In all the above cases, the buddy is in the SL friends list and tha name has been resolved (which is how we got here).
 		buddy->mNameResolved = true;
-		
+		buddy->mInSLFriends = true;
 	}
 	else
 	{
-		// This name hasn't been looked up yet.  Don't do anything with this buddy list entry until it has.
-		if(buddy)
+		// This name hasn't been looked up yet in the avatar cache. Don't do anything with this buddy list entry until it has.
+		if (buddy)
 		{
 			buddy->mNameResolved = false;
 		}
-		
 		// Initiate a lookup.
 		// The "lookup completed" callback will ensure that the friends list is rechecked after it completes.
 		lookupName(id);
@@ -2814,13 +2814,12 @@ void LLVivoxVoiceClient::sendFriendsListUpdates()
 			{
 				std::ostringstream stream;
 
-				if(buddy->mInSLFriends && (!buddy->mInVivoxBuddies || buddy->mNeedsNameUpdate))
+				if(buddy->mInSLFriends && !buddy->mInVivoxBuddies)
 				{					
 					if(mNumberOfAliases > 0)
 					{
 						// Add (or update) this entry in the vivox buddy list
 						buddy->mInVivoxBuddies = true;
-						buddy->mNeedsNameUpdate = false;
 						LL_DEBUGS("Voice") << "add/update " << buddy->mURI << " (" << buddy->mDisplayName << ")" << LL_ENDL;
 						stream 
 							<< "<Request requestId=\"" << mCommandCookie++ << "\" action=\"Account.BuddySet.1\">"
@@ -3712,8 +3711,7 @@ void LLVivoxVoiceClient::participantUpdatedEvent(
 			 voice participant mIsModeratorMuted is changed after speakers are updated in Speaker Manager                                          
 			 and event is not fired.                                                                                                               
 			 
-			 So, we have to call LLSpeakerMgr::update() here. In any case it is better than call it                                                
-			 in LLCallFloater::draw()                                                                                                              
+			 So, we have to call LLSpeakerMgr::update() here.                                                                                                              
 			 */
 			LLVoiceChannel* voice_cnl = LLVoiceChannel::getCurrentVoiceChannel();
 			
@@ -3939,10 +3937,9 @@ void LLVivoxVoiceClient::messageEvent(
 		sessionState *session = findSession(sessionHandle);
 		if(session)
 		{
-			bool is_busy = gAgent.getBusy();
+			bool is_do_not_disturb = gAgent.isDoNotDisturb();
 			bool is_muted = LLMuteList::getInstance()->isMuted(session->mCallerID, session->mName, LLMute::flagTextChat);
 			bool is_linden = LLMuteList::getInstance()->isLinden(session->mName);
-			bool quiet_chat = false;
 			LLChat chat;
 
 			chat.mMuted = is_muted && !is_linden;
@@ -3953,10 +3950,9 @@ void LLVivoxVoiceClient::messageEvent(
 				chat.mFromName = session->mName;
 				chat.mSourceType = CHAT_SOURCE_AGENT;
 
-				if(is_busy && !is_linden)
+				if(is_do_not_disturb && !is_linden)
 				{
-					quiet_chat = true;
-					// TODO: Question: Return busy mode response here?  Or maybe when session is started instead?
+					// TODO: Question: Return do not disturb mode response here?  Or maybe when session is started instead?
 				}
 				
 				LL_DEBUGS("Voice") << "adding message, name " << session->mName << " session " << session->mIMSessionID << ", target " << session->mCallerID << LL_ENDL;
@@ -3964,6 +3960,7 @@ void LLVivoxVoiceClient::messageEvent(
 						session->mCallerID,
 						session->mName.c_str(),
 						message.c_str(),
+						false,
 						LLStringUtil::null,		// default arg
 						IM_NOTHING_SPECIAL,		// default arg
 						0,						// default arg
@@ -5846,7 +5843,6 @@ LLVivoxVoiceClient::buddyListEntry::buddyListEntry(const std::string &uri) :
 	mNameResolved = false;
 	mInVivoxBuddies = false;
 	mInSLFriends = false;
-	mNeedsNameUpdate = false;
 }
 
 void LLVivoxVoiceClient::processBuddyListEntry(const std::string &uri, const std::string &displayName)
@@ -5871,25 +5867,21 @@ LLVivoxVoiceClient::buddyListEntry *LLVivoxVoiceClient::addBuddy(const std::stri
 	buddyListEntry *result = NULL;
 	buddyListMap::iterator iter = mBuddyListMap.find(uri);
 	
-	if(iter != mBuddyListMap.end())
+	if (iter != mBuddyListMap.end())
 	{
 		// Found a matching buddy already in the map.
 		LL_DEBUGS("Voice") << "adding existing buddy " << uri << LL_ENDL;
 		result = iter->second;
 	}
 
-	if(!result)
+	if (!result)
 	{
 		// participant isn't already in one list or the other.
 		LL_DEBUGS("Voice") << "adding new buddy " << uri << LL_ENDL;
 		result = new buddyListEntry(uri);
 		result->mDisplayName = displayName;
 
-		if(IDFromName(uri, result->mUUID)) 
-		{
-			// Extracted UUID from name successfully.
-		}
-		else
+		if (!IDFromName(uri, result->mUUID))
 		{
 			LL_DEBUGS("Voice") << "Couldn't find ID for buddy " << uri << " (\"" << displayName << "\")" << LL_ENDL;
 		}
@@ -6189,18 +6181,19 @@ void LLVivoxVoiceClient::notifyFriendObservers()
 
 void LLVivoxVoiceClient::lookupName(const LLUUID &id)
 {
-	LLAvatarNameCache::get(id,
-		boost::bind(&LLVivoxVoiceClient::onAvatarNameCache,
-			this, _1, _2));
+	if (mAvatarNameCacheConnection.connected())
+	{
+		mAvatarNameCacheConnection.disconnect();
+	}
+	mAvatarNameCacheConnection = LLAvatarNameCache::get(id, boost::bind(&LLVivoxVoiceClient::onAvatarNameCache, this, _1, _2));
 }
 
 void LLVivoxVoiceClient::onAvatarNameCache(const LLUUID& agent_id,
 										   const LLAvatarName& av_name)
 {
-	// For Vivox, we use the legacy name because I'm uncertain whether or
-	// not their service can tolerate switching to Username or Display Name
-	std::string legacy_name = av_name.getLegacyName();
-	avatarNameResolved(agent_id, legacy_name);	
+	mAvatarNameCacheConnection.disconnect();
+	std::string display_name = av_name.getDisplayName();
+	avatarNameResolved(agent_id, display_name);
 }
 
 void LLVivoxVoiceClient::avatarNameResolved(const LLUUID &id, const std::string &name)
@@ -6729,10 +6722,106 @@ void LLVivoxVoiceClient::removeObserver(LLVoiceEffectObserver* observer)
 	mVoiceFontObservers.erase(observer);
 }
 
+// method checks the item in VoiceMorphing menu for appropriate current voice font
+bool LLVivoxVoiceClient::onCheckVoiceEffect(const std::string& voice_effect_name)
+{
+	LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+	if (NULL != effect_interfacep)
+	{
+		const LLUUID& currect_voice_effect_id = effect_interfacep->getVoiceEffect();
+
+		if (currect_voice_effect_id.isNull())
+		{
+			if (voice_effect_name == "NoVoiceMorphing")
+			{
+				return true;
+			}
+		}
+		else
+		{
+			const LLSD& voice_effect_props = effect_interfacep->getVoiceEffectProperties(currect_voice_effect_id);
+			if (voice_effect_props["name"].asString() == voice_effect_name)
+			{
+				return true;
+			}
+		}
+	}
+
+	return false;
+}
+
+// method changes voice font for selected VoiceMorphing menu item
+void LLVivoxVoiceClient::onClickVoiceEffect(const std::string& voice_effect_name)
+{
+	LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+	if (NULL != effect_interfacep)
+	{
+		if (voice_effect_name == "NoVoiceMorphing")
+		{
+			effect_interfacep->setVoiceEffect(LLUUID());
+			return;
+		}
+		const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+		if (!effect_list.empty())
+		{
+			for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+			{
+				if (voice_effect_name == it->first)
+				{
+					effect_interfacep->setVoiceEffect(it->second);
+					return;
+				}
+			}
+		}
+	}
+}
+
+// it updates VoiceMorphing menu items in accordance with purchased properties 
+void LLVivoxVoiceClient::updateVoiceMorphingMenu()
+{
+	if (mVoiceFontListDirty)
+	{
+		LLVoiceEffectInterface * effect_interfacep = LLVoiceClient::instance().getVoiceEffectInterface();
+		if (effect_interfacep)
+		{
+			const voice_effect_list_t& effect_list = effect_interfacep->getVoiceEffectList();
+			if (!effect_list.empty())
+			{
+				LLMenuGL * voice_morphing_menup = gMenuBarView->findChildMenuByName("VoiceMorphing", TRUE);
+
+				if (NULL != voice_morphing_menup)
+				{
+					S32 items = voice_morphing_menup->getItemCount();
+					if (items > 0)
+					{
+						voice_morphing_menup->erase(1, items - 3, false);
+
+						S32 pos = 1;
+						for (voice_effect_list_t::const_iterator it = effect_list.begin(); it != effect_list.end(); ++it)
+						{
+							LLMenuItemCheckGL::Params p;
+							p.name = it->first;
+							p.label = it->first;
+							p.on_check.function(boost::bind(&LLVivoxVoiceClient::onCheckVoiceEffect, this, it->first));
+							p.on_click.function(boost::bind(&LLVivoxVoiceClient::onClickVoiceEffect, this, it->first));
+							LLMenuItemCheckGL * voice_effect_itemp = LLUICtrlFactory::create<LLMenuItemCheckGL>(p);
+							voice_morphing_menup->insert(pos++, voice_effect_itemp, false);
+						}
+
+						voice_morphing_menup->needsArrange();
+					}
+				}
+			}
+		}
+	}
+}
+
 void LLVivoxVoiceClient::notifyVoiceFontObservers()
 {
 	LL_DEBUGS("Voice") << "Notifying voice effect observers. Lists changed: " << mVoiceFontListDirty << LL_ENDL;
 
+	updateVoiceMorphingMenu();
+
 	for (voice_font_observer_set_t::iterator it = mVoiceFontObservers.begin();
 		 it != mVoiceFontObservers.end();
 		 )
@@ -7162,7 +7251,7 @@ void LLVivoxProtocolParser::StartTag(const char *tag, const char **attr)
 void LLVivoxProtocolParser::EndTag(const char *tag)
 {
 	const std::string& string = textBuffer;
-	
+
 	responseDepth--;
 	
 	if (ignoringTags)
@@ -7261,6 +7350,8 @@ void LLVivoxProtocolParser::EndTag(const char *tag)
 		}
 		else if (!stricmp("Buddy", tag))
 		{
+            // NOTE : Vivox does *not* give reliable display name for Buddy tags
+            // We don't take those very seriously as a result...
 			LLVivoxVoiceClient::getInstance()->processBuddyListEntry(uriString, displayNameString);
 		}
 		else if (!stricmp("BlockRule", tag))
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index 1142a1a49c7583a281eea990da63f136090ee030..a6f40eb3e99d8e2adca4c5d08dd147a2a2cb8b4d 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -246,6 +246,8 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 
 	//@}
 
+	bool onCheckVoiceEffect(const std::string& voice_effect_name);
+	void onClickVoiceEffect(const std::string& voice_effect_name);
 
 protected:
 	//////////////////////
@@ -582,7 +584,6 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 		bool mNameResolved;
 		bool mInSLFriends;
 		bool mInVivoxBuddies;
-		bool mNeedsNameUpdate;
 	};
 
 	typedef std::map<std::string, buddyListEntry*> buddyListMap;
@@ -641,6 +642,7 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	void lookupName(const LLUUID &id);
 	void onAvatarNameCache(const LLUUID& id, const LLAvatarName& av_name);
 	void avatarNameResolved(const LLUUID &id, const std::string &name);
+	boost::signals2::connection mAvatarNameCacheConnection;
 
 	/////////////////////////////
 	// Voice fonts
@@ -741,6 +743,8 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	std::string mRenderDevice;
 	bool mCaptureDeviceDirty;
 	bool mRenderDeviceDirty;
+
+	bool mIsInitialized;
 	
 	
 	bool checkParcelChanged(bool update = false);
@@ -851,6 +855,7 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 	void accountGetTemplateFontsSendMessage();
 	void sessionSetVoiceFontSendMessage(sessionState *session);
 
+	void updateVoiceMorphingMenu();
 	void notifyVoiceFontObservers();
 
 	typedef enum e_voice_font_type
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index fa34a6f1f56d5558bc86e22cb202b097e0006116..0b34bbb90f6cb44429a6cc727490c388c5de1799 100644
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -152,8 +152,8 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end)
 void LLVOPartGroup::freeVBSlot(S32 idx)
 {
 	llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0);
-	llassert(sVBSlotCursor > sVBSlotFree);
-	llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
+	//llassert(sVBSlotCursor > sVBSlotFree);
+	//llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT));
 
 	if (sVBSlotCursor > sVBSlotFree)
 	{
diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp
index 31358df85fc082e5bc9c660489d80a93251374ff..36793017ed903e96c0f8b65e20b784df6bf35a5f 100644
--- a/indra/newview/llvosky.cpp
+++ b/indra/newview/llvosky.cpp
@@ -298,7 +298,7 @@ void LLSkyTex::create(const F32 brightness)
 
 void LLSkyTex::createGLImage(S32 which)
 {	
-	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLViewerTexture::LOCAL);
+	mTexture[which]->createGLTexture(0, mImageRaw[which], 0, TRUE, LLGLTexture::LOCAL);
 	mTexture[which]->setAddressMode(LLTexUnit::TAM_CLAMP);
 }
 
@@ -384,9 +384,9 @@ LLVOSky::LLVOSky(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp)
 	mSun.setIntensity(SUN_INTENSITY);
 	mMoon.setIntensity(0.1f * SUN_INTENSITY);
 
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
@@ -478,9 +478,9 @@ void LLVOSky::restoreGL()
 	{
 		mSkyTex[i].restoreGL();
 	}
-	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mSunTexturep = LLViewerTextureManager::getFetchedTexture(gSunTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mSunTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
-	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, TRUE, LLViewerTexture::BOOST_UI);
+	mMoonTexturep = LLViewerTextureManager::getFetchedTexture(gMoonTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_UI);
 	mMoonTexturep->setAddressMode(LLTexUnit::TAM_CLAMP);
 	mBloomTexturep = LLViewerTextureManager::getFetchedTexture(IMG_BLOOM1);
 	mBloomTexturep->setNoDelete() ;
diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp
index cb905d02da0dd458f2490b45a7490e749943a73f..de15f0ef43f68cfeabc30996e9a4ac14f689bd77 100644
--- a/indra/newview/llvosurfacepatch.cpp
+++ b/indra/newview/llvosurfacepatch.cpp
@@ -467,7 +467,7 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	S32 vertex_count = 0;
 	S32 i, x, y;
 
-	S32 num_vertices, num_indices;
+	S32 num_vertices;
 
 	U32 render_stride = mLastStride;
 	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -485,7 +485,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	if (north_stride == render_stride)
 	{
 		num_vertices = 2 * length + 1;
-		num_indices = length * 6 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -536,7 +535,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 	{
 		// North stride is longer (has less vertices)
 		num_vertices = length + length/2 + 1;
-		num_indices = half_length*9 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -595,7 +593,6 @@ void LLVOSurfacePatch::updateNorthGeometry(LLFace *facep,
 		length = patch_size / north_stride;
 		half_length = length / 2;
 		num_vertices = length + half_length + 1;
-		num_indices = 9*half_length - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
 
@@ -666,7 +663,7 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 {
 	S32 i, x, y;
 
-	S32 num_vertices, num_indices;
+	S32 num_vertices;
 
 	U32 render_stride = mLastStride;
 	S32 patch_size = mPatchp->getSurface()->getGridsPerPatchEdge();
@@ -679,7 +676,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 	if (east_stride == render_stride)
 	{
 		num_vertices = 2 * length + 1;
-		num_indices = length * 6 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(8, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -728,7 +724,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 	{
 		// East stride is longer (has less vertices)
 		num_vertices = length + half_length + 1;
-		num_indices = half_length*9 - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(7, 15) + mPatchp->getPointAgent(8, 16))*0.5f;
 
@@ -783,7 +778,6 @@ void LLVOSurfacePatch::updateEastGeometry(LLFace *facep,
 		length = patch_size / east_stride;
 		half_length = length / 2;
 		num_vertices = length + length/2 + 1;
-		num_indices = 9*(length/2) - 3;
 
 		facep->mCenterAgent = (mPatchp->getPointAgent(15, 7) + mPatchp->getPointAgent(16, 8))*0.5f;
 
diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp
index 6687ce432fadaade4b53250b167e49d369312cf5..145a0380d6891d611e7e3494251a627fce71c76d 100644
--- a/indra/newview/llvotree.cpp
+++ b/indra/newview/llvotree.cpp
@@ -316,7 +316,7 @@ U32 LLVOTree::processUpdateMessage(LLMessageSystem *mesgsys,
 	//  Load Species-Specific data 
 	//
 	static const S32 MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL = 32 ; //frames.
-	mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	mTreeImagep = LLViewerTextureManager::getFetchedTexture(sSpeciesTable[mSpecies]->mTextureID, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 	mTreeImagep->setMaxVirtualSizeResetInterval(MAX_TREE_TEXTURE_VIRTURE_SIZE_RESET_INTERVAL); //allow to wait for at most 16 frames to reset virtual size.
 
 	mBranchLength = sSpeciesTable[mSpecies]->mBranchLength;
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index d94cd01a0b793c182b97d7ea95c6b973960da868..8730ef66bbaa503fcbbc7ed00efac0bf5edbed03 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -370,7 +370,7 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys,
 		// Unpack texture entry data
 		//
 
-		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, block_num);
+		S32 result = unpackTEMessage(mesgsys, _PREHASH_ObjectData, (S32) block_num);
 		if (result & teDirtyBits)
 		{
 			updateTEData();
@@ -747,7 +747,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 		{
 			F32 area = (F32) camera->getScreenPixelArea();
 			vsize = area;
-			imagep->setBoostLevel(LLViewerTexture::BOOST_HUD);
+			imagep->setBoostLevel(LLGLTexture::BOOST_HUD);
  			face->setPixelArea(area); // treat as full screen
 			face->setVirtualSize(vsize);
 		}
@@ -803,7 +803,7 @@ void LLVOVolume::updateTextureVirtualSize(bool forced)
 		if (mSculptTexture.notNull())
 		{
 			mSculptTexture->setBoostLevel(llmax((S32)mSculptTexture->getBoostLevel(),
-												(S32)LLViewerTexture::BOOST_SCULPTED));
+												(S32)LLGLTexture::BOOST_SCULPTED));
 			mSculptTexture->setForSculpt() ;
 			
 			if(!mSculptTexture->isCachedRawImageReady())
@@ -1006,7 +1006,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams &params_in, const S32 detail, bo
 	
 	if (is404)
 	{
-		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", TRUE, LLViewerTexture::BOOST_UI));
+		setIcon(LLViewerTextureManager::getFetchedTextureFromFile("icons/Inv_Mesh.png", FTT_LOCAL_FILE, TRUE, LLGLTexture::BOOST_UI));
 		//render prim proxy when mesh loading attempts give up
 		volume_params.setSculptID(LLUUID::null, LL_SCULPT_TYPE_NONE);
 
@@ -1090,7 +1090,7 @@ void LLVOVolume::updateSculptTexture()
 		LLUUID id =  sculpt_params->getSculptTexture();
 		if (id.notNull())
 		{
-			mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+			mSculptTexture = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
 		}
 	}
 	else
@@ -2743,7 +2743,7 @@ void LLVOVolume::updateSpotLightPriority()
 	if (mLightTexture.notNull())
 	{
 		mLightTexture->addTextureStats(mSpotLightPriority);
-		mLightTexture->setBoostLevel(LLViewerTexture::BOOST_CLOUDS);
+		mLightTexture->setBoostLevel(LLGLTexture::BOOST_CLOUDS);
 	}
 }
 
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 7f17fd3e5626efe95d9a38314b70cbe6ecdb3607..4e265871848befe736aa18b897751deeba71e994 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -724,8 +724,8 @@ void LLVOWLSky::updateStarColors()
 
 	const F32 var = 0.15f;
 	const F32 min = 0.5f; //0.75f;
-	const F32 sunclose_max = 0.6f;
-	const F32 sunclose_range = 1 - sunclose_max;
+	//const F32 sunclose_max = 0.6f;
+	//const F32 sunclose_range = 1 - sunclose_max;
 
 	//F32 below_horizon = - llmin(0.0f, gSky.mVOSkyp->getToSunLast().mV[2]);
 	//F32 brightness_factor = llmin(1.0f, below_horizon * 20);
@@ -739,14 +739,14 @@ void LLVOWLSky::updateStarColors()
 		U32 x;
 		for (x = 0; x < getStarsNumVerts(); ++x)
 		{
-			F32 sundir_factor = 1;
+			//F32 sundir_factor = 1;
 			LLVector3 tostar = *v_p;
 			tostar.normVec();
-			const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
-			if (how_close_to_sun > sunclose_max)
-			{
-				sundir_factor = (1 - how_close_to_sun) / sunclose_range;
-			}
+			//const F32 how_close_to_sun = tostar * gSky.mVOSkyp->getToSunLast();
+			//if (how_close_to_sun > sunclose_max)
+			//{
+			//	sundir_factor = (1 - how_close_to_sun) / sunclose_range;
+			//}
 			intensity = *(v_i);
 			F32 alpha = v_c->mV[VALPHA] + (ll_frand() - 0.5f) * var * intensity;
 			if (alpha < min * intensity)
diff --git a/indra/newview/llwaterparamset.cpp b/indra/newview/llwaterparamset.cpp
index 39d366b0238f00f99b087c13686188411d61d3ed..9cc91d2246ac2f3ee6021e5cb27e3c0840c24ef0 100644
--- a/indra/newview/llwaterparamset.cpp
+++ b/indra/newview/llwaterparamset.cpp
@@ -185,8 +185,6 @@ LLVector3 LLWaterParamSet::getVector3(const std::string& paramName, bool& error)
 LLVector2 LLWaterParamSet::getVector2(const std::string& paramName, bool& error) 
 {
 	// test to see if right type
-	int ttest;
-	ttest = mParamValues.size();
 	LLSD cur_val = mParamValues.get(paramName);
 	if (!cur_val.isArray() || cur_val.size() != 2) 
 	{
diff --git a/indra/newview/llwearable.cpp b/indra/newview/llwearable.cpp
deleted file mode 100644
index 402504933cd9e3ea8e4e5fdb5ccb5da7f94cceeb..0000000000000000000000000000000000000000
--- a/indra/newview/llwearable.cpp
+++ /dev/null
@@ -1,1285 +0,0 @@
-/** 
- * @file llwearable.cpp
- * @brief LLWearable class implementation
- *
- * $LicenseInfo:firstyear=2002&license=viewerlgpl$
- * Second Life Viewer Source Code
- * Copyright (C) 2010, Linden Research, Inc.
- * 
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation;
- * version 2.1 of the License only.
- * 
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- * 
- * You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- * 
- * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
- * $/LicenseInfo$
- */
-
-#include "llviewerprecompiledheaders.h"
-
-#include "llagent.h"
-#include "llagentcamera.h"
-#include "llagentwearables.h"
-#include "lldictionary.h"
-#include "llfloatersidepanelcontainer.h"
-#include "lllocaltextureobject.h"
-#include "llnotificationsutil.h"
-#include "llviewertexturelist.h"
-#include "llinventorymodel.h"
-#include "llinventoryobserver.h"
-#include "llsidepanelappearance.h"
-#include "lltexlayer.h"
-#include "lltexglobalcolor.h"
-#include "lltrans.h"
-#include "llviewerregion.h"
-#include "llvisualparam.h"
-#include "llvoavatar.h"
-#include "llvoavatarself.h"
-#include "llvoavatardefines.h"
-#include "llwearable.h"
-#include "llviewercontrol.h"
-
-using namespace LLVOAvatarDefines;
-
-// static
-S32 LLWearable::sCurrentDefinitionVersion = 1;
-
-// support class - remove for 2.1 (hackity hack hack)
-class LLOverrideBakedTextureUpdate
-{
-public:
-	LLOverrideBakedTextureUpdate(bool temp_state)
-	{
-		U32 num_bakes = (U32) LLVOAvatarDefines::BAKED_NUM_INDICES;
-		for( U32 index = 0; index < num_bakes; ++index )
-		{
-			composite_enabled[index] = gAgentAvatarp->isCompositeUpdateEnabled(index);
-		}
-		gAgentAvatarp->setCompositeUpdatesEnabled(temp_state);
-	}
-
-	~LLOverrideBakedTextureUpdate()
-	{
-		U32 num_bakes = (U32)LLVOAvatarDefines::BAKED_NUM_INDICES;		
-		for( U32 index = 0; index < num_bakes; ++index )
-		{
-			gAgentAvatarp->setCompositeUpdatesEnabled(index, composite_enabled[index]);
-		}
-	}
-private:
-	bool composite_enabled[LLVOAvatarDefines::BAKED_NUM_INDICES];
-};
-
-// Private local functions
-static std::string terse_F32_to_string(F32 f);
-static std::string asset_id_to_filename(const LLUUID &asset_id);
-
-LLWearable::LLWearable(const LLTransactionID& transaction_id) :
-	mDefinitionVersion(LLWearable::sCurrentDefinitionVersion),
-	mType(LLWearableType::WT_INVALID)
-{
-	mTransactionID = transaction_id;
-	mAssetID = mTransactionID.makeAssetID(gAgent.getSecureSessionID());
-}
-
-LLWearable::LLWearable(const LLAssetID& asset_id) :
-	mDefinitionVersion( LLWearable::sCurrentDefinitionVersion ),
-	mType(LLWearableType::WT_INVALID)
-{
-	mAssetID = asset_id;
-	mTransactionID.setNull();
-}
-
-LLWearable::~LLWearable()
-{
-}
-
-const std::string& LLWearable::getTypeLabel() const
-{
-	return LLWearableType::getTypeLabel(mType);
-}
-
-const std::string& LLWearable::getTypeName() const
-{
-	return LLWearableType::getTypeName(mType);
-}
-
-LLAssetType::EType LLWearable::getAssetType() const
-{
-	return LLWearableType::getAssetType(mType);
-}
-
-BOOL LLWearable::exportFile(LLFILE* file) const
-{
-	// header and version
-	if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// name
-	if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// description
-	if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-	
-	// permissions
-	if( !mPermissions.exportFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// sale info
-	if( !mSaleInfo.exportFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// wearable type
-	S32 type = (S32)mType;
-	if( fprintf( file, "type %d\n", type ) < 0 )
-	{
-		return FALSE;
-	}
-
-	// parameters
-	S32 num_parameters = mVisualParamIndexMap.size();
-	if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
-	{
-		return FALSE;
-	}
-
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
-		 iter != mVisualParamIndexMap.end(); 
-		 ++iter)
-	{
-		S32 param_id = iter->first;
-		const LLVisualParam* param = iter->second;
-		F32 param_weight = param->getWeight();
-		if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
-		{
-			return FALSE;
-		}
-	}
-
-	// texture entries
-	S32 num_textures = mTEMap.size();
-	if( fprintf( file, "textures %d\n", num_textures ) < 0 )
-	{
-		return FALSE;
-	}
-	
-	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
-	{
-		S32 te = iter->first;
-		const LLUUID& image_id = iter->second->getID();
-		if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
-		{
-			return FALSE;
-		}
-	}
-	return TRUE;
-}
-
-
-void LLWearable::createVisualParams()
-{
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		 param;
-		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
-	{
-		if (param->getWearableType() == mType)
-		{
-			addVisualParam(param->cloneParam(this));
-		}
-	}
-
-	// resync driver parameters to point to the newly cloned driven parameters
-	for (visual_param_index_map_t::iterator param_iter = mVisualParamIndexMap.begin(); 
-		 param_iter != mVisualParamIndexMap.end(); 
-		 ++param_iter)
-	{
-		LLVisualParam* param = param_iter->second;
-		LLVisualParam*(LLWearable::*wearable_function)(S32)const = &LLWearable::getVisualParam; 
-		// need this line to disambiguate between versions of LLCharacter::getVisualParam()
-		LLVisualParam*(LLVOAvatarSelf::*avatar_function)(S32)const = &LLVOAvatarSelf::getVisualParam; 
-		param->resetDrivenParams();
-		if(!param->linkDrivenParams(boost::bind(wearable_function,(LLWearable*)this, _1), false))
-		{
-			if( !param->linkDrivenParams(boost::bind(avatar_function,gAgentAvatarp.get(),_1 ), true))
-			{
-				llwarns << "could not link driven params for wearable " << getName() << " id: " << param->getID() << llendl;
-				continue;
-			}
-		}
-	}
-}
-
-BOOL LLWearable::importFile( LLFILE* file )
-{
-	// *NOTE: changing the type or size of this buffer will require
-	// changes in the fscanf() code below. You would be better off
-	// rewriting this to use streams and not require an open FILE.
-	char text_buffer[2048];		/* Flawfinder: ignore */
-	S32 fields_read = 0;
-
-	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
-	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
-	LLOverrideBakedTextureUpdate stop_bakes(false);
-
-	// read header and version 
-	fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
-	if( fields_read != 1 )
-	{
-		// Shouldn't really log the asset id for security reasons, but
-		// we need it in this case.
-		llwarns << "Bad Wearable asset header: " << mAssetID << llendl;
-		//gVFS->dumpMap();
-		return FALSE;
-	}
-
-
-	// Temoprary hack to allow wearables with definition version 24 to still load.
-	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
-	// the extra check for version == 24 can be removed before release, once internal testers
-	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
-	// these wearables get re-saved with version definition 22.
-	if( mDefinitionVersion > LLWearable::sCurrentDefinitionVersion && mDefinitionVersion != 24 )
-	{
-		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
-		return FALSE;
-	}
-
-	// name
-	int next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no name
-		mName = "";
-	}
-	else
-	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer);
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return FALSE;
-		}
-		mName = text_buffer;
-		LLStringUtil::truncate(mName, DB_INV_ITEM_NAME_STR_LEN );
-	}
-
-	// description
-	next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no description
-		mDescription = "";
-	}
-	else
-	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer );
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return FALSE;
-		}
-		mDescription = text_buffer;
-		LLStringUtil::truncate(mDescription, DB_INV_ITEM_DESC_STR_LEN );
-	}
-
-	// permissions
-	S32 perm_version;
-	fields_read = fscanf( file, " permissions %d\n", &perm_version );
-	if( (fields_read != 1) || (perm_version != 0) )
-	{
-		llwarns << "Bad Wearable asset: missing permissions" << llendl;
-		return FALSE;
-	}
-	if( !mPermissions.importFile( file ) )
-	{
-		return FALSE;
-	}
-
-	// sale info
-	S32 sale_info_version;
-	fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
-	if( (fields_read != 1) || (sale_info_version != 0) )
-	{
-		llwarns << "Bad Wearable asset: missing sale_info" << llendl;
-		return FALSE;
-	}
-	// Sale info used to contain next owner perm. It is now in the
-	// permissions. Thus, we read that out, and fix legacy
-	// objects. It's possible this op would fail, but it should pick
-	// up the vast majority of the tasks.
-	BOOL has_perm_mask = FALSE;
-	U32 perm_mask = 0;
-	if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
-	{
-		return FALSE;
-	}
-	if(has_perm_mask)
-	{
-		// fair use fix.
-		if(!(perm_mask & PERM_COPY))
-		{
-			perm_mask |= PERM_TRANSFER;
-		}
-		mPermissions.setMaskNext(perm_mask);
-	}
-
-	// wearable type
-	S32 type = -1;
-	fields_read = fscanf( file, "type %d\n", &type );
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: bad type" << llendl;
-		return FALSE;
-	}
-	if( 0 <= type && type < LLWearableType::WT_COUNT )
-	{
-		setType((LLWearableType::EType)type);
-	}
-	else
-	{
-		mType = LLWearableType::WT_COUNT;
-		llwarns << "Bad Wearable asset: bad type #" << type <<  llendl;
-		return FALSE;
-	}
-
-	// parameters header
-	S32 num_parameters = 0;
-	fields_read = fscanf( file, "parameters %d\n", &num_parameters );
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
-		return FALSE;
-	}
-
-	if( num_parameters != mVisualParamIndexMap.size() )
-	{
-		llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " <<  mType << llendl;
-	}
-
-	// parameters
-	S32 i;
-	for( i = 0; i < num_parameters; i++ )
-	{
-		S32 param_id = 0;
-		F32 param_weight = 0.f;
-		fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
-		if( fields_read != 2 )
-		{
-			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
-			return FALSE;
-		}
-		mSavedVisualParamMap[param_id] = param_weight;
-	}
-
-	// textures header
-	S32 num_textures = 0;
-	fields_read = fscanf( file, "textures %d\n", &num_textures);
-	if( fields_read != 1 )
-	{
-		llwarns << "Bad Wearable asset: missing textures block" << llendl;
-		return FALSE;
-	}
-
-	// textures
-	for( i = 0; i < num_textures; i++ )
-	{
-		S32 te = 0;
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%d %2047s\n",
-			&te, text_buffer);
-		if( fields_read != 2 )
-		{
-			llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
-			return FALSE;
-		}
-
-		if( !LLUUID::validate( text_buffer ) )
-		{
-			llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
-			return FALSE;
-		}
-		LLUUID id = LLUUID(text_buffer);
-		LLViewerFetchedTexture* image = LLViewerTextureManager::getFetchedTexture( id );
-		if( mTEMap.find(te) != mTEMap.end() )
-		{
-			delete mTEMap[te];
-		}
-		if( mSavedTEMap.find(te) != mSavedTEMap.end() )
-		{
-			delete mSavedTEMap[te];
-		}
-
-		if(gSavedSettings.getBOOL("DebugAvatarLocalTexLoadedTime"))
-		{
-			image->setLoadedCallback(LLVOAvatarSelf::debugOnTimingLocalTexLoaded,0,TRUE,FALSE, new LLVOAvatarSelf::LLAvatarTexData(id, (LLVOAvatarDefines::ETextureIndex)te), NULL);
-		}
-		LLUUID textureid(text_buffer);
-		mTEMap[te] = new LLLocalTextureObject(image, textureid);
-		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
-		createLayers(te);
-	}
-
-	// copy all saved param values to working params
-	revertValues();
-
-	return TRUE;
-}
-
-
-// Avatar parameter and texture definitions can change over time.
-// This function returns true if parameters or textures have been added or removed
-// since this wearable was created.
-BOOL LLWearable::isOldVersion() const
-{
-	if (!isAgentAvatarValid()) return FALSE;
-
-	if( LLWearable::sCurrentDefinitionVersion < mDefinitionVersion )
-	{
-		llwarns << "Wearable asset has newer version (" << mDefinitionVersion << ") than XML (" << LLWearable::sCurrentDefinitionVersion << ")" << llendl;
-		llassert(0);
-	}
-
-	if( LLWearable::sCurrentDefinitionVersion != mDefinitionVersion )
-	{
-		return TRUE;
-	}
-
-	S32 param_count = 0;
-	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) && (param->isTweakable() ) )
-		{
-			param_count++;
-			if( !is_in_map(mVisualParamIndexMap, param->getID() ) )
-			{
-				return TRUE;
-			}
-		}
-	}
-	if( param_count != mVisualParamIndexMap.size() )
-	{
-		return TRUE;
-	}
-
-
-	S32 te_count = 0;
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_count++;
-			if( !is_in_map(mTEMap, te ) )
-			{
-				return TRUE;
-			}
-		}
-	}
-	if( te_count != mTEMap.size() )
-	{
-		return TRUE;
-	}
-
-	return FALSE;
-}
-
-// Avatar parameter and texture definitions can change over time.
-// * If parameters or textures have been REMOVED since the wearable was created,
-// they're just ignored, so we consider the wearable clean even though isOldVersion()
-// will return true. 
-// * If parameters or textures have been ADDED since the wearable was created,
-// they are taken to have default values, so we consider the wearable clean
-// only if those values are the same as the defaults.
-BOOL LLWearable::isDirty() const
-{
-	if (!isAgentAvatarValid()) return FALSE;
-
-	for( LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) 
-			&& (param->isTweakable() ) 
-			&& !param->getCrossWearable())
-		{
-			F32 current_weight = getVisualParamWeight(param->getID());
-			current_weight = llclamp( current_weight, param->getMinWeight(), param->getMaxWeight() );
-			F32 saved_weight = get_if_there(mSavedVisualParamMap, param->getID(), param->getDefaultWeight());
-			saved_weight = llclamp( saved_weight, param->getMinWeight(), param->getMaxWeight() );
-			
-			U8 a = F32_to_U8( saved_weight, param->getMinWeight(), param->getMaxWeight() );
-			U8 b = F32_to_U8( current_weight, param->getMinWeight(), param->getMaxWeight() );
-			if( a != b  )
-			{
-				return TRUE;
-			}
-		}
-	}
-
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator current_iter = mTEMap.find(te);
-			if(current_iter != mTEMap.end())
-			{
- 				const LLUUID& current_image_id = current_iter->second->getID();
-				te_map_t::const_iterator saved_iter = mSavedTEMap.find(te);
-				if(saved_iter != mSavedTEMap.end())
-				{
-					const LLUUID& saved_image_id = saved_iter->second->getID();
-					if (saved_image_id != current_image_id)
-					{
-						// saved vs current images are different, wearable is dirty
-						return TRUE;
-					}
-				}
-				else
-				{
-					// image found in current image list but not saved image list
-					return TRUE;
-				}
-			}
-		}
-	}
-
-	return FALSE;
-}
-
-
-void LLWearable::setParamsToDefaults()
-{
-	if (!isAgentAvatarValid()) return;
-
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (((LLViewerVisualParam*)param)->getWearableType() == mType ) && (param->isTweakable() ) )
-		{
-			setVisualParamWeight(param->getID(),param->getDefaultWeight(), FALSE);
-		}
-	}
-}
-
-void LLWearable::setTexturesToDefaults()
-{
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			LLUUID id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-			LLViewerFetchedTexture * image = LLViewerTextureManager::getFetchedTexture( id );
-			if( mTEMap.find(te) == mTEMap.end() )
-			{
-				mTEMap[te] = new LLLocalTextureObject(image, id);
-				createLayers(te);
-			}
-			else
-			{
-				// Local Texture Object already created, just set image and UUID
-				LLLocalTextureObject *lto = mTEMap[te];
-				lto->setID(id);
-				lto->setImage(image);
-			}
-		}
-	}
-}
-
-// Updates the user's avatar's appearance
-void LLWearable::writeToAvatar()
-{
-	if (!isAgentAvatarValid()) return;
-
-	ESex old_sex = gAgentAvatarp->getSex();
-
-	// Pull params
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		// cross-wearable parameters are not authoritative, as they are driven by a different wearable. So don't copy the values to the
-		// avatar object if cross wearable. Cross wearable params get their values from the avatar, they shouldn't write the other way.
-		if( (((LLViewerVisualParam*)param)->getWearableType() == mType) && (!((LLViewerVisualParam*)param)->getCrossWearable()) )
-		{
-			S32 param_id = param->getID();
-			F32 weight = getVisualParamWeight(param_id);
-
-			gAgentAvatarp->setVisualParamWeight( param_id, weight, FALSE );
-		}
-	}
-
-	// Pull texture entries
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = mTEMap.find(te);
-			LLUUID image_id;
-			if(iter != mTEMap.end())
-			{
-				image_id = iter->second->getID();
-			}
-			else
-			{	
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-			}
-			LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture( image_id, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE );
-			// MULTI-WEARABLE: assume index 0 will be used when writing to avatar. TODO: eliminate the need for this.
-			gAgentAvatarp->setLocalTextureTE(te, image, 0);
-		}
-	}
-
-	ESex new_sex = gAgentAvatarp->getSex();
-	if( old_sex != new_sex )
-	{
-		gAgentAvatarp->updateSexDependentLayerSets( FALSE );
-	}	
-	
-//	if( upload_bake )
-//	{
-//		gAgent.sendAgentSetAppearance();
-//	}
-}
-
-
-// Updates the user's avatar's appearance, replacing this wearables' parameters and textures with default values.
-// static 
-void LLWearable::removeFromAvatar( LLWearableType::EType type, BOOL upload_bake )
-{
-	if (!isAgentAvatarValid()) return;
-
-	// You can't just remove body parts.
-	if( (type == LLWearableType::WT_SHAPE) ||
-		(type == LLWearableType::WT_SKIN) ||
-		(type == LLWearableType::WT_HAIR) ||
-		(type == LLWearableType::WT_EYES) )
-	{
-		return;
-	}
-
-	// Pull params
-	for( LLVisualParam* param = gAgentAvatarp->getFirstVisualParam(); param; param = gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (((LLViewerVisualParam*)param)->getWearableType() == type) && (param->isTweakable() ) )
-		{
-			S32 param_id = param->getID();
-			gAgentAvatarp->setVisualParamWeight( param_id, param->getDefaultWeight(), upload_bake );
-		}
-	}
-
-	if(gAgentCamera.cameraCustomizeAvatar())
-	{
-		LLFloaterSidePanelContainer::showPanel("appearance", LLSD().with("type", "edit_outfit"));
-	}
-
-	gAgentAvatarp->updateVisualParams();
-	gAgentAvatarp->wearableUpdated(type, FALSE);
-
-//	if( upload_bake )
-//	{
-//		gAgent.sendAgentSetAppearance();
-//	}
-}
-
-// Does not copy mAssetID.
-// Definition version is current: removes obsolete enties and creates default values for new ones.
-void LLWearable::copyDataFrom(const LLWearable* src)
-{
-	if (!isAgentAvatarValid()) return;
-
-	mDefinitionVersion = LLWearable::sCurrentDefinitionVersion;
-
-	mName = src->mName;
-	mDescription = src->mDescription;
-	mPermissions = src->mPermissions;
-	mSaleInfo = src->mSaleInfo;
-
-	setType(src->mType);
-
-	mSavedVisualParamMap.clear();
-	// Deep copy of mVisualParamMap (copies only those params that are current, filling in defaults where needed)
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		param;
-		param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam() )
-	{
-		if( (param->getWearableType() == mType) )
-		{
-			S32 id = param->getID();
-			F32 weight = src->getVisualParamWeight(id);
-			mSavedVisualParamMap[id] = weight;
-		}
-	}
-
-	destroyTextures();
-	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
-	for (S32 te = 0; te < TEX_NUM_INDICES; te++)
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = src->mTEMap.find(te);
-			LLUUID image_id;
-			LLViewerFetchedTexture *image = NULL;
-			if(iter != src->mTEMap.end())
-			{
-				image = src->getLocalTextureObject(te)->getImage();
-				image_id = src->getLocalTextureObject(te)->getID();
-				mTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mTEMap[te]->setBakedReady(src->getLocalTextureObject(te)->getBakedReady());
-				mTEMap[te]->setDiscard(src->getLocalTextureObject(te)->getDiscard());
-			}
-			else
-			{
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-				image = LLViewerTextureManager::getFetchedTexture( image_id );
-				mTEMap[te] = new LLLocalTextureObject(image, image_id);
-				mSavedTEMap[te] = new LLLocalTextureObject(image, image_id);
-			}
-			createLayers(te);
-		}
-	}
-
-	// Probably reduntant, but ensure that the newly created wearable is not dirty by setting current value of params in new wearable
-	// to be the same as the saved values (which were loaded from src at param->cloneParam(this))
-	revertValues();
-}
-
-void LLWearable::setItemID(const LLUUID& item_id)
-{
-	mItemID = item_id;
-}
-
-const LLUUID& LLWearable::getItemID() const
-{
-	return mItemID;
-}
-
-void LLWearable::setType(LLWearableType::EType type) 
-{ 
-	mType = type; 
-	createVisualParams();
-}
-
-LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
-{
-	te_map_t::iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
-{
-	te_map_t::const_iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		const LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
-{
-	std::vector<LLLocalTextureObject*> result;
-
-	for(te_map_t::const_iterator iter = mTEMap.begin();
-		iter != mTEMap.end(); iter++)
-	{
-		LLLocalTextureObject* lto = iter->second;
-		result.push_back(lto);
-	}
-
-	return result;
-}
-
-void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
-{
-	if( mTEMap.find(index) != mTEMap.end() )
-	{
-		mTEMap.erase(index);
-	}
-	mTEMap[index] = new LLLocalTextureObject(lto);
-}
-
-
-void LLWearable::addVisualParam(LLVisualParam *param)
-{
-	if( mVisualParamIndexMap[param->getID()] )
-	{
-		delete mVisualParamIndexMap[param->getID()];
-	}
-	param->setIsDummy(FALSE);
-	mVisualParamIndexMap[param->getID()] = param;
-	mSavedVisualParamMap[param->getID()] = param->getDefaultWeight();
-}
-
-void LLWearable::setVisualParams()
-{
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
-	}
-}
-
-
-void LLWearable::setVisualParamWeight(S32 param_index, F32 value, BOOL upload_bake)
-{
-	if( is_in_map(mVisualParamIndexMap, param_index ) )
-	{
-		LLVisualParam *wearable_param = mVisualParamIndexMap[param_index];
-		wearable_param->setWeight(value, upload_bake);
-	}
-	else
-	{
-		llerrs << "LLWearable::setVisualParam passed invalid parameter index: " << param_index << " for wearable type: " << this->getName() << llendl;
-	}
-}
-
-F32 LLWearable::getVisualParamWeight(S32 param_index) const
-{
-	if( is_in_map(mVisualParamIndexMap, param_index ) )
-	{
-		const LLVisualParam *wearable_param = mVisualParamIndexMap.find(param_index)->second;
-		return wearable_param->getWeight();
-	}
-	else
-	{
-		llwarns << "LLWerable::getVisualParam passed invalid parameter index: "  << param_index << " for wearable type: " << this->getName() << llendl;
-	}
-	return (F32)-1.0;
-}
-
-LLVisualParam* LLWearable::getVisualParam(S32 index) const
-{
-	visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.find(index);
-	return (iter == mVisualParamIndexMap.end()) ? NULL : iter->second;
-}
-
-
-void LLWearable::getVisualParams(visual_param_vec_t &list)
-{
-	visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
-	visual_param_index_map_t::iterator end = mVisualParamIndexMap.end();
-
-	// add all visual params to the passed-in vector
-	for( ; iter != end; ++iter )
-	{
-		list.push_back(iter->second);
-	}
-}
-
-void LLWearable::animateParams(F32 delta, BOOL upload_bake)
-{
-	for(visual_param_index_map_t::iterator iter = mVisualParamIndexMap.begin();
-		 iter != mVisualParamIndexMap.end();
-		 ++iter)
-	{
-		LLVisualParam *param = (LLVisualParam*) iter->second;
-		param->animate(delta, upload_bake);
-	}
-}
-
-LLColor4 LLWearable::getClothesColor(S32 te) const
-{
-	LLColor4 color;
-	U32 param_name[3];
-	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
-	{
-		for( U8 index = 0; index < 3; index++ )
-		{
-			color.mV[index] = getVisualParamWeight(param_name[index]);
-		}
-	}
-	return color;
-}
-
-void LLWearable::setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake )
-{
-	U32 param_name[3];
-	if( LLVOAvatar::teToColorParams( (LLVOAvatarDefines::ETextureIndex)te, param_name ) )
-	{
-		for( U8 index = 0; index < 3; index++ )
-		{
-			setVisualParamWeight(param_name[index], new_color.mV[index], upload_bake);
-		}
-	}
-}
-
-void LLWearable::revertValues()
-{
-	//update saved settings so wearable is no longer dirty
-	// non-driver params first
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	//then driver params
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	// make sure that saved values are sane
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *param = getVisualParam(id);
-		if( param )
-		{
-			mSavedVisualParamMap[id] = param->getWeight();
-		}
-	}
-
-	syncImages(mSavedTEMap, mTEMap);
-
-
-	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-	if( panel )
-	{
-		panel->updateScrollingPanelList();
-	}
-}
-
-BOOL LLWearable::isOnTop() const
-{ 
-	return (this == gAgentWearables.getTopWearable(mType));
-}
-
-void LLWearable::createLayers(S32 te)
-{
-	LLTexLayerSet *layer_set = gAgentAvatarp->getLayerSet((ETextureIndex)te);
-	if (layer_set)
-	{
-		layer_set->cloneTemplates(mTEMap[te], (ETextureIndex)te, this);
-	}
-	else
-	{
-		llerrs << "could not find layerset for LTO in wearable!" << llendl;
-	}
-}
-
-void LLWearable::saveValues()
-{
-	//update saved settings so wearable is no longer dirty
-	mSavedVisualParamMap.clear();
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		mSavedVisualParamMap[id] = value;
-	}
-
-	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
-	syncImages(mTEMap, mSavedTEMap);
-
-
-	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
-	if( panel )
-	{
-		panel->updateScrollingPanelList();
-	}
-}
-
-void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
-{
-	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLVOAvatarDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = src.find(te);
-			LLUUID image_id;
-			LLViewerFetchedTexture *image = NULL;
-			LLLocalTextureObject *lto = NULL;
-			if(iter != src.end())
-			{
-				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
-				lto = iter->second;
-				image = lto->getImage();
-				image_id = lto->getID();
-			}
-			else
-			{
-				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
-				image_id = LLVOAvatarDictionary::getDefaultTextureImageID((ETextureIndex) te);
-				image = LLViewerTextureManager::getFetchedTexture( image_id );
-			}
-
-			if( dst.find(te) != dst.end() )
-			{
-				// there's already an entry in the destination map for the texture. Just update its values.
-				dst[te]->setImage(image);
-				dst[te]->setID(image_id);
-			}
-			else
-			{
-				// no entry found in the destination map, we need to create a new Local Texture Object
-				dst[te] = new LLLocalTextureObject(image, image_id);
-			}
-
-			if( lto )
-			{
-				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
-				dst[te]->setBakedReady(lto->getBakedReady());
-				dst[te]->setDiscard(lto->getDiscard());
-			}
-		}
-	}
-}
-
-void LLWearable::destroyTextures()
-{
-	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mTEMap.clear();
-	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mSavedTEMap.clear();
-}
-
-void LLWearable::pullCrossWearableValues()
-{
-	// scan through all of the avatar's visual parameters
-	for (LLViewerVisualParam* param = (LLViewerVisualParam*) gAgentAvatarp->getFirstVisualParam(); 
-		 param;
-		 param = (LLViewerVisualParam*) gAgentAvatarp->getNextVisualParam())
-	{
-		if( param )
-		{
-			LLDriverParam *driver_param = dynamic_cast<LLDriverParam*>(param);
-			if(driver_param)
-			{
-				// parameter is a driver parameter, have it update its 
-				driver_param->updateCrossDrivenParams(getType());
-			}
-		}
-	}
-}
-
-
-void LLWearable::setLabelUpdated() const
-{ 
-	gInventory.addChangedMask(LLInventoryObserver::LABEL, getItemID());
-}
-
-void LLWearable::refreshName()
-{
-	LLUUID item_id = getItemID();
-	LLInventoryItem* item = gInventory.getItem(item_id);
-	if( item )
-	{
-		mName = item->getName();
-	}
-}
-
-struct LLWearableSaveData
-{
-	LLWearableType::EType mType;
-};
-
-void LLWearable::saveNewAsset() const
-{
-//	llinfos << "LLWearable::saveNewAsset() type: " << getTypeName() << llendl;
-	//llinfos << *this << llendl;
-
-	const std::string filename = asset_id_to_filename(mAssetID);
-	LLFILE* fp = LLFile::fopen(filename, "wb");		/* Flawfinder: ignore */
-	BOOL successful_save = FALSE;
-	if(fp && exportFile(fp))
-	{
-		successful_save = TRUE;
-	}
-	if(fp)
-	{
-		fclose(fp);
-		fp = NULL;
-	}
-	if(!successful_save)
-	{
-		std::string buffer = llformat("Unable to save '%s' to wearable file.", mName.c_str());
-		llwarns << buffer << llendl;
-		
-		LLSD args;
-		args["NAME"] = mName;
-		LLNotificationsUtil::add("CannotSaveWearableOutOfSpace", args);
-		return;
-	}
-
-	// save it out to database
-	if( gAssetStorage )
-	{
-		 /*
-		std::string url = gAgent.getRegion()->getCapability("NewAgentInventory");
-		if (!url.empty())
-		{
-			llinfos << "Update Agent Inventory via capability" << llendl;
-			LLSD body;
-			body["folder_id"] = gInventory.findCategoryUUIDForType(LLFolderType::assetToFolderType(getAssetType()));
-			body["asset_type"] = LLAssetType::lookup(getAssetType());
-			body["inventory_type"] = LLInventoryType::lookup(LLInventoryType::IT_WEARABLE);
-			body["name"] = getName();
-			body["description"] = getDescription();
-			LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, filename));
-		}
-		else
-		{
-		}
-		 */
-		 LLWearableSaveData* data = new LLWearableSaveData;
-		 data->mType = mType;
-		 gAssetStorage->storeAssetData(filename, mTransactionID, getAssetType(),
-                                     &LLWearable::onSaveNewAssetComplete,
-                                     (void*)data);
-	}
-}
-
-// static
-void LLWearable::onSaveNewAssetComplete(const LLUUID& new_asset_id, void* userdata, S32 status, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
-	LLWearableSaveData* data = (LLWearableSaveData*)userdata;
-	const std::string& type_name = LLWearableType::getTypeName(data->mType);
-	if(0 == status)
-	{
-		// Success
-		llinfos << "Saved wearable " << type_name << llendl;
-	}
-	else
-	{
-		std::string buffer = llformat("Unable to save %s to central asset store.", type_name.c_str());
-		llwarns << buffer << " Status: " << status << llendl;
-		LLSD args;
-		args["NAME"] = type_name;
-		LLNotificationsUtil::add("CannotSaveToAssetStore", args);
-	}
-
-	// Delete temp file
-	const std::string src_filename = asset_id_to_filename(new_asset_id);
-	LLFile::remove(src_filename);
-
-	// delete the context data
-	delete data;
-
-}
-
-std::ostream& operator<<(std::ostream &s, const LLWearable &w)
-{
-	s << "wearable " << LLWearableType::getTypeName(w.mType) << "\n";
-	s << "    Name: " << w.mName << "\n";
-	s << "    Desc: " << w.mDescription << "\n";
-	//w.mPermissions
-	//w.mSaleInfo
-
-	s << "    Params:" << "\n";
-	for (LLWearable::visual_param_index_map_t::const_iterator iter = w.mVisualParamIndexMap.begin();
-		 iter != w.mVisualParamIndexMap.end(); ++iter)
-	{
-		S32 param_id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 param_weight = wearable_param->getWeight();
-		s << "        " << param_id << " " << param_weight << "\n";
-	}
-
-	s << "    Textures:" << "\n";
-	for (LLWearable::te_map_t::const_iterator iter = w.mTEMap.begin();
-		 iter != w.mTEMap.end(); ++iter)
-	{
-		S32 te = iter->first;
-		const LLUUID& image_id = iter->second->getID();
-		s << "        " << te << " " << image_id << "\n";
-	}
-	return s;
-}
-
-
-std::string terse_F32_to_string(F32 f)
-{
-	std::string r = llformat("%.2f", f);
-	S32 len = r.length();
-
-    // "1.20"  -> "1.2"
-    // "24.00" -> "24."
-	while (len > 0 && ('0' == r[len - 1]))
-	{
-		r.erase(len-1, 1);
-		len--;
-	}
-	if ('.' == r[len - 1])
-	{
-		// "24." -> "24"
-		r.erase(len-1, 1);
-	}
-	else if (('-' == r[0]) && ('0' == r[1]))
-	{
-		// "-0.59" -> "-.59"
-		r.erase(1, 1);
-	}
-	else if ('0' == r[0])
-	{
-		// "0.59" -> ".59"
-		r.erase(0, 1);
-	}
-	return r;
-}
-
-std::string asset_id_to_filename(const LLUUID &asset_id)
-{
-	std::string asset_id_string;
-	asset_id.toString(asset_id_string);
-	std::string filename = gDirUtilp->getExpandedFilename(LL_PATH_CACHE,asset_id_string) + ".wbl";	
-	return filename;
-}
diff --git a/indra/newview/llwearableitemslist.cpp b/indra/newview/llwearableitemslist.cpp
index 92697fb2eb8334b4023801342cb168dd25d6b103..c196d70617d7d69aade31e05ea392cd6b3afbc3b 100644
--- a/indra/newview/llwearableitemslist.cpp
+++ b/indra/newview/llwearableitemslist.cpp
@@ -34,6 +34,7 @@
 #include "llagentwearables.h"
 #include "llappearancemgr.h"
 #include "llinventoryfunctions.h"
+#include "llinventoryicon.h"
 #include "lltransutil.h"
 #include "llviewerattachmenu.h"
 #include "llvoavatarself.h"
@@ -788,23 +789,24 @@ LLContextMenu* LLWearableItemsList::ContextMenu::createMenu()
 	const uuid_vec_t& ids = mUUIDs;		// selected items IDs
 	LLUUID selected_id = ids.front();	// ID of the first selected item
 
-	functor_t take_off = boost::bind(&LLAppearanceMgr::removeItemFromAvatar, LLAppearanceMgr::getInstance(), _1);
-
 	// Register handlers common for all wearable types.
 	registrar.add("Wearable.Wear", boost::bind(wear_multiple, ids, true));
 	registrar.add("Wearable.Add", boost::bind(wear_multiple, ids, false));
 	registrar.add("Wearable.Edit", boost::bind(handleMultiple, LLAgentWearables::editWearable, ids));
 	registrar.add("Wearable.CreateNew", boost::bind(createNewWearable, selected_id));
 	registrar.add("Wearable.ShowOriginal", boost::bind(show_item_original, selected_id));
-	registrar.add("Wearable.TakeOffDetach", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Wearable.TakeOffDetach", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 
 	// Register handlers for clothing.
-	registrar.add("Clothing.TakeOff", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Clothing.TakeOff", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 
 	// Register handlers for body parts.
 
 	// Register handlers for attachments.
-	registrar.add("Attachment.Detach", boost::bind(handleMultiple, take_off, ids));
+	registrar.add("Attachment.Detach", 
+				  boost::bind(&LLAppearanceMgr::removeItemsFromAvatar, LLAppearanceMgr::getInstance(), ids));
 	registrar.add("Attachment.Profile", boost::bind(show_item_profile, selected_id));
 	registrar.add("Object.Attach", boost::bind(LLViewerAttachMenu::attachObjects, ids, _2));
 
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 6f6411ce3cc5337a841b7ba573cef9da803ae76d..ef1a953f59d5c2d7ec47115dd50edc17fd57e8a0 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -42,20 +42,23 @@ struct LLWearableArrivedData
 {
 	LLWearableArrivedData(LLAssetType::EType asset_type,
 		const std::string& wearable_name,
-		void(*asset_arrived_callback)(LLWearable*, void* userdata),
+		LLAvatarAppearance* avatarp,
+		void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
 						  void* userdata) :
 		mAssetType( asset_type ),
 		mCallback( asset_arrived_callback ), 
 		mUserdata( userdata ),
 		mName( wearable_name ),
-		mRetries(0)
+		mRetries(0),
+		mAvatarp(avatarp)
 		{}
 
 	LLAssetType::EType mAssetType;
-	void	(*mCallback)(LLWearable*, void* userdata);
+	void	(*mCallback)(LLViewerWearable*, void* userdata);
 	void*	mUserdata;
 	std::string mName;
 	S32	mRetries;
+	LLAvatarAppearance *mAvatarp;
 };
 
 ////////////////////////////////////////////////////////////////////////////
@@ -72,10 +75,10 @@ void LLWearableList::cleanup()
 	mList.clear();
 }
 
-void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLWearable*, void* userdata), void* userdata)
+void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& wearable_name, LLAvatarAppearance* avatarp, LLAssetType::EType asset_type, void(*asset_arrived_callback)(LLViewerWearable*, void* userdata), void* userdata)
 {
 	llassert( (asset_type == LLAssetType::AT_CLOTHING) || (asset_type == LLAssetType::AT_BODYPART) );
-	LLWearable* instance = get_if_there(mList, assetID, (LLWearable*)NULL );
+	LLViewerWearable* instance = get_if_there(mList, assetID, (LLViewerWearable*)NULL );
 	if( instance )
 	{
 		asset_arrived_callback( instance, userdata );
@@ -85,7 +88,7 @@ void LLWearableList::getAsset(const LLAssetID& assetID, const std::string& weara
 		gAssetStorage->getAssetData(assetID,
 			asset_type,
 			LLWearableList::processGetAssetReply,
-			(void*)new LLWearableArrivedData( asset_type, wearable_name, asset_arrived_callback, userdata ),
+			(void*)new LLWearableArrivedData( asset_type, wearable_name, avatarp, asset_arrived_callback, userdata ),
 			TRUE);
 	}
 }
@@ -95,25 +98,31 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 {
 	BOOL isNewWearable = FALSE;
 	LLWearableArrivedData* data = (LLWearableArrivedData*) userdata;
-	LLWearable* wearable = NULL; // NULL indicates failure
+	LLViewerWearable* wearable = NULL; // NULL indicates failure
+	LLAvatarAppearance *avatarp = data->mAvatarp;
 	
 	if( !filename )
 	{
 		LL_WARNS("Wearable") << "Bad Wearable Asset: missing file." << LL_ENDL;
 	}
+	else if(!avatarp)
+	{
+		LL_WARNS("Wearable") << "Bad asset request: missing avatar pointer." << LL_ENDL;
+	}
 	else if (status >= 0)
 	{
 		// read the file
-		LLFILE* fp = LLFile::fopen(std::string(filename), "rb");		/*Flawfinder: ignore*/
-		if( !fp )
+		llifstream ifs(filename, llifstream::binary);
+		if( !ifs.is_open() )
 		{
 			LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
 		}
 		else
 		{
-			wearable = new LLWearable(uuid);
-			bool res = wearable->importFile( fp );
-			if (!res)
+			wearable = new LLViewerWearable(uuid);
+			LLWearable::EImportResult result = wearable->importStream(
+												ifs, avatarp );
+			if (LLWearable::SUCCESS != result)
 			{
 				if (wearable->getType() == LLWearableType::WT_COUNT)
 				{
@@ -123,9 +132,12 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 				wearable = NULL;
 			}
 
-			fclose( fp );
 			if(filename)
 			{
+				if (ifs.is_open())
+				{
+					ifs.close();
+				}
 				LLFile::remove(std::string(filename));
 			}
 		}
@@ -203,11 +215,11 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 }
 
 
-LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std::string& new_name)
+LLViewerWearable* LLWearableList::createCopy(const LLViewerWearable* old_wearable, const std::string& new_name)
 {
 	lldebugs << "LLWearableList::createCopy()" << llendl;
 
-	LLWearable *wearable = generateNewWearable();
+	LLViewerWearable *wearable = generateNewWearable();
 	wearable->copyDataFrom(old_wearable);
 
 	LLPermissions perm(old_wearable->getPermissions());
@@ -222,12 +234,12 @@ LLWearable* LLWearableList::createCopy(const LLWearable* old_wearable, const std
 	return wearable;
 }
 
-LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
+LLViewerWearable* LLWearableList::createNewWearable( LLWearableType::EType type, LLAvatarAppearance *avatarp )
 {
 	lldebugs << "LLWearableList::createNewWearable()" << llendl;
 
-	LLWearable *wearable = generateNewWearable();
-	wearable->setType( type );
+	LLViewerWearable *wearable = generateNewWearable();
+	wearable->setType( type, avatarp );
 	
 	std::string name = LLTrans::getString( LLWearableType::getTypeDefaultNewName(wearable->getType()) );
 	wearable->setName( name );
@@ -237,6 +249,8 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
 	perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, PERM_MOVE | PERM_TRANSFER);
 	wearable->setPermissions(perm);
 
+	wearable->setDefinitionVersion(LLWearable::getCurrentDefinitionVersion());
+
 	// Description and sale info have default values.
 	wearable->setParamsToDefaults();
 	wearable->setTexturesToDefaults();
@@ -251,13 +265,13 @@ LLWearable* LLWearableList::createNewWearable( LLWearableType::EType type )
 	return wearable;
 }
 
-LLWearable *LLWearableList::generateNewWearable()
+LLViewerWearable *LLWearableList::generateNewWearable()
 {
 	LLTransactionID tid;
 	tid.generate();
 	LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
 
-	LLWearable* wearable = new LLWearable(tid);
+	LLViewerWearable* wearable = new LLViewerWearable(tid);
 	mList[new_asset_id] = wearable;
 	return wearable;
 }
diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h
index 12d0037aee443c6969818a24f752307690ce9119..d6f0fd09a6d5c0376c78ad8ff2327e3c06c9e747 100644
--- a/indra/newview/llwearablelist.h
+++ b/indra/newview/llwearablelist.h
@@ -28,7 +28,7 @@
 #define LL_LLWEARABLELIST_H
 
 #include "llmemory.h"
-#include "llwearable.h"
+#include "llviewerwearable.h"
 #include "lluuid.h"
 #include "llassetstorage.h"
 
@@ -50,20 +50,21 @@ class LLWearableList : public LLSingleton<LLWearableList>
 
 	void				getAsset(const LLAssetID& assetID,
 								 const std::string& wearable_name,
+								 LLAvatarAppearance *avatarp,
 								 LLAssetType::EType asset_type,
-								 void(*asset_arrived_callback)(LLWearable*, void* userdata),
+								 void(*asset_arrived_callback)(LLViewerWearable*, void* userdata),
 								 void* userdata);
 
-	LLWearable*			createCopy(const LLWearable* old_wearable, const std::string& new_name = std::string());
-	LLWearable*			createNewWearable(LLWearableType::EType type);
+	LLViewerWearable*			createCopy(const LLViewerWearable* old_wearable, const std::string& new_name = std::string());
+	LLViewerWearable*			createNewWearable(LLWearableType::EType type, LLAvatarAppearance *avatarp);
 	
 	// Callback
 	static void	 	    processGetAssetReply(const char* filename, const LLAssetID& assetID, void* user_data, S32 status, LLExtStat ext_status);
 
 protected:
-	LLWearable* generateNewWearable(); // used for the create... functions
+	LLViewerWearable* generateNewWearable(); // used for the create... functions
 private:
-	std::map<LLUUID, LLWearable*> mList;
+	std::map<LLUUID, LLViewerWearable*> mList;
 };
 
 #endif  // LL_LLWEARABLELIST_H
diff --git a/indra/newview/llwebsharing.cpp b/indra/newview/llwebsharing.cpp
index 43b1a320c34b2d3b2f4751e50b39aa49e029aa06..3a80051b9b7896a06ac604ae025d3d5750b23db3 100644
--- a/indra/newview/llwebsharing.cpp
+++ b/indra/newview/llwebsharing.cpp
@@ -68,9 +68,9 @@ class LLWebSharingConfigResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 	}
 
 	virtual void result(const LLSD& content)
@@ -99,7 +99,7 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 		/// Left empty to override the default LLSD parsing behaviour.
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
 		if (HTTP_UNAUTHORIZED == status)
 		{
@@ -108,7 +108,7 @@ class LLWebSharingOpenIDAuthResponder : public LLHTTPClient::Responder
 		}
 		else
 		{
-			LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+			LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 			LLWebSharing::instance().retryOpenIDAuth();
 		}
 
@@ -152,9 +152,9 @@ class LLWebSharingSecurityTokenResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 		LLWebSharing::instance().retryOpenIDAuth();
 	}
 
@@ -221,9 +221,9 @@ class LLWebSharingUploadResponder : public LLHTTPClient::Responder
 		}
 	}
 
-	virtual void error(U32 status, const std::string& reason)
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 	{
-		LL_WARNS("WebSharing") << "Error [" << status << "]: " << reason << LL_ENDL;
+		LL_WARNS("WebSharing") << "Error [status:" << status << "]: " << content << LL_ENDL;
 	}
 
 	virtual void result(const LLSD& content)
diff --git a/indra/newview/llwlhandlers.cpp b/indra/newview/llwlhandlers.cpp
index be3e3ff30e0cb6c4ba8c260d72c82f571ebfb05e..93eba5b6048aeddcf4552df38f76c295fee5eef0 100644
--- a/indra/newview/llwlhandlers.cpp
+++ b/indra/newview/llwlhandlers.cpp
@@ -121,9 +121,11 @@ LLEnvironmentRequestResponder::LLEnvironmentRequestResponder()
 
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(unvalidated_content);
 }
-/*virtual*/ void LLEnvironmentRequestResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentRequestResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight..." << LL_ENDL;
+	LL_INFOS("WindlightCaps") << "Got an error, not using region windlight... [status:" 
+		<< status << "]: " << content << LL_ENDL;
 	LLEnvManagerNew::getInstance()->onRegionSettingsResponse(LLSD());
 }
 
@@ -190,14 +192,15 @@ bool LLEnvironmentApply::initiateRequest(const LLSD& content)
 		LLEnvManagerNew::instance().onRegionSettingsApplyResponse(false);
 	}
 }
-/*virtual*/ void LLEnvironmentApplyResponder::error(U32 status, const std::string& reason)
+/*virtual*/
+void LLEnvironmentApplyResponder::errorWithContent(U32 status, const std::string& reason, const LLSD& content)
 {
-	std::stringstream msg;
-	msg << reason << " (Code " << status << ")";
-
-	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  Reason: " << msg << LL_ENDL;
+	LL_WARNS("WindlightCaps") << "Couldn't apply windlight settings to region!  [status:"
+		<< status << "]: " << content << LL_ENDL;
 
 	LLSD args(LLSD::emptyMap());
+	std::stringstream msg;
+	msg << reason << " (Code " << status << ")";
 	args["FAIL_REASON"] = msg.str();
 	LLNotificationsUtil::add("WLRegionApplyFail", args);
 }
diff --git a/indra/newview/llwlhandlers.h b/indra/newview/llwlhandlers.h
index 23558876da73678891775d1ff033be897778007b..598ce6d52ac52c6c54989ce6d5498237564b92b5 100644
--- a/indra/newview/llwlhandlers.h
+++ b/indra/newview/llwlhandlers.h
@@ -47,7 +47,7 @@ class LLEnvironmentRequestResponder: public LLHTTPClient::Responder
 	LOG_CLASS(LLEnvironmentRequestResponder);
 public:
 	virtual void result(const LLSD& content);
-	virtual void error(U32 status, const std::string& reason);
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 private:
 	friend class LLEnvironmentRequest;
@@ -89,7 +89,8 @@ class LLEnvironmentApplyResponder: public LLHTTPClient::Responder
 	 */
 	virtual void result(const LLSD& content);
 
-	virtual void error(U32 status, const std::string& reason); // non-200 errors only
+	// non-200 errors only
+	virtual void errorWithContent(U32 status, const std::string& reason, const LLSD& content);
 
 private:
 	friend class LLEnvironmentApply;
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 09d17b37015baa287047b04009433c4776c0b7b8..793becf0c82e14397692d9838e7d0ccb4926129b 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -1192,7 +1192,7 @@ void LLWorld::getAvatars(uuid_vec_t* avatar_ids, std::vector<LLVector3d>* positi
 	{
 		LLVOAvatar* pVOAvatar = (LLVOAvatar*) *iter;
 
-		if (!pVOAvatar->isDead() && !pVOAvatar->isSelf() && !pVOAvatar->mIsDummy)
+		if (!pVOAvatar->isDead() && !pVOAvatar->mIsDummy)
 		{
 			LLVector3d pos_global = pVOAvatar->getPositionGlobal();
 			LLUUID uuid = pVOAvatar->getID();
diff --git a/indra/newview/llworldmap.cpp b/indra/newview/llworldmap.cpp
index 350ba39b45cdcde3173b2803318982872ae0d33b..5fa380e0e3a920e8ef6a726a4d5b196e089c38d0 100644
--- a/indra/newview/llworldmap.cpp
+++ b/indra/newview/llworldmap.cpp
@@ -34,6 +34,7 @@
 #include "lluistring.h"
 #include "llviewertexturelist.h"
 #include "lltrans.h"
+#include "llgltexture.h"
 
 // Timers to temporise database requests
 const F32 AGENTS_UPDATE_TIMER = 60.0;			// Seconds between 2 agent requests for a region
@@ -78,7 +79,7 @@ void LLSimInfo::setLandForSaleImage (LLUUID image_id)
 	// Fetch the image
 	if (mMapImageID.notNull())
 	{
-		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
 		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
 	}
 	else
@@ -92,13 +93,13 @@ LLPointer<LLViewerFetchedTexture> LLSimInfo::getLandForSaleImage ()
 	if (mOverlayImage.isNull() && mMapImageID.notNull())
 	{
 		// Fetch the image if it hasn't been done yet (unlikely but...)
-		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, MIPMAP_TRUE, LLViewerTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
+		mOverlayImage = LLViewerTextureManager::getFetchedTexture(mMapImageID, FTT_DEFAULT, MIPMAP_TRUE, LLGLTexture::BOOST_MAP, LLViewerTexture::LOD_TEXTURE);
 		mOverlayImage->setAddressMode(LLTexUnit::TAM_CLAMP);
 	}
 	if (!mOverlayImage.isNull())
 	{
 		// Boost the fetch level when we try to access that image
-		mOverlayImage->setBoostLevel(LLViewerTexture::BOOST_MAP);
+		mOverlayImage->setBoostLevel(LLGLTexture::BOOST_MAP);
 	}
 	return mOverlayImage;
 }
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index 73530b96940456c618d6769ab866012f89b2d68c..d514b2f14c3eafd5c6291a59f68536f27cac3a52 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -36,6 +36,7 @@
 #include "llsingleton.h"
 #include "llviewerregion.h"
 #include "llviewertexture.h"
+#include "llgltexture.h"
 
 // Description of objects like hubs, events, land for sale, people and more (TBD).
 // Note: we don't store a "type" in there so we need to store instances of this class in 
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index ccc513b80d68940020365fb3adaf3f118c8dedcc..1940cf541ece1e631284083c6b2f8c8d209ed657 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -421,7 +421,7 @@ void LLWorldMapView::draw()
 			{
 				// Inform the fetch mechanism of the size we need
 				S32 draw_size = llround(sMapScale);
-				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::sGLScaleFactor.mV[VX]), llround(draw_size * LLUI::sGLScaleFactor.mV[VY]));
+				overlayimage->setKnownDrawSize(llround(draw_size * LLUI::getScaleFactor().mV[VX]), llround(draw_size * LLUI::getScaleFactor().mV[VY]));
 				// Draw something whenever we have enough info
 				if (overlayimage->hasGLTexture())
 				{
@@ -965,8 +965,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
 	S32 text_x = x;
 	S32 text_y = (S32)(y - sTrackCircleImage->getHeight()/2 - font->getLineHeight());
 
-	BOOL is_in_window = true;
-
 	if(    x < 0 
 		|| y < 0 
 		|| x >= getRect().getWidth() 
@@ -979,7 +977,6 @@ void LLWorldMapView::drawTracking(const LLVector3d& pos_global, const LLColor4&
 			text_x = sTrackingArrowX;
 			text_y = sTrackingArrowY;
 		}
-		is_in_window = false;
 	}
 	else if (LLTracker::getTrackingStatus() == LLTracker::TRACKING_LOCATION &&
 		LLTracker::getTrackedLocationType() != LLTracker::LOCATION_NOTHING)
@@ -1320,7 +1317,7 @@ void LLWorldMapView::drawTrackingCircle( const LLRect& rect, S32 x, S32 y, const
 
 	gGL.matrixMode(LLRender::MM_MODELVIEW);
 	gGL.pushMatrix();
-	gGL.translatef((F32)x * LLUI::sGLScaleFactor.mV[VX], (F32)y * LLUI::sGLScaleFactor.mV[VY], 0.f);
+	gGL.translatef((F32)x * LLUI::getScaleFactor().mV[VX], (F32)y * LLUI::getScaleFactor().mV[VY], 0.f);
 	gl_washer_segment_2d(inner_radius, outer_radius, start_theta, end_theta, 40, color, color);
 	gGL.popMatrix();
 
diff --git a/indra/newview/llworldmipmap.cpp b/indra/newview/llworldmipmap.cpp
index 74ed844376e2fb58e2382ae82cfa1fddb38d15a8..895ccaef5a1fafe98d02b6bf21af16b8fc3e4ed3 100644
--- a/indra/newview/llworldmipmap.cpp
+++ b/indra/newview/llworldmipmap.cpp
@@ -74,21 +74,21 @@ void LLWorldMipmap::equalizeBoostLevels()
 		{
 			LLPointer<LLViewerFetchedTexture> img = iter->second;
 			S32 current_boost_level = img->getBoostLevel();
-			if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+			if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
 			{
 				// If level was BOOST_MAP_VISIBLE, the tile has been used in the last draw so keep it high
-				img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+				img->setBoostLevel(LLGLTexture::BOOST_MAP);
 			}
 			else
 			{
 				// If level was BOOST_MAP only (or anything else...), the tile wasn't used in the last draw 
 				// so we drop its boost level to BOOST_NONE.
-				img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+				img->setBoostLevel(LLGLTexture::BOOST_NONE);
 			}
 #if DEBUG_TILES_STAT
 			// Increment some stats if compile option on
 			nb_tiles++;
-			if (current_boost_level == LLViewerTexture::BOOST_MAP_VISIBLE)
+			if (current_boost_level == LLGLTexture::BOOST_MAP_VISIBLE)
 			{
 				nb_visible++;
 			}
@@ -115,7 +115,7 @@ void LLWorldMipmap::dropBoostLevels()
 		for (sublevel_tiles_t::iterator iter = level_mipmap.begin(); iter != level_mipmap.end(); iter++)
 		{
 			LLPointer<LLViewerFetchedTexture> img = iter->second;
-			img->setBoostLevel(LLViewerTexture::BOOST_NONE);
+			img->setBoostLevel(LLGLTexture::BOOST_NONE);
 		}
 	}
 }
@@ -172,7 +172,7 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::getObjectsTile(U32 grid_x, U32
 		// Boost the tile level so to mark it's in use *if* load on
 		if (load)
 		{
-			img->setBoostLevel(LLViewerTexture::BOOST_MAP_VISIBLE);
+			img->setBoostLevel(LLGLTexture::BOOST_MAP_VISIBLE);
 		}
 		return img;
 	}
@@ -189,8 +189,8 @@ LLPointer<LLViewerFetchedTexture> LLWorldMipmap::loadObjectsTile(U32 grid_x, U32
 	// END DEBUG
 	//LL_INFOS("World Map") << "LLWorldMipmap::loadObjectsTile(), URL = " << imageurl << LL_ENDL;
 
-	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, TRUE, LLViewerTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
-	img->setBoostLevel(LLViewerTexture::BOOST_MAP);
+	LLPointer<LLViewerFetchedTexture> img = LLViewerTextureManager::getFetchedTextureFromUrl(imageurl, FTT_MAP_TILE, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE);
+	img->setBoostLevel(LLGLTexture::BOOST_MAP);
 
 	// Return the smart pointer
 	return img;
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 2051772d635202b697f6f9a6523e551fd9dbafd9..f320f34f6eadb364399c931c9692573111c29f55 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -71,6 +71,7 @@
 #include "llhudtext.h"
 #include "lllightconstants.h"
 #include "llmeshrepository.h"
+#include "llpipelinelistener.h"
 #include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llsky.h"
@@ -377,6 +378,8 @@ BOOL    LLPipeline::sMemAllocationThrottled = FALSE;
 S32		LLPipeline::sVisibleLightCount = 0;
 F32		LLPipeline::sMinRenderSize = 0.f;
 
+// EventHost API LLPipeline listener.
+static LLPipelineListener sPipelineListener;
 
 static LLCullResult* sCull = NULL;
 
@@ -491,19 +494,29 @@ void LLPipeline::init()
 	LLViewerStats::getInstance()->mTrianglesDrawnStat.reset();
 	resetFrameStats();
 
-	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	if (gSavedSettings.getBOOL("DisableAllRenderFeatures"))
 	{
-		mRenderTypeEnabled[i] = TRUE; //all rendering types start enabled
+		clearAllRenderDebugFeatures();
 	}
+	else
+	{
+		setAllRenderDebugFeatures(); // By default, all debugging features on
+	}
+	clearAllRenderDebugDisplays(); // All debug displays off
 
-	mRenderDebugFeatureMask = 0xffffffff; // All debugging features on
-	mRenderDebugMask = 0;	// All debug starts off
-
-	// Don't turn on ground when this is set
-	// Mac Books with intel 950s need this
-	if(!gSavedSettings.getBOOL("RenderGround"))
+	if (gSavedSettings.getBOOL("DisableAllRenderTypes"))
 	{
-		toggleRenderType(RENDER_TYPE_GROUND);
+		clearAllRenderTypes();
+	}
+	else
+	{
+		setAllRenderTypes(); // By default, all rendering types start enabled
+		// Don't turn on ground when this is set
+		// Mac Books with intel 950s need this
+		if(!gSavedSettings.getBOOL("RenderGround"))
+		{
+			toggleRenderType(RENDER_TYPE_GROUND);
+		}
 	}
 
 	// make sure RenderPerformanceTest persists (hackity hack hack)
@@ -5290,11 +5303,6 @@ void LLPipeline::rebuildPools()
 		}
 		max_count--;
 	}
-
-	if (isAgentAvatarValid())
-	{
-		gAgentAvatarp->rebuildHUD();
-	}
 }
 
 void LLPipeline::addToQuickLookup( LLDrawPool* new_poolp )
@@ -5779,7 +5787,7 @@ void LLPipeline::calcNearbyLights(LLCamera& camera)
 				// crazy cast so that we can overwrite the fade value
 				// even though gcc enforces sets as const
 				// (fade value doesn't affect sort so this is safe)
-				Light* farthest_light = ((Light*) (&(*(mNearbyLights.rbegin()))));
+				Light* farthest_light = (const_cast<Light*>(&(*(mNearbyLights.rbegin()))));
 				if (light->dist < farthest_light->dist)
 				{
 					if (farthest_light->fade >= 0.f)
@@ -5922,7 +5930,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool)
 			if (light->isLightSpotlight() // directional (spot-)light
 			    && (LLPipeline::sRenderDeferred || RenderSpotLightsInNondeferred)) // these are only rendered as GL spotlights if we're in deferred rendering mode *or* the setting forces them on
 			{
-				LLVector3 spotparams = light->getSpotLightParams();
 				LLQuaternion quat = light->getRenderRotation();
 				LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction
 				at_axis *= quat;
@@ -6453,6 +6460,22 @@ void LLPipeline::setRenderDebugFeatureControl(U32 bit, bool value)
 	}
 }
 
+void LLPipeline::pushRenderDebugFeatureMask()
+{
+	mRenderDebugFeatureStack.push(mRenderDebugFeatureMask);
+}
+
+void LLPipeline::popRenderDebugFeatureMask()
+{
+	if (mRenderDebugFeatureStack.empty())
+	{
+		llerrs << "Depleted render feature stack." << llendl;
+	}
+
+	mRenderDebugFeatureMask = mRenderDebugFeatureStack.top();
+	mRenderDebugFeatureStack.pop();
+}
+
 // static
 void LLPipeline::setRenderScriptedBeacons(BOOL val)
 {
@@ -6810,7 +6833,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable)
 }
 
 void LLPipeline::resetVertexBuffers()
-{
+{	
 	mResetVertexBuffers = true;
 }
 
@@ -9086,9 +9109,6 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 		3,7	
 	};
 
-	LLVector3 center = (max+min)*0.5f;
-	LLVector3 size = (max-min)*0.5f;
-	
 	for (U32 i = 0; i < 12; i++)
 	{
 		for (U32 j = 0; j < 6; ++j)
@@ -9314,7 +9334,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera)
 	mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]);
 
 	//currently used for amount to extrude frusta corners for constructing shadow frusta
-	LLVector3 n = RenderShadowNearDist;
+	//LLVector3 n = RenderShadowNearDist;
 	//F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] };
 
 	//put together a universal "near clip" plane for shadow frusta
@@ -10419,6 +10439,22 @@ void LLPipeline::clearRenderTypeMask(U32 type, ...)
 	}
 }
 
+void LLPipeline::setAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = TRUE;
+	}
+}
+
+void LLPipeline::clearAllRenderTypes()
+{
+	for (U32 i = 0; i < NUM_RENDER_TYPES; ++i)
+	{
+		mRenderTypeEnabled[i] = FALSE;
+	}
+}
+
 void LLPipeline::addDebugBlip(const LLVector3& position, const LLColor4& color)
 {
 	DebugBlip blip(position, color);
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 36abeca295a25a22ec773a07bebf02f3bfd50e24..a8db93585e66aa8c22ae37f8446e32dcd3629ec0 100644
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -324,20 +324,28 @@ class LLPipeline
 
 	BOOL hasRenderDebugFeatureMask(const U32 mask) const	{ return (mRenderDebugFeatureMask & mask) ? TRUE : FALSE; }
 	BOOL hasRenderDebugMask(const U32 mask) const			{ return (mRenderDebugMask & mask) ? TRUE : FALSE; }
-	
-
+	void setAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0xffffffff; }
+	void clearAllRenderDebugFeatures() { mRenderDebugFeatureMask = 0x0; }
+	void setAllRenderDebugDisplays() { mRenderDebugMask = 0xffffffff; }
+	void clearAllRenderDebugDisplays() { mRenderDebugMask = 0x0; }
 
 	BOOL hasRenderType(const U32 type) const;
 	BOOL hasAnyRenderType(const U32 type, ...) const;
 
 	void setRenderTypeMask(U32 type, ...);
-	void orRenderTypeMask(U32 type, ...);
+	// This is equivalent to 'setRenderTypeMask'
+	//void orRenderTypeMask(U32 type, ...);
 	void andRenderTypeMask(U32 type, ...);
 	void clearRenderTypeMask(U32 type, ...);
+	void setAllRenderTypes();
+	void clearAllRenderTypes();
 	
 	void pushRenderTypeMask();
 	void popRenderTypeMask();
 
+	void pushRenderDebugFeatureMask();
+	void popRenderDebugFeatureMask();
+
 	static void toggleRenderType(U32 type);
 
 	// For UI control of render features
@@ -634,6 +642,7 @@ class LLPipeline
 
 	U32						mRenderDebugFeatureMask;
 	U32						mRenderDebugMask;
+	std::stack<U32>			mRenderDebugFeatureStack;
 
 	U32						mOldRenderDebugMask;
 	
diff --git a/indra/newview/res/viewerRes.rc b/indra/newview/res/viewerRes.rc
index df75f3f697f7fd2adc591037ca33c56d38d4d920..471a896019d86937f4bcb42e7da9f191a64189f9 100644
--- a/indra/newview/res/viewerRes.rc
+++ b/indra/newview/res/viewerRes.rc
@@ -135,8 +135,8 @@ TOOLNO                  CURSOR                  "llno.cur"
 //
 
 VS_VERSION_INFO VERSIONINFO
- FILEVERSION 2,1,1,0
- PRODUCTVERSION 2,1,1,0
+ FILEVERSION 3,4,1,264760
+ PRODUCTVERSION 3,4,1,264760
  FILEFLAGSMASK 0x3fL
 #ifdef _DEBUG
  FILEFLAGS 0x1L
@@ -153,12 +153,12 @@ BEGIN
         BEGIN
             VALUE "CompanyName", "Linden Lab"
             VALUE "FileDescription", "Second Life"
-            VALUE "FileVersion", "2.1.1.0"
+            VALUE "FileVersion", "3.4.1.264760"
             VALUE "InternalName", "Second Life"
             VALUE "LegalCopyright", "Copyright � 2001-2010, Linden Research, Inc."
             VALUE "OriginalFilename", "SecondLife.exe"
             VALUE "ProductName", "Second Life"
-            VALUE "ProductVersion", "2.1.1.0"
+            VALUE "ProductVersion", "3.4.1.264760"
         END
     END
     BLOCK "VarFileInfo"
diff --git a/indra/newview/skins/default/colors.xml b/indra/newview/skins/default/colors.xml
index 9bf2922033fcdd5c5a127dcc32da1510a8f5c3ae..0de217fc0d377c87e9af886bf2dc190ab96a669b 100644
--- a/indra/newview/skins/default/colors.xml
+++ b/indra/newview/skins/default/colors.xml
@@ -1,103 +1,106 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <colors>
 
-  <!-- Named Colors -->
-  <color
-      name="EmphasisColor"
-      value="0.38 0.694 0.573 1" />
-  <color
-      name="EmphasisColor_13"
-      value="0.38 0.694 0.573 0.13" />
-  <color
-      name="EmphasisColor_35"
-      value="0.38 0.694 0.573 0.35" />
-  <color
-      name="White"
-      value="1 1 1 1" />
-  <color
-      name="White_05"
-      value="1 1 1 0.05" />
-  <color
-      name="White_10"
-      value="1 1 1 0.1" />
-  <color
-      name="White_25"
-      value="1 1 1 0.25" />
-  <color
-      name="White_50"
-      value="1 1 1 0.5" />
-  <color
-      name="LtGray"
-      value="0.75 0.75 0.75 1" />
-  <color
-      name="LtGray_35"
-      value="0.75 0.75 0.75 0.35" />
-  <color
-      name="LtGray_50"
-      value="0.75 0.75 0.75 0.50" />
-  <color
-      name="Gray"
-      value="0.5 0.5 0.5 1" />
-  <color
-      name="DkGray"
-      value="0.125 0.125 0.125 1" />
-  <color
-      name="DkGray_66"
-      value="0.125 0.125 0.125 .66" />
-  <color
-      name="DkGray2"
-      value="0.169 0.169 0.169 1" />
-  <color
-      name="MouseGray"
-      value="0.191 0.191 0.191 1" />
-  <color
-      name="Black"
-      value="0 0 0 1" />
-  <colork
-      name="Black_10"
-      value="0 0 0 0.1" />
-  <color
-      name="Black_25"
-      value="0 0 0 0.25" />
-  <color
-      name="Black_50"
-      value="0 0 0 0.5" />
-  <color
-      name="FrogGreen"
-      value="0.26 0.345 0.263 1" />
-  <color
-      name="Red"
-      value="1 0 0 1" />
-  <color
-      name="Blue"
-      value="0 0 1 1" />
-  <color
-      name="Yellow"
-      value="1 1 0 1" />
-  <color
-      name="Green"
-      value="0 1 0 1" />
-  <color
-      name="Transparent"
-      value="0 0 0 0" />
-  <color
-      name="Purple"
-      value="1 0 1 1" />
-  <color
-      name="Lime"
-      value=".8 1 .73 1" />
-  <color
-      name="LtYellow"
-      value="1 1 .79 1" />
-  <color
-      name="DrYellow"
-      value="1 0.86 0 1" />
-  <color
-      name="LtOrange"
-      value="1 .85 .73 1" />
-  <color
-      name="MdBlue"
-      value=".07 .38 .51 1" />
+	<!-- Named Colors -->
+	<color
+	 name="EmphasisColor"
+	 value="0.38 0.694 0.573 1" />
+	<color
+	 name="EmphasisColor_13"
+	 value="0.38 0.694 0.573 0.13" />
+	<color
+	 name="EmphasisColor_35"
+	 value="0.38 0.694 0.573 0.35" />
+	<color
+	 name="BeaconColor"
+    value="0.749 0.298 0 1" />	 
+	<color
+	 name="White"
+	 value="1 1 1 1" />
+	<color
+	 name="White_05"
+	 value="1 1 1 0.05" />
+	<color
+	 name="White_10"
+	 value="1 1 1 0.1" />
+	<color
+	 name="White_25"
+	 value="1 1 1 0.25" />
+	<color
+	 name="White_50"
+	 value="1 1 1 0.5" />
+	<color
+	 name="LtGray"
+	 value="0.75 0.75 0.75 1" />
+	<color
+	 name="LtGray_35"
+	 value="0.75 0.75 0.75 0.35" />
+	<color
+	 name="LtGray_50"
+	 value="0.75 0.75 0.75 0.50" />
+	<color
+	 name="Gray"
+	 value="0.5 0.5 0.5 1" />
+	<color
+	 name="DkGray"
+	 value="0.125 0.125 0.125 1" />
+	<color
+	 name="DkGray_66"
+	 value="0.125 0.125 0.125 .66" />
+	<color
+	 name="DkGray2"
+	 value="0.169 0.169 0.169 1" />
+	<color
+	 name="MouseGray"
+	 value="0.191 0.191 0.191 1" />
+	<color
+	 name="Black"
+	 value="0 0 0 1" />
+	<colork
+	 name="Black_10"
+	 value="0 0 0 0.1" />
+	<color
+	 name="Black_25"
+	 value="0 0 0 0.25" />
+	<color
+	 name="Black_50"
+	 value="0 0 0 0.5" />
+	<color
+	name="FrogGreen"
+	value="0.26 0.345 0.263 1" />
+	<color
+	 name="Red"
+	 value="1 0 0 1" />
+	<color
+	 name="Blue"
+	 value="0 0 1 1" />
+	<color
+	 name="Yellow"
+	 value="1 1 0 1" />
+	<color
+	 name="Green"
+	 value="0 1 0 1" />
+	<color
+	 name="Transparent"
+	 value="0 0 0 0" />
+	<color
+	name="Purple"
+	value="1 0 1 1" />
+	<color
+	name="Lime"
+	value=".8 1 .73 1" />
+	<color
+	name="LtYellow"
+	value="1 1 .79 1" />
+	<color
+	name="DrYellow"
+	value="1 0.86 0 1" />
+	<color
+	name="LtOrange"
+	value="1 .85 .73 1" />
+	<color
+	name="MdBlue"
+	value=".07 .38 .51 1" />
   <color
       name="LtRed"
       value="1 0.2 0.2 1" />
@@ -115,527 +118,530 @@
       value="0 0 1 0.8" />
 
   <!-- This color name makes potentially unused colors show up bright purple.
-       Leave this here until all Unused? are removed below, otherwise
-       the viewer generates many warnings on startup. -->
+  Leave this here until all Unused? are removed below, otherwise
+  the viewer generates many warnings on startup. -->
   <color
-      name="Unused?"
-      value=".831 1 0 1" />
+	 name="Unused?"
+	 value=".831 1 0 1" />
 
   <!-- UI Definitions -->
 
-  <color
-      name="AccordionHeaderTextColor"
-      reference="LtGray" />
-  <color
-      name="AgentChatColor"
-      reference="White" />
-  <color
-      name="AlertBoxColor"
-      value="0.24 0.24 0.24 1" />
-  <color
-      name="AlertCautionBoxColor"
-      value="1 0.82 0.46 1" />
-  <color
-      name="AlertCautionTextColor"
-      reference="LtYellow" />
-  <color
-      name="AvatarListItemIconDefaultColor"
-      reference="White" />
-  <color
-      name="AvatarListItemIconOnlineColor"
-      reference="White" />
-  <color
-      name="AvatarListItemIconOfflineColor"
-      value="0.5 0.5 0.5 0.5" />
-  <color
-      name="AvatarListItemIconVoiceInvitedColor"
-      reference="AvatarListItemIconOfflineColor" />
-  <color
-      name="AvatarListItemIconVoiceJoinedColor"
-      reference="AvatarListItemIconOnlineColor" />
-  <color
-      name="AvatarListItemIconVoiceLeftColor"
-      reference="AvatarListItemIconOfflineColor" />
-  <color
-      name="BadgeImageColor"
-      value="1.0 0.40 0.0 1.0" />
-  <color
-      name="BadgeBorderColor"
-      value="0.9 0.9 0.9 1.0" />
-  <color
-      name="BadgeLabelColor"
-      reference="White" />
-  <color
-      name="ButtonBorderColor"
-      reference="Unused?" />
-  <color
-      name="ButtonCautionImageColor"
-      reference="Unused?" />
-  <color
-      name="ButtonColor"
-      reference="Unused?" />
-  <color
-      name="ButtonFlashBgColor"
-      reference="Unused?" />
-  <color
-      name="ButtonImageColor"
-      reference="White" />
-  <color
-      name="ButtonLabelColor"
-      reference="LtGray" />
-  <color
-      name="ButtonLabelDisabledColor"
-      reference="White_25" />
-  <color
-      name="ButtonLabelSelectedColor"
-      reference="White" />
-  <color
-      name="ButtonLabelSelectedDisabledColor"
-      reference="White_25" />
-  <color
-      name="ButtonSelectedBgColor"
-      reference="Unused?" />
-  <color
-      name="ButtonSelectedColor"
-      reference="Unused?" />
-  <color
-      name="ButtonUnselectedBgColor"
-      reference="Unused?" />
-  <color
-      name="ButtonUnselectedFgColor"
-      reference="Unused?" />
-  <color
-      name="ChatHistoryBgColor"
-      reference="Transparent" />
-  <color
-      name="ChatHistoryTextColor"
-      reference="LtGray" />
-  <color
-      name="ChicletFlashColor"
-      value="0.114 0.65 0.1" />
-  <color
-      name="ColorDropShadow"
-      reference="Black_50" />
-  <color
-      name="ColorPaletteEntry01"
-      reference="Black" />
-  <color
-      name="ColorPaletteEntry02"
-      reference="Gray" />
-  <color
-      name="ColorPaletteEntry03"
-      value="0.5 0 0 1" />
-  <color
-      name="ColorPaletteEntry04"
-      value="0.5 0.5 0 1" />
-  <color
-      name="ColorPaletteEntry05"
-      value="0 0.5 0 1" />
-  <color
-      name="ColorPaletteEntry06"
-      value="0 0.5 0.5 1" />
-  <color
-      name="ColorPaletteEntry07"
-      value="0 0 0.5 1" />
-  <color
-      name="ColorPaletteEntry08"
-      value="0.5 0 0.5 1" />
-  <color
-      name="ColorPaletteEntry09"
-      value="0.5 0.5 0 1" />
-  <color
-      name="ColorPaletteEntry10"
-      value="0 0.25 0.25 1" />
-  <color
-      name="ColorPaletteEntry11"
-      value="0 0.5 1 1" />
-  <color
-      name="ColorPaletteEntry12"
-      value="0 0.25 0.5 1" />
-  <color
-      name="ColorPaletteEntry13"
-      value="0.5 0 1 1" />
-  <color
-      name="ColorPaletteEntry14"
-      value="0.5 0.25 0 1" />
-  <color
-      name="ColorPaletteEntry15"
-      reference="White" />
-  <color
-      name="ColorPaletteEntry16"
-      reference="LtYellow" />
-  <color
-      name="ColorPaletteEntry17"
-      reference="White" />
-  <color
-      name="ColorPaletteEntry18"
-      reference="LtGray" />
-  <color
-      name="ColorPaletteEntry19"
-      reference="Red" />
-  <color
-      name="ColorPaletteEntry20"
-      reference="Yellow" />
-  <color
-      name="ColorPaletteEntry21"
-      reference="Green" />
-  <color
-      name="ColorPaletteEntry22"
-      value="0 1 1 1" />
-  <color
-      name="ColorPaletteEntry23"
-      reference="Blue" />
-  <color
-      name="ColorPaletteEntry24"
-      reference="Purple" />
-  <color
-      name="ColorPaletteEntry25"
-      value="1 1 0.5 1" />
-  <color
-      name="ColorPaletteEntry26"
-      value="0 1 0.5 1" />
-  <color
-      name="ColorPaletteEntry27"
-      value="0.5 1 1 1" />
-  <color
-      name="ColorPaletteEntry28"
-      value="0.5 0.5 1 1" />
-  <color
-      name="ColorPaletteEntry29"
-      value="1 0 0.5 1" />
-  <color
-      name="ColorPaletteEntry30"
-      value="1 0.5 0 1" />
-  <color
-      name="ColorPaletteEntry31"
-      reference="White" />
-  <color
-      name="ColorPaletteEntry32"
-      reference="White" />
-  <color
-      name="ComboListBgColor"
-      reference="DkGray" />
-  <color
-      name="ConsoleBackground"
-      reference="Black" />
-  <color
-      name="ContextSilhouetteColor"
-      reference="EmphasisColor" />
-  <color
-      name="DefaultHighlightDark"
-      reference="White_10" />
-  <color
-      name="DefaultHighlightLight"
-      reference="White_25" />
-  <color
-      name="DefaultShadowDark"
-      reference="Black_50" />
-  <color
-      name="DefaultShadowLight"
-      reference="Black_50" />
-  <color
-      name="EffectColor"
-      reference="White" />
-  <color
-      name="FilterBackgroundColor"
-      reference="Black" />
-  <color
-      name="FilterTextColor"
-      value="0.38 0.69 0.57 1" />
-  <color
-      name="FloaterButtonImageColor"
-      reference="LtGray" />
-  <color
-      name="FloaterDefaultBackgroundColor"
-      reference="DkGray_66" />
-  <color
-      name="FloaterFocusBackgroundColor"
-      reference="DkGray2" />
-  <color
-      name="FloaterFocusBorderColor"
-      reference="Black_50" />
-  <color
-      name="FloaterUnfocusBorderColor"
-      reference="Black_50" />
-  <color
-      name="FocusColor"
-      reference="EmphasisColor" />
-  <color
-      name="FolderViewLoadingMessageTextColor"
-      value="0.3344 0.5456 0.5159 1" />
-  <color
-      name="GridFocusPointColor"
-      reference="White_50" />
-  <color
-      name="GridlineBGColor"
-      value="0.92 0.92 1 0.78" />
-  <color
-      name="GridlineColor"
-      reference="White" />
-  <color
-      name="GridlineShadowColor"
-      value="0 0 0 0.31" />
-  <color
-      name="GroupNotifyBoxColor"
-      value="0.3344 0.5456 0.5159 1" />
-  <color
-      name="GroupNotifyTextColor"
-      reference="White"/>
-  <color
-      name="GroupNotifyDimmedTextColor"
-      reference="LtGray" />
-  <color
-      name="GroupOverTierColor"
-      value="0.43 0.06 0.06 1" />
-  <color
-      name="HTMLLinkColor"
-      reference="EmphasisColor" />
-  <color
-      name="HealthTextColor"
-      reference="White" />
-  <color
-      name="HelpBgColor"
-      reference="Unused?" />
-  <color
-      name="HelpFgColor"
-      reference="Unused?" />
-  <color
-      name="HelpScrollHighlightColor"
-      reference="Unused?" />
-  <color
-      name="HelpScrollShadowColor"
-      reference="Unused?" />
-  <color
-      name="HelpScrollThumbColor"
-      reference="Unused?" />
-  <color
-      name="HelpScrollTrackColor"
-      reference="Unused?" />
-  <color
-      name="HighlightChildColor"
-      reference="Yellow" />
-  <color
-      name="HighlightInspectColor"
-      value="1 0 1 1" />
-  <color
-      name="HighlightParentColor"
-      value="0.67 0.83 0.96 1" />
-  <color
-      name="IMHistoryBgColor"
-      reference="Unused?" />
-  <color
-      name="IMHistoryTextColor"
-      reference="Unused?" />
-  <color
-      name="IconDisabledColor"
-      reference="White_25" />
-  <color
-      name="IconEnabledColor"
-      reference="White" />
-  <color
-      name="InventoryBackgroundColor"
-      reference="DkGray2" />
-  <color
-      name="InventoryFocusOutlineColor"
-      reference="White_25" />
-  <color
-      name="InventoryItemSuffixColor"
-      reference="White_25" />
-  <color
-      name="InventoryItemLibraryColor"
-      reference="EmphasisColor" />
-  <color
-      name="InventoryItemLinkColor"
-      reference="LtGray_50" />
-  <color
-      name="InventoryMouseOverColor"
-      reference="LtGray_35" />
-  <color
-      name="InventorySearchStatusColor"
-      reference="EmphasisColor" />
-  <color
-      name="LabelDisabledColor"
-      reference="White_25" />
-  <color
-      name="LabelSelectedColor"
-      reference="White" />
-  <color
-      name="LabelSelectedDisabledColor"
-      reference="White_25" />
-  <color
-      name="LabelTextColor"
-      reference="LtGray" />
-  <color
-      name="LoginProgressBarBgColor"
-      reference="Unused?" />
-  <color
-      name="LoginProgressBarFgColor"
-      reference="Unused?" />
-  <color
-      name="LoginProgressBoxBorderColor"
-      value="0 0.12 0.24 0" />
-  <color
-      name="LoginProgressBoxCenterColor"
-      value="0 0 0 0.78" />
-  <color
-      name="LoginProgressBoxShadowColor"
-      value="0 0 0 0.78" />
-  <color
-      name="LoginProgressBoxTextColor"
-      reference="White" />
-  <color
-      name="MapAvatarColor"
-      reference="Green" />
-  <color
-      name="MapAvatarFriendColor"
-      reference="Yellow" />
-  <color
-      name="MapAvatarSelfColor"
-      value="0.53125 0 0.498047 1" />
-  <color
-      name="MapFrustumColor"
-      reference="White_10" />
-  <color
-      name="MapFrustumRotatingColor"
-      value="1 1 1 0.2" />
-  <color
-      name="MapTrackColor"
-      reference="Red" />
-  <color
-      name="MapTrackDisabledColor"
-      value="0.5 0 0 1" />
-  <color
-      name="MenuBarBgColor"
-      reference="DkGray" />
-  <color
-      name="MenuBarGodBgColor"
-      reference="FrogGreen" />
-  <color
-      name="MenuDefaultBgColor"
-      reference="DkGray2" />
-  <color
-      name="MenuItemDisabledColor"
-      reference="LtGray_50" />
-  <color
-      name="MenuItemEnabledColor"
-      reference="LtGray" />
-  <color
-      name="MenuItemHighlightBgColor"
-      reference="EmphasisColor_35" />
-  <color
-      name="MenuItemHighlightFgColor"
-      reference="White" />
-  <color
-      name="MenuNonProductionBgColor"
-      reference="Black" />
-  <color
-      name="MenuNonProductionGodBgColor"
-      value="0.263 0.325 0.345 1" />
-  <color
-      name="MenuPopupBgColor"
-      reference="DkGray2" />
-  <color
-      name="ModelUploaderLabels"
-      value="1 0.6 0 1" />	  
-  <color
-      name="MultiSliderDisabledThumbColor"
-      reference="Black" />
-  <color
-      name="MultiSliderThumbCenterColor"
-      reference="White" />
-  <color
-      name="MultiSliderThumbCenterSelectedColor"
-      reference="Green" />
-  <color
-      name="MultiSliderThumbOutlineColor"
-      reference="Unused?" />
-  <color
-      name="MultiSliderTrackColor"
-      reference="LtGray" />
-  <color
-      name="MultiSliderTriangleColor"
-      reference="Yellow" />
+    <color
+     name="AccordionHeaderTextColor"
+     reference="LtGray" />
+    <color
+     name="AgentChatColor"
+     reference="White" />
+    <color
+     name="AlertBoxColor"
+     value="0.24 0.24 0.24 1" />
+    <color
+     name="AlertCautionBoxColor"
+     value="1 0.82 0.46 1" />
+    <color
+     name="AlertCautionTextColor"
+     reference="LtYellow" />
+    <color
+     name="AvatarListItemIconDefaultColor"
+     reference="White" />
+    <color
+     name="AvatarListItemIconOnlineColor"
+     reference="White" />
+    <color
+     name="AvatarListItemIconOfflineColor"
+     value="0.5 0.5 0.5 0.5" />
+    <color
+     name="AvatarListItemIconVoiceInvitedColor"
+     reference="AvatarListItemIconOfflineColor" />
+    <color
+     name="AvatarListItemIconVoiceJoinedColor"
+     reference="AvatarListItemIconOnlineColor" />
+    <color
+     name="AvatarListItemIconVoiceLeftColor"
+     reference="AvatarListItemIconOfflineColor" />
+    <color
+     name="BadgeImageColor"
+     value="1.0 0.40 0.0 1.0" />
+    <color
+     name="BadgeBorderColor"
+     value="0.9 0.9 0.9 1.0" />
+    <color
+     name="BadgeLabelColor"
+     reference="White" />
+    <color
+     name="ButtonBorderColor"
+     reference="Unused?" />
+    <color
+     name="ButtonCautionImageColor"
+     reference="Unused?" />
+    <color
+     name="ButtonColor"
+     reference="Unused?" />
+    <color
+     name="ButtonFlashBgColor"
+     reference="Unused?" />
+    <color
+     name="ButtonImageColor"
+     reference="White" />
+    <color
+     name="ButtonLabelColor"
+     reference="LtGray" />
+    <color
+     name="ButtonLabelDisabledColor"
+     reference="White_25" />
+    <color
+     name="ButtonLabelSelectedColor"
+     reference="White" />
+    <color
+     name="ButtonLabelSelectedDisabledColor"
+     reference="White_25" />
+    <color
+     name="ButtonSelectedBgColor"
+     reference="Unused?" />
+    <color
+     name="ButtonSelectedColor"
+     reference="Unused?" />
+    <color
+     name="ButtonUnselectedBgColor"
+     reference="Unused?" />
+    <color
+     name="ButtonUnselectedFgColor"
+     reference="Unused?" />
+    <color
+     name="ChatHistoryBgColor"
+     reference="Transparent" />
+    <color
+     name="ChatHistoryTextColor"
+     reference="LtGray" />
+    <color
+     name="ChicletFlashColor"
+     value="0.114 0.65 0.1" />
+    <color
+     name="ColorDropShadow"
+     reference="Black_50" />
+    <color
+     name="ColorPaletteEntry01"
+     reference="Black" />
+    <color
+     name="ColorPaletteEntry02"
+     reference="Gray" />
+    <color
+     name="ColorPaletteEntry03"
+     value="0.5 0 0 1" />
+    <color
+     name="ColorPaletteEntry04"
+     value="0.5 0.5 0 1" />
+    <color
+     name="ColorPaletteEntry05"
+     value="0 0.5 0 1" />
+    <color
+     name="ColorPaletteEntry06"
+     value="0 0.5 0.5 1" />
+    <color
+     name="ColorPaletteEntry07"
+     value="0 0 0.5 1" />
+    <color
+     name="ColorPaletteEntry08"
+     value="0.5 0 0.5 1" />
+    <color
+     name="ColorPaletteEntry09"
+     value="0.5 0.5 0 1" />
+    <color
+     name="ColorPaletteEntry10"
+     value="0 0.25 0.25 1" />
+    <color
+     name="ColorPaletteEntry11"
+     value="0 0.5 1 1" />
+    <color
+     name="ColorPaletteEntry12"
+     value="0 0.25 0.5 1" />
+    <color
+     name="ColorPaletteEntry13"
+     value="0.5 0 1 1" />
+    <color
+     name="ColorPaletteEntry14"
+     value="0.5 0.25 0 1" />
+    <color
+     name="ColorPaletteEntry15"
+     reference="White" />
+    <color
+     name="ColorPaletteEntry16"
+     reference="LtYellow" />
+    <color
+     name="ColorPaletteEntry17"
+     reference="White" />
+    <color
+     name="ColorPaletteEntry18"
+     reference="LtGray" />
+    <color
+     name="ColorPaletteEntry19"
+     reference="Red" />
+    <color
+     name="ColorPaletteEntry20"
+     reference="Yellow" />
+    <color
+     name="ColorPaletteEntry21"
+     reference="Green" />
+    <color
+     name="ColorPaletteEntry22"
+     value="0 1 1 1" />
+    <color
+     name="ColorPaletteEntry23"
+     reference="Blue" />
+    <color
+     name="ColorPaletteEntry24"
+     reference="Purple" />
+    <color
+     name="ColorPaletteEntry25"
+     value="1 1 0.5 1" />
+    <color
+     name="ColorPaletteEntry26"
+     value="0 1 0.5 1" />
+    <color
+     name="ColorPaletteEntry27"
+     value="0.5 1 1 1" />
+    <color
+     name="ColorPaletteEntry28"
+     value="0.5 0.5 1 1" />
+    <color
+     name="ColorPaletteEntry29"
+     value="1 0 0.5 1" />
+    <color
+     name="ColorPaletteEntry30"
+     value="1 0.5 0 1" />
+    <color
+     name="ColorPaletteEntry31"
+     reference="White" />
+    <color
+     name="ColorPaletteEntry32"
+     reference="White" />
+    <color
+     name="ComboListBgColor"
+     reference="DkGray" />
+    <color
+     name="ConsoleBackground"
+     reference="Black" />
+    <color
+     name="ContextSilhouetteColor"
+     reference="EmphasisColor" />
+    <color
+     name="DefaultHighlightDark"
+     reference="White_10" />
+    <color
+     name="DefaultHighlightLight"
+     reference="White_25" />
+    <color
+     name="DefaultShadowDark"
+     reference="Black_50" />
+    <color
+     name="DefaultShadowLight"
+     reference="Black_50" />
+    <color
+     name="EffectColor"
+     reference="White" />
+     <color
+     name="FilterBackgroundColor"
+     reference="Black" />
+    <color
+     name="FilterTextColor"
+     value="0.38 0.69 0.57 1" />
+     <color
+     name="FloaterButtonImageColor"
+     reference="LtGray" />
+    <color
+     name="FloaterDefaultBackgroundColor"
+     reference="DkGray_66" />
+    <color
+     name="FloaterFocusBackgroundColor"
+     reference="DkGray2" />
+    <color
+     name="FloaterFocusBorderColor"
+     reference="Black_50" />
+    <color
+     name="FloaterUnfocusBorderColor"
+     reference="Black_50" />
+    <color
+     name="FocusColor"
+     reference="EmphasisColor" />
+    <color
+     name="FolderViewLoadingMessageTextColor"
+     value="0.3344 0.5456 0.5159 1" />
+    <color
+     name="GridFocusPointColor"
+     reference="White_50" />
+    <color
+     name="GridlineBGColor"
+     value="0.92 0.92 1 0.78" />
+    <color
+     name="GridlineColor"
+     reference="White" />
+    <color
+     name="GridlineShadowColor"
+     value="0 0 0 0.31" />
+    <color
+     name="GroupNotifyBoxColor"
+     value="0.3344 0.5456 0.5159 1" />
+    <color
+     name="GroupNotifyTextColor"
+     reference="White"/>
+    <color
+     name="GroupNotifyDimmedTextColor"
+     reference="LtGray" />
+    <color
+     name="GroupOverTierColor"
+     value="0.43 0.06 0.06 1" />
+    <color
+     name="HTMLLinkColor"
+     reference="EmphasisColor" />
+    <color
+     name="HealthTextColor"
+     reference="White" />
+    <color
+     name="HelpBgColor"
+     reference="Unused?" />
+    <color
+     name="HelpFgColor"
+     reference="Unused?" />
+    <color
+     name="HelpScrollHighlightColor"
+     reference="Unused?" />
+    <color
+     name="HelpScrollShadowColor"
+     reference="Unused?" />
+    <color
+     name="HelpScrollThumbColor"
+     reference="Unused?" />
+    <color
+     name="HelpScrollTrackColor"
+     reference="Unused?" />
+    <color
+     name="HighlightChildColor"
+     reference="Yellow" />
+    <color
+     name="HighlightInspectColor"
+     value="1 0 1 1" />
+    <color
+     name="HighlightParentColor"
+     value="0.67 0.83 0.96 1" />
+    <color
+     name="IMHistoryBgColor"
+     reference="Unused?" />
+    <color
+     name="IMHistoryTextColor"
+     reference="Unused?" />
+    <color
+     name="IconDisabledColor"
+	 reference="White_25" />
+    <color
+     name="IconEnabledColor"
+     reference="White" />
+    <color
+     name="InventoryBackgroundColor"
+     reference="DkGray2" />
+    <color
+     name="InventoryFocusOutlineColor"
+     reference="White_25" />
+    <color
+     name="InventoryItemSuffixColor"
+     reference="White_25" />
+    <color
+     name="InventoryItemLibraryColor"
+     reference="EmphasisColor" />
+    <color
+     name="InventoryItemLinkColor"
+     reference="LtGray_50" />
+    <color
+     name="InventoryMouseOverColor"
+     reference="LtGray_35" />
+    <color
+     name="InventorySearchStatusColor"
+     reference="EmphasisColor" />
+    <color
+     name="LabelDisabledColor"
+     reference="White_25" />
+    <color
+     name="LabelSelectedColor"
+     reference="White" />
+    <color
+     name="LabelSelectedDisabledColor"
+     reference="White_25" />
+    <color
+     name="LabelTextColor"
+     reference="LtGray" />
+    <color
+     name="LoginProgressBarBgColor"
+     reference="Unused?" />
+    <color
+     name="LoginProgressBarFgColor"
+     reference="Unused?" />
+    <color
+     name="LoginProgressBoxBorderColor"
+     value="0 0.12 0.24 0" />
+    <color
+     name="LoginProgressBoxCenterColor"
+     value="0 0 0 0.78" />
+    <color
+     name="LoginProgressBoxShadowColor"
+     value="0 0 0 0.78" />
+    <color
+     name="LoginProgressBoxTextColor"
+     reference="White" />
+    <color
+     name="MapAvatarColor"
+     reference="Green" />
+    <color
+     name="MapAvatarFriendColor"
+     reference="Yellow" />
+    <color
+     name="MapAvatarSelfColor"
+     value="0.53125 0 0.498047 1" />
+    <color
+     name="MapFrustumColor"
+     reference="White_10" />
+    <color
+     name="MapFrustumRotatingColor"
+     value="1 1 1 0.2" />
+    <color
+     name="MapTrackColor"
+     reference="Red" />
+    <color
+     name="MapTrackDisabledColor"
+     value="0.5 0 0 1" />
+    <color
+     name="MenuBarBgColor"
+     reference="DkGray" />
+    <color
+     name="MenuBarGodBgColor"
+     reference="FrogGreen" />
+    <color
+     name="MenuDefaultBgColor"
+     reference="DkGray2" />
+    <color
+     name="MenuItemDisabledColor"
+	 reference="LtGray_50" />
+    <color
+     name="MenuItemEnabledColor"
+     reference="LtGray" />
+    <color
+     name="MenuItemHighlightBgColor"
+     reference="EmphasisColor_35" />
+    <color
+     name="MenuItemFlashBgColor"
+     reference="BeaconColor" />
+    <color
+     name="MenuItemHighlightFgColor"
+     reference="White" />
+    <color
+     name="MenuNonProductionBgColor"
+     reference="Black" />
+    <color
+     name="MenuNonProductionGodBgColor"
+     value="0.263 0.325 0.345 1" />
+    <color
+     name="MenuPopupBgColor"
+	  reference="DkGray2" />
+    <color
+     name="ModelUploaderLabels"
+     value="1 0.6 0 1" />	  
+    <color
+     name="MultiSliderDisabledThumbColor"
+     reference="Black" />
+    <color
+     name="MultiSliderThumbCenterColor"
+     reference="White" />
+    <color
+     name="MultiSliderThumbCenterSelectedColor"
+     reference="Green" />
+    <color
+     name="MultiSliderThumbOutlineColor"
+     reference="Unused?" />
+    <color
+     name="MultiSliderTrackColor"
+     reference="LtGray" />
+    <color
+     name="MultiSliderTriangleColor"
+     reference="Yellow" />
   <!--
-      <color
+    <color
       name="NameTagBackground"
       value="0.85 0.85 0.85 0.80" />
-  -->
-  <color
+      -->
+    <color
       name="NameTagBackground"
       value="0 0 0 1" />
-  <color
-      name="NameTagChat"
-      reference="White" />
-  <color
-      name="NameTagFriend"
-      value="0.447 0.784 0.663 1" />
-  <color
-      name="NameTagLegacy"
-      reference="White" />
-  <color
-      name="NameTagMatch"
-      reference="White" />
-  <color
-      name="NameTagMismatch"
-      reference="White" />
-  <color
-      name="NetMapBackgroundColor"
-      value="0 0 0 1" />
-  <color
-      name="NetMapGroupOwnAboveWater"
-      reference="Purple" />
-  <color
-      name="NetMapGroupOwnBelowWater"
-      value="0.78 0 0.78 1" />
-  <color
-      name="NetMapOtherOwnAboveWater"
-      value="0.24 0.24 0.24 1" />
-  <color
-      name="NetMapOtherOwnBelowWater"
-      value="0.12 0.12 0.12 1" />
-  <color
-      name="NetMapYouOwnAboveWater"
-      value="0 1 1 1" />
-  <color
-      name="NetMapYouOwnBelowWater"
-      value="0 0.78 0.78 1" />
-  <color
-      name="NotifyBoxColor"
-      value="LtGray" />
-  <color
-      name="NotifyCautionBoxColor"
-      value="1 0.82 0.46 1" />
-  <color
-      name="NotifyCautionWarnColor"
-      reference="White" />
-  <color
-      name="NotifyTextColor"
-      reference="White" />
-  <color
-      name="ObjectBubbleColor"
-      reference="DkGray_66" />
-  <color
-      name="ObjectChatColor"
-      reference="EmphasisColor" />
-  <color
-      name="OverdrivenColor"
-      reference="Red" />
-  <color
-      name="PanelDefaultBackgroundColor"
-      reference="DkGray" />
-  <color
-      name="PanelDefaultHighlightLight"
-      reference="White_50" />
-  <color
-      name="PanelFocusBackgroundColor"
-      reference="DkGray2" />
-  <color
-      name="PanelNotificationBackground"
-      value="1 0.3 0.3 0" />
-  <color
-      name="ParcelHoverColor"
-      reference="White" />
-  <color
+    <color
+     name="NameTagChat"
+     reference="White" />
+    <color
+     name="NameTagFriend"
+     value="0.447 0.784 0.663 1" />
+    <color
+     name="NameTagLegacy"
+     reference="White" />
+    <color
+     name="NameTagMatch"
+     reference="White" />
+    <color
+     name="NameTagMismatch"
+     reference="White" />
+    <color
+     name="NetMapBackgroundColor"
+     value="0 0 0 1" />
+    <color
+     name="NetMapGroupOwnAboveWater"
+     reference="Purple" />
+    <color
+     name="NetMapGroupOwnBelowWater"
+     value="0.78 0 0.78 1" />
+    <color
+     name="NetMapOtherOwnAboveWater"
+     value="0.24 0.24 0.24 1" />
+    <color
+     name="NetMapOtherOwnBelowWater"
+     value="0.12 0.12 0.12 1" />
+    <color
+     name="NetMapYouOwnAboveWater"
+     value="0 1 1 1" />
+    <color
+     name="NetMapYouOwnBelowWater"
+     value="0 0.78 0.78 1" />
+    <color
+     name="NotifyBoxColor"
+     value="LtGray" />
+    <color
+     name="NotifyCautionBoxColor"
+     value="1 0.82 0.46 1" />
+    <color
+     name="NotifyCautionWarnColor"
+     reference="White" />
+    <color
+     name="NotifyTextColor"
+     reference="White" />
+    <color
+     name="ObjectBubbleColor"
+     reference="DkGray_66" />
+    <color
+     name="ObjectChatColor"
+     reference="EmphasisColor" />
+    <color
+     name="OverdrivenColor"
+     reference="Red" />
+    <color
+     name="PanelDefaultBackgroundColor"
+     reference="DkGray" />
+    <color
+     name="PanelDefaultHighlightLight"
+     reference="White_50" />
+    <color
+     name="PanelFocusBackgroundColor"
+     reference="DkGray2" />
+    <color
+     name="PanelNotificationBackground"
+     value="1 0.3 0.3 0" />
+    <color
+     name="ParcelHoverColor"
+     reference="White" />
+    <color
       name="PathfindingErrorColor"
       reference="LtRed" />
   <color
@@ -657,205 +663,205 @@
       name="PathfindingCharacterBeaconColor"
       reference="Red_80" />
   <color
-      name="PieMenuBgColor"
-      value="0.24 0.24 0.24 0.59" />
-  <color
-      name="PieMenuLineColor"
-      value="0 0 0 0.5" />
-  <color
-      name="PieMenuSelectedColor"
-      value="0.72 0.72 0.74 0.3" />
-  <color
-      name="PropertyColorAuction"
-      value="0.5 0 1 0.4" />
-  <color
-      name="PropertyColorAvail"
-      reference="Transparent" />
-  <color
-      name="PropertyColorForSale"
-      value="1 0.5 0 0.4" />
-  <color
-      name="PropertyColorGroup"
-      value="0 0.72 0.72 0.4" />
-  <color
-      name="PropertyColorOther"
-      value="1 0 0 0.4" />
-  <color
-      name="PropertyColorSelf"
-      value="0 1 0 0.4" />
-  <color
-      name="ScriptBgReadOnlyColor"
-      value="0.39 0.39 0.39 1" />
-  <color
-      name="ScriptErrorColor"
-      reference="Red" />
-  <color
-      name="ScrollBGStripeColor"
-      reference="Transparent" />
-  <color
-      name="ScrollBgReadOnlyColor"
+     name="PieMenuBgColor"
+     value="0.24 0.24 0.24 0.59" />
+    <color
+     name="PieMenuLineColor"
+     value="0 0 0 0.5" />
+    <color
+     name="PieMenuSelectedColor"
+     value="0.72 0.72 0.74 0.3" />
+    <color
+     name="PropertyColorAuction"
+     value="0.5 0 1 0.4" />
+    <color
+     name="PropertyColorAvail"
+     reference="Transparent" />
+    <color
+     name="PropertyColorForSale"
+     value="1 0.5 0 0.4" />
+    <color
+     name="PropertyColorGroup"
+     value="0 0.72 0.72 0.4" />
+    <color
+     name="PropertyColorOther"
+     value="1 0 0 0.4" />
+    <color
+     name="PropertyColorSelf"
+     value="0 1 0 0.4" />
+    <color
+     name="ScriptBgReadOnlyColor"
+     value="0.39 0.39 0.39 1" />
+    <color
+     name="ScriptErrorColor"
+     reference="Red" />
+    <color
+     name="ScrollBGStripeColor"
+     reference="Transparent" />
+    <color
+     name="ScrollBgReadOnlyColor"
       reference="Transparent" />
-  <color
-      name="ScrollBgWriteableColor"
-      reference="White_05" />
-  <color
-      name="ScrollDisabledColor"
-      reference="White_25" />
-  <color
-      name="ScrollHighlightedColor"
-      reference="Unused?" />
-  <color
-      name="ScrollHoveredColor"
-      reference="EmphasisColor_13" />
-  <color
-      name="ScrollSelectedBGColor"
-      reference="EmphasisColor_35" />
-  <color
-      name="ScrollSelectedFGColor"
-      reference="White" />
-  <color
-      name="ScrollUnselectedColor"
-      reference="LtGray" />
-  <color
-      name="ScrollbarThumbColor"
-      reference="White" />
-  <color
-      name="ScrollbarTrackColor"
-      reference="Black" />
-  <color
-      name="SelectedOutfitTextColor"
-      reference="EmphasisColor" />
-  <color
-      name="SilhouetteChildColor"
-      value="0.13 0.42 0.77 1" />
-  <color
-      name="SilhouetteParentColor"
-      reference="Yellow" />
-  <color
-      name="SliderDisabledThumbColor"
-      reference="White_25" />
-  <color
-      name="SliderThumbCenterColor"
-      reference="White" />
-  <color
-      name="SliderThumbOutlineColor"
-      reference="White" />
-  <color
-      name="SliderTrackColor"
-      reference="Unused?" />
-  <color
-      name="SpeakingColor"
-      reference="FrogGreen" />
-  <color
-      name="SystemChatColor"
-      reference="LtGray" />
-  <color
-      name="TextBgFocusColor"
-      reference="White" />
-  <color
-      name="TextBgReadOnlyColor"
-      reference="White_05" />
-  <color
-      name="TextBgWriteableColor"
-      reference="LtGray" />
-  <color
-      name="TextCursorColor"
-      reference="Black" />
-  <color
-      name="TextDefaultColor"
-      reference="Black" />
-  <color
-      name="TextEmbeddedItemColor"
-      value="0 0 0.5 1" />
-  <color
-      name="TextEmbeddedItemReadOnlyColor"
-      reference="Unused?" />
-  <color
-      name="TextFgColor"
-      value="0.102 0.102 0.102 1" />
-  <color
-      name="TextFgReadOnlyColor"
-      reference="LtGray" />
-  <color
-      name="TextFgTentativeColor"
-      value="0.4 0.4 0.4 1" />
-  <color
-      name="TimeTextColor"
-      reference="LtGray" />
-  <color
-      name="TitleBarFocusColor"
-      reference="White_10" />
-  <color
-      name="ToastBackground"
-      value="0.3 0.3 0.3 0" />
-  <color
-      name="ToolTipBgColor"
-      value="0.937 0.89 0.655 1" />
-  <color
-      name="ToolTipBorderColor"
-      value="0.812 0.753 0.451 1" />
-  <color
-      name="ToolTipTextColor"
-      reference="DkGray2" />
-  <color
-      name="InspectorTipTextColor"
-      reference="LtGray" />
-  <color
-      name="UserChatColor"
-      reference="White" />
-  <color
-      name="llOwnerSayChatColor"
-      reference="LtYellow" />
+    <color
+     name="ScrollBgWriteableColor"
+     reference="White_05" />
+    <color
+     name="ScrollDisabledColor"
+     reference="White_25" />
+    <color
+     name="ScrollHighlightedColor"
+     reference="Unused?" />
+    <color
+     name="ScrollHoveredColor"
+     reference="EmphasisColor_13" />
+    <color
+     name="ScrollSelectedBGColor"
+     reference="EmphasisColor_35" />
+    <color
+     name="ScrollSelectedFGColor"
+     reference="White" />
+    <color
+     name="ScrollUnselectedColor"
+     reference="LtGray" />
+    <color
+     name="ScrollbarThumbColor"
+     reference="White" />
+    <color
+     name="ScrollbarTrackColor"
+     reference="Black" />
+    <color
+     name="SelectedOutfitTextColor"
+     reference="EmphasisColor" />
+    <color
+     name="SilhouetteChildColor"
+     value="0.13 0.42 0.77 1" />
+    <color
+     name="SilhouetteParentColor"
+     reference="Yellow" />
+    <color
+     name="SliderDisabledThumbColor"
+     reference="White_25" />
+    <color
+     name="SliderThumbCenterColor"
+     reference="White" />
+    <color
+     name="SliderThumbOutlineColor"
+     reference="White" />
+    <color
+     name="SliderTrackColor"
+     reference="Unused?" />
+    <color
+     name="SpeakingColor"
+     reference="FrogGreen" />
+    <color
+     name="SystemChatColor"
+     reference="LtGray" />
+    <color
+     name="TextBgFocusColor"
+     reference="White" />
+    <color
+     name="TextBgReadOnlyColor"
+	 reference="White_05" />
+    <color
+     name="TextBgWriteableColor"
+     reference="LtGray" />
+    <color
+     name="TextCursorColor"
+     reference="Black" />
+    <color
+     name="TextDefaultColor"
+     reference="Black" />
+    <color
+     name="TextEmbeddedItemColor"
+     value="0 0 0.5 1" />
+    <color
+     name="TextEmbeddedItemReadOnlyColor"
+     reference="Unused?" />
+    <color
+     name="TextFgColor"
+     value="0.102 0.102 0.102 1" />
+    <color
+     name="TextFgReadOnlyColor"
+     reference="LtGray" />
+    <color
+     name="TextFgTentativeColor"
+     value="0.4 0.4 0.4 1" />
+    <color
+     name="TimeTextColor"
+     reference="LtGray" />
+    <color
+     name="TitleBarFocusColor"
+     reference="White_10" />
+    <color
+     name="ToastBackground"
+     value="0.3 0.3 0.3 0" />
+    <color
+     name="ToolTipBgColor"
+     value="0.937 0.89 0.655 1" />
+    <color
+     name="ToolTipBorderColor"
+     value="0.812 0.753 0.451 1" />
+    <color
+     name="ToolTipTextColor"
+     reference="DkGray2" />
+    <color
+     name="InspectorTipTextColor"
+     reference="LtGray" />
+    <color
+     name="UserChatColor"
+     reference="Yellow" />
+    <color
+     name="llOwnerSayChatColor"
+     reference="LtYellow" />
 
-  <!-- New Colors -->
-  <color
-      name="OutputMonitorMutedColor"
-      reference="DkGray2" />
-  <color
-      name="SysWellItemUnselected"
-      value="0 0 0 0" />
-  <color
-      name="SysWellItemSelected"
-      value="0.3 0.3 0.3 1.0" />
-  <color
-      name="ColorSwatchBorderColor"
-      value="0.45098 0.517647 0.607843 1"/>
-  <color
-      name="ChatTimestampColor"
-      reference="White" />
-  <color
-      name="MenuBarProjectBgColor"
-      reference="MdBlue" />
+    <!-- New Colors -->
+    <color
+     name="OutputMonitorMutedColor"
+     reference="DkGray2" />
+    <color
+     name="SysWellItemUnselected"
+     value="0 0 0 0" />
+    <color
+     name="SysWellItemSelected"
+     value="0.3 0.3 0.3 1.0" />
+    <color
+    name="ColorSwatchBorderColor"
+    value="0.45098 0.517647 0.607843 1"/>
+    <color
+     name="ChatTimestampColor"
+     reference="White" />
+    <color
+     name="MenuBarProjectBgColor"
+     reference="MdBlue" />
   
-  <color
+    <color
       name="MeshImportTableNormalColor"
       value="1 1 1 1"/>
-  <color
+    <color
       name="MeshImportTableHighlightColor"
       value="0.2 0.8 1 1"/>
 
-  <color
-      name="DirectChatColor"
-      reference="LtOrange" />
+    <color
+     name="DirectChatColor"
+     reference="LtOrange" />
 
-  <color
+    <color
       name="ToolbarDropZoneColor"
       value=".48 .69 1 .5" />
   
-  <!-- Generic color names (legacy) -->
+    <!-- Generic color names (legacy) -->
   <color
-      name="white"
-      value="1 1 1 1"/>
+    name="white"
+    value="1 1 1 1"/>
   <color
-      name="black"
-      value="0 0 0 1"/>
+    name="black"
+    value="0 0 0 1"/>
   <color
-      name="red"
-      value="1 0 0 1"/>
+    name="red"
+    value="1 0 0 1"/>
   <color
-      name="green"
-      value="0 1 0 1"/>
+    name="green"
+    value="0 1 0 1"/>
   <color
-      name="blue"
-      value="0 0 1 1"/>
+    name="blue"
+    value="0 0 1 1"/>
 </colors>
diff --git a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png b/indra/newview/skins/default/textures/bottomtray/Unread_IM.png
deleted file mode 100644
index 5c0c85b864e4d3c76c17fe10e46994e191cddf6e..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/Unread_IM.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png
deleted file mode 100644
index 857fa1e047887e58df3df1b5e01fe700b6ece21f..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl1_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png
deleted file mode 100644
index 453bb53673b91dc51624ec6341ad7aa8e5b883f5..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl2_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png
deleted file mode 100644
index 135a66ca0dd623c5e01ee4538f5a44460302b896..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Lvl3_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png
deleted file mode 100644
index a63aec5e6dc4dcc4f91cee641cbdefda52cf612b..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_Off_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png b/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png
deleted file mode 100644
index 1719eb3e84e0ad9788a322032750ea7f89a09ec8..0000000000000000000000000000000000000000
Binary files a/indra/newview/skins/default/textures/bottomtray/VoicePTT_On_Dark.png and /dev/null differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_log_inbox.png b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png
new file mode 100644
index 0000000000000000000000000000000000000000..bb6ca28147085c9054c3b459e19fd93ce20f0101
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_log_inbox.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png
new file mode 100755
index 0000000000000000000000000000000000000000..0631f16f3bffdbb399a3f0a8fb4294c860e5824e
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_add_person.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png
new file mode 100755
index 0000000000000000000000000000000000000000..578482f5ed786c49c02e66f05a4e73dd1b4b1a8c
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_ne.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png
new file mode 100755
index 0000000000000000000000000000000000000000..767613179099fb9f2691a309776412fafad36a27
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_arrow_sw.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png
new file mode 100755
index 0000000000000000000000000000000000000000..2880eb766a286b1b1fd6f71f52500aed5544c3d0
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_call_log.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png
new file mode 100755
index 0000000000000000000000000000000000000000..d009c8f446936f9e8513ebba7c3a9b7d2203ca90
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_close.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png
new file mode 100755
index 0000000000000000000000000000000000000000..8d82960e28c9b103b5c36fad0718254759da3c51
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_collapse.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png
new file mode 100755
index 0000000000000000000000000000000000000000..f718d3fc60580b56998b8c89965a19d962bb8881
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_expand.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png
new file mode 100755
index 0000000000000000000000000000000000000000..315e2c581ad6c04b6e98c62fa28a677ce04a493a
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_hang_up.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png
new file mode 100755
index 0000000000000000000000000000000000000000..732ab02a20cd8a99956bbda9a34547e4546d1a3f
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_open_call.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png
new file mode 100755
index 0000000000000000000000000000000000000000..25a32cb2ba94265a73a9a09342cba71f60dcfb95
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_plus.png differ
diff --git a/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png
new file mode 100755
index 0000000000000000000000000000000000000000..08debeb91f58d0219054a58632e227ac4cfc6335
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/Conv_toolbar_sort.png differ
diff --git a/indra/newview/skins/default/textures/icons/collapse_to_one_line.png b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png
new file mode 100644
index 0000000000000000000000000000000000000000..d57144a64598d1dda5d40ab564fb9a2bdd7b98bd
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/collapse_to_one_line.png differ
diff --git a/indra/newview/skins/default/textures/icons/expand_one_liner.png b/indra/newview/skins/default/textures/icons/expand_one_liner.png
new file mode 100644
index 0000000000000000000000000000000000000000..58b7d90131271665eb837e494ccf8b4156df3452
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/expand_one_liner.png differ
diff --git a/indra/newview/skins/default/textures/icons/nearby_chat_icon.png b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..5ac4258b9da117d316a5abf15c405d136a19fd48
Binary files /dev/null and b/indra/newview/skins/default/textures/icons/nearby_chat_icon.png differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 06f8f8c67051061f5bcc264b1f4c6ae456f203cc..fcab966dee78df48b26057a4b3457de3a6dc4ad8 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -162,7 +162,24 @@ with the same filename but different name
   <texture name="ComboButton_On" file_name="widgets/ComboButton_On.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
   <texture name="ComboButton_Off" file_name="widgets/ComboButton_Off.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
   <texture name="ComboButton_UpOff" file_name="widgets/ComboButton_UpOff.png" preload="true" scale.left="2" scale.top="19" scale.right="18" scale.bottom="2" />
+
   <texture name="Container" file_name="containers/Container.png" preload="false" />
+
+  <texture name="Conv_toolbar_add_person" file_name="icons/Conv_toolbar_add_person.png" preload="false" />
+  <texture name="Conv_toolbar_arrow_ne" file_name="icons/Conv_toolbar_arrow_ne.png" preload="false" />
+  <texture name="Conv_toolbar_arrow_sw" file_name="icons/Conv_toolbar_arrow_sw.png" preload="false" />
+  <texture name="Conv_toolbar_call_log" file_name="icons/Conv_toolbar_call_log.png" preload="false" />
+  <texture name="Conv_toolbar_close" file_name="icons/Conv_toolbar_close.png" preload="false" />
+  <texture name="Conv_toolbar_collapse" file_name="icons/Conv_toolbar_collapse.png" preload="false" />
+  <texture name="Conv_collapse_to_one_line" file_name="icons/collapse_to_one_line.png" preload="false" />
+  <texture name="Conv_expand_one_line" file_name="icons/expand_one_liner.png" preload="false" />
+  <texture name="Conv_toolbar_expand" file_name="icons/Conv_toolbar_expand.png" preload="false" />
+  <texture name="Conv_toolbar_hang_up" file_name="icons/Conv_toolbar_hang_up.png" preload="false" />
+  <texture name="Conv_toolbar_open_call" file_name="icons/Conv_toolbar_open_call.png" preload="false" />
+  <texture name="Conv_toolbar_plus" file_name="icons/Conv_toolbar_plus.png" preload="false" />
+  <texture name="Conv_toolbar_sort" file_name="icons/Conv_toolbar_sort.png" preload="false" />
+  <texture name="Conv_log_inbox" file_name="icons/Conv_log_inbox.png" preload="false" />
+
   <texture name="Copy" file_name="icons/Copy.png" preload="false" />
   
   <texture name="DisclosureArrow_Opened_Off" file_name="widgets/DisclosureArrow_Opened_Off.png" preload="true" />
@@ -348,6 +365,8 @@ with the same filename but different name
   <texture name="NavBar_BG_NoFav_Bevel" file_name="navbar/NavBar_BG_NoFav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
   <texture name="NavBar_BG_NoNav_Bevel" file_name="navbar/NavBar_BG_NoNav_Bevel.png" preload="true" scale.left="1" scale.top="1" scale.right="0" scale.bottom="0" />
 
+  <texture name="Nearby_chat_icon" file_name="icons/nearby_chat_icon.png" preload="false" />
+
   <texture name="Notices_Unread" file_name="bottomtray/Notices_Unread.png" preload="true" />
 
   <texture name="NoEntryLines" file_name="world/NoEntryLines.png" use_mips="true" preload="false" />
@@ -625,7 +644,6 @@ with the same filename but different name
   <texture name="TrashItem_Press" file_name="icons/TrashItem_Press.png" preload="false" />
 
   <texture name="Unread_Chiclet" file_name="bottomtray/Unread_Chiclet.png" preload="false" />
-  <texture name="Unread_IM" file_name="bottomtray/Unread_IM.png" preload="false" />
 
   <texture name="UpArrow_Off" file_name="icons/UpArrow_Off.png" preload="false" />
 
@@ -638,12 +656,6 @@ with the same filename but different name
   <texture name="VoicePTT_Off" file_name="bottomtray/VoicePTT_Off.png" preload="false" />
   <texture name="VoicePTT_On" file_name="bottomtray/VoicePTT_On.png" preload="false" />
   
-  <texture name="VoicePTT_Lvl1_Dark" file_name="bottomtray/VoicePTT_Lvl1_Dark.png" preload="false" />
-  <texture name="VoicePTT_Lvl2_Dark" file_name="bottomtray/VoicePTT_Lvl2_Dark.png" preload="false" />
-  <texture name="VoicePTT_Lvl3_Dark" file_name="bottomtray/VoicePTT_Lvl3_Dark.png" preload="false" />
-  <texture name="VoicePTT_Off_Dark" file_name="bottomtray/VoicePTT_Off_Dark.png" preload="false" />
-  <texture name="VoicePTT_On_Dark" file_name="bottomtray/VoicePTT_On_Dark.png" preload="false" />
-
   <texture name="Wearables_Divider" file_name="windows/Wearables_Divider.png" preload="false" />
 
   <texture name="Web_Profile_Off" file_name="icons/Web_Profile_Off.png" preload="false" />
@@ -712,9 +724,6 @@ with the same filename but different name
   <texture name="icon_for_sale.tga" file_name="icons/Icon_For_Sale.png" />
   <texture name="icon_top_pick.tga" />
 
-  <texture name="inv_folder_mesh.tga"/>
-  <texture name="inv_item_mesh.tga"/>
-
   <texture name="lag_status_critical.tga" />
   <texture name="lag_status_good.tga" />
   <texture name="lag_status_warning.tga" />
diff --git a/indra/newview/skins/default/xui/da/menu_im_well_button.xml b/indra/newview/skins/default/xui/da/menu_im_well_button.xml
deleted file mode 100644
index 4889230919b28cec0dbb62efdcd33201725015d6..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/da/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Luk alle" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
index 949cbcbd7b44f16f331bc576f8b41f616f7ddaa4..eb104201f8a08ba0d226a1288e519a18b4652d4b 100644
--- a/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/da/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Klik her for at chatte." name="chat_box" tool_tip="Tryk på enter for at tale, Ctrl-Enter for at råbe."/>
 	<button name="show_nearby_chat" tool_tip="Viser/skjuler log for chat nærved"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/de/floater_chat_bar.xml b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
index 2464a55665e48235b9741c54dc52048806046b0f..ab77d4dae50306c8ff0f28222790041a674f65cb 100644
--- a/indra/newview/skins/default/xui/de/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT IN DER NÄHE">
+<floater name="nearby_chat" title="CHAT IN DER NÄHE">
 	<panel name="bottom_panel">
 		<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabetaste zum Sprechen, Strg+Eingabe zum Rufen"/>
 		<button name="show_nearby_chat" tool_tip="Chatprotokoll in der Nähe ein-/ausblenden"/>
diff --git a/indra/newview/skins/default/xui/de/menu_im_well_button.xml b/indra/newview/skins/default/xui/de/menu_im_well_button.xml
deleted file mode 100644
index f464b71f4a7062e50df3b217e40323ef2dff7912..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/de/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Alle schließen" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
index 08cc0b0ec8a9eba5f64314fa71cb11bfe9422cfd..69cf6d98de6bdf4d1712e15ea62d588b01fd1300 100644
--- a/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/de/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Zum Chatten hier klicken." name="chat_box" tool_tip="Eingabe drücken, um zu sprechen, Strg-Eingabe drücken, um zu Rufen."/>
 	<button name="show_nearby_chat" tool_tip="Protokoll des Chats in der Nähe anzeigen/ausblenden"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/floater_camera.xml b/indra/newview/skins/default/xui/en/floater_camera.xml
index 22bc488a925377a06c974a10b9bd11393c3f726f..521389d7b3a18582eb9e43da4340127263af4b0f 100644
--- a/indra/newview/skins/default/xui/en/floater_camera.xml
+++ b/indra/newview/skins/default/xui/en/floater_camera.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="458"
- bottom="-80"
+ right="-460"
+ bottom="-50"
  follows="left|bottom"
  legacy_header_height="18"
  can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_chat_bar.xml b/indra/newview/skins/default/xui/en/floater_chat_bar.xml
deleted file mode 100644
index 405557242fa8c47465c5d6bf828a98b02f120fd4..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_chat_bar.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="specified"
- left="10"
- bottom="-10"
- height="60"
- layout="topleft"
- legacy_header_height="25"
- single_instance="true"
- title="NEARBY CHAT"
- save_rect="true"
- save_visibility="true"
- can_close="true"
- can_minimize="true"
- help_topic="chat_bar"
- min_height="60"
- min_width="150"
- can_resize="true"
- default_tab_group="1"
- name="chat_bar"
- width="300">
-    <panel
-        top="20"
-        class="panel_nearby_chat"
-        follow="all"
-        width="300"
-        height="0"
-        visible="false"
-        filename="panel_nearby_chat.xml"
-        name="nearby_chat" />
-    <panel width="300" 
-           height="31" 
-           left="0" 
-           name="bottom_panel"
-           bottom="-1" 
-           follows="left|right|bottom" 
-           tab_group="1">
-      <line_editor
-        border_style="line"
-        border_thickness="1"
-        follows="left|right"
-        height="23"
-        label="Click here to chat."
-        layout="topleft"
-        left_delta="7"
-        left="0"
-        max_length_bytes="1023"
-        name="chat_box"
-        spellcheck="true"
-        text_pad_left="5"
-        text_pad_right="25"
-        tool_tip="Press Enter to say, Ctrl+Enter to shout"
-        top="2"
-        width="255" />
-      <output_monitor
-        auto_update="true"
-        follows="right"
-        draw_border="false"
-        height="16"
-        layout="topleft"
-        left_pad="-24"
-        mouse_opaque="true"
-        name="chat_zone_indicator"
-        top="6"
-        visible="true"
-        width="20" />
-      <button
-        follows="right"
-        is_toggle="true"
-        width="20"
-        top="2"
-        layout="topleft"
-        left_pad="12"
-        image_disabled="ComboButton_UpOff"
-        image_unselected="ComboButton_UpOff"
-        image_selected="ComboButton_On"
-        image_pressed="ComboButton_UpSelected"
-        image_pressed_selected="ComboButton_Selected"
-        height="23"
-        chrome="true"
-        name="show_nearby_chat"
-        tool_tip="Shows/hides nearby chat log">
-      </button>
-    </panel>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_log.xml b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
new file mode 100644
index 0000000000000000000000000000000000000000..19a4cbc11983e430ee7cbf979e7fbed2c2478f88
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_log.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
+
+<floater
+ can_resize="true"
+ positioning="cascading"
+ help_topic="conversation_log"
+ height="200"
+ min_height="100"
+ min_width="230"
+ layout="topleft"
+ name="floater_conversation_log"
+ save_rect="true"
+ single_instance="true"
+ reuse_instance="true"
+ title="CONVERSATION LOG"
+ width="300">
+  <panel
+   follows="left|top|right"
+   height="32"
+   left="0"
+   name="buttons_panel"
+   top="0">
+    <filter_editor
+     follows="left|top|right"
+     height="23"
+     layout="topleft"
+     left="8"
+     label="Filter People"
+     max_length_chars="300"
+     name="people_filter_input"
+     text_color="Black"
+     text_pad_left="10"
+     top="4"
+     width="204" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="Conv_toolbar_sort"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     menu_filename="menu_conversation_log_view.xml"
+     menu_position="bottomleft"
+     name="conversation_view_btn"
+     tool_tip="View/sort options"
+     top="3"
+     width="31" />
+    <menu_button
+     follows="top|right"
+     height="25"
+     image_hover_unselected="Toolbar_Middle_Over"
+     image_overlay="OptionsMenu_Off"
+     image_selected="Toolbar_Middle_Selected"
+     image_unselected="Toolbar_Middle_Off"
+     layout="topleft"
+     left_pad="8"
+     name="conversations_gear_btn"
+     tool_tip="Actions on selected person or group"
+     top="3"
+     width="31" />
+  </panel>
+  <panel
+   bottom="-1"
+   follows="all"
+   left="0"
+   name="log_panel"
+   right="-1"
+   top="32">
+    <conversation_log_list
+     allow_select="true"
+     bottom="-8"
+     opaque="true"
+     follows="all"
+     left="8"
+     keep_selection_visible_on_reshape="true"
+     item_pad="2"
+     multi_select="false"
+     name="conversation_log_list"
+     right="-8"
+     top="0" />
+  </panel>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_conversation_preview.xml b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
new file mode 100644
index 0000000000000000000000000000000000000000..764b9d8385096446416f0e3aadfe5156b9a59dd6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_conversation_preview.xml
@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ can_resize="true"
+ default_tab_group="1"
+ help_topic="conversation_preview"
+ height="391"
+ layout="topleft"
+ min_height="243"
+ min_width="234"
+ name="preview_conversation"
+ title="CONVERSATION:"
+ width="400">
+    <floater.string
+     name="Title">
+        CONVERSATION: [NAME]
+    </floater.string>
+    <chat_history
+     font="SansSerifSmall"
+     follows="all"
+     visible="true"
+     height="330"
+     name="chat_history"
+     notify_unread_msg="false"
+     parse_highlights="true"
+     parse_urls="true"
+     left="5"
+     top_pad="25"
+     width="390">
+    </chat_history>
+    <text
+     follows="bottom|right"
+     font="SansSerif"
+     height="22"
+     layout="topleft"
+     name="page_label"
+     right="-110"
+     top_pad="7"
+     value="Page"
+     width="35">
+    </text>
+    <spinner
+     allow_digits_only="true"
+     decimal_digits="0"
+     follows="bottom|right"
+     height="23"
+     increment="1"
+     label_width="40"
+     layout="topleft"
+     left_pad="0"
+     name="history_page_spin"
+     top_delta="-3"
+     width="50"/>
+    <text
+     follows="bottom|right"
+     font="SansSerif"
+     height="22"
+     layout="topleft"
+     name="page_num_label"
+     left_pad="5"
+     top_delta="4"
+     width="40">
+    </text>
+</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_destinations.xml b/indra/newview/skins/default/xui/en/floater_destinations.xml
index 39aa8e07bb647b5131ad52614b8429aa6d4b2d33..94ebaa9cb2ed7026979860aef3c49eeca6a7ab55 100644
--- a/indra/newview/skins/default/xui/en/floater_destinations.xml
+++ b/indra/newview/skins/default/xui/en/floater_destinations.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- positioning="cascading"
+ positioning="cascading"	
  ignore_ui_scale="false"
  legacy_header_height="225"
  can_minimize="true"
@@ -17,11 +17,11 @@
  save_rect="true"
  save_visibility="true"
  title="DESTINATIONS"
- width="840">
+ width="550">
     <web_browser
       top="25"
       height="200"
-      width="840"
+      width="550"
       follows="all"
       name="destination_guide_contents"
       trusted_content="true"/>
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 e123de46c2046b6f3c63a142ce16f6182e7d3e7f..65f623a47e88a7a86b233ef32c790a08a5e6c1e8 100644
--- a/indra/newview/skins/default/xui/en/floater_im_container.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_container.xml
@@ -1,49 +1,180 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <multi_floater
- can_close="false"  
+ can_close="true"  
  can_minimize="true"
  can_resize="true"
- height="390"
+ height="210"
  layout="topleft"
  name="floater_im_box"
  help_topic="floater_im_box"
  save_rect="true"
  save_visibility="true"
  single_instance="true"
+ reuse_instance="true"
  title="CONVERSATIONS"
- width="396">
-    <tab_container
-     follows="left|right|top|bottom"
-     height="390"
+ bottom="-50"
+ right="-5"
+ width="450"
+ min_width="38">
+    <string
+     name="collapse_icon"
+     value="Conv_toolbar_collapse"/>
+    <string
+     name="expand_icon"
+     value="Conv_toolbar_expand"/>
+    <layout_stack
+     animate="true" 
+     bottom="-1"
+     follows="all"
      layout="topleft"
-     left="1"
-     name="im_box_tab_container"
-     tab_position="bottom"
-     tab_width="64"
-     tab_max_width = "134"
-     tab_height="16"
-     use_custom_icon_ctrl="true"
-     tab_icon_ctrl_pad="2"
-     halign="left"
-     use_ellipses="true"
-     top="0"
-     width="394">
-      <first_tab
-       tab_bottom_image_flash="Toolbar_Left_Flash"/>
-      <middle_tab
-       tab_bottom_image_flash="Toolbar_Middle_Flash"/>
-      <last_tab
-       tab_bottom_image_flash="Toolbar_Right_Flash"/>
-    </tab_container>
-    <icon
-     color="DefaultShadowLight"
-     enabled="false"
-     follows="left|right|bottom"
-     height="17"
-     image_name="tabarea.tga"
-     layout="bottomleft"
-     left="1"
-     name="im_box_tab_container_icon"
-     bottom="10"
-     width="394" />
+     left="0"
+     name="conversations_stack"
+     orientation="horizontal"
+     right="-1"
+     top="0">
+        <layout_panel
+         auto_resize="false"
+         user_resize="true"        
+         name="conversations_layout_panel"
+         min_dim="38"
+         expanded_min_dim="156">
+            <layout_stack
+             animate="false" 
+             follows="left|top|right"
+             height="35"
+             layout="topleft"
+             left="0"
+             name="conversations_pane_buttons_stack"
+             orientation="horizontal"
+             right="-1"
+             top="0">
+                <layout_panel
+                 auto_resize="true"
+                 height="35"
+                 name="conversations_pane_buttons_expanded">
+                    <menu_button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="Conv_toolbar_sort"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     menu_filename="menu_participant_view.xml"
+                     layout="topleft"
+                     left="5"
+                     name="sort_btn"
+                     tool_tip="View/sort options"
+                     top="5"
+                     width="31" />
+                    <button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="Conv_toolbar_plus"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="5"
+                     left_pad="2"
+                     name="add_btn"
+                     tool_tip="Start a new conversation"
+                     width="31"/>
+                    <button
+                     follows="top|left"
+                     height="25"
+                     image_hover_unselected="Toolbar_Middle_Over"
+                     image_overlay="Command_Speak_Icon"
+                     image_selected="Toolbar_Middle_Selected"
+                     image_unselected="Toolbar_Middle_Off"
+                     layout="topleft"
+                     top="5"
+                     left_pad="2"
+                     name="speak_btn"
+                     tool_tip="Speak with people using your microphone"
+                     width="31"/>	
+                </layout_panel>
+                <layout_panel
+                 auto_resize="false"
+                 height="35"
+                 name="conversations_pane_buttons_collapsed"
+                 width="41">
+                    <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="5"
+                     left="1"
+                     name="expand_collapse_btn"
+                     tool_tip="Collapse/Expand this list"
+                     width="31" />
+                </layout_panel>
+            </layout_stack>
+            <panel
+             bottom="-1"
+             follows="all"
+             layout="topleft"
+             name="conversations_list_panel"
+             opaque="true"
+             top="35"
+             left="5"
+             right="-1"/>
+        </layout_panel>
+        <layout_panel
+         auto_resize="true"
+         user_resize="true"
+         name="messages_layout_panel"
+         expanded_min_dim="222">
+            <panel_container
+             bottom="-1"
+             follows="all"
+             layout="topleft"
+             left="0"
+             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"
+                 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>
+            </panel_container>
+        </layout_panel>
+    </layout_stack>
 </multi_floater>
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 040b66623e72940042b0416980bf838890a5fc15..2152a9f6e9acc944660c5ef7b3c1ae95d010e90c 100644
--- a/indra/newview/skins/default/xui/en/floater_im_session.xml
+++ b/indra/newview/skins/default/xui/en/floater_im_session.xml
@@ -1,6 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
- legacy_header_height="18"
  background_visible="true"
  default_tab_group="1"
  height="355"
@@ -10,84 +9,328 @@
  can_dock="false"
  can_minimize="true"
  can_close="true"
+ save_rect="true"
  visible="false"
  width="394"
  can_resize="true"
- min_width="250"
- min_height="190">
-  <layout_stack
-   animate="true" 
-   default_tab_group="2"
-  follows="all"
-  height="320"
-  width="394"
-  layout="topleft"
-  orientation="horizontal"
-  name="im_panels"
-  tab_group="1"
-  top="20"
-  left="0">
-    <layout_panel
-      name="im_control_panel_holder"
-      min_width="115"
-      width="150" 
-      height="320" 
-      auto_resize="false">
-      <panel
-        name="panel_im_control_panel"
-        layout="topleft"
-        height="320"
-        width="150" 
-        follows="all"/>
-      </layout_panel>
-    <layout_panel
-       default_tab_group="3"
-       left="0"
-       tab_group="2"
-       top="0"
-       height="200"
-	     width="244"
-       user_resize="true">
-        <button
-          height="20"
-          follows="left|top"
-          top="0"
-          left="2"
-          image_overlay="TabIcon_Open_Off"
-          layout="topleft"
-          width="25"
-          name="slide_left_btn" />
-         <button
-          height="20"
-          follows="left|top"
-          top="0"
-          left="2"
-          image_overlay="TabIcon_Close_Off"
-          width="25"
-          name="slide_right_btn" />
-        <chat_history
-	 font="SansSerifSmall"
-         follows="left|right|top|bottom"
-         height="150"
-         name="chat_history"
-         parse_highlights="true"
-         parse_urls="true"
-        left="1"
-         width="238">
-        </chat_history>
-        <line_editor
-         bottom="0"
-         left="3"
-         follows="left|right|bottom"
-	 font="SansSerifSmall"
-         height="20"
-         label="To"
-         layout="bottomleft"
-         name="chat_editor"
-         spellcheck="true"
-         tab_group="3"
-         width="236">
-        </line_editor>
-    </layout_panel>
-  </layout_stack>
+ can_tear_off="false"
+ min_height="190"
+ positioning="relative">
+    <floater.string name="call_btn_start">Conv_toolbar_open_call</floater.string>
+    <floater.string name="call_btn_stop">Conv_toolbar_hang_up</floater.string>
+    <floater.string
+     name="collapseline_icon"
+     value="Conv_collapse_to_one_line"/>
+    <floater.string
+     name="expandline_icon"
+     value="Conv_expand_one_line"/>
+    <floater.string
+     name="collapse_icon"
+     value="Conv_toolbar_collapse"/>
+    <floater.string
+     name="expand_icon"
+     value="Conv_toolbar_expand"/>
+    <floater.string
+     name="tear_off_icon"
+     value="Conv_toolbar_arrow_ne"/>
+    <floater.string
+     name="return_icon"
+     value="Conv_toolbar_arrow_sw"/>
+    <floater.string
+     name="participant_added"
+     value="[NAME] was invited to the conversation."/>
+    <floater.string
+     name="multiple_participants_added"
+     value="[NAME] were invited to the conversation."/>
+    <floater.string
+     name="tooltip_to_separate_window"
+     value="Move this conversation to a separate window"/>
+    <floater.string
+     name="tooltip_to_main_window"
+     value="Move this conversation back to main window"/>
+    <floater.string
+     name="start_call_button_tooltip"
+     value="Open voice connection"/>
+    <floater.string
+     name="end_call_button_tooltip"
+     value="Close voice connection"/>
+    <floater.string
+     name="expcol_button_not_tearoff_tooltip"
+     value="Collapse this pane"/>
+    <floater.string
+     name="expcol_button_tearoff_and_expanded_tooltip"
+     value="Collapse participant list"/>
+    <floater.string
+     name="expcol_button_tearoff_and_collapsed_tooltip"
+     value="Expand participant list"/>
+    <view
+     follows="all"
+     layout="topleft"
+     name="contents_view"
+     top="0"
+     left="0"
+     right="-1"
+     bottom="-3">
+        <layout_stack
+         animate="false" 
+         default_tab_group="2"
+         follows="all"
+         right="-5"
+         bottom="-1"
+         top="0"
+         left="5"
+         border_size="0"
+         layout="topleft"
+         orientation="vertical"
+         name="main_stack"
+         tab_group="1">
+            <layout_panel
+             auto_resize="false"
+             name="toolbar_panel"
+             height="35"
+             right="-1"
+             left="1">
+                <menu_button
+                 menu_filename="menu_im_session_showmodes.xml"
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left="5"
+                 name="view_options_btn"
+                 tool_tip="View/sort options"
+                 top="5"
+                 width="31" />
+                <menu_button
+                 menu_filename="menu_im_conversation.xml"
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="2"
+                 name="gear_btn"
+                 visible="false"
+                 tool_tip="Actions on selected person"
+                 width="31"/>
+                <button
+                 enabled="false"
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_add_person"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 left_pad="2"
+                 name="add_btn"
+                 tool_tip="Add someone to this conversation"
+                 width="31"/>
+                <button
+                 follows="top|left"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_open_call"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 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" />
+                <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_close"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 top="5"
+                 right="-67"
+                 name="close_btn"
+                 tool_tip="End this conversation"
+                 width="31" />
+                <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="5"
+                 left_pad="2"
+                 name="expand_collapse_btn"
+                 tool_tip="Collapse/Expand this pane"
+                 width="31" />
+                <button
+                 follows="right|top"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_arrow_ne"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="tear_off_btn"
+                 top="5"
+                 width="31" />
+            </layout_panel>
+            <layout_panel
+             name="body_panel"
+             top="1"
+             bottom="-1">
+                <layout_stack
+                 default_tab_group="2"
+                 follows="all"
+                 orientation="horizontal"
+                 name="im_panels"
+                 tab_group="1"
+                 top="0"
+                 right="-1"
+                 bottom="-1"
+                 left="0">
+                    <layout_panel
+                     name="speakers_list_panel"
+                     expanded_min_dim="115"
+                     min_dim="0"
+                     width="150" 
+                     user_resize="true"
+                     auto_resize="false" 
+                     bottom="-1" />
+                    <layout_panel
+                     default_tab_group="3"
+                     tab_group="2"
+                     name="right_part_holder"
+                     min_width="221"
+                     bottom="-1">
+                        <layout_stack
+                         animate="true" 
+                         default_tab_group="2"
+                         follows="all"
+                         orientation="vertical"
+                         name="translate_and_chat_stack"
+                         tab_group="1"
+                         top="0"
+                         left="0"
+                         right="-1"
+                         bottom="-1">
+                            <layout_panel
+                             auto_resize="false"
+                             height="26"
+                             name="translate_chat_checkbox_lp">
+                                <check_box
+                                 top="10"
+                                 control_name="TranslateChat"
+                                 enabled="true"
+                                 height="16"
+                                 label="Translate chat"
+                                 left="5"
+                                 name="translate_chat_checkbox"
+                                 width="230" />
+                            </layout_panel>
+                            <layout_panel
+                             name="chat_holder">
+                                <chat_history
+                                 font="SansSerifSmall"
+                                 follows="all"
+                                 name="chat_history"
+                                 parse_highlights="true"
+                                 parse_urls="true"
+                                 right="-1"
+                                 left="5"
+                                 top="0"
+                                 bottom="-1" />
+                            </layout_panel>
+                        </layout_stack>
+                    </layout_panel>
+                </layout_stack>
+            </layout_panel>
+            <layout_panel
+             top_delta="0"
+             top="0"
+             height="26"
+             bottom="-1"
+             auto_resize="false"
+             name="chat_layout_panel">
+                <layout_stack
+                 animate="false"
+                 default_tab_group="2"
+                 follows="all"
+                 orientation="horizontal"
+                 name="input_panels"
+                 top="0"
+                 bottom="-2"
+                 left="0"
+                 right="-1">
+                    <layout_panel
+                     name="input_editor_layout_panel"
+                     auto_resize="true"
+                     user_resize="false"
+                     top="0"
+                     bottom="-1">
+                        <chat_editor
+                         layout="topleft"
+                         expand_lines_count="5"
+                         follows="left|right|bottom"
+                         font="SansSerifSmall"
+                         height="20"    
+                         is_expandable="true"
+                         text_tentative_color="TextFgTentativeColor"
+                         name="chat_editor"
+                         max_length="1023"
+                         spellcheck="true"
+                         tab_group="3"
+                         top="1"
+                         bottom="-2"
+                         left="4"
+                         right="-4"
+                         wrap="true" />
+                    </layout_panel>
+                    <layout_panel
+                     auto_resize="false"
+                     user_resize="false"
+                     name="input_button_layout_panel"
+                     width="30"
+                     top="0"
+                     bottom="-1">
+                        <button
+                         layout="topleft"
+                         left="1"
+                         right="-1"
+                         top="1"
+                         height="22"
+                         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" />
+                    </layout_panel>
+                </layout_stack>
+            </layout_panel>
+        </layout_stack>
+    </view>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_incoming_call.xml b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
index 81194f61cf50e94cae5af2560ba56d2a1685985e..a7864381a9b954421227b89dcaef227af71c96da 100644
--- a/indra/newview/skins/default/xui/en/floater_incoming_call.xml
+++ b/indra/newview/skins/default/xui/en/floater_incoming_call.xml
@@ -8,8 +8,8 @@
  layout="topleft"
  name="incoming call"
  help_topic="incoming_call"
- title="Incoming call"
- width="410">
+ sound_flags="0"
+ width="550">
     <floater.string
      name="lifetime">
         5
@@ -24,7 +24,7 @@
     </floater.string>
     <floater.string
      name="VoiceInviteP2P">
-        is calling.
+        is calling you.
     </floater.string>
     <floater.string
      name="VoiceInviteAdHoc">
@@ -49,14 +49,14 @@
      image_name="icon_avatar_online.tga"
      layout="topleft"
      left_delta="19"
-     top="35"
+     top="20"
      width="36" />
     <group_icon
      enabled="false"
      follows="left|top"
      height="36"
      layout="topleft"
-     top="35"
+     top="20"
      width="36" />
     <text
      clip_partial="true"
@@ -67,43 +67,43 @@
      name="caller name"
      top="20"
      use_ellipses="true"
-     width="315"
+     width="475"
      word_wrap="true" />
-    <text
-     clip_partial="true"
-     font="SansSerif"
-     height="30"
-     layout="topleft"
-     left="77"
-     name="question"
-     top_pad="5"
-     use_ellipses="true"
-     width="315"
-     word_wrap="true">
-     Do you want to leave [CURRENT_CHAT] and join this voice chat?
-    </text>
-    <button
+     <button
      height="24"
-     label="Accept"
-     label_selected="Accept"
+     label="Answer"
+     label_selected="Answer"
      layout="topleft"
      left="70"
      name="Accept"
-     top="92"
-     width="100" />
+     top_pad="5"
+     width="120" />
     <button
      height="24"
-     label="Reject"
-     label_selected="Reject"
+     label="Ignore"
+     label_selected="Ignore"
      layout="topleft"
      name="Reject"
      left_pad="10"
-     width="100" />
+     width="120" />
     <button
      height="24"
-     label="Start IM"
+     label="Open IM instead"
      layout="topleft"
      name="Start IM"
      left_pad="10"
-     width="100" />
+     width="120" />
+    <text
+     clip_partial="true"
+     font="SansSerif"
+     height="30"
+     layout="topleft"
+     left="77"
+     name="question"
+     top_pad="5"
+     use_ellipses="true"
+     width="475"
+     word_wrap="true">
+     If you answer, you will be disconnected from your current voice conversation.
+    </text>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_moveview.xml b/indra/newview/skins/default/xui/en/floater_moveview.xml
index 4e7ee7913fba8e7766646b3406b49bc1c81df15e..5e84283ab050107b58c3b23e2007302a413e3452 100644
--- a/indra/newview/skins/default/xui/en/floater_moveview.xml
+++ b/indra/newview/skins/default/xui/en/floater_moveview.xml
@@ -1,8 +1,8 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <floater
  positioning="specified"
- left="320"
- bottom="-80"
+ right="-693"
+ bottom="-50"
  legacy_header_height="18"
  can_dock="false"
  can_minimize="true"
diff --git a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
index 26293130699004f3c76a0a46e4148139331ba87e..79f2027c31862a27cb79ee34ffcd28cbe973b325 100644
--- a/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
+++ b/indra/newview/skins/default/xui/en/floater_pathfinding_console.xml
@@ -152,7 +152,7 @@
       </text>
       <check_box
           height="19"
-          label="World"
+          label="Test"
           layout="topleft"
           name="show_world"
           top_pad="4"
diff --git a/indra/newview/skins/default/xui/en/floater_people.xml b/indra/newview/skins/default/xui/en/floater_people.xml
index 08d0b00a835ebd5140021d85e94d9b23ddb12d74..701233ba4a0f2c2b4b22c4e2a38e15e8de42b6fc 100644
--- a/indra/newview/skins/default/xui/en/floater_people.xml
+++ b/indra/newview/skins/default/xui/en/floater_people.xml
@@ -6,21 +6,21 @@
   can_resize="true"
   height="570"
   help_topic="sidebar_people"
-  min_height="440"
-  min_width="333"
+  min_height="220"
+  min_width="260"
   layout="topleft"
   name="floater_people"
   save_rect="true"
   single_instance="true"
   reuse_instance="true"
   title="PEOPLE"
-  width="333">
+  width="370">
     <panel_container
       default_panel_name="panel_people"
       follows="all"
       height="570"
       name="main_panel"
-      width="333">
+      width="370">
       <panel
         class="panel_people"
         name="panel_people"
@@ -31,11 +31,5 @@
         filename="panel_group_info_sidetray.xml"
         label="Group Profile"
         font="SansSerifBold"/>
-      <panel
-        class="panel_block_list_sidetray"
-        name="panel_block_list_sidetray"
-        filename="panel_block_list_sidetray.xml"
-        label="Blocked Residents &amp; Objects"
-        font="SansSerifBold"/>
     </panel_container>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5c71fd3bc6d9c64737b0471138aa2cf359e7fb6d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_chat_volume.xml
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE CHAT VOLUME"
+ visible="true"
+ width="245">
+	<slider
+		control_name="AudioLevelVoice"
+		disabled_control="MuteAudio"
+		follows="left|top"
+		height="16"
+		increment="0.025"
+		initial_value="0.5"
+		label="Voice Chat"
+		label_width="50"
+		layout="topleft"
+		left="15"
+		top="50"
+		name="chat_voice_volume"
+		show_text="false"
+		slider_label.halign="right"
+		volume="true"
+		width="200">
+	</slider>
+	<button
+		control_name="MuteVoice"
+		disabled_control="MuteAudio"
+		follows="top|left"
+		height="16"
+		image_selected="AudioMute_Off"
+		image_unselected="Audio_Off"
+		is_toggle="true"
+		layout="topleft"
+		left_pad="5"
+		name="mute_audio"
+		tab_stop="false"
+		width="16" />
+</floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/floater_voice_controls.xml b/indra/newview/skins/default/xui/en/floater_voice_controls.xml
deleted file mode 100644
index dce2720cf8cf46c63eddfc054524f05ddafd38b3..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/floater_voice_controls.xml
+++ /dev/null
@@ -1,155 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<floater
- positioning="cascading"
- can_resize="true"
- can_minimize="true"
- can_close="true"
- chrome="true"
- height="205"
- layout="topleft"
- min_height="124"
- min_width="190"
- name="floater_voice_controls"
- help_topic="floater_voice_controls"
- title="VOICE CONTROLS"
- save_dock_state="true"
- save_visibility="true"
- save_rect="true"
- single_instance="true"
- width="282">
-    <string
-     name="title_nearby">
-        VOICE SETTINGS
-    </string>
-    <string
-     name="title_group">
-        GROUP CALL WITH [GROUP]
-    </string>
-    <string
-     name="title_adhoc">
-        CONFERENCE CALL
-    </string>
-    <string
-     name="title_peer_2_peer">
-        CALL WITH [NAME]
-    </string>
-    <string
-     name="no_one_near">
-        No one near has voice enabled
-    </string>
-      <layout_stack
-         clip="false"
-         follows="all"
-         height="189"
-         layout="topleft"
-         left="10"
-         mouse_opaque="false"
-         name="my_call_stack"
-         orientation="vertical"
-         width="263">
-        <layout_panel
-         follows="top|left|right"
-         auto_resize="false"
-         layout="topleft"
-         min_height="20"
-         height="20"
-         name="my_panel">
-            <avatar_icon
-             enabled="false"
-             follows="left|top"
-             height="18"
-             default_icon_name="Generic_Person"
-             layout="topleft"
-             left="5"
-             name="user_icon"
-             top="0"
-             width="18" />
-            <text
-             follows="top|left|right"
-             font="SansSerifSmallBold"
-             height="16"
-             layout="topleft"
-             left_pad="10"
-             name="user_text"
-             text_color="White"
-             top="4"
-             use_ellipses="true"
-             value="My Avatar:"
-             width="210" />
-            <output_monitor
-             auto_update="true"
-             draw_border="false"
-             follows="top|right"
-             height="16"
-             layout="topleft"
-             right="-3"
-             name="speaking_indicator"
-             left_pad="5"
-             visible="true"
-             width="20" />
-        </layout_panel>
-        <layout_panel name="leave_call_panel" height="26" min_height="26" auto_resize="false">
-        <layout_stack
-         clip="true"
-         follows="left|top|right"
-         height="26"
-         layout="topleft"
-         mouse_opaque="false"
-         name="voice_effect_and_leave_call_stack"
-         orientation="horizontal"
-         width="262">
-          <layout_panel
-            height="26"
-            width="200">
-            <panel
-             class="panel_voice_effect"
-             name="panel_voice_effect"
-             visiblity_control="VoiceMorphingEnabled"
-             filename="panel_voice_effect.xml" />
-          </layout_panel>
-          <layout_panel
-           auto_resize="false"
-           follows="top|right"
-           height="23"
-           visible="true"
-           layout="topleft"
-           name="leave_call_btn_panel"
-           width="100">
-            <button
-             follows="right|top"
-             height="23"
-             label="Leave Call"
-             name="leave_call_btn"
-             width="100" />
-          </layout_panel>
-        </layout_stack>
-          </layout_panel>
-      <layout_panel
-          follows="all"
-          layout="topleft"
-          left="2"
-          top_pad="0"
-          height="132"
-          name="callers_panel"
-          auto_resize="true"
-          width="280">
-        <avatar_list
-         follows="all"
-         height="132"
-         ignore_online_status="true"
-         layout="topleft"
-         multi_select="true"
-         name="speakers_list"
-         width="280" />
-        <panel
-         filename="panel_avatar_list_item.xml"
-         follows="left|right|top"
-         height="24"
-         layout="topleft"
-         left="0"
-         name="non_avatar_caller"
-         top="10"
-         width="276" />
-      </layout_panel>
-    </layout_stack>
-</floater>
diff --git a/indra/newview/skins/default/xui/en/floater_voice_effect.xml b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
index 35cb2670d0904187dfcd55e9cd06c0df45a4f27d..146c3d7e30daf841c6afdb1b8c80320cf85dbd14 100644
--- a/indra/newview/skins/default/xui/en/floater_voice_effect.xml
+++ b/indra/newview/skins/default/xui/en/floater_voice_effect.xml
@@ -5,12 +5,13 @@
  height="500"
  name="voice_effects"
  help_topic="voice_effects"
- title="VOICE MORPHING"
+ title="VOICE MORPHING PREVIEW"
  background_visible="true"
  label="Places"
  layout="topleft"
  min_height="360"
  min_width="200"
+ save_rect="true"
  width="300">
   <string name="no_voice_effect">
     (No Voice Morph)
diff --git a/indra/newview/skins/default/xui/en/floater_voice_volume.xml b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
new file mode 100644
index 0000000000000000000000000000000000000000..9346295d5b8f9ac058af150f146f596a914c5286
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_voice_volume.xml
@@ -0,0 +1,59 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!--
+  Not can_close / no title to avoid window chrome
+  Single instance - only have one at a time, recycle it each spawn
+-->
+<floater
+ legacy_header_height="25"
+ bevel_style="in"
+ bg_opaque_image="Inspector_Background"
+ can_close="false"
+ can_minimize="false"
+ height="90"
+ layout="topleft"
+ name="floater_voice_volume"
+ single_instance="true"
+ sound_flags="0"
+ title="VOICE VOLUME"
+ visible="true"
+ width="245">
+    <text
+     follows="top|left|right"
+     font="SansSerifSmall"
+     height="21"
+     left="10"
+     name="avatar_name"
+     parse_urls="false"
+     top="35"
+     text_color="White"
+     translate="false"
+     use_ellipses="true"
+     value="TestString PleaseIgnore"
+     width="225" />
+    <slider
+     follows="top|left"
+     height="23"
+     increment="0.01"
+     left="1"
+     max_val="0.95"
+     min_val="0.05"
+     name="volume_slider"
+     show_text="false"
+     tool_tip="Voice volume"
+     top_pad="0"
+     value="0.5"
+     width="200" />
+    <button
+     follows="top|left"
+     height="16"
+     image_disabled="Audio_Off"
+     image_disabled_selected="AudioMute_Off"
+     image_hover_selected="AudioMute_Over"
+     image_selected="AudioMute_Off"
+     image_unselected="Audio_Off"
+     is_toggle="true"
+     left_pad="0"
+     top_delta="4"
+     name="mute_btn"
+     width="16" />
+</floater>
diff --git a/indra/newview/skins/default/xui/en/inspect_avatar.xml b/indra/newview/skins/default/xui/en/inspect_avatar.xml
index bc3bcd331b7c672f143f7ca77315b673fc256f3e..ef4f19cd4cdbb17e98e520bf85d5f83c511aec53 100644
--- a/indra/newview/skins/default/xui/en/inspect_avatar.xml
+++ b/indra/newview/skins/default/xui/en/inspect_avatar.xml
@@ -2,14 +2,14 @@
 <!--
   Not can_close / no title to avoid window chrome
   Single instance - only have one at a time, recycle it each spawn
--->
+--> 
 <floater
  legacy_header_height="25"
  bevel_style="in"
  bg_opaque_image="Inspector_Background"
  can_close="false"
  can_minimize="false"
- height="164"
+ height="160"
  layout="topleft"
  name="inspect_avatar"
  single_instance="true"
@@ -98,13 +98,13 @@
      follows="top|left"
      height="23"
      increment="0.01"
-     left="1"
+     left="10"
      max_val="0.95"
      min_val="0.05"
      name="volume_slider"
      show_text="false"
      tool_tip="Voice volume"
-     top_pad="0"
+     top_pad="5"
      value="0.5"
      width="200" />
     <button
@@ -116,10 +116,21 @@
      image_selected="AudioMute_Off"
      image_unselected="Audio_Off"
      is_toggle="true"
-     left_pad="0"
+     left_pad="5"
      top_delta="4"
      name="mute_btn"
      width="16" />
+    <text
+     follows="top|left"
+     height="16"
+     left="8"
+     name="avatar_profile_link"
+     font="SansSerifSmall"
+     text_color="White"
+     top_pad="5"
+     translate="false"
+     value="[[LINK] View full profile]"
+     width="175" />
     <avatar_icon
      follows="top|left"
      height="38"
@@ -130,83 +141,4 @@
      name="avatar_icon"
      top="10"
      width="38" />
-<!-- Overlapping buttons for default actions
-    llinspectavatar.cpp makes visible the most likely default action 
--->
-    <button
-     follows="top|left"
-     height="20"
-     label="Add Friend"
-     left="8"
-     top="135"
-     name="add_friend_btn"
-     width="90" />
-    <button
-     follows="top|left"
-     height="20"
-     label="IM"
-     left_delta="0"
-     top_delta="0"
-     name="im_btn"
-     width="80"
-     commit_callback.function="InspectAvatar.IM"/>
-	<button
-     follows="top|left"
-     height="20"
-     label="Profile"
-     layout="topleft"
-     name="view_profile_btn"
-     left_delta="96"
-     top_delta="0"
-     tab_stop="false"
-     width="80" />
-      <!--  gear buttons here -->
-  <menu_button
-     follows="top|left"
-     height="20"
-     layout="topleft"
-     image_overlay="OptionsMenu_Off"
-     menu_filename="menu_inspect_avatar_gear.xml"
-     name="gear_btn"
-     right="-5"
-     top_delta="0"
-     width="35" />
-	<menu_button
-     follows="top|left"
-     height="20"
-     image_overlay="OptionsMenu_Off"
-     menu_filename="menu_inspect_self_gear.xml"
-     name="gear_self_btn"
-     right="-5"
-     top_delta="0"
-     width="35" />
-  <panel 
-    follows="top|left" 
-    top="164" 
-    left="0" 
-    height="60" 
-    width="228" 
-    visible="false"
-    background_visible="true"
-    name="moderator_panel"
-    background_opaque="true" 
-    bg_opaque_color="MouseGray">
-    <button
-      name="disable_voice"
-      label="Disable Voice"
-      top="20"
-      width="95"
-      height="20"
-      left="10"
-      commit_callback.function="InspectAvatar.DisableVoice"/>
-    <button
-      name="enable_voice"
-      label="Enable Voice"
-      top="20"
-      width="95"
-      height="20"
-      left="10"
-      visible="false" 
-      commit_callback.function="InspectAvatar.EnableVoice"/>
-  </panel>
 </floater>
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index b46b62ec4d18e69f5a174b883953467977d8fd87..46ba4bd29d2786bf2c0ac1f7835dffb4765eac06 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -79,6 +79,14 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
         </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 	    <menu_item_call
          label="Zoom In"
           name="Zoom In">
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_self.xml b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
index b8128da358631e2885fae37b4ebd0d72ba49eb66..28e032ce5f0e4f90c4eaf1c016efbb3d9003bfce 100644
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -123,6 +123,14 @@ name="Edit Outfit">
     <menu_item_call.on_visible
      function="IsGodCustomerService"/>
   </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
   <menu_item_separator
   layout="topleft" />
   <menu_item_call
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_other.xml b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
index 276b5f106f785799b6b829be611030b47b3e65c3..e7c2b80da27f45f8b69c8297352885aab5d5a87c 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -79,6 +79,14 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
         </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 	    <menu_item_call
          label="Zoom In"
           name="Zoom In">
diff --git a/indra/newview/skins/default/xui/en/menu_avatar_self.xml b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
index d9bdfece383b82c4f4188628694e1e0275c71a2e..c1ff026a74e51fb856db513c20fe177cc6882d12 100644
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -261,4 +261,12 @@
             <menu_item_call.on_visible
              function="IsGodCustomerService"/>
     </menu_item_call>
+    <menu_item_call
+		 label="Dump XML"
+         name="Dump XML">
+            <menu_item_call.on_click
+             function="Advanced.AppearanceToXML" />
+            <menu_item_call.on_visible
+             function="Advanced.EnableAppearanceToXML"/>
+    </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_cof_gear.xml b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
index a6e9a40e3148f19463169191af4e996b2b39a93f..45cf780557b698ce1183595917a7d17eafffaeed 100644
--- a/indra/newview/skins/default/xui/en/menu_cof_gear.xml
+++ b/indra/newview/skins/default/xui/en/menu_cof_gear.xml
@@ -9,5 +9,5 @@
     <menu
      label="New Body Parts"
      layout="topleft"
-     name="COF.Geear.New_Body_Parts" />
+     name="COF.Gear.New_Body_Parts" />
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation.xml b/indra/newview/skins/default/xui/en/menu_conversation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..5a13ef0a592f136d7e6c45845ac323a11e82a4fa
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation.xml
@@ -0,0 +1,203 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ bottom="806"
+ layout="topleft"
+ left="0"
+ mouse_opaque="false"
+ name="menu_conversation_participant"
+ visible="false">
+     <menu_item_call
+     label="Close conversation"
+     layout="topleft"
+     name="close_conversation">
+        <on_click function="Avatar.DoToSelected" parameter="close_conversation"/>
+	 </menu_item_call>
+     <menu_item_call
+     label="Open voice conversation"
+     layout="topleft"
+     name="open_voice_conversation">
+        <on_click function="Avatar.DoToSelected" parameter="open_voice_conversation"/>
+     </menu_item_call>	
+     <menu_item_call
+     label="Disconnect from voice"
+     layout="topleft"
+     name="disconnect_from_voice">
+        <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="View Profile"
+     layout="topleft"
+     name="view_profile">
+        <on_click function="Avatar.DoToSelected" parameter="view_profile"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_view_profile"/>
+    </menu_item_call>
+    <menu_item_call
+     label="IM"
+     layout="topleft"
+     name="im">
+        <on_click function="Avatar.DoToSelected" parameter="im"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_im"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Offer teleport"
+     layout="topleft"
+     name="offer_teleport">
+        <on_click function="Avatar.DoToSelected" parameter="offer_teleport"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call"
+     layout="topleft"
+     name="voice_call">
+        <on_click function="Avatar.DoToSelected" parameter="voice_call"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_call" />
+    </menu_item_call>
+    <menu_item_call
+     label="Chat history..."
+     layout="topleft"
+     name="chat_history">
+        <on_click function="Avatar.DoToSelected" parameter="chat_history"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_chat_history"/>
+    </menu_item_call>	
+    <menu_item_separator layout="topleft" name="separator_chat_history"/>	
+    <menu_item_call
+     label="Add friend"
+     layout="topleft"
+     name="add_friend">
+        <on_click function="Avatar.DoToSelected" parameter="add_friend"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+    </menu_item_call>	
+    <menu_item_call
+     label="Remove friends"
+     layout="topleft"
+     name="remove_friends">
+        <on_click function="Avatar.DoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableItem" parameter="can_delete" />
+    </menu_item_call>	
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="invite_to_group">
+        <on_click function="Avatar.DoToSelected" parameter="invite_to_group" />
+        <on_enable function="Avatar.EnableItem" parameter="can_invite" />
+    </menu_item_call>
+    <menu_item_separator layout="topleft" name="separator_invite_to_group"/>
+    <menu_item_call
+     label="Zoom In"
+     layout="topleft"
+     name="zoom_in">
+      <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+      <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+    </menu_item_call>
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="map">
+        <on_click function="Avatar.DoToSelected" parameter="map" />
+        <on_enable function="Avatar.EnableItem" parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="share">
+        <on_click function="Avatar.DoToSelected" parameter="share" />
+        <on_enable function="Avatar.EnableItem" parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="pay">
+        <on_click function="Avatar.DoToSelected" parameter="pay" />
+        <on_enable function="Avatar.EnableItem" parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_check
+     label="Block Voice"
+     layout="topleft"
+     name="block_unblock">
+        <on_click function="Avatar.DoToSelected" parameter="block_unblock" />
+		<on_check function="Avatar.CheckItem" parameter="is_blocked" />
+		<on_enable  function="Avatar.EnableItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_check
+     label="Block Text"
+     layout="topleft"
+     name="MuteText">
+     <on_click function="Avatar.DoToSelected" parameter="mute_unmute" />
+     <on_check function="Avatar.CheckItem" parameter="is_muted" />
+     <on_enable  function="Avatar.EnableItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_call
+     label="Group Profile"
+     layout="topleft"
+     name="group_profile">
+        <on_click function="Group.DoToSelected" parameter="group_profile"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_group_profile" />
+    </menu_item_call>	
+    <menu_item_call
+     label="Activate Group"
+     layout="topleft"
+     name="activate_group">
+        <on_click function="Group.DoToSelected" parameter="activate_group"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_activate_group" />
+    </menu_item_call>		
+    <menu_item_call
+     label="Leave Group"
+     layout="topleft"
+     name="leave_group">
+        <on_click function="Group.DoToSelected" parameter="leave_group"/>
+        <on_enable function="Avatar.EnableItem" parameter="can_leave_group" />
+    </menu_item_call>
+	<menu_item_separator layout="topleft" name="Moderator Options Separator"/>
+	<context_menu
+	 label="Moderator Options"
+	 layout="topleft"
+	 name="Moderator Options">
+		<menu_item_check
+		 label="Allow text chat"
+		 layout="topleft"
+		 name="AllowTextChat">
+			<on_check function="Avatar.CheckItem" parameter="is_allowed_text_chat" />
+			<on_click function="Avatar.DoToSelected" parameter="toggle_allow_text_chat" />
+			<on_enable function="Avatar.EnableItem" parameter="can_allow_text_chat" />
+		</menu_item_check>
+		<menu_item_separator layout="topleft" name="moderate_voice_separator" />
+		<menu_item_call
+		 label="Mute this participant"
+		 layout="topleft"
+		 name="ModerateVoiceMuteSelected">
+			<on_click function="Avatar.DoToSelected" parameter="selected" />
+      <on_enable function="Avatar.EnableItem" parameter="can_mute" />
+      <on_visible function="Avatar.VisibleItem" parameter="show_mute" />
+    </menu_item_call>
+    <menu_item_call
+		 label="Unmute this participant"
+		 layout="topleft"
+		 name="ModerateVoiceUnMuteSelected">
+      <on_click function="Avatar.DoToSelected" parameter="selected" />
+      <on_enable function="Avatar.EnableItem" parameter="can_unmute" />
+      <on_visible function="Avatar.VisibleItem" parameter="show_unmute" />
+		</menu_item_call>
+		<menu_item_call
+		 label="Mute everyone"
+		 layout="topleft"
+		 name="ModerateVoiceMute">
+			<on_click function="Avatar.DoToSelected" parameter="mute_all" />
+			<on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+		</menu_item_call>
+		<menu_item_call
+		 label="Unmute everyone"
+		 layout="topleft"
+		 name="ModerateVoiceUnmute">
+			<on_click function="Avatar.DoToSelected" parameter="unmute_all" />
+			<on_enable function="Avatar.EnableItem" parameter="can_moderate_voice" />
+		</menu_item_call>
+	</context_menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
new file mode 100644
index 0000000000000000000000000000000000000000..8796b87955fb99aa096cebd76fec0bf38118fed6
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_gear.xml
@@ -0,0 +1,142 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Context Menu">
+    <menu_item_call
+     label="IM..."
+     layout="topleft"
+     name="IM">
+        <on_click
+         function="Calllog.Action"
+         parameter="im" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_im" />
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call..."
+     layout="topleft"
+     name="Call">
+        <on_click
+         function="Calllog.Action"
+         parameter="call" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_call" />
+    </menu_item_call>
+    <menu_item_call
+     label="Open chat history..."
+     layout="topleft"
+     name="Chat history">
+        <on_click
+         function="Calllog.Action"
+         parameter="chat_history" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_view_chat_history" />
+    </menu_item_call>
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="View Profile">
+        <on_click
+         function="Calllog.Action"
+         parameter="view_profile" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_view_profile" />
+    </menu_item_call>
+    <menu_item_call
+    label="Offer Teleport"
+    name="teleport">
+      <on_click
+       function="Calllog.Action"
+       parameter="offer_teleport"/>
+      <on_enable
+      function="Calllog.Enable"
+      parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_separator />
+    <menu_item_call
+     label="Add Friend"
+     layout="topleft"
+     name="add_friend">
+        <on_click
+         function="Calllog.Action"
+         parameter="add_friend"/>
+        <on_visible
+         function="Calllog.Check"
+         parameter="is_not_friend" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove Friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click
+         function="Calllog.Action"
+         parameter="remove_friend"/>
+        <on_visible
+         function="Calllog.Check"
+         parameter="is_friend" />
+    </menu_item_call>
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="Invite">
+        <on_click
+         function="Calllog.Action"
+         parameter="invite_to_group"/>
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_invite_to_group" />
+    </menu_item_call>
+    <menu_item_separator />
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="Map">
+        <on_click
+         function="Calllog.Action"
+         parameter="show_on_map" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="Share">
+        <on_click
+         function="Calllog.Action"
+         parameter="share" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="Pay">
+        <on_click
+         function="Calllog.Action"
+         parameter="pay" />
+        <on_enable
+         function="Calllog.Enable"
+         parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_check
+     label="Block/Unblock"
+     layout="topleft"
+     name="Block/Unblock">
+        <menu_item_check.on_click
+         function="Calllog.Action"
+         parameter="block"/>
+        <menu_item_check.on_check
+         function="Calllog.Check"
+         parameter="is_blocked" />
+        <menu_item_check.on_enable
+         function="Calllog.Enable"
+         parameter="can_block" />
+    </menu_item_check>
+
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..ce65b23971a28e593031a063c9689099718638b0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_conversation_log_view.xml
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+     name="menu_conversation_view"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by name"
+   name="sort_by_name">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_by_name"/>
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_by_name"/>
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by date"
+   name="sort_by_date">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_by_date" />
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_by_date" />
+  </menu_item_check>
+  <menu_item_separator />
+  <menu_item_check
+   label="Sort friends on top"
+   name="sort_by_friends">
+      <on_click
+       function="CallLog.Action"
+       parameter="sort_friends_on_top" />
+      <on_check
+       function="CallLog.Check"
+       parameter="sort_friends_on_top" />
+  </menu_item_check>
+  <menu_item_separator />
+  <menu_item_call
+   label="View Nearby chat history..."
+   name="view_nearby_chat_history">
+      <on_click
+       function="CallLog.Action"
+       parameter="view_nearby_chat_history" />
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_group_plus.xml b/indra/newview/skins/default/xui/en/menu_group_plus.xml
index fce7414d801aaa9f831ceddbcb5a77fac9a7554a..eca9e7f3c9fb98e6926fb5c6e8212421fb0f6c6a 100644
--- a/indra/newview/skins/default/xui/en/menu_group_plus.xml
+++ b/indra/newview/skins/default/xui/en/menu_group_plus.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
      left="0" bottom="0" visible="false"
      mouse_opaque="false">
   <menu_item_call name="item_join" label="Join Group...">
@@ -8,4 +8,4 @@
   <menu_item_call name="item_new" label="New Group...">
     <menu_item_call.on_click function="People.Group.Plus.Action" userdata="new_group" />
   </menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_im_conversation.xml b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
new file mode 100644
index 0000000000000000000000000000000000000000..43287c6ec36e8fe6313c0f5c493d29a976232748
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_conversation.xml
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="Conversation Gear Menu">
+    <menu_item_call
+     label="View Profile"
+     layout="topleft"
+     name="View Profile">
+        <on_click function="Avatar.GearDoToSelected" parameter="view_profile" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_view_profile" />
+    </menu_item_call>
+    <menu_item_call
+     label="Add Friend"
+     layout="topleft"
+     name="Add Friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="add_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_add" />
+    </menu_item_call>
+    <menu_item_call
+     label="Remove friend"
+     layout="topleft"
+     name="remove_friend">
+        <on_click function="Avatar.GearDoToSelected" parameter="remove_friend" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_delete" />
+    </menu_item_call>
+    <menu_item_call
+     label="Offer teleport"
+     layout="topleft"
+     name="offer_teleport">
+        <on_click function="Avatar.GearDoToSelected" parameter="offer_teleport"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Invite to group..."
+     layout="topleft"
+     name="invite_to_group">
+        <on_click function="Avatar.GearDoToSelected" parameter="invite_to_group" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_invite" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"
+     name="View Icons Separator" />
+    <menu_item_call
+     label="Chat history..."
+     layout="topleft"
+     name="chat_history">
+        <on_click function="Avatar.GearDoToSelected" parameter="chat_history"/>
+        <on_enable function="Avatar.EnableGearItem" parameter="can_chat_history"/>
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_call
+       label="Zoom In"
+       layout="topleft"
+       name="zoom_in">
+      <on_click function="Avatar.DoToSelected" parameter="zoom_in" />
+      <on_enable function="Avatar.EnableItem" parameter="can_zoom_in" />
+    </menu_item_call>
+    <menu_item_call
+     label="Map"
+     layout="topleft"
+     name="map">
+        <on_click function="Avatar.GearDoToSelected" parameter="map" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_show_on_map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Share"
+     layout="topleft"
+     name="Share">
+        <on_click function="Avatar.GearDoToSelected" parameter="share" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_share" />
+    </menu_item_call>
+    <menu_item_call
+     label="Pay"
+     layout="topleft"
+     name="Pay">
+        <on_click function="Avatar.GearDoToSelected" parameter="pay" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_pay" />
+    </menu_item_call>
+    <menu_item_separator
+     layout="topleft"/>
+    <menu_item_check
+     label="Block Voice"
+     layout="topleft"
+     name="Block/Unblock">
+        <on_check function="Avatar.CheckGearItem" parameter="is_blocked" />
+        <on_click function="Avatar.GearDoToSelected" parameter="block_unblock" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_check
+     label="Block Text"
+     layout="topleft"
+     name="MuteText">
+        <on_check function="Avatar.CheckGearItem" parameter="is_muted" />
+        <on_click function="Avatar.GearDoToSelected" parameter="mute_unmute" />
+        <on_enable function="Avatar.EnableGearItem" parameter="can_block" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft"/>
+</toggleable_menu>
+
diff --git a/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b0adca0e0ec4713a187d5bc8e27818749f56c35a
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_im_session_showmodes.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_modes"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+    <menu_item_check
+       label="Compact view"
+       name="compact_view">
+      <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="compact_view"/>
+      <menu_item_check.on_check
+         function="IMSession.Menu.CompactExpandedModes.CheckItem"
+         parameter="compact_view"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Expanded view"
+       name="expanded_view">
+      <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="expanded_view"/>
+      <menu_item_check.on_check
+         function="IMSession.Menu.CompactExpandedModes.CheckItem"
+         parameter="expanded_view"/>
+    </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="IMShowTime" label="Show time">
+        <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="IMShowTime" />
+        <menu_item_check.on_check
+         function="IMSession.Menu.ShowModes.CheckItem"
+         parameter="IMShowTime" />
+        <menu_item_check.on_enable
+         function="IMSession.Menu.ShowModes.Enable"
+         parameter="IMShowTime" />
+    </menu_item_check>
+    <menu_item_check name="IMShowNamesForP2PConv" label="Show names in one-to-one conversations">
+        <menu_item_check.on_click
+         function="IMSession.Menu.Action"
+         parameter="IMShowNamesForP2PConv" />
+        <menu_item_check.on_check
+         function="IMSession.Menu.ShowModes.CheckItem"
+         parameter="IMShowNamesForP2PConv" />
+        <menu_item_check.on_enable
+         function="IMSession.Menu.ShowModes.Enable"
+         parameter="IMShowNamesForP2PConv" />    
+    </menu_item_check>      
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_im_well_button.xml b/indra/newview/skins/default/xui/en/menu_im_well_button.xml
deleted file mode 100644
index f8dfba91ff1b8144c7878a4bc9d8709755b2e1fb..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/menu_im_well_button.xml
+++ /dev/null
@@ -1,16 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<context_menu
- layout="topleft"
- name="IM Well Button Context Menu">
-    <menu_item_call
-     label="Close All"
-     layout="topleft"
-     name="Close All">
-        <menu_item_call.on_click
-         function="IMWellChicletMenu.Action"
-         parameter="close all" />
-        <menu_item_call.on_enable
-         function="IMWellChicletMenu.EnableItem"
-         parameter="can close all" />
-    </menu_item_call>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
deleted file mode 100644
index 76b188220ddca219e3e24d5e3efa7f52bf8c8fac..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_avatar_gear.xml
+++ /dev/null
@@ -1,143 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<toggleable_menu
-         create_jump_keys="true"
-         layout="topleft"
-         mouse_opaque="false"
-         visible="false"
-         name="Gear Menu">
-  <menu_item_call
-   label="View Profile"
-   enabled="true" 
-   name="view_profile">
-    <menu_item_call.on_click
-     function="InspectAvatar.ViewProfile"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Add Friend"
-   name="add_friend">
-    <menu_item_call.on_click
-     function="InspectAvatar.AddFriend"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.Enable"/>
-  </menu_item_call>
-  <menu_item_call
-   label="IM"
-   name="im">
-    <menu_item_call.on_click
-     function="InspectAvatar.IM"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Call"
-   enabled="true"
-   name="call">
-    <menu_item_call.on_click
-     function="InspectAvatar.Call"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.EnableCall"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Teleport"
-   name="teleport">
-    <menu_item_call.on_click
-     function="InspectAvatar.Teleport"/>
-    <menu_item_call.on_enable
-     function="InspectAvatar.Gear.EnableTeleportOffer"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Invite to Group"
-   name="invite_to_group">
-    <menu_item_call.on_click
-     function="InspectAvatar.InviteToGroup"/>
-  </menu_item_call>
-  <menu_item_separator />
-  <menu_item_call
-   label="Block"
-   name="block">
-    <menu_item_call.on_click
-     function="InspectAvatar.ToggleMute"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableMute" />
-  </menu_item_call>
-  <menu_item_call
-   label="Unblock"
-   name="unblock">
-    <menu_item_call.on_click
-     function="InspectAvatar.ToggleMute"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableUnmute" />
-  </menu_item_call>
-  <menu_item_call
-   label="Report"
-   name="report">
-    <menu_item_call.on_click
-     function="InspectAvatar.Report"/>
-  </menu_item_call>  
-  <menu_item_call
-   label="Freeze"
-   name="freeze">
-    <menu_item_call.on_click
-     function="InspectAvatar.Freeze"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleFreeze"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Eject"
-   name="eject">
-    <menu_item_call.on_click
-     function="InspectAvatar.Eject"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleEject"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Kick"
-   name="kick">
-    <menu_item_call.on_click
-     function="InspectAvatar.Kick"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableGod"/>
-  </menu_item_call>
-  <menu_item_call
-  label="CSR"
-  name="csr">
-    <menu_item_call.on_click
-     function="InspectAvatar.CSR" />
-    <menu_item_call.on_visible
-     function="InspectAvatar.EnableGod" />
-  </menu_item_call>
-  <menu_item_call
-   label="Debug Textures"
-   name="debug">
-    <menu_item_call.on_click
-     function="Avatar.Debug"/>
-    <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Find On Map"
-   name="find_on_map">
-    <menu_item_call.on_click
-     function="InspectAvatar.FindOnMap"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleFindOnMap"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Zoom In"
-   name="zoom_in">
-    <menu_item_call.on_click
-     function="InspectAvatar.ZoomIn"/>
-    <menu_item_call.on_visible
-     function="InspectAvatar.VisibleZoomIn"/>
-  </menu_item_call>  
-  <menu_item_call
-   label="Pay"
-   name="pay">
-    <menu_item_call.on_click
-     function="InspectAvatar.Pay"/>
-  </menu_item_call>
-  <menu_item_call
-   label="Share"
-   name="share">
-    <menu_item_call.on_click
-     function="InspectAvatar.Share"/>
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml b/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
deleted file mode 100644
index 5e7b16ed4a2cbc40219a04fe2d520117fe30f8db..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/menu_inspect_self_gear.xml
+++ /dev/null
@@ -1,252 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
- layout="topleft"
- name="Self Pie">
-  <menu_item_call
-   label="Sit Down"
-   layout="topleft"
-   name="Sit Down Here">
-    <menu_item_call.on_click
-     function="Self.SitDown"
-     parameter="" />
-    <menu_item_call.on_enable
-     function="Self.EnableSitDown" />
-  </menu_item_call>
-  <menu_item_call
-   label="Stand Up"
-   layout="topleft"
-   name="Stand Up">
-    <menu_item_call.on_click
-     function="Self.StandUp"
-     parameter="" />
-    <menu_item_call.on_enable
-     function="Self.EnableStandUp" />
-  </menu_item_call>
-  <context_menu
-   label="Take Off"
-   layout="topleft"
-   name="Take Off &gt;">
-    <context_menu
-     label="Clothes"
-     layout="topleft"
-     name="Clothes &gt;">
-      <menu_item_call
-       enabled="false"
-       label="Shirt"
-       layout="topleft"
-       name="Shirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="shirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="shirt" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Pants"
-       layout="topleft"
-       name="Pants">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="pants" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="pants" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Skirt"
-       layout="topleft"
-       name="Skirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="skirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="skirt" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Shoes"
-       layout="topleft"
-       name="Shoes">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="shoes" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="shoes" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Socks"
-       layout="topleft"
-       name="Socks">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="socks" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="socks" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Jacket"
-       layout="topleft"
-       name="Jacket">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="jacket" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="jacket" />
-      </menu_item_call>
-      <menu_item_call
-       enabled="false"
-       label="Gloves"
-       layout="topleft"
-       name="Gloves">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="gloves" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="gloves" />
-      </menu_item_call>
-      <menu_item_call
-            enabled="false"
-            label="Undershirt"
-            layout="topleft"
-            name="Self Undershirt">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="undershirt" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="undershirt" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Underpants"
-        layout="topleft"
-        name="Self Underpants">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="underpants" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="underpants" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Tattoo"
-        layout="topleft"
-        name="Self Tattoo">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="tattoo" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="tattoo" />
-      </menu_item_call>
-      <menu_item_call
-        enabled="false"
-        label="Alpha"
-        layout="topleft"
-        name="Self Alpha">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="alpha" />
-        <menu_item_call.on_enable
-         function="Edit.EnableTakeOff"
-         parameter="alpha" />
-      </menu_item_call>
-      <menu_item_separator
-       layout="topleft" />
-      <menu_item_call
-       label="All Clothes"
-       layout="topleft"
-       name="All Clothes">
-        <menu_item_call.on_click
-         function="Edit.TakeOff"
-         parameter="all" />
-      </menu_item_call>
-    </context_menu>
-    <context_menu
-     label="HUD"
-     layout="topleft"
-     name="Object Detach HUD" />
-    <context_menu
-     label="Detach"
-     layout="topleft"
-     name="Object Detach" />
-    <menu_item_call
-     label="Detach All"
-     layout="topleft"
-     name="Detach All">
-      <menu_item_call.on_click
-       function="Self.RemoveAllAttachments"
-       parameter="" />
-      <menu_item_call.on_enable
-       function="Self.EnableRemoveAllAttachments" />
-    </menu_item_call>
-  </context_menu>
-  <menu_item_call
-  label="Change Outfit"
-  layout="topleft"
-  name="Chenge Outfit">
-    <menu_item_call.on_click
-     function="CustomizeAvatar" />
-    <menu_item_call.on_enable
-     function="Edit.EnableCustomizeAvatar" />
-  </menu_item_call>
-  <menu_item_call label="Edit My Outfit"
-  layout="topleft"
-  name="Edit Outfit">
-    <menu_item_call.on_click
-     function="EditOutfit" />
-    <menu_item_call.on_enable
-     function="Edit.EnableCustomizeAvatar" />
-  </menu_item_call>
-  <menu_item_call label="Edit My Shape"
-  layout="topleft"
-  name="Edit My Shape">
-    <menu_item_call.on_click
-     function="EditShape" />
-    <menu_item_call.on_enable
-     function="Edit.EnableEditShape" />
-  </menu_item_call>
-  <menu_item_call
-    label="My Friends"
-    layout="topleft"
-    name="Friends...">
-    <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="friends_panel" />
-  </menu_item_call>
-  <menu_item_call
-   label="My Groups"
-   layout="topleft"
-   name="Groups...">
-    <menu_item_call.on_click
-     function="SideTray.PanelPeopleTab"
-     parameter="groups_panel" />
-  </menu_item_call>
-  <menu_item_call
-    label="My Profile"
-    layout="topleft"
-    name="Profile...">
-    <menu_item_call.on_click
-     function="ShowAgentProfile"
-     parameter="agent" />
-  </menu_item_call>
-  <menu_item_call
-   label="Debug Textures"
-       name="Debug...">
-    <menu_item_call.on_click
-     function="Avatar.Debug" />
-    <menu_item_call.on_visible
-     function="IsGodCustomerService"/>
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_login.xml b/indra/newview/skins/default/xui/en/menu_login.xml
index 101e104eabfd499389bd5149f71dea1badf0d30c..52c4fb1613f135181fcc5f8910d26c1938a58531 100644
--- a/indra/newview/skins/default/xui/en/menu_login.xml
+++ b/indra/newview/skins/default/xui/en/menu_login.xml
@@ -180,7 +180,8 @@
        name="Set Logging Level"
        tear_off="true">
         <menu_item_check
-          label="Debug">
+         name="Debug"
+         label="Debug">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="0" />
@@ -189,7 +190,8 @@
            parameter="0" />
         </menu_item_check>
         <menu_item_check
-          label="Info">
+         name="Info"
+         label="Info">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="1" />
@@ -198,7 +200,8 @@
            parameter="1" />
         </menu_item_check>
         <menu_item_check
-          label="Warning">
+         name="Warning"
+         label="Warning">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="2" />
@@ -207,7 +210,8 @@
            parameter="2" />
         </menu_item_check>
         <menu_item_check
-          label="Error">
+         name="Error"
+         label="Error">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="3" />
@@ -216,7 +220,8 @@
            parameter="3" />
         </menu_item_check>
         <menu_item_check
-          label="None">
+         name="None"
+         label="None">
           <menu_item_check.on_check
             function="Develop.CheckLoggingLevel"
             parameter="4" />
diff --git a/indra/newview/skins/default/xui/en/menu_object_icon.xml b/indra/newview/skins/default/xui/en/menu_object_icon.xml
index 0c8a2af0028cf74c0b862b5cc39820cb6f512e76..2d4f1792c29892eb818a0639629d7790b2dff46d 100644
--- a/indra/newview/skins/default/xui/en/menu_object_icon.xml
+++ b/indra/newview/skins/default/xui/en/menu_object_icon.xml
@@ -24,4 +24,22 @@
          function="ObjectIcon.Action"
          parameter="block" />
     </menu_item_call>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+     label="Show on Map"
+     layout="topleft"
+     name="show_on_map">
+        <menu_item_call.on_click
+         function="ObjectIcon.Action" 
+         parameter="map" />
+    </menu_item_call>
+    <menu_item_call
+     label="Teleport to Object Location"
+     layout="topleft"
+     name="teleport_to_object">
+        <menu_item_call.on_click
+         function="ObjectIcon.Action"
+         parameter="teleport" />
+    </menu_item_call>
 </menu>
diff --git a/indra/newview/skins/default/xui/en/menu_participant_view.xml b/indra/newview/skins/default/xui/en/menu_participant_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..7ea87ee05c442542a9bcc79117d6b710e832c664
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_participant_view.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ layout="topleft"
+ name="participant_manu_view">
+    <menu_item_check
+     label="Sort conversations by type"
+     layout="topleft"
+     name="sort_sessions_by_type">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_type" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_type" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort conversations by name"
+     layout="topleft"
+     name="sort_sessions_by_name">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_name" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_name" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort conversations by recent activity"
+     layout="topleft"
+     name="sort_sessions_by_recent">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_sessions_by_recent" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_sessions_by_recent" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_check
+     label="Sort participants by name"
+     layout="topleft"
+     name="sort_participants_by_name">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_participants_by_name" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_participants_by_name" />
+    </menu_item_check>
+    <menu_item_check
+     label="Sort participants by recent activity"
+     layout="topleft"
+     name="sort_participants_by_recent">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="sort_participants_by_recent" />
+        <on_check
+         function="IMFloaterContainer.Check"
+         parameter="sort_participants_by_recent" />
+    </menu_item_check>
+    <menu_item_separator
+     layout="topleft" />
+    <menu_item_call
+         label="Chat preferences..."
+         name="chat_preferences">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="chat_preferences" />
+      </menu_item_call>
+    <menu_item_call
+         label="Privacy preferences..."
+         name="privacy_preferences">
+        <on_click
+         function="IMFloaterContainer.Action"
+         parameter="privacy_preferences" />
+    </menu_item_call>
+    <menu_item_check
+         label="Conversation log..."
+         name="Conversation"
+         visible="true">
+        <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="conversation" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="conversation" />
+        <menu_item_check.on_enable
+         function="Avatar.EnableItem"
+         parameter="conversation_log" />
+    </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="Translate_chat" label="Translate Nearby chat">
+        <menu_item_check.on_click
+         function="IMFloaterContainer.Action" 
+         parameter="Translating.Toggle" />
+        <menu_item_check.on_check
+         function="IMFloaterContainer.Check" 
+         parameter="Translating.On" />
+        <menu_item_check.on_enable
+         function="IMFloaterContainer.Check" 
+         parameter="Translating.Enabled" />
+    </menu_item_check>
+    <menu_item_check name="Translation_settings" label="Translation settings...">
+    <menu_item_check.on_check
+         function="Floater.Visible"
+         parameter="prefs_translation" />
+        <menu_item_check.on_click
+         function="Floater.Toggle"
+         parameter="prefs_translation" />
+    </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
new file mode 100644
index 0000000000000000000000000000000000000000..63295ea27bbfda362d82113f046ef47146e47ddd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_gear.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_gear"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Unblock"
+   name="unblock">
+      <on_click
+       function="Block.Action"
+       parameter="unblock_item" />
+      <on_enable
+       function="Block.Enable"
+       parameter="unblock_item" /> 
+  </menu_item_call>
+  <menu_item_call
+   label="Profile..."
+   name="profile">
+      <on_click
+       function="Block.Action"
+       parameter="profile_item"/>
+      <on_enable
+       function="Block.Enable"
+       parameter="profile_item" />
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0c7155667ed13ae52fe642e9cc457b8e860ee2e7
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_plus.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_plus"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_call
+   label="Block Resident by name..."
+   name="block_resident_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="block_res_by_name"/>
+  </menu_item_call>
+  <menu_item_call
+   label="Block object by name"
+   name="block_object_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="block_obj_by_name"/>
+  </menu_item_call>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..2efb70ee37b7966d991e5d6e3ae602d8f5fd94c3
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_blocked_view.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu 
+     name="menu_blocked_view"
+     left="0" bottom="0" visible="false"
+     mouse_opaque="false">
+  <menu_item_check
+   label="Sort by name"
+   name="sort_by_name">
+      <on_click
+       function="Block.Action"
+       parameter="sort_by_name"/>
+      <on_check
+       function="Block.Check"
+       parameter="sort_by_name"/>
+  </menu_item_check>
+  <menu_item_check
+   label="Sort by type"
+   name="sort_by_type">
+      <on_click
+       function="Block.Action"
+       parameter="sort_by_type" />
+      <on_check
+       function="Block.Check"
+       parameter="sort_by_type" />
+  </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
similarity index 83%
rename from indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
rename to indra/newview/skins/default/xui/en/menu_people_friends_view.xml
index b452f96e7a90ee28be446ba7a5df9680ead547ac..dde9432867a2609251a8791076a0c028208a29e7 100644
--- a/indra/newview/skins/default/xui/en/menu_people_friends_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_friends_view.xml
@@ -40,8 +40,12 @@
      function="CheckControl"
      parameter="FriendsListShowPermissions" />
   </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Friends.ViewSort.Action" parameter="panel_block_list_sidetray" />
-  </menu_item_call>
+  <menu_item_check name="view_conversation" label="View Conversation Log...">
+    <menu_item_check.on_check
+     function="Floater.Visible"
+     parameter="conversation" />
+    <menu_item_check.on_click
+     function="Floater.Toggle"
+     parameter="conversation" />
+  </menu_item_check>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups.xml b/indra/newview/skins/default/xui/en/menu_people_groups.xml
index 8f89d37dbbef0371595d1836d1f091bdcd3b348d..1e0364b84eb658635cb4ff8aae7558c1a82c3b7d 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups.xml
@@ -1,7 +1,17 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<menu name="menu_group_plus"
+<toggleable_menu name="menu_group_plus"
  left="0" bottom="0" visible="false"
  mouse_opaque="false" opaque="true" color="MenuDefaultBgColor">
+  <menu_item_call
+   label="Activate"
+   name="Activate">
+    <menu_item_call.on_click
+     function="People.Groups.Action"
+     parameter="activate" />
+    <menu_item_call.on_enable
+     function="People.Groups.Enable"
+     parameter="activate" />
+  </menu_item_call>
   <menu_item_call
    label="View Info"
    name="View Info">
@@ -23,7 +33,7 @@
      parameter="chat" />
   </menu_item_call>
   <menu_item_call
-   label="Call"
+   label="Voice call"
    name="Call">
     <menu_item_call.on_click
      function="People.Groups.Action"
@@ -33,17 +43,6 @@
      parameter="call" />
   </menu_item_call>
   <menu_item_separator />
-  <menu_item_call
-   label="Activate"
-   name="Activate">
-    <menu_item_call.on_click
-     function="People.Groups.Action"
-     parameter="activate" />
-    <menu_item_call.on_enable
-     function="People.Groups.Enable"
-     parameter="activate" />
-  </menu_item_call>
-  <menu_item_separator />
   <menu_item_call
    label="Leave"
    name="Leave">
@@ -54,4 +53,4 @@
      function="People.Groups.Enable"
      parameter="leave" />
   </menu_item_call>
-</menu>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
similarity index 65%
rename from indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
rename to indra/newview/skins/default/xui/en/menu_people_groups_view.xml
index c710fe3b9b71ed820e533613e3c55f992cf04240..73f79f1e70d69fd8811a22afb941ff84b82d338f 100644
--- a/indra/newview/skins/default/xui/en/menu_people_groups_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_groups_view.xml
@@ -14,13 +14,4 @@
        function="CheckControl"
        parameter="GroupListShowIcons" />
   </menu_item_check>
-  <menu_item_call
-   label="Leave Selected Group"
-   layout="topleft"
-   name="Leave Selected Group">
-      <menu_item_call.on_click
-       function="People.Group.Minus.Action"/>
-      <menu_item_call.on_enable
-       function="People.Group.Minus.Enable"/>
-  </menu_item_call>
 </toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby.xml b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
index d2e35e4cc00454f9fc78dd7bbc81a8cec94fc3c9..3abb5f7bc8ca3a8a142da8c254d20a47e0de3475 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby.xml
@@ -1,28 +1,69 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu
  layout="topleft"
- name="Avatar Context Menu">
+ name="Nearby People Context Menu">
     <menu_item_call
      label="View Profile"
      layout="topleft"
-     name="View Profile">
+     name="view_profile">
         <menu_item_call.on_click
          function="Avatar.Profile" />
     </menu_item_call>
+    <menu_item_call
+     label="IM"
+     layout="topleft"
+     name="im">
+        <menu_item_call.on_click
+         function="Avatar.IM" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_im"/> 
+    </menu_item_call>
+    <menu_item_call
+    label="Offer Teleport"
+    name="offer_teleport">
+      <menu_item_call.on_click
+       function="Avatar.OfferTeleport"/>
+      <menu_item_call.on_enable
+      function="Avatar.EnableItem"
+      parameter="can_offer_teleport"/>
+    </menu_item_call>
+    <menu_item_call
+     label="Voice call"
+     layout="topleft"
+     name="voice_call">
+        <menu_item_call.on_click
+         function="Avatar.Call" />
+        <menu_item_call.on_enable
+         function="Avatar.EnableItem"
+         parameter="can_call" />
+    </menu_item_call>
+    <menu_item_separator />
+    <menu_item_call
+     label="View chat history..."
+     layout="topleft"
+     name="chat_history">
+        <menu_item_call.on_click
+         function="Avatar.Calllog" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_callog"/>
+    </menu_item_call>
+    <menu_item_separator name="separator_chat_history"/>
     <menu_item_call
      label="Add Friend"
      layout="topleft"
-     name="Add Friend">
+     name="add_friend">
         <menu_item_call.on_click
          function="Avatar.AddFriend" />
-        <menu_item_call.on_enable
+        <menu_item_call.on_visible
          function="Avatar.EnableItem"
          parameter="can_add" />
     </menu_item_call>
     <menu_item_call
      label="Remove Friend"
      layout="topleft"
-     name="Remove Friend">
+     name="remove_friend">
         <menu_item_call.on_click
          function="Avatar.RemoveFriend" />
         <menu_item_call.on_enable
@@ -30,26 +71,30 @@
          parameter="can_delete" />
     </menu_item_call>
     <menu_item_call
-     label="IM"
+     label="Invite to group..."
      layout="topleft"
-     name="IM">
+     name="invite_to_group">
         <menu_item_call.on_click
-         function="Avatar.IM" />
+         function="Avatar.InviteToGroup" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_invite"/>
     </menu_item_call>
+    <menu_item_separator name="separator_invite_to_group"/>
     <menu_item_call
-     label="Call"
+     label="Zoom In"
      layout="topleft"
-     name="Call">
-        <menu_item_call.on_click
-         function="Avatar.Call" />
-        <menu_item_call.on_enable
-         function="Avatar.EnableItem"
-         parameter="can_call" />
+     name="zoom_in">
+      <menu_item_call.on_click
+       function="Avatar.ZoomIn" />
+      <menu_item_call.on_enable
+       function="Avatar.EnableItem"
+       parameter="can_zoom_in"/>
     </menu_item_call>
     <menu_item_call
      label="Map"
      layout="topleft"
-     name="Map">
+     name="map">
         <menu_item_call.on_click
          function="Avatar.ShowOnMap" />
         <menu_item_call.on_enable
@@ -59,21 +104,27 @@
     <menu_item_call
      label="Share"
      layout="topleft"
-     name="Share">
+     name="share">
         <menu_item_call.on_click
          function="Avatar.Share" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_share"/>
     </menu_item_call>
     <menu_item_call
      label="Pay"
      layout="topleft"
-     name="Pay">
+     name="pay">
         <menu_item_call.on_click
          function="Avatar.Pay" />
+        <menu_item_call.on_enable
+      	 function="Avatar.EnableItem"
+         parameter="can_pay"/> 
     </menu_item_call>
     <menu_item_check
      label="Block/Unblock"
      layout="topleft"
-     name="Block/Unblock">
+     name="block_unblock">
         <menu_item_check.on_click
          function="Avatar.BlockUnblock" />
         <menu_item_check.on_check
@@ -83,13 +134,5 @@
          function="Avatar.EnableItem"
          parameter="can_block" />
     </menu_item_check>
-    <menu_item_call
-    label="Offer Teleport"
-    name="teleport">
-      <menu_item_call.on_click
-       function="Avatar.OfferTeleport"/>
-      <menu_item_call.on_enable
-      function="Avatar.EnableItem"
-      parameter="can_offer_teleport"/>
-    </menu_item_call>
+    <menu_item_separator />
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
index 5d58a9d28957813d94ef9cf42c71bbc375b03a65..5f973088fdda3ad89a31eee676b2945d4786fbb5 100644
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_multiselect.xml
@@ -6,7 +6,7 @@
      enabled="false"
      label="Add Friends"
      layout="topleft"
-     name="Add Friends">
+     name="add_friends">
         <on_click
          function="Avatar.AddFriends" />
         <on_enable
@@ -16,7 +16,7 @@
     <menu_item_call
      label="Remove Friends"
      layout="topleft"
-     name="Remove Friend">
+     name="remove_friends">
         <menu_item_call.on_click
          function="Avatar.RemoveFriend" />
         <menu_item_call.on_enable
@@ -26,7 +26,7 @@
     <menu_item_call
      label="IM"
      layout="topleft"
-     name="IM">
+     name="im">
         <on_click
          function="Avatar.IM" />
     </menu_item_call>
@@ -34,7 +34,7 @@
      enabled="false"
      label="Call"
      layout="topleft"
-     name="Call">
+     name="call">
         <on_click
          function="Avatar.Call" />
         <on_enable
@@ -45,7 +45,7 @@
      enabled="false"
      label="Share"
      layout="topleft"
-     name="Share">
+     name="share">
         <on_click
          function="Avatar.Share" />
     </menu_item_call>
@@ -53,13 +53,13 @@
      enabled="false"
      label="Pay"
      layout="topleft"
-     name="Pay">
+     name="pay">
         <on_click
          function="Avatar.Pay" />
     </menu_item_call>
     <menu_item_call
     label="Offer Teleport"
-    name="teleport">
+    name="offer_teleport">
       <menu_item_call.on_click
        function="Avatar.OfferTeleport"/>
       <menu_item_call.on_enable
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
new file mode 100644
index 0000000000000000000000000000000000000000..da88ca9f4d53ecd24f8591b8d0bef29cda153540
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_people_nearby_view.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<toggleable_menu
+ name="menu_group_plus"
+ left="0" bottom="0" visible="false"
+ mouse_opaque="false">
+    <menu_item_check
+       label="Sort by Recent Speakers"
+       name="sort_by_recent_speakers">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+       parameter="sort_by_recent_speakers"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_by_recent_speakers"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Sort by Name"
+       name="sort_name">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="sort_name"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_name"/>
+    </menu_item_check>
+    <menu_item_check
+       label="Sort by Distance"
+       name="sort_distance">
+      <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="sort_distance"/>
+      <menu_item_check.on_check
+         function="People.Nearby.ViewSort.CheckItem"
+         parameter="sort_distance"/>
+    </menu_item_check>
+    <menu_item_separator layout="topleft" />
+    <menu_item_check name="view_icons" label="View People Icons">
+        <menu_item_check.on_click
+         function="People.Nearby.ViewSort.Action"
+         parameter="view_icons" />
+        <menu_item_check.on_check
+         function="CheckControl"
+         parameter="NearbyListShowIcons" />
+    </menu_item_check>
+    <menu_item_check name ="view_map" label="View Map">
+        <menu_item_check.on_check
+         function="CheckControl"
+         parameter="NearbyListShowMap" />
+        <menu_item_check.on_click
+         function="ToggleControl"
+         parameter="NearbyListShowMap" />
+    </menu_item_check>
+</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
deleted file mode 100644
index 614dd693c57a10c8f4f87d7bc6e38854df4fad30..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/menu_people_nearby_view_sort.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<toggleable_menu
-     name="menu_group_plus"
-     left="0" bottom="0" visible="false"
-     mouse_opaque="false">
-  <menu_item_check
-     label="Sort by Recent Speakers"
-     name="sort_by_recent_speakers">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_by_recent_speakers"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_by_recent_speakers"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Name"
-     name="sort_name">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_name"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_name"/>
-  </menu_item_check>
-  <menu_item_check
-     label="Sort by Distance"
-     name="sort_distance">
-    <menu_item_check.on_click
-       function="People.Nearby.ViewSort.Action"
-       parameter="sort_distance"/>
-    <menu_item_check.on_check
-       function="People.Nearby.ViewSort.CheckItem"
-       parameter="sort_distance"/>
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_check name="view_icons" label="View People Icons">
-    <menu_item_check.on_click
-     function="People.Nearby.ViewSort.Action"
-     parameter="view_icons" />
-    <menu_item_check.on_check
-     function="CheckControl"
-     parameter="NearbyListShowIcons" />
-  </menu_item_check>
-  <menu_item_check name ="view_map" label="View Map">
-    <menu_item_check.on_check
-      function="CheckControl"
-      parameter="NearbyListShowMap" />
-    <menu_item_check.on_click
-      function="ToggleControl"
-      parameter="NearbyListShowMap" />
-  </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Nearby.ViewSort.Action" userdata="panel_block_list_sidetray" />
-  </menu_item_call>
-</toggleable_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
similarity index 81%
rename from indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
rename to indra/newview/skins/default/xui/en/menu_people_recent_view.xml
index 485a5a658caadb97253b85bb79c1a01827dcae51..1dbc90dd2be49550ea43950a61f88b9d08cbc923 100644
--- a/indra/newview/skins/default/xui/en/menu_people_recent_view_sort.xml
+++ b/indra/newview/skins/default/xui/en/menu_people_recent_view.xml
@@ -32,8 +32,4 @@
      function="CheckControl"
      parameter="RecentListShowIcons" />
   </menu_item_check>
-  <menu_item_separator layout="topleft" />
-  <menu_item_call name="show_blocked_list" label="Show Blocked Residents &amp; Objects">
-    <menu_item_call.on_click function="People.Recent.ViewSort.Action" userdata="panel_block_list_sidetray" />
-  </menu_item_call>
 </toggleable_menu>
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 73f0fa79797a6d88e84f093afddf48d646581001..7cd56f257a82808d1a31f4c978c618c6bd78a218 100644
--- a/indra/newview/skins/default/xui/en/menu_url_agent.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_agent.xml
@@ -1,13 +1,27 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <context_menu
  layout="topleft"
- name="Url Popup">
+ name="Url Popup">  
     <menu_item_call
-     label="Show Resident Profile"
+     label="View Profile"
      layout="topleft"
      name="show_agent">
         <menu_item_call.on_click
-         function="Url.ShowProfile" />
+         function="Url.ShowProfile" />         
+    </menu_item_call>
+    <menu_item_call
+     label="Send IM..."
+     layout="topleft"
+     name="send_im">
+        <menu_item_call.on_click
+         function="Url.SendIM" />        
+    </menu_item_call>
+    <menu_item_call
+     label="Add Friend..."
+     layout="topleft"
+     name="add_friend">
+        <menu_item_call.on_click
+         function="Url.AddFriend" />        
     </menu_item_call>
     <menu_item_separator
      layout="topleft" />
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 35c2269b0d1a5f9d941c533504eecb5129fcd831..87ab58e622e70dcd717cee5fd35b2b2584b54674 100644
--- a/indra/newview/skins/default/xui/en/menu_url_objectim.xml
+++ b/indra/newview/skins/default/xui/en/menu_url_objectim.xml
@@ -3,7 +3,7 @@
  layout="topleft"
  name="Url Popup">
     <menu_item_call
-     label="Show Object Information"
+     label="Object Profile..."
      layout="topleft"
      name="show_object">
         <menu_item_call.on_click
diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml
index caa36e7302c588701c95d7260e07ed630bbe88b5..a11cd13fdbb5c9c0436cad7af6524e467e5f47cc 100644
--- a/indra/newview/skins/default/xui/en/menu_viewer.xml
+++ b/indra/newview/skins/default/xui/en/menu_viewer.xml
@@ -130,19 +130,24 @@
        label="Status"
        name="Status"
        tear_off="true">
-        <menu_item_call
-         label="Away"
-         name="Set Away">
-          <menu_item_call.on_click
+        <menu_item_check
+         name="Away"
+         label="Away">
+          <menu_item_check.on_check
+           function="View.Status.CheckAway" />
+          <menu_item_check.on_click
            function="World.SetAway" />
-        </menu_item_call>
-        <menu_item_call
-         label="Busy"
-         name="Set Busy">
-          <menu_item_call.on_click
-           function="World.SetBusy"/>
-        </menu_item_call>
-      </menu>
+        </menu_item_check>
+        <menu_item_check
+         name="Do Not Disturb"
+         label="Do Not Disturb">
+          <menu_item_check.on_check
+           function="View.Status.CheckDoNotDisturb" />
+          <menu_item_check.on_click
+           function="World.SetDoNotDisturb"/>
+        </menu_item_check>
+      
+    </menu>
 
       <menu_item_separator/>
 
@@ -180,8 +185,7 @@
         </menu_item_call>
          <menu_item_call
          label="Toolbar buttons..."
-         name="Toolbars"
-         shortcut="control|T">
+         name="Toolbars">
             <menu_item_call.on_click
              function="Floater.Toggle"
              parameter="toybox" />
@@ -218,17 +222,28 @@
      label="Communicate"
      name="Communicate"
      tear_off="true">
-        <menu_item_check
-         label="Chat..."
+       <menu_item_check
+         label="Conversations..."
+         name="Conversations"
+         shortcut="control|T">
+            <menu_item_check.on_check
+             function="Floater.IsOpen"
+             parameter="im_container" />
+            <menu_item_check.on_click
+             function="Floater.ToggleOrBringToFront"
+             parameter="im_container" />
+	</menu_item_check>
+	<menu_item_check
+         label="Nearby Chat..."
          name="Nearby Chat"
          shortcut="control|H"
          use_mac_ctrl="true">
             <menu_item_check.on_check
              function="Floater.Visible"
-             parameter="chat_bar" />
+             parameter="nearby_chat" />
             <menu_item_check.on_click
-             function="Floater.Toggle"
-             parameter="chat_bar" />
+             function="Floater.ToggleOrBringToFront"
+             parameter="nearby_chat" />
         </menu_item_check>
         <menu_item_check
          label="Speak"
@@ -244,26 +259,48 @@
              parameter="speak" />
         </menu_item_check>
         <menu_item_check
-         label="Voice settings..."
-         name="Nearby Voice">
+         name="Conversation Log..."
+         label="Conversation Log...">
             <menu_item_check.on_check
              function="Floater.Visible"
-             parameter="voice_controls" />
+             parameter="conversation" />
+            <menu_item_check.on_enable
+             function="Conversation.IsConversationLoggingAllowed" />
             <menu_item_check.on_click
              function="Floater.Toggle"
-             parameter="voice_controls" />
+             parameter="conversation" />
         </menu_item_check>
-        <menu_item_check
-         label="Voice morphing..."
-         name="ShowVoice"
+        <menu_item_separator/>
+        <menu
+         label="Voice morphing"
+         name="VoiceMorphing"
          visibility_control="VoiceMorphingEnabled">
-            <menu_item_check.on_check
-             function="Floater.Visible"
-             parameter="voice_effect" />
-            <menu_item_check.on_click
-             function="Floater.Toggle"
-             parameter="voice_effect" />
-        </menu_item_check>
+            <menu_item_check
+             label="No voice morphing"
+             name="NoVoiceMorphing">
+                <menu_item_check.on_check
+                 function="Communicate.VoiceMorphing.NoVoiceMorphing.Check" />
+                <menu_item_check.on_click
+                 function="Communicate.VoiceMorphing.NoVoiceMorphing.Click" />
+            </menu_item_check>
+            <menu_item_separator/>
+            <menu_item_check
+             label="Preview..."
+             name="Preview">
+                <menu_item_check.on_check
+                 function="Floater.Visible"
+                 parameter="voice_effect" />
+                <menu_item_check.on_click
+                 function="Floater.Toggle"
+                 parameter="voice_effect" />
+            </menu_item_check>
+            <menu_item_call
+             label="Subscribe..."
+             name="Subscribe">
+                <menu_item_call.on_click
+                 function="Communicate.VoiceMorphing.Subscribe" />
+            </menu_item_call>
+        </menu>
         <menu_item_check
          label="Gestures..."
          name="Gestures"
@@ -313,8 +350,19 @@
          label="Block List"
          name="Block List">
             <menu_item_call.on_click
-              function="Communicate.BlockList" />
+              function="SideTray.PanelPeopleTab"
+              parameter="blocked_panel" />
         </menu_item_call>
+      <menu_item_separator/>
+      <menu_item_check
+       name="Do Not Disturb"
+       label="Do Not Disturb">
+        <menu_item_check.on_check
+         function="View.Status.CheckDoNotDisturb" />
+        <menu_item_check.on_click
+         function="World.SetDoNotDisturb"/>
+      </menu_item_check>
+
     </menu>
     <menu
      create_jump_keys="true"
@@ -1251,7 +1299,58 @@
              function="Floater.Show"
              parameter="hud" />
         </menu_item_call>-->
-
+		<menu_item_separator/>
+		
+		<menu_item_call
+             label="User’s guide"
+             name="User’s guide">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/English-Knowledge-Base/Second-Life-User-s-Guide/ta-p/1244857"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Knowledge Base"
+             name="Knowledge Base">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/tkb/communitypage"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Wiki"
+             name="Wiki">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://wiki.secondlife.com"/>
+        </menu_item_call>
+        <menu_item_call
+             label="Community Forums"
+             name="Community Forums">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Forums/ct-p/Forums"/>
+        </menu_item_call>         
+        <menu_item_call
+             label="Support portal"
+             name="Support portal">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="https://support.secondlife.com/"/>         
+        </menu_item_call>
+        <menu_item_separator/>
+        <menu_item_call
+             label="[SECOND_LIFE] News"
+             name="Second Life News">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Featured-News/bg-p/blog_feature_news"/>  
+        </menu_item_call>
+        <menu_item_call
+             label="[SECOND_LIFE] Blogs"
+             name="Second Life Blogs">
+             <menu_item_call.on_click
+                 function="Advanced.ShowURL"
+                 parameter="http://community.secondlife.com/t5/Blogs/ct-p/Blogs"/>
+        </menu_item_call>
         <menu_item_separator/>
 
         <menu_item_call
@@ -2956,13 +3055,6 @@
                 <menu_item_call.on_click
                  function="Advanced.PrintAgentInfo" />
             </menu_item_call>
-            <menu_item_call
-             label="Memory Stats"
-             name="Memory Stats"
-             shortcut="control|alt|shift|M">
-                <menu_item_call.on_click
-                 function="Advanced.PrintTextureMemoryStats" />
-            </menu_item_call>
             <menu_item_check
              label="Region Debug Console"
              name="Region Debug Console"
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index c8f5cbb2b015209d797cfd0c4e0a88495f95285d..105bef7321aec94bcb0e5b2394bd7e6c531c24e7 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -352,7 +352,7 @@ Save all changes to clothing/body parts?
    icon="alertmodal.tga"
    name="FriendsAndGroupsOnly"
    type="alertmodal">
-    Non-friends won't know that you've choosen to ignore their calls and instant messages.
+    Non-friends won't know that you've chosen to ignore their calls and instant messages.
     <usetemplate
      name="okbutton"
      yestext="OK"/>
@@ -3085,6 +3085,7 @@ Would you like to trust this authority?
    icon="alertmodal.tga"
    name="GrantedModifyRights"
    persist="true"
+   log_to_im="true"   
    type="notify">
 [NAME] has given you permission to edit their objects.
   </notification>
@@ -3093,6 +3094,7 @@ Would you like to trust this authority?
    icon="alertmodal.tga"
    name="RevokedModifyRights"
    persist="true"
+   log_to_im="true"   
    type="notify">
 Your privilege to modify [NAME]&apos;s objects has been revoked
   </notification>
@@ -3726,12 +3728,15 @@ Cannot offer friendship at this time. Please try again in a moment.
 
   <notification
    icon="alert.tga"
-   name="BusyModeSet"
+   name="DoNotDisturbModeSet"
    type="alert">
-Busy mode is set.
-Chat and instant messages will be hidden. Instant messages will get your Busy mode response. All teleportation offers will be declined. All inventory offers will go to your Trash.
+Do Not Disturb is on.  You will not be notified of incoming communications.
+
+- Other residents will receive your Do Not Disturb response (set in Preferences &gt; General).
+- Teleportation offers will be declined.
+- Voice calls will be rejected.
     <usetemplate
-     ignoretext="I change my status to Busy mode"
+     ignoretext="I change my status to Do Not Disturb mode"
      name="okignore"
      yestext="OK"/>
   </notification>
@@ -4277,6 +4282,8 @@ Are you sure you want to change the Estate Covenant?
   <notification
    icon="notifytip.tga"
    name="RegionEntryAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
    <tag>fail</tag>
 The region you're trying to visit contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
@@ -4285,6 +4292,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="RegionEntryAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The region you're trying to visit contains [REGIONMATURITY] content, which is accessible to adults only.
@@ -4356,6 +4365,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="TeleportEntryAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <unique>
       <context>REGIONMATURITY</context>
@@ -4367,6 +4378,8 @@ The region you're trying to visit contains [REGIONMATURITY] content, but your cu
   <notification
    icon="notifytip.tga"
    name="TeleportEntryAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <unique>
       <context>REGIONMATURITY</context>
@@ -4487,6 +4500,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandClaimAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     The land you're trying to claim contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
     <tag>fail</tag>
@@ -4495,6 +4510,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandClaimAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The land you're trying to claim contains [REGIONMATURITY] content, which is accessible to adults only.
@@ -4552,6 +4569,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandBuyAccessBlocked_Notify"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     The land you're trying to buy contains [REGIONMATURITY] content, but your current preferences are set to exclude [REGIONMATURITY] content.
     <tag>fail</tag>
@@ -4560,6 +4579,8 @@ You won't receive any more notifications that you're about to visit a region wit
   <notification
    icon="notifytip.tga"
    name="LandBuyAccessBlocked_NotifyAdultsOnly"
+   log_to_im="false"
+   log_to_chat="true"
    type="notifytip">
     <tag>fail</tag>
     The land you're trying to buy contains [REGIONMATURITY] content, which is accessible to adults only.
@@ -5003,6 +5024,20 @@ Go to your [http://secondlife.com/account/ Dashboard] to see your account histor
      yestext="Go to page"/>
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="ConfirmAddingChatParticipants"
+   type="alertmodal">
+    <unique/>
+When you add a person to an existing conversation, a new conversation will be created.  All participants will receive new conversation notifications.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm adding chat paticipants"
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="Ok"/>
+  </notification>
+ 
   <notification
    icon="alertmodal.tga"
    name="ConfirmQuit"
@@ -5172,25 +5207,25 @@ Do you want to replace it with the selected object?
 
   <notification
    icon="alert.tga"
-   label="Busy Mode Warning"
-   name="BusyModePay"
+   label="Do Not Disturb Mode Warning"
+   name="DoNotDisturbModePay"
    type="alert">
-You are in Busy Mode, which means you will not receive any items offered in exchange for this payment.
+You have turned on Do Not Disturb. You will not receive any items offered in exchange for this payment.
 
-Would you like to leave Busy Mode before completing this transaction?
+Would you like to turn off Do Not Disturb before completing this transaction?
     <tag>confirm</tag>
     <form name="form">
       <ignore name="ignore"
        save_option="true"
-       text="I am about to pay a person or object while I am in Busy mode"/>
+       text="I am about to pay a person or object while I am in Do Not Disturb mode"/>
       <button
        default="true"
-       ignore="Always leave Busy Mode"
+       ignore="Always leave Do Not Disturb Mode"
        index="0"
        name="Yes"
        text="OK"/>
       <button
-       ignore="Never leave Busy Mode"
+       ignore="Never leave Do Not Disturb Mode"
        index="1"
        name="No"
        text="Cancel"/>
@@ -5501,6 +5536,8 @@ The string [STRING_NAME] is missing from strings.xml
   <notification
    icon="notifytip.tga"
    name="IMSystemMessageTip"
+   log_to_im="true"   
+   log_to_chat="false"   
    type="notifytip">
 [MESSAGE]
   </notification>
@@ -5544,18 +5581,14 @@ Topic: [SUBJECT], Message: [MESSAGE]
 
   <notification
    icon="notifytip.tga"
-   name="FriendOnline"
+   name="FriendOnlineOffline"
+   log_to_chat="false"
    type="notifytip">
     <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Online
-  </notification>
-
-  <notification
-   icon="notifytip.tga"
-   name="FriendOffline"
-   type="notifytip">
-    <tag>friendship</tag>
-&lt;nolink&gt;[NAME]&lt;/nolink&gt; is Offline
+&lt;nolink&gt;[NAME]&lt;/nolink&gt; is [STATUS]
+    <unique combine="cancel_old">
+      <context>NAME</context>
+    </unique>
   </notification>
 
   <notification
@@ -5799,6 +5832,8 @@ You don&apos;t have permission to copy this.
   <notification
    icon="notifytip.tga"
    name="InventoryAccepted"
+   log_to_im="true"   
+   log_to_chat="false"
    type="notifytip">
 [NAME] received your inventory offer.
   </notification>
@@ -5806,6 +5841,8 @@ You don&apos;t have permission to copy this.
   <notification
    icon="notifytip.tga"
    name="InventoryDeclined"
+   log_to_im="true"   
+   log_to_chat="false"
    type="notifytip">
 [NAME] declined your inventory offer.
   </notification>
@@ -5887,6 +5924,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
   <notification
    icon="notify.tga"
    name="PaymentReceived"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>funds</tag>
@@ -5896,6 +5934,7 @@ Please select at least one type of content to search (General, Moderate, or Adul
   <notification
    icon="notify.tga"
    name="PaymentSent"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>funds</tag>
@@ -6040,6 +6079,7 @@ The objects on the selected parcel that are NOT owned by you have been returned
   <notification
    icon="notify.tga"
    name="ServerObjectMessage"
+   log_to_im="true"   
    persist="true"
    type="notify">
 Message from [NAME]:
@@ -6438,7 +6478,9 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="UserGiveItem"
-   type="offer">
+   log_to_im ="true"
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has given you this [OBJECTTYPE]:
 [ITEM_SLURL]
     <form name="form">
@@ -6493,7 +6535,10 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOffered"
-   type="offer">
+   log_to_im="true"
+   log_to_chat="false"
+   type="offer"
+   sound="UISndNewIncomingIMSession">
 [NAME_SLURL] has offered to teleport you to their location:
 
 “[MESSAGE]”
@@ -6514,6 +6559,8 @@ Your object named &lt;nolink&gt;[OBJECTFROMNAME]&lt;/nolink&gt; has given you th
   <notification
    icon="notify.tga"
    name="TeleportOffered_MaturityExceeded"
+   log_to_im="true"
+   log_to_chat="false"
    type="offer">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6537,6 +6584,8 @@ This region contains [REGION_CONTENT_MATURITY] content, but your current prefere
   <notification
    icon="notify.tga"
    name="TeleportOffered_MaturityBlocked"
+   log_to_im="true"
+   log_to_chat="false"
    type="notifytip">
 [NAME_SLURL] has offered to teleport you to their location:
 
@@ -6550,7 +6599,10 @@ However, this region contains content accessible to adults only.
   <notification
    icon="notify.tga"
    name="TeleportOfferSent"
-   type="offer">
+   log_to_im="true"
+   log_to_chat="false"
+   show_toast="false"
+   type="notify">
 	Teleport offer sent to [TO_NAME]
   </notification>
 
@@ -6577,6 +6629,7 @@ However, this region contains content accessible to adults only.
   <notification
    icon="notify.tga"
    name="OfferFriendship"
+   log_to_im="true"
    type="offer">
     <tag>friendship</tag>
     <tag>confirm</tag>
@@ -6600,7 +6653,9 @@ However, this region contains content accessible to adults only.
   <notification
    icon="notify.tga"
    name="FriendshipOffered"
-   type="offer">
+   log_to_im="true"   
+   show_toast="false"   
+   type="notify">
     <tag>friendship</tag>
 	You have offered friendship to [TO_NAME]
   </notification>
@@ -6629,7 +6684,8 @@ However, this region contains content accessible to adults only.
   <notification
    icon="notify.tga"
    name="FriendshipAccepted"
-   type="offer">
+   log_to_im="true"   
+   type="notify">
     <tag>friendship</tag>
 &lt;nolink&gt;[NAME]&lt;/nolink&gt; accepted your friendship offer.
   </notification>
@@ -6637,6 +6693,7 @@ However, this region contains content accessible to adults only.
   <notification
    icon="notify.tga"
    name="FriendshipDeclined"
+   log_to_im="true"   
    persist="true"
    type="notify">
     <tag>friendship</tag>
@@ -6646,7 +6703,9 @@ However, this region contains content accessible to adults only.
     <notification
    icon="notify.tga"
    name="FriendshipAcceptedByMe"
-   type="offer">
+   log_to_im="true"   
+   show_toast="false"
+   type="notify">
     <tag>friendship</tag>
 Friendship offer accepted.
   </notification>
@@ -6654,7 +6713,9 @@ Friendship offer accepted.
   <notification
    icon="notify.tga"
    name="FriendshipDeclinedByMe"
-   type="offer">
+   log_to_im="true"   
+   show_toast="false"   
+   type="notify">
     <tag>friendship</tag>
 Friendship offer declined.
   </notification>
@@ -6703,6 +6764,7 @@ If you stay in this region you will be logged out.
   <notification
    icon="notify.tga"
    name="LoadWebPage"
+   show_toast="false"
    type="notify">
 Load web page [URL]?
 
@@ -6805,6 +6867,7 @@ Do not allow access if you do not fully understand why it wants access to your a
   <notification
    icon="notify.tga"
    name="ScriptDialog"
+   show_toast="false"
    type="notify">
 [NAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
 [MESSAGE]
@@ -6823,6 +6886,7 @@ Do not allow access if you do not fully understand why it wants access to your a
   <notification
    icon="notify.tga"
    name="ScriptDialogGroup"
+   show_toast="false"
    type="notify">
     <tag>group</tag>
 [GROUPNAME]&apos;s &apos;&lt;nolink&gt;[TITLE]&lt;/nolink&gt;&apos;
@@ -9642,14 +9706,6 @@ There is no suitable surface to sit on, try another spot.
 No room to sit here, try another spot.
   </notification>
 
-  <notification
-   icon="alertmodal.tga"
-   name="AutopilotCanceled"
-   type="notify">
-   <tag>fail</tag>
-Autopilot canceled
-  </notification>
-
   <notification
    icon="alertmodal.tga"
    name="ClaimObjectFailedNoPermission"
@@ -9938,4 +9994,41 @@ An internal error prevented us from properly updating your viewer.  The L$ balan
 Cannot create large prims that intersect other players.  Please re-try when other players have moved.
   </notification>
 
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatClearLog"
+   type="alertmodal">
+    This will delete the logs of previous conversations, and any backups of that file.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete the log of previous conversations."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+    
+  <notification
+   icon="alertmodal.tga"
+   name="PreferenceChatDeleteTranscripts"
+   type="alertmodal">
+    This will delete the transcripts for all previous conversations. The list of past conversations will not be affected. All files with the suffixes .txt and txt.backup in the folder [FOLDER] will be deleted.
+    <tag>confirm</tag>
+    <usetemplate
+     ignoretext="Confirm before I delete transcripts."
+     name="okcancelignore"
+     notext="Cancel"
+     yestext="OK"/>
+  </notification>
+
+  <notification
+   icon="alert.tga"
+   name="PreferenceChatPathChanged"
+   type="alert">
+   Unable to move files. Restored previous path.
+    <usetemplate
+     ignoretext="Unable to move files. Restored previous path."
+     name="okignore"
+     yestext="OK"/>
+  </notification>
+  
 </notifications>
diff --git a/indra/newview/skins/default/xui/en/panel_activeim_row.xml b/indra/newview/skins/default/xui/en/panel_activeim_row.xml
deleted file mode 100644
index 9369d1b5cf489764a24ed35b4b50fdce97e6f3c9..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_activeim_row.xml
+++ /dev/null
@@ -1,97 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
-	name="panel_activeim_row"
-	layout="topleft"
-	follows="left|right"
-	top="0"
-	left="0"
-	height="35"
-	width="318"
-  background_opaque="false"
-  background_visible="true"
-  bg_alpha_color="0.0 0.0 0.0 0.0" >
-  <chiclet_im_p2p
-		name="p2p_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_p2p"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_p2p>
-  <chiclet_im_group
-		name="group_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_grp"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_group>
-  <chiclet_im_adhoc
-		name="adhoc_chiclet"
-		layout="topleft"
-		follows="left"
-		top="3"
-		left="5"
-		height="25"
-		width="25"
-    visible="false"
-    speaker.name="speaker_hoc"
-    speaker.width="20"
-    speaker.height="25"
-    speaker.left="25"
-    speaker.top="25"
-    speaker.auto_update="true"
-    speaker.draw_border="false"
-    speaker.visible="false">
-  </chiclet_im_adhoc>
-	<text
-	    translate="false"
-		type="string"
-		name="contact_name"
-		layout="topleft"
-		top="10"
-		left_pad="10"
-		height="14"
-		width="250"
-		length="1"
-		follows="right|left"
-		parse_urls="false"
-		use_ellipses="true"
-		font="SansSerifBold">
-    TestString PleaseIgnore
-  </text>
-  <button
-    top="10"
-    right="-5"
-    width="17"
-    height="17"
-    layout="topleft"
-    follows="right"
-    name="hide_btn"
-    mouse_opaque="true"
-    label=""
-    tab_stop="false"
-    image_unselected="Toast_CloseBtn"
-    image_selected="Toast_CloseBtn"
-  />
-</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml b/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
deleted file mode 100644
index d68fa6ca6c2d4cd6b7885793c5222683a460441a..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_adhoc_control_panel.xml
+++ /dev/null
@@ -1,95 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="215"
- name="panel_im_control_panel"
- width="150">
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="215"
-     layout="topleft"
-     left="3"
-     name="vertical_stack"
-     orientation="vertical"
-     top="0"
-     width="147">
-        <layout_panel
-         auto_resize="true"
-         follows="top|left"
-         height="130"
-         layout="topleft"
-         left="0"
-         min_height="0"
-         mouse_opaque="false"
-         width="147"
-         top="0"
-         name="speakers_list_panel">
-            <avatar_list
-             color="DkGray2"
-             follows="all"
-             height="130"
-             ignore_online_status="true"
-             layout="topleft"
-             name="speakers_list"
-             opaque="false"
-             show_info_btn="true"
-             show_profile_btn="false"
-             show_speaking_indicator="false"
-             width="147" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Call"
-             name="call_btn"
-             width="130"
-             top="0" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Leave Call"
-             name="end_call_btn"
-             top="0"/>
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="130"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="20"
-             label="Voice Controls"
-             name="voice_ctrls_btn"
-             top="0"
-             use_ellipses="true" />
-        </layout_panel>
-    </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
index b7c58eb6ab14d02ff897c161c3142e660eaf3310..aa1b929412a8aa9cf2978d9634c0e62065848bab 100644
--- a/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_avatar_list_item.xml
@@ -129,6 +129,7 @@
      left_pad="3"
      right="-53"
      name="info_btn"
+     tool_tip="More info"
      tab_stop="false"
      top_delta="0"
      width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
index 7c67fd7f835c950dd13eea2e79c5c7d32dafd3c9..53d0252215e0b485b07749669523ee648064bd7b 100644
--- a/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
+++ b/indra/newview/skins/default/xui/en/panel_block_list_sidetray.xml
@@ -4,88 +4,99 @@
  follows="left|top|right|bottom"
  height="305"
  layout="topleft"
+ left="0"
  name="block_list_panel"
  help_topic="blocked_list"
  min_height="350"
  min_width="240"
- width="280">
-        <button
-     follows="top|left"
-     height="24"
-     image_hover_unselected="BackButton_Over"
-     image_pressed="BackButton_Press"
-     image_unselected="BackButton_Off"
-     layout="topleft"
-     name="back"
-     left="4"
-     tab_stop="false"
-     top="1"
-     width="30"/>
-    <text
-     follows="top|left|right"
-     font="SansSerifLargeBold"
-     height="20"
-     layout="topleft"
-     left_pad="10"
-     name="title_text"
-     text_color="White"
-     top="5"
-     width="250">
-        Block List
-     </text>
-    <scroll_list
+ width="323">
+     <panel
+      follows="left|top|right"
+      height="27"
+      label="bottom_panel"
+      layout="topleft"
+      left="0"
+      name="blocked_buttons_panel"
+      right="-1"
+      top="0">
+         <filter_editor
+          follows="left|top|right"
+          height="23"
+          layout="topleft"
+          left="6"
+          label="Filter"
+          max_length_chars="300"
+          name="blocked_filter_input"
+          text_color="Black"
+          text_pad_left="10"
+          top="4"
+          width="177" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="OptionsMenu_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="8"
+          menu_filename="menu_people_blocked_gear.xml"
+          menu_position="bottomleft"
+          name="blocked_gear_btn"
+          tool_tip="Actions on selected person or object"
+          top="3"
+          width="31" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="Conv_toolbar_sort"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          menu_filename="menu_people_blocked_view.xml"
+          menu_position="bottomleft"
+          name="view_btn"
+          tool_tip="Sort options"
+          top_delta="0"
+          width="31" />
+         <menu_button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="AddItem_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          layout="topleft"
+          left_pad="2"
+          menu_filename="menu_people_blocked_plus.xml"
+          menu_position="bottomleft"
+          name="plus_btn"
+          tool_tip="Pick a Resident or an object to block"
+          top_delta="0"
+          width="31"/>
+          <button
+          follows="right"
+          height="25"
+          image_hover_unselected="Toolbar_Middle_Over"
+          image_overlay="TrashItem_Off"
+          image_selected="Toolbar_Middle_Selected"
+          image_unselected="Toolbar_Middle_Off"
+          left_pad="2"
+          layout="topleft"
+          name="unblock_btn"
+          tool_tip="Remove Resident or object from blocked list"
+          top_delta="0"
+          width="31"/>
+     </panel>
+    <block_list
      follows="all"
-     height="190"
+     height="273"
      layout="topleft"
-     left="5"
+     left="3"
      name="blocked"
      tool_tip="List of currently blocked Residents"
-     top="30"
-     width="270">
-        <scroll_list.columns
-         name="item_name" />
-        <scroll_list.columns
-         name="item_type"
-         width="96" />
-    </scroll_list>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Block person"
-     layout="topleft"
-     left_delta="0"
-     name="Block resident..."
-     tool_tip="Pick a Resident to block"
-     top_pad="4"
-     width="210">
-        <button.commit_callback
-         function="Block.ClickPick" />
-    </button>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Block object by name"
-     layout="topleft"
-     left_delta="0"
-     name="Block object by name..."
-     tool_tip="Pick an object to block by name"
-     top_pad="4"
-     width="210" >
-        <button.commit_callback
-         function="Block.ClickBlockByName" />
-    </button>
-    <button
-     enabled="false"
-     follows="left|bottom"
-     height="23"
-     label="Unblock"
-     layout="topleft"
-     left_delta="0"
-     name="Unblock"
-     tool_tip="Remove Resident or object from blocked list"
-     top_pad="4"
-     width="210" >
-        <button.commit_callback
-         function="Block.ClickRemove" />
-    </button>
+     top="31"
+  	 right="-1"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..752321b949ff349c3aa492cbd10efadc9fc40a20
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_blocked_list_item.xml
@@ -0,0 +1,71 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="blocked_list_item"
+ top="0"
+ width="380">
+    <icon
+     height="24"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     follows="top|right|left"
+     height="24"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <avatar_icon
+     default_icon_name="Generic_Person"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <group_icon
+     default_icon_name="Generic_Group"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     follows="top|left"
+     height="16"
+     image_name="Inv_Object"
+     layout="topleft"
+     left="7"
+     name="object_icon"
+     top="4"
+     visible="false"
+     width="16" />
+    <text
+     follows="left|right"
+     font="SansSerifSmall"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="item_name"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="180" />
+</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
index f4722b05d69a81ffc6289ee43f87e4a3b6fd7e96..27a27473d81985399b0e49cc2da154428b95c86a 100644
--- a/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
+++ b/indra/newview/skins/default/xui/en/panel_bottomtray_lite.xml
@@ -46,7 +46,7 @@
             follows="left|right"
             top="4"
             width="310"
-            name="chat_bar"
+            name="nearby_chat"
             mouse_opaque="false"/>
         </layout_panel>
         <layout_panel
diff --git a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
index ff0146490b91bbe40e1a7a57441ee2ff54c36ee8..fc321fdd2355026ce7d936e8605af3a762ed3460 100644
--- a/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_chiclet_bar.xml
@@ -80,54 +80,6 @@
     <layout_panel auto_resize="false"
                       width="4"
                       min_width="4"/>
-    <layout_panel
-         auto_resize="false"
-         follows="right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         min_width="37"
-         name="im_well_panel"
-         top="0"
-         width="37">
-      <chiclet_im_well
-             follows="right"
-             height="28"
-             layout="topleft"
-             left="0"
-             max_displayed_count="99"
-             name="im_well"
-             top="0"
-             width="35">
-        <!--
-Emulate 4 states of button by background images, see details in EXT-3147. The same should be for notification_well button
-xml attribute           Description
-image_unselected        "Unlit" - there are no new messages
-image_selected          "Unlit" + "Selected" - there are no new messages and the Well is open
-image_pressed           "Lit" - there are new messages
-image_pressed_selected  "Lit" + "Selected" - there are new messages and the Well is open
-             -->
-        <button
-                 auto_resize="false"
-                 follows="right"
-                 halign="center"
-                 height="23"
-                 image_overlay="Unread_IM"
-                 image_overlay_alignment="center"
-                 image_pressed="WellButton_Lit"
-                 image_pressed_selected="WellButton_Lit_Selected"
-                 image_selected="PushButton_Press"
-                 label_color="Black"
-                 left="0"
-                 name="Unread IM messages"
-                 tool_tip="Conversations"
-                 width="34">
-          <init_callback
-                     function="Button.SetDockableFloaterToggle"
-                     parameter="im_well_window" />
-        </button>
-      </chiclet_im_well>
-    </layout_panel>
     <layout_panel
          auto_resize="false"
          follows="right"
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a054e71e34710eaa61d99e731fcf50397606a715
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_list_item.xml
@@ -0,0 +1,98 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="left|top|right"
+ height="24"
+ layout="topleft"
+ name="conversation_list_item"
+ mouse_opaque="false"
+ width="120">
+    <avatar_icon
+     follows="top|left"
+     height="20"
+     default_icon_name="Generic_Person"
+     layout="topleft"
+     left="5"
+     top="2"
+     visible="false"
+     width="20" />
+    <group_icon
+     follows="top|left"
+     height="20"
+     default_icon_name="Generic_Group"
+     layout="topleft"
+     left="5"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     follows="top|left"
+     height="20"
+     image_name="Nearby_chat_icon"
+     layout="topleft"
+     left="5"
+     name="nearby_chat_icon"
+     top="2"
+     visible="false"
+     width="20"/>
+    <layout_stack
+     animate="false"
+     follows="all"
+     height="24"
+     layout="topleft"
+     left="30"
+     mouse_opaque="false"
+     name="conversation_item_stack"
+     orientation="horizontal"
+     top="0"
+     width="90">
+        <layout_panel
+         auto_resize="false"
+         user_resize="false"        
+         height="24"
+         mouse_opaque="false"
+         name="call_icon_panel"
+         visible="false"
+         width="20">
+            <icon
+             height="18"
+             follows="top|right|left"
+             image_name="Conv_toolbar_open_call"
+             layout="topleft"
+             left="0"
+             name="selected_icon"
+             top="3"
+             width="18" />
+        </layout_panel>
+        <layout_panel
+         auto_resize="true"
+         user_resize="false"    
+         height="24"
+         mouse_opaque="false"
+         name="conversation_title_panel"
+         width="70">
+		    <text
+		     follows="left|top|right"
+		     font="SansSerifSmall"
+		     height="15"
+		     layout="topleft"
+		     left="5"
+		     name="conversation_title"
+		     parse_urls="false"
+		     top="6"
+		     use_ellipses="true"
+		     value="(loading)"
+		     width="35" />
+		    <output_monitor
+		     auto_update="true"
+		     follows="top|right"
+		     draw_border="false"
+		     height="16"
+		     layout="topleft"
+		     left_pad="5"
+ 		     mouse_opaque="true"
+ 		     name="speaking_indicator"
+ 		     visible="false"
+ 		     width="20" />
+        </layout_panel>
+    </layout_stack>
+</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
new file mode 100644
index 0000000000000000000000000000000000000000..78d4c174d2cf7f01140c0cf82c97e9af34bba991
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/panel_conversation_log_list_item.xml
@@ -0,0 +1,107 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<panel
+ follows="top|right|left"
+ height="23"
+ layout="topleft"
+ left="0"
+ name="conversation_log_list_item"
+ top="0"
+ width="380">
+    <icon
+     height="24"
+     follows="top|right|left"
+     image_name="ListItem_Select"
+     layout="topleft"
+     left="0"
+     name="selected_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     follows="top|right|left"
+     height="24"
+     image_name="ListItem_Over"
+     layout="topleft"
+     left="0"
+     name="hovered_icon"
+     top="0"
+     visible="false"
+     width="380" />
+    <icon
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     image_name="Conv_toolbar_open_call"
+     mouse_opaque="true"
+     name="voice_session_icon"
+     tool_tip="Included a voice conversation"
+     top="2"
+     visible="false"
+     width="20" />
+    <icon
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left="5"
+     image_name="Conv_log_inbox"
+     mouse_opaque="false"
+     name="unread_ims_icon"
+     tool_tip="Messages arrived while you were logged out"
+     top="2"
+     visible="false"
+     width="20" />
+    <avatar_icon
+     default_icon_name="Generic_Person"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     left_pad="5"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <group_icon
+     default_icon_name="Generic_Group"
+     follows="top|left"
+     height="20"
+     layout="topleft"
+     mouse_opaque="true"
+     top="2"
+     visible="false"
+     width="20" />
+    <text
+     follows="left|right"
+     font="SansSerifSmall"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="conversation_name"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="180" />
+    <text
+     follows="right"
+     font="SansSerifSmall"
+     height="15"
+     layout="topleft"
+     left_pad="5"
+     name="date_time"
+     parse_urls="false"
+     top="6"
+     use_ellipses="true"
+     width="110"/>
+    <button
+     name="delete_btn"
+     tool_tip="Remove this entry"
+     layout="topleft"
+     follows="top|right"
+     image_unselected="Conv_toolbar_close"
+     image_selected="Conv_toolbar_close"
+     top="5"
+     left_pad="0"
+     height="14"
+     width="14"
+     tab_stop="false"/>
+</panel>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml b/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
deleted file mode 100644
index ad10e53a4e324cd31132e5c60eab946d38d8bbbe..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_group_control_panel.xml
+++ /dev/null
@@ -1,109 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- follows="all"
- height="238"
- name="panel_im_control_panel"
- width="150">
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="238"
-     layout="topleft"
-     left="5"
-     name="vertical_stack"
-     orientation="vertical"
-     top="0"
-     width="145">
-        <layout_panel
-         auto_resize="true"
-         follows="top|left"
-         height="100"
-         layout="topleft"
-         min_height="0"
-         mouse_opaque="false"
-         width="145"
-         top="0"
-         name="speakers_list_panel">
-            <avatar_list
-             color="DkGray2"
-             follows="all"
-             height="100"
-             ignore_online_status="true"
-             layout="topleft"
-             name="speakers_list"
-             opaque="false"
-             show_info_btn="true"
-             show_profile_btn="false"
-             show_speaking_indicator="false"
-             width="145" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="group_info_btn_panel">
-            <button
-             follows="left|right|bottom"
-             height="23"
-             label="Group Profile"
-             name="group_info_btn"
-             use_ellipses="true"
-             top="5"
-             width="130" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="call_btn_panel">
-            <button
-             follows="all"
-             height="23"
-             label="Call Group"
-             name="call_btn"
-             use_ellipses="true" 
-             width="130" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="23"
-             label="Leave Call"
-             name="end_call_btn"
-             use_ellipses="true" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="28"
-         layout="topleft"
-         min_height="28"
-         width="130"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="all"
-             height="23"
-             label="Open Voice Controls"
-             name="voice_ctrls_btn"
-             use_ellipses="true" />
-        </layout_panel>
-    </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_group_list_item.xml b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
index 12735026fa0108ccad9be967a4e41100257e2b98..cfe3aeb7c98eec298e29f675057c37e45b7b5c98 100644
--- a/indra/newview/skins/default/xui/en/panel_group_list_item.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_list_item.xml
@@ -56,6 +56,7 @@
      left_pad="3"
      right="-31"
      name="info_btn"
+     tool_tip="More info"
      tab_stop="false"
      top_delta="-2"
      width="16" />
diff --git a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml b/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
deleted file mode 100644
index 8fcd6ccbaf27ce0500ff65d966ff599b038e33fb..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/panel_im_control_panel.xml
+++ /dev/null
@@ -1,166 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<panel
- border="false"
- height="300"
- name="panel_im_control_panel"
- width="150">
-    <avatar_icon
-     follows="left|top"
-     height="105"
-     left_delta="20"
-     name="avatar_icon"
-     top="-5"
-     width="114"/>
-    <layout_stack
-     mouse_opaque="false"
-     border_size="0"
-     clip="false"
-     follows="all"
-     height="183"
-     layout="topleft"
-     left="5"
-     name="button_stack"
-     orientation="vertical"
-     top_pad="5"
-     width="145">
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="20"
-         layout="topleft"
-         left="2" 
-         min_height="20"
-         width="140"
-         name="view_profile_btn_panel"
-         top="0" >
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Profile"
-             name="view_profile_btn"
-             top="0"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="add_friend_btn_panel">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Add Friend"
-             name="add_friend_btn"
-             top="5"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="teleport_btn_panel">
-        <button
-             auto_resize="false"
-             follows="left|top|right"
-             height="23"
-             label="Teleport"
-             name="teleport_btn"
-             tool_tip = "Offer to teleport this person"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="share_btn_panel">
-           <button
-             auto_resize="true"
-             follows="left|top|right"
-             height="23"
-             label="Share"
-             name="share_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="pay_btn_panel">
-           <button
-             auto_resize="true"
-             follows="left|top|right"
-             height="23"
-             label="Pay"
-             name="pay_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="call_btn_panel">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Call"
-             name="call_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="end_call_btn_panel"
-         visible="false">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="End Call"
-             name="end_call_btn"
-             width="140" />
-        </layout_panel>
-        <layout_panel
-         auto_resize="false"
-         follows="top|left|right"
-         height="25"
-         layout="topleft"
-         min_height="25"
-         width="140"
-         name="voice_ctrls_btn_panel"
-         visible="false">
-            <button
-             follows="left|top|right"
-             height="23"
-             label="Voice Controls"
-             name="voice_ctrls_btn"
-             width="140" />
-        </layout_panel>
-      <layout_panel
-       mouse_opaque="false"
-       auto_resize="true"
-       follows="top|left"
-       height="0"
-       layout="topleft"
-       min_height="0"
-       width="140"
-       name="spacer"/>
-    </layout_stack>
-</panel>
diff --git a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
index 413e22e444947a07363ecee76dc00e83f82627c0..433a3181cd3d9dc8b817009abf386f428115ad58 100644
--- a/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_inbox_inventory.xml
@@ -2,7 +2,7 @@
 <inbox_inventory_panel
     accepts_drag_and_drop="false"
     name="inventory_inbox"
-    start_folder="Received Items"
+    start_folder.type="inbox"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
     top_pad="0"
diff --git a/indra/newview/skins/default/xui/en/panel_landmarks.xml b/indra/newview/skins/default/xui/en/panel_landmarks.xml
index 2a5933e3e93bbc9f5ebe13b07809b2d47beb17a5..67a09949ceaa59279b661925b6fbd4d3c3e052f7 100644
--- a/indra/newview/skins/default/xui/en/panel_landmarks.xml
+++ b/indra/newview/skins/default/xui/en/panel_landmarks.xml
@@ -35,7 +35,9 @@
              left="0"
              mouse_opaque="true"
              name="favorites_list"
-             start_folder="Favorites"
+             scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
+             start_folder.name="Favorites"
              width="307"/>
         </accordion_tab>
         <accordion_tab
@@ -51,7 +53,9 @@
              left="0"
              mouse_opaque="true"
              name="landmarks_list"
-             start_folder="Landmarks"
+             scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
+             start_folder.name="Landmarks"
              width="307"/>
         </accordion_tab>
         <accordion_tab
@@ -67,7 +71,9 @@
              left="0"
              mouse_opaque="true"
              name="my_inventory_list"
-             start_folder="My Inventory"
+             scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
+             start_folder.name="My Inventory"
              width="307"/>
           </accordion_tab>
           <accordion_tab
@@ -83,7 +89,9 @@
              left="0"
              mouse_opaque="true"
              name="library_list"
-             start_folder="LIBRARY"
+             scroll.hide_scrollbar="true"
+             folder_view.use_ellipses="true"
+             start_folder.name="LIBRARY"
              width="313"/>
         </accordion_tab>
     </accordion>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
index d683116eb8b339321114fc75732a3f7a260d5246..4de56b424e15b1a5d411c5477e7ff5aad9a7325a 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat.xml
@@ -1,20 +1,22 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
 <panel
  follows="all"
- height="300"
+ top="0"
+ bottom_delta="10"
  help_topic="nearby_chat"
  layout="topleft"
  name="nearby_chat"
- width="320">
+ width="242"
+ height="169">
   <layout_stack
    follows="all"
-   height="295"
+   height="164"
    layout="topleft"
    left="0"
    name="stack"
    top="5"
    orientation="vertical"
-   width="320">
+   width="242">
     <layout_panel
      auto_resize="false"
      height="26"
@@ -23,7 +25,7 @@
      name="translate_chat_checkbox_lp"
      top_delta="0"
      visible="true"
-     width="313">
+     width="230">
       <check_box
        top="10"
        control_name="TranslateChat"
@@ -33,15 +35,15 @@
        layout="topleft"
        left="5"
        name="translate_chat_checkbox"
-       width="300" />
+       width="230" />
     </layout_panel>
     <layout_panel
      auto_resize="true"
-     height="277"
+     height="138"
      left_delta="0"
      layout="topleft"
      name="chat_history_lp"
-     width="318">
+     width="242">
       <chat_history
        bg_readonly_color="ChatHistoryBgColor"
        bg_writeable_color="ChatHistoryBgColor"
@@ -49,7 +51,7 @@
        layout="topleft"
        left="5"
        left_widget_pad="0"
-       height="272"
+       height="138"
        name="chat_history"
        parse_highlights="true"
        parse_urls="true"
@@ -57,7 +59,7 @@
        text_color="ChatHistoryTextColor"
        text_readonly_color="ChatHistoryTextColor"
        top="0"
-       width="313" />
+       width="237" />
     </layout_panel>
   </layout_stack>
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
index 6bc9c48729dbb6189dc2f82fed66363668d3c10c..19143cef89835b3c1a0e62e5b400576149f2216e 100644
--- a/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/en/panel_nearby_chat_bar.xml
@@ -5,7 +5,7 @@
  height="25"
  layout="topleft"
  left="0"
- name="chat_bar"
+ name="nearby_chat"
  top="21"
  width="308">
     <line_editor
diff --git a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
index a3d39e55af53a20a6c95ccff9fd9ac8b65d10c8e..c80e5b168a4a5b9ffe236b80341c034ada5ebdfa 100644
--- a/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
+++ b/indra/newview/skins/default/xui/en/panel_outbox_inventory.xml
@@ -1,7 +1,10 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel
+<inventory_panel
     name="inventory_outbox"
-    start_folder="Outbox"
+    start_folder.name="Outbox"
+    show_empty_message="false"
+    show_load_status="false"
+    start_folder.type="outbox"
     follows="all" layout="topleft"
     top="0" left="0" height="165" width="308"
     top_pad="0"
@@ -12,6 +15,18 @@
     bevel_style="none"
     show_item_link_overlays="true"
     tool_tip="Drag and drop items here to prepare them for sale on your storefront"
-    >
-    <scroll reserve_scroll_corner="false" />
-</outbox_inventory_panel>
+    scroll.reserve_scroll_corner="false">
+      <folder folder_arrow_image="Folder_Arrow"
+              folder_indentation="8"
+              item_height="20"
+              item_top_pad="4"
+              selection_image="Rounded_Square"
+              left_pad="5"
+              icon_pad="2"
+              icon_width="16"
+              text_pad="1"
+              text_pad_right="4"
+              arrow_size="12"
+              max_folder_item_overlap="2"/>
+      <item allow_open="false"/>
+</inventory_panel>
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 98c7c49ff4793bbcc92ea1311e0b9bbd9f1cf684..7ce2627be9931c2a59c629c4c4507d21aff5ad8e 100644
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -38,12 +38,6 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      name="no_filtered_friends_msg">
          Didn't find what you're looking for? Try [secondlife:///app/search/people/[SEARCH_TERM] Search].
     </string>
-    <string
-     name="people_filter_label"
-     value="Filter People" />
-    <string
-     name="groups_filter_label"
-     value="Filter Groups" />
      <!--
      *WORKAROUND: for group_list.no_items_msg & group_list.no_filtered_items_msg attributes.
      They are not defined as translatable in VLT. See EXT-5931
@@ -60,21 +54,9 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
 	<string
 	 name="AltMiniMapToolTipMsg"
 	 value="[REGION](Double-click to teleport, shift-drag to pan)"/>
-	<filter_editor
-     follows="left|top|right"
-     height="23"
-     layout="topleft"
-     left="10"
-     label="Filter"
-     max_length_chars="300"
-     name="filter_input"
-     text_color="Black"
-     text_pad_left="10"
-     top="3"
-     width="303" />
     <tab_container
+     bottom="-10"
      follows="all"
-     height="383"
      layout="topleft"
      left="3"
      name="tabs"
@@ -82,31 +64,120 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
      tab_min_width="70"
      tab_height="30"
      tab_position="top"
-     top_pad="10"
+     top="0"
      halign="center"
-     width="319">
-     	<panel
+     right="-5">
+
+<!-- ================================= NEARBY tab =========================== -->
+
+        <panel
          background_opaque="true"
          background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
          label="NEARBY"
          layout="topleft"
          left="0"
          help_topic="people_nearby_tab"
          name="nearby_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
+            <panel
+             follows="left|top|right"
+             height="27"
+             label="bottom_panel"
+             layout="topleft"
+             left="0"
+             name="nearby_buttons_panel"
+             right="-1"
+             top="0">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="6"
+                 label="Filter People"
+                 max_length_chars="300"
+                 name="nearby_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="4"
+                 width="178" />
+                <button
+                 commit_callback.function="People.Gear"
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="7"
+                 name="gear_btn"
+                 tool_tip="Actions on selected person"
+                 top="3"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 menu_filename="menu_people_nearby_view.xml"
+                 menu_position="bottomleft"
+                 name="nearby_view_btn"
+                 tool_tip="View/sort options"
+                 top_delta="0"
+                 width="31" />
+                <button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="add_friend_btn"
+                 tool_tip="Offer friendship to a resident"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.AddFriend" />
+                </button>
+                <dnd_button
+                 enabled="false"
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="nearby_del_btn"
+                 tool_tip="Remove selected person as a friend"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                 </dnd_button>
+            </panel>
          <layout_stack
            clip="false"
            follows="all"
-           height="355"
+           height="410"
            layout="topleft"
+           left="0"
            mouse_opaque="false"
            orientation="vertical"
-           width="313">
+           right="-1"
+           top_pad="0">
            <layout_panel
              height="142"
              layout="topleft"
@@ -123,16 +194,16 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                left="3"
                mouse_opaque="false"
                name="Net Map"
-               top="4"
-               width="305"/>
+               right="-1"
+               top="4" />
            </layout_panel>
            <layout_panel
              height="213"
              layout="topleft"
              min_dim="100"
              mouse_opaque="false"
-             user_resize="true"
-             width="313">
+             right="-1"
+             user_resize="true">
              <avatar_list
                allow_select="true"
                follows="all"
@@ -143,84 +214,122 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                keep_one_selected="false"
                multi_select="true"
                name="avatar_list"
-               top="2"
-               width="306" />
+               right="-1"
+               top="2" />
            </layout_panel>
          </layout_stack>
-         <panel
-             background_visible="true"
-             follows="left|right|bottom"
-             height="27"
-             label="bottom_panel"
-             layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-             <menu_button
-             follows="bottom|left"
-             height="25"
-             image_hover_unselected="Toolbar_Left_Over"
-             image_overlay="OptionsMenu_Off"
-             image_selected="Toolbar_Left_Selected"
-             image_unselected="Toolbar_Left_Off"
-             layout="topleft"
-             left="0"
-             name="nearby_view_sort_btn"
-             tool_tip="Options"
-             top="1"
-             width="31" />
-             <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-             	 image_overlay="AddItem_Off"
-                 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="add_friend_btn"
-                 tool_tip="Add selected Resident to your friends List"
-                 width="31">
-               <commit_callback
-                  function="People.addFriend" />
-             </button>
-             <icon
-             follows="bottom|left|right"
-             height="25"
-             image_name="Toolbar_Right_Off"
-             layout="topleft"
-             left_pad="1"
-             name="dummy_icon"
-             width="243"
-             />
-            </panel>
         </panel>
+
+<!-- ================================= FRIENDS tab ========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
-         label="MY FRIENDS"
+         label="FRIENDS"
          layout="topleft"
          left="0"
          help_topic="people_friends_tab"
          name="friends_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
+            <panel
+             follows="left|top|right"
+             height="27"
+             label="bottom_panel"
+             layout="topleft"
+             left="0"
+             name="friends_buttons_panel"
+             right="-1"
+             top="0">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="6"
+                 label="Filter People"
+                 max_length_chars="300"
+                 name="friends_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="4"
+                 width="177" />
+                <button
+                 commit_callback.function="People.Gear"
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="8"
+                 name="gear_btn"
+                 tool_tip="Actions on selected person"
+                 top="3"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 menu_filename="menu_people_friends_view.xml"
+                 menu_position="bottomleft"
+                 name="friends_view_btn"
+                 tool_tip="View/sort options"
+                 top_delta="0"
+                 width="31" />
+                <button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="AddItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 name="friends_add_btn"
+                 tool_tip="Offer friendship to a resident"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.AddFriendWizard" />
+                </button>
+                <dnd_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="friends_del_btn"
+                 tool_tip="Remove selected person as a friend"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                </dnd_button>
+            </panel>
             <accordion
        		 background_visible="true"
        		 bg_alpha_color="DkGray2"
        		 bg_opaque_color="DkGray2"
              follows="all"
-             height="356"
+             height="408"
              layout="topleft"
              left="3"
              name="friends_accordion"
-             top="0"
-             width="307">
+             right="-2"
+             top_pad="2">
                 <accordion_tab
                  layout="topleft"
                  height="172"
@@ -257,247 +366,133 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                          width="307" />
                 </accordion_tab>
             </accordion>
-            <panel
-             background_visible="true"
-             follows="left|right|bottom"
-             height="27"
-             label="bottom_panel"
-             layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-             
-             	  <layout_stack
-				   animate="false"
-				   border_size="0"
-				   follows="left|right|bottom"
-				   height="25"
-				   layout="topleft"
-				   orientation="horizontal"
-				   top_pad="1"
-				   left="0"
-				   name="bottom_panel"
-				   width="308">
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="options_gear_btn_panel"
-				       width="32">
-				          <menu_button
-				           follows="bottom|left"
-				           tool_tip="Show additional options"
-				           height="25"
-				           image_hover_unselected="Toolbar_Left_Over"
-				           image_overlay="OptionsMenu_Off"
-				           image_selected="Toolbar_Left_Selected"
-				           image_unselected="Toolbar_Left_Off"
-				           layout="topleft"
-				           left="0"
-				           name="friends_viewsort_btn"
-				           top="0"
-				           width="31" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="add_btn_panel"
-				       width="32">
-				          <button
-				           follows="bottom|left"
-				           height="25"
-				           image_hover_unselected="Toolbar_Middle_Over"
-				           image_overlay="AddItem_Off"
-				           image_selected="Toolbar_Middle_Selected"
-				           image_unselected="Toolbar_Middle_Off"
-				           layout="topleft"
-				           left="0"
-				           name="add_btn"
-				           tool_tip="Offer friendship to a Resident"
-				           top="0"
-				           width="31" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="true"
-				       height="25"
-				       layout="topleft"
-				       name="dummy_panel"
-				       width="210">
-				          <icon
-				           follows="bottom|left|right"
-				           height="25"
-				           image_name="Toolbar_Middle_Off"
-				           layout="topleft"
-				           left="0"
-				           top="0"
-				           name="dummy_icon"
-				           width="210" />
-				      </layout_panel>
-				      <layout_panel
-				       auto_resize="false"
-				       height="25"
-				       layout="topleft"
-				       name="trash_btn_panel"
-				       width="31">
-				          <dnd_button
-				           follows="bottom|left"
-				           height="25"
-				           image_hover_unselected="Toolbar_Right_Over"
-				           image_overlay="TrashItem_Off"
-				           image_selected="Toolbar_Right_Selected"
-				           image_unselected="Toolbar_Right_Off"
-				           left="0"
-				           layout="topleft"
-				           name="del_btn"
-				           tool_tip="Remove selected person from your Friends list"
-				           top="0"
-				           width="31"/>
-				      </layout_panel>
-				  </layout_stack><!--
-             
-               <button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               left="0"
-               name="friends_viewsort_btn"
-               top="1"
-               width="31" />
-                <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Middle_Over"
-             	 image_overlay="AddItem_Off"
-             	 image_selected="Toolbar_Middle_Selected"
-             	 image_unselected="Toolbar_Middle_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="add_btn"
-                 tool_tip="Offer friendship to a Resident"
-                 width="31" />
-                <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Middle_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="209"
-             />
-                <button
-                 follows="bottom|left"
-                 height="25"
-                 image_hover_unselected="Toolbar_Right_Over"
-                 image_overlay="TrashItem_Off"
-                 image_selected="Toolbar_Right_Selected"
-                 image_unselected="Toolbar_Right_Off"
-                 layout="topleft"
-                 left_pad="1"
-                 name="del_btn"
-                 tool_tip="Remove selected person from your Friends list"
-                 width="31" />
-            --></panel>
             <text
              follows="all"
              height="450"
              left="13"
              name="no_friends_help_text"
-             top="10"
-             width="293"
+             right="-13"
+             top="37"
              wrap="true" />
         </panel>
+
+<!-- ================================= GROUPS tab =========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
          bg_alpha_color="DkGray"
          bg_opaque_color="DkGray"
+         bottom="-1"
          follows="all"
-         height="383"
-         label="MY GROUPS"
+         label="GROUPS"
          layout="topleft"
          left="0"
          help_topic="people_groups_tab"
          name="groups_panel"
-         top="0"
-         width="313">
+         right="-1"
+         top="0">
     <!--
      *NOTE: no_groups_msg & group_list attributes are not defined as translatable in VLT. See EXT-5931
      Values are set from appropriate strings at the top of file via LLPeoplePanel::postBuild()
     -->
-            <group_list
-             allow_select="true" 
-             follows="all"
-             height="356"
-             layout="topleft"
-             left="3"
-             name="group_list"
-             top="0"
-             width="307" />
             <panel
-             background_visible="true"
-             follows="left|right|bottom"
+             follows="left|top|right"
              height="27"
              label="bottom_panel"
              layout="topleft"
              left="0"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-               <menu_button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               left="3"
-               name="groups_viewsort_btn"
-               top="1"
-               width="31" />
-                <button
-                 follows="bottom|left"
+             name="groups_buttons_panel"
+             right="-1"
+             top="0">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="6"
+                 label="Filter Groups"
+                 max_length_chars="300"
+                 name="groups_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="4"
+                 width="177" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="8"
+                 name="groups_gear_btn"
+                 tool_tip="Actions on selected group"
+                 top="3"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 menu_filename="menu_people_groups_view.xml"
+                 menu_position="bottomleft"
+                 name="groups_view_btn"
+                 tool_tip="View/sort options"
+                 top_delta="0"
+                 width="31" />
+                <menu_button
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="AddItem_Off"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="1"
+                 left_pad="2"
+                 menu_filename="menu_group_plus.xml"
+                 menu_position="bottomleft"
                  name="plus_btn"
                  tool_tip="Join group/Create new group"
-                 width="31" />
-                <button
-                 follows="bottom|left"
+                 top_delta="0"
+                 width="31">
+                    <validate_callback
+                     function="People.Group.Plus.Validate" />
+                </menu_button>
+                <dnd_button
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
-                 image_overlay="Activate_Checkmark"
+                 image_overlay="TrashItem_Off"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
                  layout="topleft"
-                 left_pad="1"
-                 name="activate_btn"
-                 tool_tip="Activate selected group"
-                 width="31" />
-                 <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Right_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="212"
-             />
+                 name="minus_btn"
+                 tool_tip="Leave selected group"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.Group.Minus" />
+                </dnd_button>
             </panel>
+            <group_list
+             allow_select="true" 
+             follows="all"
+             height="406"
+             layout="topleft"
+             left="3"
+             name="group_list"
+             right="-2"
+             top_pad="4" />
         </panel>
+
+<!-- ================================= RECENT tab =========================== -->
+
         <panel
          background_opaque="true"
        background_visible="true"
@@ -510,265 +505,133 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
          left="0"
          help_topic="people_recent_tab"
          name="recent_panel"
-         top="0"
-         width="313">
-            <avatar_list
-             allow_select="true"
-             follows="all"
-             height="356"
-             layout="topleft"
-             left="3"
-             multi_select="true"
-             name="avatar_list"
-             show_last_interaction_time="true"
-             top="0"
-             width="307" />
+         right="-1"
+         top="0">
             <panel
-             background_visible="true"
-             follows="left|right|bottom"
+             follows="left|top|right"
              height="27"
              label="bottom_panel"
              layout="topleft"
-             left="3"
-             name="bottom_panel"
-             top_pad="0"
-             width="313">
-               <menu_button
-               follows="bottom|left"
-               tool_tip="Options"
-               height="25"
-               image_hover_unselected="Toolbar_Left_Over"
-               image_overlay="OptionsMenu_Off"
-               image_selected="Toolbar_Left_Selected"
-               image_unselected="Toolbar_Left_Off"
-               layout="topleft"
-               name="recent_viewsort_btn"
-               top="1"
-               width="31" />
-              <button
-                 follows="bottom|left"
+             left="0"
+             name="recent_buttons_panel"
+             right="-1"
+             top="0">
+                <filter_editor
+                 follows="left|top|right"
+                 height="23"
+                 layout="topleft"
+                 left="6"
+                 label="Filter People"
+                 max_length_chars="300"
+                 name="recent_filter_input"
+                 text_color="Black"
+                 text_pad_left="10"
+                 top="4"
+                 width="177" />
+                <button
+                 commit_callback.function="People.Gear"
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="OptionsMenu_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="8"
+                 name="gear_btn"
+                 tool_tip="Actions on selected person"
+                 top="3"
+                 width="31" />
+                <menu_button
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="Conv_toolbar_sort"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 layout="topleft"
+                 left_pad="2"
+                 menu_filename="menu_people_recent_view.xml"
+                 menu_position="bottomleft"
+                 name="recent_view_btn"
+                 tool_tip="View/sort options"
+                 top_delta="0"
+                 width="31" />
+                <button
+                 follows="right"
                  height="25"
                  image_hover_unselected="Toolbar_Middle_Over"
                  image_overlay="AddItem_Off"
                  image_selected="Toolbar_Middle_Selected"
                  image_unselected="Toolbar_Middle_Off"
                  layout="topleft"
-                 left_pad="1"
+                 left_pad="2"
                  name="add_friend_btn"
-                 tool_tip="Add selected Resident to your friends List"
+                 tool_tip="Offer friendship to a resident"
+                 top_delta="0"
                  width="31">
-                <commit_callback
-                   function="People.addFriend" />
-              </button>
-              <icon
-             	 follows="bottom|left|right"
-             	 height="25"
-             	 image_name="Toolbar_Right_Off"
-             	 layout="topleft"
-             	 left_pad="1"
-             	 name="dummy_icon"
-             	 width="244"
-             />
+                    <commit_callback
+                     function="People.AddFriend" />
+                </button>
+                <dnd_button
+                 enabled="false"
+                 follows="right"
+                 height="25"
+                 image_hover_unselected="Toolbar_Middle_Over"
+                 image_overlay="TrashItem_Off"
+                 image_selected="Toolbar_Middle_Selected"
+                 image_unselected="Toolbar_Middle_Off"
+                 left_pad="2"
+                 layout="topleft"
+                 name="recent_del_btn"
+                 tool_tip="Remove selected person as a friend"
+                 top_delta="0"
+                 width="31">
+                    <commit_callback
+                     function="People.DelFriend" />
+                 </dnd_button>
             </panel>
+            <avatar_list
+             allow_select="true"
+             follows="all"
+             height="351"
+             layout="topleft"
+             left="3"
+             multi_select="true"
+             name="avatar_list"
+             show_last_interaction_time="true"
+             right="-2"
+             top_pad="4" />
         </panel>
-    </tab_container>
-    <panel
-     follows="bottom|left|right"
-     height="23"
-     layout="topleft"
-     left="8"
-     top_pad="4"
-     name="button_bar"
-     width="313">
 
-<!--********************************Profile; IM; Call, Share, Teleport********************************--> 	
-     	<layout_stack
-     	follows="bottom|left|right"
-		height="23"
-		layout="topleft"
-		name="bottom_bar_ls"
-		left="0"
-		orientation="horizontal"
-		top_pad="0"
-		width="313">
+<!-- ================================= BLOCKED tab ========================== -->
 
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left="0"
-			name="view_profile_btn_lp"
-		    auto_resize="true"
-			width="68">
-				<button
-		         follows="bottom|left|right"
-		         height="23"
-		         label="Profile"
-		         layout="topleft"
-		         left="1"
-		         name="view_profile_btn"
-		         tool_tip="Show picture, groups, and other Residents information"
-		         top="0"
-		         width="67" />	
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="im_btn_lp"
-		    auto_resize="true"
-			width="41">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="IM"
-		         layout="topleft"
-		         name="im_btn"
-		         tool_tip="Open instant message session"
-		         top="0"
-		         width="40" />			
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="call_btn_lp"
-		    auto_resize="true"
-			width="52">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Call"
-		         layout="topleft"
-		         name="call_btn"
-		         tool_tip="Call this Resident"
-		         top="0"
-		         width="51" />		
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="share_btn_lp"
-		    auto_resize="true"
-			width="66">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Share"
-		         layout="topleft"
-		         name="share_btn"
-		         tool_tip="Share an inventory item"
-		         top="0"
-		         width="65" />	
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			name="teleport_btn_lp"
-		    auto_resize="true"
-			width="77">
-				<button
-		         follows="bottom|left|right"
-		         left="1"
-		         height="23"
-		         label="Teleport"
-		         layout="topleft"
-		         name="teleport_btn"
-		         tool_tip="Offer teleport"
-		         top="0"
-		         width="76" />		
-			</layout_panel>
-		</layout_stack>
-		
-<!--********************************Group Profile; Group Chat; Group Call buttons************************-->			
-		<layout_stack
-     	follows="bottom|left|right"
-		height="23"
-		layout="topleft"
-		mouse_opaque="false"
-		name="bottom_bar_ls1"
-		left="0"
-		orientation="horizontal"
-		top="0"
-		width="313">	
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left="0"			
-			mouse_opaque="false"
-			name="group_info_btn_lp"
-		    auto_resize="true"
-			width="108">
-				<button
-		        follows="bottom|left|right"
-		        left="1"
-		        height="23"
-		        label="Group Profile"
-		        layout="topleft"
-				mouse_opaque="false"
-		        name="group_info_btn"
-		        tool_tip="Show group information"
-		        top="0"
-		        width="107" />		
-			</layout_panel>
-			
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			mouse_opaque="false"
-			name="chat_btn_lp"
-		    auto_resize="true"
-			width="101">
-				<button
-		        follows="bottom|left|right"
-		        left="1"
-		        height="23"
-		        label="Group Chat"
-		        layout="topleft"
-				mouse_opaque="false"
-		        name="chat_btn"
-		        tool_tip="Open chat session"
-		        top="0"
-		        width="100" />			
-			</layout_panel>
-		
-			<layout_panel
-			follows="bottom|left|right"
-			height="23"
-			layout="bottomleft"
-			left_pad="3"
-			mouse_opaque="false"
-			name="group_call_btn_lp"
-		    auto_resize="true"
-			width="96">
-				<button
-				follows="bottom|left|right"
-				left="1"
-				height="23"
-         		label="Group Call"
-         		layout="topleft"
-				mouse_opaque="false"
-         		name="group_call_btn"
-         		tool_tip="Call this group"
-		        top="0"
-         		width="95" />			
-			</layout_panel>		
-		</layout_stack>
-    </panel>
+        <panel
+         background_opaque="true"
+         background_visible="true"
+         bg_alpha_color="DkGray"
+         bg_opaque_color="DkGray"
+         follows="all"
+         height="383"
+         label="BLOCKED"
+         layout="topleft"
+         left="0"
+         help_topic="people_blocked_tab"
+         name="blocked_panel"
+         right="-1"
+         top="0">
+          <panel
+           class="panel_block_list_sidetray"
+           height="383"
+           name="panel_block_list_sidetray"
+           filename="panel_block_list_sidetray.xml"
+           follows="all"
+           label="Blocked Residents &amp; Objects"
+           layout="topleft"
+           left="0"
+           font="SansSerifBold"
+           top="0"
+           right="-1" />
+        </panel>
+    </tab_container>
 </panel>
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 27193a984f0087e81099223de5f4736f8812e43a..bd096ebb885c1b7055c28769a7c7dff28d644718 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_chat.xml
@@ -1,242 +1,493 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Text Chat"
- layout="topleft"
- left="102"
- name="chat"
- top="1"
- width="517">
-  <text
-   follows="left|top"
-   layout="topleft"
-   left="30"
-   height="12"
-   name="font_size"
-   width="120"
-   top="10">
-    Font size:
-  </text>
-  <radio_group
-     height="30"
-     layout="topleft"
-     left="40"
-	 control_name="ChatFontSize"
-     name="chat_font_size"
-     top_pad="0"
-     width="440">
-        <radio_item
-         height="16"
-         label="Small"
-         layout="topleft"
-         left="0"
-         name="radio"
-         value="0"
-         top="10"
-         width="125" />
-        <radio_item
-         height="16"
-         label="Medium"
-         layout="topleft"
-         left_delta="145"
-         name="radio2"
-         value="1"
-         top_delta="0"
-         width="125" />
-        <radio_item
-         height="16"
-         label="Large"
-         layout="topleft"
-         left_delta="170"
-         name="radio3"
-         value="2"
-         top_delta="0"
-         width="125" />
-    </radio_group>
-    
+    border="true"
+    has_border="true"
+    height="408"
+    label="Text Chat"
+    layout="topleft"
+    left="102"
+    name="chat"
+    top="1"
+    width="517">
+
+  <panel
+      border="false"
+      height="60"
+      layout="topleft"
+      top="10"
+      left="13"
+      width="517">
+
     <check_box
-     control_name="PlayTypingAnim"
-     height="16"
-     initial_value="true"
-     label="Play typing animation when chatting"
-     layout="topleft"
-     left="30"
-     name="play_typing_animation"
-     top_pad="10"
-     width="400" />
+        control_name="PlayTypingAnim"
+        height="16"
+        initial_value="true"
+        label="Play typing animation when chatting"
+        layout="topleft"
+        top="0"
+        name="play_typing_animation"
+        width="330">
+    </check_box>
+
     <check_box
-     enabled="false"
-     height="16"
-     label="Email me IMs when I'm offline"
-     layout="topleft"
-     left_delta="0"
-     name="send_im_to_email"
-     top_pad="5"
-     width="400" />
+        enabled="false"
+        height="16"
+        label="Email me IMs when I'm offline"
+        layout="topleft"
+        name="send_im_to_email"
+        top_pad="6"
+        width="330">
+    </check_box>
+
     <check_box
-     enabled="false"
-     height="16"
-     label="Enable plain text IM and chat history"
-     layout="topleft"
-     left_delta="0"
-     name="plain_text_chat_history"
-     top_pad="5"
-     width="400" />
+        control_name="VoiceCallsFriendsOnly"
+        height="16"
+        label="Only friends and groups can call or IM me"
+        layout="topleft"
+        name="voice_call_friends_only_check"
+        top_pad="6"
+        width="350">     
+    </check_box>
+
+    <text
+        layout="topleft"
+        left="345"
+        height="12"
+        name="font_size"
+        width="120"
+        top="0">
+      Font size:
+    </text>
+
+    <combo_box
+        control_name="ChatFontSize"
+        height="23"
+        layout="topleft"
+        left="341"
+        name="chat_font_size"
+        top_pad="5"
+        width="100">
+      <item
+          label="Small"
+          name="Small"
+          value="0"/>
+      <item
+          label="Medium"
+          name="Medium"
+          value="1"/>
+      <item
+          label="Large"
+          name="Large"
+          value="2"/>  
+    </combo_box>
+
     <check_box
-     control_name="UseChatBubbles"
-     follows="left|top"
-     height="16"
-     label="Bubble Chat"
-     layout="topleft"
-     left_delta="0"
-     top_pad="5"
-     name="bubble_text_chat"
-     width="150" />     
+        control_name="UseChatBubbles"
+        height="16"
+        label="Bubble Chat"
+        layout="topleft"
+        top_pad="4"
+        name="bubble_text_chat"
+        width="330">
+    </check_box>
+      
+  </panel>
+
+  <panel
+      border="false"
+      height="165"
+      layout="topleft"
+      left="13"
+      width="517">
+
     <text
-     name="show_ims_in_label"
-     follows="left|top"
-     layout="topleft"
-     left="30"
-     height="20"
-     width="170"
-     top_pad="15">
-     Show IMs in:
+        layout="topleft"
+        height="12"
+        name="notifications"
+        left="0"
+        width="120">
+      Notifications
     </text>
     <text
-     name="requires_restart_label"
-     follows="left|top"
-     layout="topleft"
-     top_delta="0" 
-     left="170" 
-  	 height="20"
-	 width="130"
-     text_color="White_25">
-      (requires restart)
-      </text>
-    <radio_group
-     follows="left|top"
-     height="30"
-     left="40"
-     control_name="ChatWindow"
-     name="chat_window"
-     top_pad="0"
-     tool_tip="Show your Instant Messages in separate floaters, or in one floater with many tabs (Requires restart)"
-     width="150">
-     <radio_item
-      height="16"
-      label="Separate Windows"
-      layout="topleft"
-      left="0"
-      name="radio"
-      value="0"
-      top="0"
-      width="150" />
-     <radio_item
-      height="16"
-      label="Tabs"
+        layout="topleft"
+        height="12"
+        name="friend_ims"
+        width="145"
+        left="0"
+        top_pad="13">
+      Friend IMs:
+    </text>
+    <combo_box
+        control_name="NotificationFriendIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="FriendIMOptions"
+        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="None"
+          name="None"
+          value="none"/>
+    </combo_box>
+    <text
+        layout="topleft"
+        height="12"
+        name="non_friend_ims"
+        width="145"
+        left="0"
+        top_pad="9">
+      Non-friend IMs:
+    </text>
+    <combo_box
+        control_name="NotificationNonFriendIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="NonFriendIMOptions"
+        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="None"
+          name="None"
+          value="none"/>
+    </combo_box>
+    <text
+        layout="topleft"
+        left="0"
+        height="13"
+        name="conference_ims"
+        width="145"
+        top_pad="9">
+      Conference IMs:
+    </text>
+    <combo_box
+        control_name="NotificationConferenceIMOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="ConferenceIMOptions"
+        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="None"
+          name="None"
+          value="none"/>
+    </combo_box>
+    <text
+        layout="topleft"
+        left="0"
+        height="13"
+        name="group_chat"
+        width="145"
+        top_pad="9">
+      Group chat:
+    </text>
+    <combo_box
+        control_name="NotificationGroupChatOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="GroupChatOptions"
+        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="None"
+          name="None"
+          value="none"/>
+    </combo_box>
+    <text
+        layout="topleft"
+        left="0"
+        height="12"
+        name="nearby_chat"
+        width="145"
+        top_pad="9">
+      Nearby chat:
+    </text>
+    <combo_box
+        control_name="NotificationNearbyChatOptions"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        top_delta="-6"
+        name="NearbyChatOptions"
+        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="None"
+          name="None"
+          value="none"/>
+    </combo_box>
+    <text
+        layout="topleft"
+        left="0"
+        height="13"
+        name="notifications_alert"
+        width="500"
+        top_pad="9"
+        visible="true"
+        text_color="DrYellow">
+      To temporarily stop all notifications, use Communicate &gt; Do Not Disturb.
+    </text>
+
+  </panel>
+
+  <panel
+      border="false"
+      height="50"
       layout="topleft"
-      left_delta="0"
-      name="radio2"
-      value="1"
-      top_pad="5"
-      width="150" />
-    </radio_group>
+      left="13"
+      top_pad="10"
+      width="517">
+
     <text
-     name="disable_toast_label"
-     follows="left|top"
-     layout="topleft"
-     top_pad="20" 
-     left="30" 
-     height="10"
-     width="400">
-      Enable incoming chat popups:
-      </text>
+        layout="topleft"
+        left="0"
+        name="play_sound"
+        width="100"
+        top_pad="8"
+        visible="true">
+      Play sound:
+    </text>
+    <check_box
+        control_name="PlaySoundNewConversation"
+        height="16"
+        label="New conversation"
+        layout="topleft"
+        left_pad="15"
+        top_pad="-10"
+        name="new_conversation"
+        width="150" />
     <check_box
-     control_name="EnableGroupChatPopups"
-     name="EnableGroupChatPopups"
-     label="Group Chats" 
-     layout="topleft"
-     top_pad="5" 
-     left_delta="10" 
-     height="20"
-     tool_tip="Check to see popups when a Group Chat message arrives"
-     width="400" />
+        control_name="PlaySoundIncomingVoiceCall"
+        height="16"
+        label="Incoming voice call"
+        layout="topleft"
+        top_pad="6"
+        name="incoming_voice_call"
+        width="150" />
     <check_box
-     control_name="EnableIMChatPopups"
-     name="EnableIMChatPopups"
-     label="IM Chats" 
-     layout="topleft"
-     top_pad="5"
-     height="16"
-     tool_tip="Check to see popups when an instant message arrives"
-     width="400" />
-    <spinner
-     control_name="NearbyToastLifeTime"
-     decimal_digits="0"
-     follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="23"
-     label="Nearby chat toasts life time:"
-     label_width="285"
-     layout="topleft"
-     left="45"
-     max_val="60"
-     min_val="1"
-     name="nearby_toasts_lifetime"
-     top_pad="10"
-     width="325" />
-    <spinner
-     control_name="NearbyToastFadingTime"
-     decimal_digits="0"
-     follows="left|top"
-     height="23"
-     increment="1"
-     initial_value="3"
-     label="Nearby chat toasts fading time:"
-     label_width="285"
-     layout="topleft"
-     left_delta="0"
-     max_val="60"
-     min_val="0"
-     name="nearby_toasts_fadingtime"
-     top_pad="3"
-     width="325" />
+        control_name="PlaySoundTeleportOffer"
+        height="16"
+        label="Teleport offer"
+        layout="topleft"
+        left_pad="35"
+        top_pad="-38"
+        name="teleport_offer"
+        width="150" />
+    <check_box
+        control_name="PlaySoundInventoryOffer"
+        height="16"
+        label="Inventory offer"
+        layout="topleft"
+        top_pad="6"
+        name="inventory_offer"
+        width="150" />
+
+  </panel>
+
+  <view_border
+      bevel_style="none"
+      height="0"
+      layout="topleft"
+      left="13"
+      name="cost_text_border"
+      top_pad="5"
+      width="495"/>
+
+  <panel
+      height="50"
+      layout="topleft"
+      left="13"
+      top_pad="10"
+      width="505">
+
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top="5"
+        width="55">
+        Save:
+    </text>
+
+    <combo_box
+        enabled="false"
+        control_name="KeepConversationLogTranscripts"
+        height="23"
+        layout="topleft"
+        left_pad="5"
+        name="chat_font_size"
+        top="0"
+        width="165">
+        <item
+            label="Log and transcripts"
+            value="2"/>
+        <item
+            label="Log only"
+            value="1"/>
+        <item
+            label="No log or transcripts"
+            value="0"/>
+    </combo_box>
+
+    <button
+        enabled="false"
+        height="23"
+        label="Clear log..."
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="clear_log"
+        width="110">
+        <commit_callback
+            function="Pref.ClearLog" />
+    </button>
+  
+    <button
+        enabled="false"
+        height="23"
+        label="Delete transcripts..."
+        layout="topleft"
+        left_pad="5"
+        top="0"
+        name="delete_transcripts"
+        width="147">
+        <button.commit_callback
+            function="Pref.DeleteTranscripts" />
+    </button>
+  
+    <text
+        layout="topleft"
+        left="0"
+        text_color="White"
+        height="12"
+        top_pad="15"
+        width="55">
+        Location:
+    </text>
+  
+    <line_editor
+        control_name="InstantMessageLogPath"
+        border_style="line"
+        border_thickness="1"
+        font="SansSerif"
+        height="23"
+        layout="topleft"
+        left_pad="55"
+        max_length="4096"
+        name="log_path_string"
+        top_delta="-5"
+        width="185">
+    </line_editor>
+  
+    <button
+        enabled="false"
+        follows="left|top"
+        height="23"
+        label="Browse..."
+        label_selected="Browse"
+        layout="topleft"
+        left_pad="5"
+        name="log_path_button"
+        top_delta="0"
+        width="112">
+      <commit_callback function="Pref.LogPath" />
+    </button>
+
+  </panel>
+  
   <button
-   follows="left|top"
-   height="23"
-   label="Translation..."
-   layout="topleft"
-   left="30"
-   name="ok_btn"
-   top="-50"
-   width="170">
-   <button.commit_callback
-    function="Pref.TranslationSettings" />
+      height="23"
+      label="Translation..."
+      layout="topleft"
+      left="9"
+      name="ok_btn"
+      top="-29"
+      width="170">
+    <commit_callback
+        function="Pref.TranslationSettings" />
   </button>
   <button
-   follows="top|left"
-   height="23"
-   layout="topleft"
-   top_pad="-23"
-   left_pad="5"
-   name="autoreplace_showgui"
-   commit_callback.function="Pref.AutoReplace"
-   label="Auto-Replace..."
-   width="150">
+      height="23"
+      layout="topleft"
+      top_pad="-23"
+      left_pad="5"
+      name="autoreplace_showgui"
+      commit_callback.function="Pref.AutoReplace"
+      label="Auto-Replace..."
+      width="150">
   </button>
   <button
-   follows="top|left"
-   height="23"
-   layout="topleft"
-   top_pad="-23"
-   left_pad="5"
-   name="spellcheck_showgui"
-   commit_callback.function="Pref.SpellChecker"
-   label="Spell Checking..."
-   width="150">
+      height="23"
+      layout="topleft"
+      top_pad="-23"
+      left_pad="5"
+      name="spellcheck_showgui"
+      commit_callback.function="Pref.SpellChecker"
+      label="Spell Checking..."
+      width="150">
   </button>
 
 </panel>
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
index 2b22f0d6e31f8f3626a15e4d54cd9979e2cecd32..9e825fe516866445ba706e1535a2790b77d9684f 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_colors.xml
@@ -362,7 +362,7 @@
    follows="left|top"
    height="16"
    increment="0.01"
-   initial_value="0.8"
+   initial_value="1.0"
    layout="topleft"
    label_width="115"
    label="Active:"
@@ -380,7 +380,7 @@
    follows="left|top"
    height="16"
    increment="0.01"
-   initial_value="0.5"
+   initial_value="0.95"
    layout="topleft"
    label_width="115"
    label="Inactive:"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_general.xml b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
index 24882988b06619646bb5f3e51d3db867f65301d2..ea0f7d8593e39db596955d624a1c47ff99407d1e 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_general.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_general.xml
@@ -409,10 +409,10 @@
      name="text_box3"
      top_pad="3"
      width="240">
-       Busy mode response:
+       Do Not Disturb response:
     </text>
     <text_editor
-     control_name="BusyModeResponse"
+     control_name="DoNotDisturbModeResponse"
       text_readonly_color="LabelDisabledColor"
       bg_writeable_color="LtGray"
       use_ellipses="false"
@@ -421,7 +421,7 @@
      height="29"
      layout="topleft"
      left="30"
-     name="busy_response"
+     name="do_not_disturb_response"
      width="470"
      word_wrap="true">
        log_in_to_change
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
index 587c461bee96ebc9e6c20682973bcd746d6df0c7..78743d26bbe74593b60b4b9d8a70ff174428cc51 100644
--- a/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_privacy.xml
@@ -1,72 +1,69 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
 <panel
- border="true"
- follows="left|top|right|bottom"
- height="408"
- label="Communication"
- layout="topleft"
- left="102"
- name="im"
- top="1"
- width="517">
-    <panel.string
-     name="log_in_to_change">
-        log in to change
-    </panel.string>
-    <button
-     follows="left|bottom"
-     height="23"
-     label="Clear History"
-     tool_tip="Clear login image, last location, teleport history, web, and texture cache"
-     layout="topleft"
-     left="30"
-     name="clear_cache"
-     top="10"
-     width="145">
-        <button.commit_callback
-         function="Pref.WebClearCache" />
-    </button>
-    <text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_pad="10"
-     mouse_opaque="false"
-     name="cache_size_label_l"
-     top_delta="3"
-     text_color="LtGray_50"
-     width="300">
-       (Locations, images, web, search history)
-    </text>
-    <check_box
-	 height="16"
-     enabled="false"
-     label="Show me in Search results"
-     layout="topleft"
-     left="30"
-     name="online_searchresults"
-     top_pad="20"
-     width="350" />
-    <check_box
-	 height="16"
-	 enabled="false"
-     label="Only friends and groups know I'm online"
-     layout="topleft"
-     left="30"
-     name="online_visibility"
-     top_pad="30"
-     width="350" />
-    <check_box
-     control_name="VoiceCallsFriendsOnly"
-     height="16"
-     label="Only friends and groups can call or IM me"
-     layout="topleft"
-     left="30"
-     name="voice_call_friends_only_check"
-     top_pad="10"
-     width="350" />
+    border="true"
+    follows="left|top|right|bottom"
+    height="408"
+    label="Communication"
+    layout="topleft"
+    left="102"
+    name="im"
+    top="1"
+    width="517">
+
+  <panel.string
+      name="log_in_to_change">
+    log in to change
+  </panel.string>
+
+  <button
+      follows="left|bottom"
+      height="23"
+      label="Clear History"
+      tool_tip="Clear login image, last location, teleport history, web, and texture cache"
+      layout="topleft"
+      left="30"
+      name="clear_cache"
+      top="10"
+      width="145">
+    <button.commit_callback
+        function="Pref.WebClearCache" />
+  </button>
+
+  <text
+      type="string"
+      length="1"
+      follows="left|top"
+      height="10"
+      layout="topleft"
+      left_pad="10"
+      mouse_opaque="false"
+      name="cache_size_label_l"
+      top_delta="3"
+      text_color="LtGray_50"
+      width="300">
+    (Locations, images, web, search history)
+  </text>
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Show me in Search results"
+      layout="topleft"
+      left="30"
+      name="online_searchresults"
+      top_pad="20"
+      width="350" />
+
+  <check_box
+      height="16"
+      enabled="false"
+      label="Only friends and groups know I'm online"
+      layout="topleft"
+      left="30"
+      name="online_visibility"
+      top_pad="30"
+      width="350" />
+    
     <check_box
      enabled_control="EnableVoiceChat"
      control_name="AutoDisengageMic"
@@ -87,100 +84,7 @@
      name="favorites_on_login_check"
      top_pad="10"
      width="350" />
-	<text
-      type="string"
-    length="1"
-    follows="left|top"
-     height="10"
-     layout="topleft"
-     left="30"
-     mouse_opaque="false"
-     name="Logs:"
-     top_pad="20"
-     width="350">
-        Chat Logs:
-    </text>
-    <check_box
-	 enabled="false"
-     control_name="LogNearbyChat"
-     height="16"
-     label="Save nearby chat logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_nearby_chat"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-	 enabled="false"
-     control_name="LogInstantMessages"
-     height="16"
-     label="Save IM logs on my computer"
-     layout="topleft"
-     left="30"
-     name="log_instant_messages"
-     top_pad="10"
-     width="350">
-    </check_box>
-    <check_box
-     control_name="LogTimestamp"
-	 enabled="false"
-     height="16"
-     label="Add timestamp to each line in chat log"
-     layout="topleft"
-     left_delta="0"
-     name="show_timestamps_check_im"
-     top_pad="10"
-     width="237" />
-	<check_box
-     control_name="LogFileNamewithDate"
-     enabled="false"
-     height="16"
-     label="Add datestamp to log file name."
-     layout="topleft"
-     left_delta="5"
-     name="logfile_name_datestamp"
-     top_pad="10"
-     width="350"/>
-	<text
-     type="string"
-     length="1"
-     follows="left|top"
-     height="10"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_desc"
-     top_pad="30"
-     width="128">
-        Location of logs:
-    </text>    
-    <line_editor
-     bottom="366"
-     control_name="InstantMessageLogPath"
-     follows="top|left|right"
-     halign="right"
-     height="23"
-     layout="topleft"
-     left_delta="0"
-     mouse_opaque="false"
-     name="log_path_string"
-     top_pad="5"
-     width="250"/>
-    <button
-	 enabled="false"
-     follows="right|bottom"
-     height="23"
-     label="Browse"
-     label_selected="Browse"
-     layout="topleft"
-     left_pad="5"
-     name="log_path_button"
-     top_delta="0"
-     width="145">
-        <button.commit_callback
-         function="Pref.LogPath" />
-    </button>
+
     <button
      follows="left|bottom"
      height="23"
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index 4383b985921b516372d9c7c13cb287ad09d8d12f..7c08aef65e3ac9ef5f3c2d5f44a392c81d65df50 100644
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -295,7 +295,7 @@ Please try logging in again in a minute.</string>
 	<!-- llvoavatar. Displayed in the avatar chat bubble -->
 	<string name="AvatarEditingAppearance">(Editing Appearance)</string>
 	<string name="AvatarAway">Away</string>
-	<string name="AvatarBusy">Busy</string>
+	<string name="AvatarDoNotDisturb">Do Not Disturb</string>
 	<string name="AvatarMuted">Blocked</string>
 
 	<!-- animations -->
@@ -384,6 +384,8 @@ Please try logging in again in a minute.</string>
 	<string name="ST_NO_JOINT">Can't find ROOT or JOINT.</string>
 
 	<!-- Chat -->
+	<string name="NearbyChatTitle">Nearby chat</string>
+  <string name="NearbyChatLabel">(Nearby chat)</string>
 	<string name="whisper">whispers:</string>
 	<string name="shout">shouts:</string>
 	<string name="ringing">Connecting to in-world Voice Chat...</string>
@@ -405,8 +407,9 @@ Please try logging in again in a minute.</string>
 	<string name="ChangePermissions">Change its permissions</string>
 	<string name="TrackYourCamera">Track your camera</string>
   <string name="ControlYourCamera">Control your camera</string>
+	<string name="NotConnected">Not Connected</string>
+	<string name="AgentNameSubst">(You)</string> <!-- Substitution for agent name -->
   <string name="TeleportYourAgent">Teleport you</string>
-  <string name="NotConnected">Not Connected</string>
 
 	<!-- Sim Access labels -->
 	<string name="SIM_ACCESS_PG">General</string>
@@ -2071,12 +2074,6 @@ For AI Character: Get the closest navigable point to the point provided.
 	</string>
 
 
-  <!-- Avatar busy/away mode -->
-	<string name="AvatarSetNotAway">Not Away</string>
-	<string name="AvatarSetAway">Away</string>
-	<string name="AvatarSetNotBusy">Not Busy</string>
-	<string name="AvatarSetBusy">Busy</string>
-
 	<!-- Wearable Types -->
 	<string name="shape">Shape</string>
 	<string name="skin">Skin</string>
@@ -2270,7 +2267,8 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="InvFolder Gestures">Gestures</string>
 	<string name="InvFolder Favorite">My Favorites</string>
   <!-- historically default name of the Favorites folder can start from either "f" or "F" letter.
-  We should localize both of them with the same value -->
+      Also, it can be written as "Favorite" or "Favorites".
+  We should localize all variants of them with the same value -->
 	<string name="InvFolder favorite">My Favorites</string>
 	<string name="InvFolder Favorites">My Favorites</string>
 	<string name="InvFolder favorites">My Favorites</string>
@@ -2284,6 +2282,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 
   <!-- are used for Friends and Friends/All folders in Inventory "Calling cards" folder. See EXT-694-->
 	<string name="InvFolder Friends">Friends</string>
+	<string name="InvFolder Received Items">Received Items</string>
 	<string name="InvFolder All">All</string>
 
 	<string name="no_attachments">No attachments worn</string>
@@ -2524,7 +2523,7 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="PanelContentsNewScript">New Script</string>
 
   <!-- panel preferences general -->
-  <string name="BusyModeResponseDefault">The Resident you messaged is in &apos;busy mode&apos; which means they have requested not to be disturbed.  Your message will still be shown in their IM panel for later viewing.</string>
+  <string name="DoNotDisturbModeResponseDefault">This resident has turned on &apos;Do Not Disturb&apos; and will see your message later.</string>
 
 	<!-- Mute -->
 	<string name="MuteByName">(By name)</string>
@@ -2583,9 +2582,6 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="GroupMoneyDebits">Debits</string>
 	<string name="GroupMoneyDate">[weekday,datetime,utc] [mth,datetime,utc] [day,datetime,utc], [year,datetime,utc]</string>
 
-	<!-- viewer object -->
-	<string name="ViewerObjectContents">Contents</string>
-
 	<!-- Viewer menu -->
 	<string name="AcquiredItems">Acquired Items</string>
 	<string name="Cancel">Cancel</string>
@@ -2991,6 +2987,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 <string name="Higher">Higher</string>
 <string name="Hip Length">Hip Length</string>
 <string name="Hip Width">Hip Width</string>
+<string name="Hover">Hover</string>
 <string name="In">In</string>
 <string name="In Shdw Color">Inner Shadow Color</string>
 <string name="In Shdw Opacity">Inner Shadow Opacity</string>
@@ -3381,12 +3378,15 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
 	<string name="IM_moderator_label">(Moderator)</string>
 	<string name="Saved_message">(Saved [LONG_TIMESTAMP])</string>
 	<string name="IM_unblock_only_groups_friends">To see this message, you must uncheck &apos;Only friends and groups can call or IM me&apos; in Preferences/Privacy.</string>
+  <string name="OnlineStatus">Online</string>
+  <string name="OfflineStatus">Offline</string>
 
 	<!-- voice calls -->
 	<string name="answered_call">Your call has been answered</string>
 	<string name="you_started_call">You started a voice call</string>
 	<string name="you_joined_call">You joined the voice call</string>
-	<string name="name_started_call">[NAME] started a voice call</string>
+  <string name="you_auto_rejected_call-im">You automatically rejected the voice call while &apos;Do Not Disturb&apos; was on.</string>
+  <string name="name_started_call">[NAME] started a voice call</string>
 
   <string name="ringing-im">
     Joining voice call...
@@ -3401,7 +3401,7 @@ If you continue to receive this message, contact the [SUPPORT_SITE].
     Connecting...
   </string>
   <string name="conference-title">
-    Ad-hoc Conference
+    Multi-person chat
   </string>
   <string name="conference-title-incoming">
     Conference with [AGENT_NAME]
@@ -3827,6 +3827,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Avatar_Label">Avatar</string>
   <string name="Command_Build_Label">Build</string>
   <string name="Command_Chat_Label">Chat</string>
+  <string name="Command_Conversations_Label">Conversations</string>
   <string name="Command_Compass_Label">Compass</string>
   <string name="Command_Destinations_Label">Destinations</string>
   <string name="Command_Gestures_Label">Gestures</string>
@@ -3853,6 +3854,7 @@ Try enclosing path to the editor with double quotes.
   <string name="Command_Avatar_Tooltip">Choose a complete avatar</string>
   <string name="Command_Build_Tooltip">Building objects and reshaping terrain</string>
   <string name="Command_Chat_Tooltip">Chat with people nearby using text</string>
+  <string name="Command_Conversations_Tooltip">Converse with everyone</string>
   <string name="Command_Compass_Tooltip">Compass</string>
   <string name="Command_Destinations_Tooltip">Destinations of interest</string>
   <string name="Command_Gestures_Tooltip">Gestures for your avatar</string>
@@ -3907,4 +3909,15 @@ Try enclosing path to the editor with double quotes.
   <!-- Spell check settings floater -->
   <string name="UserDictionary">[User]</string>
   
+  <!-- Conversation log messages -->
+  <string name="logging_calls_disabled_log_empty">
+    Conversations are not being logged. To begin keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+  </string>
+  <string name="logging_calls_disabled_log_not_empty">
+    No more conversations will be logged. To resume keeping a log, choose "Save: Log only" or "Save: Log and transcripts" under Preferences > Chat.
+  </string>
+  <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>
+  
   </strings>
diff --git a/indra/newview/skins/default/xui/en/widgets/chat_editor.xml b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
new file mode 100644
index 0000000000000000000000000000000000000000..f9facb593ac79e2cd1282909524a560c9fcdf876
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/chat_editor.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<chat_editor
+  name="chat_editor"
+  show_context_menu="true"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
deleted file mode 100644
index 0e29ed0d0bf73cb51f670a33cd33c04a32508b81..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_adhoc.xml
+++ /dev/null
@@ -1,55 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_adhoc
- height="23"
- name="im_adhoc_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_adhoc.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25" />
-    <chiclet_im_adhoc.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"      
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_adhoc.avatar_icon
-     bottom="3"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="adhoc_icon"
-     width="21" />
-    <chiclet_im_adhoc.unread_notifications
-     halign="center"
-     height="23"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20" />
-    <chiclet_im_adhoc.new_message_icon
-  bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_adhoc>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
deleted file mode 100644
index 77011139bfe0f9835f4cb1ad200e235ef816729f..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_group.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_group
- height="23"
- name="im_group_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_group.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25" />
-    <chiclet_im_group.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"      
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_group.group_icon
-     bottom="3"
-     default_icon="Generic_Group"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="group_icon"
-     width="21" />
-    <chiclet_im_group.unread_notifications
-     height="23"
-     halign="center"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20"/>
-    <chiclet_im_group.new_message_icon
-bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_group>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml b/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
deleted file mode 100644
index 8b56a8f0f690cb9183e90afd2849a16c4af9e67e..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/widgets/chiclet_im_p2p.xml
+++ /dev/null
@@ -1,56 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<chiclet_im_p2p
- height="23"
- name="im_p2p_chiclet"
- show_speaker="false"
- width="25">
-    <chiclet_im_p2p.chiclet_button
-     height="25"
-     image_selected="PushButton_On"
-     image_unselected="PushButton_Off"
-     name="chiclet_button"
-     tab_stop="false"
-     width="25"/>
-    <chiclet_im_p2p.speaker
-      image_mute="Parcel_VoiceNo_Light"
-      image_off="VoicePTT_Off_Dark"
-      image_on="VoicePTT_On_Dark"
-      image_level_1="VoicePTT_Lvl1_Dark"
-      image_level_2="VoicePTT_Lvl2_Dark"
-      image_level_3="VoicePTT_Lvl3_Dark"
-      auto_update="true"
-      draw_border="false"
-      height="24"
-      left="25"
-      bottom="1"
-      name="speaker"
-      visible="false"
-      width="20" />
-    <chiclet_im_p2p.avatar_icon
-     bottom="3"
-     color="white"
-     follows="left|top|bottom"
-     height="20"
-     left="2"
-     mouse_opaque="false"
-     name="avatar_icon"
-     width="21" />
-    <chiclet_im_p2p.unread_notifications
-     height="23"
-     halign="center"
-     left="25"
-     mouse_opaque="false"
-     name="unread"
-     text_color="white"
-     v_pad="3"
-     visible="false"
-     width="20"/>
-    <chiclet_im_p2p.new_message_icon
-  bottom="11"
-  height="14"
-  image_name="Unread_Chiclet"
-  left="12"
-  name="new_message_icon"
-  visible="false"
-  width="14" />
-</chiclet_im_p2p>
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
new file mode 100755
index 0000000000000000000000000000000000000000..b83d9122f72cfdfe253ec44ad7bec94d30c6b744
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_participant.xml
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_participant
+  folder_arrow_image="Folder_Arrow"
+  item_height="24" 
+  item_top_pad="0"
+  selection_image="Rounded_Square"
+  mouse_opaque="true"
+  follows="left|top|right"
+  left_pad="0"
+  icon_pad="10"
+  icon_width="20"
+  text_pad="7"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"
+>
+<avatar_icon
+	 follows="left"
+     height="20"
+     default_icon_name="Generic_Person"
+	 layout="topleft"
+	 top="2"
+     width="20" />
+<info_button
+	 follows="right"
+     height="16"
+     image_pressed="Info_Press"
+     image_unselected="Info_Over"
+     right="-28"
+     name="info_btn"
+     width="16" />
+<output_monitor
+	follows="right"
+	auto_update="true"
+	draw_border="false"
+	height="16"
+	right="-3"
+	mouse_opaque="true"
+	name="speaking_indicator"
+	visible="true"
+	width="20" />	 
+</conversation_view_participant>
diff --git a/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b8c39eec1db7f6826b21972f1e69982b651a632d
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/widgets/conversation_view_session.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<conversation_view_session
+  folder_arrow_image="Folder_Arrow"
+  folder_indentation="8"
+  item_height="24" 
+  item_top_pad="4"
+  selection_image="Rounded_Square"
+  mouse_opaque="true"
+  follows="left|top|right"
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
index 6fa74f403d8f8d4add86d3e9d11589eb722c29a9..bbd53ccb121374170c7002144725d566a4bc8d90 100644
--- a/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
+++ b/indra/newview/skins/default/xui/en/widgets/folder_view_item.xml
@@ -7,4 +7,10 @@
   selection_image="Rounded_Square"
   mouse_opaque="true"
   follows="left|top|right"
-  />
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
index 77d8024cb257b35a15f351c6553b8b347bb208e8..590a4730a9bc7a10141d09cff1a67f13c206af66 100644
--- a/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_folder_view_folder.xml
@@ -5,7 +5,13 @@
   item_height="20" 
   item_top_pad="4"
   selection_image="Rounded_Square"
-  >
+  left_pad="5"
+  icon_pad="2"
+  icon_width="16"
+  text_pad="1"
+  text_pad_right="4"
+  arrow_size="12"
+  max_folder_item_overlap="2">
 	<new_badge 
         label="New" 
         label_offset_horiz="-1"
diff --git a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
index 830c27bdac83f47af3727942ac17d96a60c3e87f..d5b10e7f51b42f8f2750606bc4bf9cd67463ca28 100644
--- a/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
+++ b/indra/newview/skins/default/xui/en/widgets/inbox_inventory_panel.xml
@@ -1,2 +1,3 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<inbox_inventory_panel show_load_status="false" />
+<inbox_inventory_panel show_load_status="false"
+                       start_folder.type="inbox"/>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml b/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
deleted file mode 100644
index d19c47f54f3ce17525c2bc9d3b5d1a10d9e0165f..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_folder_view_folder.xml
+++ /dev/null
@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_folder_view_folder
-  folder_arrow_image="Folder_Arrow"
-  folder_indentation="8"
-  item_height="20" 
-  item_top_pad="4"
-  selection_image="Rounded_Square"
-  >
-</outbox_folder_view_folder>
diff --git a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml b/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
deleted file mode 100644
index 3964569da24a9346996145189a6437926b1bf7d0..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/en/widgets/outbox_inventory_panel.xml
+++ /dev/null
@@ -1,2 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
-<outbox_inventory_panel show_empty_message="false" show_load_status="false" />
diff --git a/indra/newview/skins/default/xui/en/widgets/text.xml b/indra/newview/skins/default/xui/en/widgets/text.xml
index 134f2d75229719c15a16315adf11c8e609b1354f..210207467435b44ab7231f00ef05c95906f79649 100644
--- a/indra/newview/skins/default/xui/en/widgets/text.xml
+++ b/indra/newview/skins/default/xui/en/widgets/text.xml
@@ -9,6 +9,7 @@
       h_pad="0" 
       allow_scroll="false"
       text_readonly_color="LabelTextColor"
+      text_tentative_color="TextFgTentativeColor"
       bg_writeable_color="FloaterDefaultBackgroundColor" 
       use_ellipses="false"
       bg_visible="false" 
diff --git a/indra/newview/skins/default/xui/en/widgets/toolbar.xml b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
index 0aa478ace9fc66945f817d827bad357f255d1f0b..0ace37a5dc10685e052652f87dc6a56a4741a63b 100644
--- a/indra/newview/skins/default/xui/en/widgets/toolbar.xml
+++ b/indra/newview/skins/default/xui/en/widgets/toolbar.xml
@@ -30,9 +30,9 @@
                         image_overlay_alignment="left"
                         use_ellipses="true"
                         auto_resize="true"
-                        button_flash_count="99999"
-                        button_flash_rate="1.0"
-                        flash_color="EmphasisColor"/>
+                        button_flash_count="4"
+                        button_flash_rate="0.5"
+                        flash_color="BeaconColor"/>
   <button_icon pad_left="10"
                pad_right="10"
                image_bottom_pad="10"
@@ -51,7 +51,7 @@
                chrome="true"
                use_ellipses="true"
                auto_resize="true"
-               button_flash_count="99999"
-               button_flash_rate="1.0"
-               flash_color="EmphasisColor"/>
+               button_flash_count="4"
+               button_flash_rate="0.5"
+               flash_color="BeaconColor"/>
 </toolbar>
diff --git a/indra/newview/skins/default/xui/es/floater_chat_bar.xml b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
index 2e948050570a2eca9045f21eafb78dca9a3b0fca..02369c9a43382678cafdc98f989d1af4ffec9f4d 100644
--- a/indra/newview/skins/default/xui/es/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT">
+<floater name="nearby_chat" title="CHAT">
 	<panel name="bottom_panel">
 		<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
 		<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
diff --git a/indra/newview/skins/default/xui/es/menu_im_well_button.xml b/indra/newview/skins/default/xui/es/menu_im_well_button.xml
deleted file mode 100644
index c8f6c217cc30da60175be58e89f4857273a2252a..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/es/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Cerrar todo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
index af2b6e920bcbdcf9cca527a553bd40b6e3f3c3b9..e6ca59f91202b49df1834fad58b76e5d69100eac 100644
--- a/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/es/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Pulsa aquí para chatear." name="chat_box" tool_tip="Pulsa Enter para decirlo o Ctrl+Enter para gritarlo"/>
 	<button name="show_nearby_chat" tool_tip="Muestra o esconde el registro del chat"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
index 890411d09182c28bcebbeb3b7f0d9c4dca6011d3..7dcb9a280d4b7651d8bb5458ce2cffb822a1ad67 100644
--- a/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT PRÈS DE MOI">
+<floater name="nearby_chat" title="CHAT PRÈS DE MOI">
 	<panel name="bottom_panel">
 		<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl+Entrée pour crier"/>
 		<button name="show_nearby_chat" tool_tip="Afficher/masquer le journal de chat près de vous."/>
diff --git a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml b/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
deleted file mode 100644
index 8ef1529e6b44106431b4d5f4251c3410180993fe..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/fr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Tout fermer" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
index 82cdf292abbddda0834273e8489b47f60cc9660c..762dee01bb452fc7d990c9f01d09115804d71c48 100644
--- a/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/fr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Cliquer ici pour chatter." name="chat_box" tool_tip="Appuyer sur Entrée pour dire, Ctrl-Entrée pour crier"/>
 	<button name="show_nearby_chat" tool_tip="Affiche/Masque le journal de chats près de vous"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/it/floater_chat_bar.xml b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
index 94c85b50c812bdef345c99adf8e8da0f6d2e68c0..b47e32ce90ef48058e308ac2d04d99385a2ef1ef 100644
--- a/indra/newview/skins/default/xui/it/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="CHAT NEI DINTORNI">
+<floater name="nearby_chat" title="CHAT NEI DINTORNI">
 	<panel name="bottom_panel">
 		<line_editor label="Clicca qui per la chat." name="chat_box" tool_tip="Premi Invio per parlare, Ctrl+Invio per gridare"/>
 		<button name="show_nearby_chat" tool_tip="Mostra/Nasconde il registro della chat nei dintorni"/>
diff --git a/indra/newview/skins/default/xui/it/menu_im_well_button.xml b/indra/newview/skins/default/xui/it/menu_im_well_button.xml
deleted file mode 100644
index 9e471b771c78053239a5a2a367a145964d3690ed..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/it/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Chiudi tutto" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
index 6317d3192ea76f9b4af66e829c0cbf3f2c514124..1fef88870aa5b9d048fa034e954ae718ef1c9edd 100644
--- a/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/it/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<string name="min_width">
 		192
 	</string>
diff --git a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
index 11f223ade63011c4ff19b9a7ca1a894fbb560a89..9f5df6fb85e3043e5bb1ca2cf200b3131519d4ee 100644
--- a/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="近くのチャット">
+<floater name="nearby_chat" title="近くのチャット">
 	<panel name="bottom_panel">
 		<line_editor label="ここをクリックしてチャットを開始します。" name="chat_box" tool_tip="Enter キーを押して話し、Ctrl + Enter キーで叫びます。"/>
 		<button name="show_nearby_chat" tool_tip="近くのチャットログを表示/非表示"/>
diff --git a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml b/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
deleted file mode 100644
index 3397004bd70479547bd3acfabcbe7b30a55bfabc..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/ja/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="すべて閉じる" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
index 5998206f27c2d60c7d35bb72dc412355ebe2803d..201fb0a376811d8e1b90d707375cb706ae6a6ff5 100644
--- a/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ja/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="ここをクリックしてチャットを開始します。" name="chat_box" tool_tip="Enter キーを押して発言し、Ctrl + Enter キーで叫びます。"/>
 	<button name="show_nearby_chat" tool_tip="近くのチャットログを表示・非表示"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml b/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
deleted file mode 100644
index 207bc2211b30df0242c54f17dfc33ba95794f5f2..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/pl/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Zamknij wszystkie" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
index 63cf96b5710b4d177ba0a3c4ab3eca5e20112df5..4ed3ff669b0e65ca64a0af0d0e9db0c4fae5684b 100644
--- a/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pl/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<string name="min_width">
 		192
 	</string>
diff --git a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
index 72016c6b40627ace932c2d865fd552350187ce6f..2eb2c949409191e2d768b998ff3f5a919caa7f38 100644
--- a/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="BATE-PAPO LOCAL">
+<floater name="nearby_chat" title="BATE-PAPO LOCAL">
 	<panel name="bottom_panel">
 		<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
 		<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
diff --git a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml b/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
deleted file mode 100644
index 2d37cefd6fec5f8e3a4b84713252bec4a68a235e..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/pt/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Fechar tudo" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
index 9b993488be16f027dffda0064a17fb7e7402a89e..5628a8710904cce5b20d5cbcc94f31fb387682df 100644
--- a/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/pt/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Clique aqui para bater papo." name="chat_box" tool_tip="Tecle Enter para falar, Ctrl+Enter para gritar"/>
 	<button name="show_nearby_chat" tool_tip="Mostra/oculta o histórico do bate-papo local"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
index 79b7b033fb663933aed996d29ed3b561b3d4feb4..f6b2fc81e1ed9786137f4a4833db158c558710ee 100644
--- a/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="ЛОКАЛЬНЫЙ ЧАТ">
+<floater name="nearby_chat" title="ЛОКАЛЬНЫЙ ЧАТ">
 	<panel name="bottom_panel">
 		<line_editor label="Щелкните здесь для общения." name="chat_box" tool_tip="Нажмите Enter, чтобы сказать, Ctrl+Enter, чтобы прокричать"/>
 		<button name="show_nearby_chat" tool_tip="Показать/скрыть лог локального чата"/>
diff --git a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml b/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
deleted file mode 100644
index 5a5bde61b99cc384e6ade7abb36f7118d10e1e48..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/ru/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Закрыть все" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
index 804ba7def7538d80fc475e7306695222efbf1ce9..395c643b0be0017445d684eff49b1923d743c537 100644
--- a/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/ru/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Щелкните здесь для общения" name="chat_box" tool_tip="Нажмите Enter, чтобы сказать, Ctrl+Enter, чтобы прокричать"/>
 	<button name="show_nearby_chat" tool_tip="Показать/скрыть лог локального чата"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
index 988c845982f4500c27e933bc7ea17828267eb701..cd999b4b7a0f1169cb050a989ca301fb371f7cfe 100644
--- a/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/floater_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<floater name="chat_bar" title="YAKINDAKÄ° SOHBET">
+<floater name="nearby_chat" title="YAKINDAKÄ° SOHBET">
 	<panel name="bottom_panel">
 		<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
 		<button name="show_nearby_chat" tool_tip="Yakın sohbet günlüğünü gösterir/gizler"/>
diff --git a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml b/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
deleted file mode 100644
index c3e559a7231d73bf199030929c9137c2e2fdbbaf..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/tr/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="Tümünü Kapat" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
index fd954475acdb2e6b1aab1ac0be54a80ad2af5697..7d191191c415b4060b43cbb1df17fab0ebb36668 100644
--- a/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/tr/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="Sohbet etmek için buraya tıklayın." name="chat_box" tool_tip="Söylemek için Enter, bağırmak için Ctrl+Enter yapın"/>
 	<button name="show_nearby_chat" tool_tip="yakın sohbet günlüğünü gösterir/gizler"/>
 </panel>
diff --git a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml b/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
deleted file mode 100644
index 4b9b4b275872824c9fa407894755359e5aa31d69..0000000000000000000000000000000000000000
--- a/indra/newview/skins/default/xui/zh/menu_im_well_button.xml
+++ /dev/null
@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<context_menu name="IM Well Button Context Menu">
-	<menu_item_call label="全部關閉" name="Close All"/>
-</context_menu>
diff --git a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
index 4361b588d8c472ddfffbbc972c2dcd46bd8cd14b..9489113d0930ad52e132bcbeb0971b74fe069d4f 100644
--- a/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
+++ b/indra/newview/skins/default/xui/zh/panel_nearby_chat_bar.xml
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8" standalone="yes"?>
-<panel name="chat_bar">
+<panel name="nearby_chat">
 	<line_editor label="點按此處開始聊天。" name="chat_box" tool_tip="按下 Enter 鍵來說或按下 Ctrl+Enter 來喊叫"/>
 	<button name="show_nearby_chat" tool_tip="顯示 / 隱藏 附近的聊天紀錄"/>
 </panel>
diff --git a/indra/newview/tests/llmediadataclient_test.cpp b/indra/newview/tests/llmediadataclient_test.cpp
index 0254c5881f76c8bfba620aaab54b80575774e05e..41cb344808371cf9dc9c87fe31c28b7f09a9782d 100644
--- a/indra/newview/tests/llmediadataclient_test.cpp
+++ b/indra/newview/tests/llmediadataclient_test.cpp
@@ -126,7 +126,9 @@ void LLHTTPClient::post(
 	result[LLTextureEntry::OBJECT_ID_KEY] = body[LLTextureEntry::OBJECT_ID_KEY];
 	if ( url == FAKE_OBJECT_MEDIA_CAP_URL_503 )
 	{
-		responder->error(HTTP_SERVICE_UNAVAILABLE, "fake reason");
+		LLSD content;
+		content["reason"] = "fake reason";
+		responder->errorWithContent(HTTP_SERVICE_UNAVAILABLE, "fake reason", content);
 		return;
 	}
 	else if (url == FAKE_OBJECT_MEDIA_NAVIGATE_CAP_URL_ERROR) 
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
old mode 100644
new mode 100755
index f8923b986814dcd4c80692859e06b6a08d6d7f34..a331d9aa9e5bde8f3582527ef761495fb3b0d3b4
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -37,30 +37,6 @@
 #include "llregionhandle.h"
 #include "../llvoavatar.h"
 
-void LLVOAvatar::getNearbyRezzedStats(std::vector<S32>& counts)
-{
-	counts.resize(3);
-	counts[0] = 0;
-	counts[1] = 0;
-	counts[2] = 1;
-}
-
-// static
-std::string LLVOAvatar::rezStatusToString(S32 rez_status)
-{
-	if (rez_status==0) return "cloud";
-	if (rez_status==1) return "gray";
-	if (rez_status==2) return "textured";
-	return "unknown";
-}
-
-// static
-LLViewerStats::StatsAccumulator& LLViewerStats::PhaseMap::getPhaseStats(const std::string& phase_name)
-{
-	static LLViewerStats::StatsAccumulator junk;
-	return junk;
-}
-
 static const char * all_keys[] = 
 {
 	"duration",
@@ -123,31 +99,34 @@ is_empty_map(const LLSD & sd)
 {
 	return sd.isMap() && 0 == sd.size();
 }
+#endif
 
+#if 0
 static bool
 is_single_key_map(const LLSD & sd, const std::string & key)
 {
 	return sd.isMap() && 1 == sd.size() && sd.has(key);
 }
+#endif
 
 static bool
 is_double_key_map(const LLSD & sd, const std::string & key1, const std::string & key2)
 {
 	return sd.isMap() && 2 == sd.size() && sd.has(key1) && sd.has(key2);
 }
-#endif
 
+#if 0
 static bool
 is_triple_key_map(const LLSD & sd, const std::string & key1, const std::string & key2, const std::string& key3)
 {
 	return sd.isMap() && 3 == sd.size() && sd.has(key1) && sd.has(key2) && sd.has(key3);
 }
-
+#endif
 
 static bool
 is_no_stats_map(const LLSD & sd)
 {
-	return is_triple_key_map(sd, "duration", "regions", "avatar");
+	return is_double_key_map(sd, "duration", "regions");
 }
 
 static bool
@@ -258,7 +237,7 @@ namespace tut
 		// Once the region is set, we will get a response even with no data collection
 		it->setRegion(region1_handle);
 		sd_full = it->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd_full, "duration", "regions", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd_full, "duration", "regions"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd_full["regions"], region1_handle));
 		
 		LLSD sd = sd_full["regions"][0];
@@ -299,7 +278,7 @@ namespace tut
 		it->setRegion(region1_handle);
 		
 		LLSD sd = it->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd[0];
 		
@@ -324,7 +303,7 @@ namespace tut
 		LLViewerAssetStatsFF::record_dequeue_main(LLViewerAssetType::AT_BODYPART, false, false);
 
 		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd["regions"][0];
 		
@@ -364,7 +343,7 @@ namespace tut
 		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
 		ensure("Other collector is empty", is_no_stats_map(sd));
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = sd["regions"][0];
 		
@@ -414,7 +393,7 @@ namespace tut
 
 		// std::cout << sd << std::endl;
 		
-		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
 		LLSD sd1 = get_region(sd, region1_handle);
 		LLSD sd2 = get_region(sd, region2_handle);
@@ -437,7 +416,7 @@ namespace tut
 		// Reset leaves current region in place
 		gViewerAssetStatsMain->reset();
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
 		sd2 = sd["regions"][0];
 		
@@ -486,7 +465,7 @@ namespace tut
 
 		LLSD sd = gViewerAssetStatsMain->asLLSD(false);
 
-		ensure("Correct double-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct double-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct double-slot LLSD array regions", is_double_slot_array(sd["regions"], region1_handle, region2_handle));
 		LLSD sd1 = get_region(sd, region1_handle);
 		LLSD sd2 = get_region(sd, region2_handle);
@@ -509,7 +488,7 @@ namespace tut
 		// Reset leaves current region in place
 		gViewerAssetStatsMain->reset();
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "duration", "regions", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "duration", "regions"));
 		ensure("Correct single-slot LLSD array regions (p2)", is_single_slot_array(sd["regions"], region2_handle));
 		sd2 = get_region(sd, region2_handle);
 		ensure("Region2 is present in results", sd2.isMap());
@@ -555,7 +534,7 @@ namespace tut
 		LLSD sd = gViewerAssetStatsThread1->asLLSD(false);
 		ensure("Other collector is empty", is_no_stats_map(sd));
 		sd = gViewerAssetStatsMain->asLLSD(false);
-		ensure("Correct single-key LLSD map root", is_triple_key_map(sd, "regions", "duration", "avatar"));
+		ensure("Correct single-key LLSD map root", is_double_key_map(sd, "regions", "duration"));
 		ensure("Correct single-slot LLSD array regions", is_single_slot_array(sd["regions"], region1_handle));
 		sd = get_region(sd, region1_handle);
 		ensure("Region1 is present in results", sd.isMap());
diff --git a/indra/newview/tests/llviewertexture_stub.cpp b/indra/newview/tests/llviewertexture_stub.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..889ab9bea559dcb7aef6e4e2db769daab6530129
--- /dev/null
+++ b/indra/newview/tests/llviewertexture_stub.cpp
@@ -0,0 +1,34 @@
+/** 
+ * @file llviewertexture_stub.cpp
+ * @brief  stub class to allow unit testing
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2011, Linden Research, Inc.
+ * 
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ * 
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ * 
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ * 
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+#include "../llviewertexture.h"
+#include "../../llrender/llgltexture.h"
+
+void LLViewerTexture::setBoostLevel(int level)
+{
+}
+
diff --git a/indra/newview/tests/llworldmap_test.cpp b/indra/newview/tests/llworldmap_test.cpp
index acc6e814bc7a196d1f071cc6c79d4a15b9f68123..84194adb5df409a78544dd0d8f70ac6de4878910 100644
--- a/indra/newview/tests/llworldmap_test.cpp
+++ b/indra/newview/tests/llworldmap_test.cpp
@@ -47,9 +47,9 @@
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
 // Stub image calls
-void LLViewerTexture::setBoostLevel(S32 ) { }
-void LLViewerTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, BOOL, LLViewerTexture::EBoostLevel, S8,
+void LLGLTexture::setBoostLevel(S32 ) { }
+void LLGLTexture::setAddressMode(LLTexUnit::eTextureAddressMode ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTexture(const LLUUID&, FTType, BOOL, LLGLTexture::EBoostLevel, S8,
 																  LLGLint, LLGLenum, LLHost ) { return NULL; }
 
 // Stub related map calls
diff --git a/indra/newview/tests/llworldmipmap_test.cpp b/indra/newview/tests/llworldmipmap_test.cpp
index e7ef0177608558651de83f6fa2d27a8d05dbf6c7..142d75bcfd523689f275f60091377f13c6e164a0 100644
--- a/indra/newview/tests/llworldmipmap_test.cpp
+++ b/indra/newview/tests/llworldmipmap_test.cpp
@@ -42,8 +42,8 @@
 // * Do not make any assumption as to how those classes or methods work (i.e. don't copy/paste code)
 // * A simulator for a class can be implemented here. Please comment and document thoroughly.
 
-void LLViewerTexture::setBoostLevel(S32 ) { }
-LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, BOOL, LLViewerTexture::EBoostLevel, S8, 
+void LLGLTexture::setBoostLevel(S32 ) { }
+LLViewerFetchedTexture* LLViewerTextureManager::getFetchedTextureFromUrl(const std::string&, FTType, BOOL, LLGLTexture::EBoostLevel, S8, 
 																		 LLGLint, LLGLenum, const LLUUID& ) { return NULL; }
 
 LLControlGroup::LLControlGroup(const std::string& name) : LLInstanceTracker<LLControlGroup, std::string>(name) { }
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 2211a3bdf67b6d25819113555e643602ef7ad888..e2b914aae806ceaf905695dd02101b379046984c 100644
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -1082,7 +1082,7 @@ def construct(self):
             self.path("libcrypto.so.*")
             self.path("libexpat.so.*")
             self.path("libssl.so.1.0.0")
-            self.path("libglod.so")
+            self.path("libGLOD.so")
             self.path("libminizip.so")
             self.path("libuuid.so*")
             self.path("libSDL-1.2.so.*")
diff --git a/indra/test/CMakeLists.txt b/indra/test/CMakeLists.txt
index 816f1d7175ebd177c5b3efe114d1bfef9af0d8b0..31e1d89c6839757246ae08e60b6472089281ea8f 100644
--- a/indra/test/CMakeLists.txt
+++ b/indra/test/CMakeLists.txt
@@ -28,6 +28,10 @@ include_directories(
     ${GOOGLEMOCK_INCLUDE_DIRS}
     ${TUT_INCLUDE_DIR}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(test_SOURCE_FILES
     io.cpp
diff --git a/indra/test/io.cpp b/indra/test/io.cpp
index ce747f667d2d53e0ed78b4d1640b5432877309cd..47a67deed00c80957fbfdc0136cbfe8417125581 100644
--- a/indra/test/io.cpp
+++ b/indra/test/io.cpp
@@ -1140,7 +1140,7 @@ namespace tut
 		bool connected = client->blockingConnect(server_host);
 		ensure("Connected to server", connected);
 		lldebugs << "connected" << llendl;
-		F32 elapsed = pump_loop(mPump,0.1f);
+		pump_loop(mPump,0.1f);
 		count = mPump->runningChains();
 		ensure_equals("server chain onboard", count, 2);
 		lldebugs << "** Client is connected." << llendl;
@@ -1156,20 +1156,20 @@ namespace tut
 		chain.clear();
 
 		// pump for a bit and make sure all 3 chains are running
-		elapsed = pump_loop(mPump,0.1f);
+		pump_loop(mPump,0.1f);
 		count = mPump->runningChains();
 		ensure_equals("client chain onboard", count, 3);
 		lldebugs << "** request should have been sent." << llendl;
 
 		// pump for long enough the the client socket closes, and the
 		// server socket should not be closed yet.
-		elapsed = pump_loop(mPump,0.2f);
+		pump_loop(mPump,0.2f);
 		count = mPump->runningChains();
 		ensure_equals("client chain timed out ", count, 2);
 		lldebugs << "** client chain should be closed." << llendl;
 
 		// At this point, the socket should be closed by the timeout
-		elapsed = pump_loop(mPump,1.0f);
+		pump_loop(mPump,1.0f);
 		count = mPump->runningChains();
 		ensure_equals("accepted socked close", count, 1);
 		lldebugs << "** Sleeper should have timed out.." << llendl;
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index bf6766424c60264fe999ca7d4d2cf18c9bc663fb..bc2c87ba46db351af3f15daf5f7cc1548d476330 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -407,7 +407,7 @@ namespace tut
 		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
 		LLPermissions perm,perm1;
@@ -425,15 +425,15 @@ namespace tut
 
 		perm.initMasks(base, ownerp, everyone, groupp, next);
 
-		perm.exportFile(fp);
+		ensure("Permissions export failed", perm.exportFile(fp));
 		fclose(fp);	
 		fp = LLFile::fopen("linden_file.dat","r+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
-		perm1.importFile(fp);
+		ensure("Permissions import failed", perm1.importFile(fp));
 		fclose(fp);
 		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	
 }
@@ -461,7 +461,7 @@ namespace tut
 		std::istringstream istream(ostream.str());
 		perm1.importLegacyStream(istream);
 
-		ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm);
+		ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);
 	}
 
 	template<> template<>
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 09fca2abbab19013063aaf558fd511c6f861f680..2689eaa15e5f0088e72e9918ae5adf75a78a25ae 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -154,8 +154,9 @@ namespace tut
 		BOOL has_perm_mask = FALSE;
 		llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
 					
-		ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
-										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		
+		ensure("importStream() fn failed ",
+			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
+			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
 	}
 
 	template<> template<>
diff --git a/indra/test/llstreamtools_tut.cpp b/indra/test/llstreamtools_tut.cpp
index a93f2e8f65e992001e06fadb88383cdd20c522bb..0f6436f0f4a8b51e5d517ff85d2840c4895126da 100644
--- a/indra/test/llstreamtools_tut.cpp
+++ b/indra/test/llstreamtools_tut.cpp
@@ -385,16 +385,15 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "  First Second \t \r  \n Third  Fourth-ShouldThisBePartOfFourth  Fifth\n");
 		actual_result = "";
-		ret = get_word(actual_result, is); // First
+		get_word(actual_result, is); // First
 		actual_result = "";
-		ret = get_word(actual_result, is); // Second
+		get_word(actual_result, is); // Second
 		actual_result = "";
-		ret = get_word(actual_result, is); // Third
+		get_word(actual_result, is); // Third
 
 		// the current implementation of get_word seems inconsistent with
 		// skip_to_next_word. skip_to_next_word treats any character other
@@ -403,22 +402,22 @@ namespace tut
 		// carriage  return ('\r'), horizontal tab ('\t'), and vertical tab ('\v')
 		// as delimiters 
 		actual_result = "";
-		ret = get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
+		get_word(actual_result, is); // will copy Fourth-ShouldThisBePartOfFourth
 
 		actual_result = "";
-		ret = get_word(actual_result, is); // will copy Fifth
+		get_word(actual_result, is); // will copy Fifth
 
 		is.clear();
 		is.str(str = "  First Second \t \r  \n Third  Fourth_ShouldThisBePartOfFourth Fifth\n");
-		ret = skip_to_next_word(is);  // should now point to First
-		ret = skip_to_next_word(is);  // should now point to Second
-		ret = skip_to_next_word(is);  // should now point to Third
-		ret = skip_to_next_word(is);  // should now point to Fourth
-		ret = skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth
+		skip_to_next_word(is);  // should now point to First
+		skip_to_next_word(is);  // should now point to Second
+		skip_to_next_word(is);  // should now point to Third
+		skip_to_next_word(is);  // should now point to Fourth
+		skip_to_next_word(is);  // should now point to ShouldThisBePartOfFourth
 		expected_result = "";
 		// will copy ShouldThisBePartOfFourth, the fifth word, 
 		// while using get_word above five times result in getting "Fifth"
-		ret = get_word(expected_result, is); 
+		get_word(expected_result, is); 
 		ensure_equals("get_word: skip_to_next_word compatibility", actual_result, expected_result);
 	}
 
@@ -480,39 +479,38 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "First Second \t \r\n Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "First Second \t \r\n";
 		ensure_equals("get_line: 1", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = " Third  Fourth-ShouldThisBePartOfFourth  IsThisFifth\n";
 		ensure_equals("get_line: 2", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "\nFirst Line.\n\nSecond Line.\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: First char as newline", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "First Line.\n";
 		ensure_equals("get_line: 3", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: 4", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "Second Line.\n";
 		ensure_equals("get_line: 5", actual_result, expected_result);
 	}	
@@ -544,13 +542,12 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		// need to be check if this test case is wrong or the implementation is wrong.
 		is.clear();
 		is.str(str = "Should not skip lone \r.\r\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "Should not skip lone \r.\r\n";
 		ensure_equals("get_line: carriage return skipped even though not followed by newline", actual_result, expected_result);
 	}
@@ -563,12 +560,11 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "\n");
 		actual_result = "";
-		ret = get_line(actual_result, is);
+		get_line(actual_result, is);
 		expected_result = "\n";
 		ensure_equals("get_line: Just newline", actual_result, expected_result);
 	}
@@ -582,36 +578,35 @@ namespace tut
 		std::string expected_result;
 		std::string actual_result;
 		std::istringstream is;
-		bool ret;
 
 		is.clear();
 		is.str(str = "First Line.\nSecond Line.\n");
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = "First Line.\n";
 		ensure_equals("get_line: Basic Operation", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is, sizeof("Second")-1);
+		get_line(actual_result, is, sizeof("Second")-1);
 		expected_result = "Second\n";
 		ensure_equals("get_line: Insufficient length 1", actual_result, expected_result);
 
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = " Line.\n";
 		ensure_equals("get_line: Remainder after earlier insufficient length", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "One Line only with no newline with limited length");
 		actual_result = "";
-		ret = get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
+		get_line(actual_result, is, sizeof("One Line only with no newline with limited length")-1);
 		expected_result = "One Line only with no newline with limited length\n";
 		ensure_equals("get_line: No newline with limited length", actual_result, expected_result);
 
 		is.clear();
 		is.str(str = "One Line only with no newline");
 		actual_result = "";
-		ret = get_line(actual_result, is, 255);
+		get_line(actual_result, is, 255);
 		expected_result = "One Line only with no newline";
 		ensure_equals("get_line: No newline", actual_result, expected_result);
 	}
diff --git a/indra/test/lltemplatemessagebuilder_tut.cpp b/indra/test/lltemplatemessagebuilder_tut.cpp
index 6e1c82bb2464949a99ef34854bade4aa8df3d25e..6c0b70edd2e15690186dfd30af42fefa7d02b0ac 100644
--- a/indra/test/lltemplatemessagebuilder_tut.cpp
+++ b/indra/test/lltemplatemessagebuilder_tut.cpp
@@ -937,7 +937,7 @@ namespace tut
 		// build message with single block
 		LLMessageTemplate messageTemplate = defaultTemplate();
 		messageTemplate.addBlock(defaultBlock(MVT_U32, 4, MBT_SINGLE));
-		U32 outValue, outValue2, inValue = 0xbbbbbbbb;
+		U32 outValue, inValue = 0xbbbbbbbb;
 		LLTemplateMessageBuilder* builder = defaultBuilder(messageTemplate);
 		builder->addU32(_PREHASH_Test0, inValue);
 		const U32 bufferSize = 1024;
@@ -962,7 +962,6 @@ namespace tut
 		memset(buffer, 0xcc, bufferSize);
 		reader->getString(_PREHASH_Test1, _PREHASH_Test0, bufferSize, 
 						  outBuffer);
-		outValue2 = reader->getNumberOfBlocks(_PREHASH_Test1);
 		ensure_equals("Ensure present value ", outValue, inValue);
 		ensure_equals("Ensure unchanged buffer ", strlen(outBuffer), 0);
 		delete reader;
diff --git a/indra/test_apps/llplugintest/CMakeLists.txt b/indra/test_apps/llplugintest/CMakeLists.txt
index 1211bb7e5a35bb1724bd52c7de0b5c5f117138bf..8179be66f51ce194e1433c6735391a5af1ef68ee 100644
--- a/indra/test_apps/llplugintest/CMakeLists.txt
+++ b/indra/test_apps/llplugintest/CMakeLists.txt
@@ -2,7 +2,7 @@
 project(llplugintest)
 
 include(00-Common)
-include(FindOpenGL)
+include(OpenGL)
 include(LLCommon)
 include(LLPlugin)
 include(Linking)
@@ -25,6 +25,9 @@ include_directories(
     ${LLRENDER_INCLUDE_DIRS}
     ${LLWINDOW_INCLUDE_DIRS}
 )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 if (DARWIN)
     include(CMakeFindFrameworks)
diff --git a/indra/viewer_components/login/CMakeLists.txt b/indra/viewer_components/login/CMakeLists.txt
index 7720619df3017a718a3ba393f086fbb67d8db768..658f167c2e2802e7c4318d012003e1e8cd309aaa 100644
--- a/indra/viewer_components/login/CMakeLists.txt
+++ b/indra/viewer_components/login/CMakeLists.txt
@@ -15,6 +15,10 @@ include_directories(
     ${LLMATH_INCLUDE_DIRS}
     ${LLXML_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(login_SOURCE_FILES
     lllogin.cpp
diff --git a/indra/viewer_components/updater/CMakeLists.txt b/indra/viewer_components/updater/CMakeLists.txt
index ef82290b4719d9213f25722d007d01d17890c118..de7e3363414a937f2d8ed05285bf8dfae33809fa 100644
--- a/indra/viewer_components/updater/CMakeLists.txt
+++ b/indra/viewer_components/updater/CMakeLists.txt
@@ -20,6 +20,9 @@ include_directories(
     ${LLVFS_INCLUDE_DIRS}
     ${CURL_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(updater_service_SOURCE_FILES
     llupdaterservice.cpp
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index a49bc4161e2cdc4558a7d633d878d471b35ee963..de07beee7c8ebe2ab9fa7e116e4257faba8cb443 100644
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -83,6 +83,7 @@ std::string LLDir::getSkinFolder() const { return "default"; }
 std::string LLDir::getLanguage() const { return "en"; }
 bool LLDir::setCacheDir(const std::string &path){ return true; }
 void LLDir::dumpCurrentDirectories() {}
+void LLDir::updatePerAccountChatLogsDir() {}
 
 std::string LLDir::getExpandedFilename(ELLPath location, 
 									   const std::string &filename) const 
diff --git a/indra/win_crash_logger/CMakeLists.txt b/indra/win_crash_logger/CMakeLists.txt
index 5329c89554298df4d4ea21d319b7b13332508b0c..aa35c3b05ea885aa6a13abc02cde879a21c28a3f 100644
--- a/indra/win_crash_logger/CMakeLists.txt
+++ b/indra/win_crash_logger/CMakeLists.txt
@@ -21,6 +21,10 @@ include_directories(
     ${LLXML_INCLUDE_DIRS}
     ${LLVFS_INCLUDE_DIRS}
     )
+include_directories(SYSTEM
+    ${LLCOMMON_SYSTEM_INCLUDE_DIRS}
+    ${LLXML_SYSTEM_INCLUDE_DIRS}
+    )
 
 set(win_crash_logger_SOURCE_FILES
     win_crash_logger.cpp
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index 2cb0a833d4cfd94a926b7f4477be4b4a20cb8059..6702de9b4a7a98eea4dbb7d2ddea0b8c1a6574e7 100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -2939,6 +2939,10 @@ version 2.0
 		PidStat Single
 		{	PID					S32				}
 	}
+	{
+		RegionInfo Variable
+		{	RegionFlagsExtended	U64				}
+	}
 }
 
 // viewer -> sim
@@ -2991,6 +2995,10 @@ version 2.0
 		{	HardMaxAgents		U32			}
 		{	HardMaxObjects		U32			}
 	}
+	{
+		RegionInfo3		Variable
+		{	RegionFlagsExtended	U64			}
+	}
 }
 
 // GodUpdateRegionInfo
@@ -3016,6 +3024,10 @@ version 2.0
 		{	RedirectGridX 		S32			}
 		{	RedirectGridY 		S32			}
 	}
+	{
+		RegionInfo2	Variable
+		{	RegionFlagsExtended	U64			}
+	}
 }
 
 //NearestLandingRegionRequest
@@ -3116,6 +3128,11 @@ version 2.0
 		{	ProductSKU				Variable	1	}	// string
 		{	ProductName				Variable	1	}	// string
 	}
+	{
+		RegionInfo4		Variable
+		{	RegionFlagsExtended	U64			}
+		{	RegionProtocols		U64			}
+	}
 }
 
 // RegionHandshakeReply
@@ -3571,6 +3588,12 @@ version 2.0
 		VisualParam			Variable
 		{	ParamValue		U8	}
 	}
+	{
+		AppearanceData		Variable
+		{	AppearanceVersion	U8	}
+		{	CofVersion			S32	}
+		{	Flags				U32	}
+	}
 }
 
 // AvatarSitResponse - response to a request to sit on an object
diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1
index 6486d92851a7590ef7ba205c7a40390290562e82..7a31177f118ecd39a32866c51b3664e62e8affe6 100644
--- a/scripts/messages/message_template.msg.sha1
+++ b/scripts/messages/message_template.msg.sha1
@@ -1 +1 @@
-465164e1a07f63d68c4ad1f00c19805dfb6ee2d7
\ No newline at end of file
+4dbf88396c3188ad4c54c4f847a7d8817793668d
\ No newline at end of file