diff --git a/.hgtags b/.hgtags
index 9ca419211ea7617e3b753ae43caf3f479115283b..36e5d6442d60f2ed3b663ecf0501180685b130c4 100755
--- a/.hgtags
+++ b/.hgtags
@@ -56,11 +56,11 @@ a82e5b1e22c7f90e3c7977d146b80588f004ed0d 2.5.0-start
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f 2.5.0-beta2
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33--2.5.0beta2
 54d772d8687c69b1d773f6ce14bbc7bdc9d6c05f DRTVWR-33_2.5.0-beta2
+b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-beta3
 b723921b5c711bd24dbe77dc76ef488b544dac78 2.5.0-release
 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-31_2.5.0-release
 b723921b5c711bd24dbe77dc76ef488b544dac78 DRTVWR-34_2.5.0-beta3
-b542f8134a2bb5dd054ff4e509a44b2ee463b1bf nat-eventapi2-base
 63a6aedfce785a6c760377bf685b2dae616797d2 2.5.1-start
 4dede9ae1ec74d41f6887719f6f1de7340d8578d 2.5.1-release
 4dede9ae1ec74d41f6887719f6f1de7340d8578d DRTVWR-37_2.5.1-release
@@ -458,8 +458,8 @@ a314f1c94374ab1f6633dd2983f7090a68663eb2 3.5.2-beta4
 9b1b6f33aa5394b27bb652b31b5cb81ef6060370 3.5.2-release
 a277b841729f2a62ba1e34acacc964bc13c1ad6f 3.5.3-release
 fb1630153bac5552046ea914af3f14deabc1def8 3.6.0-materials-beta1
-69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
-69429d81ae4dd321eda2607901ef0a0fde71b54c 3.6.0-release
 0a56f33ad6aa112032b14a41dad759ad377bdde9 3.6.0-release
 75cf8e855ae1af6895a35da475314c2b5acf1850 3.6.1-release
 f6741d5fe8d632651424484df0fe0cb4a01e9fbe 3.6.2-release
+fe4f7c5e9fd27e09d03deb1cc9ab3e5093f6309e 3.6.3-release
+83357f31d8dbf048a8bfdc323f363bf4d588aca1 CHOP-951-a
diff --git a/BuildParams b/BuildParams
index accc019a72b20b7e5014cfd9471527e64a65b867..327530934d288942111ea437cda3ef7acb3c05d5 100755
--- a/BuildParams
+++ b/BuildParams
@@ -26,6 +26,9 @@ codeticket_since = 3.3.0-release
 Linux.gcc_version = /usr/bin/gcc-4.6
 Linux.cxx_version = /usr/bin/g++-4.6
 
+# Setup default sourceid so Windows can pick up the TeamCity override
+sourceid = ""
+
 ################################################################
 ####      Examples of how to set the viewer_channel         ####
 #
diff --git a/doc/contributions.txt b/doc/contributions.txt
index ebd8e54fe8f0728db75ddb63a1679591266b5ef7..a6d522de2f375083e808f5c1716b28ff00bf15b6 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -175,6 +175,8 @@ Ansariel Hiller
 	STORM-1685
 	STORM-1713
 	STORM-1899
+	MAINT-2368
+	STORM-1931
 Aralara Rajal
 Arare Chantilly
 	CHUIBUG-191
@@ -303,6 +305,8 @@ Ciaran Laval
 Cinder Roxley
     BUG-2326
     STORM-1703
+	STORM-1948
+    STORM-1952
 Clara Young
 Coaldust Numbers
     VWR-1095
@@ -314,6 +318,7 @@ Cron Stardust
 	VWR-10579
 	VWR-25120
 	STORM-1075
+	STORM-1919
 Cypren Christenson
 	STORM-417
 Dante Tucker
@@ -406,6 +411,7 @@ Ganymedes Costagravas
 Geenz Spad
 	STORM-1823
 	STORM-1900
+	STORM-1905
 	NORSPEC-229
 Gene Frostbite
 GeneJ Composer
@@ -481,6 +487,7 @@ Hiro Sommambulist
 Hitomi Tiponi
 	STORM-1741
 	STORM-1862
+	BUG-1067
 Holger Gilruth
 Horatio Freund
 Hoze Menges
@@ -501,6 +508,8 @@ Ima Mechanique
 	STORM-959
 	STORM-1175
 	STORM-1708
+	STORM-1855
+	VWR-20553
 Imnotgoing Sideways
 Inma Rau
 Innula Zenovka
@@ -644,12 +653,16 @@ Jonathan Yap
 	STORM-1793
 	STORM-1810
 	STORM-1877
+	STORM-1892
+	STORM-1894
 	STORM-1860
 	STORM-1852
 	STORM-1870
 	STORM-1872
 	STORM-1858
 	STORM-1862
+	STORM-1918
+	STORM-1953
 	OPEN-161
 Kadah Coba
 	STORM-1060
@@ -688,6 +701,7 @@ Kitty Barnett
 	STORM-800
 	STORM-1001
 	STORM-1175
+	STORM-1905
     VWR-24217
 	STORM-1804
 Kolor Fall
@@ -697,6 +711,7 @@ Kunnis Basiat
 	VWR-82
 	VWR-102
 Lance Corrimal
+	STORM-1910
 	VWR-25269
 Latif Khalifa
 	VWR-5370
@@ -751,9 +766,11 @@ Marianne McCann
 Marine Kelley
     CHUIBUG-134
     STORM-281
+    STORM-1910
 MartinRJ Fayray
     STORM-1844
     STORM-1845
+    STORM-1911
     STORM-1934
 Matthew Anthony
 Matthew Dowd
@@ -1049,6 +1066,7 @@ Satanello Miami
 Satomi Ahn
 	STORM-501
 	STORM-229
+	VWR-20553
 	VWR-24502
 Scrim Pinion
 Scrippy Scofield
@@ -1218,6 +1236,8 @@ Tofu Buzzard
 	STORM-1684
 	STORM-1819
 Tony Kembia
+Tonya Souther
+	STORM-1905
 Torben Trautman
 TouchaHoney Perhaps
 TraductoresAnonimos Alter
diff --git a/indra/cmake/BuildVersion.cmake b/indra/cmake/BuildVersion.cmake
index b9ec8f5266beb054d97c26544b03c294b6ffcfde..af2063ce6d7ad8d2f9d241baec448ec41734df0e 100755
--- a/indra/cmake/BuildVersion.cmake
+++ b/indra/cmake/BuildVersion.cmake
@@ -18,7 +18,7 @@ if (NOT DEFINED VIEWER_SHORT_VERSION) # will be true in indra/, false in indra/n
            find_program(MERCURIAL hg)
            if (DEFINED MERCURIAL)
               execute_process(
-                 COMMAND ${MERCURIAL} log -r tip --template "{p1rev}"
+                 COMMAND ${MERCURIAL} log -r tip --template "{rev}"
                  OUTPUT_VARIABLE VIEWER_VERSION_REVISION
                  OUTPUT_STRIP_TRAILING_WHITESPACE
                  )
diff --git a/indra/cmake/LLAddBuildTest.cmake b/indra/cmake/LLAddBuildTest.cmake
old mode 100755
new mode 100644
diff --git a/indra/lib/python/indra/util/llmanifest.py b/indra/lib/python/indra/util/llmanifest.py
index 9cb830a2dbd1956424cbfb3063f2f6dfcf569ef2..54049b5545bf8ef9dae8321b5ded922b7240228a 100755
--- a/indra/lib/python/indra/util/llmanifest.py
+++ b/indra/lib/python/indra/util/llmanifest.py
@@ -392,11 +392,21 @@ def created_path(self, path):
             raise ManifestError, "Should be something at path " + path
         self.created_paths.append(path)
 
-    def put_in_file(self, contents, dst):
+    def put_in_file(self, contents, dst, src=None):
         # write contents as dst
-        f = open(self.dst_path_of(dst), "wb")
-        f.write(contents)
-        f.close()
+        dst_path = self.dst_path_of(dst)
+        f = open(dst_path, "wb")
+        try:
+            f.write(contents)
+        finally:
+            f.close()
+
+        # Why would we create a file in the destination tree if not to include
+        # it in the installer? The default src=None (plus the fact that the
+        # src param is last) is to preserve backwards compatibility.
+        if src:
+            self.file_list.append([src, dst_path])
+        return dst_path
 
     def replace_in(self, src, dst=None, searchdict={}):
         if dst == None:
diff --git a/indra/llcommon/tests/llprocess_test.cpp b/indra/llcommon/tests/llprocess_test.cpp
index f188865eb004b7395928773dc715461a31aa862a..3e68ef068e5061d2905ee61a04a58d525f965e3d 100755
--- a/indra/llcommon/tests/llprocess_test.cpp
+++ b/indra/llcommon/tests/llprocess_test.cpp
@@ -608,9 +608,6 @@ namespace tut
     void object::test<5>()
     {
         set_test_name("exit(2)");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         PythonProcessLauncher py(get_test_name(),
                                  "import sys\n"
                                  "sys.exit(2)\n");
@@ -622,10 +619,7 @@ namespace tut
     template<> template<>
     void object::test<6>()
     {
-        set_test_name("syntax_error:");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
+        set_test_name("syntax_error");
         PythonProcessLauncher py(get_test_name(),
                                  "syntax_error:\n");
         py.mParams.files.add(LLProcess::FileParam()); // inherit stdin
@@ -647,9 +641,6 @@ namespace tut
     void object::test<7>()
     {
         set_test_name("explicit kill()");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         PythonProcessLauncher py(get_test_name(),
                                  "from __future__ import with_statement\n"
                                  "import sys, time\n"
@@ -694,9 +685,6 @@ namespace tut
     void object::test<8>()
     {
         set_test_name("implicit kill()");
-#if LL_WINDOWS
-		skip("MAINT-2302: This frequently (though not always) fails on Windows.");
-#endif
         NamedTempFile out("out", "not started");
         LLProcess::handle phandle(0);
         {
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 1c25256e9521894a04c7e0b0230932d201f7c84b..c8a05e1faea6e0244ecc03f88c325bc7f5570879 100755
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -689,8 +689,17 @@ void LLImageRaw::fill( const LLColor4U& color )
 	}
 }
 
+LLPointer<LLImageRaw> LLImageRaw::duplicate()
+{
+	if(getNumRefs() < 2)
+	{
+		return this; //nobody else refences to this image, no need to duplicate.
+	}
 
-
+	//make a duplicate
+	LLPointer<LLImageRaw> dup = new LLImageRaw(getData(), getWidth(), getHeight(), getComponents());
+	return dup; 
+}
 
 // Src and dst can be any size.  Src and dst can each have 3 or 4 components.
 void LLImageRaw::copy(LLImageRaw* src)
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 4fc40ecff7703364b950cd7c8cdadd18266c5f3d..2277afc5852b6f21d4e1cc7e5b8bd72ad0ae6501 100755
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -30,6 +30,7 @@
 #include "lluuid.h"
 #include "llstring.h"
 #include "llthread.h"
+#include "llpointer.h"
 
 const S32 MIN_IMAGE_MIP =  2; // 4x4, only used for expand/contract power of 2
 const S32 MAX_IMAGE_MIP = 11; // 2048x2048
@@ -214,6 +215,9 @@ class LLImageRaw : public LLImageBase
 
 	// Copy operations
 	
+	//duplicate this raw image if refCount > 1.
+	LLPointer<LLImageRaw> duplicate();
+
 	// Src and dst can be any size.  Src and dst can each have 3 or 4 components.
 	void copy( LLImageRaw* src );
 
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 22ba26f99b20d178f22fae7c5e4c5589470700e5..33cf185196ad59a496f2812e2cd9eb5bfd553e69 100755
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -42,6 +42,11 @@ LLCamera::LLCamera() :
 	mPlaneCount(6),
 	mFrustumCornerDist(0.f)
 {
+	for (U32 i = 0; i < PLANE_MASK_NUM; i++)
+	{
+		mPlaneMask[i] = PLANE_MASK_NONE;
+	}
+
 	calculateFrustumPlanes();
 } 
 
@@ -52,6 +57,11 @@ LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_p
 	mPlaneCount(6),
 	mFrustumCornerDist(0.f)
 {
+	for (U32 i = 0; i < PLANE_MASK_NUM; i++)
+	{
+		mPlaneMask[i] = PLANE_MASK_NONE;
+	}
+
 	mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
 	mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
 	if(far_plane < 0) far_plane = DEFAULT_FAR_PLANE;
@@ -87,14 +97,14 @@ F32 LLCamera::getMaxView() const
 
 void LLCamera::setUserClipPlane(LLPlane& plane)
 {
-	mPlaneCount = 7;
-	mAgentPlanes[6] = plane;
-	mPlaneMask[6] = plane.calcPlaneMask();
+	mPlaneCount = AGENT_PLANE_USER_CLIP_NUM;
+	mAgentPlanes[AGENT_PLANE_USER_CLIP] = plane;
+	mPlaneMask[AGENT_PLANE_USER_CLIP] = plane.calcPlaneMask();
 }
 
 void LLCamera::disableUserClipPlane()
 {
-	mPlaneCount = 6;
+	mPlaneCount = AGENT_PLANE_NO_USER_CLIP_NUM;
 }
 
 void LLCamera::setView(F32 vertical_fov_rads) 
@@ -161,31 +171,33 @@ size_t LLCamera::readFrustumFromBuffer(const char *buffer)
 
 // ---------------- test methods  ---------------- 
 
-S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius) 
+static	const LLVector4a sFrustumScaler[] = 
 {
-	static const LLVector4a scaler[] = {
-		LLVector4a(-1,-1,-1),
-		LLVector4a( 1,-1,-1),
-		LLVector4a(-1, 1,-1),
-		LLVector4a( 1, 1,-1),
-		LLVector4a(-1,-1, 1),
-		LLVector4a( 1,-1, 1),
-		LLVector4a(-1, 1, 1),
-		LLVector4a( 1, 1, 1)
-	};
+	LLVector4a(-1,-1,-1),
+	LLVector4a( 1,-1,-1),
+	LLVector4a(-1, 1,-1),
+	LLVector4a( 1, 1,-1),
+	LLVector4a(-1,-1, 1),
+	LLVector4a( 1,-1, 1),
+	LLVector4a(-1, 1, 1),
+	LLVector4a( 1, 1, 1)		// 8 entries
+};
 
+S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius) 
+{
 	U8 mask = 0;
 	bool result = false;
 	LLVector4a rscale, maxp, minp;
 	LLSimdScalar d;
-	for (U32 i = 0; i < mPlaneCount; i++)
+	U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);		// mAgentPlanes[] size is 7
+	for (U32 i = 0; i < max_planes; i++)
 	{
 		mask = mPlaneMask[i];
-		if (mask != 0xff)
+		if (mask < PLANE_MASK_NUM)
 		{
 			const LLPlane& p(mAgentPlanes[i]);
 			p.getAt<3>(d);
-			rscale.setMul(radius, scaler[mask]);
+			rscale.setMul(radius, sFrustumScaler[mask]);
 			minp.setSub(center, rscale);
 			d = -d;
 			if (p.dot3(minp).getF32() > d) 
@@ -207,29 +219,19 @@ S32 LLCamera::AABBInFrustum(const LLVector4a &center, const LLVector4a& radius)
 
 S32 LLCamera::AABBInFrustumNoFarClip(const LLVector4a& center, const LLVector4a& radius) 
 {
-	static const LLVector4a scaler[] = {
-		LLVector4a(-1,-1,-1),
-		LLVector4a( 1,-1,-1),
-		LLVector4a(-1, 1,-1),
-		LLVector4a( 1, 1,-1),
-		LLVector4a(-1,-1, 1),
-		LLVector4a( 1,-1, 1),
-		LLVector4a(-1, 1, 1),
-		LLVector4a( 1, 1, 1)
-	};
-
 	U8 mask = 0;
 	bool result = false;
 	LLVector4a rscale, maxp, minp;
 	LLSimdScalar d;
-	for (U32 i = 0; i < mPlaneCount; i++)
+	U32 max_planes = llmin(mPlaneCount, (U32) AGENT_PLANE_USER_CLIP_NUM);		// mAgentPlanes[] size is 7
+	for (U32 i = 0; i < max_planes; i++)
 	{
 		mask = mPlaneMask[i];
-		if ((i != 5) && (mask != 0xff))
+		if ((i != 5) && (mask < PLANE_MASK_NUM))
 		{
 			const LLPlane& p(mAgentPlanes[i]);
 			p.getAt<3>(d);
-			rscale.setMul(radius, scaler[mask]);
+			rscale.setMul(radius, sFrustumScaler[mask]);
 			minp.setSub(center, rscale);
 			d = -d;
 			if (p.dot3(minp).getF32() > d) 
@@ -369,7 +371,7 @@ int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius)
 	bool res = false;
 	for (int i = 0; i < 6; i++)
 	{
-		if (mPlaneMask[i] != 0xff)
+		if (mPlaneMask[i] != PLANE_MASK_NONE)
 		{
 			float d = mAgentPlanes[i].dist(sphere_center);
 
@@ -541,14 +543,14 @@ void LLCamera::ignoreAgentFrustumPlane(S32 idx)
 		return;
 	}
 
-	mPlaneMask[idx] = 0xff;
+	mPlaneMask[idx] = PLANE_MASK_NONE;
 	mAgentPlanes[idx].clear();
 }
 
 void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
 {
 	
-	for (int i = 0; i < 8; i++)
+	for (int i = 0; i < AGENT_FRUSTRUM_NUM; i++)
 	{
 		mAgentFrustum[i] = frust[i];
 	}
@@ -560,22 +562,22 @@ void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
 	//order of planes is important, keep most likely to fail in the front of the list
 
 	//near - frust[0], frust[1], frust[2]
-	mAgentPlanes[2] = planeFromPoints(frust[0], frust[1], frust[2]);
+	mAgentPlanes[AGENT_PLANE_NEAR] = planeFromPoints(frust[0], frust[1], frust[2]);
 
 	//far  
-	mAgentPlanes[5] = planeFromPoints(frust[5], frust[4], frust[6]);
+	mAgentPlanes[AGENT_PLANE_FAR] = planeFromPoints(frust[5], frust[4], frust[6]);
 
 	//left  
-	mAgentPlanes[0] = planeFromPoints(frust[4], frust[0], frust[7]);
+	mAgentPlanes[AGENT_PLANE_LEFT] = planeFromPoints(frust[4], frust[0], frust[7]);
 
 	//right  
-	mAgentPlanes[1] = planeFromPoints(frust[1], frust[5], frust[6]);
+	mAgentPlanes[AGENT_PLANE_RIGHT] = planeFromPoints(frust[1], frust[5], frust[6]);
 
 	//top  
-	mAgentPlanes[4] = planeFromPoints(frust[3], frust[2], frust[6]);
+	mAgentPlanes[AGENT_PLANE_TOP] = planeFromPoints(frust[3], frust[2], frust[6]);
 
 	//bottom  
-	mAgentPlanes[3] = planeFromPoints(frust[1], frust[0], frust[4]);
+	mAgentPlanes[AGENT_PLANE_BOTTOM] = planeFromPoints(frust[1], frust[0], frust[4]);
 
 	//cache plane octant facing mask for use in AABBInFrustum
 	for (U32 i = 0; i < mPlaneCount; i++)
@@ -635,7 +637,7 @@ void LLCamera::calculateWorldFrustumPlanes()
 	LLVector3 center = mOrigin - mXAxis*mNearPlane;
 	mWorldPlanePos = center;
 	LLVector3 pnorm;	
-	for (int p=0; p<4; p++)
+	for (int p = 0; p < PLANE_NUM; p++)
 	{
 		mLocalPlanes[p].getVector3(pnorm);
 		LLVector3 norm = rotateToAbsolute(pnorm);
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 0b591be622e453915809b3e557caeb04310a937c..1283cfb16b63aef6eeebf1570274157046c55e71 100755
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -76,26 +76,39 @@ class LLCamera
 		PLANE_RIGHT = 1,
 		PLANE_BOTTOM = 2,
 		PLANE_TOP = 3,
-		PLANE_NUM = 4
+		PLANE_NUM = 4,
+		PLANE_MASK_NONE = 0xff		// Disable this plane
 	};
 	enum {
 		PLANE_LEFT_MASK = (1<<PLANE_LEFT),
 		PLANE_RIGHT_MASK = (1<<PLANE_RIGHT),
 		PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM),
 		PLANE_TOP_MASK = (1<<PLANE_TOP),
-		PLANE_ALL_MASK = 0xf
+		PLANE_ALL_MASK = 0xf,
 	};
 
 	enum
-	{
+	{	// Indexes to mAgentPlanes[] and mPlaneMask[]
 		AGENT_PLANE_LEFT = 0,
-		AGENT_PLANE_RIGHT,
-		AGENT_PLANE_NEAR,
-		AGENT_PLANE_BOTTOM,
-		AGENT_PLANE_TOP,
-		AGENT_PLANE_FAR,
+		AGENT_PLANE_RIGHT = 1,
+		AGENT_PLANE_NEAR = 2,
+		AGENT_PLANE_BOTTOM = 3,
+		AGENT_PLANE_TOP = 4,
+		AGENT_PLANE_FAR = 5,
+		AGENT_PLANE_USER_CLIP = 6
+	};
+	enum
+	{	// Sizes for mAgentPlanes[].  7th entry is special case for user clip
+		AGENT_PLANE_NO_USER_CLIP_NUM = 6,
+		AGENT_PLANE_USER_CLIP_NUM = 7,
+		PLANE_MASK_NUM = 8			// 7 actually used, 8 is for alignment
 	};
 
+	enum
+	{
+		AGENT_FRUSTRUM_NUM = 8
+	};
+	
 	enum {
 		HORIZ_PLANE_LEFT = 0,
 		HORIZ_PLANE_RIGHT = 1,
@@ -108,15 +121,15 @@ class LLCamera
 	};
 
 private:
-	LL_ALIGN_16(LLPlane mAgentPlanes[7]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
-	U8 mPlaneMask[8];         // 8 for alignment	
+	LL_ALIGN_16(LLPlane mAgentPlanes[AGENT_PLANE_USER_CLIP_NUM]);  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
+	U8 mPlaneMask[PLANE_MASK_NUM];         // 8 for alignment	
 	
 	F32 mView;					// angle between top and bottom frustum planes in radians.
 	F32 mAspect;				// width/height
 	S32 mViewHeightInPixels;	// for ViewHeightInPixels() only
 	F32 mNearPlane;
 	F32 mFarPlane;
-	LL_ALIGN_16(LLPlane mLocalPlanes[4]);
+	LL_ALIGN_16(LLPlane mLocalPlanes[PLANE_NUM]);
 	F32 mFixedDistance;			// Always return this distance, unless < 0
 	LLVector3 mFrustCenter;		// center of frustum and radius squared for ultra-quick exclusion test
 	F32 mFrustRadiusSquared;
@@ -128,7 +141,7 @@ class LLCamera
 
 	LLVector3 mWorldPlanePos;		// Position of World Planes (may be offset from camera)
 public:
-	LLVector3 mAgentFrustum[8];  //8 corners of 6-plane frustum
+	LLVector3 mAgentFrustum[AGENT_FRUSTRUM_NUM];  //8 corners of 6-plane frustum
 	F32	mFrustumCornerDist;		//distance to corner of frustum against far clip plane
 	LLPlane& getAgentPlane(U32 idx) { return mAgentPlanes[idx]; }
 
diff --git a/indra/llmessage/llcurl.cpp b/indra/llmessage/llcurl.cpp
index 47041a2880710e50e201cca400a3e35f44511b0d..f2a3e059ef64e9d7c214b9d6cbf2674c35f9e420 100755
--- a/indra/llmessage/llcurl.cpp
+++ b/indra/llmessage/llcurl.cpp
@@ -72,7 +72,8 @@
 
 static const U32 EASY_HANDLE_POOL_SIZE		= 5;
 static const S32 MULTI_PERFORM_CALL_REPEAT	= 5;
-static const S32 CURL_REQUEST_TIMEOUT = 30; // seconds per operation
+static const S32 CURL_REQUEST_TIMEOUT = 120; // seconds per operation
+static const S32 CURL_CONNECT_TIMEOUT = 30; //seconds to wait for a connection
 static const S32 MAX_ACTIVE_REQUEST_COUNT = 100;
 
 // DEBUG //
@@ -517,6 +518,7 @@ void LLCurl::Easy::prepRequest(const std::string& url,
 	//don't verify host name so urls with scrubbed host names will work (improves DNS performance)
 	setopt(CURLOPT_SSL_VERIFYHOST, 0);
 	setopt(CURLOPT_TIMEOUT, llmax(time_out, CURL_REQUEST_TIMEOUT));
+	setopt(CURLOPT_CONNECTTIMEOUT, CURL_CONNECT_TIMEOUT);
 
 	setoptString(CURLOPT_URL, url);
 
diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp
index 28ed051c5537a606873ecd8db38b48f0efd4f4ae..5ed05e220113a526a0a8ec9dbf56eb456489284c 100755
--- a/indra/llprimitive/llmodel.cpp
+++ b/indra/llprimitive/llmodel.cpp
@@ -628,25 +628,41 @@ LLModel::EModelStatus load_face_from_dom_polygons(std::vector<LLVolumeFace>& fac
 			if (v)
 			{
 				U32 v_idx = idx[j*stride+v_offset]*3;
+				v_idx = llclamp(v_idx, (U32) 0, (U32) v->getCount());
 				vert.getPosition().set(v->get(v_idx),
 								v->get(v_idx+1),
 								v->get(v_idx+2));
 			}
 			
-			if (n)
+			//bounds check n and t lookups because some FBX to DAE converters
+			//use negative indices and empty arrays to indicate data does not exist
+			//for a particular channel
+			if (n && n->getCount() > 0)
 			{
 				U32 n_idx = idx[j*stride+n_offset]*3;
+				n_idx = llclamp(n_idx, (U32) 0, (U32) n->getCount());
 				vert.getNormal().set(n->get(n_idx),
 								n->get(n_idx+1),
 								n->get(n_idx+2));
 			}
+			else
+			{
+				vert.getNormal().clear();
+			}
+
 			
-			if (t)
+			if (t && t->getCount() > 0)
 			{
 				U32 t_idx = idx[j*stride+t_offset]*2;
+				t_idx = llclamp(t_idx, (U32) 0, (U32) t->getCount());
 				vert.mTexCoord.setVec(t->get(t_idx),
 								t->get(t_idx+1));								
 			}
+			else
+			{
+				vert.mTexCoord.clear();
+			}
+
 						
 			verts.push_back(vert);
 		}
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 088ba95b7502a282261c6320c1f64296135cbff0..c3005f1722b2f4677588dba987a09770d6d2bc68 100755
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -1154,7 +1154,8 @@ void LLGLManager::initExtensions()
 	// Misc
 	glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange);
 	glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange);
-	
+	glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize);
+
 #if (LL_WINDOWS || LL_LINUX || LL_SOLARIS) && !LL_MESA_HEADLESS
 	LL_DEBUGS("RenderInit") << "GL Probe: Getting symbols" << LL_ENDL;
 	if (mHasVertexBufferObject)
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 60597fd090943c42d6a8eeaaf38a216eb55aac5a..75e5fe86ec0ce1447b6df43b9fc62c3afe7fa0da 100755
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -155,6 +155,7 @@ class LLGLManager
 	S32 mVRAM; // VRAM in MB
 	S32 mGLMaxVertexRange;
 	S32 mGLMaxIndexRange;
+	S32 mGLMaxTextureSize;
 	
 	void getPixelFormat(); // Get the best pixel format
 
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
old mode 100644
new mode 100755
diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp
index 6e22712b94f8158b3d099c627ba71337156f42b9..d53c37a8475835f5c90add214e8d5ecb036ef3d1 100755
--- a/indra/llrender/llrendertarget.cpp
+++ b/indra/llrender/llrendertarget.cpp
@@ -117,8 +117,8 @@ void LLRenderTarget::resize(U32 resx, U32 resy, U32 color_fmt)
 
 bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, bool stencil, LLTexUnit::eTextureType usage, bool use_fbo, S32 samples)
 {
-	resx = llmin(resx, (U32) 4096);
-	resy = llmin(resy, (U32) 4096);
+	resx = llmin(resx, (U32) gGLManager.mGLMaxTextureSize);
+	resy = llmin(resy, (U32) gGLManager.mGLMaxTextureSize);
 
 	stop_glerror();
 	release();
diff --git a/indra/llui/llfloaterreg.cpp b/indra/llui/llfloaterreg.cpp
index 1cdddf0d5b93e830eabc4776cabcfb26bf3dd6e0..b1b75776a7b43bc56a4dca5d419103b6faced0cb 100755
--- a/indra/llui/llfloaterreg.cpp
+++ b/indra/llui/llfloaterreg.cpp
@@ -356,8 +356,8 @@ std::string LLFloaterReg::declareRectControl(const std::string& name)
 {
 	std::string controlname = getRectControlName(name);
 	LLFloater::getControlGroup()->declareRect(controlname, LLRect(),
-												 llformat("Window Size for %s", name.c_str()),
-												 TRUE);
+											  llformat("Window Size for %s", name.c_str()),
+											  LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -367,7 +367,7 @@ std::string LLFloaterReg::declarePosXControl(const std::string& name)
 	LLFloater::getControlGroup()->declareF32(controlname, 
 											10.f,
 											llformat("Window X Position for %s", name.c_str()),
-											TRUE);
+											LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -377,7 +377,7 @@ std::string LLFloaterReg::declarePosYControl(const std::string& name)
 	LLFloater::getControlGroup()->declareF32(controlname,
 											10.f,
 											llformat("Window Y Position for %s", name.c_str()),
-											TRUE);
+											LLControlVariable::PERSIST_NONDFT);
 
 	return controlname;
 }
@@ -404,7 +404,7 @@ std::string LLFloaterReg::declareVisibilityControl(const std::string& name)
 	std::string controlname = getVisibilityControlName(name);
 	LLFloater::getControlGroup()->declareBOOL(controlname, FALSE,
 												 llformat("Window Visibility for %s", name.c_str()),
-												 TRUE);
+												 LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 }
 
@@ -414,7 +414,7 @@ std::string LLFloaterReg::declareDockStateControl(const std::string& name)
 	std::string controlname = getDockStateControlName(name);
 	LLFloater::getControlGroup()->declareBOOL(controlname, TRUE,
 												 llformat("Window Docking state for %s", name.c_str()),
-												 TRUE);
+												 LLControlVariable::PERSIST_NONDFT);
 	return controlname;
 
 }
diff --git a/indra/llui/llnotifications.cpp b/indra/llui/llnotifications.cpp
index 1789f003b91ecd843aba930d724b22e4184e4f48..a1853ca1f787de02aec6216015af041244c3d0d2 100755
--- a/indra/llui/llnotifications.cpp
+++ b/indra/llui/llnotifications.cpp
@@ -214,7 +214,7 @@ LLNotificationForm::LLNotificationForm(const std::string& name, const LLNotifica
 		}
 		else
 		{
-			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", TRUE);
+			LLUI::sSettingGroups["ignores"]->declareBOOL(name, show_notification, "Show notification with this name", LLControlVariable::PERSIST_NONDFT);
 			mIgnoreSetting = LLUI::sSettingGroups["ignores"]->getControl(name);
 		}
 	}
diff --git a/indra/llui/llscrolllistcolumn.cpp b/indra/llui/llscrolllistcolumn.cpp
index af124d9826a5cc335ef4f6519b4e7cfeab5f2105..cc9ff7a487d60c4dc8ee28d4778ea10b9ccb5f30 100755
--- a/indra/llui/llscrolllistcolumn.cpp
+++ b/indra/llui/llscrolllistcolumn.cpp
@@ -236,7 +236,8 @@ void LLScrollColumnHeader::handleReshape(const LLRect& new_rect, bool by_user)
 		// tell scroll list to layout columns again
 		// do immediate update to get proper feedback to resize handle
 		// which needs to know how far the resize actually went
-		mColumn->mParentCtrl->updateColumns();
+		const bool force_update = true;
+		mColumn->mParentCtrl->updateColumns(force_update);
 	}
 }
 
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 40f828ed470609b6ecdaa4ce7a80f74eecf4eb26..6e03f604a2f05de05660aae67b6b981205af427d 100755
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -615,7 +615,6 @@ S32 LLScrollListCtrl::calcMaxContentWidth()
 
 		if (mColumnWidthsDirty)
 		{
-			mColumnWidthsDirty = false;
 			// update max content width for this column, by looking at all items
 			column->mMaxContentWidth = column->mHeader ? LLFontGL::getFontSansSerifSmall()->getWidth(column->mLabel) + mColumnPadding + HEADING_TEXT_PADDING : 0;
 			item_list::iterator iter;
@@ -629,6 +628,7 @@ S32 LLScrollListCtrl::calcMaxContentWidth()
 		}
 		max_item_width += column->mMaxContentWidth;
 	}
+	mColumnWidthsDirty = false;
 
 	return max_item_width;
 }
@@ -643,7 +643,7 @@ bool LLScrollListCtrl::updateColumnWidths()
 		if (!column) continue;
 
 		// update column width
-		S32 new_width = column->getWidth();
+		S32 new_width = 0;
 		if (column->mRelWidth >= 0)
 		{
 			new_width = (S32)llround(column->mRelWidth*mItemListRect.getWidth());
@@ -652,6 +652,10 @@ bool LLScrollListCtrl::updateColumnWidths()
 		{
 			new_width = (mItemListRect.getWidth() - mTotalStaticColumnWidth - mTotalColumnPadding) / mNumDynamicWidthColumns;
 		}
+		else
+		{
+			new_width = column->getWidth();
+		}
 
 		if (column->getWidth() != new_width)
 		{
@@ -693,9 +697,9 @@ void LLScrollListCtrl::updateLineHeightInsert(LLScrollListItem* itemp)
 }
 
 
-void LLScrollListCtrl::updateColumns()
+void LLScrollListCtrl::updateColumns(bool force_update)
 {
-	if (!mColumnsDirty)
+	if (!mColumnsDirty && !force_update)
 		return;
 
 	mColumnsDirty = false;
@@ -749,7 +753,7 @@ void LLScrollListCtrl::updateColumns()
 	}
 
 	// propagate column widths to individual cells
-	if (columns_changed_width)
+	if (columns_changed_width || force_update)
 	{
 		item_list::iterator iter;
 		for (iter = mItemList.begin(); iter != mItemList.end(); iter++)
diff --git a/indra/llui/llscrolllistctrl.h b/indra/llui/llscrolllistctrl.h
index 9b361c39d704d9ee769a38b94074b5ab6e6f5996..c61e281a31ec61d21b38aa352e6f2b46ca4cee97 100755
--- a/indra/llui/llscrolllistctrl.h
+++ b/indra/llui/llscrolllistctrl.h
@@ -342,7 +342,7 @@ class LLScrollListCtrl : public LLUICtrl, public LLEditMenuHandler,
 
 	static void onClickColumn(void *userdata);
 
-	virtual void updateColumns();
+	virtual void updateColumns(bool force_update = false);
 	S32 calcMaxContentWidth();
 	bool updateColumnWidths();
 
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index d1c4bcb24bf872167b00fb0c4799fbf97774b84b..0c16e06109fbd51b21eea8484785201adcc9d978 100755
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -1125,7 +1125,8 @@ void LLTextEditor::addChar(llwchar wc)
 	}
 }
 
-void LLTextEditor::addLineBreakChar()
+
+void LLTextEditor::addLineBreakChar(BOOL group_together)
 {
 	if( !getEnabled() )
 	{
@@ -1143,7 +1144,7 @@ void LLTextEditor::addLineBreakChar()
 	LLStyleConstSP sp(new LLStyle(LLStyle::Params()));
 	LLTextSegmentPtr segment = new LLLineBreakTextSegment(sp, mCursorPos);
 
-	S32 pos = execute(new TextCmdAddChar(mCursorPos, FALSE, '\n', segment));
+	S32 pos = execute(new TextCmdAddChar(mCursorPos, group_together, '\n', segment));
 	
 	setCursorPos(mCursorPos + pos);
 }
@@ -1484,21 +1485,28 @@ void LLTextEditor::pasteTextWithLinebreaks(LLWString & clean_string)
 	std::basic_string<llwchar>::size_type start = 0;
 	std::basic_string<llwchar>::size_type pos = clean_string.find('\n',start);
 	
-	while(pos!=-1)
+	while((pos != -1) && (pos != clean_string.length() -1))
 	{
 		if(pos!=start)
 		{
 			std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,pos-start);
-			setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+			setCursorPos(mCursorPos + insert(mCursorPos, str, TRUE, LLTextSegmentPtr()));
 		}
-		addLineBreakChar();
-		
+		addLineBreakChar(TRUE);			// Add a line break and group with the next addition.
+
 		start = pos+1;
 		pos = clean_string.find('\n',start);
 	}
 
-	std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
-	setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+	if (pos != start)
+	{
+		std::basic_string<llwchar> str = std::basic_string<llwchar>(clean_string,start,clean_string.length()-start);
+		setCursorPos(mCursorPos + insert(mCursorPos, str, FALSE, LLTextSegmentPtr()));
+	}
+	else
+	{
+		addLineBreakChar(FALSE);		// Add a line break and end the grouping.
+	}
 }
 
 // copy selection to primary
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 13f63a17effcf0ac14c200f5294057c21a5d25b9..32b543ec0e3439380847c001ee18f4cefb3dece0 100755
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -248,7 +248,7 @@ class LLTextEditor :
 	// Undoable operations
 	void			addChar(llwchar c); // at mCursorPos
 	S32				addChar(S32 pos, llwchar wc);
-	void			addLineBreakChar();
+	void			addLineBreakChar(BOOL group_together = FALSE);
 	S32				overwriteChar(S32 pos, llwchar wc);
 	void			removeChar();
 	S32 			removeChar(S32 pos);
diff --git a/indra/llvfs/lldir.h b/indra/llvfs/lldir.h
index cc10ed5bbd02501f5da65037a4a8f735ab16404f..e02bf552aadccfd7b38dc83f26346cf7a18f04bb 100755
--- a/indra/llvfs/lldir.h
+++ b/indra/llvfs/lldir.h
@@ -32,7 +32,7 @@
 #define MAX_PATH MAXPATHLEN
 #endif
 
-// these numbers *may* get serialized (really??), so we need to be explicit
+// these numbers are read from settings_files.xml, so we need to be explicit
 typedef enum ELLPath
 {
 	LL_PATH_NONE = 0,
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index 666c03e9fffc89295d0549544d0c3c18e9382104..16f22907872f01a7b3fbedc454716285145ee665 100755
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -132,14 +132,14 @@ bool LLControlVariable::llsd_compare(const LLSD& a, const LLSD & b)
 
 LLControlVariable::LLControlVariable(const std::string& name, eControlType type,
 							 LLSD initial, const std::string& comment,
-							 bool persist, bool hidefromsettingseditor)
+							 ePersist persist, bool hidefromsettingseditor)
 	: mName(name),
 	  mComment(comment),
 	  mType(type),
 	  mPersist(persist),
 	  mHideFromSettingsEditor(hidefromsettingseditor)
 {
-	if (mPersist && mComment.empty())
+	if ((persist != PERSIST_NO) && mComment.empty())
 	{
 		llerrs << "Must supply a comment for control " << mName << llendl;
 	}
@@ -260,7 +260,7 @@ void LLControlVariable::setDefaultValue(const LLSD& value)
 	}
 }
 
-void LLControlVariable::setPersist(bool state)
+void LLControlVariable::setPersist(ePersist state)
 {
 	mPersist = state;
 }
@@ -292,10 +292,29 @@ void LLControlVariable::resetToDefault(bool fire_signal)
 	}
 }
 
-bool LLControlVariable::isSaveValueDefault()
-{ 
-    return (mValues.size() ==  1) 
-        || ((mValues.size() > 1) && llsd_compare(mValues[1], mValues[0]));
+bool LLControlVariable::shouldSave(bool nondefault_only)
+{
+	// This method is used to decide whether we should save a given
+	// variable. Two of the three values of mPersist are easy.
+	if (mPersist == PERSIST_NO)
+		return false;
+
+	if (mPersist == PERSIST_ALWAYS)
+		return true;
+
+	// PERSIST_NONDFT
+	// If caller doesn't need us to filter, just save.
+	if (! nondefault_only)
+		return true;
+
+	// PERSIST_NONDFT: caller only wants us to save this variable if its value
+	// differs from default.
+	if (isDefault())                // never been altered
+		return false;
+
+	// We've set at least one other value: compare it to default. Save only if
+	// they differ.
+	return ! llsd_compare(getSaveValue(), getDefault());
 }
 
 LLSD LLControlVariable::getSaveValue() const
@@ -355,12 +374,12 @@ std::string LLControlGroup::typeEnumToString(eControlType typeenum)
 	return mTypeString[typeenum];
 }
 
-BOOL LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor)
+LLControlVariable* LLControlGroup::declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor)
 {
 	LLControlVariable* existing_control = getControl(name);
 	if (existing_control)
  	{
-		if (persist && existing_control->isType(type))
+		if ((persist != LLControlVariable::PERSIST_NO) && existing_control->isType(type))
 		{
 			if (!existing_control->llsd_compare(existing_control->getDefault(), initial_val))
 			{
@@ -374,66 +393,66 @@ BOOL LLControlGroup::declareControl(const std::string& name, eControlType type,
 		{
 			llwarns << "Control named " << name << " already exists, ignoring new declaration." << llendl;
 		}
- 		return TRUE;
+ 		return existing_control;
 	}
 
 	// if not, create the control and add it to the name table
 	LLControlVariable* control = new LLControlVariable(name, type, initial_val, comment, persist, hidefromsettingseditor);
 	mNameTable[name] = control;	
-	return TRUE;
+	return control;
 }
 
-BOOL LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, const U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_U32, (LLSD::Integer) initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareS32(const std::string& name, const S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_S32, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareF32(const std::string& name, const F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_F32, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, const BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_BOOLEAN, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string& initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_STRING, initial_val, comment, persist);
 }
 
-BOOL LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3(const std::string& name, const LLVector3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_VEC3, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_VEC3D, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	return declareControl(name, TYPE_RECT, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_COL4, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_COL3, initial_val.getValue(), comment, persist);
 }
 
-BOOL LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist )
+LLControlVariable* LLControlGroup::declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist )
 {
 	return declareControl(name, TYPE_LLSD, initial_val, comment, persist);
 }
@@ -664,11 +683,11 @@ U32 LLControlGroup::loadFromFileLegacy(const std::string& filename, BOOL require
 			switch(declare_as)
 			{
 			case TYPE_COL4:
-				declareColor4(name, LLColor4::white, LLStringUtil::null, NO_PERSIST);
+				declareColor4(name, LLColor4::white, LLStringUtil::null, LLControlVariable::PERSIST_NO);
 				break;
 			case TYPE_STRING:
 			default:
-				declareString(name, LLStringUtil::null, LLStringUtil::null, NO_PERSIST);
+				declareString(name, LLStringUtil::null, LLStringUtil::null, LLControlVariable::PERSIST_NO);
 				break;
 			}
 		}
@@ -805,21 +824,12 @@ U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only
 		{
 			llwarns << "Tried to save invalid control: " << iter->first << llendl;
 		}
-
-		if( control && control->isPersisted() )
+		else if( control->shouldSave(nondefault_only) )
 		{
-			if (!(nondefault_only && (control->isSaveValueDefault())))
-			{
-				settings[iter->first]["Type"] = typeEnumToString(control->type());
-				settings[iter->first]["Comment"] = control->getComment();
-				settings[iter->first]["Value"] = control->getSaveValue();
-				++num_saved;
-			}
-			else
-			{
-				// Debug spam
-				// llinfos << "Skipping " << control->getName() << llendl;
-			}
+			settings[iter->first]["Type"] = typeEnumToString(control->type());
+			settings[iter->first]["Comment"] = control->getComment();
+			settings[iter->first]["Value"] = control->getSaveValue();
+			++num_saved;
 		}
 	}
 	llofstream file;
@@ -862,13 +872,14 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 	
 	for(LLSD::map_const_iterator itr = settings.beginMap(); itr != settings.endMap(); ++itr)
 	{
-		bool persist = true;
+		LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT;
 		std::string const & name = itr->first;
 		LLSD const & control_map = itr->second;
 		
 		if(control_map.has("Persist")) 
 		{
-			persist = control_map["Persist"].asInteger();
+			persist = control_map["Persist"].asInteger()?
+					  LLControlVariable::PERSIST_NONDFT : LLControlVariable::PERSIST_NO;
 		}
 		
 		// Sometimes we want to use the settings system to provide cheap persistence, but we
@@ -887,6 +898,8 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		LLControlVariable* existing_control = getControl(name);
 		if(existing_control)
 		{
+			// set_default_values is true when we're loading the initial,
+			// immutable files from app_settings, e.g. settings.xml.
 			if(set_default_values)
 			{
 				// Override all previously set properties of this control.
@@ -908,6 +921,9 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 			}
 			else if(existing_control->isPersisted())
 			{
+				// save_values is specifically false for (e.g.)
+				// SessionSettingsFile and UserSessionSettingsFile -- in other
+				// words, for a file that's supposed to be transient.
 				existing_control->setValue(control_map["Value"], save_values);
 			}
 			// *NOTE: If not persisted and not setting defaults, 
@@ -915,6 +931,39 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 		}
 		else
 		{
+			// We've never seen this control before. Either we're loading up
+			// the initial set of default settings files (set_default_values)
+			// -- or we're loading user settings last saved by a viewer that
+			// supports a superset of the variables we know.
+			// CHOP-962: if we're loading an unrecognized user setting, make
+			// sure we save it later. If you try an experimental viewer, tweak
+			// a new setting, briefly revert to an old viewer, then return to
+			// the new one, we don't want the old viewer to discard the
+			// setting you changed.
+			if (! set_default_values)
+			{
+				// Using PERSIST_ALWAYS insists that saveToFile() (which calls
+				// LLControlVariable::shouldSave()) must save this control
+				// variable regardless of its value. We can safely set this
+				// LLControlVariable persistent because the 'persistent' flag
+				// is not itself persisted!
+				persist = LLControlVariable::PERSIST_ALWAYS;
+				// We want to mention unrecognized user settings variables
+				// (e.g. from a newer version of the viewer) in the log. But
+				// we also arrive here for Boolean variables generated by
+				// the notifications subsystem when the user checks "Don't
+				// show me this again." These aren't declared in settings.xml;
+				// they're actually named for the notification they suppress.
+				// We don't want to mention those. Apologies, this is a bit of
+				// a hack: we happen to know that user settings go into an
+				// LLControlGroup whose name is "Global".
+				if (getKey() == "Global")
+				{
+					LL_INFOS("LLControlGroup") << "preserving unrecognized " << getKey()
+											   << " settings variable " << name << LL_ENDL;
+				}
+			}
+
 			declareControl(name, 
 						   typeStringToEnum(control_map["Type"].asString()), 
 						   control_map["Value"], 
@@ -923,7 +972,7 @@ U32 LLControlGroup::loadFromFile(const std::string& filename, bool set_default_v
 						   hidefromsettingseditor
 						   );
 		}
-		
+
 		++validitems;
 	}
 
diff --git a/indra/llxml/llcontrol.h b/indra/llxml/llcontrol.h
index ee7d1d50b7e1de8cb81e372330c9de128fda49ec..e1f9be80ddad26d909449b0a6300f4d50c08b553 100755
--- a/indra/llxml/llcontrol.h
+++ b/indra/llxml/llcontrol.h
@@ -72,8 +72,6 @@ class LLVector3d;
 class LLColor4;
 class LLColor3;
 
-const BOOL NO_PERSIST = FALSE;
-
 typedef enum e_control_type
 {
 	TYPE_U32 = 0,
@@ -100,21 +98,28 @@ class LLControlVariable : public LLRefCount
 	typedef boost::signals2::signal<bool(LLControlVariable* control, const LLSD&), boost_boolean_combiner> validate_signal_t;
 	typedef boost::signals2::signal<void(LLControlVariable* control, const LLSD&, const LLSD&)> commit_signal_t;
 
+	enum ePersist
+	{
+		PERSIST_NO,                 // don't save this var
+		PERSIST_NONDFT,             // save this var if differs from default
+		PERSIST_ALWAYS              // save this var even if has default value
+	};
+
 private:
 	std::string		mName;
 	std::string		mComment;
 	eControlType	mType;
-	bool			mPersist;
+	ePersist		mPersist;
 	bool			mHideFromSettingsEditor;
 	std::vector<LLSD> mValues;
-	
+
 	commit_signal_t mCommitSignal;
 	validate_signal_t mValidateSignal;
 	
 public:
 	LLControlVariable(const std::string& name, eControlType type,
 					  LLSD initial, const std::string& comment,
-					  bool persist = true, bool hidefromsettingseditor = false);
+					  ePersist persist = PERSIST_NONDFT, bool hidefromsettingseditor = false);
 
 	virtual ~LLControlVariable();
 	
@@ -131,8 +136,8 @@ class LLControlVariable : public LLRefCount
 	validate_signal_t* getValidateSignal() { return &mValidateSignal; }
 
 	bool isDefault() { return (mValues.size() == 1); }
-	bool isSaveValueDefault();
-	bool isPersisted() { return mPersist; }
+	bool shouldSave(bool nondefault_only);
+	bool isPersisted() { return mPersist != PERSIST_NO; }
 	bool isHiddenFromSettingsEditor() { return mHideFromSettingsEditor; }
 	LLSD get()			const	{ return getValue(); }
 	LLSD getValue()		const	{ return mValues.back(); }
@@ -142,7 +147,7 @@ class LLControlVariable : public LLRefCount
 	void set(const LLSD& val)	{ setValue(val); }
 	void setValue(const LLSD& value, bool saved_value = TRUE);
 	void setDefaultValue(const LLSD& value);
-	void setPersist(bool state);
+	void setPersist(ePersist);
 	void setHiddenFromSettingsEditor(bool hide);
 	void setComment(const std::string& comment);
 
@@ -207,19 +212,19 @@ class LLControlGroup : public LLInstanceTracker<LLControlGroup, std::string>
 		virtual void apply(const std::string& name, LLControlVariable* control) = 0;
 	};
 	void applyToAll(ApplyFunctor* func);
-	
-	BOOL declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, BOOL persist, BOOL hidefromsettingseditor = FALSE);
-	BOOL declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareS32(const std::string& name, S32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareF32(const std::string& name, F32 initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  BOOL persist = TRUE);
-	BOOL declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, BOOL persist = TRUE);
-	BOOL declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, BOOL persist = TRUE);
+
+	LLControlVariable* declareControl(const std::string& name, eControlType type, const LLSD initial_val, const std::string& comment, LLControlVariable::ePersist persist, BOOL hidefromsettingseditor = FALSE);
+	LLControlVariable* declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareS32(const std::string& name, S32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareF32(const std::string& name, F32 initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareVec3(const std::string& name, const LLVector3 &initial_val,const std::string& comment,  LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareVec3d(const std::string& name, const LLVector3d &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareRect(const std::string& name, const LLRect &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareColor4(const std::string& name, const LLColor4 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareColor3(const std::string& name, const LLColor3 &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
+	LLControlVariable* declareLLSD(const std::string& name, const LLSD &initial_val, const std::string& comment, LLControlVariable::ePersist persist = LLControlVariable::PERSIST_NONDFT);
 
 	std::string getString(const std::string& name);
 	std::string getText(const std::string& name);
@@ -368,7 +373,7 @@ class LLControlCache : public LLRefCount, public LLInstanceTracker<LLControlCach
 		init_value = convert_to_llsd(default_value);
 		if(type < TYPE_COUNT)
 		{
-			group.declareControl(name, type, init_value, comment, FALSE);
+			group.declareControl(name, type, init_value, comment, LLControlVariable::PERSIST_NO);
 			return true;
 		}
 		return false;
diff --git a/indra/llxml/tests/llcontrol_test.cpp b/indra/llxml/tests/llcontrol_test.cpp
index ede81956ec6879b896ba09be308211f1b002fc67..c273773c9b43a9223dfc43fc7dba44bb76f67934 100755
--- a/indra/llxml/tests/llcontrol_test.cpp
+++ b/indra/llxml/tests/llcontrol_test.cpp
@@ -128,7 +128,11 @@ namespace tut
 	template<> template<>
 	void control_group_t::test<3>()
 	{
-		int results = mCG->loadFromFile(mTestConfigFile.c_str());
+		// Pass default_values = true. This tells loadFromFile() we're loading
+		// a default settings file that declares variables, rather than a user
+		// settings file. When loadFromFile() encounters an unrecognized user
+		// settings variable, it forcibly preserves it (CHOP-962).
+		int results = mCG->loadFromFile(mTestConfigFile.c_str(), true);
 		LLControlVariable* control = mCG->getControl("TestSetting");
 		LLSD new_value = 13;
 		control->setValue(new_value, FALSE);
diff --git a/indra/lscript/lscript_compile/indra.l b/indra/lscript/lscript_compile/indra.l
index 1bb38bbf655f5c3313db95b81055e6cb52b2a2eb..1c9f50202d8fbf07088219cf42af4a9aefe16d5b 100755
--- a/indra/lscript/lscript_compile/indra.l
+++ b/indra/lscript/lscript_compile/indra.l
@@ -336,6 +336,8 @@ int yyerror(const char *fmt, ...);
 "ATTACH_HUD_BOTTOM_LEFT" { count(); yylval.ival = 36; return(INTEGER_CONSTANT); }
 "ATTACH_HUD_BOTTOM"		{ count(); yylval.ival = 37; return(INTEGER_CONSTANT); }
 "ATTACH_HUD_BOTTOM_RIGHT"	{ count(); yylval.ival = 38; return(INTEGER_CONSTANT); }
+"ATTACH_NECK"   { count(); yylval.ival = 39; return(INTEGER_CONSTANT); }
+"ATTACH_AVATAR_CENTER"   { count(); yylval.ival = 40; return(INTEGER_CONSTANT); }
 
 "LAND_LEVEL"		{ count(); yylval.ival = E_LANDBRUSH_LEVEL; return(INTEGER_CONSTANT); }
 "LAND_RAISE"		{ count(); yylval.ival = E_LANDBRUSH_RAISE; return(INTEGER_CONSTANT); }
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 89add3e21f776cac6682af572fc9bdb5bfe95a52..e2ae7a5a9af1e64abdb98c8e7d23ce7badcb1f47 100755
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -229,6 +229,7 @@ set(viewer_SOURCE_FILES
     llfloaterfonttest.cpp
     llfloatergesture.cpp
     llfloatergodtools.cpp
+    llfloatergotoline.cpp
     llfloatergroupinvite.cpp
     llfloatergroups.cpp
     llfloaterhandler.cpp
@@ -812,6 +813,7 @@ set(viewer_HEADER_FILES
     llfloaterfonttest.h
     llfloatergesture.h
     llfloatergodtools.h
+    llfloatergotoline.h
     llfloatergroupinvite.h
     llfloatergroups.h
     llfloaterhandler.h
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index 4a788a01dad42913228f213ad78fbb1fb8cb0928..0f44168a4d54427731b95473ed03e4730fe645b6 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-3.6.3
+3.6.4
diff --git a/indra/newview/app_settings/cmd_line.xml b/indra/newview/app_settings/cmd_line.xml
index 7ab7787d77c874b1b3d075001e3e621023a45664..a9f6079630342966ea96a365eb43079bf9e55f1c 100755
--- a/indra/newview/app_settings/cmd_line.xml
+++ b/indra/newview/app_settings/cmd_line.xml
@@ -22,7 +22,8 @@
     <map>
       <key>count</key>
       <integer>1</integer>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineChannel</string>
     </map>
 
     <key>console</key>
@@ -96,6 +97,8 @@
 0 - low, 1 - medium, 2 - high, 3 - ultra</string>
       <key>count</key>
       <integer>1</integer>
+      <key>map-to</key>
+      <string>RenderQualityPerformance</string>
     </map>
 
     <key>grid</key>
@@ -108,6 +111,16 @@
       <string>CmdLineGridChoice</string>
     </map>
 
+    <key>update-service</key>
+    <map>
+      <key>desc</key>
+      <string>Override the url base for the update query.</string>
+      <key>count</key>
+      <integer>1</integer>
+      <key>map-to</key>
+      <string>CmdLineUpdateService</string>
+    </map>
+
     <key>help</key>
     <map>
       <key>desc</key>
@@ -370,7 +383,8 @@
       <boolean>true</boolean>
       <key>last_option</key>
       <boolean>true</boolean>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineLoginLocation</string>
     </map>
 
     <key>url</key>
@@ -381,7 +395,8 @@
       <integer>1</integer>
       <key>last_option</key>
       <boolean>true</boolean>
-      <!-- Special case. Not mapped to a setting. -->
+      <key>map-to</key>
+      <string>CmdLineLoginLocation</string>
     </map>
 
     <key>usersessionsettings</key>
diff --git a/indra/newview/app_settings/keywords.ini b/indra/newview/app_settings/keywords.ini
index f0d8b77afd8ea7748cfa6abb687f25a1d0a72261..a87310955fa929d2952741f27a903971398779e9 100755
--- a/indra/newview/app_settings/keywords.ini
+++ b/indra/newview/app_settings/keywords.ini
@@ -274,7 +274,8 @@ ATTACH_LLLEG		Passed to llAttachToAvatar to attach task to left lower leg
 ATTACH_BELLY		Passed to llAttachToAvatar to attach task to belly
 ATTACH_LEFT_PEC		Passed to llAttachToAvatar to attach task to left pectoral
 ATTACH_RIGHT_PEC	Passed to llAttachToAvatar to attach task to right pectoral
-
+ATTACH_NECK			Passed to llAttachToAvatar to attach task to neck
+ATTACH_AVATAR_CENTER	Passed to llAttachToAvatar to attach task to avatar center
 LAND_LEVEL			Passed to llModifyLand to level terrain
 LAND_RAISE			Passed to llModifyLand to raise terrain
 LAND_LOWER			Passed to llModifyLand to lower terrain
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 515199604bb5c841b0b91da0a7baced054f1539b..72fe21cf14be78b8d82f77bf2ed220082c78e8d0 100755
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -126,6 +126,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>AnalyzePerformance</key>
+    <map>
+      <key>Comment</key>
+      <string>Request performance analysis for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>AnimateTextures</key>
     <map>
       <key>Comment</key>
@@ -1738,6 +1749,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>CmdLineChannel</key>
+    <map>
+      <key>Comment</key>
+      <string>Command line specified channel name</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>CmdLineDisableVoice</key>
     <map>
       <key>Comment</key>
@@ -1760,6 +1782,17 @@
       <key>Value</key>
       <string />
     </map>
+    <key>CmdLineUpdateService</key>
+    <map>
+      <key>Comment</key>
+      <string>Override the url base for the update query.</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string />
+    </map>
     <key>CmdLineHelperURI</key>
     <map>
       <key>Comment</key>
@@ -1784,6 +1817,17 @@
         <string />
       </array>
     </map>
+    <key>CmdLineLoginLocation</key>
+    <map>
+      <key>Comment</key>
+      <string>Startup destination requested on command line</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string/>
+    </map>
     <key>ConnectAsGod</key>
     <map>
       <key>Comment</key>
@@ -1916,6 +1960,17 @@
       <key>Value</key>
       <integer>262144</integer>
     </map>
+    <key>CrashOnStartup</key>
+    <map>
+      <key>Comment</key>
+      <string>User-requested crash on viewer startup</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>CreateToolCopyCenters</key>
     <map>
       <key>Comment</key>
@@ -2158,6 +2213,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DebugSession</key>
+    <map>
+      <key>Comment</key>
+      <string>Request debugging for a particular viewer session</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DebugShowColor</key>
     <map>
       <key>Comment</key>
@@ -2972,6 +3038,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>DisableCrashLogger</key>
+    <map>
+      <key>Comment</key>
+      <string>Do not send crash report to Linden server</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>DisableMouseWarp</key>
     <map>
       <key>Comment</key>
@@ -5228,6 +5305,28 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LogMetrics</key>
+    <map>
+      <key>Comment</key>
+      <string>Log viewer metrics</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string/>
+    </map>
+    <key>LogPerformance</key>
+    <map>
+      <key>Comment</key>
+      <string>Log performance analysis for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>LogTextureNetworkTraffic</key>
     <map>
       <key>Comment</key>
@@ -6405,6 +6504,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>NoQuickTime</key>
+    <map>
+      <key>Comment</key>
+      <string>Disable QuickTime for a particular viewer run</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>NoVerifySSLCert</key>
     <map>
       <key>Comment</key>
@@ -7027,6 +7137,17 @@
       <key>Value</key>
       <real>90.0</real>
     </map>
+    <key>PlayChatAnim</key>
+    <map>
+      <key>Comment</key>
+      <string>Your avatar plays the chat animation whenever you say, shout or whisper something in nearby chat</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>PlayTypingAnim</key>
     <map>
       <key>Comment</key>
@@ -8552,6 +8673,18 @@
     <integer>0</integer>
   </map>
 
+  <key>RenderDepthOfFieldInEditMode</key>
+  <map>
+    <key>Comment</key>
+    <string>Whether to use depth of field effect when in edit mode</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Boolean</string>
+    <key>Value</key>
+    <integer>0</integer>
+  </map>
+
   <key>CameraDoFResScale</key>
   <map>
     <key>Comment</key>
@@ -9748,6 +9881,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>ReplaySession</key>
+    <map>
+      <key>Comment</key>
+      <string>Request replay of previously-recorded pilot file</string>
+      <key>Persist</key>
+      <integer>0</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>RotateRight</key>
     <map>
       <key>Comment</key>
@@ -12964,12 +13108,13 @@
     <key>UserLoginInfo</key>
     <map>
       <key>Comment</key>
-      <string>Users loging data.</string>
+      <string>User login data.</string>
       <key>Persist</key>
       <integer>1</integer>
       <key>Type</key>
       <string>LLSD</string>
       <key>Value</key>
+      <string/>
     </map>
     <key>VFSOldSize</key>
     <map>
diff --git a/indra/newview/app_settings/settings_files.xml b/indra/newview/app_settings/settings_files.xml
index bfc09286e39abd63cadb21d20bf4928230fa690b..4a9e522a96dd036cef7e29b96580d390bb02f539 100755
--- a/indra/newview/app_settings/settings_files.xml
+++ b/indra/newview/app_settings/settings_files.xml
@@ -4,6 +4,9 @@
     <file name="Global"
           file_name="settings.xml"
           required="true"/>
+    <file name="Global"
+          file_name="settings_install.xml"
+          required="false"/>
     <file name="PerAccount"
           file_name="settings_per_account.xml"
           required="true"/>
diff --git a/indra/newview/app_settings/settings_minimal.xml b/indra/newview/app_settings/settings_minimal.xml
index 01a70f267132f34bfe0cae54c55a46627b5efb44..e660c1a33b060c29d5d7f7771aea4e8e3a7d5b5b 100755
--- a/indra/newview/app_settings/settings_minimal.xml
+++ b/indra/newview/app_settings/settings_minimal.xml
@@ -1 +1,4 @@
-<llsd/>
\ No newline at end of file
+<?xml version="1.0"?>
+<llsd>
+  <undef/>
+</llsd>
diff --git a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
index 43ed41a2050c11affab3e55a044787fa7be14bf3..efd0d03965725dcdd8b3fcb42efc68c0c9718690 100755
--- a/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
+++ b/indra/newview/app_settings/shaders/class1/avatar/objectSkinV.glsl
@@ -45,3 +45,4 @@ mat4 getObjectSkinnedTransform()
 		
 	return mat;
 }
+
diff --git a/indra/newview/gpu_table.txt b/indra/newview/gpu_table.txt
index c64e11929df8b09d55a9d2787487405d50eb2c3e..122577b13236c49e45a0a127c2cac60b6245b307 100755
--- a/indra/newview/gpu_table.txt
+++ b/indra/newview/gpu_table.txt
@@ -38,7 +38,7 @@ ATI 3D-Analyze							.*ATI.*3D-Analyze.*									0	0	0	0
 ATI All-in-Wonder 7500					.*ATI.*All-in-Wonder 75.*							0	1	0	0
 ATI All-in-Wonder 8500					.*ATI.*All-in-Wonder 85.*							0	1	0	0
 ATI All-in-Wonder 9200					.*ATI.*All-in-Wonder 92.*							0	1	0	0
-ATI All-in-Wonder 9xxx					.*ATI.*All-in-Wonder 9.*				1	1	0	0
+ATI All-in-Wonder 9xxx					.*ATI.*All-in-Wonder 9.*							1	1	0	2.1
 ATI All-in-Wonder HD					.*ATI.*All-in-Wonder HD.*							1	1	1	3.3
 ATI All-in-Wonder X600					.*ATI.*All-in-Wonder X6.*							1	1	0	0
 ATI All-in-Wonder X800					.*ATI.*All-in-Wonder X8.*							1	1	1	2.1
@@ -46,162 +46,132 @@ ATI All-in-Wonder X1800					.*ATI.*All-in-Wonder X18.*							3	1	0	0
 ATI All-in-Wonder X1900					.*ATI.*All-in-Wonder X19.*							3	1	0	0
 ATI All-in-Wonder PCI-E					.*ATI.*All-in-Wonder.*PCI-E.*						1	1	0	0
 ATI All-in-Wonder Radeon				.*ATI.*All-in-Wonder Radeon.*						0	1	0	0
-ATI ASUS ARES							.*ATI.*ASUS.*ARES.*						3	1	0	0
-ATI ASUS A9xxx							.*ATI.*ASUS.*A9.*						1	1	0	0
-ATI ASUS AH24xx							.*ATI.*ASUS.*AH24.*						1	1	1	3.3
-ATI ASUS AH26xx							.*ATI.*ASUS.*AH26.*						1	1	1	3.3
-ATI ASUS AH34xx							.*ATI.*ASUS.*AH34.*						1	1	1	3.3
-ATI ASUS AH36xx							.*ATI.*ASUS.*AH36.*						1	1	1	3.3
-ATI ASUS AH46xx							.*ATI.*ASUS.*AH46.*						2	1	1	3.3
-ATI ASUS AX3xx							.*ATI.*ASUS.*AX3.*						1	1	0	0
-ATI ASUS AX5xx							.*ATI.*ASUS.*AX5.*						1	1	0	0
-ATI ASUS AX8xx							.*ATI.*ASUS.*AX8.*						2	1	0	0
-ATI ASUS EAH24xx						.*ATI.*ASUS.*EAH24.*					2	1	0	0
-ATI ASUS EAH26xx						.*ATI.*ASUS.*EAH26.*					3	1	0	0
-ATI ASUS EAH29xx						.*ATI.*ASUS.*EAH29.*					3	1	0	0
-ATI ASUS EAH34xx						.*ATI.*ASUS.*EAH34.*					1	1	0	0
-ATI ASUS EAH36xx						.*ATI.*ASUS.*EAH36.*					2	1	0	0
-ATI ASUS EAH38xx						.*ATI.*ASUS.*EAH38.*					2	1	1	3.3
-ATI ASUS EAH43xx						.*ATI.*ASUS.*EAH43.*					2	1	1	3.3
-ATI ASUS EAH45xx						.*ATI.*ASUS.*EAH45.*					2	1	0	0
-ATI ASUS EAH48xx						.*ATI.*ASUS.*EAH48.*					3	1	1	3.3
-ATI ASUS EAH57xx						.*ATI.*ASUS.*EAH57.*					3	1	1	4.1
-ATI ASUS EAH58xx						.*ATI.*ASUS.*EAH58.*					5	1	1	4.1
-ATI ASUS EAH62xx						.*ATI.*ASUS.*EAH62.*					2	1	0	0
-ATI ASUS EAH63xx						.*ATI.*ASUS.*EAH63.*					2	1	0	0
-ATI ASUS EAH64xx						.*ATI.*ASUS.*EAH64.*					2	1	0	0
-ATI ASUS EAH65xx						.*ATI.*ASUS.*EAH65.*					2	1	0	4.1
-ATI ASUS EAH66xx						.*ATI.*ASUS.*EAH66.*					3	1	0	4.1
-ATI ASUS EAH67xx						.*ATI.*ASUS.*EAH67.*					3	1	0	0
-ATI ASUS EAH68xx						.*ATI.*ASUS.*EAH68.*					5	1	0	4
-ATI ASUS EAH69xx						.*ATI.*ASUS.*EAH69.*					5	1	0	4.1
-ATI ASUS Radeon X1xxx					.*ATI.*ASUS.*X1.*						2	1	1	2.1
-ATI Radeon X7xx							.*ATI.*ASUS.*X7.*						1	1	0	0
-ATI Radeon X19xx						.*ATI.*(Radeon|Diamond) X19.* ?.*		2	1	1	2.1
-ATI Radeon X18xx						.*ATI.*(Radeon|Diamond) X18.* ?.*		3	1	1	2.1
+ATI Radeon X1300						.*ATI.*(ASUS|Radeon).*X13.*							2	1	1	2.1
+ATI Radeon X1500						.*ATI.*(ASUS|Radeon).*X15.*							2	1	1	2.1
+ATI Radeon X1600						.*ATI.*(ASUS|Radeon).*X16.*							2	1	1	2.1
+ATI Radeon X1700						.*ATI.*(ASUS|Radeon).*X17.*							2	1	1	2.1
+ATI Radeon X1800						.*ATI.*(Radeon|Diamond) X18.* ?.*					3	1	1	2.1
+ATI Radeon X1900						.*ATI.*(Radeon|Diamond|ASUS) X19.* ?.*				2	1	1	2.1
 ATI Radeon X17xx						.*ATI.*(Radeon|Diamond) X17.* ?.*					1	1	1	2.1
-ATI Radeon X16xx						.*ATI.*(Radeon|Diamond) X16.* ?.*		1	1	1	2.1
-ATI Radeon X15xx						.*ATI.*(Radeon|Diamond) X15.* ?.*		1	1	1	2.1
-ATI Radeon X13xx						.*ATI.*(Radeon|Diamond) X13.* ?.*		1	1	1	2.1
-ATI Radeon X1xxx						.*ATI.*(Radeon|Diamond) X1.. ?.*		0	1	1	2.1
-ATI Radeon X2xxx						.*ATI.*(Radeon|Diamond) X2.. ?.*		1	1	1	2.1
+ATI Radeon X16xx						.*ATI.*(Radeon|Diamond) X17.* ?.*					1	1	1	2.1
+ATI Radeon X28xx						.*ATI.*(Radeon|Diamond) X28.. ?.*					1	1	1	2.1
 ATI Display Adapter						.*ATI.*display adapter.*							1	1	1	4.1
 ATI FireGL 5200							.*ATI.*FireGL V52.*									1	1	1	2.1
 ATI FireGL 5xxx							.*ATI.*FireGL V5.*									2	1	1	3.3
 ATI FireGL								.*ATI.*Fire.*GL.*									4	1	1	4.2
-ATI FirePro M3900						.*ATI.*FirePro.*M39.*					2	1	0	0
+ATI FirePro M3900						.*ATI.*FirePro.*M39.*								2	1	0	4.1
 ATI FirePro M5800						.*ATI.*FirePro.*M58.*								3	1	0	0
 ATI FirePro M7740						.*ATI.*FirePro.*M77.*								3	1	0	0
 ATI FirePro M7820						.*ATI.*FirePro.*M78.*								5	1	1	4.2
-ATI FireMV								.*ATI.*FireMV.*							0	1	1	1.3
+ATI FireMV								.*ATI.*FireMV.*										0	1	1	3.2
 ATI Generic								.*ATI.*Generic.*									0	0	0	0
 ATI Hercules 9800						.*ATI.*Hercules.* 9800.*							1	1	0	0
-ATI IGP 340M							.*ATI.*IGP.*340M.*						0	0	0	0
+ATI IGP 340M							.*ATI.*IGP.* 34[0-9]M.*								0	0	0	1.3
 ATI M52									.*ATI.*M52.*										1	1	0	0
 ATI M54									.*ATI.*M54.*										1	1	0	0
 ATI M56									.*ATI.*M56.*										1	1	0	0
 ATI M71									.*ATI.*M71.*										1	1	0	0
 ATI M72									.*ATI.*M72.*										1	1	0	0
 ATI M76									.*ATI.*M76.*										3	1	0	0
-ATI Radeon HD 64xx						.*ATI.*AMD Radeon.* HD [67]4..[MG]		2	1	1	4.2
-ATI Radeon HD 65xx						.*ATI.*AMD Radeon.* HD [67]5..[MG]		2	1	1	4.2
-ATI Radeon HD 66xx						.*ATI.*AMD Radeon.* HD [67]6..[MG]		3	1	1	4.2
-ATI Radeon HD 7100						.*ATI.*AMD Radeon.* HD 71.*				2	1	0	0
-ATI Radeon HD 7200						.*ATI.*AMD Radeon.* HD 72.*				2	1	0	0
-ATI Radeon HD 7300						.*ATI.*AMD Radeon.* HD 73.*				2	1	0	4.2
-ATI Radeon HD 7400						.*ATI.*AMD Radeon.* HD 74.*				2	1	0	4.2
-ATI Radeon HD 7500						.*ATI.*AMD Radeon.* HD 75.*				3	1	1	4.2
-ATI Radeon HD 7600						.*ATI.*AMD Radeon.* HD 76.*				3	1	0	4.2
-ATI Radeon HD 7700						.*ATI.*AMD Radeon.* HD 77.*				4	1	1	4.2
-ATI Radeon HD 7800						.*ATI.*AMD Radeon.* HD 78.*				5	1	1	4.2
-ATI Radeon HD 7900						.*ATI.*AMD Radeon.* HD 79.*				5	1	1	4.2
-ATI ASUS HD7100							.*ATI.*ASUS.* HD71.*					2	1	0	0
-ATI ASUS HD7200							.*ATI.*ASUS.* HD72.*					2	1	0	0
-ATI ASUS HD7300							.*ATI.*ASUS.* HD73.*					2	1	0	0
-ATI ASUS HD7400							.*ATI.*ASUS.* HD74.*					2	1	0	0
-ATI ASUS HD7500							.*ATI.*ASUS.* HD75.*					3	1	1	4.2
-ATI ASUS HD7600							.*ATI.*ASUS.* HD76.*					3	1	0	0
-ATI ASUS HD7700							.*ATI.*ASUS.* HD77.*					4	1	1	4.2
-ATI ASUS HD7800							.*ATI.*ASUS.* HD78.*					5	1	1	4.2
-ATI ASUS HD7900							.*ATI.*ASUS.* HD79.*					5	1	1	4.2
+ATI Radeon HD 6300M						.*ATI.*AMD Radeon.* (HD|HD )63..M					2	1	1	4.2
+ATI Radeon HD 6400M						.*ATI.*AMD Radeon.* (HD|HD )64..M					2	1	1	4.2
+ATI Radeon HD 6500M						.*ATI.*AMD Radeon.* (HD|HD )65..M					2	1	1	4.2
+ATI Radeon HD 6600M						.*ATI.*AMD Radeon.* (HD 6|6)6..M					3	1	1	4.2
+ATI Radeon HD 6700M						.*ATI.*AMD Radeon.* (HD|HD )67..M					3	1	1	4.2
+ATI Radeon HD 6800M						.*ATI.*AMD Radeon.* (HD|HD )68..M					3	1	1	4.2
+ATI Radeon HD 6300G						.*ATI.*AMD Radeon.* (HD|HD )63..G					2	1	1	4.2
+ATI Radeon HD 6400G						.*ATI.*AMD Radeon.* (HD|HD )64..G					2	1	1	4.2
+ATI Radeon HD 6500G						.*ATI.*AMD Radeon.* (HD|HD )65..G					2	1	1	4.2
+ATI Radeon HD 6600G						.*ATI.*AMD Radeon.* (HD|HD )66..G					3	1	1	4.2
+ATI Radeon HD 7100						.*ATI.*(Radeon|ASUS).* (HD|HD )71.*					2	1	0	0
+ATI Radeon HD 7200						.*ATI.*(Radeon|ASUS).* (HD|HD )72.*					2	1	0	4.2
+ATI Radeon HD 7300						.*ATI.*(Radeon|ASUS).* (HD|HD )73.*					2	1	0	4.2
+ATI Radeon HD 7400						.*ATI.*(Radeon|ASUS).* (HD|HD )74.*					2	1	0	4.2
+ATI Radeon HD 7500						.*ATI.*(Radeon|ASUS).* (HD|HD )75.*					3	1	1	4.2
+ATI Radeon HD 7600						.*ATI.*(Radeon|ASUS).* (HD|HD )76.*					3	1	0	4.2
+ATI Radeon HD 7700						.*ATI.*(Radeon|ASUS).* (HD|HD )77.*					4	1	1	4.2
+ATI Radeon HD 7800						.*ATI.*(Radeon|ASUS).* (HD|HD )78.*					5	1	1	4.2
+ATI Radeon HD 7900						.*ATI.*(Radeon|ASUS).* (HD|HD )79.*					5	1	1	4.2
+ATI Radeon HD 7000 Series				.*ATI.*(Radeon|ASUS).* (HD|HD )7000 Series.*		3	1	1	4.2
 ATI Mobility Radeon 4100				.*ATI.*Mobility.* 41..								1	1	1	3.3
+ATI Mobility Radeon 5000				.*ATI.*Mobility.* 50..								1	1	1	4.2
 ATI Mobility Radeon 7xxx				.*ATI.*Mobility.*Radeon 7.*							0	1	1	1.3
 ATI Mobility Radeon 8xxx				.*ATI.*Mobility.*Radeon 8.*							0	1	0	0
 ATI Mobility Radeon 9800				.*ATI.*Mobility.* 98.*								1	1	0	0
 ATI Mobility Radeon 9700				.*ATI.*Mobility.* 97.*								0	1	1	2.1
 ATI Mobility Radeon 9600				.*ATI.*Mobility.* 96.*								1	1	1	2.1
-ATI Mobility Radeon HD 530v				.*ATI.*Mobility.*HD *530v.*				1	1	1	3.3
-ATI Mobility Radeon HD 540v				.*ATI.*Mobility.*HD *540v.*				1	1	1	3.3
-ATI Mobility Radeon HD 545v				.*ATI.*Mobility.*HD *545v.*				2	1	1	4
-ATI Mobility Radeon HD 550v				.*ATI.*Mobility.*HD *550v.*				3	1	1	4
-ATI Mobility Radeon HD 560v				.*ATI.*Mobility.*HD *560v.*				3	1	1	3.2
-ATI Mobility Radeon HD 565v				.*ATI.*Mobility.*HD *565v.*				3	1	1	3.3
-ATI Mobility Radeon HD 2300				.*ATI.*Mobility.*HD *23.*				0	1	1	2.1
-ATI Mobility Radeon HD 2400				.*ATI.*Mobility.*HD *24.*				1	1	1	3.3
-ATI Mobility Radeon HD 2600				.*ATI.*Mobility.*HD *26.*				1	1	1	3.3
-ATI Mobility Radeon HD 2700				.*ATI.*Mobility.*HD *27.*				3	1	0	0
-ATI Mobility Radeon HD 3100				.*ATI.*Mobility.*HD *31.*				0	1	0	0
-ATI Mobility Radeon HD 3200				.*ATI.*Mobility.*HD *32.*				0	1	0	0
-ATI Mobility Radeon HD 3400				.*ATI.*Mobility.*HD *34.*				1	1	1	3.3
-ATI Mobility Radeon HD 3600				.*ATI.*Mobility.*HD *36.*				1	1	1	4
-ATI Mobility Radeon HD 3800				.*ATI.*Mobility.*HD *38.*				3	1	1	3.3
-ATI Mobility Radeon HD 4200				.*ATI.*Mobility.*HD *42.*				1	1	1	4
-ATI Mobility Radeon HD 4300				.*ATI.*Mobility.*HD *43.*				1	1	1	4
-ATI Mobility Radeon HD 4500				.*ATI.*Mobility.*HD *45.*				1	1	1	4
-ATI Mobility Radeon HD 4600				.*ATI.*Mobility.*HD *46.*				2	1	1	3.3
-ATI Mobility Radeon HD 4800				.*ATI.*Mobility.*HD *48.*				3	1	1	3.3
-ATI Mobility Radeon HD 5100				.*ATI.*Mobility.*HD *51.*				3	1	1	3.2
-ATI Mobility Radeon HD 5300				.*ATI.*Mobility.*HD *53.*				3	1	0	0
-ATI Mobility Radeon HD 5400				.*ATI.*Mobility.*HD *54.*				2	1	1	4.2
-ATI Mobility Radeon HD 5500				.*ATI.*Mobility.*HD *55.*				3	1	0	0
-ATI Mobility Radeon HD 5600				.*ATI.*Mobility.*HD *56.*				3	1	1	4.2
-ATI Mobility Radeon HD 5700				.*ATI.*Mobility.*HD *57.*				3	1	1	4.1
-ATI Mobility Radeon HD 6200				.*ATI.*Mobility.*HD *62.*				3	1	0	0
-ATI Mobility Radeon HD 6300				.*ATI.*Mobility.*HD *63.*				3	1	1	4.2
-ATI Mobility Radeon HD 6400M			.*ATI.*Mobility.*HD *64.*				3	1	0	0
-ATI Mobility Radeon HD 6500M			.*ATI.*Mobility.*HD *65.*				5	1	1	4.2
-ATI Mobility Radeon HD 6600M			.*ATI.*Mobility.*HD *66.*				5	1	0	0
-ATI Mobility Radeon HD 6700M			.*ATI.*Mobility.*HD *67.*				5	1	0	0
-ATI Mobility Radeon HD 6800M			.*ATI.*Mobility.*HD *68.*				5	1	0	0
-ATI Mobility Radeon HD 6900M			.*ATI.*Mobility.*HD *69.*				5	1	0	0
-ATI Radeon HD 2300						.*ATI.*Radeon HD *23..					0	1	1	3.3
-ATI Radeon HD 2400						.*ATI.*Radeon HD *24..					1	1	1	4
-ATI Radeon HD 2600						.*ATI.*Radeon HD *26..					2	1	1	3.3
-ATI Radeon HD 2900						.*ATI.*Radeon HD *29..					3	1	1	3.3
-ATI Radeon HD 3000						.*ATI.*Radeon HD *30..					0	1	0	0
-ATI Radeon HD 3100						.*ATI.*Radeon HD *31..					1	1	0	0
-ATI Radeon HD 3200						.*ATI.*Radeon HD *32..					1	1	1	4
-ATI Radeon HD 3300						.*ATI.*Radeon HD *33..					1	1	1	3.3
-ATI Radeon HD 3400						.*ATI.*Radeon HD *34..					1	1	1	4
-ATI Radeon HD 3500						.*ATI.*Radeon HD *35..					2	1	0	0
-ATI Radeon HD 3600						.*ATI.*Radeon HD *36..					3	1	1	3.3
-ATI Radeon HD 3700						.*ATI.*Radeon HD *37..					3	1	0	0
+ATI Mobility Radeon HD 530v				.*ATI.*Mobility.*HD 530v.*							1	1	1	3.3
+ATI Mobility Radeon HD 540v				.*ATI.*Mobility.*HD 540v.*							1	1	1	3.3
+ATI Mobility Radeon HD 545v				.*ATI.*Mobility.*HD 545v.*							2	1	1	4
+ATI Mobility Radeon HD 550v				.*ATI.*Mobility.*HD 550v.*							3	1	1	4
+ATI Mobility Radeon HD 560v				.*ATI.*Mobility.*HD 560v.*							3	1	1	3.2
+ATI Mobility Radeon HD 565v				.*ATI.*Mobility.*HD 565v.*							3	1	1	3.3
+ATI Mobility Radeon HD 2300				.*ATI.*Mobility.*HD 23.*							0	1	1	2.1
+ATI Mobility Radeon HD 2400				.*ATI.*Mobility.*HD 24.*							1	1	1	3.3
+ATI Mobility Radeon HD 2600				.*ATI.*Mobility.*HD 26.*							1	1	1	3.3
+ATI Mobility Radeon HD 2700				.*ATI.*Mobility.*HD 27.*							3	1	0	0
+ATI Mobility Radeon HD 3100				.*ATI.*Mobility.*HD 31.*							0	1	0	0
+ATI Mobility Radeon HD 3200				.*ATI.*Mobility.*HD 32.*							0	1	0	0
+ATI Mobility Radeon HD 3400				.*ATI.*Mobility.*HD 34.*							1	1	1	4
+ATI Mobility Radeon HD 3600				.*ATI.*Mobility.*HD 36.*							1	1	1	4
+ATI Mobility Radeon HD 3800				.*ATI.*Mobility.*HD 38.*							3	1	1	3.3
+ATI Mobility Radeon HD 4200				.*ATI.*Mobility.*HD 42.*							1	1	1	4
+ATI Mobility Radeon HD 4300				.*ATI.*Mobility.*(HD |HD)43.*						1	1	1	4
+ATI Mobility Radeon HD 4500				.*ATI.*Mobility.*HD 45.*							1	1	1	4
+ATI Mobility Radeon HD 4600				.*ATI.*Mobility.*HD 46.*							2	1	1	3.3
+ATI Mobility Radeon HD 4800				.*ATI.*Mobility.*HD 48.*							3	1	1	3.3
+ATI Mobility Radeon HD 5000 Series		.*ATI.*Mobility.*HD 50.*							3	1	1	3.2
+ATI Mobility Radeon HD 5100				.*ATI.*Mobility.*HD 51.*							3	1	1	3.2
+ATI Mobility Radeon HD 5300				.*ATI.*Mobility.*HD 53.*							3	1	0	0
+ATI Mobility Radeon HD 5400				.*ATI.*Mobility.*HD 54.*							2	1	1	4.2
+ATI Mobility Radeon HD 5500				.*ATI.*Mobility.*HD 55.*							3	1	0	4.2
+ATI Mobility Radeon HD 5600				.*ATI.*Mobility.*HD 56.*							3	1	1	4.2
+ATI Mobility Radeon HD 5700				.*ATI.*Mobility.*HD 57.*							3	1	1	4.1
+ATI Mobility Radeon HD 6200				.*ATI.*Mobility.*HD 62.*							3	1	0	0
+ATI Mobility Radeon HD 6300				.*ATI.*Mobility.*HD 63.*							3	1	1	4.2
+ATI Mobility Radeon HD 6400M			.*ATI.*Mobility.*HD 64.*							3	1	0	0
+ATI Mobility Radeon HD 6500M			.*ATI.*Mobility.*HD 65.*							5	1	1	4.2
+ATI Mobility Radeon HD 6600M			.*ATI.*Mobility.*HD 66.*							5	1	0	0
+ATI Mobility Radeon HD 6700M			.*ATI.*Mobility.*HD 67.*							5	1	0	0
+ATI Mobility Radeon HD 6800M			.*ATI.*Mobility.*HD 68.*							5	1	0	0
+ATI Mobility Radeon HD 6900M			.*ATI.*Mobility.*HD 69.*							5	1	0	0
+ATI Mobility Radeon Graphics			.*ATI Mobility Radeon Graphics.*					1	1	0	4
+ATI Radeon HD 2300						.*ATI.*Radeon.* (HD|HD )23..						0	1	1	3.3
+ATI Radeon HD 2400						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)24..				1	1	1	4
+ATI Radeon HD 2600						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)26..				2	1	1	4
+ATI Radeon HD 2900						.*ATI.*Radeon.* (HD|HD )29..						3	1	1	3.3
+ATI Radeon HD 3000						.*ATI.*Radeon.* (HD|HD )30..						0	1	0	0
+ATI Radeon HD 3100						.*ATI.*Radeon.* (HD|HD )31..						1	1	0	0
+ATI Radeon HD 3200						.*ATI.*Radeon.* (HD|HD )32..						1	1	1	4
+ATI Radeon HD 3300						.*ATI.*Radeon.* (HD|HD )33..						1	1	1	3.3
+ATI Radeon HD 3400						.*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)34..			1	1	1	4
+ATI Radeon HD 3500						.*ATI.*Radeon.* (HD|HD )35..						2	1	0	0
+ATI Radeon HD 3600						.*ATI.*(Radeon|ASUS).* (HD|HD |AH|EAH)36..			3	1	1	4
+ATI Radeon HD 3700						.*ATI.*Radeon.* (HD|HD )37..						3	1	0	3.3
 ATI HD3700								.*ATI.* HD37..										3	1	0	3.3
-ATI Radeon HD 3800						.*ATI.*Radeon HD *38..					3	1	1	4
-ATI Radeon HD 4100						.*ATI.*Radeon HD *41..					1	1	0	0
-ATI Radeon HD 4200						.*ATI.*Radeon HD *42..					1	1	1	4
-ATI Radeon HD 4300						.*ATI.*Radeon HD *43..					2	1	1	4
-ATI Radeon HD 4400						.*ATI.*Radeon HD *44..					2	1	0	0
-ATI Radeon HD 4500						.*ATI.*Radeon HD *45..					2	1	1	3.3
-ATI Radeon HD 4600						.*ATI.*Radeon HD *46..					3	1	1	4
-ATI Radeon HD 4700						.*ATI.*Radeon HD *47..					3	1	1	3.3
-ATI Radeon HD 4800						.*ATI.*Radeon HD *48..					3	1	1	4
-ATI ASUS EAH5400						.*ATI.*ASUS EAH54..						3	1	1	4.2
-ATI Radeon HD 5400						.*ATI.*Radeon HD *54..					3	1	1	4.2
-ATI Radeon HD 5500						.*ATI.*Radeon HD *55..					3	1	1	4.2
-ATI ASUS EAH5500						.*ATI.*ASUS EAH55..						3	1	1	4.2
-ATI Radeon HD 5600						.*ATI.*Radeon HD *56..					3	1	1	4.2
-ATI Radeon HD 5700						.*ATI.*Radeon HD *57..					3	1	1	4.2
-ATI Radeon HD 5800						.*ATI.*Radeon HD *58..					4	1	1	4.2
-ATI Radeon HD 5900						.*ATI.*Radeon HD *59..					4	1	1	4.2
-ATI Radeon HD 6200						.*ATI.*Radeon HD *62..					0	1	1	4.2
-ATI Radeon HD 6300						.*ATI.*Radeon HD *63..					1	1	1	4.2
-ATI Radeon HD 6400						.*ATI.*Radeon HD *64..					3	1	1	4.2
-ATI Radeon HD 6500						.*ATI.*Radeon HD *65..					3	1	1	4.2
-ATI Radeon HD 6600						.*ATI.*Radeon HD *66..					3	1	1	4.2
-ATI Radeon HD 6700						.*ATI.*Radeon HD *67..					3	1	1	4.2
-ATI Radeon HD 6800						.*ATI.*Radeon HD *68..					4	1	1	4.2
-ATI Radeon HD 6900						.*ATI.*Radeon HD *69..					5	1	1	4.2
+ATI Radeon HD 3800						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)38..				3	1	1	4
+ATI Radeon HD 4100						.*ATI.*Radeon.* (HD|HD )41..						1	1	0	0
+ATI Radeon HD 4200						.*ATI.*Radeon.* (HD|HD )42..						1	1	1	4
+ATI Radeon HD 4300						.*ATI.*(Radeon|ASUS).* (HD4|HD 4|EAH4|4)3..			2	1	1	4
+ATI Radeon HD 4400						.*ATI.*Radeon.* (HD|HD )44..						2	1	0	0
+ATI Radeon HD 4500						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)45..				2	1	1	3.3
+ATI Radeon HD 4600						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)46..				3	1	1	4
+ATI Radeon HD 4700						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)47..				3	1	1	3.3
+ATI Radeon HD 4800						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)48..				3	1	1	4
+ATI Radeon HD 5400						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)54..				3	1	1	4.2
+ATI Radeon HD 5500						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)55..				3	1	1	4.2
+ATI Radeon HD 5600						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)56..				3	1	1	4.2
+ATI Radeon HD 5700						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)57..				3	1	1	4.2
+ATI Radeon HD 5800						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)58..				4	1	1	4.2
+ATI Radeon HD 5900						.*ATI.*Radeon.* (HD|HD )59..						4	1	1	4.2
+ATI Radeon HD 6200						.*ATI.*Radeon.* (HD|HD )62..						0	1	1	4.2
+ATI Radeon HD 6300						.*ATI.*Radeon.* (HD|HD )63..						1	1	1	4.2
+ATI Radeon HD 6400						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)64..				3	1	1	4.2
+ATI Radeon HD 6500						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)65..				3	1	1	4.2
+ATI Radeon HD 6600						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)66..				3	1	1	4.2
+ATI Radeon HD 6700						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)67..				3	1	1	4.2
+ATI Radeon HD 6800						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)68..				4	1	1	4.2
+ATI Radeon HD 6900						.*ATI.*(Radeon|ASUS).* (HD|HD |EAH)69..				5	1	1	4.2
 ATI Radeon OpenGL						.*ATI.*Radeon OpenGL.*								0	0	0	0
 ATI Radeon 2100							.*ATI.*Radeon 21..									0	1	1	2.1
 ATI Radeon 3000							.*ATI.*Radeon 30..									1	1	1	4
@@ -219,17 +189,21 @@ ATI Radeon 9800							.*ATI.*Radeon 98..									1	1	1	2.1
 ATI Radeon RV250						.*ATI.*RV250.*										0	1	0	0
 ATI Radeon RV600						.*ATI.*RV6.*										1	1	0	0
 ATI Radeon RX700						.*ATI.*RX70.*										1	1	0	0
-ATI Radeon RX800						.*ATI.*Radeon *RX80.*					2	1	0	0
+ATI Radeon RX800						.*ATI.*Radeon RX80.*								2	1	0	0
 ATI RS880M								.*ATI.*RS880M										1	1	0	0
 ATI Radeon RX9550						.*ATI.*RX9550.*										1	1	0	0
 ATI Radeon VE							.*ATI.*Radeon.*VE.*									0	0	0	0
-ATI Radeon X300							.*ATI.*Radeon *X3.*						1	1	1	2.1
+ATI Radeon X300							.*ATI.*Radeon X3.*									1	1	1	2.1
 ATI Radeon X400							.*ATI.*Radeon ?X4.*									0	1	0	0
 ATI Radeon X500							.*ATI.*Radeon ?X5.*									1	1	1	2.1
-ATI Radeon X600							.*ATI.*Radeon ?X6.*						1	1	1	2.1
+ATI Radeon X600							.*ATI.*(Radeon |ASUS Extreme A)X6.*					1	1	1	2.1
 ATI Radeon X700							.*ATI.*Radeon ?X7.*									2	1	1	2.1
 ATI Radeon X800							.*ATI.*Radeon ?X8.*									1	1	1	2.1
 ATI Radeon X900							.*ATI.*Radeon ?X9.*									2	1	0	0
+ATI Radeon X1000						.*ATI.*Radeon ?X10.*								2	1	0	2.1
+ATI Radeon X1200						.*ATI.*Radeon ?X12.*								2	1	0	2.1
+ATI Radeon X1400						.*ATI.*Radeon ?X14.*								2	1	0	2.1
+ATI Radeon X2300						.*ATI.*Radeon ?X23.*								2	1	0	2.1
 ATI Radeon Xpress						.*ATI.*Radeon Xpress.*								0	1	1	2.1
 ATI Rage 128							.*ATI.*Rage 128.*									0	1	0	0
 ATI R300 (9700)							.*R300.*											0	1	1	2.1
@@ -248,41 +222,43 @@ ATI RV530								.*RV530.*											1	1	0	0
 ATI RX480 (Xpress 200P)					.*RX480.*											0	1	0	0
 ATI RX700								.*RX700.*											1	1	0	0
 AMD ANTILLES (HD 6990)					.*(AMD|ATI).*Antilles.*								3	1	0	0
+ATI ROBSON								.*(AMD|ATI).*ROBSON.*								3	1	0	4
 AMD BARTS (HD 6800)						.*(AMD|ATI).*Barts.*								3	1	1	2.1
+AMD WRESTLER							.*(AMD|ATI).*WRESTLER.*								3	1	1	4
+AMD SUMO								.*(AMD|ATI).*SUMO.*									3	1	1	4.1
 AMD CAICOS (HD 6400)					.*(AMD|ATI).*Caicos.*								3	1	0	0
 AMD CAYMAN (HD 6900)					.*(AMD|ATI).*(Cayman|CAYMAM).*						3	1	0	0
-AMD CEDAR (HD 5450)						.*(AMD|ATI).*Cedar.*					2	1	0	0
+AMD CEDAR (HD 5450)						.*(AMD|ATI).*Cedar.*								2	1	0	2.1
 AMD CYPRESS (HD 5800)					.*(AMD|ATI).*Cypress.*								3	1	0	0
 AMD HEMLOCK (HD 5970)					.*(AMD|ATI).*Hemlock.*								3	1	0	0
 AMD JUNIPER (HD 5700)					.*(AMD|ATI).*Juniper.*								3	1	0	0
 AMD PARK								.*(AMD|ATI).*Park.*									3	1	0	0
-AMD REDWOOD (HD 5500/5600)				.*(AMD|ATI).*Redwood.*					3	1	0	0
-AMD TURKS (HD 6500/6600)				.*(AMD|ATI).*Turks.*					3	1	0	0
+AMD REDWOOD (HD 5500/5600)				.*(AMD|ATI).*Redwood.*								3	1	0	1.4
+AMD TURKS (HD 6500/6600)				.*(AMD|ATI).*Turks.*								3	1	0	2.1
 AMD RS780 (HD 3200)						.*RS780.*											0	1	1	2.1
 AMD RS880 (HD 4200)						.*RS880.*											0	1	1	3.2
 AMD RV610 (HD 2400)						.*RV610.*											1	1	0	0
 AMD RV620 (HD 3400)						.*RV620.*											1	1	0	0
 AMD RV630 (HD 2600)						.*RV630.*											2	1	0	0
-AMD RV635 (HD 3600)						.*RV635.*								3	1	0	0
+AMD RV635 (HD 3600)						.*RV635.*											3	1	0	1.4
 AMD RV670 (HD 3800)						.*RV670.*											3	1	0	0
 AMD R680 (HD 3870 X2)					.*R680.*											3	1	0	0
 AMD R700 (HD 4800 X2)					.*R700.*											3	1	0	0
 AMD RV710 (HD 4300)						.*RV710.*											0	1	1	1.4
-AMD RV730 (HD 4600)						.*RV730.*								3	1	0	0
+AMD RV730 (HD 4600)						.*RV730.*											3	1	0	1.4
 AMD RV740 (HD 4700)						.*RV740.*											3	1	0	0
 AMD RV770 (HD 4800)						.*RV770.*											3	1	0	0
 AMD RV790 (HD 4800)						.*RV790.*											3	1	0	0
 ATI 760G/Radeon 3000					.*ATI.*AMD 760G.*									1	1	1	3.3
 ATI 780L/Radeon 3000					.*ATI.*AMD 780L.*									1	1	0	0
 ATI Radeon DDR							.*ATI.*Radeon ?DDR.*								0	1	0	0
-ATI FirePro 2000						.*ATI.*FirePro 2.*						2	1	1	4.1
+ATI FirePro 2000						.*ATI.*FirePro 2.*									2	1	1	4.2
 ATI FirePro 3000						.*ATI.*FirePro V3.*									2	1	0	0
-ATI FirePro 4000						.*ATI.*FirePro V4.*						2	1	0	0
+ATI FirePro 4000						.*ATI.*FirePro V4.*									2	1	0	4.1
 ATI FirePro 5000						.*ATI.*FirePro V5.*									3	1	0	0
 ATI FirePro 7000						.*ATI.*FirePro V7.*									3	1	0	0
 ATI FirePro M							.*ATI.*FirePro M.*									3	1	1	4.2
 ATI R300 (9700)							.*R300.*											0	1	1	2.1
-ATI Radeon								.*ATI.*(Diamond|Radeon).*				0	1	0	4.2
 Intel X3100								.*Intel.*X3100.*									1	1	1	2.1
 Intel GMA 3600							.*Intel.* 3600.*									0	1	1	3
 Intel 830M								.*Intel.*830M										0	0	0	0
@@ -308,8 +284,6 @@ Intel Graphics Media HD					.*Intel.*Graphics Media.*HD.*						1	1	1	2.1
 Intel HD Graphics 2000					.*Intel.*HD Graphics 2.*							2	1	0	4
 Intel HD Graphics 3000					.*Intel.*HD Graphics 3.*							3	1	1	3.1
 Intel HD Graphics 4000					.*Intel.*HD Graphics 4.*							3	1	1	4
-Intel HD2000							.*Intel.*HD2000.*						2	1	0	0
-Intel HD3000							.*Intel.*HD3000.*						3	1	0	0
 Intel HD Graphics						.*Intel.*HD Graphics.*								2	1	1	4
 Intel Mobile 4 Series					.*Intel.*Mobile.* 4 Series.*						0	1	1	2.1
 Intel 4 Series Internal					.*Intel.* 4 Series Internal.*						1	1	1	2.1
@@ -322,113 +296,109 @@ Intel Q45/Q43							.*Intel.*Q4.*										1	1	1	2.1
 Intel B45/B43							.*Intel.*B4.*										1	1	1	2.1
 Intel 3D-Analyze						.*Intel.*3D-Analyze.*								2	1	0	0
 Matrox									.*Matrox.*											0	0	0	0
-Mesa									.*Mesa.*								1	0	1	2.1
+Mesa									.*Mesa.*											1	0	1	3
 Gallium									.*Gallium.*											1	1	1	2.1
-NVIDIA G100M							.*NVIDIA .*100M.*						4	1	1	3.3
-NVIDIA G102M							.*NVIDIA .*102M.*						1	1	1	3.3
-NVIDIA G103M							.*NVIDIA .*103M.*						2	1	1	3.3
-NVIDIA G105M							.*NVIDIA .*105M.*						2	1	1	3.3
-NVIDIA G 110M							.*NVIDIA .*110M.*						1	1	1	3.3
-NVIDIA G 120M							.*NVIDIA .*120M.*						1	1	1	3.3
-NVIDIA G 205M							.*NVIDIA .*205M.*						1	1	0	0
-NVIDIA G 410M							.*NVIDIA .*410M.*						3	1	1	4.2
-NVIDIA GT 120M							.*NVIDIA .*GT *12*M.*					3	1	1	3.3
-NVIDIA GT 130M							.*NVIDIA .*GT *13*M.*					3	1	1	3.3
-NVIDIA GT 140M							.*NVIDIA .*GT *14*M.*					3	1	1	3.3
-NVIDIA GT 150M							.*NVIDIA .*GTS *15*M.*					2	1	0	0
-NVIDIA GTS 160M							.*NVIDIA .*GTS *16*M.*					2	1	0	0
-NVIDIA G210M							.*NVIDIA .*G21*M.*						3	1	0	0
-NVIDIA GT 220M							.*NVIDIA .*GT *22*M.*					3	1	1	3.3
-NVIDIA GT 230M							.*NVIDIA .*GT *23*M.*					3	1	1	3.3
-NVIDIA GT 240M							.*NVIDIA .*GT *24*M.*					3	1	1	3.3
-NVIDIA GTS 250M							.*NVIDIA .*GTS *25*M.*					3	1	0	0
-NVIDIA GTS 260M							.*NVIDIA .*GTS *26*M.*					3	1	0	0
-NVIDIA GTX 260M							.*NVIDIA .*GTX *26*M.*					3	1	0	0
-NVIDIA GTX 270M							.*NVIDIA .*GTX *27*M.*					3	1	0	0
-NVIDIA GTX 280M							.*NVIDIA .*GTX *28*M.*					3	1	0	0
-NVIDIA 300M								.*NVIDIA .*30*M.*						3	1	1	4.2
-NVIDIA G 310M							.*NVIDIA .*31*M.*						2	1	0	0
-NVIDIA GT 320M							.*NVIDIA .*GT *32*M.*					3	1	0	0
-NVIDIA GT 325M							.*NVIDIA .*GT *32*M.*					3	1	1	3.3
-NVIDIA GT 330M							.*NVIDIA .*GT *33*M.*					3	1	1	3.3
-NVIDIA GT 340M							.*NVIDIA .*GT *34*M.*					4	1	1	3.3
-NVIDIA GTS 350M							.*NVIDIA .*GTS *35*M.*					4	1	1	3.3
-NVIDIA GTS 360M							.*NVIDIA .*GTS *360M.*					5	1	1	3.3
-NVIDIA 405M								.*NVIDIA .* 40*M.*						2	1	0	4.2
-NVIDIA 410M								.*NVIDIA .* 41*M.*						3	1	0	0
-NVIDIA GT 415M							.*NVIDIA .*GT *41*M.*					3	1	1	4.2
-NVIDIA GT 420M							.*NVIDIA .*GT *42*M.*					3	1	1	4.2
-NVIDIA GT 430M							.*NVIDIA .*GT *43*M.*					3	1	1	4.2
-NVIDIA GT 440M							.*NVIDIA .*GT *44*M.*					3	1	1	4.2
-NVIDIA GT 450M							.*NVIDIA .*GT *45*M.*					3	1	0	0
-NVIDIA GTX 460M							.*NVIDIA .*GTX *46*M.*					4	1	1	4.2
-NVIDIA GTX 470M							.*NVIDIA .*GTX *47*M.*					3	1	0	0
-NVIDIA GTX 480M							.*NVIDIA .*GTX *48*M.*					3	1	1	4.2
-NVIDIA GT 520M							.*NVIDIA .*GT *52*M.*					3	1	1	4.2
-NVIDIA GT 530M							.*NVIDIA .*GT *53*M.*					3	1	1	4.2
-NVIDIA GT 540M							.*NVIDIA .*GT *54*M.*					3	1	1	4.2
-NVIDIA GT 550M							.*NVIDIA .*GT *55*M.*					3	1	1	4.2
-NVIDIA GTX 560M							.*NVIDIA .*GTX *56*M.*					3	1	0	0
-NVIDIA GTX 570M							.*NVIDIA .*GTX *57*M.*					5	1	0	0
-NVIDIA GTX 580M							.*NVIDIA .*GTX *58*M.*					5	1	1	4.2
-NVIDIA 610M								.*NVIDIA.* 61*M.*						3	1	1	4.2
-NVIDIA GT 620M							.*NVIDIA .*GT *62*M.*					3	1	0	0
-NVIDIA GT 630M							.*NVIDIA .*GT *63*M.*					3	1	0	0
-NVIDIA GT 640M							.*NVIDIA .*GT *64*M.*					3	1	0	0
-NVIDIA GT 650M							.*NVIDIA .*GT *65*M.*					3	1	0	0
-NVIDIA GTX 660M							.*NVIDIA .*GTX *66*M.*					5	1	0	0
-NVIDIA GTX 670M							.*NVIDIA .*GTX *67*M.*					5	1	1	4.2
-NVIDIA GTX 680M							.*NVIDIA .*GTX *68*M.*					5	1	0	0
-NVIDIA GTX 690M							.*NVIDIA .*GTX *69*M.*					5	1	0	0
+NVIDIA G100M							.*NVIDIA .* 10[0-9]M.*								4	1	1	3.3
+NVIDIA G 110M							.*NVIDIA .* 11[0-9]M.*								1	1	1	3.3
+NVIDIA G 120M							.*NVIDIA .* 12[0-9]M.*								1	1	1	3.3
+NVIDIA G 200M							.*NVIDIA .* 20[0-9]M.*								1	1	0	0
+NVIDIA G 410M							.*NVIDIA .* 41[0-9]M.*								3	1	1	4.2
+NVIDIA GT 130M							.*NVIDIA .*GT 13[0-9]M.*							3	1	1	3.3
+NVIDIA GT 140M							.*NVIDIA .*GT 14[0-9]M.*							3	1	1	3.3
+NVIDIA GT 150M							.*NVIDIA .*GTS 15[0-9]M.*							2	1	0	0
+NVIDIA GTS 160M							.*NVIDIA .*GTS 16[0-9]M.*							2	1	0	0
+NVIDIA G210M							.*NVIDIA .*G21[0-9]M.*								3	1	0	3.3
+NVIDIA GT 220M							.*NVIDIA .*GT 22[0-9]M.*							3	1	1	3.3
+NVIDIA GT 230M							.*NVIDIA .*GT 23[0-9]M.*							3	1	1	3.3
+NVIDIA GT 240M							.*NVIDIA .*GT 24[0-9]M.*							3	1	1	3.3
+NVIDIA GTS 250M							.*NVIDIA .*GTS 25[0-9]M.*							3	1	0	3.3
+NVIDIA GTS 260M							.*NVIDIA .*GTS 26[0-9]M.*							3	1	0	0
+NVIDIA GTX 260M							.*NVIDIA .*GTX 26[0-9]M.*							3	1	0	3.3
+NVIDIA GTX 270M							.*NVIDIA .*GTX 27[0-9]M.*							3	1	0	0
+NVIDIA GTX 280M							.*NVIDIA .*GTX 28[0-9]M.*							3	1	0	3.3
+NVIDIA 300M								.*NVIDIA .*GT 30[0-9]M.*							3	1	1	4.2
+NVIDIA G 310M							.*NVIDIA .* 31[0-9]M.*								2	1	0	3.3
+NVIDIA GT 320M							.*NVIDIA .* 32[0-9]M.*								3	1	0	3.3
+NVIDIA GT 330M							.*NVIDIA .*GT 33[0-9]M.*							3	1	1	3.3
+NVIDIA GT 340M							.*NVIDIA .*GT 34[0-9]M.*							4	1	1	3.3
+NVIDIA GTS 350M							.*NVIDIA .*GTS 35[0-9]M.*							4	1	1	3.3
+NVIDIA GTS 360M							.*NVIDIA .*GTS 36[0-9]M.*							5	1	1	3.3
+NVIDIA 400M								.*NVIDIA .* 40[0-9]M.*								2	1	0	0
+NVIDIA 410M								.*NVIDIA .* 41[0-9]M.*								3	1	0	0
+NVIDIA GT 420M							.*NVIDIA .*GT 42[0-9]M.*							3	1	1	4.2
+NVIDIA GT 430M							.*NVIDIA .*GT 43[0-9]M.*							3	1	1	4.2
+NVIDIA GT 440M							.*NVIDIA .*GT 44[0-9]M.*							3	1	1	4.2
+NVIDIA GT 450M							.*NVIDIA .*GT 45[0-9]M.*							3	1	0	0
+NVIDIA GTX 460M							.*NVIDIA .*GTX 46[0-9]M.*							4	1	1	4.3
+NVIDIA GTX 470M							.*NVIDIA .*GTX 47[0-9]M.*							3	1	0	4.2
+NVIDIA GTX 480M							.*NVIDIA .*GTX 48[0-9]M.*							3	1	1	4.2
+NVIDIA GT 520M							.*NVIDIA .*GT 52[0-9]M.*							3	1	1	4.2
+NVIDIA GT 530M							.*NVIDIA .*GT 53[0-9]M.*							3	1	1	4.2
+NVIDIA GT 540M							.*NVIDIA .*GT 54[0-9]M.*							3	1	1	4.2
+NVIDIA GT 550M							.*GeForce GT 55[0-9]M.*								3	1	1	4.2
+NVIDIA GTX 560M							.*NVIDIA .*GTX 56[0-9]M.*							3	1	0	4.2
+NVIDIA GTX 570M							.*NVIDIA .*GTX 57[0-9]M.*							5	1	0	4.2
+NVIDIA GTX 580M							.*NVIDIA .*GTX 58[0-9]M.*							5	1	1	4.2
+NVIDIA 610M								.*NVIDIA.* 61[0-9]M.*								3	1	1	4.2
+NVIDIA GT 620M							.*NVIDIA .*GT 62[0-9]M.*							3	1	0	4.2
+NVIDIA GT 630M							.*NVIDIA .*GT 63[0-9]M.*							3	1	0	4.2
+NVIDIA GT 640M							.*NVIDIA .*GT 64[0-9]M.*							3	1	0	4.2
+NVIDIA GT 650M							.*NVIDIA .*GT 65[0-9]M.*							3	1	0	4.2
+NVIDIA GTX 660M							.*NVIDIA .*GTX 66[0-9]M.*							5	1	0	4.3
+NVIDIA GTX 670M							.*NVIDIA .*GTX 67[0-9]M.*							5	1	1	4.2
+NVIDIA GTX 680M							.*NVIDIA .*GTX 68[0-9]M.*							5	1	0	4.2
+NVIDIA GTX 690M							.*NVIDIA .*GTX 69[0-9]M.*							5	1	0	0
 NVIDIA G100								.*NVIDIA .*G10.*									3	1	1	4.2
-NVIDIA GT 120							.*NVIDIA .*GT *12.*						2	1	0	3
-NVIDIA GT 130							.*NVIDIA .*GT *13.*						2	1	0	3.3
-NVIDIA GTS 150							.*NVIDIA .*GTS *15.*					2	1	0	0
+NVIDIA GT 120							.*NVIDIA .*GT 12.*									2	1	0	3.3
+NVIDIA GT 130							.*NVIDIA .*GT 13.*									2	1	0	3.3
+NVIDIA GT 140							.*NVIDIA .*GT 14.*									2	1	0	3.3
+NVIDIA GTS 150							.*NVIDIA .*GTS 15.*									2	1	0	0
 NVIDIA 200								.*NVIDIA .*GeForce 20.*								2	1	1	3.3
 NVIDIA G200								.*NVIDIA .*GeForce G20.*							2	1	1	3.3
 NVIDIA G210								.*NVIDIA .*GeForce G210.*							3	1	1	3.3
 NVIDIA 210								.*NVIDIA .*GeForce 210.*							3	1	1	3.3
-NVIDIA GT 220							.*NVIDIA .*GT *22.*						2	1	1	3.3
-NVIDIA GT 230							.*NVIDIA .*GT *23.*						2	1	1	3.3
-NVIDIA GT 240							.*NVIDIA .*GT *24.*						4	1	1	3.3
-NVIDIA GTS 240							.*NVIDIA .*GTS *24.*					4	1	1	3.3
-NVIDIA GTS 250							.*NVIDIA .*GTS *25.*					4	1	1	3.3
-NVIDIA GTX 260							.*NVIDIA .*GTX *26.*					4	1	1	3.3
-NVIDIA GTX 270							.*NVIDIA .*GTX *27.*					4	1	0	3.3
-NVIDIA GTX 280							.*NVIDIA .*GTX *28.*					4	1	1	3.3
-NVIDIA GTX 290							.*NVIDIA .*GTX *29.*					5	1	0	3.3
+NVIDIA GT 220							.*NVIDIA .*GT 22.*									2	1	1	3.3
+NVIDIA GT 230							.*NVIDIA .*GT 23.*									2	1	1	3.3
+NVIDIA GT 240							.*NVIDIA .*GT 24.*									4	1	1	3.3
+NVIDIA GTS 240							.*NVIDIA .*GTS 24.*									4	1	1	3.3
+NVIDIA GTS 250							.*NVIDIA .*GTS 25.*									4	1	1	3.3
+NVIDIA GTX 260							.*NVIDIA .*GTX 26.*									4	1	1	3.3
+NVIDIA GTX 270							.*NVIDIA .*GTX 27.*									4	1	0	3.3
+NVIDIA GTX 280							.*NVIDIA .*GTX 28.*									4	1	1	3.3
+NVIDIA GTX 290							.*NVIDIA .*GTX 29.*									5	1	0	3.3
 NVIDIA 310								.*NVIDIA .*GeForce 310.*							3	1	1	3.3
 NVIDIA 315								.*NVIDIA .*GeForce 315.*							3	1	1	3.3
-NVIDIA GT 320							.*NVIDIA .*GT *32.*						3	1	0	3.3
-NVIDIA GT 330							.*NVIDIA .*GT *33.*						3	1	0	3.3
-NVIDIA GT 340							.*NVIDIA .*GT *34.*						3	1	0	0
+NVIDIA GT 320							.*NVIDIA .*GT 32.*									3	1	0	3.3
+NVIDIA GT 330							.*NVIDIA .*GT 33.*									3	1	0	3.3
+NVIDIA GT 340							.*NVIDIA .*GT 34.*									3	1	0	3.3
 NVIDIA 405								.*NVIDIA .* 405.*									3	1	0	3.3
-NVIDIA GT 420							.*NVIDIA .*GT *42.*						3	1	1	4.2
-NVIDIA GT 430							.*NVIDIA .*GT *43.*						3	1	1	4.2
-NVIDIA GT 440							.*NVIDIA .*GT *44.*						4	1	0	4.2
-NVIDIA GTS 450							.*NVIDIA .*GTS *45.*					4	1	1	4.2
-NVIDIA GTX 460							.*NVIDIA .*GTX *46.*					5	1	1	4.3
-NVIDIA GTX 470							.*NVIDIA .*GTX *47.*					5	1	1	4.2
-NVIDIA GTX 480							.*NVIDIA .*GTX *48.*					5	1	1	4.2
-NVIDIA 510								.*NVIDIA .* 510.*						3	1	0	0
-NVIDIA GT 520							.*NVIDIA .*GT *52.*						3	1	1	4.2
-NVIDIA GT 530							.*NVIDIA .*GT *53.*						3	1	1	4.2
-NVIDIA GT 540							.*NVIDIA .*GT *54.*						3	1	1	4.2
-NVIDIA GTX 550							.*NVIDIA .*GTX *55.*					5	1	1	4.3
-NVIDIA GTX 560							.*NVIDIA .*GTX *56.*					5	1	1	4.2
-NVIDIA GTX 570							.*NVIDIA .*GTX *57.*					5	1	1	4.2
-NVIDIA GTX 580							.*NVIDIA .*GTX *58.*					5	1	1	4.3
-NVIDIA GTX 590							.*NVIDIA .*GTX *59.*					5	1	1	4.2
-NVIDIA GT 610							.*NVIDIA .*GT *61.*						3	1	1	4.2
-NVIDIA GT 620							.*NVIDIA .*GT *62.*						3	1	0	4.2
-NVIDIA GT 630							.*NVIDIA .*GT *63.*						3	1	0	4.2
-NVIDIA GT 640							.*NVIDIA .*GT *64.*						3	1	0	4.3
-NVIDIA GT 650							.*NVIDIA .*GT *65.*						3	1	1	4.2
-NVIDIA GTX 650							.*NVIDIA .*GTX *65.*					3	1	1	4.2
-NVIDIA GTX 660							.*NVIDIA .*GTX *66.*					5	1	0	4.3
-NVIDIA GTX 670							.*NVIDIA .*GTX *67.*					5	1	1	4.2
-NVIDIA GTX 680							.*NVIDIA .*GTX *68.*					5	1	1	4.2
-NVIDIA GTX 690							.*NVIDIA .*GTX *69.*					5	1	1	4.2
+NVIDIA GT 420							.*NVIDIA .*GT 42.*									3	1	1	4.2
+NVIDIA GT 430							.*NVIDIA .*GT 43.*									3	1	1	4.3
+NVIDIA GT 440							.*NVIDIA .*GT 44.*									4	1	0	4.3
+NVIDIA GTS 450							.*NVIDIA .*GTS 45.*									4	1	1	4.2
+NVIDIA GTX 460							.*NVIDIA .*GTX 46.*									5	1	1	4.3
+NVIDIA GTX 470							.*NVIDIA .*GTX 47.*									5	1	1	4.2
+NVIDIA GTX 480							.*NVIDIA .*GTX 48.*									5	1	1	4.2
+NVIDIA 510								.*NVIDIA .* 510.*									3	1	0	4.2
+NVIDIA GT 520							.*NVIDIA .*GT 52.*									3	1	1	4.2
+NVIDIA GT 530							.*NVIDIA .*GT 53.*									3	1	1	4.2
+NVIDIA GT 540							.*NVIDIA .*GT 54.*									3	1	1	4.2
+NVIDIA GTX 550							.*NVIDIA .*GTX 55.*									5	1	1	4.3
+NVIDIA GTX 560							.*NVIDIA .*GTX 56.*									5	1	1	4.3
+NVIDIA GTX 570							.*NVIDIA .*GTX 57.*									5	1	1	4.2
+NVIDIA GTX 580							.*NVIDIA .*GTX 58.*									5	1	1	4.3
+NVIDIA GTX 590							.*NVIDIA .*GTX 59.*									5	1	1	4.2
+NVIDIA 605								.*NVIDIA .* 605.*									3	1	1	4.2
+NVIDIA GT 610							.*NVIDIA .*GT 61.*									3	1	1	4.2
+NVIDIA GT 620							.*NVIDIA .*GT 62.*									3	1	0	4.2
+NVIDIA GT 630							.*NVIDIA .*GT 63.*									3	1	0	4.2
+NVIDIA GT 640							.*NVIDIA .*GT 64.*									3	1	0	4.2
+NVIDIA GT 650							.*NVIDIA .*GT 65.*									3	1	1	4.2
+NVIDIA GTX 650							.*NVIDIA .*GTX 65.*									3	1	1	4.2
+NVIDIA GTX 660							.*NVIDIA .*GTX 66.*									5	1	0	4.3
+NVIDIA GTX 670							.*NVIDIA .*GTX 67.*									5	1	1	4.2
+NVIDIA GTX 680							.*NVIDIA .*GTX 68.*									5	1	1	4.2
+NVIDIA GTX 690							.*NVIDIA .*GTX 69.*									5	1	1	4.2
 NVIDIA C51								.*NVIDIA .*C51.*									0	1	1	2
 NVIDIA G72								.*NVIDIA .*G72.*									1	1	0	0
 NVIDIA G73								.*NVIDIA .*G73.*									1	1	0	0
@@ -437,13 +407,7 @@ NVIDIA G86								.*NVIDIA .*G86.*									3	1	0	0
 NVIDIA G92								.*NVIDIA .*G92.*									3	1	0	0
 NVIDIA GeForce							.*GeForce 256.*										0	0	0	0
 NVIDIA GeForce 2						.*GeForce ?2 ?.*									0	1	1	1.5
-NVIDIA GeForce 3						.*GeForce ?3 ?.*						2	1	1	2.1
-NVIDIA GeForce 3 Ti						.*GeForce ?3 Ti.*						0	1	0	0
 NVIDIA GeForce 4						.*NVIDIA .*GeForce ?4.*								0	1	1	1.5
-NVIDIA GeForce 4 Go						.*NVIDIA .*GeForce ?4.*Go.*				0	1	0	0
-NVIDIA GeForce 4 MX						.*NVIDIA .*GeForce ?4 MX.*				0	1	0	0
-NVIDIA GeForce 4 PCX					.*NVIDIA .*GeForce ?4 PCX.*				0	1	0	0
-NVIDIA GeForce 4 Ti						.*NVIDIA .*GeForce ?4 Ti.*				0	1	0	0
 NVIDIA GeForce 6100						.*NVIDIA .*GeForce 61.*								3	1	1	4.2
 NVIDIA GeForce 6200						.*NVIDIA .*GeForce 62.*								0	1	1	2.1
 NVIDIA GeForce 6500						.*NVIDIA .*GeForce 65.*								1	1	1	2.1
@@ -458,33 +422,33 @@ NVIDIA GeForce 7500						.*NVIDIA .*GeForce 75.*								2	1	1	2.1
 NVIDIA GeForce 7600						.*NVIDIA .*GeForce 76.*								2	1	1	2.1
 NVIDIA GeForce 7800						.*NVIDIA .*GeForce 78.*								2	1	1	2.1
 NVIDIA GeForce 7900						.*NVIDIA .*GeForce 79.*								3	1	1	2.1
-NVIDIA GeForce 8100						.*NVIDIA .*GeForce 81.*					1	1	0	0
-NVIDIA GeForce 8200M					.*NVIDIA .*GeForce 8200M.*				1	1	0	3.3
-NVIDIA GeForce 8200						.*NVIDIA .*GeForce 82.*					1	1	0	2.1
+NVIDIA GeForce 8100						.*NVIDIA .*GeForce 81.*								1	1	0	3.3
+NVIDIA GeForce 8200M					.*NVIDIA .*GeForce 820[0-9]M.*						1	1	0	3.3
+NVIDIA GeForce 8200						.*NVIDIA .*GeForce 82.*								1	1	0	3.3
 NVIDIA GeForce 8300						.*NVIDIA .*GeForce 83.*								3	1	1	3.3
-NVIDIA GeForce 8400M					.*NVIDIA .*GeForce 8400M.*				1	1	1	3.3
+NVIDIA GeForce 8400M					.*NVIDIA .*GeForce 840[0-9]M.*						1	1	1	3.3
 NVIDIA GeForce 8400						.*NVIDIA .*GeForce 84.*								2	1	1	3.3
 NVIDIA GeForce 8500						.*NVIDIA .*GeForce 85.*								2	1	1	3.3
-NVIDIA GeForce 8600M					.*NVIDIA .*GeForce 8600M.*				2	1	1	3.3
+NVIDIA GeForce 8600M					.*NVIDIA .*GeForce 860[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 8600						.*NVIDIA .*GeForce 86.*								3	1	1	3.3
-NVIDIA GeForce 8700M					.*NVIDIA .*GeForce 8700M.*				2	1	1	3.3
+NVIDIA GeForce 8700M					.*NVIDIA .*GeForce 870[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 8700						.*NVIDIA .*GeForce 87.*								3	1	0	0
-NVIDIA GeForce 8800M					.*NVIDIA .*GeForce 8800M.*				2	1	1	3.3
+NVIDIA GeForce 8800M					.*NVIDIA .*GeForce 880[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 8800						.*NVIDIA .*GeForce 88.*								3	1	1	3.3
-NVIDIA GeForce 9100M					.*NVIDIA .*GeForce 9100M.*				0	1	0	0
+NVIDIA GeForce 9100M					.*NVIDIA .*GeForce 910[0-9]M.*						0	1	0	3.3
 NVIDIA GeForce 9100						.*NVIDIA .*GeForce 91.*								0	1	0	3.3
-NVIDIA GeForce 9200M					.*NVIDIA .*GeForce 9200M.*				1	1	0	3.1
+NVIDIA GeForce 9200M					.*NVIDIA .*GeForce 920[0-9]M.*						1	1	0	3.3
 NVIDIA GeForce 9200						.*NVIDIA .*GeForce 92.*								1	1	0	3.3
-NVIDIA GeForce 9300M					.*NVIDIA .*GeForce 9300M.*				1	1	1	3.3
+NVIDIA GeForce 9300M					.*NVIDIA .*GeForce 930[0-9]M.*						1	1	1	3.3
 NVIDIA GeForce 9300						.*NVIDIA .*GeForce 93.*								1	1	1	3.3
-NVIDIA GeForce 9400M					.*NVIDIA .*GeForce 9400M.*				2	1	1	3.3
+NVIDIA GeForce 9400M					.*NVIDIA .*GeForce 940[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 9400						.*NVIDIA .*GeForce 94.*								3	1	1	3.3
-NVIDIA GeForce 9500M					.*NVIDIA .*GeForce 9500M.*				1	1	1	3.3
+NVIDIA GeForce 9500M					.*NVIDIA .*GeForce 950[0-9]M.*						1	1	1	3.3
 NVIDIA GeForce 9500						.*NVIDIA .*GeForce 95.*								3	1	1	3.3
-NVIDIA GeForce 9600M					.*NVIDIA .*GeForce 9600M.*				2	1	1	3.3
+NVIDIA GeForce 9600M					.*NVIDIA .*GeForce 960[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 9600						.*NVIDIA .*GeForce 96.*								3	1	1	3.3
-NVIDIA GeForce 9700M					.*NVIDIA .*GeForce 9700M.*				0	1	1	3.3
-NVIDIA GeForce 9800M					.*NVIDIA .*GeForce 9800M.*				2	1	1	3.3
+NVIDIA GeForce 9700M					.*NVIDIA .*GeForce 970[0-9]M.*						0	1	1	3.3
+NVIDIA GeForce 9800M					.*NVIDIA .*GeForce 980[0-9]M.*						2	1	1	3.3
 NVIDIA GeForce 9800						.*NVIDIA .*GeForce 98.*								3	1	1	3.3
 NVIDIA GeForce FX 5100					.*NVIDIA .*GeForce FX 51.*							0	1	0	0
 NVIDIA GeForce FX 5200					.*NVIDIA .*GeForce FX 52.*							0	1	0	2.1
@@ -495,7 +459,7 @@ NVIDIA GeForce FX 5700					.*NVIDIA .*GeForce FX 57.*							0	1	1	2.1
 NVIDIA GeForce FX 5800					.*NVIDIA .*GeForce FX 58.*							1	1	0	0
 NVIDIA GeForce FX 5900					.*NVIDIA .*GeForce FX 59.*							1	1	1	2.1
 NVIDIA GeForce FX Go5100				.*NVIDIA .*GeForce FX Go51.*						0	1	0	0
-NVIDIA GeForce FX Go5200				.*NVIDIA .*GeForce FX Go52.*			0	1	0	0
+NVIDIA GeForce FX Go5200				.*NVIDIA .*GeForce FX Go52.*						0	1	0	1.5
 NVIDIA GeForce FX Go5300				.*NVIDIA .*GeForce FX Go53.*						0	1	0	0
 NVIDIA GeForce FX Go5500				.*NVIDIA .*GeForce FX Go55.*						0	1	0	0
 NVIDIA GeForce FX Go5600				.*NVIDIA .*GeForce FX Go56.*						0	1	1	2.1
@@ -504,13 +468,13 @@ NVIDIA GeForce FX Go5800				.*NVIDIA .*GeForce FX Go58.*						1	1	0	0
 NVIDIA GeForce FX Go5900				.*NVIDIA .*GeForce FX Go59.*						1	1	0	0
 NVIDIA GeForce FX Go5xxx				.*NVIDIA .*GeForce FX Go.*							0	1	0	0
 NVIDIA GeForce Go 6100					.*NVIDIA .*GeForce Go 61.*							0	1	1	2.1
-NVIDIA GeForce Go 6200					.*NVIDIA .*GeForce Go 62.*				0	1	0	0
-NVIDIA GeForce Go 6400					.*NVIDIA .*GeForce Go 64.*				1	1	1	2
+NVIDIA GeForce Go 6200					.*NVIDIA .*GeForce Go 62.*							0	1	0	1.5
+NVIDIA GeForce Go 6400					.*NVIDIA .*GeForce Go 64.*							1	1	1	2.1
 NVIDIA GeForce Go 6500					.*NVIDIA .*GeForce Go 65.*							1	1	0	0
 NVIDIA GeForce Go 6600					.*NVIDIA .*GeForce Go 66.*							0	1	1	2.1
 NVIDIA GeForce Go 6700					.*NVIDIA .*GeForce Go 67.*							1	1	0	0
 NVIDIA GeForce Go 6800					.*NVIDIA .*GeForce Go 68.*							0	1	1	2.1
-NVIDIA GeForce Go 7200					.*NVIDIA .*GeForce Go 72.*				1	1	0	0
+NVIDIA GeForce Go 7200					.*NVIDIA .*GeForce Go 72.*							1	1	0	2.1
 NVIDIA GeForce Go 7300 LE				.*NVIDIA .*GeForce Go 73.*LE.*						1	1	0	0
 NVIDIA GeForce Go 7300					.*NVIDIA .*GeForce Go 73.*							1	1	1	2.1
 NVIDIA GeForce Go 7400					.*NVIDIA .*GeForce Go 74.*							1	1	1	2.1
@@ -528,9 +492,9 @@ NVIDIA NB8P								.*NVIDIA .*NB8P.*									2	1	0	0
 NVIDIA NB9E								.*NVIDIA .*NB9E.*									3	1	0	0
 NVIDIA NB9M								.*NVIDIA .*NB9M.*									1	1	0	0
 NVIDIA NB9P								.*NVIDIA .*NB9P.*									2	1	0	0
-NVIDIA N10								.*NVIDIA .*N10.*						1	1	0	0
-NVIDIA GeForce PCX						.*GeForce PCX.*							0	1	0	0
-NVIDIA Generic							.*NVIDIA .*Unknown.*					0	0	0	3
+NVIDIA N10								.*NVIDIA .*N10.*									1	1	0	2.1
+NVIDIA GeForce PCX						.*GeForce PCX.*										0	1	0	1.5
+NVIDIA Generic							.*NVIDIA .*Unknown.*								0	0	0	2.1
 NVIDIA NV17								.*NVIDIA .*NV17.*									0	1	0	0
 NVIDIA NV34								.*NVIDIA .*NV34.*									0	1	0	0
 NVIDIA NV35								.*NVIDIA .*NV35.*									0	1	0	0
@@ -540,7 +504,7 @@ NVIDIA NV43								.*NVIDIA .*NV43.*									1	1	0	0
 NVIDIA NV44								.*NVIDIA .*NV44.*									1	1	0	0
 NVIDIA nForce							.*NVIDIA .*nForce.*									0	0	0	3.3
 NVIDIA MCP51							.*NVIDIA .*MCP51.*									1	1	0	0
-NVIDIA MCP61							.*NVIDIA .*MCP61.*						1	1	0	0
+NVIDIA MCP61							.*NVIDIA .*MCP61.*									1	1	0	2.1
 NVIDIA MCP67							.*NVIDIA .*MCP67.*									1	1	0	0
 NVIDIA MCP68							.*NVIDIA .*MCP68.*									1	1	0	0
 NVIDIA MCP73							.*NVIDIA .*MCP73.*									1	1	0	0
@@ -548,44 +512,44 @@ NVIDIA MCP77							.*NVIDIA .*MCP77.*									1	1	0	0
 NVIDIA MCP78							.*NVIDIA .*MCP78.*									1	1	0	0
 NVIDIA MCP79							.*NVIDIA .*MCP79.*									1	1	0	0
 NVIDIA MCP7A							.*NVIDIA .*MCP7A.*									1	1	0	0
-NVIDIA Quadro2							.*Quadro2.*								0	1	0	0
-NVIDIA Quadro 1000M						.*Quadro.*1000M.*						2	1	0	4.2
-NVIDIA Quadro 2000 M/D					.*Quadro.*2000.*						3	1	0	4.2
-NVIDIA Quadro 3000M						.*Quadro.*3000M.*						3	1	0	0
-NVIDIA Quadro 4000M						.*Quadro.*4000M.*						3	1	0	0
-NVIDIA Quadro 4000						.*Quadro *4000.*						3	1	0	4.2
-NVIDIA Quadro 50x0 M					.*Quadro.*50.0.*						3	1	0	0
+NVIDIA Quadro2							.*Quadro2.*											0	1	0	1.5
+NVIDIA Quadro 1000M						.*Quadro.* (K1|1)00[0-9]M.*							2	1	0	4.2
+NVIDIA Quadro 2000 M/D					.*Quadro.* (K2|2)000.*								3	1	0	4.2
+NVIDIA Quadro 3000M						.*Quadro.* (K3|3)00[0-9]M.*							3	1	0	4.2
+NVIDIA Quadro 4000M						.*Quadro.* (K4|4)00[0-9]M.*							3	1	0	4.2
+NVIDIA Quadro 4000						.*Quadro 4000.*										3	1	0	4.2
+NVIDIA Quadro 50x0 M					.*Quadro.* 50.0.*									3	1	0	4.2
 NVIDIA Quadro 6000						.*Quadro.* 6000.*									3	1	0	0
 NVIDIA Quadro 400						.*Quadro.* 400.*									2	1	0	3.3
-NVIDIA Quadro 600						.*Quadro.*600.*							2	1	0	3.3
-NVIDIA Quadro4							.*Quadro4.*								0	1	0	0
+NVIDIA Quadro 600						.*Quadro.* 600.*									2	1	0	4.2
+NVIDIA Quadro4							.*Quadro4.*											0	1	0	1.5
 NVIDIA Quadro DCC						.*Quadro DCC.*										0	1	0	0
 NVIDIA Quadro CX						.*Quadro.*CX.*										3	1	0	0
-NVIDIA Quadro FX 770M					.*Quadro.*FX *770M.*					2	1	0	0
-NVIDIA Quadro FX 1500M					.*Quadro.*FX *1500M.*					1	1	0	2.1
-NVIDIA Quadro FX 1600M					.*Quadro.*FX *1600M.*					2	1	0	0
-NVIDIA Quadro FX 2500M					.*Quadro.*FX *2500M.*					2	1	0	0
-NVIDIA Quadro FX 2700M					.*Quadro.*FX *2700M.*					3	1	0	0
-NVIDIA Quadro FX 2800M					.*Quadro.*FX *2800M.*					3	1	0	3.3
-NVIDIA Quadro FX 3500					.*Quadro.*FX *3500.*					2	1	0	2.1
-NVIDIA Quadro FX 3600					.*Quadro.*FX *3600.*					3	1	0	0
-NVIDIA Quadro FX 3700					.*Quadro.*FX *3700.*					3	1	0	3.3
-NVIDIA Quadro FX 3800					.*Quadro.*FX *3800.*					3	1	0	3.2
-NVIDIA Quadro FX 4500					.*Quadro.*FX *45.*						3	1	0	0
-NVIDIA Quadro FX 880M					.*Quadro.*FX *880M.*					3	1	0	3.3
-NVIDIA Quadro FX 4800					.*NVIDIA .*Quadro *FX *4800.*			3	1	0	0
+NVIDIA Quadro FX 770M					.*Quadro.*FX 77[0-9]M.*								2	1	0	3.3
+NVIDIA Quadro FX 1500M					.*Quadro.*FX 150[0-9]M.*							1	1	0	2.1
+NVIDIA Quadro FX 1600M					.*Quadro.*FX 160[0-9]M.*							2	1	0	3.3
+NVIDIA Quadro FX 2500M					.*Quadro.*FX 250[0-9]M.*							2	1	0	2.1
+NVIDIA Quadro FX 2700M					.*Quadro.*FX 270[0-9]M.*							3	1	0	3.3
+NVIDIA Quadro FX 2800M					.*Quadro.*FX 280[0-9]M.*							3	1	0	3.3
+NVIDIA Quadro FX 3500					.*Quadro.*FX 3500.*									2	1	0	2.1
+NVIDIA Quadro FX 3600					.*Quadro.*FX 3600.*									3	1	0	3.3
+NVIDIA Quadro FX 3700					.*Quadro.*FX 3700.*									3	1	0	3.3
+NVIDIA Quadro FX 3800					.*Quadro.*FX 3800.*									3	1	0	3.3
+NVIDIA Quadro FX 4500					.*Quadro.*FX 45.*									3	1	0	2.1
+NVIDIA Quadro FX 880M					.*Quadro.*FX 88[0-9]M.*								3	1	0	3.3
+NVIDIA Quadro FX 4800					.*NVIDIA .*Quadro FX 4800.*							3	1	0	3.1
 NVIDIA Quadro FX						.*Quadro FX.*										1	1	0	3.3
-NVIDIA Quadro NVS 1xxM					.*Quadro NVS *1.[05]M.*					0	1	1	3.3
-NVIDIA Quadro NVS 300M					.*NVIDIA .*NVS *300M.*					2	1	0	0
-NVIDIA Quadro NVS 320M					.*NVIDIA .*NVS *320M.*					2	1	0	0
-NVIDIA Quadro NVS 2100M					.*NVIDIA .*NVS *2100M.*					2	1	0	0
-NVIDIA Quadro NVS 3100M					.*NVIDIA .*NVS *3100M.*					2	1	0	0
-NVIDIA Quadro NVS 4200M					.*NVIDIA .*NVS *4200M.*					2	1	0	4.1
-NVIDIA Quadro NVS 5100M					.*NVIDIA .*NVS *5100M.*					2	1	0	0
-NVIDIA Quadro NVS						.*NVIDIA .*NVS							0	1	0	3.2
+NVIDIA Quadro NVS 1xxM					.*Quadro NVS 1.[05]M.*								0	1	1	3.3
+NVIDIA Quadro NVS 300M					.*NVIDIA .*NVS 30[0-9]M.*							2	1	0	0
+NVIDIA Quadro NVS 320M					.*NVIDIA .*NVS 32[0-9]M.*							2	1	0	0
+NVIDIA Quadro NVS 2100M					.*NVIDIA .*NVS 210[0-9]M.*							2	1	0	3.3
+NVIDIA Quadro NVS 3100M					.*NVIDIA .*NVS 310[0-9]M.*							2	1	0	3.3
+NVIDIA Quadro NVS 4200M					.*NVIDIA .*NVS 420[0-9]M.*							2	1	0	4.2
+NVIDIA Quadro NVS 5100M					.*NVIDIA .*NVS 510[0-9]M.*							2	1	0	0
+NVIDIA Quadro NVS						.*NVIDIA .*NVS										0	1	0	4.2
 NVIDIA Corporation N12P					.*NVIDIA .*N12P.*									1	1	1	4.1
-NVIDIA Corporation N11M					.*NVIDIA .*N11M.*						2	1	0	0
-NVIDIA RIVA TNT							.*RIVA TNT.*							0	0	0	0
+NVIDIA Corporation N11M					.*NVIDIA .*N11M.*									2	1	0	3.1
+NVIDIA RIVA TNT							.*RIVA TNT.*										0	0	0	1.5
 S3										.*S3 Graphics.*										0	0	1	1.4
 SiS										SiS.*												0	0	1	1.5
 Trident									Trident.*											0	0	0	0
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index d8440eebf1c54c4b8a1f687a666285229c71c330..c23401d5a661fd954536fadf9c9b8fa0c7da3779 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -121,37 +121,21 @@ export SAVED_LD_LIBRARY_PATH="${LD_LIBRARY_PATH}"
 
 export LD_LIBRARY_PATH="$PWD/lib:${LD_LIBRARY_PATH}"
 
-# Have to deal specially with gridargs.dat; typical contents look like:
-# --channel "Second Life Test"  --settings settings_test.xml
-# Simply embedding $(<etc/gridargs.dat) into a command line treats each of
-# Second, Life and Developer as separate args -- no good. We need bash to
-# process quotes using eval.
-# First, check if we have been instructed to skip reading in gridargs.dat:
-skip_gridargs=false
-argnum=0
+# Copy "$@" to ARGS array specifically to delete the --skip-gridargs switch.
+# The gridargs.dat file is no more, but we still want to avoid breaking
+# scripts that invoke this one with --skip-gridargs.
+ARGS=()
 for ARG in "$@"; do
-    if [ "--skip-gridargs" == "$ARG" ]; then
-        skip_gridargs=true
-    else
-        ARGS[$argnum]="$ARG"
-        argnum=$(($argnum+1))
+    if [ "--skip-gridargs" != "$ARG" ]; then
+        ARGS[${#ARGS[*]}]="$ARG"
     fi
 done
 
-# Second, read it without scanning, then scan that string. Break quoted words
-# into a bash array. Note that if gridargs.dat is empty, or contains only
-# whitespace, the resulting gridargs array will be empty -- zero entries --
-# therefore "${gridargs[@]}" entirely vanishes from the command line below,
-# just as we want.
-if ! $skip_gridargs ; then
-    eval gridargs=("$(<etc/gridargs.dat)")
-fi
-
 # Run the program.
 # Don't quote $LL_WRAPPER because, if empty, it should simply vanish from the
-# command line. But DO quote "$@": preserve separate args as individually
-# quoted. Similar remarks about the contents of gridargs.
-$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${gridargs[@]}" "${ARGS[@]}"
+# command line. But DO quote "${ARGS[@]}": preserve separate args as
+# individually quoted.
+$LL_WRAPPER bin/do-not-directly-run-secondlife-bin "${ARGS[@]}"
 LL_RUN_ERR=$?
 
 # Handle any resulting errors
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index f960b31cc7b42bc8160b0810dfb9b3a51ff7fb79..f4ce3c9118c216d9c6c5de7c2ad97e99ac3dceb8 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -435,7 +435,7 @@ void LLAgent::init()
 {
 	mMoveTimer.start();
 
-	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", FALSE);
+	gSavedSettings.declareBOOL("SlowMotionAnimation", FALSE, "Declared in code", LLControlVariable::PERSIST_NO);
 	gSavedSettings.getControl("SlowMotionAnimation")->getSignal()->connect(boost::bind(&handleSlowMotionAnimation, _2));
 	
 	// *Note: this is where LLViewerCamera::getInstance() used to be constructed.
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f92274dbbd84d0ed7b80bab78b745b4355ef61ac..003d82dd0e7d374989dfde840eeeb3547b9da119 100755
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -668,7 +668,6 @@ LLAppViewer::LLAppViewer() :
 	mSecondInstance(false),
 	mSavedFinalSnapshot(false),
 	mSavePerAccountSettings(false),		// don't save settings on logout unless login succeeded.
-	mForceGraphicsDetail(false),
 	mQuitRequested(false),
 	mLogoutRequestSent(false),
 	mYieldTime(-1),
@@ -2307,17 +2306,24 @@ void LLAppViewer::loadColorSettings()
 	LLUIColorTable::instance().loadFromSettings();
 }
 
+namespace
+{
+    void handleCommandLineError(LLControlGroupCLP& clp)
+    {
+		llwarns << "Error parsing command line options. Command Line options ignored."  << llendl;
+
+		llinfos << "Command line usage:\n" << clp << llendl;
+
+		OSMessageBox(STRINGIZE(LLTrans::getString("MBCmdLineError") << clp.getErrorMessage()),
+					 LLStringUtil::null,
+					 OSMB_OK);
+    }
+} // anonymous namespace
+
 bool LLAppViewer::initConfiguration()
 {	
 	//Load settings files list
 	std::string settings_file_list = gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "settings_files.xml");
-	//LLControlGroup settings_control("SettingsFiles");
-	//llinfos << "Loading settings file list " << settings_file_list << llendl;
-	//if (0 == settings_control.loadFromFile(settings_file_list))
-	//{
- //       llerrs << "Cannot load default configuration file " << settings_file_list << llendl;
-	//}
-
 	LLXMLNodePtr root;
 	BOOL success  = LLXMLNode::parseFile(settings_file_list, root, NULL);
 	if (!success)
@@ -2376,9 +2382,7 @@ bool LLAppViewer::initConfiguration()
 	{
 		c->setValue(true, false);
 	}
-#endif
 
-#ifndef	LL_RELEASE_FOR_DOWNLOAD
 	gSavedSettings.setBOOL("QAMode", TRUE );
 	gSavedSettings.setS32("WatchdogEnabled", 0);
 #endif
@@ -2414,13 +2418,7 @@ bool LLAppViewer::initConfiguration()
 
 	if(!initParseCommandLine(clp))
 	{
-		llwarns	<< "Error parsing command line options.	Command	Line options ignored."  << llendl;
-		
-		llinfos	<< "Command	line usage:\n" << clp << llendl;
-
-		std::ostringstream msg;
-		msg << LLTrans::getString("MBCmdLineError") << clp.getErrorMessage();
-		OSMessageBox(msg.str(),LLStringUtil::null,OSMB_OK);
+		handleCommandLineError(clp);
 		return false;
 	}
 	
@@ -2467,12 +2465,16 @@ bool LLAppViewer::initConfiguration()
 	loadSettingsFromDirectory("UserSession");
 
 	// - apply command line settings 
-	clp.notify(); 
+	if (! clp.notify())
+	{
+		handleCommandLineError(clp);
+		return false;
+	}
 
 	// Register the core crash option as soon as we can
 	// if we want gdb post-mortem on cores we need to be up and running
 	// ASAP or we might miss init issue etc.
-	if(clp.hasOption("disablecrashlogger"))
+	if(gSavedSettings.getBOOL("DisableCrashLogger"))
 	{
 		llwarns << "Crashes will be handled by system, stack trace logs and crash logger are both disabled" << llendl;
 		LLAppViewer::instance()->disableCrashlogger();
@@ -2545,91 +2547,52 @@ bool LLAppViewer::initConfiguration()
         }
     }
 
-    if(clp.hasOption("channel"))
-    {
-		LLVersionInfo::resetChannel(clp.getOption("channel")[0]);
+	std::string CmdLineChannel(gSavedSettings.getString("CmdLineChannel"));
+	if(! CmdLineChannel.empty())
+	{
+		LLVersionInfo::resetChannel(CmdLineChannel);
 	}
 
 	// If we have specified crash on startup, set the global so we'll trigger the crash at the right time
-	if(clp.hasOption("crashonstartup"))
-	{
-		gCrashOnStartup = TRUE;
-	}
+	gCrashOnStartup = gSavedSettings.getBOOL("CrashOnStartup");
 
-	if (clp.hasOption("logperformance"))
+	if (gSavedSettings.getBOOL("LogPerformance"))
 	{
 		LLFastTimer::sLog = TRUE;
 		LLFastTimer::sLogName = std::string("performance");		
 	}
-	
-	if (clp.hasOption("logmetrics"))
- 	{
- 		LLFastTimer::sMetricLog = TRUE ;
-		// '--logmetrics' can be specified with a named test metric argument so the data gathering is done only on that test
-		// In the absence of argument, every metric is gathered (makes for a rather slow run and hard to decipher report...)
-		std::string test_name = clp.getOption("logmetrics")[0];
+
+	std::string test_name(gSavedSettings.getString("LogMetrics"));
+	if (! test_name.empty())
+	{
+		LLFastTimer::sMetricLog = TRUE ;
+		// '--logmetrics' is specified with a named test metric argument so the data gathering is done only on that test
+		// In the absence of argument, every metric would be gathered (makes for a rather slow run and hard to decipher report...)
 		llinfos << "'--logmetrics' argument : " << test_name << llendl;
-		if (test_name == "")
-		{
-			llwarns << "No '--logmetrics' argument given, will output all metrics to " << DEFAULT_METRIC_NAME << llendl;
-			LLFastTimer::sLogName = DEFAULT_METRIC_NAME;
-		}
-		else
-		{
-			LLFastTimer::sLogName = test_name;
-		}
+		LLFastTimer::sLogName = test_name;
  	}
 
 	if (clp.hasOption("graphicslevel"))
 	{
-		const LLCommandLineParser::token_vector_t& value = clp.getOption("graphicslevel");
-        if(value.size() != 1)
-        {
-			llwarns << "Usage: -graphicslevel <0-3>" << llendl;
-        }
-        else
-        {
-			std::string detail = value.front();
-			mForceGraphicsDetail = TRUE;
-			
-			switch (detail.c_str()[0])
-			{
-				case '0': 
-					gSavedSettings.setU32("RenderQualityPerformance", 0);		
-					break;
-				case '1': 
-					gSavedSettings.setU32("RenderQualityPerformance", 1);		
-					break;
-				case '2': 
-					gSavedSettings.setU32("RenderQualityPerformance", 2);		
-					break;
-				case '3': 
-					gSavedSettings.setU32("RenderQualityPerformance", 3);		
-					break;
-				default:
-					mForceGraphicsDetail = FALSE;
-					llwarns << "Usage: -graphicslevel <0-3>" << llendl;
-					break;
-			}
-        }
-	}
-
-	if (clp.hasOption("analyzeperformance"))
-	{
-		LLFastTimerView::sAnalyzePerformance = TRUE;
+		// User explicitly requested --graphicslevel on the command line. We
+		// expect this switch has already set RenderQualityPerformance. Check
+		// that value for validity.
+		U32 graphicslevel = gSavedSettings.getU32("RenderQualityPerformance");
+		if (LLFeatureManager::instance().isValidGraphicsLevel(graphicslevel))
+		{
+			// graphicslevel is valid: save it and engage it later. Capture
+			// the requested value separately from the settings variable
+			// because, if this is the first run, LLViewerWindow's constructor
+			// will call LLFeatureManager::applyRecommendedSettings(), which
+			// overwrites this settings variable!
+			mForceGraphicsLevel = graphicslevel;
+		}
 	}
 
-	if (clp.hasOption("replaysession"))
-	{
-		gAgentPilot.setReplaySession(TRUE);
-	}
+	LLFastTimerView::sAnalyzePerformance = gSavedSettings.getBOOL("AnalyzePerformance");
+	gAgentPilot.setReplaySession(gSavedSettings.getBOOL("ReplaySession"));
 
-	if (clp.hasOption("nonotifications"))
-	{
-		gSavedSettings.getControl("IgnoreAllNotifications")->setValue(true, false);
-	}
-	
-	if (clp.hasOption("debugsession"))
+	if (gSavedSettings.getBOOL("DebugSession"))
 	{
 		gDebugSession = TRUE;
 		gDebugGL = TRUE;
@@ -2654,20 +2617,16 @@ bool LLAppViewer::initConfiguration()
     // What can happen is that someone can use IE (or potentially 
     // other browsers) and do the rough equivalent of command 
     // injection and steal passwords. Phoenix. SL-55321
-    if(clp.hasOption("url"))
-    {
-		LLStartUp::setStartSLURL(LLSLURL(clp.getOption("url")[0]));
-		if(LLStartUp::getStartSLURL().getType() == LLSLURL::LOCATION) 
-		{  
-			LLGridManager::getInstance()->setGridChoice(LLStartUp::getStartSLURL().getGrid());
-			
-		}  
-    }
-    else if(clp.hasOption("slurl"))
-    {
-		LLSLURL start_slurl(clp.getOption("slurl")[0]);
+	std::string CmdLineLoginLocation(gSavedSettings.getString("CmdLineLoginLocation"));
+	if(! CmdLineLoginLocation.empty())
+	{
+		LLSLURL start_slurl(CmdLineLoginLocation);
 		LLStartUp::setStartSLURL(start_slurl);
-    }
+		if(start_slurl.getType() == LLSLURL::LOCATION) 
+		{  
+			LLGridManager::getInstance()->setGridChoice(start_slurl.getGrid());
+		}
+	}
 
 	const LLControlVariable* skinfolder = gSavedSettings.getControl("SkinCurrent");
 	if(skinfolder && LLStringUtil::null != skinfolder->getValue().asString())
@@ -2810,9 +2769,8 @@ bool LLAppViewer::initConfiguration()
 		LL_DEBUGS("AppInit")<<"set start from NextLoginLocation: "<<nextLoginLocation<<LL_ENDL;
 		LLStartUp::setStartSLURL(LLSLURL(nextLoginLocation));
 	}
-	else if (   (   clp.hasOption("login") || clp.hasOption("autologin"))
-			 && !clp.hasOption("url")
-			 && !clp.hasOption("slurl"))
+	else if ((clp.hasOption("login") || clp.hasOption("autologin"))
+			 && gSavedSettings.getString("CmdLineLoginLocation").empty())
 	{
 		// If automatic login from command line with --login switch
 		// init StartSLURL location.
@@ -3048,13 +3006,19 @@ namespace {
 void LLAppViewer::initUpdater()
 {
 	// Initialize the updater service.
-	// Generate URL to the udpater service
 	// Get Channel
 	// Get Version
-	std::string url = gSavedSettings.getString("UpdaterServiceURL");
+
+	/*****************************************************************
+	 * Previously, the url was derived from the settings 
+	 *    UpdaterServiceURL
+	 *    UpdaterServicePath
+	 * it is now obtained from the grid manager.  The settings above
+	 * are no longer used.
+	 *****************************************************************/
 	std::string channel = LLVersionInfo::getChannel();
 	std::string version = LLVersionInfo::getVersion();
-	std::string service_path = gSavedSettings.getString("UpdaterServicePath");
+
 	U32 check_period = gSavedSettings.getU32("UpdaterServiceCheckPeriod");
 	bool willing_to_test;
 	LL_DEBUGS("UpdaterService") << "channel " << channel << LL_ENDL;
@@ -3079,9 +3043,7 @@ void LLAppViewer::initUpdater()
 	}
 
 	mUpdater->setAppExitCallback(boost::bind(&LLAppViewer::forceQuit, this));
-	mUpdater->initialize(url, 
-						 service_path, 
-						 channel, 
+	mUpdater->initialize(channel, 
 						 version,
 						 gPlatform,
 						 getOSInfo().getOSVersionString(),
@@ -3186,11 +3148,12 @@ bool LLAppViewer::initWindow()
 	// Initialize GL stuff
 	//
 
-	if (mForceGraphicsDetail)
+	if (mForceGraphicsLevel)
 	{
-		LLFeatureManager::getInstance()->setGraphicsLevel(gSavedSettings.getU32("RenderQualityPerformance"), false);
+		LLFeatureManager::getInstance()->setGraphicsLevel(*mForceGraphicsLevel, false);
+		gSavedSettings.setU32("RenderQualityPerformance", *mForceGraphicsLevel);
 	}
-			
+
 	// Set this flag in case we crash while initializing GL
 	gSavedSettings.setBOOL("RenderInitError", TRUE);
 	gSavedSettings.saveToFile( gSavedSettings.getString("ClientSettingsFile"), TRUE );
@@ -4599,11 +4562,6 @@ void LLAppViewer::idle()
 				llinfos << "Dead object updates: " << gObjectList.mNumDeadObjectUpdates << llendl;
 				gObjectList.mNumDeadObjectUpdates = 0;
 			}
-			if (gObjectList.mNumUnknownKills)
-			{
-				llinfos << "Kills on unknown objects: " << gObjectList.mNumUnknownKills << llendl;
-				gObjectList.mNumUnknownKills = 0;
-			}
 			if (gObjectList.mNumUnknownUpdates)
 			{
 				llinfos << "Unknown object updates: " << gObjectList.mNumUnknownUpdates << llendl;
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index cd91ae8b2bc9c3ba76b67418270af5c6d939790d..3af360b52991b3bcf53c9412e951f05b4da4cf6f 100755
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -32,6 +32,7 @@
 #include "llsys.h"			// for LLOSInfo
 #include "lltimer.h"
 #include "llappcorehttp.h"
+#include <boost/optional.hpp>
 
 class LLCommandLineParser;
 class LLFrameTimer;
@@ -258,7 +259,7 @@ class LLAppViewer : public LLApp
 	bool mSavedFinalSnapshot;
 	bool mSavePerAccountSettings;		// only save per account settings if login succeeded
 
-	bool mForceGraphicsDetail;
+	boost::optional<U32> mForceGraphicsLevel;
 
     bool mQuitRequested;				// User wants to quit, may have modified documents open.
     bool mLogoutRequestSent;			// Disconnect message sent to simulator, no longer safe to send messages to the sim.
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index 4d340cafa9dfed9769b5a56382e32886a611fd35..c7b437598c2d55c7f90b3ee50ea641898a97c6ff 100755
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -148,28 +148,13 @@ bool LLAppViewerMacOSX::initParseCommandLine(LLCommandLineParser& clp)
 	// The next two lines add the support for parsing the mac -psn_XXX arg.
 	clp.addOptionDesc("psn", NULL, 1, "MacOSX process serial number");
 	clp.setCustomParser(parse_psn);
-	
-    // First read in the args from arguments txt.
-    const char* filename = "arguments.txt";
-	llifstream ifs(filename, llifstream::binary);
-	if (!ifs.is_open())
-	{
-		llwarns << "Unable to open file" << filename << llendl;
-		return false;
-	}
-	
-	if(clp.parseCommandLineFile(ifs) == false)
-	{
-		return false;
-	}
 
-	// Then parse the user's command line, so that any --url arg can appear last
-	// Succesive calls to clp.parse... will NOT override earlier options. 
+	// parse the user's command line
 	if(clp.parseCommandLine(gArgC, gArgV) == false)
 	{
 		return false;
 	}
-    	
+
 	// Get the user's preferred language string based on the Mac OS localization mechanism.
 	// To add a new localization:
 		// go to the "Resources" section of the project
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 7d0331757bed74a6c3887127f417d104d105d47d..b3bc0ba966dca4760715f539dd433572a80afafd 100755
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -381,7 +381,7 @@ void LLChatBar::sendChat( EChatType type )
 			if (!utf8_revised_text.empty())
 			{
 				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
+				sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
 			}
 		}
 	}
diff --git a/indra/newview/llcommandlineparser.cpp b/indra/newview/llcommandlineparser.cpp
index 17d403bbe1040b492658123af45a8e606e99037a..a6384ded1251b67fc48578b3c5978de0553c6352 100755
--- a/indra/newview/llcommandlineparser.cpp
+++ b/indra/newview/llcommandlineparser.cpp
@@ -38,16 +38,23 @@
 #endif
 
 #include <boost/program_options.hpp>
+#include <boost/lexical_cast.hpp>
 #include <boost/bind.hpp>
-#include<boost/tokenizer.hpp>
+#include <boost/tokenizer.hpp>
+#include <boost/assign/list_of.hpp>
 
 #if _MSC_VER
 #   pragma warning(pop)
 #endif
 
 #include "llsdserialize.h"
+#include "llerror.h"
+#include "stringize.h"
+#include <string>
+#include <set>
 #include <iostream>
 #include <sstream>
+#include <typeinfo>
 
 #include "llcontrol.h"
 
@@ -63,10 +70,22 @@ namespace po = boost::program_options;
 // This could be good or bad, and probably won't matter for most use cases.
 namespace 
 {
+    // List of command-line switches that can't map-to settings variables.
+    // Going forward, we want every new command-line switch to map-to some
+    // settings variable. This list is used to validate that.
+    const std::set<std::string> unmapped_options = boost::assign::list_of
+        ("help")
+        ("set")
+        ("setdefault")
+        ("settings")
+        ("sessionsettings")
+        ("usersessionsettings")
+    ;
+
     po::options_description gOptionsDesc;
     po::positional_options_description gPositionalOptions;
 	po::variables_map gVariableMap;
-    
+
     const LLCommandLineParser::token_vector_t gEmptyValue;
 
     void read_file_into_string(std::string& str, const std::basic_istream < char >& file)
@@ -384,9 +403,19 @@ bool LLCommandLineParser::parseCommandLineFile(const std::basic_istream < char >
     return parseCommandLineString(args);
 }
 
-void LLCommandLineParser::notify()
+bool LLCommandLineParser::notify()
 {
-    po::notify(gVariableMap);    
+    try
+    {
+        po::notify(gVariableMap);
+        return true;
+    }
+    catch (const LLCLPError& e)
+    {
+        llwarns << "Caught Error: " << e.what() << llendl;
+        mErrorMsg = e.what();
+        return false;
+    }
 }
 
 void LLCommandLineParser::printOptions() const
@@ -428,43 +457,129 @@ const LLCommandLineParser::token_vector_t& LLCommandLineParser::getOption(const
 //----------------------------------------------------------------------------
 // LLControlGroupCLP defintions
 //----------------------------------------------------------------------------
+namespace {
+LLCommandLineParser::token_vector_t::value_type
+onevalue(const std::string& option,
+         const LLCommandLineParser::token_vector_t& value)
+{
+    if (value.empty())
+    {
+        // What does it mean when the user specifies a command-line switch
+        // that requires a value, but omits the value? Complain.
+        throw LLCLPError(STRINGIZE("No value specified for --" << option << "!"));
+    }
+    else if (value.size() > 1)
+    {
+        llwarns << "Ignoring extra tokens specified for --"
+                << option << "." << llendl; 
+    }
+    return value[0];
+}
+
+void badvalue(const std::string& option,
+              const std::string& varname,
+              const std::string& type,
+              const std::string& value)
+{
+    // If the user passes an unusable value for a command-line switch, it
+    // seems like a really bad idea to just ignore it, even with a log
+    // warning.
+    throw LLCLPError(STRINGIZE("Invalid value specified by command-line switch '" << option
+                               << "' for variable '" << varname << "' of type " << type
+                               << ": '" << value << "'"));
+}
+
+template <typename T>
+T convertTo(const std::string& option,
+            const std::string& varname,
+            const LLCommandLineParser::token_vector_t::value_type& value)
+{
+    try
+    {
+        return boost::lexical_cast<T>(value);
+    }
+    catch (const boost::bad_lexical_cast&)
+    {
+        badvalue(option, varname, typeid(T).name(), value);
+        // bogus return; compiler unaware that badvalue() won't return
+        return T();
+    }
+}
+
 void setControlValueCB(const LLCommandLineParser::token_vector_t& value, 
-                       const std::string& opt_name, 
-                       LLControlGroup* ctrlGroup)
+                       const std::string& option, 
+                       LLControlVariable* ctrl)
 {
-    // *FIX: Do sematic conversion here.
+    // *FIX: Do semantic conversion here.
     // LLSD (ImplString) Is no good for doing string to type conversion for...
     // booleans
     // compound types
     // ?...
 
-    LLControlVariable* ctrl = ctrlGroup->getControl(opt_name);
     if(NULL != ctrl)
     {
         switch(ctrl->type())
         {
         case TYPE_BOOLEAN:
-            if(value.size() > 1)
+            if (value.empty())
             {
-                llwarns << "Ignoring extra tokens." << llendl; 
+                // Boolean-valued command-line switches are unusual. If you
+                // simply specify the switch without an explicit value, we can
+                // infer you mean 'true'.
+                ctrl->setValue(LLSD(true), false);
             }
-              
-            if(value.size() > 0)
+            else
             {
+                // Only call onevalue() AFTER handling value.empty() case!
+                std::string token(onevalue(option, value));
+            
                 // There's a token. check the string for true/false/1/0 etc.
                 BOOL result = false;
-                BOOL gotSet = LLStringUtil::convertToBOOL(value[0], result);
-                if(gotSet)
+                BOOL gotSet = LLStringUtil::convertToBOOL(token, result);
+                if (gotSet)
                 {
                     ctrl->setValue(LLSD(result), false);
                 }
+                else
+                {
+                    badvalue(option, ctrl->getName(), "bool", token);
+                }
+            }
+            break;
+
+        case TYPE_U32:
+        {
+            std::string token(onevalue(option, value));
+            // To my surprise, for an unsigned target, lexical_cast() doesn't
+            // complain about an input string such as "-17". In that case, you
+            // get a very large positive result. So for U32, make sure there's
+            // no minus sign!
+            if (token.find('-') == std::string::npos)
+            {
+                ctrl->setValue(LLSD::Integer(convertTo<U32>(option, ctrl->getName(), token)),
+                               false);
             }
             else
             {
-                ctrl->setValue(LLSD(true), false);
+                badvalue(option, ctrl->getName(), "unsigned", token);
             }
             break;
+        }
+
+        case TYPE_S32:
+            ctrl->setValue(convertTo<S32>(option, ctrl->getName(),
+                                          onevalue(option, value)), false);
+            break;
+
+        case TYPE_F32:
+            ctrl->setValue(convertTo<F32>(option, ctrl->getName(),
+                                          onevalue(option, value)), false);
+            break;
 
+        // It appears that no one has yet tried to define a command-line
+        // switch mapped to a settings variable of TYPE_VEC3, TYPE_VEC3D,
+        // TYPE_RECT, TYPE_COL4, TYPE_COL3. Such types would certainly seem to
+        // call for a bit of special handling here...
         default:
             {
                 // For the default types, let llsd do the conversion.
@@ -481,16 +596,9 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
 
                     ctrl->setValue(llsdArray, false);
                 }
-                else if(value.size() > 0)
+                else
                 {
-					if(value.size() > 1)
-					{
-						llwarns << "Ignoring extra tokens mapped to the setting: " << opt_name << "." << llendl; 
-					}
-
-                    LLSD llsdValue;
-                    llsdValue.assign(LLSD::String(value[0]));
-                    ctrl->setValue(llsdValue, false);
+                    ctrl->setValue(onevalue(option, value), false);
                 }
             }
             break;
@@ -498,12 +606,14 @@ void setControlValueCB(const LLCommandLineParser::token_vector_t& value,
     }
     else
     {
-        llwarns << "Command Line option mapping '" 
-            << opt_name 
-            << "' not found! Ignoring." 
-            << llendl;
+        // This isn't anything a user can affect -- it's a misconfiguration on
+        // the part of the coder. Rub the coder's nose in the problem right
+        // away so even preliminary testing will surface it.
+        llerrs << "Command Line option --" << option
+               << " maps to unknown setting!" << llendl;
     }
 }
+} // anonymous namespace
 
 void LLControlGroupCLP::configure(const std::string& config_filename, LLControlGroup* controlGroup)
 {
@@ -561,11 +671,37 @@ void LLControlGroupCLP::configure(const std::string& config_filename, LLControlG
             }
 
             boost::function1<void, const token_vector_t&> callback;
-            if(option_params.has("map-to") && (NULL != controlGroup))
+            if (! option_params.has("map-to"))
+            {
+                // If this option isn't mapped to a settings variable, is it
+                // one of the ones for which that's unreasonable, or did
+                // someone carelessly add a new option? (Make all these
+                // configuration errors fatal so a maintainer will catch them
+                // right away.)
+                std::set<std::string>::const_iterator found = unmapped_options.find(long_name);
+                if (found == unmapped_options.end())
+                {
+                    llerrs << "New command-line option " << long_name
+                           << " should map-to a variable in settings.xml" << llendl;
+                }
+            }
+            else                    // option specifies map-to
             {
                 std::string controlName = option_params["map-to"].asString();
-                callback = boost::bind(setControlValueCB, _1, 
-                                       controlName, controlGroup);
+                if (! controlGroup)
+                {
+                    llerrs << "Must pass gSavedSettings to LLControlGroupCLP::configure() for "
+                           << long_name << " (map-to " << controlName << ")" << llendl;
+                }
+
+                LLControlVariable* ctrl = controlGroup->getControl(controlName);
+                if (! ctrl)
+                {
+                    llerrs << "Option " << long_name << " specifies map-to " << controlName
+                           << " which does not exist" << llendl;
+                }
+
+                callback = boost::bind(setControlValueCB, _1, long_name, ctrl);
             }
 
             this->addOptionDesc(
diff --git a/indra/newview/llcommandlineparser.h b/indra/newview/llcommandlineparser.h
index 44f2a268431edbb64917cc4f12217b7e7b3c113e..71388b8217ec700d3cb711475f96bb2bc0a054ab 100755
--- a/indra/newview/llcommandlineparser.h
+++ b/indra/newview/llcommandlineparser.h
@@ -86,7 +86,7 @@ class LLCommandLineParser
 	 * 
 	 * Use this to handle the results of parsing. 
 	 */
-	void notify();
+	bool notify();
 	
 	/** @brief Print a description of the configured options.
 	 *
diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp
index 075299386e70a039a0389425130ab93c1e2e79f6..a0024a231c95831909063235be5d16e92118c80c 100755
--- a/indra/newview/lldrawpoolavatar.cpp
+++ b/indra/newview/lldrawpoolavatar.cpp
@@ -135,6 +135,16 @@ void LLDrawPoolAvatar::prerender()
 	{
 		sBufferUsage = GL_STREAM_DRAW_ARB;
 	}
+
+	if (!mDrawFace.empty())
+	{
+		const LLFace *facep = mDrawFace[0];
+		if (facep && facep->getDrawable())
+		{
+			LLVOAvatar* avatarp = (LLVOAvatar *)facep->getDrawable()->getVObj().get();
+			updateRiggedVertexBuffers(avatarp);
+		}
+	}
 }
 
 LLMatrix4& LLDrawPoolAvatar::getModelView()
@@ -1434,6 +1444,65 @@ void LLDrawPoolAvatar::renderAvatars(LLVOAvatar* single_avatar, S32 pass)
 	}
 }
 
+void LLDrawPoolAvatar::getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
+{
+	face->setGeomIndex(0);
+	face->setIndicesIndex(0);
+		
+	//rigged faces do not batch textures
+	face->setTextureIndex(255);
+
+	if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
+	{ //make a new buffer
+		if (sShaderLevel > 0)
+		{
+			buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
+		}
+		else
+		{
+			buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+		}
+		buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
+	}
+	else
+	{ //resize existing buffer
+		buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
+	}
+
+	face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
+	face->setVertexBuffer(buffer);
+
+	U16 offset = 0;
+		
+	LLMatrix4 mat_vert = skin->mBindShapeMatrix;
+	glh::matrix4f m((F32*) mat_vert.mMatrix);
+	m = m.inverse().transpose();
+		
+	F32 mat3[] = 
+	{ m.m[0], m.m[1], m.m[2],
+		m.m[4], m.m[5], m.m[6],
+		m.m[8], m.m[9], m.m[10] };
+
+	LLMatrix3 mat_normal(mat3);				
+
+	//let getGeometryVolume know if alpha should override shiny
+	U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+
+	if (type == LLDrawPool::POOL_ALPHA)
+	{
+		face->setPoolType(LLDrawPool::POOL_ALPHA);
+	}
+	else
+	{
+		face->setPoolType(LLDrawPool::POOL_AVATAR);
+	}
+
+	//llinfos << "Rebuilt face " << face->getTEOffset() << " of " << face->getDrawable() << " at " << gFrameTimeSeconds << llendl;
+	face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
+
+	buffer->flush();
+}
+
 void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace* face, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face)
 {
 	LLVector4a* weight = vol_face.mWeights;
@@ -1453,60 +1522,27 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 		buffer->getNumIndices() != vol_face.mNumIndices ||
 		(drawable && drawable->isState(LLDrawable::REBUILD_ALL)))
 	{
-		face->setGeomIndex(0);
-		face->setIndicesIndex(0);
-		
-		//rigged faces do not batch textures
-		face->setTextureIndex(255);
-
-		if (buffer.isNull() || buffer->getTypeMask() != data_mask || !buffer->isWriteable())
-		{ //make a new buffer
-			if (sShaderLevel > 0)
+		if (drawable && drawable->isState(LLDrawable::REBUILD_ALL))
+		{ //rebuild EVERY face in the drawable, not just this one, to avoid missing drawable wide rebuild issues
+			for (S32 i = 0; i < drawable->getNumFaces(); ++i)
 			{
-				buffer = new LLVertexBuffer(data_mask, GL_DYNAMIC_DRAW_ARB);
-			}
-			else
-			{
-				buffer = new LLVertexBuffer(data_mask, GL_STREAM_DRAW_ARB);
+				LLFace* facep = drawable->getFace(i);
+				U32 face_data_mask = facep->getRiggedVertexBufferDataMask();
+				if (face_data_mask)
+				{
+					LLPointer<LLVertexBuffer> cur_buffer = facep->getVertexBuffer();
+					const LLVolumeFace& cur_vol_face = volume->getVolumeFace(i);
+					getRiggedGeometry(facep, cur_buffer, face_data_mask, skin, volume, cur_vol_face);
+				}
 			}
-			buffer->allocateBuffer(vol_face.mNumVertices, vol_face.mNumIndices, true);
-		}
-		else
-		{ //resize existing buffer
-			buffer->resizeBuffer(vol_face.mNumVertices, vol_face.mNumIndices);
-		}
-
-		face->setSize(vol_face.mNumVertices, vol_face.mNumIndices);
-		face->setVertexBuffer(buffer);
-
-		U16 offset = 0;
-		
-		LLMatrix4 mat_vert = skin->mBindShapeMatrix;
-		glh::matrix4f m((F32*) mat_vert.mMatrix);
-		m = m.inverse().transpose();
-		
-		F32 mat3[] = 
-		{ m.m[0], m.m[1], m.m[2],
-		  m.m[4], m.m[5], m.m[6],
-		  m.m[8], m.m[9], m.m[10] };
-
-		LLMatrix3 mat_normal(mat3);				
-
-		//let getGeometryVolume know if alpha should override shiny
-		U32 type = gPipeline.getPoolTypeFromTE(face->getTextureEntry(), face->getTexture());
+			drawable->clearState(LLDrawable::REBUILD_ALL);
 
-		if (type == LLDrawPool::POOL_ALPHA)
-		{
-			face->setPoolType(LLDrawPool::POOL_ALPHA);
+			buffer = face->getVertexBuffer();
 		}
 		else
-		{
-			face->setPoolType(LLDrawPool::POOL_AVATAR);
+		{ //just rebuild this face
+			getRiggedGeometry(face, buffer, data_mask, skin, volume, vol_face);
 		}
-
-		face->getGeometryVolume(*volume, face->getTEOffset(), mat_vert, mat_normal, offset, true);
-
-		buffer->flush();
 	}
 
 	if (sShaderLevel <= 0 && face->mLastSkinTime < avatar->getLastSkinTime())
@@ -1591,11 +1627,6 @@ void LLDrawPoolAvatar::updateRiggedFaceVertexBuffer(LLVOAvatar* avatar, LLFace*
 			}
 		}
 	}
-
-	if (drawable && (face->getTEOffset() == drawable->getNumFaces()-1))
-	{
-		drawable->clearState(LLDrawable::REBUILD_ALL);
-	}
 }
 
 void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
@@ -1771,7 +1802,6 @@ void LLDrawPoolAvatar::renderRigged(LLVOAvatar* avatar, U32 type, bool glow)
 
 void LLDrawPoolAvatar::renderDeferredRiggedSimple(LLVOAvatar* avatar)
 {
-	updateRiggedVertexBuffers(avatar);
 	renderRigged(avatar, RIGGED_DEFERRED_SIMPLE);
 }
 
@@ -1840,7 +1870,6 @@ void LLDrawPoolAvatar::updateRiggedVertexBuffers(LLVOAvatar* avatar)
 
 void LLDrawPoolAvatar::renderRiggedSimple(LLVOAvatar* avatar)
 {
-	updateRiggedVertexBuffers(avatar);
 	renderRigged(avatar, RIGGED_SIMPLE);
 }
 
diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h
index 7d0368a9459d7b7363228e12e7968730e490f14b..4fbda1f862b90aa67a98d3d17b8a82b7beb5223e 100755
--- a/indra/newview/lldrawpoolavatar.h
+++ b/indra/newview/lldrawpoolavatar.h
@@ -133,6 +133,7 @@ class LLDrawPoolAvatar : public LLFacePool
 	void endDeferredRiggedSimple();
 	void endDeferredRiggedBump();
 		
+	void getRiggedGeometry(LLFace* face, LLPointer<LLVertexBuffer>& buffer, U32 data_mask, const LLMeshSkinInfo* skin, LLVolume* volume, const LLVolumeFace& vol_face);
 	void updateRiggedFaceVertexBuffer(LLVOAvatar* avatar,
 									  LLFace* facep, 
 									  const LLMeshSkinInfo* skin, 
diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp
index f021f4ed0f4e9f11912d317806c0e6431e957a96..9b2b778677aaa7a16f2bbe7f5bfc4fe711697a5c 100755
--- a/indra/newview/llface.cpp
+++ b/indra/newview/llface.cpp
@@ -768,7 +768,7 @@ bool less_than_max_mag(const LLVector4a& vec)
 }
 
 BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
-								const LLMatrix4& mat_vert_in, const LLMatrix3& mat_normal_in, BOOL global_volume)
+								const LLMatrix4& mat_vert_in, BOOL global_volume)
 {
 	//get bounding box
 	if (mDrawablep->isState(LLDrawable::REBUILD_VOLUME | LLDrawable::REBUILD_POSITION | LLDrawable::REBUILD_RIGGED))
@@ -777,10 +777,6 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
 		LLMatrix4a mat_vert;
 		mat_vert.loadu(mat_vert_in);
 
-		LLMatrix4a mat_normal;
-		mat_normal.loadu(mat_normal_in);
-
-		//VECTORIZE THIS
 		LLVector4a min,max;
 	
 		if (f >= volume.getNumVolumeFaces())
@@ -797,100 +793,68 @@ BOOL LLFace::genVolumeBBoxes(const LLVolume &volume, S32 f,
 		llassert(less_than_max_mag(max));
 
 		//min, max are in volume space, convert to drawable render space
-		LLVector4a center;
-		LLVector4a t;
-		t.setAdd(min, max);
-		t.mul(0.5f);
-		mat_vert.affineTransform(t, center);
-		LLVector4a size;
-		size.setSub(max, min);
-		size.mul(0.5f);
 
-		llassert(less_than_max_mag(min));
-		llassert(less_than_max_mag(max));
+		//get 8 corners of bounding box
+		LLVector4Logical mask[6];
 
-		if (!global_volume)
+		for (U32 i = 0; i < 6; ++i)
 		{
-			//VECTORIZE THIS
-			LLVector4a scale;
-			scale.load3(mDrawablep->getVObj()->getScale().mV);
-			size.mul(scale);
+			mask[i].clear();
 		}
 
-		// Catch potential badness from normalization before it happens
-		//
-		llassert(mat_normal.mMatrix[0].isFinite3() && (mat_normal.mMatrix[0].dot3(mat_normal.mMatrix[0]).getF32() > F_APPROXIMATELY_ZERO));
-		llassert(mat_normal.mMatrix[1].isFinite3() && (mat_normal.mMatrix[1].dot3(mat_normal.mMatrix[1]).getF32() > F_APPROXIMATELY_ZERO));
-		llassert(mat_normal.mMatrix[2].isFinite3() && (mat_normal.mMatrix[2].dot3(mat_normal.mMatrix[2]).getF32() > F_APPROXIMATELY_ZERO));
-
-		mat_normal.mMatrix[0].normalize3fast();
-		mat_normal.mMatrix[1].normalize3fast();
-		mat_normal.mMatrix[2].normalize3fast();
+		mask[0].setElement<2>(); //001
+		mask[1].setElement<1>(); //010
+		mask[2].setElement<1>(); //011
+		mask[2].setElement<2>();
+		mask[3].setElement<0>(); //100
+		mask[4].setElement<0>(); //101
+		mask[4].setElement<2>();
+		mask[5].setElement<0>(); //110
+		mask[5].setElement<1>();
 		
-		LLVector4a v[4];
+		LLVector4a v[8];
 
-		//get 4 corners of bounding box
-		mat_normal.rotate(size,v[0]);
+		v[6] = min;
+		v[7] = max;
 
-		//VECTORIZE THIS
-		LLVector4a scale;
-		
-		scale.set(-1.f, -1.f, 1.f);
-		scale.mul(size);
-		mat_normal.rotate(scale, v[1]);
-		
-		scale.set(1.f, -1.f, -1.f);
-		scale.mul(size);
-		mat_normal.rotate(scale, v[2]);
-		
-		scale.set(-1.f, 1.f, -1.f);
-		scale.mul(size);
-		mat_normal.rotate(scale, v[3]);
+		for (U32 i = 0; i < 6; ++i)
+		{
+			v[i].setSelectWithMask(mask[i], min, max);
+		}
+
+		LLVector4a tv[8];
 
+		//transform bounding box into drawable space
+		for (U32 i = 0; i < 8; ++i)
+		{
+			mat_vert.affineTransform(v[i], tv[i]);
+		}
+	
+		//find bounding box
 		LLVector4a& newMin = mExtents[0];
 		LLVector4a& newMax = mExtents[1];
-		
-		newMin = newMax = center;
-		
-		llassert(less_than_max_mag(center));
-		
-		for (U32 i = 0; i < 4; i++)
-		{
-			LLVector4a delta;
-			delta.setAbs(v[i]);
-			LLVector4a min;
-			min.setSub(center, delta);
-			LLVector4a max;
-			max.setAdd(center, delta);
 
-			newMin.setMin(newMin,min);
-			newMax.setMax(newMax,max);
+		newMin = newMax = tv[0];
 
-			llassert(less_than_max_mag(newMin));
-			llassert(less_than_max_mag(newMax));
+		for (U32 i = 1; i < 8; ++i)
+		{
+			newMin.setMin(newMin, tv[i]);
+			newMax.setMax(newMax, tv[i]);
 		}
 
 		if (!mDrawablep->isActive())
-		{
+		{	// Shift position for region
 			LLVector4a offset;
 			offset.load3(mDrawablep->getRegion()->getOriginAgent().mV);
 			newMin.add(offset);
 			newMax.add(offset);
-			
-			llassert(less_than_max_mag(newMin));
-			llassert(less_than_max_mag(newMax));
 		}
 
-		t.setAdd(newMin, newMax);
+		LLVector4a t;
+		t.setAdd(newMin,newMax);
 		t.mul(0.5f);
 
-		llassert(less_than_max_mag(t));
-		
-		//VECTORIZE THIS
 		mCenterLocal.set(t.getF32ptr());
-		
-		llassert(less_than_max_mag(newMin));
-		llassert(less_than_max_mag(newMax));
 
 		t.setSub(newMax,newMin);
 		mBoundingSphereRadius = t.getLength3().getF32()*0.5f;
diff --git a/indra/newview/llface.h b/indra/newview/llface.h
index 0687544d53880f00ba956e9d6a40fa0046643cfd..763634a3ab53708a66f81458cda06e1fde7d1455 100755
--- a/indra/newview/llface.h
+++ b/indra/newview/llface.h
@@ -195,7 +195,7 @@ class LLFace
 	void		setSize(S32 numVertices, S32 num_indices = 0, bool align = false);
 	
 	BOOL		genVolumeBBoxes(const LLVolume &volume, S32 f,
-								   const LLMatrix4& mat, const LLMatrix3& inv_trans_mat, BOOL global_volume = FALSE);
+								   const LLMatrix4& mat, BOOL global_volume = FALSE);
 	
 	void		init(LLDrawable* drawablep, LLViewerObject* objp);
 	void		destroy();
diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp
index ddb9d3bc4369ab4d03c2dcbd41884776158e5488..9d292ce7bb7a7f3fe6f66642715bcc0c4e9b3dad 100755
--- a/indra/newview/llfeaturemanager.cpp
+++ b/indra/newview/llfeaturemanager.cpp
@@ -30,6 +30,7 @@
 #include <fstream>
 
 #include <boost/regex.hpp>
+#include <boost/assign/list_of.hpp>
 
 #include "llfeaturemanager.h"
 #include "lldir.h"
@@ -52,6 +53,8 @@
 #include "llboost.h"
 #include "llweb.h"
 #include "llviewershadermgr.h"
+#include "llstring.h"
+#include "stringize.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -187,6 +190,55 @@ void LLFeatureList::dump()
 	LL_DEBUGS("RenderInit") << LL_ENDL;
 }
 
+static const std::vector<std::string> sGraphicsLevelNames = boost::assign::list_of
+	("Low")
+	("LowMid")
+	("Mid")
+	("MidHigh")
+	("High")
+	("HighUltra")
+	("Ultra")
+;
+
+U32 LLFeatureManager::getMaxGraphicsLevel() const
+{
+	return sGraphicsLevelNames.size() - 1;
+}
+
+bool LLFeatureManager::isValidGraphicsLevel(U32 level) const
+{
+	return (level <= getMaxGraphicsLevel());
+}
+
+std::string LLFeatureManager::getNameForGraphicsLevel(U32 level) const
+{
+	if (isValidGraphicsLevel(level))
+	{
+		return sGraphicsLevelNames[level];
+	}
+	return STRINGIZE("Invalid graphics level " << level << ", valid are 0 .. "
+					 << getMaxGraphicsLevel());
+}
+
+S32 LLFeatureManager::getGraphicsLevelForName(const std::string& name) const
+{
+	const std::string FixedFunction("FixedFunction");
+	std::string rname(name);
+	if (LLStringUtil::endsWith(rname, FixedFunction))
+	{
+		// chop off any "FixedFunction" suffix
+		rname = rname.substr(0, rname.length() - FixedFunction.length());
+	}
+	for (S32 i(0), iend(getMaxGraphicsLevel()); i <= iend; ++i)
+	{
+		if (sGraphicsLevelNames[i] == rname)
+		{
+			return i;
+		}
+	}
+	return -1;
+}
+
 LLFeatureList *LLFeatureManager::findMask(const std::string& name)
 {
 	if (mMaskList.count(name))
@@ -620,7 +672,7 @@ void LLFeatureManager::applyRecommendedSettings()
 {
 	// apply saved settings
 	// cap the level at 2 (high)
-	S32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
+	U32 level = llmax(GPU_CLASS_0, llmin(mGPUClass, GPU_CLASS_5));
 
 	llinfos << "Applying Recommended Features" << llendl;
 
@@ -696,62 +748,33 @@ void LLFeatureManager::applyFeatures(bool skipFeatures)
 	}
 }
 
-void LLFeatureManager::setGraphicsLevel(S32 level, bool skipFeatures)
+void LLFeatureManager::setGraphicsLevel(U32 level, bool skipFeatures)
 {
 	LLViewerShaderMgr::sSkipReload = true;
 
 	applyBaseMasks();
-	
-	switch (level)
+
+	// if we're passed an invalid level, default to "Low"
+	std::string features(isValidGraphicsLevel(level)? getNameForGraphicsLevel(level) : "Low");
+	if (features == "Low")
 	{
-		case 0:
 #if LL_DARWIN
-			// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
-			// systems which support them instead of falling back to fixed-function unnecessarily
-			// MAINT-2157
-			//
-			if (gGLManager.mGLVersion < 2.1f)
-			{
-				maskFeatures("LowFixedFunction");			
-			}
-			else
-			{ //same as low, but with "Basic Shaders" enabled
-				maskFeatures("Low");
-			}
+		// This Mac-specific change is to insure that we force 'Basic Shaders' for all Mac
+		// systems which support them instead of falling back to fixed-function unnecessarily
+		// MAINT-2157
+		if (gGLManager.mGLVersion < 2.1f)
 #else
-			if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
-			{ //only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
-				maskFeatures("LowFixedFunction");			
-			}
-			else
-			{ //same as low, but with "Basic Shaders" enabled
-				maskFeatures("Low");
-			}
+		// only use fixed function by default if GL version < 3.0 or this is an intel graphics chip
+		if (gGLManager.mGLVersion < 3.f || gGLManager.mIsIntel)
 #endif
-			break;
-		case 1:
-			maskFeatures("LowMid");
-			break;
-		case 2:
-			maskFeatures("Mid");
-			break;
-		case 3:
-			maskFeatures("MidHigh");
-			break;
-		case 4:
-			maskFeatures("High");
-			break;
-		case 5:
-			maskFeatures("HighUltra");
-			break;
-		case 6:
-			maskFeatures("Ultra");
-			break;
-		default:
-			maskFeatures("Low");
-			break;
+		{
+            // same as Low, but with "Basic Shaders" disabled
+			features = "LowFixedFunction";
+		}
 	}
 
+	maskFeatures(features);
+
 	applyFeatures(skipFeatures);
 
 	LLViewerShaderMgr::sSkipReload = false;
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index ad72c167432e838d6adeb55ac0701efb5905e57d..3b8d2512362b298c8b4a57c3ee0a8a236b5cb598 100755
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -134,8 +134,18 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
 	// skipFeatures forces skipping of mostly hardware settings
 	// that we don't want to change when we change graphics
 	// settings
-	void setGraphicsLevel(S32 level, bool skipFeatures);
-	
+	void setGraphicsLevel(U32 level, bool skipFeatures);
+
+	// What 'level' values are valid to pass to setGraphicsLevel()?
+	// 0 is the low end...
+	U32 getMaxGraphicsLevel() const;
+	bool isValidGraphicsLevel(U32 level) const;
+
+	// setGraphicsLevel() levels have names.
+	std::string getNameForGraphicsLevel(U32 level) const;
+	// returns -1 for unrecognized name (hence S32 rather than U32)
+	S32 getGraphicsLevelForName(const std::string& name) const;
+
 	void applyBaseMasks();
 	void applyRecommendedSettings();
 
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81b3e2ad2c19fa193886d19e7ba3aa3e..fea8e34729e131acea20aa70213df227e135592a 100755
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -33,8 +33,10 @@
 
 // Viewer includes
 #include "llagent.h"
+#include "llagentui.h"
 #include "llappviewer.h" 
 #include "llsecondlifeurls.h"
+#include "llslurl.h"
 #include "llvoiceclient.h"
 #include "lluictrlfactory.h"
 #include "llviewertexteditor.h"
@@ -250,12 +252,16 @@ LLSD LLFloaterAbout::getInfo()
 	LLViewerRegion* region = gAgent.getRegion();
 	if (region)
 	{
-		const LLVector3d &pos = gAgent.getPositionGlobal();
+		LLVector3d pos = gAgent.getPositionGlobal();
 		info["POSITION"] = ll_sd_from_vector3d(pos);
+		info["POSITION_LOCAL"] = ll_sd_from_vector3(gAgent.getPosAgentFromGlobal(pos));
 		info["REGION"] = gAgent.getRegion()->getName();
 		info["HOSTNAME"] = gAgent.getRegion()->getHost().getHostName();
 		info["HOSTIP"] = gAgent.getRegion()->getHost().getString();
 		info["SERVER_VERSION"] = gLastVersionChannel;
+		LLSLURL slurl;
+		LLAgentUI::buildSLURL(slurl);
+		info["SLURL"] = slurl.getSLURLString();
 	}
 
 	// CPU
@@ -307,12 +313,12 @@ LLSD LLFloaterAbout::getInfo()
 static std::string get_viewer_release_notes_url()
 {
 	// return a URL to the release notes for this viewer, such as:
-	// http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0
+	// http://wiki.secondlife.com/wiki/Release_Notes/Second Life Beta Viewer/2.1.0.123456
 	std::string url = LLTrans::getString("RELEASE_NOTES_BASE_URL");
 	if (! LLStringUtil::endsWith(url, "/"))
 		url += "/";
 	url += LLVersionInfo::getChannel() + "/";
-	url += LLVersionInfo::getShortVersion();
+	url += LLVersionInfo::getVersion();
 	return LLWeb::escapeURL(url);
 }
 
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
index 39b6e465f3fa32e27cc608f0fe32020b4bbec5d3..76f62a7880a3c9aee0a1c42873c3f1b435fafadf 100755
--- a/indra/newview/llfloaterbulkpermission.cpp
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -57,6 +57,7 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
 	mDone(FALSE)
 {
 	mID.generate();
+	mCommitCallbackRegistrar.add("BulkPermission.Ok",		boost::bind(&LLFloaterBulkPermission::onOkBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.Apply",	boost::bind(&LLFloaterBulkPermission::onApplyBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.Close",	boost::bind(&LLFloaterBulkPermission::onCloseBtn, this));
 	mCommitCallbackRegistrar.add("BulkPermission.CheckAll",	boost::bind(&LLFloaterBulkPermission::onCheckAll, this));
@@ -66,6 +67,21 @@ LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed)
 
 BOOL LLFloaterBulkPermission::postBuild()
 {
+	mBulkChangeIncludeAnimations = gSavedSettings.getBOOL("BulkChangeIncludeAnimations");
+	mBulkChangeIncludeBodyParts = gSavedSettings.getBOOL("BulkChangeIncludeBodyParts");
+	mBulkChangeIncludeClothing = gSavedSettings.getBOOL("BulkChangeIncludeClothing");
+	mBulkChangeIncludeGestures = gSavedSettings.getBOOL("BulkChangeIncludeGestures");
+	mBulkChangeIncludeNotecards = gSavedSettings.getBOOL("BulkChangeIncludeNotecards");
+	mBulkChangeIncludeObjects = gSavedSettings.getBOOL("BulkChangeIncludeObjects");
+	mBulkChangeIncludeScripts = gSavedSettings.getBOOL("BulkChangeIncludeScripts");
+	mBulkChangeIncludeSounds = gSavedSettings.getBOOL("BulkChangeIncludeSounds");
+	mBulkChangeIncludeTextures = gSavedSettings.getBOOL("BulkChangeIncludeTextures");
+	mBulkChangeShareWithGroup = gSavedSettings.getBOOL("BulkChangeShareWithGroup");
+	mBulkChangeEveryoneCopy = gSavedSettings.getBOOL("BulkChangeEveryoneCopy");
+	mBulkChangeNextOwnerModify = gSavedSettings.getBOOL("BulkChangeNextOwnerModify");
+	mBulkChangeNextOwnerCopy = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
+	mBulkChangeNextOwnerTransfer = gSavedSettings.getBOOL("BulkChangeNextOwnerTransfer");
+
 	return TRUE;
 }
 
@@ -144,6 +160,12 @@ void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
 	}
 }
 
+void LLFloaterBulkPermission::onOkBtn()
+{
+	doApply();
+	closeFloater();
+}
+
 void LLFloaterBulkPermission::onApplyBtn()
 {
 	doApply();
@@ -151,6 +173,20 @@ void LLFloaterBulkPermission::onApplyBtn()
 
 void LLFloaterBulkPermission::onCloseBtn()
 {
+	gSavedSettings.setBOOL("BulkChangeIncludeAnimations", mBulkChangeIncludeAnimations);
+	gSavedSettings.setBOOL("BulkChangeIncludeBodyParts", mBulkChangeIncludeBodyParts);
+	gSavedSettings.setBOOL("BulkChangeIncludeClothing", mBulkChangeIncludeClothing);
+	gSavedSettings.setBOOL("BulkChangeIncludeGestures", mBulkChangeIncludeGestures);
+	gSavedSettings.setBOOL("BulkChangeIncludeNotecards", mBulkChangeIncludeNotecards);
+	gSavedSettings.setBOOL("BulkChangeIncludeObjects", mBulkChangeIncludeObjects);
+	gSavedSettings.setBOOL("BulkChangeIncludeScripts", mBulkChangeIncludeScripts);
+	gSavedSettings.setBOOL("BulkChangeIncludeSounds", mBulkChangeIncludeSounds);
+	gSavedSettings.setBOOL("BulkChangeIncludeTextures", mBulkChangeIncludeTextures);
+	gSavedSettings.setBOOL("BulkChangeShareWithGroup", mBulkChangeShareWithGroup);
+	gSavedSettings.setBOOL("BulkChangeEveryoneCopy", mBulkChangeEveryoneCopy);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerModify", mBulkChangeNextOwnerModify);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerCopy", mBulkChangeNextOwnerCopy);
+	gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", mBulkChangeNextOwnerTransfer);
 	closeFloater();
 }
 
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
index 7dd05df7ee15e0962b648d120b689671d787d8f6..25e76eca65159c02d2a4dde3c62f8f8407c52d67 100755
--- a/indra/newview/llfloaterbulkpermission.h
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -72,6 +72,7 @@ class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
 								bool is_new);
 
 	void onCloseBtn();
+	void onOkBtn();
 	void onApplyBtn();
 	void onCommitCopy();
 	void onCheckAll() { doCheckUncheckAll(TRUE); }
@@ -94,6 +95,21 @@ class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener
 	LLUUID mCurrentObjectID;
 	BOOL mDone;
 
+	bool mBulkChangeIncludeAnimations;
+	bool mBulkChangeIncludeBodyParts;
+	bool mBulkChangeIncludeClothing;
+	bool mBulkChangeIncludeGestures;
+	bool mBulkChangeIncludeNotecards;
+	bool mBulkChangeIncludeObjects;
+	bool mBulkChangeIncludeScripts;
+	bool mBulkChangeIncludeSounds;
+	bool mBulkChangeIncludeTextures;
+	bool mBulkChangeShareWithGroup;
+	bool mBulkChangeEveryoneCopy;
+	bool mBulkChangeNextOwnerModify;
+	bool mBulkChangeNextOwnerCopy;
+	bool mBulkChangeNextOwnerTransfer;
+
 	LLUUID mID;
 
 	const char* mStartString;
diff --git a/indra/newview/llfloatergotoline.cpp b/indra/newview/llfloatergotoline.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..d66e418926caa5aaaa6db6eedc3ca83d0d0d11f9
--- /dev/null
+++ b/indra/newview/llfloatergotoline.cpp
@@ -0,0 +1,160 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class implementation
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloatergotoline.h"
+#include "llpreviewscript.h"
+#include "llfloaterreg.h"
+#include "lllineeditor.h"
+#include "llviewertexteditor.h"
+#include "llviewerwindow.h"
+
+LLFloaterGotoLine* LLFloaterGotoLine::sInstance = NULL;
+
+LLFloaterGotoLine::LLFloaterGotoLine(LLScriptEdCore* editor_core)
+:       LLFloater(LLSD()),
+        mGotoBox(NULL),
+        mEditorCore(editor_core)
+{
+        buildFromFile("floater_goto_line.xml");
+
+        sInstance = this;
+        
+        // find floater in which script panel is embedded
+        LLView* viewp = (LLView*)editor_core;
+        while(viewp)
+        {
+                LLFloater* floaterp = dynamic_cast<LLFloater*>(viewp);
+                if (floaterp)
+                {
+                        floaterp->addDependentFloater(this);
+                        break;
+                }
+                viewp = viewp->getParent();
+        }
+}
+
+BOOL LLFloaterGotoLine::postBuild()
+{
+	mGotoBox = getChild<LLLineEditor>("goto_line");
+	mGotoBox->setCommitCallback(boost::bind(&LLFloaterGotoLine::onGotoBoxCommit, this));
+	mGotoBox->setCommitOnFocusLost(FALSE);
+        getChild<LLLineEditor>("goto_line")->setPrevalidate(LLTextValidate::validateNonNegativeS32);
+        childSetAction("goto_btn", onBtnGoto,this);
+        setDefaultBtn("goto_btn");
+
+        return TRUE;
+}
+
+//static 
+void LLFloaterGotoLine::show(LLScriptEdCore* editor_core)
+{
+        if (sInstance && sInstance->mEditorCore && sInstance->mEditorCore != editor_core)
+        {
+                sInstance->closeFloater();
+                delete sInstance;
+        }
+
+        if (!sInstance)
+        {
+                // sInstance will be assigned in the constructor.
+                new LLFloaterGotoLine(editor_core);
+        }
+
+        sInstance->openFloater();
+}
+
+LLFloaterGotoLine::~LLFloaterGotoLine()
+{
+        sInstance = NULL;
+}
+
+// static 
+void LLFloaterGotoLine::onBtnGoto(void *userdata)
+{
+        LLFloaterGotoLine* self = (LLFloaterGotoLine*)userdata;
+        self->handleBtnGoto();
+}
+
+void LLFloaterGotoLine::handleBtnGoto()
+{
+        S32 row = 0;
+        S32 column = 0;
+        row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+        if (row >= 0)
+        {
+                if (mEditorCore && mEditorCore->mEditor)
+                {
+			mEditorCore->mEditor->deselect();
+			mEditorCore->mEditor->setCursor(row, column);
+			mEditorCore->mEditor->setFocus(TRUE);
+                }
+        }
+}
+
+bool LLFloaterGotoLine::hasAccelerators() const
+{
+        if (mEditorCore)
+        {
+                return mEditorCore->hasAccelerators();
+        }
+        return FALSE;
+}
+
+BOOL LLFloaterGotoLine::handleKeyHere(KEY key, MASK mask)
+{
+        if (mEditorCore)
+        {
+                return mEditorCore->handleKeyHere(key, mask);
+        }
+
+        return FALSE;
+}
+
+void LLFloaterGotoLine::onGotoBoxCommit()
+{
+        S32 row = 0;
+        S32 column = 0;
+        row = getChild<LLUICtrl>("goto_line")->getValue().asInteger();
+        if (row >= 0)
+        {
+                if (mEditorCore && mEditorCore->mEditor)
+                {
+			mEditorCore->mEditor->setCursor(row, column);
+
+			S32 rownew = 0;
+			S32 columnnew = 0;
+			mEditorCore->mEditor->getCurrentLineAndColumn( &rownew, &columnnew, FALSE );  // don't include wordwrap
+			if (rownew == row && columnnew == column)
+			{
+			        mEditorCore->mEditor->deselect();
+			        mEditorCore->mEditor->setFocus(TRUE);
+			        sInstance->closeFloater();
+			} //else do nothing (if the cursor-position didn't change)
+                }
+        }
+}
diff --git a/indra/newview/llfloatergotoline.h b/indra/newview/llfloatergotoline.h
new file mode 100644
index 0000000000000000000000000000000000000000..058d6017522a278cda32461413d6d44c547d5017
--- /dev/null
+++ b/indra/newview/llfloatergotoline.h
@@ -0,0 +1,66 @@
+/**
+ * @file llfloatergotoline.h
+ * @author MartinRJ
+ * @brief LLFloaterGotoLine class definition
+ *
+ * $LicenseInfo:firstyear=2012&license=viewerlgpl$
+ * Second Life Viewer Source Code
+ * Copyright (C) 2012, Linden Research, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation;
+ * version 2.1 of the License only.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERGOTOLINE_H
+#define LL_LLFLOATERGOTOLINE_H
+
+#include "llfloater.h"
+#include "lllineeditor.h"
+#include "llpreviewscript.h"
+
+class LLScriptEdCore;
+
+class LLFloaterGotoLine : public LLFloater
+{
+public:
+        LLFloaterGotoLine(LLScriptEdCore* editor_core);
+        ~LLFloaterGotoLine();
+
+        /*virtual*/     BOOL    postBuild();
+        static void show(LLScriptEdCore* editor_core);
+
+        static void onBtnGoto(void* userdata);
+        void handleBtnGoto();
+
+        LLScriptEdCore* getEditorCore() { return mEditorCore; }
+        static LLFloaterGotoLine* getInstance() { return sInstance; }
+
+        virtual bool hasAccelerators() const;
+        virtual BOOL handleKeyHere(KEY key, MASK mask);
+
+private:
+
+        LLScriptEdCore* mEditorCore;
+
+        static LLFloaterGotoLine*       sInstance;
+
+protected:
+	LLLineEditor*			mGotoBox;
+        void onGotoBoxCommit();
+};
+
+#endif  // LL_LLFLOATERGOTOLINE_H
diff --git a/indra/newview/llfloaterimnearbychat.cpp b/indra/newview/llfloaterimnearbychat.cpp
index 5999c74d5161664acf82310878b024950002cc4a..3d77ea4f0bb3ab7fc1861214f39b125173e0ae68 100755
--- a/indra/newview/llfloaterimnearbychat.cpp
+++ b/indra/newview/llfloaterimnearbychat.cpp
@@ -125,7 +125,7 @@ BOOL LLFloaterIMNearbyChat::postBuild()
 	setTitle(LLTrans::getString("NearbyChatTitle"));
 
 	// obsolete, but may be needed for backward compatibility?
-	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", true);
+	gSavedSettings.declareS32("nearbychat_showicons_and_names", 2, "NearByChat header settings", LLControlVariable::PERSIST_NONDFT);
 
 	if (gSavedPerAccountSettings.getBOOL("LogShowHistory"))
 	{
@@ -593,7 +593,7 @@ void LLFloaterIMNearbyChat::sendChat( EChatType type )
 			if (!utf8_revised_text.empty())
 			{
 				// Chat with animation
-				sendChatFromViewer(utf8_revised_text, type, TRUE);
+				sendChatFromViewer(utf8_revised_text, type, gSavedSettings.getBOOL("PlayChatAnim"));
 			}
 		}
 
diff --git a/indra/newview/llfloaterimnearbychatlistener.cpp b/indra/newview/llfloaterimnearbychatlistener.cpp
index 14a22bcd84cb2f0f7b0936796ef10037272dba98..5a5f6c72c8ce29beeed6db1e3fb1dbd75e7b215c 100755
--- a/indra/newview/llfloaterimnearbychatlistener.cpp
+++ b/indra/newview/llfloaterimnearbychatlistener.cpp
@@ -33,7 +33,7 @@
 
 #include "llagent.h"
 #include "llchat.h"
-
+#include "llviewercontrol.h"
 
 
 LLFloaterIMNearbyChatListener::LLFloaterIMNearbyChatListener(LLFloaterIMNearbyChat & chatbar)
@@ -95,6 +95,6 @@ void LLFloaterIMNearbyChatListener::sendChat(LLSD const & chat_data) const
 	}
 
 	// Send it as if it was typed in
-	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, (BOOL)(channel == 0));
+	mChatbar.sendChatFromViewer(chat_to_send, type_o_chat, ((BOOL)(channel == 0)) && gSavedSettings.getBOOL("PlayChatAnim"));
 }
 
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 8290494c229c7d596e03e1d26e02ee5c839c01c2..d4355007c1fe493203266dc9545dc8d4dbba4a72 100755
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -2118,7 +2118,7 @@ void LLPanelLandOptions::refreshSearch()
 
 	bool can_change =
 			LLViewerParcelMgr::isParcelModifiableByAgent(
-				parcel, GP_LAND_CHANGE_IDENTITY)
+				parcel, GP_LAND_FIND_PLACES)
 			&& region
 			&& !(region->getRegionFlag(REGION_FLAGS_BLOCK_PARCEL_SEARCH));
 
diff --git a/indra/newview/llmaniprotate.cpp b/indra/newview/llmaniprotate.cpp
index d79f1040bba740c385ecbf13e72e446df852f073..4cbdfde8689b59c9b1919d3ac12ee3ebc2398691 100755
--- a/indra/newview/llmaniprotate.cpp
+++ b/indra/newview/llmaniprotate.cpp
@@ -1376,74 +1376,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 		BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
 		projected_mouse -= snap_plane_center;
 
-		S32 snap_plane = 0;
-
-		F32 dot = cam_to_snap_plane * constraint_axis;
-		if (llabs(dot) < 0.01f)
-		{
-			// looking at ring edge on, project onto view plane and check if mouse is past ring
-			getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
-			projected_mouse -= snap_plane_center;
-			dot = projected_mouse * constraint_axis;
-			if (projected_mouse * constraint_axis > 0)
-			{
-				snap_plane = 1;
-			}
-			projected_mouse -= dot * constraint_axis;
-		}
-		else if (dot > 0.f)
-		{
-			// look for mouse position outside and in front of snap circle
-			if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
-			{
-				snap_plane = 1;
-			}
-		}
-		else
-		{
-			// look for mouse position inside or in back of snap circle
-			if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
-			{
-				snap_plane = 1;
-			}
-		}
-
-		if (snap_plane == 0)
-		{
-			// try other plane
-			snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
-			if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
-			{
-				cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
-			}
-			else
-			{
-				cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
-				cam_to_snap_plane.normVec();
-			}
-
-			hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
-			projected_mouse -= snap_plane_center;
-
-			dot = cam_to_snap_plane * constraint_axis;
+		if (gSavedSettings.getBOOL("SnapEnabled")) {
+			S32 snap_plane = 0;
+	
+			F32 dot = cam_to_snap_plane * constraint_axis;
 			if (llabs(dot) < 0.01f)
 			{
 				// looking at ring edge on, project onto view plane and check if mouse is past ring
 				getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
 				projected_mouse -= snap_plane_center;
 				dot = projected_mouse * constraint_axis;
-				if (projected_mouse * constraint_axis < 0)
+				if (projected_mouse * constraint_axis > 0)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 				projected_mouse -= dot * constraint_axis;
 			}
-			else if (dot < 0.f)
+			else if (dot > 0.f)
 			{
 				// look for mouse position outside and in front of snap circle
 				if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 			}
 			else
@@ -1451,78 +1405,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
 				// look for mouse position inside or in back of snap circle
 				if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
 				{
-					snap_plane = 2;
+					snap_plane = 1;
 				}
 			}
-		}
-
-		if (snap_plane > 0)
-		{
-			LLVector3 cam_at_axis;
-			if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
-			{
-				cam_at_axis.setVec(1.f, 0.f, 0.f);
-			}
-			else
-			{
-				cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
-				cam_at_axis.normVec();
-			}
-
-			// first, project mouse onto screen plane at point tangent to rotation radius. 
-			getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
-			// project that point onto rotation plane
-			projected_mouse -= snap_plane_center;
-			projected_mouse -= projected_vec(projected_mouse, constraint_axis);
-
-			F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
-			F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
-			if (llabs(mouse_lateral_dist) > 0.01f)
-			{
-				mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - 
-									(mouse_lateral_dist * mouse_lateral_dist));
-			}
-			LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
-			projected_mouse -= mouse_depth * projected_camera_at;
-
-			if (!mInSnapRegime)
+	
+			if (snap_plane == 0)
 			{
-				mSmoothRotate = TRUE;
+				// try other plane
+				snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
+				if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+				{
+					cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
+				}
+				else
+				{
+					cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+					cam_to_snap_plane.normVec();
+				}
+	
+				hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
+				projected_mouse -= snap_plane_center;
+	
+				dot = cam_to_snap_plane * constraint_axis;
+				if (llabs(dot) < 0.01f)
+				{
+					// looking at ring edge on, project onto view plane and check if mouse is past ring
+					getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
+					projected_mouse -= snap_plane_center;
+					dot = projected_mouse * constraint_axis;
+					if (projected_mouse * constraint_axis < 0)
+					{
+						snap_plane = 2;
+					}
+					projected_mouse -= dot * constraint_axis;
+				}
+				else if (dot < 0.f)
+				{
+					// look for mouse position outside and in front of snap circle
+					if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
+					{
+						snap_plane = 2;
+					}
+				}
+				else
+				{
+					// look for mouse position inside or in back of snap circle
+					if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
+					{
+						snap_plane = 2;
+					}
+				}
 			}
-			mInSnapRegime = TRUE;
-			// 0 to 360 deg
-			F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
 			
-			F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
-			//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
-
-			LLVector3 object_axis;
-			getObjectAxisClosestToMouse(object_axis);
-			object_axis = object_axis * first_object_node->mSavedRotation;
-
-			// project onto constraint plane
-			object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
-			object_axis.normVec();
-
-			if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+			if (snap_plane > 0)
 			{
-				F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
-				angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				LLVector3 cam_at_axis;
+				if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
+				{
+					cam_at_axis.setVec(1.f, 0.f, 0.f);
+				}
+				else
+				{
+					cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
+					cam_at_axis.normVec();
+				}
+	
+				// first, project mouse onto screen plane at point tangent to rotation radius. 
+				getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
+				// project that point onto rotation plane
+				projected_mouse -= snap_plane_center;
+				projected_mouse -= projected_vec(projected_mouse, constraint_axis);
+	
+				F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
+				F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
+				if (llabs(mouse_lateral_dist) > 0.01f)
+				{
+					mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) - 
+										(mouse_lateral_dist * mouse_lateral_dist));
+				}
+				LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
+				projected_mouse -= mouse_depth * projected_camera_at;
+	
+				if (!mInSnapRegime)
+				{
+					mSmoothRotate = TRUE;
+				}
+				mInSnapRegime = TRUE;
+				// 0 to 360 deg
+				F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
+				
+				F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
+				//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
+	
+				LLVector3 object_axis;
+				getObjectAxisClosestToMouse(object_axis);
+				object_axis = object_axis * first_object_node->mSavedRotation;
+	
+				// project onto constraint plane
+				object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
+				object_axis.normVec();
+	
+				if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
+				{
+					F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
+					angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				}
+				else
+				{
+					angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				}
+				return LLQuaternion( -angle, constraint_axis );
 			}
 			else
 			{
-				angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
+				if (mInSnapRegime)
+				{
+					mSmoothRotate = TRUE;
+				}
+				mInSnapRegime = FALSE;
 			}
-			return LLQuaternion( -angle, constraint_axis );
 		}
-		else
-		{
+		else {
 			if (mInSnapRegime)
 			{
 				mSmoothRotate = TRUE;
 			}
 			mInSnapRegime = FALSE;
-
+		}
+		
+		if (!mInSnapRegime)
+		{
 			LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
 			up_from_axis.normVec();
 			LLVector3 cur_intersection;
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
index 2b92b0b3d1c1e1ce216da214932f6dc02c015574..a567d1217a1b049db2695c742ec54c9e4bc906e3 100755
--- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -92,7 +92,7 @@ void LLMenuOptionPathfindingRebakeNavmesh::initialize()
 
 void LLMenuOptionPathfindingRebakeNavmesh::quit()
 {
-	if (mIsInitialized)
+	if (mIsInitialized)		// Quitting from the login screen leaves this uninitialized
 	{
 		if (mNavMeshSlot.connected())
 		{
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 8602271f84470e016ec1cd6f78502351e5b44876..8eaf691d6fbe2e9a7c6254a0693bb37caec397ad 100755
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -413,7 +413,7 @@ class LLMeshUploadThread : public LLThread
 
 	void startRequest() { ++mPendingUploads; }
 	void stopRequest() { --mPendingUploads; }
-		
+
 	bool finished() { return mFinished; }
 	virtual void run();
 	void preStart();
diff --git a/indra/newview/llnamelistctrl.cpp b/indra/newview/llnamelistctrl.cpp
index 7f396b7b7ed42d4067feb20800efdaf14ad69483..7ddd04fed0a616a8616af8e2cefc449b1c8d0a81 100755
--- a/indra/newview/llnamelistctrl.cpp
+++ b/indra/newview/llnamelistctrl.cpp
@@ -416,9 +416,9 @@ void LLNameListCtrl::onAvatarNameCache(const LLUUID& agent_id,
 }
 
 
-void LLNameListCtrl::updateColumns()
+void LLNameListCtrl::updateColumns(bool force_update)
 {
-	LLScrollListCtrl::updateColumns();
+	LLScrollListCtrl::updateColumns(force_update);
 
 	if (!mNameColumn.empty())
 	{
diff --git a/indra/newview/llnamelistctrl.h b/indra/newview/llnamelistctrl.h
index 271802d48a52ad5c99e483494a9063b45f539135..5aa1e1c458b0569d5e58bb367b07e4a216b543c2 100755
--- a/indra/newview/llnamelistctrl.h
+++ b/indra/newview/llnamelistctrl.h
@@ -149,7 +149,7 @@ class LLNameListCtrl
 
 	void sortByName(BOOL ascending);
 
-	/*virtual*/ void updateColumns();
+	/*virtual*/ void updateColumns(bool force_update);
 
 	/*virtual*/ void	mouseOverHighlightNthItem( S32 index );
 private:
diff --git a/indra/newview/llpanelgroupinvite.cpp b/indra/newview/llpanelgroupinvite.cpp
index 133b269c112433824dea63880210092b1880d552..a9a3c686a65d50f0997a199da27f7d57324b1641 100755
--- a/indra/newview/llpanelgroupinvite.cpp
+++ b/indra/newview/llpanelgroupinvite.cpp
@@ -85,6 +85,7 @@ class LLPanelGroupInvite::impl
 	std::string		mAlreadyInGroup;
 	std::string		mTooManySelected;
 	bool		mConfirmedOwnerInvite;
+	std::set<LLUUID>	mInviteeIDs;
 
 	void (*mCloseCallback)(void* data);
 
@@ -117,31 +118,30 @@ LLPanelGroupInvite::impl::~impl()
 	}
 }
 
+const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.
+
 void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
 										const uuid_vec_t& agent_ids)
 {
 	std::string name;
 	LLUUID id;
 
+	if (names.size() + mInviteeIDs.size() > MAX_GROUP_INVITES)
+	{
+		// Fail! Show a warning and don't add any names.
+		LLSD msg;
+		msg["MESSAGE"] = mTooManySelected;
+		LLNotificationsUtil::add("GenericAlert", msg);
+		return;
+	}
+
 	for (S32 i = 0; i < (S32)names.size(); i++)
 	{
 		name = names[i];
 		id = agent_ids[i];
 
 		// Make sure this agent isn't already in the list.
-		bool already_in_list = false;
-		std::vector<LLScrollListItem*> items = mInvitees->getAllData();
-		for (std::vector<LLScrollListItem*>::iterator iter = items.begin();
-			 iter != items.end(); ++iter)
-		{
-			LLScrollListItem* item = *iter;
-			if (item->getUUID() == id)
-			{
-				already_in_list = true;
-				break;
-			}
-		}
-		if (already_in_list)
+		if (mInviteeIDs.find(id) != mInviteeIDs.end())
 		{
 			continue;
 		}
@@ -152,6 +152,7 @@ void LLPanelGroupInvite::impl::addUsers(const std::vector<std::string>& names,
 		row["columns"][0]["value"] = name;
 
 		mInvitees->addElement(row);
+		mInviteeIDs.insert(id);
 	}
 }
 
@@ -193,7 +194,6 @@ void LLPanelGroupInvite::impl::submitInvitations()
 		role_member_pairs[item->getUUID()] = role_id;
 	}
 	
-	const S32 MAX_GROUP_INVITES = 100; // Max invites per request. 100 to match server cap.
 	if (role_member_pairs.size() > MAX_GROUP_INVITES)
 	{
 		// Fail!
@@ -334,6 +334,12 @@ void LLPanelGroupInvite::impl::handleRemove()
 			mInvitees->getAllSelected();
 	if (selection.empty()) return;
 
+	std::vector<LLScrollListItem*>::iterator iter;
+	for(iter = selection.begin(); iter != selection.end(); ++iter)
+	{
+		mInviteeIDs.erase( (*iter)->getUUID() );
+	}
+
 	// Remove all selected invitees.
 	mInvitees->deleteSelectedItems();
 	mRemoveButton->setEnabled(FALSE);
@@ -459,6 +465,7 @@ void LLPanelGroupInvite::clear()
 	mImplementation->mRoleNames->clear();
 	mImplementation->mRoleNames->removeall();
 	mImplementation->mOKButton->setEnabled(FALSE);
+	mImplementation->mInviteeIDs.clear();
 }
 
 void LLPanelGroupInvite::addUsers(uuid_vec_t& agent_ids)
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index cfdac11d26b6bfb0ccbf04c4fbd042121fa5643f..fdcd1f5ebb1fa8a8339866ec504fe934894151d2 100755
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -1101,27 +1101,61 @@ void LLPanelGroupMembersSubTab::onEjectMembers(void *userdata)
 }
 
 void LLPanelGroupMembersSubTab::handleEjectMembers()
-{
-	//send down an eject message
-	uuid_vec_t selected_members;
-
+{	
 	std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
 	if (selection.empty()) return;
-
-	std::vector<LLScrollListItem*>::iterator itor;
-	for (itor = selection.begin() ; 
-		 itor != selection.end(); ++itor)
+	
+	S32 selection_count = selection.size();
+	if (selection_count == 1)
 	{
-		LLUUID member_id = (*itor)->getUUID();
-		selected_members.push_back( member_id );
+		LLSD args;
+		LLUUID selected_avatar = mMembersList->getValue().asUUID();
+		std::string fullname = LLSLURL("agent", selected_avatar, "inspect").getSLURLString();
+		args["AVATAR_NAME"] = fullname;
+		LLSD payload;
+		LLNotificationsUtil::add("EjectGroupMemberWarning",
+								 args,
+								 payload,
+								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
 	}
+	else
+	{
+		LLSD args;
+		args["COUNT"] = llformat("%d", selection_count);
+		LLSD payload;
+		LLNotificationsUtil::add("EjectGroupMembersWarning",
+								 args,
+								 payload,
+								 boost::bind(&LLPanelGroupMembersSubTab::handleEjectCallback, this, _1, _2));
+	}
+}
 
-	mMembersList->deleteSelectedItems();
-
-	sendEjectNotifications(mGroupID, selected_members);
-
-	LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID,
-									 selected_members);
+bool LLPanelGroupMembersSubTab::handleEjectCallback(const LLSD& notification, const LLSD& response)
+{
+	S32 option = LLNotificationsUtil::getSelectedOption(notification, response);
+	if (0 == option) // Eject button
+	{
+		//send down an eject message
+		uuid_vec_t selected_members;
+		
+		std::vector<LLScrollListItem*> selection = mMembersList->getAllSelected();
+		if (selection.empty()) return false;
+		
+		std::vector<LLScrollListItem*>::iterator itor;
+		for (itor = selection.begin() ;
+			 itor != selection.end(); ++itor)
+		{
+			LLUUID member_id = (*itor)->getUUID();
+			selected_members.push_back( member_id );
+		}
+		
+		mMembersList->deleteSelectedItems();
+		
+		sendEjectNotifications(mGroupID, selected_members);
+		
+		LLGroupMgr::getInstance()->sendGroupMemberEjects(mGroupID, selected_members);
+	}
+	return false;
 }
 
 void LLPanelGroupMembersSubTab::sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members)
diff --git a/indra/newview/llpanelgrouproles.h b/indra/newview/llpanelgrouproles.h
index 78bb3c57a16a282c73868897305820fb5341b0a5..0cf272f3ee05de0fe7d3023a39ab3a2bb410b64a 100755
--- a/indra/newview/llpanelgrouproles.h
+++ b/indra/newview/llpanelgrouproles.h
@@ -167,6 +167,7 @@ class LLPanelGroupMembersSubTab : public LLPanelGroupSubTab
 	static void onEjectMembers(void*);
 	void handleEjectMembers();
 	void sendEjectNotifications(const LLUUID& group_id, const uuid_vec_t& selected_members);
+	bool handleEjectCallback(const LLSD& notification, const LLSD& response);
 
 	static void onRoleCheck(LLUICtrl* check, void* user_data);
 	void handleRoleCheck(const LLUUID& role_id,
diff --git a/indra/newview/llpanelpeople.cpp b/indra/newview/llpanelpeople.cpp
index 4138558bad150b4414f45eceb37845ab78a49c6c..d7c634d6194678b84bfb03f3bf19211ebe7422ed 100755
--- a/indra/newview/llpanelpeople.cpp
+++ b/indra/newview/llpanelpeople.cpp
@@ -76,6 +76,8 @@ static const std::string BLOCKED_TAB_NAME	= "blocked_panel"; // blocked avatars
 
 static const std::string COLLAPSED_BY_USER  = "collapsed_by_user";
 
+extern S32 gMaxAgentGroups;
+
 /** Comparator for comparing avatar items by last interaction date */
 class LLAvatarItemRecentComparator : public LLAvatarItemComparator
 {
@@ -808,6 +810,8 @@ void LLPanelPeople::updateButtons()
 
 		LLPanel* groups_panel = mTabContainer->getCurrentPanel();
 		groups_panel->getChildView("minus_btn")->setEnabled(item_selected && selected_id.notNull()); // a real group selected
+		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[COUNT]", llformat("%d",gAgent.mGroups.count()));
+		groups_panel->getChild<LLUICtrl>("groupcount")->setTextArg("[REMAINING]", llformat("%d",(gMaxAgentGroups-gAgent.mGroups.count())));
 	}
 	else
 	{
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 968a912ea28c51825c51bddd1df00b3bf27618fd..e533be7f246da3ab3393f3412eaab438afdf1f3e 100755
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -86,6 +86,7 @@
 #include "lltrans.h"
 #include "llviewercontrol.h"
 #include "llappviewer.h"
+#include "llfloatergotoline.h"
 
 const std::string HELLO_LSL =
 	"default\n"
@@ -193,12 +194,17 @@ class LLFloaterScriptSearch : public LLFloater
 	LLScriptEdCore* mEditorCore;
 
 	static LLFloaterScriptSearch*	sInstance;
+
+protected:
+	LLLineEditor*			mSearchBox;
+        void onSearchBoxCommit();
 };
 
 LLFloaterScriptSearch* LLFloaterScriptSearch::sInstance = NULL;
 
 LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
 :	LLFloater(LLSD()),
+	mSearchBox(NULL),
 	mEditorCore(editor_core)
 {
 	buildFromFile("floater_script_search.xml");
@@ -221,6 +227,9 @@ LLFloaterScriptSearch::LLFloaterScriptSearch(LLScriptEdCore* editor_core)
 
 BOOL LLFloaterScriptSearch::postBuild()
 {
+	mSearchBox = getChild<LLLineEditor>("search_text");
+	mSearchBox->setCommitCallback(boost::bind(&LLFloaterScriptSearch::onSearchBoxCommit, this));
+	mSearchBox->setCommitOnFocusLost(FALSE);
 	childSetAction("search_btn", onBtnSearch,this);
 	childSetAction("replace_btn", onBtnReplace,this);
 	childSetAction("replace_all_btn", onBtnReplaceAll,this);
@@ -315,6 +324,15 @@ BOOL LLFloaterScriptSearch::handleKeyHere(KEY key, MASK mask)
 	return FALSE;
 }
 
+void LLFloaterScriptSearch::onSearchBoxCommit()
+{
+	if (mEditorCore && mEditorCore->mEditor)
+	{
+		LLCheckBoxCtrl* caseChk = getChild<LLCheckBoxCtrl>("case_text");
+		mEditorCore->mEditor->selectNext(getChild<LLUICtrl>("search_text")->getValue().asString(), caseChk->get());
+	}
+}
+
 /// ---------------------------------------------------------------------------
 /// LLScriptEdCore
 /// ---------------------------------------------------------------------------
@@ -503,6 +521,9 @@ void LLScriptEdCore::initMenu()
 	menuItem = getChild<LLMenuItemCallGL>("Search / Replace...");
 	menuItem->setClickCallback(boost::bind(&LLFloaterScriptSearch::show, this));
 
+	menuItem = getChild<LLMenuItemCallGL>("Go to line...");
+	menuItem->setClickCallback(boost::bind(&LLFloaterGotoLine::show, this));
+
 	menuItem = getChild<LLMenuItemCallGL>("Help...");
 	menuItem->setClickCallback(boost::bind(&LLScriptEdCore::onBtnHelp, this));
 
diff --git a/indra/newview/llpreviewscript.h b/indra/newview/llpreviewscript.h
index 7563cecd9dba8b979f34e405d660d0a1e5500c95..9fb0a4fb63b9a838d88385a0f000c0a310bae84a 100755
--- a/indra/newview/llpreviewscript.h
+++ b/indra/newview/llpreviewscript.h
@@ -34,6 +34,7 @@
 #include "llcombobox.h"
 #include "lliconctrl.h"
 #include "llframetimer.h"
+#include "llfloatergotoline.h"
 
 class LLLiveLSLFile;
 class LLMessageSystem;
@@ -49,6 +50,7 @@ class LLKeywordToken;
 class LLVFS;
 class LLViewerInventoryItem;
 class LLScriptEdContainer;
+class LLFloaterGotoLine;
 
 // Inner, implementation class.  LLPreviewScript and LLLiveLSLEditor each own one of these.
 class LLScriptEdCore : public LLPanel
@@ -58,6 +60,7 @@ class LLScriptEdCore : public LLPanel
 	friend class LLLiveLSLEditor;
 	friend class LLFloaterScriptSearch;
 	friend class LLScriptEdContainer;
+	friend class LLFloaterGotoLine;
 
 protected:
 	// Supposed to be invoked only by the container.
diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp
index 941c5787835c61a42d80a9ca2488a357e321423e..9e97790df89baad5ade893d87c2bddf749fa3b8e 100755
--- a/indra/newview/llspatialpartition.cpp
+++ b/indra/newview/llspatialpartition.cpp
@@ -3457,7 +3457,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 	}
 	else if	(type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::SPHERE)
 	{
-		/*LLVolumeParams volume_params;
+		LLVolumeParams volume_params;
 		volume_params.setType( LL_PCODE_PROFILE_CIRCLE_HALF, LL_PCODE_PATH_CIRCLE );
 		volume_params.setBeginAndEndS( 0.f, 1.f );
 		volume_params.setBeginAndEndT( 0.f, 1.f );
@@ -3467,7 +3467,7 @@ void renderPhysicsShape(LLDrawable* drawable, LLVOVolume* volume)
 		
 		gGL.diffuseColor4fv(color.mV);
 		pushVerts(sphere);
-		LLPrimitive::sVolumeManager->unrefVolume(sphere);*/
+		LLPrimitive::sVolumeManager->unrefVolume(sphere);
 	}
 	else if (type == LLPhysicsShapeBuilderUtil::PhysicsShapeSpecification::CYLINDER)
 	{
@@ -3545,51 +3545,67 @@ void renderPhysicsShapes(LLSpatialGroup* group)
 	for (LLSpatialGroup::OctreeNode::const_element_iter i = group->getDataBegin(); i != group->getDataEnd(); ++i)
 	{
 		LLDrawable* drawable = *i;
-		LLVOVolume* volume = drawable->getVOVolume();
-		if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
+
+		if (drawable->isSpatialBridge())
 		{
-			if (!group->mSpatialPartition->isBridge())
+			LLSpatialBridge* bridge = drawable->asPartition()->asBridge();
+
+			if (bridge)
 			{
 				gGL.pushMatrix();
-				LLVector3 trans = drawable->getRegion()->getOriginAgent();
-				gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
-				renderPhysicsShape(drawable, volume);
+				gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
+				bridge->renderPhysicsShapes();
 				gGL.popMatrix();
 			}
-			else
-			{
-				renderPhysicsShape(drawable, volume);
-			}
 		}
 		else
 		{
-			LLViewerObject* object = drawable->getVObj();
-			if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+			LLVOVolume* volume = drawable->getVOVolume();
+			if (volume && !volume->isAttachment() && volume->getPhysicsShapeType() != LLViewerObject::PHYSICS_SHAPE_NONE )
 			{
-				gGL.pushMatrix();
-				gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix);
-				//push face vertices for terrain
-				for (S32 i = 0; i < drawable->getNumFaces(); ++i)
+				if (!group->mSpatialPartition->isBridge())
 				{
-					LLFace* face = drawable->getFace(i);
-					if (face)
+					gGL.pushMatrix();
+					LLVector3 trans = drawable->getRegion()->getOriginAgent();
+					gGL.translatef(trans.mV[0], trans.mV[1], trans.mV[2]);
+					renderPhysicsShape(drawable, volume);
+					gGL.popMatrix();
+				}
+				else
+				{
+					renderPhysicsShape(drawable, volume);
+				}
+			}
+			else
+			{
+				LLViewerObject* object = drawable->getVObj();
+				if (object && object->getPCode() == LLViewerObject::LL_VO_SURFACE_PATCH)
+				{
+					gGL.pushMatrix();
+					gGL.multMatrix((F32*) object->getRegion()->mRenderMatrix.mMatrix);
+					//push face vertices for terrain
+					for (S32 i = 0; i < drawable->getNumFaces(); ++i)
 					{
-						LLVertexBuffer* buff = face->getVertexBuffer();
-						if (buff)
+						LLFace* face = drawable->getFace(i);
+						if (face)
 						{
-							glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
+							LLVertexBuffer* buff = face->getVertexBuffer();
+							if (buff)
+							{
+								glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
 
-							buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
-							gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
-							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+								buff->setBuffer(LLVertexBuffer::MAP_VERTEX);
+								gGL.diffuseColor3f(0.2f, 0.5f, 0.3f);
+								buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
 									
-							gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
-							glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
-							buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+								gGL.diffuseColor3f(0.2f, 1.f, 0.3f);
+								glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
+								buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0);
+							}
 						}
 					}
+					gGL.popMatrix();
 				}
-				gGL.popMatrix();
 			}
 		}
 	}
diff --git a/indra/newview/lltexturecache.cpp b/indra/newview/lltexturecache.cpp
index 36a7aeb59024078a8fd7e74f5fb25e374a82c05b..5bc2e971ebee8be581ba3049511b3334db38a330 100755
--- a/indra/newview/lltexturecache.cpp
+++ b/indra/newview/lltexturecache.cpp
@@ -1922,10 +1922,10 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
 		h >>= i;
 		if(w * h *c > 0) //valid
 		{
-			LLPointer<LLImageRaw> newraw = new LLImageRaw(raw->getData(), raw->getWidth(), raw->getHeight(), raw->getComponents());
-			newraw->scale(w, h) ;
-			raw = newraw;
-
+			//make a duplicate to keep the original raw image untouched.
+			raw = raw->duplicate();
+			raw->scale(w, h) ;
+			
 			discardlevel += i ;
 		}
 	}
@@ -1935,9 +1935,12 @@ bool LLTextureCache::writeToFastCache(S32 id, LLPointer<LLImageRaw> raw, S32 dis
 	memcpy(mFastCachePadBuffer + sizeof(S32), &h, sizeof(S32));
 	memcpy(mFastCachePadBuffer + sizeof(S32) * 2, &c, sizeof(S32));
 	memcpy(mFastCachePadBuffer + sizeof(S32) * 3, &discardlevel, sizeof(S32));
-	if(w * h * c > 0) //valid
+
+	S32 copy_size = w * h * c;
+	if(copy_size > 0) //valid
 	{
-		memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), w * h * c);
+		copy_size = llmin(copy_size, TEXTURE_FAST_CACHE_ENTRY_SIZE - TEXTURE_FAST_CACHE_ENTRY_OVERHEAD);
+		memcpy(mFastCachePadBuffer + TEXTURE_FAST_CACHE_ENTRY_OVERHEAD, raw->getData(), copy_size);
 	}
 	S32 offset = id * TEXTURE_FAST_CACHE_ENTRY_SIZE;
 
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
old mode 100755
new mode 100644
diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp
index fc9a316759e45046c09d18f93c43390112746978..1c362c18e0d7ede5f872388f6b41c46b8cd573c1 100755
--- a/indra/newview/lltoolpie.cpp
+++ b/indra/newview/lltoolpie.cpp
@@ -121,7 +121,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
 BOOL LLToolPie::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
 	// don't pick transparent so users can't "pay" transparent objects
-	mPick = gViewerWindow->pickImmediate(x, y, FALSE);
+	mPick = gViewerWindow->pickImmediate(x, y, FALSE, TRUE);
 	mPick.mKeyMask = mask;
 
 	// claim not handled so UI focus stays same
@@ -1687,6 +1687,13 @@ BOOL LLToolPie::handleRightClickPick()
 			showVisualContextMenuEffect();
 		}
 	}
+	else if (mPick.mParticleOwnerID.notNull())
+	{
+		if (gMenuMuteParticle && mPick.mParticleOwnerID != gAgent.getID())
+		{
+			gMenuMuteParticle->show(x,y);
+		}
+	}
 
 	LLTool::handleRightMouseDown(x, y, mask);
 	// We handled the event.
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index afbb59e72343e2ea05404adc93d9f097d432e790..744ec4de2b02705f5605ff792df317d58dee2a03 100755
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -83,7 +83,9 @@
 BOOL 				gHackGodmode = FALSE;
 #endif
 
-
+// Should you contemplate changing the name "Global", please first grep for
+// that string literal. There are at least a couple other places in the C++
+// code that assume the LLControlGroup named "Global" is gSavedSettings.
 LLControlGroup gSavedSettings("Global");	// saved at end of session
 LLControlGroup gSavedPerAccountSettings("PerAccount"); // saved at end of session
 LLControlGroup gCrashSettings("CrashSettings");	// saved at end of session
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 5e2f05f4687297dabc2e9dd8156f1ae925d28fab..49eb7dc94a17cb8e1a27ebbac6ef448640c0ee67 100755
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -169,6 +169,7 @@ LLContextMenu	*gMenuObject = NULL;
 LLContextMenu	*gMenuAttachmentSelf = NULL;
 LLContextMenu	*gMenuAttachmentOther = NULL;
 LLContextMenu	*gMenuLand	= NULL;
+LLContextMenu	*gMenuMuteParticle = NULL;
 
 const std::string SAVE_INTO_TASK_INVENTORY("Save Object Back to Object Contents");
 
@@ -425,6 +426,9 @@ void init_menus()
 	gMenuLand = LLUICtrlFactory::createFromFile<LLContextMenu>(
 		"menu_land.xml", gMenuHolder, registry);
 
+	gMenuMuteParticle = LLUICtrlFactory::createFromFile<LLContextMenu>(
+		"menu_mute_particle.xml", gMenuHolder, registry);
+
 	///
 	/// set up the colors
 	///
@@ -2450,6 +2454,9 @@ void cleanup_menus()
 	delete gMenuLand;
 	gMenuLand = NULL;
 
+	delete gMenuMuteParticle;
+	gMenuMuteParticle = NULL;
+
 	delete gMenuBarView;
 	gMenuBarView = NULL;
 
@@ -2803,6 +2810,13 @@ bool enable_object_edit()
 	return enable;
 }
 
+bool enable_mute_particle()
+{
+	const LLPickInfo& pick = LLToolPie::getInstance()->getPick();
+
+	return pick.mParticleOwnerID != LLUUID::null && pick.mParticleOwnerID != gAgent.getID();
+}
+
 // mutually exclusive - show either edit option or build in menu
 bool enable_object_build()
 {
@@ -6220,6 +6234,33 @@ class LLLandEdit : public view_listener_t
 	}
 };
 
+class LLMuteParticle : public view_listener_t
+{
+	bool handleEvent(const LLSD& userdata)
+	{
+		LLUUID id = LLToolPie::getInstance()->getPick().mParticleOwnerID;
+		
+		if (id.notNull())
+		{
+			std::string name;
+			gCacheName->getFullName(id, name);
+
+			LLMute mute(id, name, LLMute::AGENT);
+			if (LLMuteList::getInstance()->isMuted(mute.mID))
+			{
+				LLMuteList::getInstance()->remove(mute);
+			}
+			else
+			{
+				LLMuteList::getInstance()->add(mute);
+				LLPanelBlockedList::showPanelAndSelect(mute.mID);
+			}
+		}
+
+		return true;
+	}
+};
+
 class LLWorldEnableBuyLand : public view_listener_t
 {
 	bool handleEvent(const LLSD& userdata)
@@ -8713,6 +8754,9 @@ void initialize_menus()
 	view_listener_t::addMenu(new LLLandBuyPass(), "Land.BuyPass");
 	view_listener_t::addMenu(new LLLandEdit(), "Land.Edit");
 
+	// Particle muting
+	view_listener_t::addMenu(new LLMuteParticle(), "Particle.Mute");
+
 	view_listener_t::addMenu(new LLLandEnableBuyPass(), "Land.EnableBuyPass");
 	commit.add("Land.Buy", boost::bind(&handle_buy_land));
 
@@ -8735,6 +8779,7 @@ void initialize_menus()
 	enable.add("EnablePayObject", boost::bind(&enable_pay_object));
 	enable.add("EnablePayAvatar", boost::bind(&enable_pay_avatar));
 	enable.add("EnableEdit", boost::bind(&enable_object_edit));
+	enable.add("EnableMuteParticle", boost::bind(&enable_mute_particle));
 	enable.add("VisibleBuild", boost::bind(&enable_object_build));
 	commit.add("Pathfinding.Linksets.Select", boost::bind(&LLFloaterPathfindingLinksets::openLinksetsWithSelectedObjects));
 	enable.add("EnableSelectInPathfindingLinksets", boost::bind(&enable_object_select_in_pathfinding_linksets));
diff --git a/indra/newview/llviewermenu.h b/indra/newview/llviewermenu.h
index 143420e2274971e814ee97484d0293651ef1be8e..7f09fc2d8faf74acc4c56cd89083ca960a1736c0 100755
--- a/indra/newview/llviewermenu.h
+++ b/indra/newview/llviewermenu.h
@@ -177,6 +177,7 @@ extern LLContextMenu		*gMenuObject;
 extern LLContextMenu		*gMenuAttachmentSelf;
 extern LLContextMenu		*gMenuAttachmentOther;
 extern LLContextMenu		*gMenuLand;
+extern LLContextMenu		*gMenuMuteParticle;
 
 // Needed to build menus when attachment site list available
 extern LLMenuGL* gAttachSubMenu;
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 61353dba7d12627b895b1e1d3f3b226f9a8ee12d..e3335c9cd859b333045e82fa30967e3b2dbc96f5 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4576,7 +4576,6 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
 		if (id == LLUUID::null)
 		{
 			LL_DEBUGS("Messaging") << "Unknown kill for local " << local_id << LL_ENDL;
-			gObjectList.mNumUnknownKills++;
 			continue;
 		}
 		else
@@ -4600,18 +4599,12 @@ void process_kill_object(LLMessageSystem *mesgsys, void **user_data)
 				// Do the kill
 				gObjectList.killObject(objectp);
 			}
-			else
-			{
-				LL_WARNS("Messaging") << "Object in UUID lookup, but not on object list in kill!" << LL_ENDL;
-				gObjectList.mNumUnknownKills++;
-			}
 		}
 
 		// We should remove the object from selection after it is marked dead by gObjectList to make LLToolGrab,
         // which is using the object, release the mouse capture correctly when the object dies.
         // See LLToolGrab::handleHoverActive() and LLToolGrab::handleHoverNonPhysical().
 		LLSelectMgr::getInstance()->removeObjectFromSelections(id);
-
 	}
 }
 
@@ -5943,6 +5936,15 @@ bool attempt_standard_notification(LLMessageSystem* msgsystem)
 				return true;
 			}
 		}
+		// HACK -- handle callbacks for specific alerts.
+		if( notificationID == "HomePositionSet" )
+		{
+			// save the home location image to disk
+			std::string snap_filename = gDirUtilp->getLindenUserDir();
+			snap_filename += gDirUtilp->getDirDelimiter();
+			snap_filename += SCREEN_HOME_FILENAME;
+			gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
+		}
 		
 		LLNotificationsUtil::add(notificationID, llsdBlock);
 		return true;
@@ -6018,14 +6020,6 @@ void process_alert_core(const std::string& message, BOOL modal)
 	{
 		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
 	}
-	else if( message == "Home position set." )
-	{
-		// save the home location image to disk
-		std::string snap_filename = gDirUtilp->getLindenUserDir();
-		snap_filename += gDirUtilp->getDirDelimiter();
-		snap_filename += SCREEN_HOME_FILENAME;
-		gViewerWindow->saveSnapshot(snap_filename, gViewerWindow->getWindowWidthRaw(), gViewerWindow->getWindowHeightRaw(), FALSE, FALSE);
-	}
 
 	const std::string ALERT_PREFIX("ALERT: ");
 	const std::string NOTIFY_PREFIX("NOTIFY: ");
@@ -7332,8 +7326,12 @@ void process_script_teleport_request(LLMessageSystem* msg, void**)
 	LLFloaterWorldMap* instance = LLFloaterWorldMap::getInstance();
 	if(instance)
 	{
-		instance->trackURL(
-						   sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
+		llinfos << "Object named " << object_name 
+			<< " is offering TP to region "
+			<< sim_name << " position " << pos
+			<< llendl;
+
+		instance->trackURL(sim_name, (S32)pos.mV[VX], (S32)pos.mV[VY], (S32)pos.mV[VZ]);
 		LLFloaterReg::showInstance("world_map", "center");
 	}
 	
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 97f4c3e5feb1e627f69494ed0852d15f8e81a8cf..e7821d4b9e489a43692d3b7013f1a95497d501e5 100755
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -43,6 +43,8 @@ const std::string  GRID_LABEL_VALUE = "label";
 const std::string  GRID_ID_VALUE = "grid_login_id";
 /// the url for the login cgi script
 const std::string  GRID_LOGIN_URI_VALUE = "login_uri";
+/// url base for update queries
+const std::string  GRID_UPDATE_SERVICE_URL = "update_query_url_base";
 ///
 const std::string  GRID_HELPER_URI_VALUE = "helper_uri";
 /// the splash page url
@@ -63,6 +65,8 @@ const std::string DEFAULT_LOGIN_PAGE = "http://viewer-login.agni.lindenlab.com/"
 
 const std::string MAIN_GRID_LOGIN_URI = "https://login.agni.lindenlab.com/cgi-bin/login.cgi";
 
+const std::string SL_UPDATE_QUERY_URL = "https://update.secondlife.com/update";
+
 const std::string MAIN_GRID_SLURL_BASE = "http://maps.secondlife.com/secondlife/";
 const std::string SYSTEM_GRID_APP_SLURL_BASE = "secondlife:///app";
 
@@ -120,12 +124,14 @@ void LLGridManager::initialize(const std::string& grid_file)
 				  MAIN_GRID_LOGIN_URI,
 				  "https://secondlife.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
+				  SL_UPDATE_QUERY_URL,
 				  "Agni");
 	addSystemGrid("Second Life Beta Test Grid (Aditi)",
 				  "util.aditi.lindenlab.com",
 				  "https://login.aditi.lindenlab.com/cgi-bin/login.cgi",
 				  "http://aditi-secondlife.webdev.lindenlab.com/helpers/",
 				  DEFAULT_LOGIN_PAGE,
+				  SL_UPDATE_QUERY_URL,
 				  "Aditi");
 
 	LLSD other_grids;
@@ -332,6 +338,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& login_uri,
 								  const std::string& helper,
 								  const std::string& login_page,
+								  const std::string& update_url_base,
 								  const std::string& login_id)
 {
 	LLSD grid = LLSD::emptyMap();
@@ -341,6 +348,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 	grid[GRID_LOGIN_URI_VALUE] = LLSD::emptyArray();
 	grid[GRID_LOGIN_URI_VALUE].append(login_uri);
 	grid[GRID_LOGIN_PAGE_VALUE] = login_page;
+	grid[GRID_UPDATE_SERVICE_URL] = update_url_base;
 	grid[GRID_IS_SYSTEM_GRID_VALUE] = true;
 	grid[GRID_LOGIN_IDENTIFIER_TYPES] = LLSD::emptyArray();
 	grid[GRID_LOGIN_IDENTIFIER_TYPES].append(CRED_IDENTIFIER_TYPE_AGENT);
@@ -537,6 +545,30 @@ std::string LLGridManager::getGridLoginID()
 	return mGridList[mGrid][GRID_ID_VALUE];
 }
 
+std::string LLGridManager::getUpdateServiceURL()
+{
+	std::string update_url_base = gSavedSettings.getString("CmdLineUpdateService");;
+	if ( !update_url_base.empty() )
+	{
+		LL_INFOS2("UpdaterService","GridManager")
+			<< "Update URL base overridden from command line: " << update_url_base
+			<< LL_ENDL;
+	}
+	else if ( mGridList[mGrid].has(GRID_UPDATE_SERVICE_URL) )
+	{
+		update_url_base = mGridList[mGrid][GRID_UPDATE_SERVICE_URL].asString();
+	}
+	else
+	{
+		LL_WARNS2("UpdaterService","GridManager")
+			<< "The grid property '" << GRID_UPDATE_SERVICE_URL
+			<< "' is not defined for the grid '" << mGrid << "'"
+			<< LL_ENDL;
+	}
+			
+	return update_url_base;
+}
+
 void LLGridManager::updateIsInProductionGrid()
 {
 	mIsInProductionGrid = false;
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 3f56103b2e72df1b1edfeaa7d903ba95987e8811..8526c0ba7f35959b41e90fc81b3a072d3f128b22 100755
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -139,6 +139,14 @@ class LLGridManager : public LLSingleton<LLGridManager>
 	 * I am not sure which is which
 	 */
 
+	//@}
+	/* ================================================================
+	 * @name Update Related Properties
+	 * @{
+	 */
+	/// Get the update service URL base (host and path) for the selected grid
+	std::string getUpdateServiceURL();
+	
 	//@}
 
 	/* ================================================================
@@ -207,6 +215,7 @@ class LLGridManager : public LLSingleton<LLGridManager>
 					   const std::string& login, 
 					   const std::string& helper,
 					   const std::string& login_page,
+					   const std::string& update_url_base,
 					   const std::string& login_id = "");	
 	
 	
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index caacf26cb38ac23977b2bbee1b5f80c66230be42..66615657d82a723d433c96b4e1fbeb1c688a5686 100755
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -106,7 +106,6 @@ LLViewerObjectList::LLViewerObjectList()
 	mNumNewObjects = 0;
 	mWasPaused = FALSE;
 	mNumDeadObjectUpdates = 0;
-	mNumUnknownKills = 0;
 	mNumUnknownUpdates = 0;
 }
 
diff --git a/indra/newview/llviewerobjectlist.h b/indra/newview/llviewerobjectlist.h
index 449a4633ff28794f467da1fc91edbb0807a8269e..6518c25d09f773b171dce567da5f8d222883b715 100755
--- a/indra/newview/llviewerobjectlist.h
+++ b/indra/newview/llviewerobjectlist.h
@@ -188,7 +188,6 @@ class LLViewerObjectList
 
 	S32 mNumUnknownUpdates;
 	S32 mNumDeadObjectUpdates;
-	S32 mNumUnknownKills;
 	S32 mNumDeadObjects;
 protected:
 	std::vector<U64>	mOrphanParents;	// LocalID/ip,port of orphaned objects
diff --git a/indra/newview/llviewerpartsim.cpp b/indra/newview/llviewerpartsim.cpp
index 6bd9f66b9c482e564ac34dbcb4434aefdfe84971..61cdfd781874871e8e683fe58c2d5af5ef1d1357 100755
--- a/indra/newview/llviewerpartsim.cpp
+++ b/indra/newview/llviewerpartsim.cpp
@@ -488,9 +488,13 @@ void LLViewerPartSim::destroyClass()
 //static
 BOOL LLViewerPartSim::shouldAddPart()
 {
-	if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+	if (sParticleCount >= MAX_PART_COUNT)
 	{
+		return FALSE;
+	}
 
+	if (sParticleCount > PART_THROTTLE_THRESHOLD*sMaxParticleCount)
+	{
 		F32 frac = (F32)sParticleCount/(F32)sMaxParticleCount;
 		frac -= PART_THROTTLE_THRESHOLD;
 		frac *= PART_THROTTLE_RESCALE;
@@ -500,7 +504,10 @@ BOOL LLViewerPartSim::shouldAddPart()
 			return FALSE;
 		}
 	}
-	if (sParticleCount >= MAX_PART_COUNT)
+
+	// Check frame rate, and don't add more if the viewer is really slow
+	const F32 MIN_FRAME_RATE_FOR_NEW_PARTICLES = 4.f;
+	if (gFPSClamped < MIN_FRAME_RATE_FOR_NEW_PARTICLES)
 	{
 		return FALSE;
 	}
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index 6cc9f4ace178506abade0d17529b7892ab57b493..84f66c359fbda3ebcdb3eb8cc54331f97731718e 100755
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -1199,10 +1199,10 @@ void LLViewerFetchedTexture::dump()
 // ONLY called from LLViewerFetchedTextureList
 void LLViewerFetchedTexture::destroyTexture() 
 {
-	//if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes)//not ready to release unused memory.
-	//{
-	//	return ;
-	//}
+	if(LLImageGL::sGlobalTextureMemoryInBytes < sMaxDesiredTextureMemInBytes * 0.95f)//not ready to release unused memory.
+	{
+		return ;
+	}
 	if (mNeedsCreateTexture)//return if in the process of generating a new texture.
 	{
 		return ;
@@ -1290,7 +1290,12 @@ void LLViewerFetchedTexture::addToCreateTexture()
 							destroyRawImage();
 							return ;
 						}
-						mRawImage->scale(w >> i, h >> i) ;					
+
+						{
+							//make a duplicate in case somebody else is using this raw image
+							mRawImage = mRawImage->duplicate(); 
+							mRawImage->scale(w >> i, h >> i) ;					
+						}
 					}
 				}
 			}
@@ -1521,7 +1526,7 @@ F32 LLViewerFetchedTexture::calcDecodePriority()
 	else if (pixel_priority < 0.001f && !have_all_data)
 	{
 		// Not on screen but we might want some data
-		if (mBoostLevel > BOOST_HIGH)
+		if (mBoostLevel > BOOST_SELECTED)
 		{
 			// Always want high boosted images
 			priority = 1.f;
@@ -2669,7 +2674,11 @@ void LLViewerFetchedTexture::setCachedRawImage()
 				--i ;
 			}
 			
-			mRawImage->scale(w >> i, h >> i) ;
+			{
+				//make a duplicate in case somebody else is using this raw image
+				mRawImage = mRawImage->duplicate(); 
+				mRawImage->scale(w >> i, h >> i) ;
+			}
 		}
 		mCachedRawImage = mRawImage ;
 		mRawDiscardLevel += i ;
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index c96f89017fd75d96734faecbf20383326bcd7851..10101a4b9b7ce70cd61ca834f869892ecdf9e22b 100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -101,6 +101,7 @@ class LLViewerTexture : public LLGLTexture
 		INVALID_TEXTURE_TYPE
 	};
 
+
 	typedef std::vector<LLFace*> ll_face_list_t;
 	typedef std::vector<LLVOVolume*> ll_volume_list_t;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 4c1d19f2f2dec3f1238bbce5985e4c03ef235a7c..40b856007104ace5beb23386dc722785d25b21fe 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -229,7 +229,9 @@ LLFrameTimer	gAwayTriggerTimer;
 BOOL			gShowOverlayTitle = FALSE;
 
 LLViewerObject*  gDebugRaycastObject = NULL;
+LLVOPartGroup* gDebugRaycastParticle = NULL;
 LLVector4a       gDebugRaycastIntersection;
+LLVector4a		gDebugRaycastParticleIntersection;
 LLVector2        gDebugRaycastTexCoord;
 LLVector4a       gDebugRaycastNormal;
 LLVector4a       gDebugRaycastTangent;
@@ -2843,6 +2845,8 @@ void LLViewerWindow::updateUI()
 											  &gDebugRaycastTangent,
 											  &gDebugRaycastStart,
 											  &gDebugRaycastEnd);
+
+		gDebugRaycastParticle = gPipeline.lineSegmentIntersectParticle(gDebugRaycastStart, gDebugRaycastEnd, &gDebugRaycastParticleIntersection, NULL);
 	}
 
 	updateMouseDelta();
@@ -3663,7 +3667,7 @@ void LLViewerWindow::pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback
 		pick_transparent = TRUE;
 	}
 
-	LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, TRUE, callback);
+	LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, FALSE, TRUE, callback);
 	schedulePick(pick_info);
 }
 
@@ -3719,7 +3723,7 @@ void LLViewerWindow::returnEmptyPicks()
 }
 
 // Performs the GL object/land pick.
-LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_transparent)
+LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_transparent, BOOL pick_particle)
 {
 	BOOL in_build_mode = LLFloaterReg::instanceVisible("build");
 	if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha)
@@ -3728,10 +3732,10 @@ LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot,  BOOL pick_trans
 		// "Show Debug Alpha" means no object actually transparent
 		pick_transparent = TRUE;
 	}
-
+	
 	// shortcut queueing in mPicks and just update mLastPick in place
 	MASK	key_mask = gKeyboard->currentMask(TRUE);
-	mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, TRUE, NULL);
+	mLastPick = LLPickInfo(LLCoordGL(x, y_from_bot), key_mask, pick_transparent, pick_particle, TRUE, NULL);
 	mLastPick.fetchResults();
 
 	return mLastPick;
@@ -4290,7 +4294,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	F32 scale_factor = 1.0f ;
 	if (!keep_window_aspect || (image_width > window_width) || (image_height > window_height))
 	{	
-		if ((image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
+		if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && 
+			(image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui)
 		{
 			if (scratch_space.allocate(image_width, image_height, GL_RGBA, true, true))
 			{
@@ -4305,6 +4310,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 					snapshot_height = image_height;
 					reset_deferred = true;
 					mWorldViewRectRaw.set(0, image_height, image_width, 0);
+					LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+					LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
 					scratch_space.bindTarget();
 				}
 				else
@@ -4514,6 +4521,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 	if (reset_deferred)
 	{
 		mWorldViewRectRaw = window_rect;
+		LLViewerCamera::getInstance()->setViewHeightInPixels( mWorldViewRectRaw.getHeight() );
+		LLViewerCamera::getInstance()->setAspect( getWorldViewAspectRatio() );
 		scratch_space.flush();
 		scratch_space.release();
 		gPipeline.allocateScreenBuffer(original_width, original_height);
@@ -5127,13 +5136,15 @@ LLPickInfo::LLPickInfo()
 	  mTangent(),
 	  mBinormal(),
 	  mHUDIcon(NULL),
-	  mPickTransparent(FALSE)
+	  mPickTransparent(FALSE),
+	  mPickParticle(FALSE)
 {
 }
 
 LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos, 
 		       MASK keyboard_mask, 
 		       BOOL pick_transparent,
+			   BOOL pick_particle,
 		       BOOL pick_uv_coords,
 		       void (*pick_callback)(const LLPickInfo& pick_info))
 	: mMousePt(mouse_pos),
@@ -5149,7 +5160,8 @@ LLPickInfo::LLPickInfo(const LLCoordGL& mouse_pos,
 	  mTangent(),
 	  mBinormal(),
 	  mHUDIcon(NULL),
-	  mPickTransparent(pick_transparent)
+	  mPickTransparent(pick_transparent),
+	  mPickParticle(pick_particle)
 {
 }
 
@@ -5167,6 +5179,10 @@ void LLPickInfo::fetchResults()
 	LLVector4a origin;
 	origin.load3(LLViewerCamera::getInstance()->getOrigin().mV);
 	F32 icon_dist = 0.f;
+	LLVector4a start;
+	LLVector4a end;
+	LLVector4a particle_end;
+
 	if (hit_icon)
 	{
 		LLVector4a delta;
@@ -5176,14 +5192,24 @@ void LLPickInfo::fetchResults()
 
 	LLViewerObject* hit_object = gViewerWindow->cursorIntersect(mMousePt.mX, mMousePt.mY, 512.f,
 									NULL, -1, mPickTransparent, &face_hit,
-									&intersection, &uv, &normal, &tangent);
+									&intersection, &uv, &normal, &tangent, &start, &end);
 	
 	mPickPt = mMousePt;
 
 	U32 te_offset = face_hit > -1 ? face_hit : 0;
 
-	//unproject relative clicked coordinate from window coordinate using GL
-	
+	if (mPickParticle)
+	{ //get the end point of line segement to use for particle raycast
+		if (hit_object)
+		{
+			particle_end = intersection;
+		}
+		else
+		{
+			particle_end = end;
+		}
+	}
+
 	LLViewerObject* objectp = hit_object;
 
 
@@ -5198,6 +5224,7 @@ void LLPickInfo::fetchResults()
 		mHUDIcon = hit_icon;
 		mPickType = PICK_ICON;
 		mPosGlobal = mHUDIcon->getPositionGlobal();
+
 	}
 	else if (objectp)
 	{
@@ -5247,6 +5274,18 @@ void LLPickInfo::fetchResults()
 		}
 	}
 	
+	if (mPickParticle)
+	{ //search for closest particle to click origin out to intersection point
+		S32 part_face = -1;
+
+		LLVOPartGroup* group = gPipeline.lineSegmentIntersectParticle(start, particle_end, NULL, &part_face);
+		if (group)
+		{
+			mParticleOwnerID = group->getPartOwner(part_face);
+			mParticleSourceID = group->getPartSource(part_face);
+		}
+	}
+
 	if (mPickCallback)
 	{
 		mPickCallback(*this);
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 89f6e3bc26e7194b7de436342ad8204146b9b3f2..c16b80b2149f5cbe7551f2352650ef2fbcd8f1c6 100755
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -65,6 +65,7 @@ class LLWindow;
 class LLRootView;
 class LLWindowListener;
 class LLViewerWindowListener;
+class LLVOPartGroup;
 class LLPopupView;
 
 #define PICK_HALF_WIDTH 5
@@ -87,7 +88,8 @@ class LLPickInfo
 	LLPickInfo();
 	LLPickInfo(const LLCoordGL& mouse_pos, 
 		MASK keyboard_mask, 
-		BOOL pick_transparent, 
+		BOOL pick_transparent,
+		BOOL pick_particle,
 		BOOL pick_surface_info,
 		void (*pick_callback)(const LLPickInfo& pick_info));
 
@@ -108,6 +110,8 @@ class LLPickInfo
 	LLVector3d		mPosGlobal;
 	LLVector3		mObjectOffset;
 	LLUUID			mObjectID;
+	LLUUID			mParticleOwnerID;
+	LLUUID			mParticleSourceID;
 	S32				mObjectFace;
 	LLHUDIcon*		mHUDIcon;
 	LLVector3       mIntersection;
@@ -118,6 +122,7 @@ class LLPickInfo
 	LLVector4		mTangent;
 	LLVector3		mBinormal;
 	BOOL			mPickTransparent;
+	BOOL			mPickParticle;
 	void		    getSurfaceInfo();
 
 private:
@@ -356,7 +361,7 @@ class LLViewerWindow : public LLWindowCallbacks
 	void			returnEmptyPicks();
 
 	void			pickAsync(S32 x, S32 y_from_bot, MASK mask, void (*callback)(const LLPickInfo& pick_info), BOOL pick_transparent = FALSE);
-	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent);
+	LLPickInfo		pickImmediate(S32 x, S32 y, BOOL pick_transparent, BOOL pick_particle = FALSE);
 	LLHUDIcon* cursorIntersectIcon(S32 mouse_x, S32 mouse_y, F32 depth,
 										   LLVector4a* intersection);
 
@@ -501,6 +506,8 @@ extern LLFrameTimer		gAwayTriggerTimer;		// how long the avatar has been away
 
 extern LLViewerObject*  gDebugRaycastObject;
 extern LLVector4a       gDebugRaycastIntersection;
+extern LLVOPartGroup*	gDebugRaycastParticle;
+extern LLVector4a		gDebugRaycastParticleIntersection;
 extern LLVector2        gDebugRaycastTexCoord;
 extern LLVector4a       gDebugRaycastNormal;
 extern LLVector4a       gDebugRaycastTangent;
diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp
index 43a5ddba425c70bbdee7eb2182576888e3c15a71..8ed86b4fd512a6fc95632194207a6c88c88421bd 100755
--- a/indra/newview/llvopartgroup.cpp
+++ b/indra/newview/llvopartgroup.cpp
@@ -193,8 +193,14 @@ void LLVOPartGroup::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax)
 	const LLVector3& pos_agent = getPositionAgent();
 	newMin.load3( (pos_agent - mScale).mV);
 	newMax.load3( (pos_agent + mScale).mV);
+
+	llassert(newMin.isFinite3());
+	llassert(newMax.isFinite3());
+
 	LLVector4a pos;
 	pos.load3(pos_agent.mV);
+
+	llassert(pos.isFinite3());
 	mDrawable->setPositionGroup(pos);
 }
 
@@ -234,6 +240,37 @@ LLDrawable* LLVOPartGroup::createDrawable(LLPipeline *pipeline)
 
  const F32 MAX_PARTICLE_AREA_SCALE = 0.02f; // some tuned constant, limits on how much particle area to draw
 
+ LLUUID LLVOPartGroup::getPartOwner(S32 idx)
+ {
+	 LLUUID ret = LLUUID::null;
+
+	 if (idx < (S32) mViewerPartGroupp->mParticles.size())
+	 {
+		 ret = mViewerPartGroupp->mParticles[idx]->mPartSourcep->getOwnerUUID();
+	 }
+
+	 return ret;
+ }
+
+ LLUUID LLVOPartGroup::getPartSource(S32 idx)
+ {
+	 LLUUID ret = LLUUID::null;
+
+	 if (idx < (S32) mViewerPartGroupp->mParticles.size())
+	 {
+		 LLViewerPart* part = mViewerPartGroupp->mParticles[idx];
+		 if (part && part->mPartSourcep.notNull() &&
+			 part->mPartSourcep->mSourceObjectp.notNull())
+		 {
+			 LLViewerObject* source = part->mPartSourcep->mSourceObjectp;
+			 ret = source->getID();
+		 }
+	 }
+
+	 return ret;
+ }
+
+
 F32 LLVOPartGroup::getPartSize(S32 idx)
 {
 	if (idx < (S32) mViewerPartGroupp->mParticles.size())
@@ -316,6 +353,10 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 			inv_camera_dist_squared = 1.f / camera_dist_squared;
 		else
 			inv_camera_dist_squared = 1.f;
+
+		llassert(llfinite(inv_camera_dist_squared));
+		llassert(!llisnan(inv_camera_dist_squared));
+
 		F32 area = part->mScale.mV[0] * part->mScale.mV[1] * inv_camera_dist_squared;
 		tot_area = llmax(tot_area, area);
  		
@@ -387,20 +428,63 @@ BOOL LLVOPartGroup::updateGeometry(LLDrawable *drawable)
 	return TRUE;
 }
 
-void LLVOPartGroup::getGeometry(S32 idx,
-								LLStrider<LLVector4a>& verticesp,
-								LLStrider<LLVector3>& normalsp, 
-								LLStrider<LLVector2>& texcoordsp,
-								LLStrider<LLColor4U>& colorsp, 
-								LLStrider<U16>& indicesp)
+
+BOOL LLVOPartGroup::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+										  S32 face,
+										  BOOL pick_transparent,
+										  S32* face_hit,
+										  LLVector4a* intersection,
+										  LLVector2* tex_coord,
+										  LLVector4a* normal,
+										  LLVector4a* bi_normal)
 {
-	if (idx >= (S32) mViewerPartGroupp->mParticles.size())
+	LLVector4a dir;
+	dir.setSub(end, start);
+
+	F32 closest_t = 2.f;
+	BOOL ret = FALSE;
+	
+	for (U32 idx = 0; idx < mViewerPartGroupp->mParticles.size(); ++idx)
 	{
-		return;
+		const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
+
+		LLVector4a v[4];
+		LLStrider<LLVector4a> verticesp;
+		verticesp = v;
+		
+		getGeometry(part, verticesp);
+
+		F32 a,b,t;
+		if (LLTriangleRayIntersect(v[0], v[1], v[2], start, dir, a,b,t) ||
+			LLTriangleRayIntersect(v[1], v[3], v[2], start, dir, a,b,t))
+		{
+			if (t >= 0.f &&
+				t <= 1.f &&
+				t < closest_t)
+			{
+				ret = TRUE;
+				closest_t = t;
+				if (face_hit)
+				{
+					*face_hit = idx;
+				}
+
+				if (intersection)
+				{
+					LLVector4a intersect = dir;
+					intersect.mul(closest_t);
+					intersection->setAdd(intersect, start);
+				}
+			}
+		}
 	}
 
-	const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
+	return ret;
+}
 
+void LLVOPartGroup::getGeometry(const LLViewerPart& part,
+								LLStrider<LLVector4a>& verticesp)
+{
 	LLVector4a part_pos_agent;
 	part_pos_agent.load3(part.mPosAgent.mV);
 	LLVector4a camera_agent;
@@ -452,8 +536,6 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	up.mul(0.5f*part.mScale.mV[1]);
 
 
-	LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
-
 	//HACK -- the verticesp->mV[3] = 0.f here are to set the texture index to 0 (particles don't use texture batching, maybe they should)
 	// this works because there is actually a 4th float stored after the vertex position which is used as a texture index
 	// also, somebody please VECTORIZE THIS
@@ -472,6 +554,25 @@ void LLVOPartGroup::getGeometry(S32 idx,
 	(*verticesp++).getF32ptr()[3] = 0.f;
 	verticesp->setAdd(ppamu, right);
 	(*verticesp++).getF32ptr()[3] = 0.f;
+}
+
+
+								
+void LLVOPartGroup::getGeometry(S32 idx,
+								LLStrider<LLVector4a>& verticesp,
+								LLStrider<LLVector3>& normalsp, 
+								LLStrider<LLVector2>& texcoordsp,
+								LLStrider<LLColor4U>& colorsp, 
+								LLStrider<U16>& indicesp)
+{
+	if (idx >= (S32) mViewerPartGroupp->mParticles.size())
+	{
+		return;
+	}
+	
+	const LLViewerPart &part = *((LLViewerPart*) (mViewerPartGroupp->mParticles[idx]));
+
+	getGeometry(part, verticesp);
 
 	*colorsp++ = part.mColor;
 	*colorsp++ = part.mColor;
@@ -480,6 +581,7 @@ void LLVOPartGroup::getGeometry(S32 idx,
 
 	if (!(part.mFlags & LLPartData::LL_PART_EMISSIVE_MASK))
 	{ //not fullbright, needs normal
+		LLVector3 normal = -LLViewerCamera::getInstance()->getXAxis();
 		*normalsp++   = normal;
 		*normalsp++   = normal;
 		*normalsp++   = normal;
diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h
index 42c1252d01f69c9fccfbf08c272c35205b03f10b..2befb018239f85f43a04490c516c95187609eafd 100755
--- a/indra/newview/llvopartgroup.h
+++ b/indra/newview/llvopartgroup.h
@@ -69,11 +69,23 @@ class LLVOPartGroup : public LLAlphaObject
 	virtual void updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax);
 	virtual U32 getPartitionType() const;
 	
+	/*virtual*/ BOOL lineSegmentIntersect(const LLVector4a& start, const LLVector4a& end,
+										  S32 face,
+										  BOOL pick_transparent,
+										  S32* face_hit,
+										  LLVector4a* intersection,
+										  LLVector2* tex_coord,
+										  LLVector4a* normal,
+										  LLVector4a* tangent);
+
 	/*virtual*/ void setPixelAreaAndAngle(LLAgent &agent);
 	/*virtual*/ void updateTextures();
 
 	/*virtual*/ LLDrawable* createDrawable(LLPipeline *pipeline);
 	/*virtual*/ BOOL        updateGeometry(LLDrawable *drawable);
+	void		getGeometry(const LLViewerPart& part,							
+								LLStrider<LLVector4a>& verticesp);
+				
 				void		getGeometry(S32 idx,
 								LLStrider<LLVector4a>& verticesp,
 								LLStrider<LLVector3>& normalsp, 
@@ -83,6 +95,9 @@ class LLVOPartGroup : public LLAlphaObject
 
 	void updateFaceSize(S32 idx) { }
 	F32 getPartSize(S32 idx);
+	LLUUID getPartOwner(S32 idx);
+	LLUUID getPartSource(S32 idx);
+
 	void setViewerPartGroup(LLViewerPartGroup *part_groupp)		{ mViewerPartGroupp = part_groupp; }
 	LLViewerPartGroup* getViewerPartGroup()	{ return mViewerPartGroupp; }
 
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index 3be1f523529c78adbe6f42692a8a044fe53e4c93..e6385dceeac8eccb0bad86ce4589c0c014a19b70 100755
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -1113,7 +1113,13 @@ void LLVOVolume::sculpt()
 		
 		S32 max_discard = mSculptTexture->getMaxDiscardLevel();
 		if (discard_level > max_discard)
-			discard_level = max_discard;    // clamp to the best we can do
+		{
+			discard_level = max_discard;    // clamp to the best we can do			
+		}
+		if(discard_level > MAX_DISCARD_LEVEL)
+		{
+			return; //we think data is not ready yet.
+		}
 
 		S32 current_discard = getVolume()->getSculptLevel() ;
 		if(current_discard < -2)
@@ -1452,7 +1458,7 @@ BOOL LLVOVolume::genBBoxes(BOOL force_global)
 			continue;
 		}
 		res &= face->genVolumeBBoxes(*volume, i,
-										mRelativeXform, mRelativeXformInvTrans,
+										mRelativeXform, 
 										(mVolumeImpl && mVolumeImpl->isVolumeGlobal()) || force_global);
 		
 		if (rebuild)
@@ -4833,7 +4839,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
 
 			if (is_rigged)
 			{
-				drawablep->setState(LLDrawable::RIGGED);
+				if (!drawablep->isState(LLDrawable::RIGGED))
+				{
+					drawablep->setState(LLDrawable::RIGGED);
+
+					//first time this is drawable is being marked as rigged,
+					// do another LoD update to use avatar bounding box
+					vobj->updateLOD();
+				}
 			}
 			else
 			{
diff --git a/indra/newview/noise.h b/indra/newview/noise.h
index 0923bffcf2c8090997743783cde0365d9f6dc717..b3efad73c5622063e5334c3ba75e2129f90e6461 100755
--- a/indra/newview/noise.h
+++ b/indra/newview/noise.h
@@ -310,6 +310,8 @@ static void normalize3(F32 v[3])
 
 static void init(void)
 {
+	// we want repeatable noise (e.g. for stable terrain texturing), so seed with known value
+	srand(42);
 	int i, j, k;
 
 	for (i = 0 ; i < B ; i++) {
@@ -340,6 +342,9 @@ static void init(void)
 		for (j = 0 ; j < 3 ; j++)
 			g3[B + i][j] = g3[i][j];
 	}
+
+	// reintroduce entropy
+	srand(time(NULL));		// Flawfinder: ignore
 }
 
 #undef B
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index c25d22bbdf77f0b77072eecd5c88df9de6bb2981..f49395da349e57ef71a5d39b1b8e452ce1fffb7f 100755
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -163,6 +163,7 @@ S32 LLPipeline::RenderGlowIterations;
 F32 LLPipeline::RenderGlowWidth;
 F32 LLPipeline::RenderGlowStrength;
 BOOL LLPipeline::RenderDepthOfField;
+BOOL LLPipeline::RenderDepthOfFieldInEditMode;
 F32 LLPipeline::CameraFocusTransitionTime;
 F32 LLPipeline::CameraFNumber;
 F32 LLPipeline::CameraFocalLength;
@@ -615,6 +616,7 @@ void LLPipeline::init()
 	connectRefreshCachedSettingsSafe("RenderGlowWidth");
 	connectRefreshCachedSettingsSafe("RenderGlowStrength");
 	connectRefreshCachedSettingsSafe("RenderDepthOfField");
+	connectRefreshCachedSettingsSafe("RenderDepthOfFieldInEditMode");
 	connectRefreshCachedSettingsSafe("CameraFocusTransitionTime");
 	connectRefreshCachedSettingsSafe("CameraFNumber");
 	connectRefreshCachedSettingsSafe("CameraFocalLength");
@@ -1125,6 +1127,7 @@ void LLPipeline::refreshCachedSettings()
 	RenderGlowWidth = gSavedSettings.getF32("RenderGlowWidth");
 	RenderGlowStrength = gSavedSettings.getF32("RenderGlowStrength");
 	RenderDepthOfField = gSavedSettings.getBOOL("RenderDepthOfField");
+	RenderDepthOfFieldInEditMode = gSavedSettings.getBOOL("RenderDepthOfFieldInEditMode");
 	CameraFocusTransitionTime = gSavedSettings.getF32("CameraFocusTransitionTime");
 	CameraFNumber = gSavedSettings.getF32("CameraFNumber");
 	CameraFocalLength = gSavedSettings.getF32("CameraFocalLength");
@@ -4864,18 +4867,6 @@ void LLPipeline::renderPhysicsDisplay()
 		}
 	}
 
-	for (LLCullResult::bridge_iterator i = sCull->beginVisibleBridge(); i != sCull->endVisibleBridge(); ++i)
-	{
-		LLSpatialBridge* bridge = *i;
-		if (!bridge->isDead() && hasRenderType(bridge->mDrawableType))
-		{
-			gGL.pushMatrix();
-			gGL.multMatrix((F32*)bridge->mDrawable->getRenderMatrix().mMatrix);
-			bridge->renderPhysicsShapes();
-			gGL.popMatrix();
-		}
-	}
-
 	gGL.flush();
 
 	if (LLGLSLShader::sNoFixedFunction)
@@ -5323,6 +5314,42 @@ void LLPipeline::renderDebug()
 		gUIProgram.bind();
 	}
 
+	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_RAYCAST) && !hud_only)
+	{ //draw crosshairs on particle intersection
+		if (gDebugRaycastParticle)
+		{
+			if (LLGLSLShader::sNoFixedFunction)
+			{ //this debug display requires shaders
+				gDebugProgram.bind();
+
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
+
+				LLVector3 center(gDebugRaycastParticleIntersection.getF32ptr());
+				LLVector3 size(0.1f, 0.1f, 0.1f);
+
+				LLVector3 p[6];
+
+				p[0] = center + size.scaledVec(LLVector3(1,0,0));
+				p[1] = center + size.scaledVec(LLVector3(-1,0,0));
+				p[2] = center + size.scaledVec(LLVector3(0,1,0));
+				p[3] = center + size.scaledVec(LLVector3(0,-1,0));
+				p[4] = center + size.scaledVec(LLVector3(0,0,1));
+				p[5] = center + size.scaledVec(LLVector3(0,0,-1));
+				
+				gGL.begin(LLRender::LINES);
+				gGL.diffuseColor3f(1.f, 1.f, 0.f);
+				for (U32 i = 0; i < 6; i++)
+				{
+					gGL.vertex3fv(p[i].mV);
+				}
+				gGL.end();
+				gGL.flush();
+
+				gDebugProgram.unbind();
+			}
+		}
+	}
+
 	if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA))
 	{
 		LLVertexBuffer::unbind();
@@ -5356,7 +5383,7 @@ void LLPipeline::renderDebug()
 			if (i > 3)
 			{ //render shadow frusta as volumes
 				if (mShadowFrustPoints[i-4].empty())
-			{
+				{
 					continue;
 				}
 
@@ -7003,6 +7030,48 @@ void LLPipeline::setRenderHighlightTextureChannel(LLRender::eTexIndex channel)
 	sRenderHighlightTextureChannel = channel;
 }
 
+LLVOPartGroup* LLPipeline::lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+														S32* face_hit)
+{
+	LLVector4a local_end = end;
+
+	LLVector4a position;
+
+	LLDrawable* drawable = NULL;
+
+	for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); 
+			iter != LLWorld::getInstance()->getRegionList().end(); ++iter)
+	{
+		LLViewerRegion* region = *iter;
+
+		LLSpatialPartition* part = region->getSpatialPartition(LLViewerRegion::PARTITION_PARTICLE);
+		if (part && hasRenderType(part->mDrawableType))
+		{
+			LLDrawable* hit = part->lineSegmentIntersect(start, local_end, TRUE, face_hit, &position, NULL, NULL, NULL);
+			if (hit)
+			{
+				drawable = hit;
+				local_end = position;						
+			}
+		}
+	}
+
+	LLVOPartGroup* ret = NULL;
+	if (drawable)
+	{
+		//make sure we're returning an LLVOPartGroup
+		llassert(drawable->getVObj()->getPCode() == LLViewerObject::LL_VO_PART_GROUP);
+		ret = (LLVOPartGroup*) drawable->getVObj().get();
+	}
+		
+	if (intersection)
+	{
+		*intersection = position;
+	}
+
+	return ret;
+}
+
 LLViewerObject* LLPipeline::lineSegmentIntersectInWorld(const LLVector4a& start, const LLVector4a& end,
 														BOOL pick_transparent,												
 														S32* face_hit,
@@ -7562,7 +7631,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
 	{
 
 		bool dof_enabled = !LLViewerCamera::getInstance()->cameraUnderWater() &&
-							!LLToolMgr::getInstance()->inBuildMode() &&
+			(RenderDepthOfFieldInEditMode || !LLToolMgr::getInstance()->inBuildMode()) &&
 							RenderDepthOfField;
 
 
@@ -9582,7 +9651,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 	pp.push_back(LLVector3(max.mV[0], max.mV[1], max.mV[2]));
 
 	//add corners of camera frustum
-	for (U32 i = 0; i < 8; i++)
+	for (U32 i = 0; i < LLCamera::AGENT_FRUSTRUM_NUM; i++)
 	{
 		pp.push_back(camera.mAgentFrustum[i]);
 	}
@@ -9609,7 +9678,7 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 
 	for (U32 i = 0; i < 12; i++)
 	{ //for each line segment in bounding box
-		for (U32 j = 0; j < 6; j++) 
+		for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; j++) 
 		{ //for each plane in camera frustum
 			const LLPlane& cp = camera.getAgentPlane(j);
 			const LLVector3& v1 = pp[bs[i*2+0]];
@@ -9695,19 +9764,19 @@ BOOL LLPipeline::getVisiblePointCloud(LLCamera& camera, LLVector3& min, LLVector
 			}
 		}
 				
-		for (U32 j = 0; j < 6; ++j)
+		for (U32 j = 0; j < LLCamera::AGENT_PLANE_NO_USER_CLIP_NUM; ++j)
 		{
 			const LLPlane& cp = camera.getAgentPlane(j);
 			F32 dist = cp.dist(pp[i]);
 			if (dist > 0.05f) //point is above some plane, not contained
-					{
+			{
 				found = false;
 				break;
-						}
-					}
+			}
+		}
 
-					if (found)
-					{
+		if (found)
+		{
 			fp.push_back(pp[i]);
 		}
 	}
diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h
index 70dcf8040708568ae3c576bb686a814a137c635c..f0bebbe20d869d1421ad8411375d3ec2ffe45da1 100755
--- a/indra/newview/pipeline.h
+++ b/indra/newview/pipeline.h
@@ -58,6 +58,7 @@ class LLRenderFunc;
 class LLCubeMap;
 class LLCullResult;
 class LLVOAvatar;
+class LLVOPartGroup;
 class LLGLSLShader;
 class LLCurlRequest;
 class LLDrawPoolAlpha;
@@ -202,6 +203,12 @@ class LLPipeline
 												LLVector4a* normal = NULL,               // return the surface normal at the intersection point
 												LLVector4a* tangent = NULL             // return the surface tangent at the intersection point  
 		);
+
+	//get the closest particle to start between start and end, returns the LLVOPartGroup and particle index
+	LLVOPartGroup* lineSegmentIntersectParticle(const LLVector4a& start, const LLVector4a& end, LLVector4a* intersection,
+														S32* face_hit);
+
+
 	LLViewerObject* lineSegmentIntersectInHUD(const LLVector4a& start, const LLVector4a& end,
 											  BOOL pick_transparent,
 											  S32* face_hit,                          // return the face hit
@@ -910,6 +917,7 @@ class LLPipeline
 	static F32 RenderGlowWidth;
 	static F32 RenderGlowStrength;
 	static BOOL RenderDepthOfField;
+	static BOOL RenderDepthOfFieldInEditMode;
 	static F32 CameraFocusTransitionTime;
 	static F32 CameraFNumber;
 	static F32 CameraFocalLength;
diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml
index fc8bc33096d17eb5a96f689fb1511afe9ef87da1..9206690c8f27a5b44a4effe44932dd4a11b4f28f 100755
--- a/indra/newview/skins/default/xui/da/floater_about.xml
+++ b/indra/newview/skins/default/xui/da/floater_about.xml
@@ -8,7 +8,7 @@
 		Bygget med [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Du er ved [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Du er ved [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] i regionen [REGION] lokaliseret ved &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml
index 4387a619634bab5fd4f2b23cc7044ac666a632d7..524546718327f201848959feadbe37e16b616dbb 100755
--- a/indra/newview/skins/default/xui/de/floater_about.xml
+++ b/indra/newview/skins/default/xui/de/floater_about.xml
@@ -8,7 +8,7 @@
 		Kompiliert mit [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Sie befinden sich in [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Sie befinden sich in [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] auf &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml
index 63eb87f27a17531b618229d8883eaeb11119c0c1..703015af20081678693a8f0d72ad20312f1dd2e4 100755
--- a/indra/newview/skins/default/xui/en/floater_about.xml
+++ b/indra/newview/skins/default/xui/en/floater_about.xml
@@ -22,7 +22,9 @@ Built with [COMPILER] version [COMPILER_VERSION]
 </floater.string>
   <floater.string
      name="AboutPosition">
-You are at [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+You are at [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] located at &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+SLURL: &lt;nolink&gt;[SLURL]&lt;/nolink&gt;
+(global coordinates [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 
diff --git a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
index 4e0cfb0cd4750e3502e3d5547e327754cbdc5a10..e7ab3cacdc4439086e723e68c0e079c540de60e0 100755
--- a/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
+++ b/indra/newview/skins/default/xui/en/floater_bulk_perms.xml
@@ -6,7 +6,7 @@
  layout="topleft"
  name="floaterbulkperms"
  help_topic="floaterbulkperms"
- title="EDIT CONTENT PERMISSIONS"
+ title="ADJUST CONTENT PERMISSIONS"
  width="410">
     <floater.string
      name="nothing_to_modify_text">
@@ -192,7 +192,7 @@
      name="newperms"
      top="90"
      width="250">
-        New Content Permissions
+        Adjust Content Permissions To
     </text>
       <text
        type="string"
@@ -292,9 +292,20 @@
      height="23"
      label="OK"
      layout="topleft"
-     left="205"
-     name="apply"
+     left="110"
+     name="ok"
      top_pad="10"
+     width="90">
+      <button.commit_callback
+       function="BulkPermission.Ok"/>
+    </button>
+    <button
+     follows="left|top"
+     height="23"
+     label="Apply"
+     layout="topleft"
+     left_pad="5"
+     name="apply"
      width="90">
       <button.commit_callback
        function="BulkPermission.Apply"/>
diff --git a/indra/newview/skins/default/xui/en/floater_goto_line.xml b/indra/newview/skins/default/xui/en/floater_goto_line.xml
new file mode 100644
index 0000000000000000000000000000000000000000..b2368882199bb3419fdce0c63309271c8fc53fe0
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/floater_goto_line.xml
@@ -0,0 +1,44 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<floater
+ legacy_header_height="18"
+ default_tab_group="1"
+ height="90"
+ layout="topleft"
+ name="script goto"
+ help_topic="script_goto"
+ title="GO TO LINE"
+ width="200">
+    <button
+     height="24"
+     label="OK"
+     label_selected="OK"
+     layout="topleft"
+     left="55"
+     name="goto_btn"
+     top="53"
+     width="90" />
+    <text
+     type="string"
+     length="1"
+     follows="left|top"
+     height="16"
+     layout="topleft"
+     left="10"
+     name="txt"
+     top="21"
+     width="65">
+        Go to line
+    </text>
+    <line_editor
+     border_style="line"
+     border_thickness="1"
+     follows="left|top"
+     height="16"
+     layout="topleft"
+     left="75"
+     max_length_bytes="9"
+     name="goto_line"
+     tab_group="1"
+     top="21"
+     width="85" />
+</floater>
\ No newline at end of file
diff --git a/indra/newview/skins/default/xui/en/menu_attachment_other.xml b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
index 46ba4bd29d2786bf2c0ac1f7835dffb4765eac06..0a8beec7de025d569fb13bc68e5c6dbbfce16d3f 100755
--- a/indra/newview/skins/default/xui/en/menu_attachment_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_other.xml
@@ -112,4 +112,15 @@
          <menu_item_call.on_enable
           function="Object.EnableInspect" />
    </menu_item_call>
+  <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
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 28e032ce5f0e4f90c4eaf1c016efbb3d9003bfce..bcbc8d5b86c7df1ba7d93c0e69ee85e92b55769e 100755
--- a/indra/newview/skins/default/xui/en/menu_attachment_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_attachment_self.xml
@@ -143,4 +143,15 @@ name="Edit Outfit">
     <menu_item_call.on_enable
      function="Attachment.EnableDrop" />
   </menu_item_call>
+  <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
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 e7c2b80da27f45f8b69c8297352885aab5d5a87c..8be2683680fa6115b4a9740e6112320899a74e52 100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_other.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_other.xml
@@ -103,4 +103,15 @@
         <menu_item_call.on_enable
          function="EnablePayAvatar" />
     </menu_item_call>
+  <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
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 c1ff026a74e51fb856db513c20fe177cc6882d12..ca0c9bd5e4947d8235235fc6b7c65364df09edae 100755
--- a/indra/newview/skins/default/xui/en/menu_avatar_self.xml
+++ b/indra/newview/skins/default/xui/en/menu_avatar_self.xml
@@ -269,4 +269,16 @@
             <menu_item_call.on_visible
              function="Advanced.EnableAppearanceToXML"/>
     </menu_item_call>
+  <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_land.xml b/indra/newview/skins/default/xui/en/menu_land.xml
index cc6d8ad9c1d8dcd37fd57b56d324dd8feca35a91..2ad5cbbe951cd561d4b72ab58fa5afb16380842b 100755
--- a/indra/newview/skins/default/xui/en/menu_land.xml
+++ b/indra/newview/skins/default/xui/en/menu_land.xml
@@ -61,4 +61,15 @@
         <menu_item_call.on_enable
          function="EnableEdit" />
     </menu_item_call>
+   <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_mute_particle.xml b/indra/newview/skins/default/xui/en/menu_mute_particle.xml
new file mode 100644
index 0000000000000000000000000000000000000000..a4261bf39e6ea5f411d477fa195132e765ccdcfd
--- /dev/null
+++ b/indra/newview/skins/default/xui/en/menu_mute_particle.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
+<!-- *NOTE: See also menu_attachment_other.xml -->
+<context_menu
+ layout="topleft"
+ name="Mute Particle Pie">
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
+</context_menu>
diff --git a/indra/newview/skins/default/xui/en/menu_object.xml b/indra/newview/skins/default/xui/en/menu_object.xml
index f6004621a652988262a4c0d0225236fa449bf661..52ab7da51550113eb57baca78fa4ac8f1a3f35b9 100755
--- a/indra/newview/skins/default/xui/en/menu_object.xml
+++ b/indra/newview/skins/default/xui/en/menu_object.xml
@@ -196,4 +196,15 @@
     <menu_item_call.on_enable
         function="Object.EnableDelete" />
   </menu_item_call>
+  <menu_item_separator
+       layout="topleft" />
+  <menu_item_call
+     enabled="false"
+     label="Block Particle Owner"
+     name="Mute Particle">
+    <menu_item_call.on_click
+     function="Particle.Mute" />
+    <menu_item_call.on_enable
+     function="EnableMuteParticle" />
+  </menu_item_call>
 </context_menu>
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index 597f57eb0af6a1aecff21d202ca12ee94dd1b82f..ebd2799ebf8b3d1cbcc1c105acc74579115bbf6d 100755
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -506,6 +506,33 @@ Add this Ability to &apos;[ROLE_NAME]&apos;?
      notext="No"
      yestext="Yes"/>
   </notification>
+  
+  <notification
+    icon="alertmodal.tga"
+    name="EjectGroupMemberWarning"
+    type="alertmodal">
+     You are about to eject [AVATAR_NAME] from the group.
+     <tag>group</tag>
+     <tag>confirm</tag>
+     <usetemplate
+      ignoretext="Confirm ejecting a participant from group"
+      name="okcancelignore"
+      notext="Cancel"
+      yestext="Eject"/>
+  </notification>
+  <notification
+    icon="alertmodal.tga"
+    name="EjectGroupMembersWarning"
+    type="alertmodal">
+     You are about to eject [COUNT] members from the group.
+     <tag>group</tag>
+     <tag>confirm</tag>
+     <usetemplate
+      ignoretext="Confirm ejecting multiple members from group"
+      name="okcancelignore"
+      notext="Cancel"
+      yestext="Eject"/>
+  </notification>
 
   <notification
    icon="alertmodal.tga"
@@ -2682,7 +2709,7 @@ Please enter a higher price.
    icon="alertmodal.tga"
    name="ConfirmItemDeleteHasLinks"
    type="alertmodal">
-At least one of the items you has link items that point to it.  If you delete this item, its links will permanently stop working.  It is strongly advised to delete the links first.
+At least one of the items has links that point to it.  If you delete this item, its links will permanently stop working.  It is strongly advised to delete the links first.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2724,7 +2751,7 @@ Are you sure you want to delete these items?
    icon="alertmodal.tga"
    name="ConfirmObjectDeleteNoOwn"
    type="alertmodal">
-You do not own least one of the items you have selected.
+You do not own at least one of the items you have selected.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2754,7 +2781,7 @@ Are you sure you want to delete these items?
    name="ConfirmObjectDeleteLockNoOwn"
    type="alertmodal">
 At least one object is locked.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2769,7 +2796,7 @@ Are you sure you want to delete these items?
    name="ConfirmObjectDeleteNoCopyNoOwn"
    type="alertmodal">
 At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
@@ -2785,13 +2812,13 @@ Are you sure you want to delete these items?
    type="alertmodal">
 At least one object is locked.
 At least one object is not copyable.
-You do not own least one object.
+You do not own at least one object.
 
 Are you sure you want to delete these items?
     <tag>confirm</tag>
     <usetemplate
      name="okcancelbuttons"
-     notext="cancel"
+     notext="Cancel"
      yestext="OK"/>
   </notification>
 
@@ -6813,7 +6840,6 @@ This will add a bookmark in your inventory so you can quickly IM this Resident.
    name="RegionRestartMinutes"
    priority="high"
    sound="UISndAlert"
-   persist="true"
    type="notify">
 This region will restart in [MINUTES] minutes.
 If you stay in this region you will be logged out.
@@ -6824,7 +6850,6 @@ If you stay in this region you will be logged out.
    name="RegionRestartSeconds"
    priority="high"
    sound="UISndAlert"
-   persist="true"
    type="notify">
 This region will restart in [SECONDS] seconds.
 If you stay in this region you will be logged out.
diff --git a/indra/newview/skins/default/xui/en/panel_group_notices.xml b/indra/newview/skins/default/xui/en/panel_group_notices.xml
index 6d5fb51e85892d86d1836e4a89c8681629459821..c8ce5cdebf01c8b9d5db52bcb27bd519be7c3da0 100755
--- a/indra/newview/skins/default/xui/en/panel_group_notices.xml
+++ b/indra/newview/skins/default/xui/en/panel_group_notices.xml
@@ -202,14 +202,14 @@ Maximum 200 per group daily
             Drag and drop item here to attach it:
         </text>
         <icon
-         height="72"
+         height="48"
          image_name="DropTarget"
          layout="topleft"
          left_pad="10"
          mouse_opaque="true"
          name="drop_icon"
          top_delta="-10"
-         width="72" />
+         width="110" />
         <button
          follows="left|top"
          layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_people.xml b/indra/newview/skins/default/xui/en/panel_people.xml
index 7ce2627be9931c2a59c629c4c4507d21aff5ad8e..ed274d02337bd81253c674aaf23e7faa1dca6f08 100755
--- a/indra/newview/skins/default/xui/en/panel_people.xml
+++ b/indra/newview/skins/default/xui/en/panel_people.xml
@@ -480,10 +480,22 @@ Looking for people to hang out with? Try the [secondlife:///app/worldmap World M
                      function="People.Group.Minus" />
                 </dnd_button>
             </panel>
+            <text
+                type="string"
+                length="1"
+                follows="all"
+                height="14"
+                layout="topleft"
+                right="-10"
+                top_pad="4"
+                left="3"
+                name="groupcount">
+              You belong to [COUNT] groups, and can join [REMAINING] more.
+            </text>
             <group_list
              allow_select="true" 
              follows="all"
-             height="406"
+             height="388"
              layout="topleft"
              left="3"
              name="group_list"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
index 2cc9d9c1b075437557c7467dfb98f39bd61ad50a..50fd57494f91b60dff52895737381ba643716bfe 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_advanced.xml
@@ -138,7 +138,7 @@
    initial_value="1"
    layout="topleft"
    left_pad="0"
-   max_val="1.4"
+   max_val="1.5"
    min_val="0.75"
    name="ui_scale_slider"
    top_pad="-14"
diff --git a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
index d7db7caf66efc65ee754638f17d96d29569d9320..3c4d28803729b82942bcca6674ea73e2f59192e1 100755
--- a/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
+++ b/indra/newview/skins/default/xui/en/panel_preferences_graphics1.xml
@@ -47,7 +47,7 @@
         Better
     </text>
     <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
@@ -56,16 +56,15 @@
      top_delta="-2"
      width="2" />
   <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
      left_pad="41"
-     name="LowMidraphicsDivet"
-     top_delta="-2"
+     name="LowMidGraphicsDivet"
      width="2" />
     <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
@@ -74,7 +73,7 @@
      top_delta="0"
      width="2" />
   <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
@@ -83,7 +82,7 @@
      top_delta="0"
      width="2" />
     <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
@@ -92,7 +91,7 @@
      top_delta="0"
      width="2" />
   <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
@@ -101,7 +100,7 @@
      top_delta="0"
      width="2" />
     <icon
-     color="0.12 0.12 0.12 1"
+     color="DkGray"
      height="14"
      image_name="Rounded_Square"
      layout="topleft"
diff --git a/indra/newview/skins/default/xui/en/panel_script_ed.xml b/indra/newview/skins/default/xui/en/panel_script_ed.xml
index 765b07ed8b36ab74a03c2dbcb3645764bcc4c958..bcdef96138127908cb98a4172587b41ec1da7606 100755
--- a/indra/newview/skins/default/xui/en/panel_script_ed.xml
+++ b/indra/newview/skins/default/xui/en/panel_script_ed.xml
@@ -125,6 +125,10 @@
              label="Search / Replace..."
              layout="topleft"
              name="Search / Replace..." />
+            <menu_item_call
+             label="Go to line..."
+             layout="topleft"
+             name="Go to line..." />
         </menu>
         <menu
          top="0"
diff --git a/indra/newview/skins/default/xui/en/role_actions.xml b/indra/newview/skins/default/xui/en/role_actions.xml
index 89aef57ccaea0ab8274168fa6bda56f017a4520c..0eeccbeac516983fcf523daae0cf7685a0f481a1 100755
--- a/indra/newview/skins/default/xui/en/role_actions.xml
+++ b/indra/newview/skins/default/xui/en/role_actions.xml
@@ -70,8 +70,8 @@
 		     longdescription="Toggle &apos;Show Place in Search&apos; and setting a parcel&apos;s category in About Land &gt; Options tab."
 		     name="land find places" value="17" />
 		<action
-		     description="Change parcel name, description, and &apos;Show Place in Search&apos; settings"
-		     longdescription="Change parcel name, description, and &apos;Show Place in Search&apos; settings. This is done in About Land &gt; Options tab."
+		     description="Change parcel name, description, and &apos;Moderate Content&apos; settings"
+		     longdescription="Change parcel name, description, and &apos;Moderate Content&apos; settings. This is done in About Land &gt; Options tab."
 		     name="land change identity" value="18" />
 		<action description="Set landing point and set teleport routing"
 		     longdescription="On a group-owned parcel, Members in a Role with this Ability can set a landing point to specify where incoming teleports arrive, and also set teleport routing for further control. This is done in About Land &gt; Options tab."
diff --git a/indra/newview/skins/default/xui/en/strings.xml b/indra/newview/skins/default/xui/en/strings.xml
index f1e551695fdcc7d4f22258e66ab34aa48ec6fb83..73601ecb9f45650efed5ca8cc41c9ab0fa0a658d 100755
--- a/indra/newview/skins/default/xui/en/strings.xml
+++ b/indra/newview/skins/default/xui/en/strings.xml
@@ -2516,6 +2516,8 @@ Drag folders to this area and click "Send to Marketplace" to list them for sale
 	<string name="ATTACH_HUD_BOTTOM_LEFT">HUD Bottom Left</string>
 	<string name="ATTACH_HUD_BOTTOM">HUD Bottom</string>
 	<string name="ATTACH_HUD_BOTTOM_RIGHT">HUD Bottom Right</string>
+	<string name="ATTACH_NECK">Neck</string>
+	<string name="ATTACH_AVATAR_CENTER">Avatar Center</string>
 
 	<!-- script editor -->
 	<string name="CursorPos">Line [LINE], Column [COLUMN]</string>
diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml
index 3696c7e12cfe6bc4ea349126b2612f28ebf70e41..7ca1e3721f48952bafa9d73296033b08219c2e77 100755
--- a/indra/newview/skins/default/xui/es/floater_about.xml
+++ b/indra/newview/skins/default/xui/es/floater_about.xml
@@ -8,7 +8,7 @@
 		Compilado con [COMPILER], versión [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Estás en la posición [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1], de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Estás en la posición [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1], de [REGION], alojada en &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml
index a659cb4245825c358dec94a8d3bc056fdafaa191..d45bdccf3e8f3e75f75fc2f0eb73ec6abe69017a 100755
--- a/indra/newview/skins/default/xui/fr/floater_about.xml
+++ b/indra/newview/skins/default/xui/fr/floater_about.xml
@@ -8,7 +8,7 @@
 		Compilé avec [COMPILER] version [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Vous êtes à [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Vous êtes à [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] dans [REGION], se trouvant à &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml
index c672511fc5a675edcc2515a8a22f2922677b59db..b0fb585fa252f9a118db2282639e6fa26b5a7afe 100755
--- a/indra/newview/skins/default/xui/it/floater_about.xml
+++ b/indra/newview/skins/default/xui/it/floater_about.xml
@@ -8,7 +8,7 @@
 		Generato con [COMPILER] versione [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Tu sei  [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Tu sei  [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] in [REGION] che si trova a &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml
index 6d5df7564521497710b87166d5e4922f0b123d49..eae52c98ec2375af9c3aecadfb7a9fb1b6a1c37d 100755
--- a/indra/newview/skins/default/xui/ja/floater_about.xml
+++ b/indra/newview/skins/default/xui/ja/floater_about.xml
@@ -8,7 +8,7 @@
 		コンパイラー [COMPILER] [COMPILER_VERSION] バージョン
 	</floater.string>
 	<floater.string name="AboutPosition">
-		あなたの現在地は、[POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] の [REGION] です。位置は &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; です。([HOSTIP])
+		あなたの現在地は、[POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] の [REGION] です。位置は &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; です。([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/pl/floater_about.xml b/indra/newview/skins/default/xui/pl/floater_about.xml
index 409429ffaa64b2f5584ed937ebbce14fac9dc3fb..61a72ff27de35ec7a4870df323b5e882d4afaf6c 100755
--- a/indra/newview/skins/default/xui/pl/floater_about.xml
+++ b/indra/newview/skins/default/xui/pl/floater_about.xml
@@ -8,7 +8,7 @@
 		Buduj z [COMPILER] wersjÄ… [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Położenie [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Położenie [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] w [REGION] zlokalizowanym w &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml
index 299f88b22a14211393417e5d8e0520cae587d399..d08926634208f1442c31cf58c7d69f83f8993413 100755
--- a/indra/newview/skins/default/xui/pt/floater_about.xml
+++ b/indra/newview/skins/default/xui/pt/floater_about.xml
@@ -7,7 +7,7 @@
 		Construído com [COMPILER] versão [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Você está em [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] em [REGION] localizado em [HOSTNAME]&lt;/nolink&gt;([HOSTIP])
+		Você está em [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] em [REGION] localizado em [HOSTNAME]&lt;/nolink&gt;([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml
index bb6266ac9ae4196f593c2cef75cd74262fbd3f83..2b2b3cf453385abf54408b2fb5c3df30fe525ab2 100755
--- a/indra/newview/skins/default/xui/ru/floater_about.xml
+++ b/indra/newview/skins/default/xui/ru/floater_about.xml
@@ -8,7 +8,7 @@
 		Использован компилятор [COMPILER], версия [COMPILER_VERSION]
 	</floater.string>
 	<floater.string name="AboutPosition">
-		Вы в точке [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] в регионе «[REGION]», расположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		Вы в точке [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] в регионе «[REGION]», расположенном на &lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml
index 9cc9c7a2201ae01263d0ecd8a0ac53c07ce30a6e..4dcf6200c6377d7606f117da9062ee0a6449efed 100755
--- a/indra/newview/skins/default/xui/tr/floater_about.xml
+++ b/indra/newview/skins/default/xui/tr/floater_about.xml
@@ -8,7 +8,7 @@
 		[COMPILER] [COMPILER_VERSION] sürümü ile oluşturuldu
 	</floater.string>
 	<floater.string name="AboutPosition">
-		&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1] konumundasınız
+		&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP]) üzerinde bulunan [REGION] içerisinde [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1] konumundasınız
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml
index 643881e416e06e5fa9924085ccb4e01f152fc5e6..1193243c7ecbfeb4776c3099ff0a5ee74e1709f7 100755
--- a/indra/newview/skins/default/xui/zh/floater_about.xml
+++ b/indra/newview/skins/default/xui/zh/floater_about.xml
@@ -8,7 +8,7 @@
 		以 [COMPILER_VERSION] 版本 [COMPILER] 建置
 	</floater.string>
 	<floater.string name="AboutPosition">
-		你的方位是 [POSITION_0,number,1], [POSITION_1,number,1], [POSITION_2,number,1],地區名:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
+		你的方位是 [POSITION_LOCAL_0,number,1], [POSITION_LOCAL_1,number,1], [POSITION_LOCAL_2,number,1],地區名:[REGION],主機:&lt;nolink&gt;[HOSTNAME]&lt;/nolink&gt; ([HOSTIP])
 [SERVER_VERSION]
 [SERVER_RELEASE_NOTES_URL]
 	</floater.string>
diff --git a/indra/newview/tests/llagentaccess_test.cpp b/indra/newview/tests/llagentaccess_test.cpp
index 3ba25f3c10963b160bfd1dc6a824b341d39cc1d2..a40b5c9a3d1836691d7ca0f2adeb1e77ad58158e 100755
--- a/indra/newview/tests/llagentaccess_test.cpp
+++ b/indra/newview/tests/llagentaccess_test.cpp
@@ -49,10 +49,10 @@ LLControlGroup::~LLControlGroup()
 }
 
 // Implementation of just the LLControlGroup methods we requre
-BOOL LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, BOOL persist)
+LLControlVariable* LLControlGroup::declareU32(const std::string& name, U32 initial_val, const std::string& comment, LLControlVariable::ePersist persist)
 {
 	test_preferred_maturity = initial_val;
-	return true;
+	return NULL;
 }
 
 void LLControlGroup::setU32(const std::string& name, U32 val)
@@ -80,7 +80,7 @@ namespace tut
 	void agentaccess_object_t::test<1>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		cgr.setU32("PreferredMaturity", SIM_ACCESS_PG);
@@ -109,7 +109,7 @@ namespace tut
 	void agentaccess_object_t::test<2>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		// make sure default is PG
@@ -157,7 +157,7 @@ namespace tut
 	void agentaccess_object_t::test<3>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 #ifndef HACKED_GODLIKE_VIEWER
@@ -195,7 +195,7 @@ namespace tut
 	void agentaccess_object_t::test<4>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 #ifndef HACKED_GODLIKE_VIEWER
@@ -272,7 +272,7 @@ namespace tut
 	void agentaccess_object_t::test<5>()
 	{
 		LLControlGroup cgr("test");
-		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", FALSE);
+		cgr.declareU32("PreferredMaturity", SIM_ACCESS_PG, "declared_for_test", LLControlVariable::PERSIST_NO);
 		LLAgentAccess aa(cgr);
 		
 		cgr.setU32("PreferredMaturity", SIM_ACCESS_ADULT);
diff --git a/indra/newview/tests/lllogininstance_test.cpp b/indra/newview/tests/lllogininstance_test.cpp
index f038112fd07ccf4ccea9bf7e6d78bea82450c343..adeb848e0338ab089c6d0f2a51933140692d7309 100755
--- a/indra/newview/tests/lllogininstance_test.cpp
+++ b/indra/newview/tests/lllogininstance_test.cpp
@@ -135,6 +135,7 @@ void LLGridManager::addSystemGrid(const std::string& label,
 								  const std::string& login, 
 								  const std::string& helper,
 								  const std::string& login_page,
+								  const std::string& update_url_base,
 								  const std::string& login_id)
 {
 }
@@ -175,8 +176,8 @@ F32 LLControlGroup::getF32(const std::string& name) { return 0.0f; }
 U32 LLControlGroup::saveToFile(const std::string& filename, BOOL nondefault_only) { return 1; }
 void LLControlGroup::setString(const std::string& name, const std::string& val) {}
 std::string LLControlGroup::getString(const std::string& name) { return "test_string"; }
-BOOL LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, BOOL persist) { return TRUE; }
-BOOL LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, BOOL persist) { return TRUE; }
+LLControlVariable* LLControlGroup::declareBOOL(const std::string& name, BOOL initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
+LLControlVariable* LLControlGroup::declareString(const std::string& name, const std::string &initial_val, const std::string& comment, LLControlVariable::ePersist persist) { return NULL; }
 
 #include "lluicolortable.h"
 void LLUIColorTable::saveUserSettings(void)const {}
@@ -208,9 +209,7 @@ std::string const & LLUpdaterService::pumpName(void)
 	return wakka;
 }
 bool LLUpdaterService::updateReadyToInstall(void) { return false; }
-void LLUpdaterService::initialize(const std::string& url, 
-								  const std::string& path,
-								  const std::string& channel,
+void LLUpdaterService::initialize(const std::string& channel,
 								  const std::string& version,
 								  const std::string& platform,
 								  const std::string& platform_version,
@@ -344,13 +343,13 @@ namespace tut
 			gTOSReplyPump = 0; // clear the callback.
 
 
-			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", FALSE);
-			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", FALSE);
-			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", FALSE);
-			gSavedSettings.declareString("NextLoginLocation", "", "", FALSE);
-			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", FALSE);
+			gSavedSettings.declareBOOL("NoInventoryLibrary", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("ConnectAsGod", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("UseDebugMenus", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("ForceMandatoryUpdate", FALSE, "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareString("ClientSettingsFile", "test_settings.xml", "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareString("NextLoginLocation", "", "", LLControlVariable::PERSIST_NO);
+			gSavedSettings.declareBOOL("LoginLastLocation", FALSE, "", LLControlVariable::PERSIST_NO);
 
 			LLSD authenticator = LLSD::emptyMap();
 			LLSD identifier = LLSD::emptyMap();
diff --git a/indra/newview/tests/llsecapi_test.cpp b/indra/newview/tests/llsecapi_test.cpp
index 703603e2dbff8911f91ad9bebff4ada5728149ee..d7e87ed52ea5dc0c1a8d9c9853a358774c1fd180 100755
--- a/indra/newview/tests/llsecapi_test.cpp
+++ b/indra/newview/tests/llsecapi_test.cpp
@@ -39,10 +39,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llsechandler_basic_test.cpp b/indra/newview/tests/llsechandler_basic_test.cpp
index 02354009760348c40dd7bc1b294d250a9ed0a449..2a8dc153466a7ee12efe56f815d7f027c9774855 100755
--- a/indra/newview/tests/llsechandler_basic_test.cpp
+++ b/indra/newview/tests/llsechandler_basic_test.cpp
@@ -71,10 +71,10 @@ std::string gLastName;
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llslurl_test.cpp b/indra/newview/tests/llslurl_test.cpp
index 09343ef227b209efdc0ecc8ce7522dddc7dcd5f4..86229ad636b1b7ced88daed66d231177e6a23257 100755
--- a/indra/newview/tests/llslurl_test.cpp
+++ b/indra/newview/tests/llslurl_test.cpp
@@ -37,10 +37,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 
 std::string gCmdLineLoginURI;
diff --git a/indra/newview/tests/llviewerhelputil_test.cpp b/indra/newview/tests/llviewerhelputil_test.cpp
index 710881d81124587d8dcb5512a030732880b87c8b..f6456a28392b5af902743800117c0c60203f4127 100755
--- a/indra/newview/tests/llviewerhelputil_test.cpp
+++ b/indra/newview/tests/llviewerhelputil_test.cpp
@@ -49,10 +49,10 @@ static std::string gOS;
 LLControlGroup::LLControlGroup(const std::string& name)
 	: LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
 				   const std::string& initial_val,
 				   const std::string& comment,
-				   BOOL persist) {return TRUE;}
+				   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 std::string LLControlGroup::getString(const std::string& name)
 {
diff --git a/indra/newview/tests/llviewernetwork_test.cpp b/indra/newview/tests/llviewernetwork_test.cpp
index a1e97ea17eac6641eb0788d97b0fa1a1aac1e595..7ad7947ca43ec3c0d0ef847759fd6d2311719fbb 100755
--- a/indra/newview/tests/llviewernetwork_test.cpp
+++ b/indra/newview/tests/llviewernetwork_test.cpp
@@ -37,10 +37,10 @@
 LLControlGroup::LLControlGroup(const std::string& name)
 : LLInstanceTracker<LLControlGroup, std::string>(name) {}
 LLControlGroup::~LLControlGroup() {}
-BOOL LLControlGroup::declareString(const std::string& name,
+LLControlVariable* LLControlGroup::declareString(const std::string& name,
                                    const std::string& initial_val,
                                    const std::string& comment,
-                                   BOOL persist) {return TRUE;}
+                                   LLControlVariable::ePersist persist) {return NULL;}
 void LLControlGroup::setString(const std::string& name, const std::string& val){}
 
 std::string gCmdLineLoginURI;
@@ -127,6 +127,7 @@ const char *gSampleGridFile =
 	"      <array>"
 	"        <string>myloginuri</string>"
 	"      </array>"
+	"      <key>update_query_url_base</key><string>https://update.secondlife.com/update</string>"
 	"      <key>keyname</key><string>util.foobar.lindenlab.com</string>"
 	"    </map>"
 	"  </map>"
@@ -185,6 +186,9 @@ namespace tut
 		ensure_equals("id for agni",
 					  std::string("Agni"),
 					  LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure_equals("label for agni",
 					  LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
 					  std::string("Second Life Main Grid (Agni)"));
@@ -256,6 +260,9 @@ namespace tut
 		ensure_equals("id for agni",
 					  LLGridManager::getInstance()->getGridId("util.agni.lindenlab.com"),
 					  std::string("Agni"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure_equals("label for agni",
 					  LLGridManager::getInstance()->getGridLabel("util.agni.lindenlab.com"),
 					  std::string("Second Life Main Grid (Agni)"));
@@ -384,6 +391,9 @@ namespace tut
 		ensure_equals("getLoginPage",
 					  LLGridManager::getInstance()->getLoginPage(),
 					  std::string("http://viewer-login.agni.lindenlab.com/"));
+		ensure_equals("update url base for Agni", // relies on agni being the default
+					  std::string("https://update.secondlife.com/update"),
+					  LLGridManager::getInstance()->getUpdateServiceURL());
 		ensure("Is Agni a production grid", LLGridManager::getInstance()->isInProductionGrid());
 		std::vector<std::string> uris;
 		LLGridManager::getInstance()->getLoginURIs(uris);
diff --git a/indra/newview/tests/llxmlrpclistener_test.cpp b/indra/newview/tests/llxmlrpclistener_test.cpp
index 711c2a3d51a908ba9a18316556c49f643d1c1960..20f913b67083be6aeef3635428f8dbb9b2a35d90 100755
--- a/indra/newview/tests/llxmlrpclistener_test.cpp
+++ b/indra/newview/tests/llxmlrpclistener_test.cpp
@@ -62,8 +62,8 @@ namespace tut
             // These variables are required by machinery used by
             // LLXMLRPCTransaction. The values reflect reality for this test
             // executable; hopefully these values are correct.
-            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", FALSE); // don't persist
-            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", FALSE); // don't persist
+            gSavedSettings.declareBOOL("BrowserProxyEnabled", FALSE, "", LLControlVariable::PERSIST_NO); // don't persist
+            gSavedSettings.declareBOOL("NoVerifySSLCert", TRUE, "", LLControlVariable::PERSIST_NO); // don't persist
         }
 
         // LLEventPump listener signature
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 5e08e54b7c6de60882f99a135e607a8957065278..19863dd84548f7eb077899f97dfb55a2fdcaeb7a 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -34,9 +34,15 @@
 import time
 import random
 viewer_dir = os.path.dirname(__file__)
-# add llmanifest library to our path so we don't have to muck with PYTHONPATH
-sys.path.append(os.path.join(viewer_dir, '../lib/python/indra/util'))
-from llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+# Add indra/lib/python to our path so we don't have to muck with PYTHONPATH.
+# Put it FIRST because some of our build hosts have an ancient install of
+# indra.util.llmanifest under their system Python!
+sys.path.insert(0, os.path.join(viewer_dir, os.pardir, "lib", "python"))
+from indra.util.llmanifest import LLManifest, main, proper_windows_path, path_ancestors
+try:
+    from llbase import llsd
+except ImportError:
+    from indra.base import llsd
 
 class ViewerManifest(LLManifest):
     def is_packaging_viewer(self):
@@ -65,13 +71,13 @@ def construct(self):
                 # include the entire shaders directory recursively
                 self.path("shaders")
                 # include the extracted list of contributors
-                contributor_names = self.extract_names("../../doc/contributions.txt")
-                self.put_in_file(contributor_names, "contributors.txt")
-                self.file_list.append(["../../doc/contributions.txt",self.dst_path_of("contributors.txt")])
+                contributions_path = "../../doc/contributions.txt"
+                contributor_names = self.extract_names(contributions_path)
+                self.put_in_file(contributor_names, "contributors.txt", src=contributions_path)
                 # include the extracted list of translators
-                translator_names = self.extract_names("../../doc/translations.txt")
-                self.put_in_file(translator_names, "translators.txt")
-                self.file_list.append(["../../doc/translations.txt",self.dst_path_of("translators.txt")])
+                translations_path = "../../doc/translations.txt"
+                translator_names = self.extract_names(translations_path)
+                self.put_in_file(translator_names, "translators.txt", src=translations_path)
                 # include the list of Lindens (if any)
                 #   see https://wiki.lindenlab.com/wiki/Generated_Linden_Credits
                 linden_names_path = os.getenv("LINDEN_CREDITS")
@@ -85,10 +91,9 @@ def construct(self):
                     else:
                          # all names should be one line, but the join below also converts to a string
                         linden_names = ', '.join(linden_file.readlines())
-                        self.put_in_file(linden_names, "lindens.txt")
+                        self.put_in_file(linden_names, "lindens.txt", src=linden_names_path)
                         linden_file.close()
                         print "Linden names extracted from '%s'" % linden_names_path
-                        self.file_list.append([linden_names_path,self.dst_path_of("lindens.txt")])
 
                 # ... and the entire windlight directory
                 self.path("windlight")
@@ -99,6 +104,27 @@ def construct(self):
                     self.path("dictionaries")
                     self.end_prefix(pkgdir)
 
+                # CHOP-955: If we have "sourceid" in the build process
+                # environment, generate it into settings_install.xml.
+                try:
+                    sourceid = os.environ["sourceid"]
+                except KeyError:
+                    # no sourceid, no settings_install.xml file
+                    pass
+                else:
+                    if sourceid:
+                        # Single-entry subset of the LLSD content of settings.xml
+                        content = dict(sourceid=dict(Comment='Identify referring agency to Linden web servers',
+                                                     Persist=1,
+                                                     Type='String',
+                                                     Value=sourceid))
+                        # put_in_file(src=) need not be an actual pathname; it
+                        # only needs to be non-empty
+                        settings_install = self.put_in_file(llsd.format_pretty_xml(content),
+                                                            "settings_install.xml",
+                                                            src="environment")
+                        print "Put sourceid '%s' in %s" % (sourceid, settings_install)
+
                 self.end_prefix("app_settings")
 
             if self.prefix(src="character"):
@@ -196,24 +222,26 @@ def flags_list(self):
         """ Convenience function that returns the command-line flags
         for the grid"""
 
-        # Set command line flags relating to the target grid
-        grid_flags = ''
-        if not self.default_grid():
-            grid_flags = "--grid %(grid)s "\
-                         "--helperuri http://preview-%(grid)s.secondlife.com/helpers/" %\
-                           {'grid':self.grid()}
-
-        # Deal with settings 
-        setting_flags = ''
-        if not self.default_channel() or not self.default_grid():
-            if self.default_grid():
-                setting_flags = '--settings settings_%s.xml'\
-                                % self.channel_lowerword()
-            else:
-                setting_flags = '--settings settings_%s_%s.xml'\
-                                % (self.grid(), self.channel_lowerword())
-                                                
-        return " ".join((grid_flags, setting_flags)).strip()
+        # The original role of this method seems to have been to build a
+        # grid-specific viewer: one that would, on launch, preselect a
+        # particular grid. (Apparently that dates back to when the protocol
+        # between viewer and simulator required them to be updated in
+        # lockstep, so that "the beta grid" required "a beta viewer.") But
+        # those viewer command-line switches no longer work without tweaking
+        # user_settings/grids.xml. In fact, going forward, it's unclear what
+        # use case that would address.
+
+        # This method also set a channel-specific (or grid-and-channel-
+        # specific) user_settings/settings_something.xml file. It has become
+        # clear that saving user settings in a channel-specific file causes
+        # more problems (confusion) than it solves, so we've discontinued that.
+
+        # In fact we now avoid forcing viewer command-line switches at all,
+        # instead introducing a settings_install.xml file. Command-line
+        # switches don't aggregate well; for instance the generated --channel
+        # switch actually prevented the user specifying --channel on the
+        # command line. Settings files have well-defined override semantics.
+        return None
 
     def extract_names(self,src):
         try:
@@ -530,8 +558,7 @@ def package_finish(self):
             'final_exe' : self.final_exe(),
             'grid':self.args['grid'],
             'grid_caps':self.args['grid'].upper(),
-            # escape quotes becase NSIS doesn't handle them well
-            'flags':self.flags_list().replace('"', '$\\"'),
+            'flags':'',
             'channel':self.channel(),
             'channel_oneword':self.channel_oneword(),
             'channel_unique':self.channel_unique(),
@@ -759,9 +786,6 @@ def path_optional(src, dst):
 
                     self.end_prefix("llplugin")
 
-                # command line arguments for connecting to the proper grid
-                self.put_in_file(self.flags_list(), 'arguments.txt')
-
                 self.end_prefix("Resources")
 
             self.end_prefix("Contents")
@@ -807,10 +831,6 @@ def package_finish(self):
                                  'bundle': self.get_dst_prefix()
                 })
 
-        channel_standin = 'Second Life Viewer'  # hah, our default channel is not usable on its own
-        if not self.default_channel():
-            channel_standin = self.channel()
-
         imagename="SecondLife_" + '_'.join(self.args['version'])
 
         # MBW -- If the mounted volume name changes, it breaks the .DS_Store's background image and icon positioning.
@@ -928,9 +948,6 @@ def construct(self):
             self.path("install.sh")
             self.end_prefix("linux_tools")
 
-        # Create an appropriate gridargs.dat for this package, denoting required grid.
-        self.put_in_file(self.flags_list(), 'etc/gridargs.dat')
-
         if self.prefix(src="", dst="bin"):
             self.path("secondlife-bin","do-not-directly-run-secondlife-bin")
             self.path("../linux_crash_logger/linux-crash-logger","linux-crash-logger.bin")
diff --git a/indra/viewer_components/updater/llupdatechecker.cpp b/indra/viewer_components/updater/llupdatechecker.cpp
index 1e768f52d9d5ebac40a3e5eadbbbaf3f1e49029b..91a5f9246eb86f0420a4f44b2b1736f62535d07f 100755
--- a/indra/viewer_components/updater/llupdatechecker.cpp
+++ b/indra/viewer_components/updater/llupdatechecker.cpp
@@ -62,8 +62,7 @@ LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client):
 }
 
 
-void LLUpdateChecker::checkVersion(std::string const & hostUrl, 
-								   std::string const & servicePath,
+void LLUpdateChecker::checkVersion(std::string const & urlBase, 
 								   std::string const & channel,
 								   std::string const & version,
 								   std::string const & platform,
@@ -71,7 +70,7 @@ void LLUpdateChecker::checkVersion(std::string const & hostUrl,
 								   unsigned char       uniqueid[MD5HEX_STR_SIZE],
 								   bool                willing_to_test)
 {
-	mImplementation->checkVersion(hostUrl, servicePath, channel, version, platform, platform_version, uniqueid, willing_to_test);
+	mImplementation->checkVersion(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
 }
 
 
@@ -99,8 +98,7 @@ LLUpdateChecker::Implementation::~Implementation()
 }
 
 
-void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl, 
-												   std::string const & servicePath,
+void LLUpdateChecker::Implementation::checkVersion(std::string const & urlBase, 
 												   std::string const & channel,
 												   std::string const & version,
 												   std::string const & platform,
@@ -112,8 +110,7 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl,
 	{
 		mInProgress = true;
 
-		mHostUrl     	 = hostUrl;
-		mServicePath 	 = servicePath;
+		mUrlBase     	 = urlBase;
 		mChannel     	 = channel;
 		mVersion     	 = version;
 		mPlatform        = platform;
@@ -123,7 +120,7 @@ void LLUpdateChecker::Implementation::checkVersion(std::string const & hostUrl,
 	
 		mProtocol = sProtocolVersion;
 
-		std::string checkUrl = buildUrl(hostUrl, servicePath, channel, version, platform, platform_version, uniqueid, willing_to_test);
+		std::string checkUrl = buildUrl(urlBase, channel, version, platform, platform_version, uniqueid, willing_to_test);
 		LL_INFOS("UpdaterService") << "checking for updates at " << checkUrl << LL_ENDL;
 	
 		mHttpClient.get(checkUrl, this);
@@ -158,7 +155,7 @@ void LLUpdateChecker::Implementation::completed(U32 status,
 			if (mProtocol == sProtocolVersion)
 			{
 				mProtocol = sLegacyProtocolVersion;
-				std::string retryUrl = buildUrl(mHostUrl, mServicePath, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
+				std::string retryUrl = buildUrl(mUrlBase, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
 
 				LL_WARNS("UpdaterService")
 					<< "update response using " << sProtocolVersion
@@ -203,8 +200,7 @@ void LLUpdateChecker::Implementation::error(U32 status, const std::string & reas
 }
 
 
-std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUrl, 
-													  std::string const & servicePath,
+std::string LLUpdateChecker::Implementation::buildUrl(std::string const & urlBase, 
 													  std::string const & channel,
 													  std::string const & version,
 													  std::string const & platform,
@@ -213,7 +209,6 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr
 													  bool                willing_to_test)
 {	
 	LLSD path;
-	path.append(servicePath);
 	path.append(mProtocol);
 	path.append(channel);
 	path.append(version);
@@ -224,5 +219,5 @@ std::string LLUpdateChecker::Implementation::buildUrl(std::string const & hostUr
 		path.append(willing_to_test ? "testok" : "testno");
 		path.append((char*)uniqueid);
 	}
-	return LLURI::buildHTTP(hostUrl, path).asString();
+	return LLURI::buildHTTP(urlBase, path).asString();
 }
diff --git a/indra/viewer_components/updater/llupdatechecker.h b/indra/viewer_components/updater/llupdatechecker.h
index 8e8558749030b5368b143612b00e431a345bfa6f..4244007340103b2274fa027377bdfa9bd821031b 100755
--- a/indra/viewer_components/updater/llupdatechecker.h
+++ b/indra/viewer_components/updater/llupdatechecker.h
@@ -43,8 +43,7 @@ class LLUpdateChecker {
 	public:
 		Implementation(Client & client);
 		~Implementation();
-		void checkVersion(std::string const & hostUrl, 
-						  std::string const & servicePath,
+		void checkVersion(std::string const & urlBase, 
 						  std::string const & channel,
 						  std::string const & version,
 						  std::string const & platform,
@@ -68,16 +67,14 @@ class LLUpdateChecker {
 		LLHTTPClient mHttpClient;
 		bool         mInProgress;
 		std::string   mVersion;
-		std::string   mHostUrl;
-		std::string   mServicePath;
+		std::string   mUrlBase;
 		std::string   mChannel;
 		std::string   mPlatform;
 		std::string   mPlatformVersion;
 		unsigned char mUniqueId[MD5HEX_STR_SIZE];
 		bool          mWillingToTest;
 		
-		std::string buildUrl(std::string const & hostUrl, 
-							 std::string const & servicePath,
+		std::string buildUrl(std::string const & urlBase, 
 							 std::string const & channel,
 							 std::string const & version,
 							 std::string const & platform,
@@ -95,8 +92,7 @@ class LLUpdateChecker {
 	LLUpdateChecker(Client & client);
 	
 	// Check status of current app on the given host for the channel and version provided.
-	void checkVersion(std::string const & hostUrl, 
-					  std::string const & servicePath,
+	void checkVersion(std::string const & urlBase, 
 					  std::string const & channel,
 					  std::string const & version,
 					  std::string const & platform,
diff --git a/indra/viewer_components/updater/llupdaterservice.cpp b/indra/viewer_components/updater/llupdaterservice.cpp
index 1bd9fa4fc0f30c533b912a243b6ac58f66bb1858..16950e1d62ea821010119022e227c2b7ecba3654 100755
--- a/indra/viewer_components/updater/llupdaterservice.cpp
+++ b/indra/viewer_components/updater/llupdaterservice.cpp
@@ -38,6 +38,7 @@
 #include "lldir.h"
 #include "llsdserialize.h"
 #include "llfile.h"
+#include "llviewernetwork.h"
 
 #if LL_WINDOWS
 #pragma warning (disable : 4355) // 'this' used in initializer list: yes, intentionally
@@ -93,8 +94,6 @@ class LLUpdaterServiceImpl :
 	static const std::string sListenerName;
 	
 	std::string   mProtocolVersion;
-	std::string   mUrl;
-	std::string   mPath;
 	std::string   mChannel;
 	std::string   mVersion;
 	std::string   mPlatform;
@@ -120,9 +119,7 @@ class LLUpdaterServiceImpl :
 	LLUpdaterServiceImpl();
 	virtual ~LLUpdaterServiceImpl();
 
-	void initialize(const std::string& 	url, 
-					const std::string& 	path,
-					const std::string& 	channel,
+	void initialize(const std::string& 	channel,
 					const std::string& 	version,
 					const std::string&  platform,
 					const std::string&  platform_version,
@@ -183,9 +180,7 @@ LLUpdaterServiceImpl::~LLUpdaterServiceImpl()
 	LLEventPumps::instance().obtain("mainloop").stopListening(sListenerName);
 }
 
-void LLUpdaterServiceImpl::initialize(const std::string&  url, 
-									  const std::string&  path,
-									  const std::string&  channel,
+void LLUpdaterServiceImpl::initialize(const std::string&  channel,
 									  const std::string&  version,
 									  const std::string&  platform,
 									  const std::string&  platform_version,
@@ -198,8 +193,6 @@ void LLUpdaterServiceImpl::initialize(const std::string&  url,
 										   "while updater is running.");
 	}
 		
-	mUrl = url;
-	mPath = path;
 	mChannel = channel;
 	mVersion = version;
 	mPlatform = platform;
@@ -207,8 +200,6 @@ void LLUpdaterServiceImpl::initialize(const std::string&  url,
 	memcpy(mUniqueId, uniqueid, MD5HEX_STR_SIZE);
 	mWillingToTest = willing_to_test;
 	LL_DEBUGS("UpdaterService")
-		<< "\n  url: " << mUrl
-		<< "\n  path: " << mPath
 		<< "\n  channel: " << mChannel
 		<< "\n  version: " << mVersion
 		<< "\n  uniqueid: " << mUniqueId
@@ -228,7 +219,7 @@ void LLUpdaterServiceImpl::setBandwidthLimit(U64 bytesPerSecond)
 
 void LLUpdaterServiceImpl::startChecking(bool install_if_ready)
 {
-	if(mUrl.empty() || mChannel.empty() || mVersion.empty())
+	if(mChannel.empty() || mVersion.empty())
 	{
 		throw LLUpdaterService::UsageError("Set params before call to "
 			"LLUpdaterService::startCheck().");
@@ -415,7 +406,7 @@ void LLUpdaterServiceImpl::response(LLSD const & content)
 	
 		setState(LLUpdaterService::UP_TO_DATE);
 	}
-	else
+	else if ( content.isMap() && content.has("url") )
 	{
 		// there is an update available...
 		stopTimer();
@@ -439,6 +430,12 @@ void LLUpdaterServiceImpl::response(LLSD const & content)
 			<< LL_ENDL;
 		mUpdateDownloader.download(url, content["hash"].asString(), mNewChannel, mNewVersion, more_info, required);
 	}
+	else
+	{
+		LL_WARNS("UpdaterService") << "Invalid update query response ignored; retry in "
+								   << mCheckPeriod << " seconds" << LL_ENDL;
+		restartTimer(mCheckPeriod);
+	}
 }
 
 void LLUpdaterServiceImpl::downloadComplete(LLSD const & data) 
@@ -565,8 +562,26 @@ bool LLUpdaterServiceImpl::onMainLoop(LLSD const & event)
 		}
 		else
 		{
-			mUpdateChecker.checkVersion(mUrl, mPath, mChannel, mVersion, mPlatform, mPlatformVersion, mUniqueId, mWillingToTest);
-			setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+			std::string query_url = LLGridManager::getInstance()->getUpdateServiceURL();
+			if ( !query_url.empty() )
+			{
+				mUpdateChecker.checkVersion(query_url, mChannel, mVersion,
+											mPlatform, mPlatformVersion, mUniqueId,
+											mWillingToTest);
+				setState(LLUpdaterService::CHECKING_FOR_UPDATE);
+			}
+			else
+			{
+				LL_WARNS("UpdaterService")
+					<< "No updater service defined for grid '" << LLGridManager::getInstance()->getGrid()
+					<< "' will check again in " << mCheckPeriod << " seconds"
+					<< LL_ENDL;
+				// Because the grid can be changed after the viewer is started (when the first check takes place)
+				// but before the user logs in, the next check may be on a different grid, so set the retry timer
+				// even though this check did not happen.  The default time is once an hour, and if we're not
+				// doing the check anyway the performance impact is completely insignificant.
+				restartTimer(mCheckPeriod);
+			}
 		}
 	} 
 	else 
@@ -610,9 +625,7 @@ LLUpdaterService::~LLUpdaterService()
 {
 }
 
-void LLUpdaterService::initialize(const std::string& url, 
-								  const std::string& path,
-								  const std::string& channel,
+void LLUpdaterService::initialize(const std::string& channel,
 								  const std::string& version,
 								  const std::string& platform,
 								  const std::string& platform_version,
@@ -620,7 +633,7 @@ void LLUpdaterService::initialize(const std::string& url,
 								  const bool&         willing_to_test
 )
 {
-	mImpl->initialize(url, path, channel, version, platform, platform_version, uniqueid, willing_to_test);
+	mImpl->initialize(channel, version, platform, platform_version, uniqueid, willing_to_test);
 }
 
 void LLUpdaterService::setCheckPeriod(unsigned int seconds)
diff --git a/indra/viewer_components/updater/llupdaterservice.h b/indra/viewer_components/updater/llupdaterservice.h
index 982f99b86135032c26842c93373356331e516ce3..0ddf24935b173bc77c5cb4abf5d6e3607e389dda 100755
--- a/indra/viewer_components/updater/llupdaterservice.h
+++ b/indra/viewer_components/updater/llupdaterservice.h
@@ -71,9 +71,7 @@ class LLUpdaterService
 	LLUpdaterService();
 	~LLUpdaterService();
 
-	void initialize(const std::string& 	url, 
-				    const std::string& 	path,
-				    const std::string& 	channel,
+	void initialize(const std::string& 	channel,
 				    const std::string& 	version,
 					const std::string&  platform,
 					const std::string&  platform_version,
diff --git a/indra/viewer_components/updater/scripts/linux/update_install b/indra/viewer_components/updater/scripts/linux/update_install
index a9df9042fda2a029d55cbef46f707926b06cafc9..03089f192e899b2d82c33d43ea02fdb7c495a9c0 100755
--- a/indra/viewer_components/updater/scripts/linux/update_install
+++ b/indra/viewer_components/updater/scripts/linux/update_install
@@ -69,8 +69,11 @@ then # zenity on PATH and is executable
          # clear any previous message
          clear_message
          # put up a new zenity box and capture its pid
-         "$zenpath" --info --title "Second Life Viewer Updater" \
-                    --width=320 --height=120 --text="$*" &
+##       "$zenpath" --info --title "Second Life Viewer Updater" \
+##                  --width=320 --height=120 --text="$*" &
+         # MAINT-2333: use bouncing progress bar
+         "$zenpath" --progress --pulsate --no-cancel --title "Second Life Viewer Updater" \
+                    --width=320 --height=120 --text "$*" </dev/null &
          statuspid=$!
      }
 
diff --git a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
index 4812272ebc12c919f97a692ef1edf5825d40e0f1..759e41ef4c1823c3f837a750424627eb12941aab 100755
--- a/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
+++ b/indra/viewer_components/updater/tests/llupdaterservice_test.cpp
@@ -44,8 +44,7 @@
 *****************************************************************************/
 LLUpdateChecker::LLUpdateChecker(LLUpdateChecker::Client & client)
 {}
-void LLUpdateChecker::checkVersion(std::string const & hostUrl, 
-								   std::string const & servicePath,
+void LLUpdateChecker::checkVersion(std::string const & urlBase, 
 								   std::string const & channel,
 								   std::string const & version,
 								   std::string const & platform,
@@ -91,6 +90,21 @@ bool LLDir::setCacheDir(const std::string &path){ return true; }
 void LLDir::dumpCurrentDirectories() {}
 void LLDir::updatePerAccountChatLogsDir() {}
 
+#include "llviewernetwork.h"
+LLGridManager::LLGridManager() :
+	mGrid("test.grid.lindenlab.com"),
+	mIsInProductionGrid(false)
+{
+}
+std::string LLGridManager::getUpdateServiceURL()
+{
+	return "https://update.secondlife.com/update";
+}
+LLGridManager::~LLGridManager()
+{
+}
+
+
 std::string LLDir::getExpandedFilename(ELLPath location, 
 									   const std::string &filename) const 
 {
@@ -179,10 +193,10 @@ namespace tut
 		try
 		{
 			unsigned char id1[MD5HEX_STR_SIZE] = "11111111111111111111111111111111";
-			updater.initialize(test_url, "update" ,test_channel, test_version, "win", "1.2.3", id1, true);
+			updater.initialize(test_channel, test_version, "win", "1.2.3", id1, true);
 			updater.startChecking();
 			unsigned char id2[MD5HEX_STR_SIZE] = "22222222222222222222222222222222";
-			updater.initialize("other_url", "update", test_channel, test_version, "win", "4.5.6", id2, true);
+			updater.initialize(test_channel, test_version, "win", "4.5.6", id2, true);
 		}
 		catch(LLUpdaterService::UsageError)
 		{
@@ -197,7 +211,7 @@ namespace tut
         DEBUG;
 		LLUpdaterService updater;
 		unsigned char id[MD5HEX_STR_SIZE] = "33333333333333333333333333333333";
-		updater.initialize(test_url, "update", test_channel, test_version, "win", "7.8.9", id, true);
+		updater.initialize(test_channel, test_version, "win", "7.8.9", id, true);
 		updater.startChecking();
 		ensure(updater.isChecking());
 		updater.stopChecking();