diff --git a/doc/contributions.txt b/doc/contributions.txt
index 842dc3ac9e8a8ada13132f0ecce7b7175a4e565f..ad0018bd7baa0e2fbdcb0291f3b700aa365245ec 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -13,7 +13,7 @@ Able Whitman
 Adam Marker
 	VWR-2755
 Aimee Trescothick
-        VWR-3336
+	VWR-3336
 	VWR-3903
 	VWR-4083
 	VWR-6348
@@ -26,6 +26,7 @@ Aimee Trescothick
 	VWR-8341
 	VWR-8482
 	VWR-9255
+	VWR-1813
 Alejandro Rosenthal
 	VWR-1184
 Alissa Sabre
@@ -99,6 +100,7 @@ Carjay McGinnis
 	VWR-6154
 Catherine Pfeffer
 	VWR-1282
+	VWR-8624
 Dale Glass
 	VWR-120
 	VWR-560
@@ -225,8 +227,11 @@ Matthew Dowd
 	VWR-1761
 McCabe Maxsted
 	VWR-1318
+	VWR-4065
+	VWR-7827
 	VWR-7877
 	VWR-7893
+	VWR-8080
 	VWR-8689
 Michelle2 Zenovka
 	VWR-2652
@@ -237,6 +242,7 @@ Michelle2 Zenovka
 	VWR-4331
 	VWR-4506
 	VWR-4981
+	VWR-5082
 	VWR-5659
 	VWR-7831
 	VWR-8889
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 4001e1f0c565c6fa10153ab2b50ddc4006334774..3f14be6e185344c5fd68c2857db797015b469ee3 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -20,6 +20,7 @@ set(llcommon_SOURCE_FILES
     llcommon.cpp
     llcrc.cpp
     llcriticaldamp.cpp
+    llcursortypes.cpp
     lldate.cpp
     llerror.cpp
     llerrorthread.cpp
@@ -90,6 +91,7 @@ set(llcommon_HEADER_FILES
     llcommon.h
     llcrc.h
     llcriticaldamp.h
+    llcursortypes.h
     lldarray.h
     lldarrayptr.h
     lldate.h
diff --git a/indra/llcommon/llchat.h b/indra/llcommon/llchat.h
index b6f84b25b57a263c31e553b65b06e3b10e2d5b0f..29f6b27e22cb23e9eb1c4d4e463450c578582f55 100644
--- a/indra/llcommon/llchat.h
+++ b/indra/llcommon/llchat.h
@@ -77,7 +77,8 @@ class LLChat
 		mAudible(CHAT_AUDIBLE_FULLY),
 		mMuted(FALSE),
 		mTime(0.0),
-		mPosAgent()
+		mPosAgent(),
+		mURL()
 	{ }
 	
 	std::string		mText;		// UTF-8 line of text
@@ -89,6 +90,7 @@ class LLChat
 	BOOL			mMuted;		// pass muted chat to maintain list of chatters
 	F64				mTime;		// viewer only, seconds from viewer start
 	LLVector3		mPosAgent;
+	std::string		mURL;
 };
 
 #endif
diff --git a/indra/llcommon/llcursortypes.cpp b/indra/llcommon/llcursortypes.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9f1a899dae0b915c2ef072ebe5c2d5fa14daf046
--- /dev/null
+++ b/indra/llcommon/llcursortypes.cpp
@@ -0,0 +1,89 @@
+/** 
+ * @file llcursortypes.cpp
+ * @brief Cursor types and lookup of types from a string
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llcursortypes.h"
+
+ECursorType getCursorFromString(const std::string& cursor_string)
+{
+	static std::map<std::string,U32> cursor_string_table;
+	if (cursor_string_table.empty())
+	{
+		cursor_string_table["UI_CURSOR_ARROW"] = UI_CURSOR_ARROW;
+		cursor_string_table["UI_CURSOR_WAIT"] = UI_CURSOR_WAIT;
+		cursor_string_table["UI_CURSOR_HAND"] = UI_CURSOR_HAND;
+		cursor_string_table["UI_CURSOR_IBEAM"] = UI_CURSOR_IBEAM;
+		cursor_string_table["UI_CURSOR_CROSS"] = UI_CURSOR_CROSS;
+		cursor_string_table["UI_CURSOR_SIZENWSE"] = UI_CURSOR_SIZENWSE;
+		cursor_string_table["UI_CURSOR_SIZENESW"] = UI_CURSOR_SIZENESW;
+		cursor_string_table["UI_CURSOR_SIZEWE"] = UI_CURSOR_SIZEWE;
+		cursor_string_table["UI_CURSOR_SIZENS"] = UI_CURSOR_SIZENS;
+		cursor_string_table["UI_CURSOR_NO"] = UI_CURSOR_NO;
+		cursor_string_table["UI_CURSOR_WORKING"] = UI_CURSOR_WORKING;
+		cursor_string_table["UI_CURSOR_TOOLGRAB"] = UI_CURSOR_TOOLGRAB;
+		cursor_string_table["UI_CURSOR_TOOLLAND"] = UI_CURSOR_TOOLLAND;
+		cursor_string_table["UI_CURSOR_TOOLFOCUS"] = UI_CURSOR_TOOLFOCUS;
+		cursor_string_table["UI_CURSOR_TOOLCREATE"] = UI_CURSOR_TOOLCREATE;
+		cursor_string_table["UI_CURSOR_ARROWDRAG"] = UI_CURSOR_ARROWDRAG;
+		cursor_string_table["UI_CURSOR_ARROWCOPY"] = UI_CURSOR_ARROWCOPY;
+		cursor_string_table["UI_CURSOR_ARROWDRAGMULTI"] = UI_CURSOR_ARROWDRAGMULTI;
+		cursor_string_table["UI_CURSOR_ARROWCOPYMULTI"] = UI_CURSOR_ARROWCOPYMULTI;
+		cursor_string_table["UI_CURSOR_NOLOCKED"] = UI_CURSOR_NOLOCKED;
+		cursor_string_table["UI_CURSOR_ARROWLOCKED"] = UI_CURSOR_ARROWLOCKED;
+		cursor_string_table["UI_CURSOR_GRABLOCKED"] = UI_CURSOR_GRABLOCKED;
+		cursor_string_table["UI_CURSOR_TOOLTRANSLATE"] = UI_CURSOR_TOOLTRANSLATE;
+		cursor_string_table["UI_CURSOR_TOOLROTATE"] = UI_CURSOR_TOOLROTATE;
+		cursor_string_table["UI_CURSOR_TOOLSCALE"] = UI_CURSOR_TOOLSCALE;
+		cursor_string_table["UI_CURSOR_TOOLCAMERA"] = UI_CURSOR_TOOLCAMERA;
+		cursor_string_table["UI_CURSOR_TOOLPAN"] = UI_CURSOR_TOOLPAN;
+		cursor_string_table["UI_CURSOR_TOOLZOOMIN"] = UI_CURSOR_TOOLZOOMIN;
+		cursor_string_table["UI_CURSOR_TOOLPICKOBJECT3"] = UI_CURSOR_TOOLPICKOBJECT3;
+		cursor_string_table["UI_CURSOR_TOOLSIT"] = UI_CURSOR_TOOLSIT;
+		cursor_string_table["UI_CURSOR_TOOLBUY"] = UI_CURSOR_TOOLBUY;
+		cursor_string_table["UI_CURSOR_TOOLPAY"] = UI_CURSOR_TOOLPAY;
+		cursor_string_table["UI_CURSOR_TOOLOPEN"] = UI_CURSOR_TOOLOPEN;
+		cursor_string_table["UI_CURSOR_TOOLPLAY"] = UI_CURSOR_TOOLPLAY;
+		cursor_string_table["UI_CURSOR_TOOLPAUSE"] = UI_CURSOR_TOOLPAUSE;
+		cursor_string_table["UI_CURSOR_TOOLMEDIAOPEN"] = UI_CURSOR_TOOLMEDIAOPEN;
+		cursor_string_table["UI_CURSOR_PIPETTE"] = UI_CURSOR_PIPETTE;
+	}
+
+	std::map<std::string,U32>::const_iterator iter = cursor_string_table.find(cursor_string);
+	
+	if (iter != cursor_string_table.end())
+	{
+		return (ECursorType)iter->second;
+	}
+
+	return UI_CURSOR_ARROW;
+}
+
+
+
diff --git a/indra/llcommon/llcursortypes.h b/indra/llcommon/llcursortypes.h
new file mode 100644
index 0000000000000000000000000000000000000000..a9f23060c7c7ea7a5afd50a4ef838dddf80685a3
--- /dev/null
+++ b/indra/llcommon/llcursortypes.h
@@ -0,0 +1,81 @@
+/** 
+ * @file llcursortypes.h
+ * @brief Cursor types
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLCURSORTYPES_H
+#define LL_LLCURSORTYPES_H
+
+#include "linden_common.h"
+
+// If you add types here, add them in LLCursor::getCursorFromString
+enum ECursorType {
+	UI_CURSOR_ARROW,
+	UI_CURSOR_WAIT,
+	UI_CURSOR_HAND,
+	UI_CURSOR_IBEAM,
+	UI_CURSOR_CROSS,
+	UI_CURSOR_SIZENWSE,
+	UI_CURSOR_SIZENESW,
+	UI_CURSOR_SIZEWE,
+	UI_CURSOR_SIZENS,
+	UI_CURSOR_NO,
+	UI_CURSOR_WORKING,
+	UI_CURSOR_TOOLGRAB,
+	UI_CURSOR_TOOLLAND,
+	UI_CURSOR_TOOLFOCUS,
+	UI_CURSOR_TOOLCREATE,
+	UI_CURSOR_ARROWDRAG,
+	UI_CURSOR_ARROWCOPY,	// drag with copy
+	UI_CURSOR_ARROWDRAGMULTI,
+	UI_CURSOR_ARROWCOPYMULTI,	// drag with copy
+	UI_CURSOR_NOLOCKED,
+	UI_CURSOR_ARROWLOCKED,
+	UI_CURSOR_GRABLOCKED,
+	UI_CURSOR_TOOLTRANSLATE,
+	UI_CURSOR_TOOLROTATE,
+	UI_CURSOR_TOOLSCALE,
+	UI_CURSOR_TOOLCAMERA,
+	UI_CURSOR_TOOLPAN,
+	UI_CURSOR_TOOLZOOMIN,
+	UI_CURSOR_TOOLPICKOBJECT3,
+	UI_CURSOR_TOOLSIT,
+	UI_CURSOR_TOOLBUY,
+	UI_CURSOR_TOOLPAY,
+	UI_CURSOR_TOOLOPEN,
+	UI_CURSOR_TOOLPLAY,
+	UI_CURSOR_TOOLPAUSE,
+	UI_CURSOR_TOOLMEDIAOPEN,
+	UI_CURSOR_PIPETTE,
+	UI_CURSOR_COUNT			// Number of elements in this enum (NOT a cursor)
+};
+
+ECursorType getCursorFromString(const std::string& cursor_string);
+
+#endif // LL_LLCURSORTYPES_H
diff --git a/indra/llmath/llcamera.cpp b/indra/llmath/llcamera.cpp
index 3b9ba9d0f764cb6893b3418227383f46b7732435..6c28013af8c8f32bf677755ba37c1faabbcbb398 100644
--- a/indra/llmath/llcamera.cpp
+++ b/indra/llmath/llcamera.cpp
@@ -50,33 +50,38 @@ LLCamera::LLCamera() :
 } 
 
 
-LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) :
+LLCamera::LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) :
 	LLCoordFrame(),
-	mView(z_field_of_view),
-	mAspect(aspect_ratio),
 	mViewHeightInPixels(view_height_in_pixels),
-	mNearPlane(near_plane),
-	mFarPlane(far_plane),
 	mFixedDistance(-1.f),
 	mPlaneCount(6)
 {
-	if (mView < MIN_FIELD_OF_VIEW) 			{ mView = MIN_FIELD_OF_VIEW; }
-	else if (mView > MAX_FIELD_OF_VIEW)		{ mView = MAX_FIELD_OF_VIEW; }
+	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;
+	mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
 
-	if (mAspect < MIN_ASPECT_RATIO)			{ mAspect = MIN_ASPECT_RATIO; }
-	else if (mAspect > MAX_ASPECT_RATIO)	{ mAspect = MAX_ASPECT_RATIO; }
-
-	if (mNearPlane < MIN_NEAR_PLANE)		{ mNearPlane = MIN_NEAR_PLANE; }
-	else if (mNearPlane > MAX_NEAR_PLANE)	{ mNearPlane = MAX_NEAR_PLANE; }
+	setView(vertical_fov_rads);
+} 
 
-	if (mFarPlane < 0) 						{ mFarPlane = DEFAULT_FAR_PLANE; }
-	else if (mFarPlane < MIN_FAR_PLANE)		{ mFarPlane = MIN_FAR_PLANE; }
-	else if (mFarPlane > MAX_FAR_PLANE)		{ mFarPlane = MAX_FAR_PLANE; }
 
-	calculateFrustumPlanes();
-} 
+// ---------------- LLCamera::getFoo() member functions ----------------
 
+F32 LLCamera::getMinView() const 
+{
+	// minimum vertical fov needs to be constrained in narrow windows.
+	return mAspect > 1
+		? MIN_FIELD_OF_VIEW // wide views
+		: MIN_FIELD_OF_VIEW * 1/mAspect; // clamps minimum width in narrow views
+}
 
+F32 LLCamera::getMaxView() const 
+{
+	// maximum vertical fov needs to be constrained in wide windows.
+	return mAspect > 1 
+		? MAX_FIELD_OF_VIEW / mAspect  // clamps maximum width in wide views
+		: MAX_FIELD_OF_VIEW; // narrow views
+}
 
 // ---------------- LLCamera::setFoo() member functions ----------------
 
@@ -92,11 +97,9 @@ void LLCamera::disableUserClipPlane()
 	mPlaneCount = 6;
 }
 
-void LLCamera::setView(F32 field_of_view) 
+void LLCamera::setView(F32 vertical_fov_rads) 
 {
-	mView = field_of_view;
-	if (mView < MIN_FIELD_OF_VIEW) 			{ mView = MIN_FIELD_OF_VIEW; }
-	else if (mView > MAX_FIELD_OF_VIEW)		{ mView = MAX_FIELD_OF_VIEW; }
+	mView = llclamp(vertical_fov_rads, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
 	calculateFrustumPlanes();
 }
 
@@ -110,27 +113,21 @@ void LLCamera::setViewHeightInPixels(S32 height)
 
 void LLCamera::setAspect(F32 aspect_ratio) 
 {
-	mAspect = aspect_ratio;
-	if (mAspect < MIN_ASPECT_RATIO)			{ mAspect = MIN_ASPECT_RATIO; }
-	else if (mAspect > MAX_ASPECT_RATIO)	{ mAspect = MAX_ASPECT_RATIO; }
+	mAspect = llclamp(aspect_ratio, MIN_ASPECT_RATIO, MAX_ASPECT_RATIO);
 	calculateFrustumPlanes();
 }
 
 
 void LLCamera::setNear(F32 near_plane) 
 {
-	mNearPlane = near_plane;
-	if (mNearPlane < MIN_NEAR_PLANE)		{ mNearPlane = MIN_NEAR_PLANE; }
-	else if (mNearPlane > MAX_NEAR_PLANE)	{ mNearPlane = MAX_NEAR_PLANE; }
+	mNearPlane = llclamp(near_plane, MIN_NEAR_PLANE, MAX_NEAR_PLANE);
 	calculateFrustumPlanes();
 }
 
 
 void LLCamera::setFar(F32 far_plane) 
 {
-	mFarPlane = far_plane;
-	if (mFarPlane < MIN_FAR_PLANE)			{ mFarPlane = MIN_FAR_PLANE; }
-	else if (mFarPlane > MAX_FAR_PLANE)		{ mFarPlane = MAX_FAR_PLANE; }
+	mFarPlane = llclamp(far_plane, MIN_FAR_PLANE, MAX_FAR_PLANE);
 	calculateFrustumPlanes();
 }
 
diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h
index 82c712e5e7aed6d6b81855dbef0668a1abee1368..094e59fd0a9e75e332817714d7b90f74c718be23 100644
--- a/indra/llmath/llcamera.h
+++ b/indra/llmath/llcamera.h
@@ -42,17 +42,19 @@ const F32 DEFAULT_ASPECT_RATIO 		= 640.f / 480.f;
 const F32 DEFAULT_NEAR_PLANE 		= 0.25f;
 const F32 DEFAULT_FAR_PLANE 		= 64.f;	// far reaches across two horizontal, not diagonal, regions
 
-const F32 MAX_FIELD_OF_VIEW = F_PI;
 const F32 MAX_ASPECT_RATIO 	= 50.0f;
 const F32 MAX_NEAR_PLANE 	= 10.f;
 const F32 MAX_FAR_PLANE 	= 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though.
 const F32 MAX_FAR_CLIP		= 512.0f;
 
-const F32 MIN_FIELD_OF_VIEW = 0.1f;
 const F32 MIN_ASPECT_RATIO 	= 0.02f;
 const F32 MIN_NEAR_PLANE 	= 0.1f;
 const F32 MIN_FAR_PLANE 	= 0.2f;
 
+// Min/Max FOV values for square views. Call getMin/MaxView to get extremes based on current aspect ratio.
+static const F32 MIN_FIELD_OF_VIEW = 5.0f * DEG_TO_RAD;
+static const F32 MAX_FIELD_OF_VIEW = 175.f * DEG_TO_RAD;
+
 static const LLVector3 X_AXIS(1.f,0.f,0.f);
 static const LLVector3 Y_AXIS(0.f,1.f,0.f);
 static const LLVector3 Z_AXIS(0.f,0.f,1.f);
@@ -101,7 +103,7 @@ class LLCamera
 		HORIZ_PLANE_ALL_MASK = 0x3
 	};
 
-protected:
+private:
 	F32 mView;					// angle between top and bottom frustum planes in radians.
 	F32 mAspect;				// width/height
 	S32 mViewHeightInPixels;	// for ViewHeightInPixels() only
@@ -117,12 +119,12 @@ class LLCamera
 
 	struct frustum_plane
 	{
-        frustum_plane() : mask(0) {}
+		frustum_plane() : mask(0) {}
 		LLPlane p;
 		U8 mask;
 	};
 	frustum_plane mAgentPlanes[7];  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
-									
+
 	U32 mPlaneCount;  //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
 
 	LLVector3 mWorldPlanePos;		// Position of World Planes (may be offset from camera)
@@ -132,12 +134,13 @@ class LLCamera
 	
 public:
 	LLCamera();
-	LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
+	LLCamera(F32 vertical_fov_rads, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
+	virtual ~LLCamera(){} // no-op virtual destructor
 
 	void setUserClipPlane(LLPlane plane);
 	void disableUserClipPlane();
 	U8 calcPlaneMask(const LLPlane& plane);
-	void setView(F32 new_view);
+	virtual void setView(F32 vertical_fov_rads);
 	void setViewHeightInPixels(S32 height);
 	void setAspect(F32 new_aspect);
 	void setNear(F32 new_near);
@@ -148,6 +151,11 @@ class LLCamera
 	F32 getAspect() const						{ return mAspect; }				// width / height
 	F32 getNear() const							{ return mNearPlane; }			// meters
 	F32 getFar() const							{ return mFarPlane; }			// meters
+
+	// The values returned by the min/max view getters depend upon the aspect ratio
+	// at the time they are called and therefore should not be cached.
+	F32 getMinView() const;
+	F32 getMaxView() const;
 	
 	F32 getYaw() const
 	{
diff --git a/indra/llmath/lloctree.h b/indra/llmath/lloctree.h
index 25b7100eb7a898b8dbbc57032231b639b1e089ef..5a1efdbe28f5e4e07b0b62797c7c8442ec679103 100644
--- a/indra/llmath/lloctree.h
+++ b/indra/llmath/lloctree.h
@@ -38,9 +38,9 @@
 #include <set>
 
 #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
-#define OCT_ERRS LL_WARNS("OctreeErrors")
-#else
 #define OCT_ERRS LL_ERRS("OctreeErrors")
+#else
+#define OCT_ERRS LL_WARNS("OctreeErrors")
 #endif
 
 #define LL_OCTREE_PARANOIA_CHECK 0
diff --git a/indra/llmessage/llnamevalue.cpp b/indra/llmessage/llnamevalue.cpp
index 58755871865add208f3b26e441081c3f1de414a0..33c19dc57cd94b3b7a30a5ed52d693f1e1889b1b 100644
--- a/indra/llmessage/llnamevalue.cpp
+++ b/indra/llmessage/llnamevalue.cpp
@@ -38,7 +38,6 @@
 
 #include "u64.h"
 #include "llstring.h"
-#include "llcamera.h"
 #include "string_table.h"
 
 // Anonymous enumeration to provide constants in this file.
diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp
index ba2846202fe6c6f738f13ee0155167e70d7f08b6..60a0e65cbf1a3af1fef9a50cd65198adac5f0b3c 100644
--- a/indra/llrender/llcubemap.cpp
+++ b/indra/llrender/llcubemap.cpp
@@ -39,7 +39,6 @@
 #include "v3dmath.h"
 #include "m3math.h"
 #include "m4math.h"
-#include "llcamera.h"
 
 #include "llrender.h"
 
diff --git a/indra/llui/CMakeLists.txt b/indra/llui/CMakeLists.txt
index 77efec5696a5f3629a87e629ac26c904dcedfbc0..897cc4275d497d316ec8a9aa443f91e2d432865d 100644
--- a/indra/llui/CMakeLists.txt
+++ b/indra/llui/CMakeLists.txt
@@ -44,6 +44,7 @@ set(llui_SOURCE_FILES
     llmultislider.cpp
     llmultisliderctrl.cpp
     llpanel.cpp
+    llprogressbar.cpp
     llradiogroup.cpp
     llresizebar.cpp
     llresizehandle.cpp
@@ -95,6 +96,7 @@ set(llui_HEADER_FILES
     llmultisliderctrl.h
     llmultislider.h
     llpanel.h
+    llprogressbar.h
     llradiogroup.h
     llresizebar.h
     llresizehandle.h
diff --git a/indra/llui/llbutton.cpp b/indra/llui/llbutton.cpp
index 47b7067f630c9f03f238202d5e71f6f020096267..7441d2f73479e3f7ee27fa628c98723482271b2a 100644
--- a/indra/llui/llbutton.cpp
+++ b/indra/llui/llbutton.cpp
@@ -422,13 +422,7 @@ void LLButton::draw()
 	// Unselected image assignments
 	S32 local_mouse_x;
 	S32 local_mouse_y;
-	LLCoordWindow cursor_pos_window;
-	getWindow()->getCursorPosition(&cursor_pos_window);
-	LLCoordGL cursor_pos_gl;
-	getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
-	cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
-	cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
-	screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
+	LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
 
 	BOOL pressed = pressed_by_keyboard 
 					|| (hasMouseCapture() && pointInView(local_mouse_x, local_mouse_y)) 
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index f3941ff7d104302122144d9dd3bfd7604687151b..415419748f10c687431d24024acecb2e39e2f764 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -456,7 +456,7 @@ class VisibilityPolicy<LLFloater>
 
 
 // singleton implementation for floaters (provides visibility policy)
-// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=79410
+// https://wiki.lindenlab.com/mediawiki/index.php?title=LLFloaterSingleton&oldid=164990
 
 template <class T> class LLFloaterSingleton : public LLUISingleton<T, VisibilityPolicy<LLFloater> >
 {
diff --git a/indra/llui/llpanel.cpp b/indra/llui/llpanel.cpp
index f6c621444da13728935a838dde38585774b36e1c..22934450e79c87148051f306dbd6942903c8f928 100644
--- a/indra/llui/llpanel.cpp
+++ b/indra/llui/llpanel.cpp
@@ -982,12 +982,12 @@ void LLPanel::childSetAction(const std::string& id, void(*function)(void*), void
 	}
 }
 
-void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*))
+void LLPanel::childSetActionTextbox(const std::string& id, void(*function)(void*), void* value)
 {
 	LLTextBox* textbox = getChild<LLTextBox>(id);
 	if (textbox)
 	{
-		textbox->setClickedCallback(function);
+		textbox->setClickedCallback(function, value);
 	}
 }
 
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index 355e32f1cd65de218bdd55b9ab3190fab2616878..c55eb6bba2d8db485768f72485c0870b0c320bf1 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -220,7 +220,7 @@ class LLPanel : public LLUICtrl
 
 	// LLButton
 	void childSetAction(const std::string& id, void(*function)(void*), void* value);
-	void childSetActionTextbox(const std::string& id, void(*function)(void*));
+	void childSetActionTextbox(const std::string& id, void(*function)(void*), void* value = NULL);
 	void childSetControlName(const std::string& id, const std::string& control_name);
 
 	// Error reporting
diff --git a/indra/llui/llprogressbar.cpp b/indra/llui/llprogressbar.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4425bad7bfe7c8e40900f3b7a55cb5b7eead1eed
--- /dev/null
+++ b/indra/llui/llprogressbar.cpp
@@ -0,0 +1,180 @@
+/** 
+ * @file llprogressbar.cpp
+ * @brief LLProgressBar class implementation
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "linden_common.h"
+
+#include "llprogressbar.h"
+
+#include "indra_constants.h"
+#include "llmath.h"
+#include "llgl.h"
+#include "llui.h"
+#include "llfontgl.h"
+#include "llimagegl.h"
+#include "lltimer.h"
+#include "llglheaders.h"
+
+#include "llfocusmgr.h"
+
+static LLRegisterWidget<LLProgressBar> r("progress_bar");
+
+LLProgressBar::LLProgressBar(const std::string& name, const LLRect &rect) 
+	: LLView(name, rect, FALSE),
+	  mImageBar( NULL ),
+	  mImageShadow( NULL )
+{
+	mPercentDone = 0.f;
+
+	// Defaults:
+
+	setImageBar("rounded_square.tga");	
+	setImageShadow("rounded_square_soft.tga");
+
+	mColorBackground = LLColor4(0.3254f, 0.4000f, 0.5058f, 1.0f);
+	mColorBar        = LLColor4(0.5764f, 0.6627f, 0.8352f, 1.0f);
+	mColorBar2       = LLColor4(0.5764f, 0.6627f, 0.8352f, 1.0f);
+	mColorShadow     = LLColor4(0.2000f, 0.2000f, 0.4000f, 1.0f);
+}
+
+LLProgressBar::~LLProgressBar()
+{
+	gFocusMgr.releaseFocusIfNeeded( this );
+}
+
+void LLProgressBar::draw()
+{
+	static LLTimer timer;
+
+	LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga");
+	LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga");
+	LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("progressbar_track.tga");
+	LLUIImagePtr bar_imagep = LLUI::getUIImage("rounded_square.tga");
+	LLColor4 background_color = LLUI::sColorsGroup->getColor("LoginProgressBarBgColor");
+	
+	bar_bg_imagep->draw(getLocalRect(),
+		background_color);
+
+	F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
+	LLColor4 bar_color = LLUI::sColorsGroup->getColor("LoginProgressBarFgColor");
+	bar_color.mV[3] = alpha;
+	LLRect progress_rect = getLocalRect();
+	progress_rect.mRight = llround(getRect().getWidth() * (mPercentDone / 100.f));
+	bar_fg_imagep->draw(progress_rect);
+}
+
+void LLProgressBar::setPercent(const F32 percent)
+{
+	mPercentDone = llclamp(percent, 0.f, 100.f);
+}
+
+void LLProgressBar::setImageBar( const std::string &bar_name )
+{
+	mImageBar = LLUI::sImageProvider->getUIImage(bar_name)->getImage();
+}
+
+void LLProgressBar::setImageShadow(const std::string &shadow_name)
+{
+	mImageShadow = LLUI::sImageProvider->getUIImage(shadow_name)->getImage();
+}
+
+void LLProgressBar::setColorBar(const LLColor4 &c)
+{
+	mColorBar = c;
+}
+void LLProgressBar::setColorBar2(const LLColor4 &c)
+{
+	mColorBar2 = c;
+}
+void LLProgressBar::setColorShadow(const LLColor4 &c)
+{
+	mColorShadow = c;
+}
+void LLProgressBar::setColorBackground(const LLColor4 &c)
+{
+	mColorBackground = c;
+}
+
+
+// static
+LLView* LLProgressBar::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory)
+{
+	std::string name("progress_bar");
+	node->getAttributeString("name", name);
+
+	LLProgressBar *progress = new LLProgressBar(name, LLRect());
+
+
+	std::string image_bar;
+	if (node->hasAttribute("image_bar")) node->getAttributeString("image_bar",image_bar);
+	if (image_bar != LLStringUtil::null) progress->setImageBar(image_bar);
+
+
+	std::string image_shadow;
+	if (node->hasAttribute("image_shadow")) node->getAttributeString("image_shadow",image_shadow);
+	if (image_shadow != LLStringUtil::null) progress->setImageShadow(image_shadow);
+
+
+	LLColor4 color_bar;
+	if (node->hasAttribute("color_bar"))
+	{
+		node->getAttributeColor4("color_bar",color_bar);
+		progress->setColorBar(color_bar);
+	}
+
+
+	LLColor4 color_bar2;
+	if (node->hasAttribute("color_bar2"))
+	{
+		node->getAttributeColor4("color_bar2",color_bar2);
+		progress->setColorBar2(color_bar2);
+	}
+
+
+	LLColor4 color_shadow;
+	if (node->hasAttribute("color_shadow"))
+	{
+		node->getAttributeColor4("color_shadow",color_shadow);
+		progress->setColorShadow(color_shadow);
+	}
+
+
+	LLColor4 color_bg;
+	if (node->hasAttribute("color_bg"))
+	{
+		node->getAttributeColor4("color_bg",color_bg);
+		progress->setColorBackground(color_bg);
+	}
+
+	
+	progress->initFromXML(node, parent);
+	
+	return progress;
+}
diff --git a/indra/llui/llprogressbar.h b/indra/llui/llprogressbar.h
new file mode 100644
index 0000000000000000000000000000000000000000..6c720290fcf7ec2b7ebe049dc82530eb368b938d
--- /dev/null
+++ b/indra/llui/llprogressbar.h
@@ -0,0 +1,75 @@
+/** 
+ * @file llprogressbar.h
+ * @brief LLProgressBar class definition
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLPROGRESSBAR_H
+#define LL_LLPROGRESSBAR_H
+
+#include "llview.h"
+#include "llframetimer.h"
+
+class LLProgressBar
+	: public LLView
+{
+public:
+	LLProgressBar(const std::string& name, const LLRect &rect);
+	virtual ~LLProgressBar();
+
+	void setPercent(const F32 percent);
+
+	void setImageBar(const std::string &bar_name);
+	void setImageShadow(const std::string &shadow_name);
+
+	void setColorBar(const LLColor4 &c);
+	void setColorBar2(const LLColor4 &c);
+	void setColorShadow(const LLColor4 &c);
+	void setColorBackground(const LLColor4 &c);
+
+	static LLView* fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *factory);
+
+	/*virtual*/ void draw();
+
+protected:
+	F32 mPercentDone;
+
+	LLPointer<LLImageGL>  mImageBar;
+	//LLUUID                mImageBarID;
+	//LLString              mImageBarName;
+	LLColor4              mColorBar;
+	LLColor4              mColorBar2;
+
+	LLPointer<LLImageGL>  mImageShadow;
+	//LLUUID                mImageShadowID;
+	//LLString              mImageShadowName;
+	LLColor4              mColorShadow;
+	LLColor4              mColorBackground;
+};
+
+#endif // LL_LLPROGRESSBAR_H
diff --git a/indra/llui/llscrollbar.cpp b/indra/llui/llscrollbar.cpp
index 07babd9f55de976fd788e95be3ffb0da11774d9c..a7163323bd1541d23b3682fdbbf4a44a08278e69 100644
--- a/indra/llui/llscrollbar.cpp
+++ b/indra/llui/llscrollbar.cpp
@@ -464,12 +464,7 @@ void LLScrollbar::draw()
 {
 	S32 local_mouse_x;
 	S32 local_mouse_y;
-	LLCoordWindow cursor_pos_window;
-	getWindow()->getCursorPosition(&cursor_pos_window);
-	LLCoordGL cursor_pos_gl;
-	getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
-
-	screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, &local_mouse_x, &local_mouse_y);
+	LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
 	BOOL other_captor = gFocusMgr.getMouseCapture() && gFocusMgr.getMouseCapture() != this;
 	BOOL hovered = getEnabled() && !other_captor && (hasMouseCapture() || mThumbRect.pointInRect(local_mouse_x, local_mouse_y));
 	if (hovered)
diff --git a/indra/llui/lltextbox.cpp b/indra/llui/lltextbox.cpp
index ac2f2a64a3ed7a5d211189942ec2716c7682ae6f..c616931cd60ce42f935bf45902e12939fa2c20c0 100644
--- a/indra/llui/lltextbox.cpp
+++ b/indra/llui/lltextbox.cpp
@@ -33,32 +33,16 @@
 #include "lltextbox.h"
 #include "lluictrlfactory.h"
 #include "llfocusmgr.h"
+#include "llwindow.h"
 
 static LLRegisterWidget<LLTextBox> r("text");
 
 LLTextBox::LLTextBox(const std::string& name, const LLRect& rect, const std::string& text,
 					 const LLFontGL* font, BOOL mouse_opaque)
 :	LLUICtrl(name, rect, mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP ),
-	mFontGL(font ? font : LLFontGL::sSansSerifSmall),
-	mTextColor(			LLUI::sColorsGroup->getColor( "LabelTextColor" ) ),
-	mDisabledColor(		LLUI::sColorsGroup->getColor( "LabelDisabledColor" ) ),
-	mBackgroundColor(	LLUI::sColorsGroup->getColor( "DefaultBackgroundColor" ) ),
-	mBorderColor(		LLUI::sColorsGroup->getColor( "DefaultHighlightLight" ) ),
-	mHoverColor(		LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ),
-	mHoverActive( FALSE ),
-	mHasHover( FALSE ),
-	mBackgroundVisible( FALSE ),
-	mBorderVisible( FALSE ),
-	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
-	mBorderDropShadowVisible( FALSE ),
-	mUseEllipses( FALSE ),
-	mHPad(0),
-	mVPad(0),
-	mHAlign( LLFontGL::LEFT ),
-	mVAlign( LLFontGL::TOP ),
-	mClickedCallback(NULL),
-	mCallbackUserData(NULL)
+	mFontGL(font ? font : LLFontGL::sSansSerifSmall)
 {
+	initDefaults();
 	setText( text );
 	setTabStop(FALSE);
 }
@@ -66,26 +50,9 @@ LLTextBox::LLTextBox(const std::string& name, const LLRect& rect, const std::str
 LLTextBox::LLTextBox(const std::string& name, const std::string& text, F32 max_width,
 					 const LLFontGL* font, BOOL mouse_opaque) :
 	LLUICtrl(name, LLRect(0, 0, 1, 1), mouse_opaque, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),	
-	mFontGL(font ? font : LLFontGL::sSansSerifSmall),
-	mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")),
-	mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")),
-	mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")),
-	mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")),
-	mHoverColor( LLUI::sColorsGroup->getColor( "LabelSelectedColor" ) ),
-	mHoverActive( FALSE ),
-	mHasHover( FALSE ),
-	mBackgroundVisible(FALSE),
-	mBorderVisible(FALSE),
-	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
-	mBorderDropShadowVisible(FALSE),
-	mUseEllipses( FALSE ),
-	mHPad(0),
-	mVPad(0),
-	mHAlign(LLFontGL::LEFT),
-	mVAlign( LLFontGL::TOP ),
-	mClickedCallback(NULL),
-	mCallbackUserData(NULL)
+	mFontGL(font ? font : LLFontGL::sSansSerifSmall)
 {
+	initDefaults();
 	setWrappedText(text, max_width);
 	reshapeToFitText();
 	setTabStop(FALSE);
@@ -93,47 +60,34 @@ LLTextBox::LLTextBox(const std::string& name, const std::string& text, F32 max_w
 
 LLTextBox::LLTextBox(const std::string& name_and_label, const LLRect& rect) :
 	LLUICtrl(name_and_label, rect, TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),	
-	mFontGL(LLFontGL::sSansSerifSmall),
-	mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")),
-	mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")),
-	mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")),
-	mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")),
-	mBackgroundVisible(FALSE),
-	mBorderVisible(FALSE),
-	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
-	mBorderDropShadowVisible(FALSE),
-	mHPad(0),
-	mVPad(0),
-	mHAlign(LLFontGL::LEFT),
-	mVAlign( LLFontGL::TOP ),
-	mClickedCallback(NULL),
-	mCallbackUserData(NULL)
+	mFontGL(LLFontGL::sSansSerifSmall)
 {
+	initDefaults();
 	setText( name_and_label );
 	setTabStop(FALSE);
 }
 
-LLTextBox::LLTextBox(const std::string& name_and_label) :
-	LLUICtrl(name_and_label, LLRect(0, 0, 1, 1), TRUE, NULL, NULL, FOLLOWS_LEFT | FOLLOWS_TOP),	
-	mFontGL(LLFontGL::sSansSerifSmall),
-	mTextColor(LLUI::sColorsGroup->getColor("LabelTextColor")),
-	mDisabledColor(LLUI::sColorsGroup->getColor("LabelDisabledColor")),
-	mBackgroundColor(LLUI::sColorsGroup->getColor("DefaultBackgroundColor")),
-	mBorderColor(LLUI::sColorsGroup->getColor("DefaultHighlightLight")),
-	mBackgroundVisible(FALSE),
-	mBorderVisible(FALSE),
-	mFontStyle(LLFontGL::DROP_SHADOW_SOFT),
-	mBorderDropShadowVisible(FALSE),
-	mHPad(0),
-	mVPad(0),
-	mHAlign(LLFontGL::LEFT),
-	mVAlign( LLFontGL::TOP ),
-	mClickedCallback(NULL),
-	mCallbackUserData(NULL)
+void LLTextBox::initDefaults()
 {
-	setWrappedText(name_and_label);
-	reshapeToFitText();
-	setTabStop(FALSE);
+	mTextColor = LLUI::sColorsGroup->getColor("LabelTextColor");
+	mDisabledColor = LLUI::sColorsGroup->getColor("LabelDisabledColor");
+	mBackgroundColor = LLUI::sColorsGroup->getColor("DefaultBackgroundColor");
+	mBorderColor = LLUI::sColorsGroup->getColor("DefaultHighlightLight");
+	mHoverColor = LLUI::sColorsGroup->getColor( "LabelSelectedColor" );
+	mHoverActive = FALSE;
+	mHasHover = FALSE;
+	mBackgroundVisible = FALSE;
+	mBorderVisible = FALSE;
+	mFontStyle = LLFontGL::DROP_SHADOW_SOFT;
+	mBorderDropShadowVisible = FALSE;
+	mUseEllipses = FALSE;
+	mLineSpacing = 0;
+	mHPad = 0;
+	mVPad = 0;
+	mHAlign = LLFontGL::LEFT;
+	mVAlign = LLFontGL::TOP;
+	mClickedCallback = NULL;
+	mCallbackUserData = NULL;
 }
 
 BOOL LLTextBox::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -193,12 +147,14 @@ BOOL LLTextBox::handleMouseUp(S32 x, S32 y, MASK mask)
 
 BOOL LLTextBox::handleHover(S32 x, S32 y, MASK mask)
 {
+	BOOL handled = LLView::handleHover(x,y,mask);
 	if(mHoverActive)
 	{
 		mHasHover = TRUE; // This should be set every frame during a hover.
-		return TRUE;
+		getWindow()->setCursor(UI_CURSOR_ARROW);
 	}
-	return LLView::handleHover(x,y,mask);
+
+	return (handled || mHasHover);
 }
 
 void LLTextBox::setText(const LLStringExplicit& text)
@@ -412,7 +368,7 @@ void LLTextBox::drawText( S32 x, S32 y, const LLColor4& color )
 							mFontStyle,
 							line_length, getRect().getWidth(), NULL, TRUE, mUseEllipses );
 			cur_pos += line_length + 1;
-			y -= llfloor(mFontGL->getLineHeight());
+			y -= llfloor(mFontGL->getLineHeight()) + mLineSpacing;
 		}
 	}
 }
@@ -469,6 +425,8 @@ LLView* LLTextBox::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *f
 
 	text_box->initFromXML(node, parent);
 
+	node->getAttributeS32("line_spacing", text_box->mLineSpacing);
+
 	std::string font_style;
 	if (node->getAttributeString("font-style", font_style))
 	{
diff --git a/indra/llui/lltextbox.h b/indra/llui/lltextbox.h
index b1e8e0b7c6185d1992b12e9b824d2ab8ee4dcc3f..c28d0e5f9490a38eb0e51b07b61535e7dbb32733 100644
--- a/indra/llui/lltextbox.h
+++ b/indra/llui/lltextbox.h
@@ -54,7 +54,10 @@ class LLTextBox
 
 	// "Simple" constructors for text boxes that have the same name and label *TO BE DEPRECATED*
 	LLTextBox(const std::string& name_and_label, const LLRect& rect);
-	LLTextBox(const std::string& name_and_label);
+
+	// Consolidate common member initialization
+	// 20+ initializers times 3+ constructors is unmaintainable.
+	void initDefaults(); 
 
 	virtual ~LLTextBox() {}
 
@@ -88,8 +91,7 @@ class LLTextBox
 	void			setVPad(S32 pixels)						{ mVPad = pixels; }
 	void			setRightAlign()							{ mHAlign = LLFontGL::RIGHT; }
 	void			setHAlign( LLFontGL::HAlign align )		{ mHAlign = align; }
-	void			setClickedCallback( void (*cb)(void *data) ){ mClickedCallback = cb; }		// mouse down and up within button
-	void			setCallbackUserData( void* data )		{ mCallbackUserData = data; }
+	void			setClickedCallback( void (*cb)(void *data), void* data = NULL ){ mClickedCallback = cb; mCallbackUserData = data; }		// mouse down and up within button
 
 	const LLFontGL* getFont() const							{ return mFontGL; }
 
@@ -124,6 +126,8 @@ class LLTextBox
 	BOOL			mBorderDropShadowVisible;
 	BOOL			mUseEllipses;
 
+	S32				mLineSpacing;
+
 	S32				mHPad;
 	S32				mVPad;
 	LLFontGL::HAlign mHAlign;
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index 92b6cc8bb6285d7d8b40d759e2ea2fbc5055777e..f2562a015dd632b4ba6bf8dc8a629d45b4b5541c 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -3520,13 +3520,13 @@ void LLTextEditor::appendColoredText(const std::string &new_text,
 	style->setVisible(true);
 	style->setColor(color);
 	style->setFontName(font_name);
-	appendStyledText(new_text, allow_undo, prepend_newline, &style);
+	appendStyledText(new_text, allow_undo, prepend_newline, style);
 }
 
 void LLTextEditor::appendStyledText(const std::string &new_text, 
 									 bool allow_undo, 
 									 bool prepend_newline,
-									 const LLStyleSP *stylep)
+									 const LLStyleSP stylep)
 {
 	if(mParseHTML)
 	{
@@ -3540,13 +3540,13 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
 			html->setColor(mLinkColor);
 			if (stylep)
 			{
-				html->setFontName((*stylep)->getFontString());
+				html->setFontName(stylep->getFontString());
 			}
 			html->mUnderline = TRUE;
 
 			if (start > 0) appendText(text.substr(0,start),allow_undo, prepend_newline, stylep);
 			html->setLinkHREF(text.substr(start,end-start));
-			appendText(text.substr(start, end-start),allow_undo, prepend_newline, &html);
+			appendText(text.substr(start, end-start),allow_undo, prepend_newline, html);
 			if (end < (S32)text.length()) 
 			{
 				text = text.substr(end,text.length() - end);
@@ -3567,7 +3567,7 @@ void LLTextEditor::appendStyledText(const std::string &new_text,
 
 // Appends new text to end of document
 void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool prepend_newline,
-							  const LLStyleSP *stylep)
+							  const LLStyleSP stylep)
 {
 	// Save old state
 	BOOL was_scrolled_to_bottom = (mScrollbar->getDocPos() == mScrollbar->getDocPosMax());
@@ -3599,7 +3599,7 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
 	{
 		S32 segment_start = old_length;
 		S32 segment_end = getLength();
-		LLTextSegment* segment = new LLTextSegment(*stylep, segment_start, segment_end );
+		LLTextSegment* segment = new LLTextSegment(stylep, segment_start, segment_end );
 		mSegments.push_back(segment);
 	}
 	
diff --git a/indra/llui/lltexteditor.h b/indra/llui/lltexteditor.h
index 4f41f67ce8e82ff4292bc14ab599f80447537090..8209f6d798b062ed8b4117aacb1b96a5bcd59b89 100644
--- a/indra/llui/lltexteditor.h
+++ b/indra/llui/lltexteditor.h
@@ -139,7 +139,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	void			insertText(const std::string &text);
 	// appends text at end
 	void 			appendText(const std::string &wtext, bool allow_undo, bool prepend_newline,
-							   const LLStyleSP *stylep = NULL);
+							   const LLStyleSP stylep = NULL);
 
 	void 			appendColoredText(const std::string &wtext, bool allow_undo, 
 									  bool prepend_newline,
@@ -148,7 +148,7 @@ class LLTextEditor : public LLUICtrl, LLEditMenuHandler, protected LLPreeditor
 	// if styled text starts a line, you need to prepend a newline.
 	void 			appendStyledText(const std::string &new_text, bool allow_undo, 
 									 bool prepend_newline,
-									 const LLStyleSP *stylep = NULL);
+									 const LLStyleSP stylep = NULL);
 
 	// Removes text from the end of document
 	// Does not change highlight or cursor position.
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index f1e7b98a609e91836cbf23cfed598eab804e34ec..a4b16dc2deeb95e6a1060bface8fbf7828be2ea2 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -1645,6 +1645,18 @@ void LLUI::setCursorPositionLocal(const LLView* viewp, S32 x, S32 y)
 	setCursorPositionScreen(screen_x, screen_y);
 }
 
+//static 
+void LLUI::getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y)
+{
+	LLCoordWindow cursor_pos_window;
+	LLView::getWindow()->getCursorPosition(&cursor_pos_window);
+	LLCoordGL cursor_pos_gl;
+	LLView::getWindow()->convertCoords(cursor_pos_window, &cursor_pos_gl);
+	cursor_pos_gl.mX = llround((F32)cursor_pos_gl.mX / LLUI::sGLScaleFactor.mV[VX]);
+	cursor_pos_gl.mY = llround((F32)cursor_pos_gl.mY / LLUI::sGLScaleFactor.mV[VY]);
+	viewp->screenPointToLocal(cursor_pos_gl.mX, cursor_pos_gl.mY, x, y);
+}
+
 // On Windows, the user typically sets the language when they install the
 // app (by running it with a shortcut that sets InstallLanguage).  On Mac,
 // or on Windows if the SecondLife.exe executable is run directly, the 
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index aa3cff433ef5ff2c172725bef61085941f417b47..e2629ee2a4af85f62c1a8070a744224b7c496dd6 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -175,6 +175,7 @@ class LLUI
 	static std::string locateSkin(const std::string& filename);
 	static void setCursorPositionScreen(S32 x, S32 y);
 	static void setCursorPositionLocal(const LLView* viewp, S32 x, S32 y);
+	static void getCursorPositionLocal(const LLView* viewp, S32 *x, S32 *y);
 	static void setScaleFactor(const LLVector2& scale_factor);
 	static void setLineWidth(F32 width);
 	static LLUIImage* getUIImage(const std::string& name);
diff --git a/indra/llui/lluictrl.cpp b/indra/llui/lluictrl.cpp
index c01845e524f321ee3bb5a9cca20adb367006a119..f7419d615b405452a9653187561ae50d218c181d 100644
--- a/indra/llui/lluictrl.cpp
+++ b/indra/llui/lluictrl.cpp
@@ -551,19 +551,6 @@ LLView* LLUICtrl::fromXML(LLXMLNodePtr node, LLView* parent, class LLUICtrlFacto
 }
 
 
-// *NOTE: If other classes derive from LLPanel, they will need to be
-// added to this function.
-LLPanel* LLUICtrl::getParentPanel() const
-{
-	LLView* parent = getParent();
-	LLPanel* parent_panel = dynamic_cast<LLPanel*>(parent);
-	while (!parent_panel)
-	{
-		parent = parent->getParent();
-	}
-	return (LLPanel*)(parent);
-}
-
 // Skip over any parents that are not LLUICtrl's
 //  Used in focus logic since only LLUICtrl elements can have focus
 LLUICtrl* LLUICtrl::getParentUICtrl() const
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 52ea37ffdd2c2c0218c22d481857c25d31305232..4ad9042b9a6fe1759cc8eff891fe926a34aa2eb9 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -130,9 +130,7 @@ class LLUICtrl
 	void			setTabStop( BOOL b );
 	BOOL			hasTabStop() const;
 
-	// Returns containing panel/floater or NULL if none found.
-	class LLPanel*	getParentPanel() const;
-	class LLUICtrl*	getParentUICtrl() const;
+	LLUICtrl*		getParentUICtrl() const;
 
 	void*			getCallbackUserData() const								{ return mCallbackUserData; }
 	void			setCallbackUserData( void* data )						{ mCallbackUserData = data; }
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 5b71851520edfe3a71ea4b68865739e3588b9f51..5ea9d6b5d83140ee0e64d8b7b98392127d2f7445 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -85,7 +85,8 @@ LLView::LLView() :
 	mLastVisible(TRUE),
 	mUseBoundingRect(FALSE),
 	mVisible(TRUE),
-	mNextInsertionOrdinal(0)
+	mNextInsertionOrdinal(0),
+	mHoverCursor(UI_CURSOR_ARROW)
 {
 }
 
@@ -102,7 +103,8 @@ LLView::LLView(const std::string& name, BOOL mouse_opaque) :
 	mLastVisible(TRUE),
 	mUseBoundingRect(FALSE),
 	mVisible(TRUE),
-	mNextInsertionOrdinal(0)
+	mNextInsertionOrdinal(0),
+	mHoverCursor(UI_CURSOR_ARROW)
 {
 }
 
@@ -123,7 +125,8 @@ LLView::LLView(
 	mLastVisible(TRUE),
 	mUseBoundingRect(FALSE),
 	mVisible(TRUE),
-	mNextInsertionOrdinal(0)
+	mNextInsertionOrdinal(0),
+	mHoverCursor(UI_CURSOR_ARROW)
 {
 }
 
@@ -657,7 +660,7 @@ BOOL LLView::handleHover(S32 x, S32 y, MASK mask)
 	if( !handled 
 		&& blockMouseEvent(x, y) )
 	{
-		LLUI::sWindow->setCursor(UI_CURSOR_ARROW);
+		LLUI::sWindow->setCursor(mHoverCursor);
 		lldebugst(LLERR_USER_INPUT) << "hover handled by " << getName() << llendl;
 		handled = TRUE;
 	}
@@ -2664,6 +2667,13 @@ void LLView::initFromXML(LLXMLNodePtr node, LLView* parent)
 		node->getAttributeBOOL("visible", visible);
 		setVisible(visible);
 	}
+
+	if (node->hasAttribute("hover_cursor"))
+	{
+		std::string cursor_string;
+		node->getAttributeString("hover_cursor", cursor_string);
+		mHoverCursor = getCursorFromString(cursor_string);
+	}
 	
 	node->getAttributeBOOL("use_bounding_rect", mUseBoundingRect);
 	node->getAttributeBOOL("mouse_opaque", mMouseOpaque);
diff --git a/indra/llui/llview.h b/indra/llui/llview.h
index 130c3b52f7a5be47377db71b45391edeb24933b6..ff7a1afb387a8ae5e3e884d69b3c419006f8ec44 100644
--- a/indra/llui/llview.h
+++ b/indra/llui/llview.h
@@ -51,6 +51,7 @@
 #include "llxmlnode.h"
 #include "stdenums.h"
 #include "lluistring.h"
+#include "llcursortypes.h"
 
 const U32	FOLLOWS_NONE	= 0x00;
 const U32	FOLLOWS_LEFT	= 0x01;
@@ -649,6 +650,8 @@ class LLView : public LLMouseHandler, public LLMortician
 	mutable dummy_widget_map_t mDummyWidgets;
 
 	boost::signals::connection mControlConnection;
+
+	ECursorType mHoverCursor;
 	
 public:
 	static BOOL	sDebugRects;	// Draw debug rects behind everything.
diff --git a/indra/llvfs/lldir.cpp b/indra/llvfs/lldir.cpp
index 8acf7d88ca771a2b022f6281ce3432406b13805c..c2562bcfc96f9bc583b27acb3eabda8a920516bd 100644
--- a/indra/llvfs/lldir.cpp
+++ b/indra/llvfs/lldir.cpp
@@ -378,7 +378,7 @@ std::string LLDir::getExpandedFilename(ELLPath location, const std::string& subd
 	case LL_PATH_EXECUTABLE:
 		prefix = getExecutableDir();
 		break;
-
+		
 	default:
 		llassert(0);
 	}
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 8dc179748ad32401af412d572212140b29d31cbe..66cad59712cca9a473750d26fa8ecb4734ceb19a 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -35,48 +35,7 @@
 #include "llrect.h"
 #include "llcoord.h"
 #include "llstring.h"
-
-
-enum ECursorType {
-	UI_CURSOR_ARROW,
-	UI_CURSOR_WAIT,
-	UI_CURSOR_HAND,
-	UI_CURSOR_IBEAM,
-	UI_CURSOR_CROSS,
-	UI_CURSOR_SIZENWSE,
-	UI_CURSOR_SIZENESW,
-	UI_CURSOR_SIZEWE,
-	UI_CURSOR_SIZENS,
-	UI_CURSOR_NO,
-	UI_CURSOR_WORKING,
-	UI_CURSOR_TOOLGRAB,
-	UI_CURSOR_TOOLLAND,
-	UI_CURSOR_TOOLFOCUS,
-	UI_CURSOR_TOOLCREATE,
-	UI_CURSOR_ARROWDRAG,
-	UI_CURSOR_ARROWCOPY,	// drag with copy
-	UI_CURSOR_ARROWDRAGMULTI,
-	UI_CURSOR_ARROWCOPYMULTI,	// drag with copy
-	UI_CURSOR_NOLOCKED,
-	UI_CURSOR_ARROWLOCKED,
-	UI_CURSOR_GRABLOCKED,
-	UI_CURSOR_TOOLTRANSLATE,
-	UI_CURSOR_TOOLROTATE,
-	UI_CURSOR_TOOLSCALE,
-	UI_CURSOR_TOOLCAMERA,
-	UI_CURSOR_TOOLPAN,
-	UI_CURSOR_TOOLZOOMIN,
-	UI_CURSOR_TOOLPICKOBJECT3,
-	UI_CURSOR_TOOLSIT,
-	UI_CURSOR_TOOLBUY,
-	UI_CURSOR_TOOLPAY,
-	UI_CURSOR_TOOLOPEN,
-	UI_CURSOR_TOOLPLAY,
-	UI_CURSOR_TOOLPAUSE,
-	UI_CURSOR_TOOLMEDIAOPEN,
-	UI_CURSOR_PIPETTE,
-	UI_CURSOR_COUNT			// Number of elements in this enum (NOT a cursor)
-};
+#include "llcursortypes.h"
 
 class LLSplashScreen;
 
diff --git a/indra/llxml/llcontrol.cpp b/indra/llxml/llcontrol.cpp
index c967855e938153c27c43e0cfe928d45d7abad3d5..a0514373e59f0a28df8391de585f98c87397a7b1 100644
--- a/indra/llxml/llcontrol.cpp
+++ b/indra/llxml/llcontrol.cpp
@@ -50,9 +50,9 @@
 #include "llsdserialize.h"
 
 #if LL_RELEASE_WITH_DEBUG_INFO || LL_DEBUG
-#define CONTROL_ERRS LL_WARNS("ControlErrors")
-#else
 #define CONTROL_ERRS LL_ERRS("ControlErrors")
+#else
+#define CONTROL_ERRS LL_WARNS("ControlErrors")
 #endif
 
 //this defines the current version of the settings file
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index e62e4be0f1574885c7cdacd3db9536bc0b41f266..21e491e1b5b49a4d7cdc806d8af7c834058fdea0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -127,6 +127,7 @@ set(viewer_SOURCE_FILES
     llfloateravatartextures.cpp
     llfloaterbeacons.cpp
     llfloaterbuildoptions.cpp
+    llfloaterbulkpermission.cpp
     llfloaterbump.cpp
     llfloaterbuycontents.cpp
     llfloaterbuy.cpp
@@ -150,9 +151,11 @@ set(viewer_SOURCE_FILES
     llfloatergroupinfo.cpp
     llfloatergroupinvite.cpp
     llfloatergroups.cpp
+    llfloaterhandler.cpp
     llfloaterhardwaresettings.cpp
     llfloaterhtml.cpp
     llfloaterhtmlhelp.cpp
+    llfloaterhtmlsimple.cpp
     llfloaterhud.cpp
     llfloaterimagepreview.cpp
     llfloaterinspect.cpp
@@ -166,9 +169,11 @@ set(viewer_SOURCE_FILES
     llfloatermute.cpp
     llfloaternamedesc.cpp
     llfloaternewim.cpp
+    llfloaterobjectiminfo.cpp
     llfloateropenobject.cpp
     llfloaterparcel.cpp
     llfloaterpermissionsmgr.cpp
+    llfloaterperms.cpp
     llfloaterpostcard.cpp
     llfloaterpostprocess.cpp
     llfloaterpreference.cpp
@@ -224,6 +229,7 @@ set(viewer_SOURCE_FILES
     lljoystickbutton.cpp
     lllandmarklist.cpp
     lllogchat.cpp
+    llloginhandler.cpp
     llmanip.cpp
     llmaniprotate.cpp
     llmanipscale.cpp
@@ -522,6 +528,7 @@ set(viewer_HEADER_FILES
     llfloateravatartextures.h
     llfloaterbeacons.h
     llfloaterbuildoptions.h
+    llfloaterbulkpermission.h
     llfloaterbump.h
     llfloaterbuy.h
     llfloaterbuycontents.h
@@ -545,9 +552,11 @@ set(viewer_HEADER_FILES
     llfloatergroupinfo.h
     llfloatergroupinvite.h
     llfloatergroups.h
+    llfloaterhandler.h
     llfloaterhardwaresettings.h
     llfloaterhtml.h
     llfloaterhtmlhelp.h
+    llfloaterhtmlsimple.h
     llfloaterhud.h
     llfloaterimagepreview.h
     llfloaterinspect.h
@@ -561,12 +570,14 @@ set(viewer_HEADER_FILES
     llfloatermute.h
     llfloaternamedesc.h
     llfloaternewim.h
+    llfloaterobjectiminfo.h
     llfloateropenobject.h
     llfloaterparcel.h
     llfloaterpermissionsmgr.h
     llfloaterpostcard.h
     llfloaterpostprocess.h
     llfloaterpreference.h
+    llfloaterperms.h
     llfloaterproperties.h
     llfloaterregioninfo.h
     llfloaterreporter.h
@@ -618,6 +629,7 @@ set(viewer_HEADER_FILES
     lllandmarklist.h
     lllightconstants.h
     lllogchat.h
+    llloginhandler.h
     llmanip.h
     llmaniprotate.h
     llmanipscale.h
@@ -1030,6 +1042,7 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/floater_avatar_textures.xml
     skins/default/xui/en-us/floater_beacons.xml
     skins/default/xui/en-us/floater_build_options.xml
+    skins/default/xui/en-us/floater_bulk_perms.xml
     skins/default/xui/en-us/floater_bumps.xml
     skins/default/xui/en-us/floater_buy_contents.xml
     skins/default/xui/en-us/floater_buy_currency.xml
@@ -1052,6 +1065,7 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/floater_group_info.xml
     skins/default/xui/en-us/floater_hardware_settings.xml
     skins/default/xui/en-us/floater_html.xml
+    skins/default/xui/en-us/floater_html_simple.xml
     skins/default/xui/en-us/floater_hud.xml
     skins/default/xui/en-us/floater_image_preview.xml
     skins/default/xui/en-us/floater_import.xml
@@ -1077,11 +1091,13 @@ set(viewer_XUI_FILES
     skins/default/xui/en-us/floater_name_description.xml
     skins/default/xui/en-us/floater_new_im.xml
     skins/default/xui/en-us/floater_new_outfit_dialog.xml
+    skins/default/xui/en-us/floater_object_im_info.xml
     skins/default/xui/en-us/floater_openobject.xml
     skins/default/xui/en-us/floater_pay_object.xml
     skins/default/xui/en-us/floater_pay.xml
     skins/default/xui/en-us/floater_postcard.xml
     skins/default/xui/en-us/floater_post_process.xml
+    skins/default/xui/en-us/floater_perm_prefs.xml
     skins/default/xui/en-us/floater_preferences.xml
     skins/default/xui/en-us/floater_preview_animation.xml
     skins/default/xui/en-us/floater_preview_classified.xml
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e6943869dbbe1afba84291f537eb5f6748bdbfc3..a13d883682f77e578a527b471ec8723fa3f09387 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -906,6 +906,204 @@
       <key>Value</key>
       <real>16.0</real>
     </map>
+    <key>BulkChangeIncludeAnimations</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect animations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeAnimations</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect animations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeAnimations</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect animations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeAnimations</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect animations</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeBodyParts</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect body parts</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeClothing</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect clothing</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeGestures</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect gestures</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeLandmarks</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect landmarks</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeNotecards</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect notecards</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeObjects</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect objects</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeScripts</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect scripts</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeSounds</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect sounds</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeIncludeTextures</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk permission changes affect textures</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
+    <key>BulkChangeEveryoneCopy</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk changed objects can be copied by everyone</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>BulkChangeNextOwnerCopy</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk changed objects can be copied by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>BulkChangeNextOwnerModify</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk changed objects can be modified by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>BulkChangeNextOwnerTransfer</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk changed objects can be resold or given away by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>BulkChangeShareWithGroup</key>
+    <map>
+      <key>Comment</key>
+      <string>Bulk changed objects are shared with the currently active group</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ButtonFlashCount</key>
     <map>
       <key>Comment</key>
@@ -1016,6 +1214,17 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>CameraAngle</key>
+    <map>
+      <key>Comment</key>
+      <string>Camera field of view angle (Radians)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>F32</string>
+      <key>Value</key>
+      <real>1.047197551</real>
+    </map>
     <key>CameraOffset</key>
     <map>
       <key>Comment</key>
@@ -2404,6 +2613,17 @@
       <key>Value</key>
       <integer>175</integer>
     </map>
+    <key>EveryoneCopy</key>
+      <map>
+        <key>Comment</key>
+        <string>Everyone can copy the newly created objects</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>Boolean</string>
+        <key>Value</key>
+        <integer>0</integer>
+    </map>
     <key>FPSLogFrequency</key>
     <map>
       <key>Comment</key>
@@ -3100,7 +3320,24 @@
         <integer>0</integer>
       </array>
     </map>
-    <key>FloaterOpenObjectRect</key>
+  
+  <key>FloaterObjectIMInfo</key>
+  <map>
+    <key>Comment</key>
+    <string>Rectangle for floater object im info windows</string>
+    <key>Persist</key>
+    <integer>1</integer>
+    <key>Type</key>
+    <string>Rect</string>
+    <key>Value</key>
+    <array>
+      <integer>0</integer>
+      <integer>300</integer>
+      <integer>300</integer>
+      <integer>0</integer>
+    </array>
+  </map>
+  <key>FloaterOpenObjectRect</key>
     <map>
       <key>Comment</key>
       <string>Rectangle for Open Object window</string>
@@ -3132,6 +3369,22 @@
         <integer>0</integer>
       </array>
     </map>
+    <key>FloaterPermPrefsRect</key>
+    <map>
+      <key>Comment</key>
+      <string>Rectangle for initial permissions preferences</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Rect</string>
+      <key>Value</key>
+      <array>
+        <integer>200</integer>
+        <integer>250</integer>
+        <integer>250</integer>
+        <integer>200</integer>
+      </array>
+    </map>
     <key>FloaterRegionInfo</key>
     <map>
       <key>Comment</key>
@@ -3971,18 +4224,18 @@
       <key>Value</key>
       <real>0.0</real>
     </map>
-	<key>InstallLanguage</key>
-	<map>
-		<key>Comment</key>
-		<string>Language passed from installer (for UI)</string>
-		<key>Persist</key>
-		<integer>1</integer>
-		<key>Type</key>
-		<string>String</string>
-		<key>Value</key>
-		<string>default</string>
-	</map>
-	<key>InventoryAutoOpenDelay</key>
+    <key>InstallLanguage</key>
+    <map>
+      <key>Comment</key>
+      <string>Language passed from installer (for UI)</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>String</string>
+      <key>Value</key>
+      <string>default</string>
+    </map>
+    <key>InventoryAutoOpenDelay</key>
     <map>
       <key>Comment</key>
       <string>Seconds before automatically opening inventory when mouse is over inventory button when performing inventory drag and drop</string>
@@ -4966,6 +5219,39 @@
       <key>Value</key>
       <integer>1</integer>
     </map>
+    <key>NextOwnerCopy</key>
+    <map>
+      <key>Comment</key>
+      <string>Newly created objects can be copied by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>NextOwnerModify</key>
+    <map>
+      <key>Comment</key>
+      <string>Newly created objects can be modified by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
+    <key>NextOwnerTransfer</key>
+    <map>
+      <key>Comment</key>
+      <string>Newly created objects can be resold or given away by next owner</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>1</integer>
+    </map>
     <key>NewCacheLocation</key>
     <map>
       <key>Comment</key>
@@ -6858,6 +7144,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>ShareWithGroup</key>
+    <map>
+      <key>Comment</key>
+      <string>Newly created objects are shared with the currently active group</string>
+      <key>Persist</key>
+      <integer>1</integer>
+      <key>Type</key>
+      <string>Boolean</string>
+      <key>Value</key>
+      <integer>0</integer>
+    </map>
     <key>ShowActiveSpeakers</key>
     <map>
       <key>Comment</key>
@@ -7858,17 +8155,6 @@
         <integer>100</integer>
       </array>
     </map>
-    <key>ToolboxShowMore</key>
-    <map>
-      <key>Comment</key>
-      <string>Whether to show additional build tool controls</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
     <key>TrackFocusObject</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index ab2f06ef5308bb77bcf65c7f3b5c0e4c0d77baaa..7eca956f7dbc5bf0ba3daa36c83790e7d03ba927 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -5830,18 +5830,18 @@ bool LLAgent::teleportCore(bool is_local)
 		return false;
 	}
 
-	// Stop all animation before actual teleporting 
+	// Stop all animation before actual teleporting
 	LLVOAvatar* avatarp = gAgent.getAvatarObject();
-	if (avatarp)
+        if (avatarp)
 	{
-		for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin()
-			; anim_it != avatarp->mPlayingAnimations.end()
-			; anim_it++)
-		{
-			avatarp->stopMotion(anim_it->first);
-		}
-		avatarp->processAnimationStateChanges();
-	}
+		for ( LLVOAvatar::AnimIterator anim_it= avatarp->mPlayingAnimations.begin();
+		      anim_it != avatarp->mPlayingAnimations.end();
+		      ++anim_it)
+               {
+                       avatarp->stopMotion(anim_it->first);
+               }
+               avatarp->processAnimationStateChanges();
+       }
 
 	// Don't call LLFirstUse::useTeleport because we don't know
 	// yet if the teleport will succeed.  Look in 
@@ -6020,6 +6020,42 @@ void LLAgent::setTeleportState(ETeleportState state)
 	}
 }
 
+void LLAgent::stopCurrentAnimations()
+{
+	// This function stops all current overriding animations on this
+	// avatar, propagating this change back to the server.
+
+	LLVOAvatar* avatarp = gAgent.getAvatarObject();
+	if (avatarp)
+	{
+		for ( LLVOAvatar::AnimIterator anim_it =
+			      avatarp->mPlayingAnimations.begin();
+		      anim_it != avatarp->mPlayingAnimations.end();
+		      anim_it++)
+		{
+			if (anim_it->first ==
+			    ANIM_AGENT_SIT_GROUND_CONSTRAINED)
+			{
+				// don't cancel a ground-sit anim, as viewers
+				// use this animation's status in
+				// determining whether we're sitting. ick.
+			}
+			else
+			{
+				// stop this animation locally
+				avatarp->stopMotion(anim_it->first, TRUE);
+				// ...and tell the server to tell everyone.
+				sendAnimationRequest(anim_it->first, ANIM_REQUEST_STOP);
+			}
+		}
+
+		// re-assert at least the default standing animation, because
+		// viewers get confused by avs with no associated anims.
+		sendAnimationRequest(ANIM_AGENT_STAND,
+				     ANIM_REQUEST_START);
+	}
+}
+
 void LLAgent::fidget()
 {
 	if (!getAFK())
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index e8537f2fba0e6640718d716d631a74cf31d7b82a..f561f55e466c4f184136d034a857b20d36926b4f 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -372,6 +372,7 @@ class LLAgent : public LLObservable
 	BOOL canFly();
 
 	// Animation functions
+	void                    stopCurrentAnimations();
 	void			requestStopMotion( LLMotion* motion );
 	void			onAnimStop(const LLUUID& id);
 
diff --git a/indra/newview/llappviewerlinux.cpp b/indra/newview/llappviewerlinux.cpp
index 3f6a30cf329002fd013ddfeab545c8d2c6174790..2a5f0ea2707c9c1e25be0b7ff48aea85bdede2a6 100644
--- a/indra/newview/llappviewerlinux.cpp
+++ b/indra/newview/llappviewerlinux.cpp
@@ -425,8 +425,10 @@ gboolean viewer_app_api_GoSLURL(ViewerAppAPI *obj, gchar *slurl, gboolean **succ
 
 	llinfos << "Was asked to go to slurl: " << slurl << llendl;
 
-	const bool from_external_browser = true;
-	if (LLURLDispatcher::dispatch(slurl, from_external_browser))
+	std::string url = slurl;
+	LLWebBrowserCtrl* web = NULL;
+	const bool trusted_browser = false;
+	if (LLURLDispatcher::dispatch(url, web, trusted_browser))
 	{
 		// bring window to foreground, as it has just been "launched" from a URL
 		// todo: hmm, how to get there from here?
diff --git a/indra/newview/llappviewermacosx.cpp b/indra/newview/llappviewermacosx.cpp
index bad4746870764557fbb96be2baa379c56dff342b..81990b046431cf52bf48a6ea55db6b1a91a712f4 100644
--- a/indra/newview/llappviewermacosx.cpp
+++ b/indra/newview/llappviewermacosx.cpp
@@ -48,6 +48,9 @@
 #include "llurldispatcher.h"
 #include <Carbon/Carbon.h>
 #include "lldir.h"
+
+class LLWebBrowserCtrl;		// for LLURLDispatcher
+
 namespace 
 {
 	// The command line args stored.
@@ -260,8 +263,21 @@ OSErr AEGURLHandler(const AppleEvent *messagein, AppleEvent *reply, long refIn)
 	if(result == noErr)
 	{
 		std::string url = buffer;
-		const bool from_external_browser = true;
-		LLURLDispatcher::dispatch(url, from_external_browser);
+		
+		// Safari 3.2 silently mangles secondlife:///app/ URLs into
+		// secondlife:/app/ (only one leading slash).
+		// Fix them up to meet the URL specification. JC
+		const std::string prefix = "secondlife:/app/";
+		std::string test_prefix = url.substr(0, prefix.length());
+		LLStringUtil::toLower(test_prefix);
+		if (test_prefix == prefix)
+		{
+			url.replace(0, prefix.length(), "secondlife:///app/");
+		}
+		
+		LLWebBrowserCtrl* web = NULL;
+		const bool trusted_browser = false;
+		LLURLDispatcher::dispatch(url, web, trusted_browser);
 	}
 	
 	return(result);
diff --git a/indra/newview/llassetuploadresponders.cpp b/indra/newview/llassetuploadresponders.cpp
index 962066471f168a333751233ec4c92c4c9b65a870..d25f827a725d9a994f0e4b7424c76030a8ca43f0 100644
--- a/indra/newview/llassetuploadresponders.cpp
+++ b/indra/newview/llassetuploadresponders.cpp
@@ -48,12 +48,17 @@
 #include "llpreviewgesture.h"
 #include "llgesturemgr.h"
 #include "llscrolllistctrl.h"
+#include "llsdserialize.h"
 #include "lluploaddialog.h"
 #include "llviewerobject.h"
+#include "llviewercontrol.h"
 #include "llviewerobjectlist.h"
 #include "llviewermenufile.h"
 #include "llviewerwindow.h"
 
+// When uploading multiple files, don't display any of them when uploading more than this number.
+static const S32 FILE_COUNT_DISPLAY_THRESHOLD = 5;
+
 void dialog_refresh_all();
 
 LLAssetUploadResponder::LLAssetUploadResponder(const LLSD &post_data,
@@ -193,6 +198,10 @@ LLNewAgentInventoryResponder::LLNewAgentInventoryResponder(const LLSD& post_data
 void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
 {
 	lldebugs << "LLNewAgentInventoryResponder::result from capabilities" << llendl;
+	
+	//std::ostringstream llsdxml;
+	//LLSDSerialize::toXML(content, llsdxml);
+	//llinfos << "upload complete content:\n " << llsdxml.str() << llendl;
 
 	LLAssetType::EType asset_type = LLAssetType::lookup(mPostData["asset_type"].asString());
 	LLInventoryType::EType inventory_type = LLInventoryType::lookup(mPostData["inventory_type"].asString());
@@ -221,23 +230,39 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
 			<< content["new_asset"].asUUID() << " to inventory." << llendl;
 	if(mPostData["folder_id"].asUUID().notNull())
 	{
-		LLPermissions perm;
-		U32 next_owner_perm;
-		perm.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
-		if (mPostData["inventory_type"].asString() == "snapshot")
+		//std::ostringstream out;
+		//LLSDXMLFormatter *formatter = new LLSDXMLFormatter;
+		//formatter->format(mPostData, out, LLSDFormatter::OPTIONS_PRETTY);
+		//llinfos << "Post Data: " << out.str() << llendl;
+
+		U32 everyone_perms = PERM_NONE;
+		U32 group_perms = PERM_NONE;
+		U32 next_owner_perms = PERM_ALL;
+		if(content.has("new_next_owner_mask"))
 		{
-			next_owner_perm = PERM_ALL;
+			// This is a new sim that provides creation perms so use them.
+			// Do not assume we got the perms we asked for in mPostData 
+			// since the sim may not have granted them all.
+			everyone_perms = content["new_everyone_mask"].asInteger();
+			group_perms = content["new_group_mask"].asInteger();
+			next_owner_perms = content["new_next_owner_mask"].asInteger();
 		}
-		else
+		else 
 		{
-			next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+			// This old sim doesn't provide creation perms so use old assumption-based perms.
+			if(mPostData["inventory_type"].asString() != "snapshot")
+			{
+				next_owner_perms = PERM_MOVE | PERM_TRANSFER;
+			}
 		}
-		perm.initMasks(PERM_ALL, PERM_ALL, PERM_NONE, PERM_NONE, next_owner_perm);
+		LLPermissions new_perms;
+		new_perms.init(gAgent.getID(), gAgent.getID(), LLUUID::null, LLUUID::null);
+		new_perms.initMasks(PERM_ALL, PERM_ALL, everyone_perms, group_perms, next_owner_perms);
 		S32 creation_date_now = time_corrected();
 		LLPointer<LLViewerInventoryItem> item
 			= new LLViewerInventoryItem(content["new_inventory_item"].asUUID(),
 										mPostData["folder_id"].asUUID(),
-										perm,
+										new_perms,
 										content["new_asset"].asUUID(),
 										asset_type,
 										inventory_type,
@@ -255,10 +280,9 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
 		if(view)
 		{
 			LLUICtrl* focus_ctrl = gFocusMgr.getKeyboardFocus();
-
 			view->getPanel()->setSelection(content["new_inventory_item"].asUUID(), TAKE_FOCUS_NO);
-			if((LLAssetType::AT_TEXTURE == asset_type)
-				|| (LLAssetType::AT_SOUND == asset_type))
+			if((LLAssetType::AT_TEXTURE == asset_type || LLAssetType::AT_SOUND == asset_type)
+				&& LLFilePicker::instance().getFileCount() <= FILE_COUNT_DISPLAY_THRESHOLD)
 			{
 				view->getPanel()->openSelected();
 			}
@@ -289,8 +313,15 @@ void LLNewAgentInventoryResponder::uploadComplete(const LLSD& content)
 		LLStringUtil::stripNonprintable(asset_name);
 		LLStringUtil::trim(asset_name);
 
+		// Continuing the horrible hack above, we need to extract the originally requested permissions data, if any,
+		// and use them for each next file to be uploaded. Note the requested perms are not the same as the
+		// granted ones found in the given "content" structure but can still be found in mPostData. -MG
+		U32 everyone_perms   = mPostData.has("everyone_mask")   ? mPostData.get("everyone_mask"  ).asInteger() : PERM_NONE;
+		U32 group_perms      = mPostData.has("group_mask")      ? mPostData.get("group_mask"     ).asInteger() : PERM_NONE;
+		U32 next_owner_perms = mPostData.has("next_owner_mask") ? mPostData.get("next_owner_mask").asInteger() : PERM_NONE;
 		upload_new_resource(next_file, asset_name, asset_name,
-							0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
+							0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE,
+							next_owner_perms, group_perms, everyone_perms);
 	}
 }
 
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index 2844b888dc8e1d9586aa1b0ae7a28c675662fe31..c7a55c969acd6e4934e68a018d86cc7b821b688f 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -684,10 +684,11 @@ class LLChatHandler : public LLCommandHandler
 {
 public:
 	// not allowed from outside the app
-	LLChatHandler() : LLCommandHandler("chat", false) { }
+	LLChatHandler() : LLCommandHandler("chat", true) { }
 
     // Your code here
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		if (tokens.size() < 2) return false;
 		S32 channel = tokens[0].asInteger();
diff --git a/indra/newview/llcolorswatch.cpp b/indra/newview/llcolorswatch.cpp
index 57f65fed38f9eb1606767a7ac43d020d91bc1787..2732a17d3a8e7d007bf7a0bd828e1582e605dc7c 100644
--- a/indra/newview/llcolorswatch.cpp
+++ b/indra/newview/llcolorswatch.cpp
@@ -199,7 +199,6 @@ BOOL LLColorSwatchCtrl::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
-
 // assumes GL state is set for 2D
 void LLColorSwatchCtrl::draw()
 {
@@ -231,10 +230,23 @@ void LLColorSwatchCtrl::draw()
 	}
 	else
 	{
-		// Draw grey and an X
-		gl_rect_2d(interior, LLColor4::grey, TRUE);
-
-		gl_draw_x(interior, LLColor4::black);
+		if (!mFallbackImageName.empty())
+		{
+			LLPointer<LLViewerImage> fallback_image = gImageList.getImageFromFile(mFallbackImageName);
+			if( fallback_image->getComponents() == 4 )
+			{	
+				gl_rect_2d_checkerboard( interior );
+			}	
+			gl_draw_scaled_image( interior.mLeft, interior.mBottom, interior.getWidth(), interior.getHeight(), fallback_image);
+			fallback_image->addTextureStats( (F32)(interior.getWidth() * interior.getHeight()) );
+		}
+		else
+		{
+			// Draw grey and an X
+			gl_rect_2d(interior, LLColor4::grey, TRUE);
+			
+			gl_draw_x(interior, LLColor4::black);
+		}
 	}
 
 	LLUICtrl::draw();
diff --git a/indra/newview/llcolorswatch.h b/indra/newview/llcolorswatch.h
index 4b69df8dbb1a260730688317ef9294f91a46f106..4f5360b25ce5dcadde4685d60f8da12fe8ea680b 100644
--- a/indra/newview/llcolorswatch.h
+++ b/indra/newview/llcolorswatch.h
@@ -77,6 +77,7 @@ class LLColorSwatchCtrl
 	void			setCanApplyImmediately(BOOL apply) { mCanApplyImmediately = apply; }
 	void			setOnCancelCallback(LLUICtrlCallback cb) { mOnCancelCallback = cb; }
 	void			setOnSelectCallback(LLUICtrlCallback cb) { mOnSelectCallback = cb; }
+	void			setFallbackImageName(const std::string& name) { mFallbackImageName = name; }
 
 	void			showPicker(BOOL take_focus);
 
@@ -104,6 +105,7 @@ class LLColorSwatchCtrl
 	LLUICtrlCallback mOnSelectCallback;
 
 	LLPointer<LLUIImage> mAlphaGradientImage;
+	std::string		mFallbackImageName;
 };
 
 #endif  // LL_LLBUTTON_H
diff --git a/indra/newview/llcommandhandler.cpp b/indra/newview/llcommandhandler.cpp
index 8b86b1be5d0d64e3080ab57fb6f471067642eac3..cfe91bc5b55e9a4719442a838e70ef40e778c1ea 100644
--- a/indra/newview/llcommandhandler.cpp
+++ b/indra/newview/llcommandhandler.cpp
@@ -42,7 +42,7 @@
 //---------------------------------------------------------------------------
 struct LLCommandHandlerInfo
 {
-	bool mAllowFromExternalBrowser;
+	bool mRequireTrustedBrowser;
 	LLCommandHandler* mHandler;	// safe, all of these are static objects
 };
 
@@ -50,8 +50,12 @@ class LLCommandHandlerRegistry
 {
 public:
 	static LLCommandHandlerRegistry& instance();
-	void add(const char* cmd, bool allow_from_external_browser, LLCommandHandler* handler);
-	bool dispatch(const std::string& cmd, bool from_external_browser, const LLSD& params, const LLSD& queryMap);
+	void add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler);
+	bool dispatch(const std::string& cmd,
+				  const LLSD& params,
+				  const LLSD& query_map,
+				  LLWebBrowserCtrl* web,
+				  bool trusted_browser);
 
 private:
 	std::map<std::string, LLCommandHandlerInfo> mMap;
@@ -67,40 +71,44 @@ LLCommandHandlerRegistry& LLCommandHandlerRegistry::instance()
 	return instance;
 }
 
-void LLCommandHandlerRegistry::add(const char* cmd, bool allow_from_external_browser, LLCommandHandler* handler)
+void LLCommandHandlerRegistry::add(const char* cmd, bool require_trusted_browser, LLCommandHandler* handler)
 {
 	LLCommandHandlerInfo info;
-	info.mAllowFromExternalBrowser = allow_from_external_browser;
+	info.mRequireTrustedBrowser = require_trusted_browser;
 	info.mHandler = handler;
 
 	mMap[cmd] = info;
 }
 
 bool LLCommandHandlerRegistry::dispatch(const std::string& cmd,
-										bool from_external_browser,
 										const LLSD& params,
-										const LLSD& queryMap)
+										const LLSD& query_map,
+										LLWebBrowserCtrl* web,
+										bool trusted_browser)
 {
 	std::map<std::string, LLCommandHandlerInfo>::iterator it = mMap.find(cmd);
 	if (it == mMap.end()) return false;
 	const LLCommandHandlerInfo& info = it->second;
-	if (from_external_browser && !info.mAllowFromExternalBrowser)
+	if (!trusted_browser && info.mRequireTrustedBrowser)
 	{
 		// block request from external browser, but report as
 		// "handled" because it was well formatted.
+		LL_WARNS_ONCE("SLURL") << "Blocked SLURL command from untrusted browser" << LL_ENDL;
 		return true;
 	}
 	if (!info.mHandler) return false;
-	return info.mHandler->handle(params, queryMap);
+	return info.mHandler->handle(params, query_map, web);
 }
 
 //---------------------------------------------------------------------------
 // Automatic registration of commands, runs before main()
 //---------------------------------------------------------------------------
 
-LLCommandHandler::LLCommandHandler(const char* cmd, bool allow_from_external_browser)
+LLCommandHandler::LLCommandHandler(const char* cmd,
+								   bool require_trusted_browser)
 {
-	LLCommandHandlerRegistry::instance().add(cmd, allow_from_external_browser, this);
+	LLCommandHandlerRegistry::instance().add(
+			cmd, require_trusted_browser, this);
 }
 
 LLCommandHandler::~LLCommandHandler()
@@ -115,9 +123,11 @@ LLCommandHandler::~LLCommandHandler()
 
 // static
 bool LLCommandDispatcher::dispatch(const std::string& cmd,
-								   bool from_external_browser,
-								   const LLSD& params, const LLSD& queryMap)
+								   const LLSD& params,
+								   const LLSD& query_map,
+								   LLWebBrowserCtrl* web,
+								   bool trusted_browser)
 {
 	return LLCommandHandlerRegistry::instance().dispatch(
-		cmd, from_external_browser, params, queryMap);
+		cmd, params, query_map, web, trusted_browser);
 }
diff --git a/indra/newview/llcommandhandler.h b/indra/newview/llcommandhandler.h
index 8fe40a9a022725d7f7b99537411dee1771619eac..bb77b5a5423fa62cbbf75c78ce91f4371693c93b 100644
--- a/indra/newview/llcommandhandler.h
+++ b/indra/newview/llcommandhandler.h
@@ -33,34 +33,38 @@
 #ifndef LLCOMMANDHANDLER_H
 #define LLCOMMANDHANDLER_H
 
-/* To implement a command "foo" that takes one parameter,
-   a UUID, do this:
+/* Example:  secondlife:///app/foo/<uuid>
+   Command "foo" that takes one parameter, a UUID.
 
 class LLFooHandler : public LLCommandHandler
 {
 public:
     // Inform the system you handle commands starting
-	// with "foo" and they are not allowed from external web
-	// browser links.
-	LLFooHandler() : LLCommandHandler("foo", false) { }
+	// with "foo" and they are only allowed from
+	// "trusted" (pointed at Linden content) browsers
+	LLFooHandler() : LLCommandHandler("foo", true) { }
 
     // Your code here
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		if (tokens.size() < 1) return false;
 		LLUUID id( tokens[0] );
-		return doFoo(id);
+		return do_foo(id);
 	}
 };
 
-// Creating the object registers with the dispatcher.
+// *NOTE: Creating the object registers with the dispatcher.
 LLFooHandler gFooHandler;
+
 */
 
+class LLWebBrowserCtrl;
+
 class LLCommandHandler
 {
 public:
-	LLCommandHandler(const char* command, bool allow_from_external_browser);
+	LLCommandHandler(const char* command, bool allow_from_untrusted_browser);
 		// Automatically registers object to get called when 
 		// command is executed.  All commands can be processed
 		// in links from LLWebBrowserCtrl, but some (like teleport)
@@ -69,9 +73,12 @@ class LLCommandHandler
 	virtual ~LLCommandHandler();
 
 	virtual bool handle(const LLSD& params,
-						const LLSD& queryMap) = 0;
-		// Execute the command with a provided (possibly empty)
-		// list of parameters.
+						const LLSD& query_map,
+						LLWebBrowserCtrl* web) = 0;
+		// For URL secondlife:///app/foo/bar/baz?cat=1&dog=2
+		// @params - array of "bar", "baz", possibly empty
+		// @query_map - map of "cat" -> 1, "dog" -> 2, possibly empty
+		// @web - pointer to web browser control, possibly NULL
 		// Return true if you did something, false if the parameters
 		// are invalid or on error.
 };
@@ -81,9 +88,10 @@ class LLCommandDispatcher
 {
 public:
 	static bool dispatch(const std::string& cmd,
-						 bool from_external_browser,
 						 const LLSD& params,
-						 const LLSD& queryMap);
+						 const LLSD& query_map,
+						 LLWebBrowserCtrl* web,
+						 bool trusted_browser);
 		// Execute a command registered via the above mechanism,
 		// passing string parameters.
 		// Returns true if command was found and executed correctly.
diff --git a/indra/newview/lldynamictexture.h b/indra/newview/lldynamictexture.h
index 2e7ba1d42236685066bb4d2c977e870afd421c51..e5bc3d31705931b7217ee1b495cb80032570fdd7 100644
--- a/indra/newview/lldynamictexture.h
+++ b/indra/newview/lldynamictexture.h
@@ -33,7 +33,6 @@
 #define LL_LLDYNAMICTEXTURE_H
 
 #include "llgl.h"
-#include "llcamera.h"
 #include "llcoord.h"
 #include "llimagegl.h"
 
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 7ac50d76100b0659f2d31a6d43cff0e3e9ecd057..91f88277a44cff4926c090d2da81d6164036ae82 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -115,7 +115,7 @@ const std::string LLFilePicker::getFirstFile()
 
 const std::string LLFilePicker::getNextFile()
 {
-	if (mCurrentFile >= (S32)mFiles.size())
+	if (mCurrentFile >= getFileCount())
 	{
 		mLocked = FALSE;
 		return std::string();
@@ -128,7 +128,7 @@ const std::string LLFilePicker::getNextFile()
 
 const std::string LLFilePicker::getCurFile()
 {
-	if (mCurrentFile >= (S32)mFiles.size())
+	if (mCurrentFile >= getFileCount())
 	{
 		mLocked = FALSE;
 		return std::string();
@@ -824,7 +824,7 @@ BOOL LLFilePicker::getOpenFile(ELoadFilter filter)
 	send_agent_resume();
 	if (error == noErr)
 	{
-		if (mFiles.size())
+		if (getFileCount())
 			success = true;
 	}
 
@@ -853,9 +853,9 @@ BOOL LLFilePicker::getMultipleOpenFiles(ELoadFilter filter)
 	send_agent_resume();
 	if (error == noErr)
 	{
-		if (mFiles.size())
+		if (getFileCount())
 			success = true;
-		if (mFiles.size() > 1)
+		if (getFileCount() > 1)
 			mLocked = TRUE;
 	}
 
@@ -883,7 +883,7 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 	send_agent_resume();
 	if (error == noErr)
 	{
-		if (mFiles.size())
+		if (getFileCount())
 			success = true;
 	}
 
@@ -1147,7 +1147,7 @@ BOOL LLFilePicker::getSaveFile( ESaveFilter filter, const std::string& filename
 		gtk_widget_show_all(GTK_WIDGET(picker));
 		gtk_main();
 
-		rtn = (mFiles.size() == 1);
+		rtn = (getFileCount() == 1);
 	}
 
 	gViewerWindow->mWindow->afterDialog();
@@ -1191,7 +1191,7 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter )
 		gtk_widget_show_all(GTK_WIDGET(picker));
 		gtk_main();
 
-		rtn = (mFiles.size() == 1);
+		rtn = (getFileCount() == 1);
 	}
 
 	gViewerWindow->mWindow->afterDialog();
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 83a935752342508d4e65562667e155e209aa2d28..4c9b9d590de6c5a92d6fb98d18b202b87617357e 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -130,6 +130,11 @@ class LLFilePicker
 	// doing any incrementing.
 	const std::string getCurFile();
 
+	// Returns the index of the current file.
+	S32 getCurFileNum() const { return mCurrentFile; }
+
+	S32 getFileCount() const { return (S32)mFiles.size(); }
+
 	// See llvfs/lldir.h : getBaseFileName and getDirName to extract base or directory names
 	
 	// clear any lists of buffers or whatever, and make sure the file
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index a6863531561cbc6ecb109c2bc6740d93e5ed21e3..21535895bddf59ff56d9905368ebd7753d01c430 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -116,7 +116,7 @@ LLFloaterAbout::LLFloaterAbout()
 				   __DATE__, __TIME__,
 				   gSavedSettings.getString("VersionChannelName").c_str());
 	support_widget->appendColoredText(version, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
-	support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), FALSE, FALSE, &viewer_link_style);
+	support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, viewer_link_style);
 
 	std::string support;
 	support.append("\n\n");
@@ -152,7 +152,7 @@ LLFloaterAbout::LLFloaterAbout()
 		support.append("\n");
 
 		support_widget->appendColoredText(support, FALSE, FALSE, gColors.getColor("TextFgReadOnlyColor"));
-		support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), FALSE, FALSE, &server_link_style);
+		support_widget->appendStyledText(LLTrans::getString("ReleaseNotes"), false, false, server_link_style);
 
 		support = "\n\n";
 	}
diff --git a/indra/newview/llfloateranimpreview.cpp b/indra/newview/llfloateranimpreview.cpp
index 6c42a71fe64780a65d99a279619a3cc860c15567..c7e35bcfb55dc7cbc8354bc907eda36e1323367a 100644
--- a/indra/newview/llfloateranimpreview.cpp
+++ b/indra/newview/llfloateranimpreview.cpp
@@ -52,6 +52,7 @@
 #include "llfocusmgr.h"
 #include "llkeyframemotion.h"
 #include "lllineeditor.h"
+#include "llfloaterperms.h"
 #include "llsliderctrl.h"
 #include "llspinctrl.h"
 #include "lltextbox.h"
@@ -994,7 +995,7 @@ void LLFloaterAnimPreview::onBtnOK(void* userdata)
 									0,
 									LLAssetType::AT_NONE,
 									LLInventoryType::IT_ANIMATION,
-									PERM_NONE,
+									LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms(),
 									name);
 			}
 			else
diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..b07fa025d142eafec7674eb48b63e16838e94111
--- /dev/null
+++ b/indra/newview/llfloaterbulkpermission.cpp
@@ -0,0 +1,366 @@
+/** 
+ * @file llfloaterbulkpermissions.cpp
+ * @author Michelle2 Zenovka
+ * @brief A floater which allows task inventory item's properties to be changed on mass.
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+
+#include "llviewerprecompiledheaders.h"
+#include "llfloaterbulkpermission.h"
+#include "llfloaterperms.h" // for utilities
+#include "llagent.h"
+#include "llchat.h"
+#include "llviewerwindow.h"
+#include "llviewerobject.h"
+#include "llviewerobjectlist.h"
+#include "llviewerregion.h"
+#include "lscript_rt_interface.h"
+#include "llviewercontrol.h"
+#include "llviewerobject.h"
+#include "llviewerregion.h"
+#include "llresmgr.h"
+#include "llbutton.h"
+#include "lldir.h"
+#include "llfloaterchat.h"
+#include "llviewerstats.h"
+#include "lluictrlfactory.h"
+#include "llselectmgr.h"
+
+#include "roles_constants.h" // for GP_OBJECT_MANIPULATE
+
+
+LLFloaterBulkPermission::LLFloaterBulkPermission(const LLSD& seed) : mDone(FALSE)
+{
+	mID.generate();
+	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_bulk_perms.xml");
+	childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("BulkChangeNextOwnerCopy"));
+	childSetAction("apply", onApplyBtn, this);
+	childSetAction("close", onCloseBtn, this);
+	childSetAction("check_all", onCheckAll, this);
+	childSetAction("check_none", onUncheckAll, this);
+	childSetCommitCallback("next_owner_copy", &onCommitCopy, this);
+}
+
+void LLFloaterBulkPermission::doApply()
+{
+	// Inspects a stream of selected object contents and adds modifiable ones to the given array.
+	class ModifiableGatherer : public LLSelectedNodeFunctor
+	{
+	public:
+		ModifiableGatherer(LLDynamicArray<LLUUID>& q) : mQueue(q) {}
+		virtual bool apply(LLSelectNode* node)
+		{
+			if( node->allowOperationOnNode(PERM_MODIFY, GP_OBJECT_MANIPULATE) )
+			{
+				mQueue.put(node->getObject()->getID());
+			}
+			return true;
+		}
+	private:
+		LLDynamicArray<LLUUID>& mQueue;
+	};
+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
+	list->deleteAllItems();
+	ModifiableGatherer gatherer(mObjectIDs);
+	LLSelectMgr::getInstance()->getSelection()->applyToNodes(&gatherer);
+	if(mObjectIDs.empty())
+	{
+		list->addCommentText(getString("nothing_to_modify_text"));
+	}
+	else
+	{
+		mDone = FALSE;
+		if (!start())
+		{
+			llwarns << "Unexpected bulk permission change failure." << llendl;
+		}
+	}
+}
+
+
+// This is the callback method for the viewer object currently being
+// worked on.
+// NOT static, virtual!
+void LLFloaterBulkPermission::inventoryChanged(LLViewerObject* viewer_object,
+											 InventoryObjectList* inv,
+											 S32,
+											 void* q_id)
+{
+	//llinfos << "changed object: " << viewer_object->getID() << llendl;
+
+	//Remove this listener from the object since its
+	//listener callback is now being executed.
+	
+	//We remove the listener here because the function
+	//removeVOInventoryListener removes the listener from a ViewerObject
+	//which it internally stores.
+	
+	//If we call this further down in the function, calls to handleInventory
+	//and nextObject may update the interally stored viewer object causing
+	//the removal of the incorrect listener from an incorrect object.
+	
+	//Fixes SL-6119:Recompile scripts fails to complete
+	removeVOInventoryListener();
+
+	if (viewer_object && inv && (viewer_object->getID() == mCurrentObjectID) )
+	{
+		handleInventory(viewer_object, inv);
+	}
+	else
+	{
+		// something went wrong...
+		// note that we're not working on this one, and move onto the
+		// next object in the list.
+		llwarns << "No inventory for " << mCurrentObjectID << llendl;
+		nextObject();
+	}
+}
+
+void LLFloaterBulkPermission::onApplyBtn(void* user_data)
+{
+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data;
+	self->doApply();
+}
+
+void LLFloaterBulkPermission::onCloseBtn(void* user_data)
+{
+	LLFloaterBulkPermission* self = (LLFloaterBulkPermission*)user_data;
+	self->onClose(false);
+}
+
+//static 
+void LLFloaterBulkPermission::onCommitCopy(LLUICtrl* ctrl, void* data)
+{
+	// Implements fair use
+	BOOL copyable = gSavedSettings.getBOOL("BulkChangeNextOwnerCopy");
+	if(!copyable)
+	{
+		gSavedSettings.setBOOL("BulkChangeNextOwnerTransfer", TRUE);
+	}
+	LLCheckBoxCtrl* xfer = static_cast<LLFloaterPerms*>(data)->getChild<LLCheckBoxCtrl>("next_owner_transfer");
+	xfer->setEnabled(copyable);
+}
+
+BOOL LLFloaterBulkPermission::start()
+{
+	// note: number of top-level objects to modify is mObjectIDs.count().
+	getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("start_text"));
+	return nextObject();
+}
+
+// Go to the next object and start if found. Returns false if no objects left, true otherwise.
+BOOL LLFloaterBulkPermission::nextObject()
+{
+	S32 count;
+	BOOL successful_start = FALSE;
+	do
+	{
+		count = mObjectIDs.count();
+		//llinfos << "Objects left to process = " << count << llendl;
+		mCurrentObjectID.setNull();
+		if(count > 0)
+		{
+			successful_start = popNext();
+			//llinfos << (successful_start ? "successful" : "unsuccessful") << llendl; 
+		}
+	} while((mObjectIDs.count() > 0) && !successful_start);
+
+	if(isDone() && !mDone)
+	{
+		getChild<LLScrollListCtrl>("queue output")->addCommentText(getString("done_text"));
+		mDone = TRUE;
+	}
+	return successful_start;
+}
+
+// Pop the top object off of the queue.
+// Return TRUE if the queue has started, otherwise FALSE.
+BOOL LLFloaterBulkPermission::popNext()
+{
+	// get the head element from the container, and attempt to get its inventory.
+	BOOL rv = FALSE;
+	S32 count = mObjectIDs.count();
+	if(mCurrentObjectID.isNull() && (count > 0))
+	{
+		mCurrentObjectID = mObjectIDs.get(0);
+		//llinfos << "mCurrentID: " << mCurrentObjectID << llendl;
+		mObjectIDs.remove(0);
+		LLViewerObject* obj = gObjectList.findObject(mCurrentObjectID);
+		if(obj)
+		{
+			//llinfos << "requesting inv for " << mCurrentObjectID << llendl;
+			LLUUID* id = new LLUUID(mID);
+			registerVOInventoryListener(obj,id);
+			requestVOInventory();
+			rv = TRUE;
+		}
+		else
+		{
+			llinfos<<"NULL LLViewerObject" <<llendl;
+		}
+	}
+
+	return rv;
+}
+
+
+void LLFloaterBulkPermission::doCheckUncheckAll(BOOL check)
+{
+	gSavedSettings.setBOOL("BulkChangeIncludeAnimations", check);
+	gSavedSettings.setBOOL("BulkChangeIncludeBodyParts" , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeClothing"  , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeGestures"  , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeLandmarks" , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeNotecards" , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeObjects"   , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeScripts"   , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeSounds"    , check);
+	gSavedSettings.setBOOL("BulkChangeIncludeTextures"  , check);
+}
+
+
+void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, InventoryObjectList* inv)
+{
+	LLScrollListCtrl* list = getChild<LLScrollListCtrl>("queue output");
+
+	InventoryObjectList::const_iterator it = inv->begin();
+	InventoryObjectList::const_iterator end = inv->end();
+	for ( ; it != end; ++it)
+	{
+		LLAssetType::EType asstype = (*it)->getType();
+		if(
+			( asstype == LLAssetType::AT_ANIMATION && gSavedSettings.getBOOL("BulkChangeIncludeAnimations")) ||
+			( asstype == LLAssetType::AT_BODYPART  && gSavedSettings.getBOOL("BulkChangeIncludeBodyParts" )) ||
+			( asstype == LLAssetType::AT_CLOTHING  && gSavedSettings.getBOOL("BulkChangeIncludeClothing"  )) ||
+			( asstype == LLAssetType::AT_GESTURE   && gSavedSettings.getBOOL("BulkChangeIncludeGestures"  )) ||
+			( asstype == LLAssetType::AT_LANDMARK  && gSavedSettings.getBOOL("BulkChangeIncludeLandmarks" )) ||
+			( asstype == LLAssetType::AT_NOTECARD  && gSavedSettings.getBOOL("BulkChangeIncludeNotecards" )) ||
+			( asstype == LLAssetType::AT_OBJECT    && gSavedSettings.getBOOL("BulkChangeIncludeObjects"   )) ||
+			( asstype == LLAssetType::AT_LSL_TEXT  && gSavedSettings.getBOOL("BulkChangeIncludeScripts"   )) ||
+			( asstype == LLAssetType::AT_SOUND     && gSavedSettings.getBOOL("BulkChangeIncludeSounds"    )) ||
+			( asstype == LLAssetType::AT_TEXTURE   && gSavedSettings.getBOOL("BulkChangeIncludeTextures"  )))
+		{
+			LLViewerObject* object = gObjectList.findObject(viewer_obj->getID());
+
+			if (object)
+			{
+				LLInventoryItem* item = (LLInventoryItem*)((LLInventoryObject*)(*it));
+				LLViewerInventoryItem* new_item = (LLViewerInventoryItem*)item;
+				LLPermissions perm(new_item->getPermissions());
+
+				// chomp the inventory name so it fits in the scroll window nicely
+				// and the user can see the [OK]
+				std::string invname;
+				invname=item->getName().substr(0,item->getName().size() < 30 ? item->getName().size() : 30 );
+				
+				LLUIString status_text = getString("status_text");
+				status_text.setArg("[NAME]", invname.c_str());
+				// Check whether we appear to have the appropriate permissions to change permission on this item.
+				// Although the server will disallow any forbidden changes, it is a good idea to guess correctly
+				// so that we can warn the user. The risk of getting this check wrong is therefore the possibility
+				// of incorrectly choosing to not attempt to make a valid change.
+				//
+				// Trouble is this is extremely difficult to do and even when we know the results
+				// it is difficult to design the best messaging. Therefore in this initial implementation
+				// we'll always try to set the requested permissions and consider all cases successful
+				// and perhaps later try to implement a smarter, friendlier solution. -MG
+				if(true
+					//gAgent.allowOperation(PERM_MODIFY, perm, GP_OBJECT_MANIPULATE) // for group and everyone masks
+					//|| something else // for next owner perms
+					)
+				{
+					perm.setMaskNext(LLFloaterPerms::getNextOwnerPerms("BulkChange"));
+					perm.setMaskEveryone(LLFloaterPerms::getEveryonePerms("BulkChange"));
+					perm.setMaskGroup(LLFloaterPerms::getGroupPerms("BulkChange"));
+					new_item->setPermissions(perm); // here's the beef
+					updateInventory(object,new_item,TASK_INVENTORY_ITEM_KEY,FALSE);
+					//status_text.setArg("[STATUS]", getString("status_ok_text"));
+					status_text.setArg("[STATUS]", "");
+				}
+				else
+				{
+					//status_text.setArg("[STATUS]", getString("status_bad_text"));
+					status_text.setArg("[STATUS]", "");
+				}
+				
+				list->addCommentText(status_text.getString());
+
+				//TODO if we are an object inside an object we should check a recuse flag and if set
+				//open the inventory of the object and recurse - Michelle2 Zenovka
+
+				//	if(recurse &&  ( (*it)->getType() == LLAssetType::AT_OBJECT && processObject))
+				//	{
+				//		I think we need to get the UUID of the object inside the inventory
+				//		call item->fetchFromServer();
+				//		we need a call back to say item has arrived *sigh*
+				//		we then need to do something like
+				//		LLUUID* id = new LLUUID(mID);
+				//		registerVOInventoryListener(obj,id);
+				//		requestVOInventory();
+				//	}
+			}
+		}
+	}
+
+	nextObject();
+}
+
+
+// Avoid inventory callbacks etc by just fire and forgetting the message with the permissions update
+// we could do this via LLViewerObject::updateInventory but that uses inventory call backs and buggers
+// us up and we would have a dodgy item iterator
+
+void LLFloaterBulkPermission::updateInventory(LLViewerObject* object, LLViewerInventoryItem* item, U8 key, bool is_new)
+{
+	LLMemType mt(LLMemType::MTYPE_OBJECT);
+	
+	// This slices the object into what we're concerned about on the viewer. 
+	// The simulator will take the permissions and transfer ownership.
+	LLPointer<LLViewerInventoryItem> task_item =
+		new LLViewerInventoryItem(item->getUUID(), mID, item->getPermissions(),
+								  item->getAssetUUID(), item->getType(),
+								  item->getInventoryType(),
+								  item->getName(), item->getDescription(),
+								  item->getSaleInfo(),
+								  item->getFlags(),
+								  item->getCreationDate());
+	task_item->setTransactionID(item->getTransactionID());
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_UpdateTaskInventory);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->nextBlockFast(_PREHASH_UpdateData);
+	msg->addU32Fast(_PREHASH_LocalID, object->mLocalID);
+	msg->addU8Fast(_PREHASH_Key, key);
+	msg->nextBlockFast(_PREHASH_InventoryData);
+	task_item->packMessage(msg);
+	msg->sendReliable(object->getRegion()->getHost());
+}
+
diff --git a/indra/newview/llfloaterbulkpermission.h b/indra/newview/llfloaterbulkpermission.h
new file mode 100644
index 0000000000000000000000000000000000000000..814c472fa35a1fb5719126d6ce10d585250b6654
--- /dev/null
+++ b/indra/newview/llfloaterbulkpermission.h
@@ -0,0 +1,107 @@
+/** 
+ * @file llfloaterbulkpermissions.h
+ * @brief Allow multiple task inventory properties to be set in one go.
+ * @author Michelle2 Zenovka
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLBULKPERMISSION_H
+#define LL_LLBULKPERMISSION_H
+
+#include "lldarray.h"
+#include "llinventory.h"
+#include "llviewerobject.h"
+#include "llvoinventorylistener.h"
+#include "llmap.h"
+#include "lluuid.h"
+
+#include "llfloater.h"
+#include "llscrolllistctrl.h"
+
+#include "llviewerinventory.h"
+
+class LLFloaterBulkPermission : public LLFloater, public LLVOInventoryListener, public LLFloaterSingleton<LLFloaterBulkPermission>
+{
+public:
+
+	LLFloaterBulkPermission(const LLSD& seed);
+
+private:
+	virtual ~LLFloaterBulkPermission() {}
+
+	BOOL start(); // returns TRUE if the queue has started, otherwise FALSE.
+	BOOL nextObject();
+	BOOL popNext();
+
+	// This is the callback method for the viewer object currently
+	// being worked on.
+	/*virtual*/ void inventoryChanged(LLViewerObject* obj,
+								 InventoryObjectList* inv,
+								 S32 serial_num,
+								 void* queue);
+	
+	// This is called by inventoryChanged
+	void handleInventory(LLViewerObject* viewer_obj,
+								InventoryObjectList* inv);
+
+
+	void updateInventory(LLViewerObject* object,
+								LLViewerInventoryItem* item,
+								U8 key,
+								bool is_new);
+
+	static void onCloseBtn(void* user_data);
+	static void onApplyBtn(void* user_data);
+	static void onCommitCopy(LLUICtrl* ctrl, void* data);
+	static void onCheckAll(  void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(TRUE); }
+	static void onUncheckAll(void* user_data) { ((LLFloaterBulkPermission*)user_data)->doCheckUncheckAll(FALSE); }
+	
+	// returns true if this is done
+	BOOL isDone() const { return (mCurrentObjectID.isNull() || (mObjectIDs.count() == 0)); }
+
+	//Read the settings and Apply the permissions
+	void doApply();
+	void doCheckUncheckAll(BOOL check);
+
+private:
+	// UI
+	LLScrollListCtrl* mMessages;
+	LLButton* mCloseBtn;
+
+	// Object Queue
+	LLDynamicArray<LLUUID> mObjectIDs;
+	LLUUID mCurrentObjectID;
+	BOOL mDone;
+
+	LLUUID mID;
+
+	const char* mStartString;
+};
+
+#endif
+
diff --git a/indra/newview/llfloaterbuyland.cpp b/indra/newview/llfloaterbuyland.cpp
index b08dea248fa1b0b72d363c5455d097c5ef4db379..7aa6af2fea0a0b91d1ae61f69c74c38478cb2738 100644
--- a/indra/newview/llfloaterbuyland.cpp
+++ b/indra/newview/llfloaterbuyland.cpp
@@ -1020,14 +1020,24 @@ void LLFloaterBuyLandUI::refreshUI()
 		
 			childSetText("info_size", getString("meters_supports_object", string_args));
 
+			F32 cost_per_sqm = 0.0f;
+			if (mParcelActualArea > 0)
+			{
+				cost_per_sqm = (F32)mParcelPrice / (F32)mParcelActualArea;
+			}
 
-			childSetText("info_price",
-				llformat(
-					"L$ %d%s",
-					mParcelPrice,
-					mParcelSoldWithObjects
-						? "\nsold with objects"
-						: ""));
+			LLStringUtil::format_map_t info_price_args;
+			info_price_args["[PRICE]"] = llformat("%d", mParcelPrice);
+			info_price_args["[PRICE_PER_SQM]"] = llformat("%.1f", cost_per_sqm);
+			if (mParcelSoldWithObjects)
+			{
+				info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_with_objects");
+			}
+			else
+			{
+				info_price_args["[SOLD_WITH_OBJECTS]"] = getString("sold_without_objects");
+			}
+			childSetText("info_price", getString("info_price_string", info_price_args));
 			childSetVisible("info_price", mParcelIsForSale);
 		}
 		else
diff --git a/indra/newview/llfloaterchat.cpp b/indra/newview/llfloaterchat.cpp
index ba02ccc320dde96f47bd53a2cd32f804d2f767bd..cf1dfa42e03a8c059920e7456b9c4ed1a421f442 100644
--- a/indra/newview/llfloaterchat.cpp
+++ b/indra/newview/llfloaterchat.cpp
@@ -189,7 +189,7 @@ void LLFloaterChat::updateConsoleVisibility()
 							|| (getHost() && getHost()->isMinimized() ));	// are we hosted in a minimized floater?
 }
 
-void add_timestamped_line(LLViewerTextEditor* edit, const LLChat &chat, const LLColor4& color)
+void add_timestamped_line(LLViewerTextEditor* edit, LLChat chat, const LLColor4& color)
 {
 	std::string line = chat.mText;
 	bool prepend_newline = true;
@@ -199,16 +199,22 @@ void add_timestamped_line(LLViewerTextEditor* edit, const LLChat &chat, const LL
 		prepend_newline = false;
 	}
 
-	// If the msg is not from an agent (not yourself though),
+	// If the msg is from an agent (not yourself though),
 	// extract out the sender name and replace it with the hotlinked name.
 	if (chat.mSourceType == CHAT_SOURCE_AGENT &&
-		chat.mFromID != LLUUID::null &&
-		(line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
+		chat.mFromID != LLUUID::null)
+	{
+		chat.mURL = llformat("secondlife:///app/agent/%s/about",chat.mFromID.asString().c_str());
+	}
+
+	// If the chat line has an associated url, link it up to the name.
+	if (!chat.mURL.empty()
+		&& (line.length() > chat.mFromName.length() && line.find(chat.mFromName,0) == 0))
 	{
 		std::string start_line = line.substr(0, chat.mFromName.length() + 1);
 		line = line.substr(chat.mFromName.length() + 1);
-		const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID);
-		edit->appendStyledText(start_line, false, prepend_newline, &sourceStyle);
+		const LLStyleSP &sourceStyle = LLStyleMap::instance().lookup(chat.mFromID,chat.mURL);
+		edit->appendStyledText(start_line, false, prepend_newline, sourceStyle);
 		prepend_newline = false;
 	}
 	edit->appendColoredText(line, false, prepend_newline, color);
diff --git a/indra/newview/llfloaterevent.cpp b/indra/newview/llfloaterevent.cpp
index 3579b2a058603af1021691b4862b002c6c5ca0bf..523ce6cb7325ed0df239f490d78cd8a7b25b6bb6 100644
--- a/indra/newview/llfloaterevent.cpp
+++ b/indra/newview/llfloaterevent.cpp
@@ -54,9 +54,10 @@ LLMap< U32, LLFloaterEventInfo* > gEventInfoInstances;
 class LLEventHandler : public LLCommandHandler
 {
 public:
-	// don't allow from external browsers
-	LLEventHandler() : LLCommandHandler("event", false) { }
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	// requires trusted browser to trigger
+	LLEventHandler() : LLCommandHandler("event", true) { }
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		if (tokens.size() < 2)
 		{
diff --git a/indra/newview/llfloaterhandler.cpp b/indra/newview/llfloaterhandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..4c0461e910c8dd9b2a1538aed7aed9a97b818f71
--- /dev/null
+++ b/indra/newview/llfloaterhandler.cpp
@@ -0,0 +1,77 @@
+/** 
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llfloaterhandler.h"
+
+#include "llfloater.h"
+#include "llwebbrowserctrl.h"
+
+// register with dispatch via global object
+LLFloaterHandler gFloaterHandler;
+
+
+LLFloater* get_parent_floater(LLView* view)
+{
+	LLFloater* floater = NULL;
+	LLView* parent = view->getParent();
+	while (parent)
+	{
+		floater = dynamic_cast<LLFloater*>(parent);
+		if (floater)
+		{
+			break;
+		}
+		parent = parent->getParent();
+	}
+	return floater;
+}
+
+
+bool LLFloaterHandler::handle(const LLSD &params, const LLSD &query_map, LLWebBrowserCtrl *web)
+{
+	if (params.size() < 2) return false;
+	LLFloater* floater = NULL;
+	// *TODO: implement floater lookup by name
+	if (params[0].asString() == "self")
+	{
+		if (web)
+		{
+			floater = get_parent_floater(web);
+		}
+	}
+	if (params[1].asString() == "close")
+	{
+		if (floater)
+		{
+			floater->close();
+			return true;
+		}
+	}
+	return false;
+}
diff --git a/indra/newview/llfloaterhandler.h b/indra/newview/llfloaterhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..90e87c07e347a95ec5233bbef3a8b848db852011
--- /dev/null
+++ b/indra/newview/llfloaterhandler.h
@@ -0,0 +1,44 @@
+/** 
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLFLOATERHANDLER_H
+#define LLFLOATERHANDLER_H
+
+// Support for SLURL control of floaters, such as
+//   secondlife:///app/floater/self/close
+
+#include "llcommandhandler.h"
+
+class LLFloaterHandler
+:	public LLCommandHandler
+{
+public:
+	LLFloaterHandler() : LLCommandHandler("floater", true) { }
+	bool handle(const LLSD& params, const LLSD& query_map, LLWebBrowserCtrl* web);
+};
+
+#endif
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index f4a515e0a047d970be815cef0dd57f5f31ff2c22..a92634bc311f3865bb94da24a072a0ab619d86b5 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -604,6 +604,25 @@ void LLPanelLandGeneral::refresh()
 		mBtnSellLand->setVisible(FALSE);
 		mBtnStopSellLand->setVisible(FALSE);
 		
+		// show pricing information
+		S32 area;
+		S32 claim_price;
+		S32 rent_price;
+		F32 dwell;
+		LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
+								 &claim_price,
+								 &rent_price,
+								 &for_sale,
+								 &dwell);
+
+		// Area
+		LLUIString price = childGetText("area_size_text");
+		price.setArg("[AREA]", llformat("%d",area));    
+		mTextPriceLabel->setText(childGetText("area_text"));
+		mTextPrice->setText(price.getString());
+
+		mTextDwell->setText(llformat("%.0f", dwell));
+
 		if (for_sale)
 		{
 			mSaleInfoForSale1->setVisible(TRUE);
@@ -619,7 +638,15 @@ void LLPanelLandGeneral::refresh()
 				mSaleInfoForSaleNoObjects->setVisible(TRUE);
 			}
 			mSaleInfoNotForSale->setVisible(FALSE);
+
+			F32 cost_per_sqm = 0.0f;
+			if (area > 0)
+			{
+				cost_per_sqm = (F32)parcel->getSalePrice() / (F32)area;
+			}
+
 			mSaleInfoForSale1->setTextArg("[PRICE]", llformat("%d", parcel->getSalePrice()));
+			mSaleInfoForSale1->setTextArg("[PRICE_PER_SQM]", llformat("%.1f", cost_per_sqm));
 			if (can_be_sold)
 			{
 				mBtnStopSellLand->setVisible(TRUE);
@@ -645,25 +672,6 @@ void LLPanelLandGeneral::refresh()
 		mBtnBuyGroupLand->setEnabled(
 			LLViewerParcelMgr::getInstance()->canAgentBuyParcel(parcel, true));
 
-		// show pricing information
-		S32 area;
-		S32 claim_price;
-		S32 rent_price;
-		F32 dwell;
-		LLViewerParcelMgr::getInstance()->getDisplayInfo(&area,
-								   &claim_price,
-								   &rent_price,
-								   &for_sale,
-								   &dwell);
-
-		// Area
-		LLUIString price = getString("area_size_text");
-		price.setArg("[AREA]", llformat("%d",area));	
-		mTextPriceLabel->setText(getString("area_text"));
-		mTextPrice->setText(price.getString());
-		
-		mTextDwell->setText(llformat("%.0f", dwell));
-
 		if(region_owner)
 		{
 			mBtnReclaimLand->setEnabled(
@@ -1716,8 +1724,6 @@ LLPanelLandOptions::LLPanelLandOptions(LLParcelSelectionHandle& parcel)
 
 BOOL LLPanelLandOptions::postBuild()
 {
-
-	
 	mCheckEditObjects = getChild<LLCheckBoxCtrl>( "edit objects check");
 	childSetCommitCallback("edit objects check", onCommitAny, this);
 	
@@ -1829,6 +1835,8 @@ BOOL LLPanelLandOptions::postBuild()
 	mLandingTypeCombo = getChild<LLComboBox>( "landing type");
 	childSetCommitCallback("landing type", onCommitAny, this);
 
+	getChild<LLTextureCtrl>("snapshot_ctrl")->setFallbackImageName("default_land_picture.j2c");
+
 	return TRUE;
 }
 
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index f53482a476e7c5d01423b87db8170d5e689a8751..b16351af179fd38e2a7f94e31eb64ba1bb945e29 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -43,6 +43,7 @@
 #include "llradiogroup.h"
 #include "lldbstrings.h"
 #include "lldir.h"
+#include "llfloaterperms.h"
 #include "llviewercontrol.h"
 #include "llviewermenufile.h"	// upload_new_resource()
 #include "lluictrlfactory.h"
@@ -180,7 +181,8 @@ void LLFloaterNameDesc::onBtnOK( void* userdata )
 	upload_new_resource(fp->mFilenameAndPath, // file
 		fp->childGetValue("name_form").asString(), 
 		fp->childGetValue("description_form").asString(), 
-		0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE);
+		0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE,
+		LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms());
 	fp->close(false);
 }
 
diff --git a/indra/newview/llfloaterparcel.cpp b/indra/newview/llfloaterparcel.cpp
index 59e95fb9438eafe0d019f1f24adfef348665ee23..bbe278f88573a3c9a73d9a45953bf5ea52d22a3d 100644
--- a/indra/newview/llfloaterparcel.cpp
+++ b/indra/newview/llfloaterparcel.cpp
@@ -51,9 +51,10 @@ LLMap< const LLUUID, LLFloaterParcelInfo* > gPlaceInfoInstances;
 class LLParcelHandler : public LLCommandHandler
 {
 public:
-	// don't allow from external browsers
-	LLParcelHandler() : LLCommandHandler("parcel", false) { }
-	bool handle(const LLSD& params, const LLSD& queryMap)
+	// requires trusted browser to trigger
+	LLParcelHandler() : LLCommandHandler("parcel", true) { }
+	bool handle(const LLSD& params, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		if (params.size() < 2)
 		{
diff --git a/indra/newview/llfloaterperms.cpp b/indra/newview/llfloaterperms.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..9405bc61b25b5592b6e26b58c96138df9f29911b
--- /dev/null
+++ b/indra/newview/llfloaterperms.cpp
@@ -0,0 +1,157 @@
+/** 
+ * @file llfloaterperms.cpp
+ * @brief Asset creation permission preferences.
+ * @author Coco
+ *
+ * $LicenseInfo:firstyear=2001&license=viewergpl$
+ * 
+ * Copyright (c) 2001-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#include "llviewerprecompiledheaders.h"
+#include "llalertdialog.h"
+#include "llcheckboxctrl.h"
+#include "llfloaterperms.h"
+#include "llviewercontrol.h"
+#include "llviewerwindow.h"
+#include "lluictrlfactory.h"
+#include "llpermissions.h"
+
+
+LLFloaterPerms::LLFloaterPerms(const LLSD& seed)
+{
+	LLUICtrlFactory::getInstance()->buildFloater(this, "floater_perm_prefs.xml");
+}
+
+BOOL LLFloaterPerms::postBuild()
+{
+	childSetEnabled("next_owner_transfer", gSavedSettings.getBOOL("NextOwnerCopy"));
+	childSetAction("help",   onClickHelp,   this);
+	childSetAction("ok",     onClickOK,     this);
+	childSetAction("cancel", onClickCancel, this);
+	childSetCommitCallback("next_owner_copy", &onCommitCopy, this);
+
+	refresh();
+	
+	return TRUE;
+}
+
+//static 
+void LLFloaterPerms::onClickOK(void* data)
+{
+	LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data);
+	self->ok();
+	self->close();
+}
+
+//static 
+void LLFloaterPerms::onClickCancel(void* data)
+{
+	LLFloaterPerms* self = static_cast<LLFloaterPerms*>(data);
+	self->cancel();
+	self->close();
+}
+
+//static 
+void LLFloaterPerms::onCommitCopy(LLUICtrl* ctrl, void* data)
+{
+	// Implements fair use
+	BOOL copyable = gSavedSettings.getBOOL("NextOwnerCopy");
+	if(!copyable)
+	{
+		gSavedSettings.setBOOL("NextOwnerTransfer", TRUE);
+	}
+	LLCheckBoxCtrl* xfer = static_cast<LLFloaterPerms*>(data)->getChild<LLCheckBoxCtrl>("next_owner_transfer");
+	xfer->setEnabled(copyable);
+}
+
+void LLFloaterPerms::ok()
+{
+	refresh(); // Changes were already applied to saved settings. Refreshing internal values makes it official.
+}
+
+void LLFloaterPerms::cancel()
+{
+	gSavedSettings.setBOOL("ShareWithGroup",    mShareWithGroup);
+	gSavedSettings.setBOOL("EveryoneCopy",      mEveryoneCopy);
+	gSavedSettings.setBOOL("NextOwnerCopy",     mNextOwnerCopy);
+	gSavedSettings.setBOOL("NextOwnerModify",   mNextOwnerModify);
+	gSavedSettings.setBOOL("NextOwnerTransfer", mNextOwnerTransfer);
+}
+
+void LLFloaterPerms::refresh()
+{
+	mShareWithGroup    = gSavedSettings.getBOOL("ShareWithGroup");
+	mEveryoneCopy      = gSavedSettings.getBOOL("EveryoneCopy");
+	mNextOwnerCopy     = gSavedSettings.getBOOL("NextOwnerCopy");
+	mNextOwnerModify   = gSavedSettings.getBOOL("NextOwnerModify");
+	mNextOwnerTransfer = gSavedSettings.getBOOL("NextOwnerTransfer");
+}
+
+void LLFloaterPerms::onClose(bool app_quitting)
+{
+	// Cancel any unsaved changes before closing. 
+	// Note: when closed due to the OK button this amounts to a no-op.
+	cancel();
+	LLFloater::onClose(app_quitting);
+}
+
+//static 
+U32 LLFloaterPerms::getGroupPerms(std::string prefix)
+{	
+	return gSavedSettings.getBOOL(prefix+"ShareWithGroup") ? PERM_COPY : PERM_NONE;
+}
+
+//static 
+U32 LLFloaterPerms::getEveryonePerms(std::string prefix)
+{
+	return gSavedSettings.getBOOL(prefix+"EveryoneCopy") ? PERM_COPY : PERM_NONE;
+}
+
+//static 
+U32 LLFloaterPerms::getNextOwnerPerms(std::string prefix)
+{
+	U32 flags = 0;
+	if ( gSavedSettings.getBOOL(prefix+"NextOwnerCopy") )
+	{
+		flags |= PERM_COPY;
+	}
+	if ( gSavedSettings.getBOOL(prefix+"NextOwnerModify") )
+	{
+		flags |= PERM_MODIFY;
+	}
+	if ( gSavedSettings.getBOOL(prefix+"NextOwnerTransfer") )
+	{
+		flags |= PERM_TRANSFER;
+	}
+	return flags;
+}
+
+
+//static
+void LLFloaterPerms::onClickHelp(void* data)
+{
+	gViewerWindow->alertXml("ClickUploadHelpPermissions");
+}
diff --git a/indra/newview/llfloaterperms.h b/indra/newview/llfloaterperms.h
new file mode 100644
index 0000000000000000000000000000000000000000..bd9dee1869baf82b73a72a4e71bb7b1faa2df879
--- /dev/null
+++ b/indra/newview/llfloaterperms.h
@@ -0,0 +1,70 @@
+/** 
+ * @file llfloaterperms.h
+ * @brief Asset creation permission preferences.
+ * @author Coco 
+ *
+ * $LicenseInfo:firstyear=2002&license=viewergpl$
+ * 
+ * Copyright (c) 2002-2007, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+
+#ifndef LL_LLFLOATERPERMPREFS_H
+#define LL_LLFLOATERPERMPREFS_H
+
+#include "llfloater.h"
+
+class LLFloaterPerms : public LLFloater, public LLFloaterSingleton<LLFloaterPerms>
+{
+	friend class LLUISingleton<LLFloaterPerms, VisibilityPolicy<LLFloater> >;
+	
+public:
+	/*virtual*/ void onClose(bool app_quitting = false);
+	/*virtual*/ BOOL postBuild();
+	void ok();
+	void cancel();
+	static void onClickOK(void*);
+	static void onClickCancel(void*);
+	static void onCommitCopy(LLUICtrl* ctrl, void* data);
+	// Convenience methods to get current permission preference bitfields from saved settings:
+	static U32 getEveryonePerms(std::string prefix=""); // prefix + "EveryoneCopy"
+	static U32 getGroupPerms(std::string prefix=""); // prefix + "ShareWithGroup"
+	static U32 getNextOwnerPerms(std::string prefix=""); // bitfield for prefix + "NextOwner" + "Copy", "Modify", and "Transfer"
+
+private:
+	LLFloaterPerms(const LLSD& seed);
+	void refresh();
+
+	/// callback for the menus help button
+	static void onClickHelp(void* data);
+
+	BOOL // cached values only for implementing cancel.
+		mShareWithGroup,
+		mEveryoneCopy,
+		mNextOwnerCopy,
+		mNextOwnerModify,
+		mNextOwnerTransfer;
+};
+
+#endif
diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp
index 15d4d302216339aa34b92d52e3f953b109012c57..2de00ec45761113e46224f58ec1cf8c24904a8d1 100644
--- a/indra/newview/llfloaterpreference.cpp
+++ b/indra/newview/llfloaterpreference.cpp
@@ -1,6 +1,6 @@
 /** 
  * @file llfloaterpreference.cpp
- * @brief LLPreferenceCore class implementation
+ * @brief Global preferences with and without persistence.
  *
  * $LicenseInfo:firstyear=2002&license=viewergpl$
  * 
@@ -89,9 +89,10 @@ LLFloaterPreference* LLFloaterPreference::sInstance = NULL;
 class LLPreferencesHandler : public LLCommandHandler
 {
 public:
-	// don't allow from external browsers
-	LLPreferencesHandler() : LLCommandHandler("preferences", false) { }
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	// requires trusted browser
+	LLPreferencesHandler() : LLCommandHandler("preferences", true) { }
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		LLFloaterPreference::show(NULL);
 		return true;
@@ -259,6 +260,7 @@ void LLPreferenceCore::apply()
 	mInputPanel->apply();
 	mNetworkPanel->apply();
 	mDisplayPanel->apply();
+	mAudioPanel->apply();
 	mPrefsChat->apply();
 	mPrefsVoice->apply();
 	mPrefsIM->apply();
@@ -477,6 +479,7 @@ void LLFloaterPreference::onBtnApply( void* userdata )
 void LLFloaterPreference::onClose(bool app_quitting)
 {
 	LLPanelLogin::setAlwaysRefresh(false);
+	cancel(); // will be a no-op if OK or apply was performed just prior.
 	LLFloater::onClose(app_quitting);
 }
 
@@ -493,8 +496,7 @@ void LLFloaterPreference::onBtnCancel( void* userdata )
 			cur_focus->onCommit();
 		}
 	}
-	fp->cancel();
-	fp->close();
+	fp->close(); // side effect will also cancel any unsaved changes.
 }
 
 
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index f4843ea1a5394e9db3dbb9bbe6cd2ae4b3a61713..db2ea7f41ae547c7fef8554225885e6e97fe3898 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -369,7 +369,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
 	glLineWidth(2.0f * line_width) ;
 	LLColor4 color(0.0f, 0.0f, 0.0f, 1.0f) ;
 	gl_rect_2d( mPreviewRect.mLeft + offset_x, mPreviewRect.mTop + offset_y,
-		        mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
+				mPreviewRect.mRight + offset_x, mPreviewRect.mBottom + offset_y, color, FALSE ) ;
 	glLineWidth(line_width) ;
 
 	//draw four alpha rectangles to cover areas outside of the snapshot image
@@ -383,20 +383,20 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
 			dwr = mThumbnailWidth - mPreviewRect.getWidth() - dwl ;
 
 			gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y,
-		        mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
+				mPreviewRect.mLeft + offset_x, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
 			gl_rect_2d( mPreviewRect.mRight + offset_x, mPreviewRect.mTop + offset_y,
-		        mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
+				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y, alpha_color, TRUE ) ;
 		}
 
 		if(mThumbnailHeight > mPreviewRect.getHeight())
 		{
 			S32 dh = (mThumbnailHeight - mPreviewRect.getHeight()) >> 1 ;
 			gl_rect_2d(mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mBottom + offset_y ,
-		        mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
+				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mBottom + offset_y - dh, alpha_color, TRUE ) ;
 
 			dh = mThumbnailHeight - mPreviewRect.getHeight() - dh ;
 			gl_rect_2d( mPreviewRect.mLeft + offset_x - dwl, mPreviewRect.mTop + offset_y + dh,
-		        mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
+				mPreviewRect.mRight + offset_x + dwr, mPreviewRect.mTop + offset_y, alpha_color, TRUE ) ;
 		}
 	}
 }
@@ -950,7 +950,9 @@ void LLSnapshotLivePreview::saveTexture()
 							0,
 							LLAssetType::AT_SNAPSHOT_CATEGORY,
 							LLInventoryType::IT_SNAPSHOT,
-							PERM_ALL,
+							PERM_ALL,  // Note: Snapshots to inventory is a special case of content upload
+							PERM_NONE, // that ignores the user's premissions preferences and continues to
+							PERM_NONE, // always use these fairly permissive hard-coded initial perms. - MG
 							"Snapshot : " + pos_string);
 		gViewerWindow->playSnapshotAnimAndSound();
 	}
@@ -1424,7 +1426,7 @@ void LLFloaterSnapshot::Impl::onClickMore(void* data)
 		if(getPreviewView(view))
 		{
 			getPreviewView(view)->setThumbnailImageSize() ;
-	}
+		}
 	}
 }
 void LLFloaterSnapshot::Impl::onClickLess(void* data)
@@ -1664,15 +1666,15 @@ void LLFloaterSnapshot::Impl::updateResolution(LLUICtrl* ctrl, void* data, BOOL
 
 		if(view->childGetValue("snapshot_width").asInteger() != width || view->childGetValue("snapshot_height").asInteger() != height)
 		{
-		view->childSetValue("snapshot_width", width);
-		view->childSetValue("snapshot_height", height);
-		// hide old preview as the aspect ratio could be wrong
-		checkAutoSnapshot(previewp, FALSE);
+			view->childSetValue("snapshot_width", width);
+			view->childSetValue("snapshot_height", height);
+			// hide old preview as the aspect ratio could be wrong
+			checkAutoSnapshot(previewp, FALSE);
 			getPreviewView(view)->updateSnapshot(FALSE, TRUE);
 			if(do_update)
 			{
 				updateControls(view);
-	}
+			}
 		}
 	}
 }
diff --git a/indra/newview/llfloatertelehub.cpp b/indra/newview/llfloatertelehub.cpp
index 0b4a05867f2815596a0f5471a918e27198740bbf..49ece7a19e9f8da287fee8d3608a624bbc22bb70 100644
--- a/indra/newview/llfloatertelehub.cpp
+++ b/indra/newview/llfloatertelehub.cpp
@@ -68,7 +68,6 @@ void LLFloaterTelehub::show()
 	// Find tools floater, glue to bottom
 	if (gFloaterTools)
 	{
-		gFloaterTools->showMore(FALSE);
 		LLRect tools_rect = gFloaterTools->getRect();
 		S32 our_width = sInstance->getRect().getWidth();
 		S32 our_height = sInstance->getRect().getHeight();
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index 9e5eb2008b37de3237e9c6f6a94c8a5bcdae36b1..1c289912619b7ee6c2a465904bc6149aaa5715c5 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -53,6 +53,7 @@
 #include "llpanelobject.h"
 #include "llpanelvolume.h"
 #include "llpanelpermissions.h"
+#include "llresmgr.h"
 #include "llselectmgr.h"
 #include "llslider.h"
 #include "llstatusbar.h"
@@ -106,9 +107,8 @@ void click_popup_rotate_left(void*);
 void click_popup_rotate_reset(void*);
 void click_popup_rotate_right(void*);
 void click_popup_dozer_mode(LLUICtrl *, void *user);
-void click_popup_dozer_size(LLUICtrl *, void *user);
+void commit_slider_dozer_size(LLUICtrl *, void*);
 void commit_slider_dozer_force(LLUICtrl *, void*);
-void click_dozer_size(LLUICtrl *, void*);
 void click_apply_to_selection(void*);
 void commit_radio_zoom(LLUICtrl *, void*);
 void commit_radio_orbit(LLUICtrl *, void*);
@@ -303,27 +303,22 @@ BOOL	LLFloaterTools::postBuild()
 	childSetCommitCallback("radio noise",click_popup_dozer_mode,  (void*)4);
 	mRadioDozerRevert = getChild<LLCheckBoxCtrl>("radio revert");
 	childSetCommitCallback("radio revert",click_popup_dozer_mode,  (void*)5);
-	mComboDozerSize = getChild<LLComboBox>("combobox brush size");
-	childSetCommitCallback("combobox brush size",click_dozer_size,  (void*)0);
-	if(mComboDozerSize) mComboDozerSize->setCurrentByIndex(0);
 	mBtnApplyToSelection = getChild<LLButton>("button apply to selection");
 	childSetAction("button apply to selection",click_apply_to_selection,  (void*)0);
-	mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners");
-	childSetValue("checkbox show owners",gSavedSettings.getBOOL("ShowParcelOwners"));
 
+	mSliderDozerSize = getChild<LLSlider>("slider brush size");
+	childSetCommitCallback("slider brush size", commit_slider_dozer_size,  (void*)0);
+	childSetValue( "slider brush size", gSavedSettings.getS32("RadioLandBrushSize"));
+	
 	mSliderDozerForce = getChild<LLSlider>("slider force");
 	childSetCommitCallback("slider force",commit_slider_dozer_force,  (void*)0);
 	// the setting stores the actual force multiplier, but the slider is logarithmic, so we convert here
 	childSetValue( "slider force", log10(gSavedSettings.getF32("LandBrushForce")));
 
-	childSetAction("button more", click_show_more, this);
-	childSetAction("button less", click_show_more, this);
 	mTab = getChild<LLTabContainer>("Object Info Tabs");
 	if(mTab)
 	{
-		mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") );
 		mTab->setFollows(FOLLOWS_TOP | FOLLOWS_LEFT);
-		mTab->setVisible( gSavedSettings.getBOOL("ToolboxShowMore") );
 		mTab->setBorderVisible(FALSE);
 		mTab->selectFirstTab();
 	}
@@ -391,10 +386,9 @@ LLFloaterTools::LLFloaterTools()
 	mRadioDozerSmooth(NULL),
 	mRadioDozerNoise(NULL),
 	mRadioDozerRevert(NULL),
-	mComboDozerSize(NULL),
+	mSliderDozerSize(NULL),
+	mSliderDozerForce(NULL),
 	mBtnApplyToSelection(NULL),
-	mCheckShowOwners(NULL),
-
 
 	mTab(NULL),
 	mPanelPermissions(NULL),
@@ -418,19 +412,6 @@ LLFloaterTools::LLFloaterTools()
 	factory_map["land info panel"] = LLCallbackMap(createPanelLandInfo, this);//LLPanelLandInfo
 
 	LLUICtrlFactory::getInstance()->buildFloater(this,"floater_tools.xml",&factory_map,FALSE);
-
-	mLargeHeight = getRect().getHeight();
-	mSmallHeight = mLargeHeight;
-	if (mTab) mSmallHeight -= mTab->getRect().getHeight();
-	
-	// force a toggle initially. seems to be needed to correctly initialize 
-	// both "more" and "less" cases. it also seems to be important to begin
-	// with the user's preference first so that it's initial position will
-	// be correct (SL-51192) -MG
-	BOOL show_more = gSavedSettings.getBOOL("ToolboxShowMore"); // get user's preference
-	gSavedSettings.setBOOL("ToolboxShowMore", show_more); // sets up forced toggle below
-	showMore( !show_more ); // does the toggle
-	showMore(  show_more ); // reset the real user's preference
 }
 
 LLFloaterTools::~LLFloaterTools()
@@ -474,6 +455,16 @@ void LLFloaterTools::refresh()
 	mTab->enableTabButton(idx_face, all_volume);
 	mTab->enableTabButton(idx_contents, all_volume);
 
+	// Refresh object and prim count labels
+	LLLocale locale(LLLocale::USER_LOCALE);
+	std::string obj_count_string;
+	LLResMgr::getInstance()->getIntegerString(obj_count_string, LLSelectMgr::getInstance()->getSelection()->getRootObjectCount());
+	childSetTextArg("obj_count",  "[COUNT]", obj_count_string);	
+	std::string prim_count_string;
+	LLResMgr::getInstance()->getIntegerString(prim_count_string, LLSelectMgr::getInstance()->getSelection()->getObjectCount());
+	childSetTextArg("prim_count", "[COUNT]", prim_count_string);
+
+	// Refresh child tabs
 	mPanelPermissions->refresh();
 	mPanelObject->refresh();
 	mPanelVolume->refresh();
@@ -702,7 +693,6 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 	if (mRadioSelectLand)	mRadioSelectLand->setVisible( land_visible );
 
 	S32 dozer_mode = gSavedSettings.getS32("RadioLandBrushAction");
-	S32 dozer_size = gSavedSettings.getS32("RadioLandBrushSize");
 
 	if (mRadioDozerFlatten)
 	{
@@ -734,20 +724,16 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 		mRadioDozerRevert	->set( tool == LLToolBrushLand::getInstance() && dozer_mode == 5);
 		mRadioDozerRevert	->setVisible( land_visible );
 	}
-	if (mComboDozerSize)
-	{
-		mComboDozerSize		->setCurrentByIndex(dozer_size);
-		mComboDozerSize 	->setVisible( land_visible );
-		mComboDozerSize 	->setEnabled( tool == LLToolBrushLand::getInstance() );
-	}
 	if (mBtnApplyToSelection)
 	{
 		mBtnApplyToSelection->setVisible( land_visible );
 		mBtnApplyToSelection->setEnabled( land_visible && !LLViewerParcelMgr::getInstance()->selectionEmpty() && tool != LLToolSelectLand::getInstance());
 	}
-	if (mCheckShowOwners)
+	if (mSliderDozerSize)
 	{
-		mCheckShowOwners	->setVisible( land_visible );
+		mSliderDozerSize	->setVisible( land_visible );
+		childSetVisible("Bulldozer:", land_visible);
+		childSetVisible("Dozer Size:", land_visible);
 	}
 	if (mSliderDozerForce)
 	{
@@ -755,13 +741,10 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 		childSetVisible("Strength:", land_visible);
 	}
 
-	//
-	// More panel visibility
-	//
-	BOOL show_more = gSavedSettings.getBOOL("ToolboxShowMore");
-
-	mTab->setVisible(show_more && tool != LLToolBrushLand::getInstance() && tool != LLToolSelectLand::getInstance());
-	mPanelLandInfo->setVisible(show_more && (tool == LLToolBrushLand::getInstance() || tool == LLToolSelectLand::getInstance()));
+	childSetVisible("obj_count", !land_visible);
+	childSetVisible("prim_count", !land_visible);
+	mTab->setVisible(!land_visible);
+	mPanelLandInfo->setVisible(land_visible);
 }
 
 
@@ -816,46 +799,12 @@ void LLFloaterTools::onClose(bool app_quitting)
 	// gMenuBarView->arrange();
 }
 
-void LLFloaterTools::showMore(BOOL show_more)
-{
-	BOOL showing_more = gSavedSettings.getBOOL("ToolboxShowMore");
-	if (show_more == showing_more)
-	{
-		return;
-	}
-	
-	gSavedSettings.setBOOL("ToolboxShowMore", show_more);
-
-	// Visibility updated next frame - JC
-	// mTab->setVisible(show_more);
-
-	if (show_more)
-	{
-		reshape( getRect().getWidth(), mLargeHeight, TRUE);
-		translate( 0, mSmallHeight - mLargeHeight );
-	}
-	else
-	{
-		reshape( getRect().getWidth(), mSmallHeight, TRUE);
-		translate( 0, mLargeHeight - mSmallHeight );
-	}
-	childSetVisible("button less",  show_more);
-	childSetVisible("button more", !show_more);
-}
-
 void LLFloaterTools::showPanel(EInfoPanel panel)
 {
 	llassert(panel >= 0 && panel < PANEL_COUNT);
 	mTab->selectTabByName(PANEL_NAMES[panel]);
 }
 
-void click_show_more(void *userdata)
-{
-	LLFloaterTools *f = (LLFloaterTools *)userdata;
-	BOOL show_more = !gSavedSettings.getBOOL("ToolboxShowMore");
-	f->showMore( show_more );
-}
-
 void click_popup_info(void*)
 {
 //	gBuildView->setPropertiesPanelOpen(TRUE);
@@ -933,22 +882,14 @@ void click_popup_rotate_right(void*)
 
 void click_popup_dozer_mode(LLUICtrl *, void *user)
 {
-	S32 show_owners = gSavedSettings.getBOOL("ShowParcelOwners");
 	S32 mode = (S32)(intptr_t) user;
 	gFloaterTools->setEditTool( LLToolBrushLand::getInstance() );
 	gSavedSettings.setS32("RadioLandBrushAction", mode);
-	gSavedSettings.setBOOL("ShowParcelOwners", show_owners);
-}
-
-void click_popup_dozer_size(LLUICtrl *, void *user)
-{
-	S32 size = (S32)(intptr_t) user;
-	gSavedSettings.setS32("RadioLandBrushSize", size);
 }
 
-void click_dozer_size(LLUICtrl *ctrl, void *user)
+void commit_slider_dozer_size(LLUICtrl *ctrl, void*)
 {
-	S32 size = ((LLComboBox*) ctrl)->getCurrentIndex();
+	S32 size = (S32)ctrl->getValue().asInteger();
 	gSavedSettings.setS32("RadioLandBrushSize", size);
 }
 
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index 81e40c04085c48ebbff93e9f3637010aeeef2766..27e05ce2377ab5e6cd3a2bda47e7221df593219b 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -95,7 +95,6 @@ class LLFloaterTools
 	/*virtual*/  void draw();
 
 	void dirty();
-	void showMore(BOOL show_more);
 	void showPanel(EInfoPanel panel);
 
 	void setStatusText(const std::string& text);
@@ -168,11 +167,10 @@ class LLFloaterTools
 	LLCheckBoxCtrl	*mRadioDozerSmooth;
 	LLCheckBoxCtrl	*mRadioDozerNoise;
 	LLCheckBoxCtrl	*mRadioDozerRevert;
+	LLSlider		*mSliderDozerSize;
 	LLSlider		*mSliderDozerForce;
 
-	LLComboBox		*mComboDozerSize;
 	LLButton		*mBtnApplyToSelection;
-	LLCheckBoxCtrl	*mCheckShowOwners;
 
 	std::vector<LLButton*>	mButtons;//[ 15 ];
 
@@ -191,8 +189,6 @@ class LLFloaterTools
 
 private:
 	BOOL					mDirty;
-	S32						mSmallHeight;
-	S32						mLargeHeight;
 
 	std::map<std::string, std::string> mStatusText;
 };
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 89c91bbf2b169f580ba25a5c151d6b983a352986..2281f1b5989b11c10816703ac4e04441de521eff 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -49,10 +49,8 @@
 #include "lldraghandle.h"
 #include "llfirstuse.h"
 #include "llfocusmgr.h"
-#include "llinventorymodel.h"
 #include "lllandmarklist.h"
 #include "lllineeditor.h"
-#include "llnetmap.h"
 #include "llpreviewlandmark.h"
 #include "llregionhandle.h"
 #include "llscrolllistctrl.h"
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 51b0470e07abe6c095efb654cd8d1f2c43a56afa..770c1177981fc5281e699c70b82f0698a70f148d 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -1500,8 +1500,8 @@ void LLFloaterIMPanel::addHistoryLine(const std::string &utf8msg, const LLColor4
 		else
 		{
 			// Convert the name to a hotlink and add to message.
-			const LLStyleSP &source_style = LLStyleMap::instance().lookup(source);
-			mHistoryEditor->appendStyledText(name,false,prepend_newline,&source_style);
+			const LLStyleSP &source_style = LLStyleMap::instance().lookupAgent(source);
+			mHistoryEditor->appendStyledText(name,false,prepend_newline,source_style);
 		}
 		prepend_newline = false;
 	}
diff --git a/indra/newview/llloginhandler.cpp b/indra/newview/llloginhandler.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c311b467791f51f3cc94657d9b1fa8dd8127a83a
--- /dev/null
+++ b/indra/newview/llloginhandler.cpp
@@ -0,0 +1,227 @@
+/** 
+ * @file llloginhandler.cpp
+ * @brief Handles filling in the login panel information from a SLURL
+ * such as secondlife:///app/login?first=Bob&last=Dobbs
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#include "llviewerprecompiledheaders.h"
+
+#include "llloginhandler.h"
+
+// viewer includes
+#include "llpanellogin.h"			// save_password_to_disk()
+#include "llstartup.h"				// getStartupState()
+#include "llurlsimstring.h"
+#include "llviewercontrol.h"		// gSavedSettings
+#include "llviewernetwork.h"		// EGridInfo
+
+// library includes
+#include "llmd5.h"
+
+
+// Must have instance to auto-register with LLCommandDispatcher
+LLLoginHandler gLoginHandler;
+
+
+//parses the input url and returns true if afterwards
+//a web-login-key, firstname and lastname  is set
+bool LLLoginHandler::parseDirectLogin(std::string url)
+{
+	LLURI uri(url);
+	parse(uri.queryMap());
+
+	if (mWebLoginKey.isNull() ||
+		mFirstName.empty() ||
+		mLastName.empty())
+	{
+		return false;
+	}
+	else
+	{
+		return true;
+	}
+}
+
+
+void LLLoginHandler::parse(const LLSD& queryMap)
+{
+	mWebLoginKey = queryMap["web_login_key"].asUUID();
+	mFirstName = queryMap["first_name"].asString();
+	mLastName = queryMap["last_name"].asString();
+	
+	EGridInfo grid_choice = GRID_INFO_NONE;
+	if (queryMap["grid"].asString() == "aditi")
+	{
+		grid_choice = GRID_INFO_ADITI;
+	}
+	else if (queryMap["grid"].asString() == "agni")
+	{
+		grid_choice = GRID_INFO_AGNI;
+	}
+	else if (queryMap["grid"].asString() == "siva")
+	{
+		grid_choice = GRID_INFO_SIVA;
+	}
+	else if (queryMap["grid"].asString() == "damballah")
+	{
+		grid_choice = GRID_INFO_DAMBALLAH;
+	}
+	else if (queryMap["grid"].asString() == "durga")
+	{
+		grid_choice = GRID_INFO_DURGA;
+	}
+	else if (queryMap["grid"].asString() == "shakti")
+	{
+		grid_choice = GRID_INFO_SHAKTI;
+	}
+	else if (queryMap["grid"].asString() == "soma")
+	{
+		grid_choice = GRID_INFO_SOMA;
+	}
+	else if (queryMap["grid"].asString() == "ganga")
+	{
+		grid_choice = GRID_INFO_GANGA;
+	}
+	else if (queryMap["grid"].asString() == "vaak")
+	{
+		grid_choice = GRID_INFO_VAAK;
+	}
+	else if (queryMap["grid"].asString() == "uma")
+	{
+		grid_choice = GRID_INFO_UMA;
+	}
+	else if (queryMap["grid"].asString() == "mohini")
+	{
+		grid_choice = GRID_INFO_MOHINI;
+	}
+	else if (queryMap["grid"].asString() == "yami")
+	{
+		grid_choice = GRID_INFO_YAMI;
+	}
+	else if (queryMap["grid"].asString() == "nandi")
+	{
+		grid_choice = GRID_INFO_NANDI;
+	}
+	else if (queryMap["grid"].asString() == "mitra")
+	{
+		grid_choice = GRID_INFO_MITRA;
+	}
+	else if (queryMap["grid"].asString() == "radha")
+	{
+		grid_choice = GRID_INFO_RADHA;
+	}
+	else if (queryMap["grid"].asString() == "ravi")
+	{
+		grid_choice = GRID_INFO_RAVI;
+	}
+	else if (queryMap["grid"].asString() == "aruna")
+	{
+		grid_choice = GRID_INFO_ARUNA;
+	}
+
+	if(grid_choice != GRID_INFO_NONE)
+	{
+		LLViewerLogin::getInstance()->setGridChoice(grid_choice);
+	}
+
+	std::string startLocation = queryMap["location"].asString();
+
+	if (startLocation == "specify")
+	{
+		LLURLSimString::setString(queryMap["region"].asString());
+	}
+	else if (startLocation == "home")
+	{
+		gSavedSettings.setBOOL("LoginLastLocation", FALSE);
+		LLURLSimString::setString(LLStringUtil::null);
+	}
+	else if (startLocation == "last")
+	{
+		gSavedSettings.setBOOL("LoginLastLocation", TRUE);
+		LLURLSimString::setString(LLStringUtil::null);
+	}
+}
+
+bool LLLoginHandler::handle(const LLSD& tokens,
+							const LLSD& query_map,
+							LLWebBrowserCtrl* web)
+{	
+	parse(query_map);
+	
+	//if we haven't initialized stuff yet, this is 
+	//coming in from the GURL handler, just parse
+	if (STATE_FIRST == LLStartUp::getStartupState())
+	{
+		return true;
+	}
+	
+	std::string password = query_map["password"].asString();
+
+	if (!password.empty())
+	{
+		gSavedSettings.setBOOL("RememberPassword", TRUE);
+
+		if (password.substr(0,3) != "$1$")
+		{
+			LLMD5 pass((unsigned char*)password.c_str());
+			char md5pass[33];		/* Flawfinder: ignore */
+			pass.hex_digest(md5pass);
+			password = ll_safe_string(md5pass, 32);
+			save_password_to_disk(password.c_str());
+		}
+	}
+	else
+	{
+		save_password_to_disk(NULL);
+		gSavedSettings.setBOOL("RememberPassword", FALSE);
+	}
+			
+
+	if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)  //on splash page
+	{
+		if (!mFirstName.empty() || !mLastName.empty())
+		{
+			// Fill in the name, and maybe the password, preserving the
+			// remember-password setting. JC
+			std::string ignore;
+			BOOL remember;
+			LLPanelLogin::getFields(ignore, ignore, ignore, remember);
+			LLPanelLogin::setFields(mFirstName, mLastName, password, remember);
+		}
+
+		if (mWebLoginKey.isNull())
+		{
+			LLPanelLogin::loadLoginPage();
+		}
+		else
+		{
+			LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
+		}
+	}
+	return true;
+}
diff --git a/indra/newview/llloginhandler.h b/indra/newview/llloginhandler.h
new file mode 100644
index 0000000000000000000000000000000000000000..96149e3f0655efb23ff9da6d6b6e5500ec2d787d
--- /dev/null
+++ b/indra/newview/llloginhandler.h
@@ -0,0 +1,63 @@
+/** 
+ * @file llloginhandler.h
+ * @brief Handles filling in the login panel information from a SLURL
+ * such as secondlife:///app/login?first=Bob&last=Dobbs
+ *
+ * $LicenseInfo:firstyear=2008&license=viewergpl$
+ * 
+ * Copyright (c) 2008, Linden Research, Inc.
+ * 
+ * Second Life Viewer Source Code
+ * The source code in this file ("Source Code") is provided by Linden Lab
+ * to you under the terms of the GNU General Public License, version 2.0
+ * ("GPL"), unless you have obtained a separate licensing agreement
+ * ("Other License"), formally executed by you and Linden Lab.  Terms of
+ * the GPL can be found in doc/GPL-license.txt in this distribution, or
+ * online at http://secondlife.com/developers/opensource/gplv2
+ * 
+ * There are special exceptions to the terms and conditions of the GPL as
+ * it is applied to this Source Code. View the full text of the exception
+ * in the file doc/FLOSS-exception.txt in this software distribution, or
+ * online at http://secondlife.com/developers/opensource/flossexception
+ * 
+ * By copying, modifying or distributing this software, you acknowledge
+ * that you have read and understood your obligations described above,
+ * and agree to abide by those obligations.
+ * 
+ * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
+ * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
+ * COMPLETENESS OR PERFORMANCE.
+ * $/LicenseInfo$
+ */
+#ifndef LLLOGINHANDLER_H
+#define LLLOGINHANDLER_H
+
+#include "llcommandhandler.h"
+
+class LLLoginHandler : public LLCommandHandler
+{
+ public:
+	// allow from external browsers
+	LLLoginHandler() : LLCommandHandler("login", false) { }
+	/*virtual*/ bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web);
+
+	// Fill in our internal fields from a SLURL like
+	// secondlife:///app/login?first=Bob&last=Dobbs
+	bool parseDirectLogin(std::string url);
+
+	std::string getFirstName() const { return mFirstName; }
+	std::string getLastName() const { return mLastName; }
+	LLUUID getWebLoginKey() const { return mWebLoginKey; }
+
+private:
+	void parse(const LLSD& queryMap);
+
+private:
+	std::string mFirstName;
+	std::string mLastName;
+	LLUUID mWebLoginKey;
+};
+
+extern LLLoginHandler gLoginHandler;
+
+#endif
diff --git a/indra/newview/llnetmap.cpp b/indra/newview/llnetmap.cpp
index 21b1bee54f6f6f18e2f3d67100da8fedded30fc6..d836876d668359886fe3489462ac969a1276fd37 100644
--- a/indra/newview/llnetmap.cpp
+++ b/indra/newview/llnetmap.cpp
@@ -44,6 +44,7 @@
 #include "llcallingcard.h"
 #include "llcolorscheme.h"
 #include "llviewercontrol.h"
+#include "llfloateravatarinfo.h"
 #include "llfloaterworldmap.h"
 #include "llfloatermap.h"
 #include "llframetimer.h"
@@ -73,6 +74,7 @@ const F32 MAP_SCALE_MIN = 64;
 const F32 MAP_SCALE_MID = 172;
 const F32 MAP_SCALE_MAX = 512;
 const F32 MAP_SCALE_INCREMENT = 16;
+const F32 MAP_MIN_PICK_DIST = 4;
 
 const S32 TRACKING_RADIUS = 3;
 
@@ -161,10 +163,11 @@ LLNetMap::LLNetMap(
 	menu->appendSeparator();
 	menu->append(new LLMenuItemCallGL(std::string("Stop Tracking"), &LLTracker::stopTracking,
 										&LLTracker::isTracking, NULL) );
+	menu->append(new LLMenuItemCallGL(std::string("Profile..."), &showAgentProfile,
+										&isAgentUnderCursor, NULL) );
 	menu->setVisible(FALSE);
 	addChild(menu);
 	mPopupMenuHandle = menu->getHandle();
-
 	sInstance = this;
 }
 
@@ -370,6 +373,14 @@ void LLNetMap::draw()
 		LLVector3d pos_global;
 		LLVector3 pos_map;
 
+		// Mouse pointer in local coordinates
+		S32 local_mouse_x;
+		S32 local_mouse_y;
+		//localMouse(&local_mouse_x, &local_mouse_y);
+		LLUI::getCursorPositionLocal(this, &local_mouse_x, &local_mouse_y);
+		mClosestAgentToCursor.setNull();
+		F32 closest_dist = F32_MAX;
+
 		// Draw avatars
 		for (LLWorld::region_list_t::iterator iter = LLWorld::getInstance()->mActiveRegionList.begin();
 			 iter != LLWorld::getInstance()->mActiveRegionList.end(); ++iter)
@@ -413,6 +424,13 @@ void LLNetMap::draw()
 					pos_map.mV[VX], pos_map.mV[VY], 
 					show_as_friend ? gFriendMapColor : gAvatarMapColor, 
 					pos_map.mV[VZ]);
+
+				F32	dist_to_cursor = dist_vec(LLVector2(pos_map.mV[VX], pos_map.mV[VY]), LLVector2(local_mouse_x,local_mouse_y));
+				if(dist_to_cursor < MAP_MIN_PICK_DIST && dist_to_cursor < closest_dist)
+				{
+					closest_dist = dist_to_cursor;
+					mClosestAgentToCursor = regionp->mMapAvatarIDs.get(i);
+				}
 			}
 		}
 
@@ -590,7 +608,14 @@ BOOL LLNetMap::handleToolTip( S32 x, S32 y, std::string& msg, LLRect* sticky_rec
 	LLViewerRegion*	region = LLWorld::getInstance()->getRegionFromPosGlobal( viewPosToGlobal( x, y ) );
 	if( region )
 	{
-		msg.assign( region->getName() );
+		msg.assign("");
+		std::string fullname;
+		if(mClosestAgentToCursor.notNull() && gCacheName->getFullName(mClosestAgentToCursor, fullname))
+		{
+			msg.append(fullname);
+			msg.append("\n");
+		}
+		msg.append( region->getName() );
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 		std::string buffer;
@@ -774,6 +799,7 @@ BOOL LLNetMap::handleDoubleClick( S32 x, S32 y, MASK mask )
 
 BOOL LLNetMap::handleRightMouseDown(S32 x, S32 y, MASK mask)
 {
+	mClosestAgentAtLastRightClick = mClosestAgentToCursor;
 	LLMenuGL* menu = (LLMenuGL*)mPopupMenuHandle.get();
 	if (menu)
 	{
@@ -805,3 +831,9 @@ void LLNetMap::handleZoomLevel(void* which)
 		break;
 	}
 }
+
+// static
+void LLNetMap::showAgentProfile(void*) 
+{ 
+	LLFloaterAvatarInfo::show(sInstance->mClosestAgentAtLastRightClick); 
+}
diff --git a/indra/newview/llnetmap.h b/indra/newview/llnetmap.h
index 3950a081660270646df8cdf0370dc49f53530d0c..214dc4df932e10352aaab67a712a8d05c7241046 100644
--- a/indra/newview/llnetmap.h
+++ b/indra/newview/llnetmap.h
@@ -108,8 +108,14 @@ class LLNetMap : public LLUICtrl
 	LLTextBox*		mTextBoxNorthWest;
 	LLTextBox*		mTextBoxSouthWest;
 
+private:
+	LLUUID			mClosestAgentToCursor;
+	LLUUID			mClosestAgentAtLastRightClick;
+
 	static BOOL		sRotateMap;
 	static LLNetMap*	sInstance;
+	static BOOL isAgentUnderCursor(void*) { return sInstance && sInstance->mClosestAgentToCursor.notNull(); }
+	static void showAgentProfile(void*);
 };
 
 
diff --git a/indra/newview/llpanelavatar.cpp b/indra/newview/llpanelavatar.cpp
index 7d66da30e5c2fb6ac49eba2cec752f5c199279d3..9c8817da9ad262b185d2e9ff265c857961d8df00 100644
--- a/indra/newview/llpanelavatar.cpp
+++ b/indra/newview/llpanelavatar.cpp
@@ -389,7 +389,6 @@ LLPanelAvatarFirstLife::LLPanelAvatarFirstLife(const std::string& name,
 {
 }
 
-
 void LLPanelAvatarFirstLife::enableControls(BOOL self)
 {
 	childSetEnabled("img", self);
@@ -438,6 +437,8 @@ BOOL LLPanelAvatarSecondLife::postBuild(void)
 
 	childSetDoubleClickCallback("groups", onDoubleClickGroup, this );
 
+	getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c");
+
 	return TRUE;
 }
 
@@ -445,6 +446,9 @@ BOOL LLPanelAvatarFirstLife::postBuild(void)
 {
 	BOOL own_avatar = (getPanelAvatar()->getAvatarID() == gAgent.getID() );
 	enableControls(own_avatar);
+
+	getChild<LLTextureCtrl>("img")->setFallbackImageName("default_profile_picture.j2c");
+
 	return TRUE;
 }
 
@@ -1778,7 +1782,7 @@ void LLPanelAvatar::processAvatarPropertiesReply(LLMessageSystem *msg, void**)
 		msg->getStringFast(_PREHASH_PropertiesData, _PREHASH_BornOn, born_on);
 		msg->getString("PropertiesData","ProfileURL", profile_url);
 		msg->getU32Fast(_PREHASH_PropertiesData, _PREHASH_Flags, flags);
-		
+
 		identified = (flags & AVATAR_IDENTIFIED);
 		transacted = (flags & AVATAR_TRANSACTED);
 		age_verified = (flags & AVATAR_AGEVERIFIED); // Not currently getting set in dataserver/lldataavatar.cpp for privacy considerations
diff --git a/indra/newview/llpanelclassified.cpp b/indra/newview/llpanelclassified.cpp
index 34731f653f681e0ec95507e7dcf41656c7f933c9..64cc19e2fd5896a08ee3f8fd4bc75917d3d1d511 100644
--- a/indra/newview/llpanelclassified.cpp
+++ b/indra/newview/llpanelclassified.cpp
@@ -116,7 +116,7 @@ class LLClassifiedTeleportHandler : public LLCommandHandler
 {
 public:
 	// don't allow from external browsers because it moves you immediately
-	LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", false) { }
+	LLClassifiedTeleportHandler() : LLCommandHandler("classifiedteleport", true) { }
 
 	bool handle(const LLSD& tokens, const LLSD& queryMap)
 	{
@@ -139,8 +139,9 @@ class LLClassifiedTeleportHandler : public LLCommandHandler
 		const bool from_search = true;
 		LLPanelClassified::sendClassifiedClickMessage(classified_id, "teleport", from_search);
 		// Invoke teleport
-		const bool from_external_browser = false;
-		return LLURLDispatcher::dispatch(url, from_external_browser);
+		LLWebBrowserCtrl* web = NULL;
+		const bool trusted_browser = true;
+		return LLURLDispatcher::dispatch(url, web, trusted_browser);
 	}
 };
 // Creating the object registers with the dispatcher.
diff --git a/indra/newview/llpanelcontents.cpp b/indra/newview/llpanelcontents.cpp
index e9fb9d3a17791fc5eaf8cf9651e807a114c8694a..7fdd052af5fb34b15cf5218dedd4cba8666d5fef 100644
--- a/indra/newview/llpanelcontents.cpp
+++ b/indra/newview/llpanelcontents.cpp
@@ -52,6 +52,7 @@
 #include "lltextbox.h"
 #include "llbutton.h"
 #include "llcombobox.h"
+#include "llfloaterbulkpermission.h"
 
 #include "llagent.h"
 #include "llviewerwindow.h"
@@ -82,6 +83,7 @@ BOOL LLPanelContents::postBuild()
 	setMouseOpaque(FALSE);
 
 	childSetAction("button new script",&LLPanelContents::onClickNewScript, this);
+	childSetAction("button permissions",&LLPanelContents::onClickPermissions, this);
 
 	return TRUE;
 }
@@ -104,7 +106,6 @@ void LLPanelContents::getState(LLViewerObject *objectp )
 	if( !objectp )
 	{
 		childSetEnabled("button new script",FALSE);
-		//mBtnNewScript->setEnabled( FALSE );
 		return;
 	}
 
@@ -117,21 +118,12 @@ void LLPanelContents::getState(LLViewerObject *objectp )
 					       && ( objectp->permYouOwner() || ( !group_id.isNull() && gAgent.isInGroup(group_id) )));  // solves SL-23488
 	BOOL all_volume = LLSelectMgr::getInstance()->selectionAllPCode( LL_PCODE_VOLUME );
 
-	// Edit script button - ok if object is editable and there's an
-	// unambiguous destination for the object.
-	if(	editable &&
+	// Edit script button - ok if object is editable and there's an unambiguous destination for the object.
+	childSetEnabled("button new script",
+		editable &&
 		all_volume &&
 		((LLSelectMgr::getInstance()->getSelection()->getRootObjectCount() == 1)
-					|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)))
-	{
-		//mBtnNewScript->setEnabled(TRUE);
-		childSetEnabled("button new script",TRUE);
-	}
-	else
-	{
-		//mBtnNewScript->setEnabled(FALSE);
-		childSetEnabled("button new script",FALSE);
-	}
+			|| (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)));
 }
 
 
@@ -210,3 +202,11 @@ void LLPanelContents::onClickNewScript(void *userdata)
 #endif
 	}
 }
+
+
+// static
+void LLPanelContents::onClickPermissions(void *userdata)
+{
+	LLPanelContents* self = (LLPanelContents*)userdata;
+	gFloaterView->getParentFloater(self)->addDependentFloater(LLFloaterBulkPermission::showInstance());
+}
diff --git a/indra/newview/llpanelcontents.h b/indra/newview/llpanelcontents.h
index 98e53d6de3860e611ee9a629c83a15e42d81151e..e8a00b9c6e8f471b10f43fa1c3813ec673e79a21 100644
--- a/indra/newview/llpanelcontents.h
+++ b/indra/newview/llpanelcontents.h
@@ -51,6 +51,7 @@ class LLPanelContents : public LLPanel
 	void			refresh();
 
 	static void		onClickNewScript(		void* userdata);
+	static void		onClickPermissions(		void* userdata);
 
 protected:
 	void			getState(LLViewerObject *object);
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 8cc7844c0fbb48354a86c8ffbab5956f4124a10d..b3d03bba6f81dc2941dc830bfe630d42e08e369b 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -424,7 +424,7 @@ void LLPanelFace::getState()
 				}
 			} func;
 			identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, id );
-			
+
 			if (identical)
 			{
 				// All selected have the same texture
@@ -765,6 +765,7 @@ void LLPanelFace::getState()
 		if(texture_ctrl)
 		{
 			texture_ctrl->setImageAssetID( LLUUID::null );
+			texture_ctrl->setFallbackImageName( "locked_image.j2c" );
 			texture_ctrl->setEnabled( FALSE );  // this is a LLUICtrl, but we don't want it to have keyboard focus so we add it as a child, not a ctrl.
 // 			texture_ctrl->setValid(FALSE);
 		}
@@ -772,6 +773,7 @@ void LLPanelFace::getState()
 		if(mColorSwatch)
 		{
 			mColorSwatch->setEnabled( FALSE );			
+			mColorSwatch->setFallbackImageName("locked_image.j2c" );
 			mColorSwatch->setValid(FALSE);
 		}
 		childSetEnabled("color trans",FALSE);
diff --git a/indra/newview/llpanelgrouproles.cpp b/indra/newview/llpanelgrouproles.cpp
index ba4153b087f5d97565a40f1bfb9a607d35052ea7..4b48fb35109f481847e3271a51af9c53103033a2 100644
--- a/indra/newview/llpanelgrouproles.cpp
+++ b/indra/newview/llpanelgrouproles.cpp
@@ -2085,8 +2085,19 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
 				gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
 		mRoleTitle->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
 		mRoleDescription->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
-		mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
-
+		
+		if ( is_owner_role ) 
+			{
+				// you can't delete the owner role
+				can_delete = FALSE;
+				// ... or hide members with this role
+				mMemberVisibleCheck->setEnabled(FALSE);
+			}
+		else
+			{
+				mMemberVisibleCheck->setEnabled(gAgent.hasPowerInGroup(mGroupID, GP_ROLE_PROPERTIES));
+			}
+		
 		if (item->getUUID().isNull())
 		{
 			// Everyone role, can't edit description or name or delete
@@ -2094,8 +2105,6 @@ void LLPanelGroupRolesSubTab::handleRoleSelect()
 			mRoleName->setEnabled(FALSE);
 			can_delete = FALSE;
 		}
-		//you can't delete the owner role
-		if ( is_owner_role ) can_delete = FALSE;
 	}
 	else
 	{
diff --git a/indra/newview/llpanelland.cpp b/indra/newview/llpanelland.cpp
index f0afa3434ef3e80450d175af9ac2f36d0cd49ab4..11f88695c5778667c0f35e4483c19aae90e27ed3 100644
--- a/indra/newview/llpanelland.cpp
+++ b/indra/newview/llpanelland.cpp
@@ -37,10 +37,13 @@
 
 #include "llagent.h"
 #include "llbutton.h"
+#include "llcheckboxctrl.h"
 #include "llfloaterland.h"
 #include "lltextbox.h"
+#include "llviewercontrol.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
+#include "llviewerwindow.h"
 #include "roles_constants.h"
 
 #include "lluictrlfactory.h"
@@ -65,6 +68,10 @@ BOOL	LLPanelLandInfo::postBuild()
 	childSetAction("button subdivide land",onClickDivide,this);
 	childSetAction("button join land",onClickJoin,this);
 	childSetAction("button about land",onClickAbout,this);
+	childSetAction("button show owners help", onShowOwnersHelp, this);
+
+	mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners");
+	childSetValue("checkbox show owners", gSavedSettings.getBOOL("ShowParcelOwners"));
 
 	return TRUE;
 }
@@ -72,7 +79,8 @@ BOOL	LLPanelLandInfo::postBuild()
 // Methods
 //
 LLPanelLandInfo::LLPanelLandInfo(const std::string& name)
-:	LLPanel(name)
+:	LLPanel(name),
+	mCheckShowOwners(NULL)
 {
 	if (!sInstance)
 	{
@@ -255,3 +263,8 @@ void LLPanelLandInfo::onClickAbout(void*)
 
 	LLFloaterLand::showInstance();
 }
+
+void LLPanelLandInfo::onShowOwnersHelp(void* user_data)
+{
+	gViewerWindow->alertXml("ShowOwnersHelp");
+}
diff --git a/indra/newview/llpanelland.h b/indra/newview/llpanelland.h
index 7db8e648011704b64bc5e882420263d879551eed..477c5ed970562a87cd85b82f404ba890e512a3e1 100644
--- a/indra/newview/llpanelland.h
+++ b/indra/newview/llpanelland.h
@@ -50,6 +50,8 @@ class LLPanelLandInfo
 
 	void refresh();
 	static void refreshAll();
+	
+	LLCheckBoxCtrl	*mCheckShowOwners;
 
 protected:
 	static void onClickClaim(void*);
@@ -57,6 +59,7 @@ class LLPanelLandInfo
 	static void onClickDivide(void*);
 	static void onClickJoin(void*);
 	static void onClickAbout(void*);
+	static void onShowOwnersHelp(void*);
 
 protected:
 	//LLTextBox*		mTextPriceLabel;
diff --git a/indra/newview/llpanellogin.cpp b/indra/newview/llpanellogin.cpp
index 816a8b5765e6f57c3a9e6c07b25f5f65ed567088..20228ed3064b493d5c7a56c79967b8e8414bfea4 100644
--- a/indra/newview/llpanellogin.cpp
+++ b/indra/newview/llpanellogin.cpp
@@ -32,6 +32,7 @@
 #include "llviewerprecompiledheaders.h"
 
 #include "llpanellogin.h"
+
 #include "llpanelgeneral.h"
 
 #include "indra_constants.h"		// for key and mask constants
@@ -43,7 +44,7 @@
 
 #include "llbutton.h"
 #include "llcheckboxctrl.h"
-#include "llcommandhandler.h"
+#include "llcommandhandler.h"		// for secondlife:///app/login/
 #include "llcombobox.h"
 #include "llcurl.h"
 #include "llviewercontrol.h"
@@ -78,9 +79,6 @@
 
 #define USE_VIEWER_AUTH 0
 
-std::string load_password_from_disk(void);
-void save_password_to_disk(const char* hashed_password);
-
 const S32 BLACK_BORDER_HEIGHT = 160;
 const S32 MAX_PASSWORD = 16;
 
@@ -92,8 +90,8 @@ class LLLoginRefreshHandler : public LLCommandHandler
 {
 public:
 	// don't allow from external browsers
-	LLLoginRefreshHandler() : LLCommandHandler("login_refresh", false) { }
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	LLLoginRefreshHandler() : LLCommandHandler("login_refresh", true) { }
+	bool handle(const LLSD& tokens, const LLSD& query_map, LLWebBrowserCtrl* web)
 	{	
 		if (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)
 		{
@@ -106,191 +104,6 @@ class LLLoginRefreshHandler : public LLCommandHandler
 LLLoginRefreshHandler gLoginRefreshHandler;
 
 
-//parses the input url and returns true if afterwards
-//a web-login-key, firstname and lastname  is set
-bool LLLoginHandler::parseDirectLogin(std::string url)
-{
-	LLURI uri(url);
-	parse(uri.queryMap());
-
-	if (mWebLoginKey.isNull() ||
-		mFirstName.empty() ||
-		mLastName.empty())
-	{
-		return false;
-	}
-	else
-	{
-		return true;
-	}
-}
-
-
-void LLLoginHandler::parse(const LLSD& queryMap)
-{
-	mWebLoginKey = queryMap["web_login_key"].asUUID();
-	mFirstName = queryMap["first_name"].asString();
-	mLastName = queryMap["last_name"].asString();
-	
-	EGridInfo grid_choice = GRID_INFO_NONE;
-	if (queryMap["grid"].asString() == "aditi")
-	{
-		grid_choice = GRID_INFO_ADITI;
-	}
-	else if (queryMap["grid"].asString() == "agni")
-	{
-		grid_choice = GRID_INFO_AGNI;
-	}
-	else if (queryMap["grid"].asString() == "siva")
-	{
-		grid_choice = GRID_INFO_SIVA;
-	}
-	else if (queryMap["grid"].asString() == "damballah")
-	{
-		grid_choice = GRID_INFO_DAMBALLAH;
-	}
-	else if (queryMap["grid"].asString() == "durga")
-	{
-		grid_choice = GRID_INFO_DURGA;
-	}
-	else if (queryMap["grid"].asString() == "shakti")
-	{
-		grid_choice = GRID_INFO_SHAKTI;
-	}
-	else if (queryMap["grid"].asString() == "soma")
-	{
-		grid_choice = GRID_INFO_SOMA;
-	}
-	else if (queryMap["grid"].asString() == "ganga")
-	{
-		grid_choice = GRID_INFO_GANGA;
-	}
-	else if (queryMap["grid"].asString() == "vaak")
-	{
-		grid_choice = GRID_INFO_VAAK;
-	}
-	else if (queryMap["grid"].asString() == "uma")
-	{
-		grid_choice = GRID_INFO_UMA;
-	}
-	else if (queryMap["grid"].asString() == "mohini")
-	{
-		grid_choice = GRID_INFO_MOHINI;
-	}
-	else if (queryMap["grid"].asString() == "yami")
-	{
-		grid_choice = GRID_INFO_YAMI;
-	}
-	else if (queryMap["grid"].asString() == "nandi")
-	{
-		grid_choice = GRID_INFO_NANDI;
-	}
-	else if (queryMap["grid"].asString() == "mitra")
-	{
-		grid_choice = GRID_INFO_MITRA;
-	}
-	else if (queryMap["grid"].asString() == "radha")
-	{
-		grid_choice = GRID_INFO_RADHA;
-	}
-	else if (queryMap["grid"].asString() == "ravi")
-	{
-		grid_choice = GRID_INFO_RAVI;
-	}
-	else if (queryMap["grid"].asString() == "aruna")
-	{
-		grid_choice = GRID_INFO_ARUNA;
-	}
-	else if (queryMap["grid"].asString() == "bharati")
-	{
-		grid_choice = GRID_INFO_BHARATI;
-	}
-	else if (queryMap["grid"].asString() == "chandra")
-	{
-		grid_choice = GRID_INFO_CHANDRA;
-	}
-	else if (queryMap["grid"].asString() == "danu")
-	{
-		grid_choice = GRID_INFO_DANU;
-	}
-	else if (queryMap["grid"].asString() == "parvati")
-	{
-		grid_choice = GRID_INFO_PARVATI;
-	}
-	else if (queryMap["grid"].asString() == "skanda")
-	{
-		grid_choice = GRID_INFO_SKANDA;
-	}
-
-	if(grid_choice != GRID_INFO_NONE)
-	{
-		LLViewerLogin::getInstance()->setGridChoice(grid_choice);
-	}
-
-	std::string startLocation = queryMap["location"].asString();
-
-	if (startLocation == "specify")
-	{
-		LLURLSimString::setString(queryMap["region"].asString());
-	}
-	else if (startLocation == "home")
-	{
-		gSavedSettings.setBOOL("LoginLastLocation", FALSE);
-		LLURLSimString::setString(LLStringUtil::null);
-	}
-	else if (startLocation == "last")
-	{
-		gSavedSettings.setBOOL("LoginLastLocation", TRUE);
-		LLURLSimString::setString(LLStringUtil::null);
-	}
-}
-
-bool LLLoginHandler::handle(const LLSD& tokens,
-						  const LLSD& queryMap)
-{	
-	parse(queryMap);
-	
-	//if we haven't initialized stuff yet, this is 
-	//coming in from the GURL handler, just parse
-	if (STATE_FIRST == LLStartUp::getStartupState())
-	{
-		return true;
-	}
-	
-	std::string password = queryMap["password"].asString();
-
-	if (!password.empty())
-	{
-		gSavedSettings.setBOOL("RememberPassword", TRUE);
-
-		if (password.substr(0,3) != "$1$")
-		{
-			LLMD5 pass((unsigned char*)password.c_str());
-			char md5pass[33];		/* Flawfinder: ignore */
-			pass.hex_digest(md5pass);
-			password = ll_safe_string(md5pass, 32);
-			save_password_to_disk(password.c_str());
-		}
-	}
-	else
-	{
-		save_password_to_disk(NULL);
-		gSavedSettings.setBOOL("RememberPassword", FALSE);
-	}
-			
-
-	if  (LLStartUp::getStartupState() < STATE_LOGIN_CLEANUP)  //on splash page
-	{
-		if (mWebLoginKey.isNull()) {
-			LLPanelLogin::loadLoginPage();
-		} else {
-			LLStartUp::setStartupState( STATE_LOGIN_CLEANUP );
-		}
-	}
-	return true;
-}
-
-LLLoginHandler gLoginHandler;
 
 // helper class that trys to download a URL from a web site and calls a method 
 // on parent class indicating if the web server is working or not
@@ -450,7 +263,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 		LL_VERSION_PATCH,
 		LL_VIEWER_BUILD );
 	LLTextBox* channel_text = getChild<LLTextBox>("channel_text");
-	channel_text->setTextArg("[CHANNEL]", channel);
+	channel_text->setTextArg("[CHANNEL]", channel); // though not displayed
 	channel_text->setTextArg("[VERSION]", version);
 	channel_text->setClickedCallback(onClickVersion);
 	channel_text->setCallbackUserData(this);
@@ -465,7 +278,7 @@ LLPanelLogin::LLPanelLogin(const LLRect &rect,
 	// get the web browser control
 	LLWebBrowserCtrl* web_browser = getChild<LLWebBrowserCtrl>("login_html");
 	// Need to handle login secondlife:///app/ URLs
-	web_browser->setOpenAppSLURLs( true );
+	web_browser->setTrusted( true );
 
 	// observe browser events
 	web_browser->addObserver( this );
diff --git a/indra/newview/llpanellogin.h b/indra/newview/llpanellogin.h
index aa41ab70b8a61509c2d62628476af456e0b218c2..9d7e386cdad93183e6382326faa177b3bdd97104 100644
--- a/indra/newview/llpanellogin.h
+++ b/indra/newview/llpanellogin.h
@@ -33,36 +33,11 @@
 #define LL_LLPANELLOGIN_H
 
 #include "llpanel.h"
-#include "llcommandhandler.h"
-#include "lldbstrings.h"
-#include "llmemory.h"
-#include "llviewerimage.h"
-#include "llstring.h"
-#include "llmd5.h"
-#include "llwebbrowserctrl.h"
-
-class LLTextBox;
-class LLLineEditor;
-class LLCheckBoxCtrl;
-class LLButton;
-class LLComboBox;
-
-
-class LLLoginHandler : public LLCommandHandler
-{
- public:
-	// allow from external browsers
-	LLLoginHandler() : LLCommandHandler("login", true) { }
-	bool handle(const LLSD& tokens, const LLSD& queryMap);
-	bool parseDirectLogin(std::string url);
-	void parse(const LLSD& queryMap);
-
-	LLUUID mWebLoginKey;
-	std::string mFirstName;
-	std::string mLastName;
-};
+#include "llmemory.h"			// LLPointer<>
+#include "llwebbrowserctrl.h"	// LLWebBrowserCtrlObserver
+
+class LLUIImage;
 
-extern LLLoginHandler gLoginHandler;
 
 class LLPanelLogin:	
 	public LLPanel,
@@ -130,4 +105,7 @@ class LLPanelLogin:
 	BOOL			mHtmlAvailable;
 };
 
+std::string load_password_from_disk(void);
+void save_password_to_disk(const char* hashed_password);
+
 #endif
diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp
index f7f33cb66b43aadbccc1d71c621fa2580c215a93..38214d78d6e76b3ad08d4c555e1f899f99db9339 100644
--- a/indra/newview/llpanelobject.cpp
+++ b/indra/newview/llpanelobject.cpp
@@ -849,6 +849,7 @@ void LLPanelObject::getState( )
 	F32	 twist_inc					= OBJECT_TWIST_LINEAR_INC;
 
 	BOOL advanced_is_dimple = FALSE;
+	BOOL advanced_is_slice = FALSE;
 	BOOL size_is_hole = FALSE;
 
 	// Tune based on overall volume type
@@ -902,8 +903,20 @@ void LLPanelObject::getState( )
 		break;
 		
 	case MI_BOX:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
 	case MI_CYLINDER:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
 	case MI_PRISM:
+		advanced_cut_visible	= TRUE;
+		advanced_is_slice		= TRUE;
+		break;
+
 	default:
 		break;
 	}
@@ -995,6 +1008,8 @@ void LLPanelObject::getState( )
 
 	childSetVisible("advanced_cut", FALSE);
 	childSetVisible("advanced_dimple", FALSE);
+	childSetVisible("advanced_slice", FALSE);
+
 	if (advanced_cut_visible)
 	{
 		if (advanced_is_dimple)
@@ -1002,6 +1017,12 @@ void LLPanelObject::getState( )
 			childSetVisible("advanced_dimple", TRUE);
 			childSetEnabled("advanced_dimple", enabled);
 		}
+
+		else if (advanced_is_slice)
+		{
+			childSetVisible("advanced_slice", TRUE);
+			childSetEnabled("advanced_slice", enabled);
+		}
 		else
 		{
 			childSetVisible("advanced_cut", TRUE);
@@ -1895,8 +1916,9 @@ void LLPanelObject::clearCtrls()
 	
 	childSetEnabled("scale_hole", FALSE);
 	childSetEnabled("scale_taper", FALSE);
-	childSetEnabled( "advanced_cut", FALSE );
-	childSetEnabled( "advanced_dimple", FALSE );
+	childSetEnabled("advanced_cut", FALSE);
+	childSetEnabled("advanced_dimple", FALSE);
+	childSetVisible("advanced_slice", FALSE);
 }
 
 //
diff --git a/indra/newview/llpanelpermissions.cpp b/indra/newview/llpanelpermissions.cpp
index fff5c1985bc2894f70392c3c6004fa700fcadae8..8a75385984d7c4ca612b1e19dde72f7f561902fc 100644
--- a/indra/newview/llpanelpermissions.cpp
+++ b/indra/newview/llpanelpermissions.cpp
@@ -190,9 +190,6 @@ void LLPanelPermissions::refresh()
 		childSetEnabled("Description:",false);
 		childSetText("Object Description",LLStringUtil::null);
 		childSetEnabled("Object Description",false);
- 
-		childSetText("prim info",LLStringUtil::null);
-		childSetEnabled("prim info",false);
 
 		childSetEnabled("Permissions:",false);
 		
@@ -395,33 +392,6 @@ void LLPanelPermissions::refresh()
 		childSetEnabled("Object Description",false);
 	}
 
-
-	// Pre-compute object info string
-	S32 prim_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount();
-	S32 obj_count = LLSelectMgr::getInstance()->getSelection()->getRootObjectCount();
-
-	std::string object_info_string;
-	if (1 == obj_count)
-	{
-		object_info_string.assign("1 Object, ");
-	}
-	else
-	{
-		object_info_string = llformat( "%d Objects, ", obj_count);
-	}
-	if (1 == prim_count)
-	{
-		object_info_string.append("1 Primitive");
-	}
-	else
-	{
-		std::string buffer;
-		buffer = llformat( "%d Primitives", prim_count);
-		object_info_string.append(buffer);
-	}
-	childSetText("prim info",object_info_string);
-	childSetEnabled("prim info",true);
-
 	S32 total_sale_price = 0;
 	S32 individual_sale_price = 0;
 	BOOL is_for_sale_mixed = FALSE;
diff --git a/indra/newview/llpanelplace.cpp b/indra/newview/llpanelplace.cpp
index f40c101a4d2ce6aac8303fd906458f237fddf02f..4ae253360a9fe3fbe5fad33835699b90abef0c4e 100644
--- a/indra/newview/llpanelplace.cpp
+++ b/indra/newview/llpanelplace.cpp
@@ -360,6 +360,7 @@ void LLPanelPlace::displayParcelInfo(const LLVector3& pos_region,
 		mDescEditor->setText(getString("server_update_text"));
 	}
 	mSnapshotCtrl->setImageAssetID(LLUUID::null);
+	mSnapshotCtrl->setFallbackImageName("default_land_picture.j2c");
 }
 
 
diff --git a/indra/newview/llprogressview.cpp b/indra/newview/llprogressview.cpp
index c79022a98f304fd80a3182cf1c8e49cc262b7271..897596ea42ba6d301019af83f3fcfc3bafd947de 100644
--- a/indra/newview/llprogressview.cpp
+++ b/indra/newview/llprogressview.cpp
@@ -46,12 +46,14 @@
 #include "llagent.h"
 #include "llbutton.h"
 #include "llfocusmgr.h"
+#include "llprogressbar.h"
 #include "llstartup.h"
 #include "llviewercontrol.h"
 #include "llviewerimagelist.h"
 #include "llviewerwindow.h"
 #include "llappviewer.h"
 #include "llweb.h"
+#include "lluictrlfactory.h"
 
 LLProgressView* LLProgressView::sInstance = NULL;
 
@@ -69,28 +71,28 @@ const S32 ANIMATION_FRAMES = 1; //13;
 LLProgressView::LLProgressView(const std::string& name, const LLRect &rect) 
 :	LLPanel(name, rect, FALSE),
 	mPercentDone( 0.f ),
+	mURLInMessage(false),
 	mMouseDownInActiveArea( false )
 {
-	const S32 CANCEL_BTN_WIDTH = 70;
-	const S32 CANCEL_BTN_OFFSET = 16;
-	LLRect r;
-	r.setOriginAndSize( 
-		getRect().getWidth() - CANCEL_BTN_OFFSET - CANCEL_BTN_WIDTH, CANCEL_BTN_OFFSET,
-		CANCEL_BTN_WIDTH, BTN_HEIGHT );
-	
-	mCancelBtn = new LLButton(std::string("Quit"),
-							  r,
-							  std::string(""),
-							  LLProgressView::onCancelButtonClicked,
-							  NULL );
-	mCancelBtn->setFollows( FOLLOWS_RIGHT | FOLLOWS_BOTTOM );
-	addChild( mCancelBtn );
+	LLUICtrlFactory::getInstance()->buildPanel(this, "panel_progress.xml");
+	reshape(rect.getWidth(), rect.getHeight());
+}
+
+BOOL LLProgressView::postBuild()
+{
+	mProgressBar = getChild<LLProgressBar>("login_progress_bar");
+
+	mCancelBtn = getChild<LLButton>("cancel_btn");
+	mCancelBtn->setClickedCallback(  LLProgressView::onCancelButtonClicked );
 	mFadeTimer.stop();
-	setVisible(FALSE);
 
-	mOutlineRect.set( 0, 0, 0, 0 );
+	getChild<LLTextBox>("title_text")->setText(LLStringExplicit(LLAppViewer::instance()->getSecondLifeTitle()));
+
+	getChild<LLTextBox>("message_text")->setClickedCallback(onClickMessage);
+	getChild<LLTextBox>("message_text")->setCallbackUserData(this);
 
 	sInstance = this;
+	return TRUE;
 }
 
 
@@ -101,59 +103,11 @@ LLProgressView::~LLProgressView()
 	sInstance = NULL;
 }
 
-BOOL LLProgressView::handleMouseDown(S32 x, S32 y, MASK mask)
-{
-	if ( mOutlineRect.pointInRect( x, y ) )
-	{
-		mMouseDownInActiveArea = TRUE;
-		return TRUE;
-	};
-
-	return LLPanel::handleMouseDown(x, y, mask);
-}
-
-BOOL LLProgressView::handleMouseUp(S32 x, S32 y, MASK mask)
-{
-	if ( mOutlineRect.pointInRect( x, y ) )
-	{
-		if ( mMouseDownInActiveArea )
-		{
-			if ( ! mMessage.empty() )
-			{
-				std::string url_to_open( "" );
-
-				size_t start_pos = mMessage.find( "http://" );
-				if ( start_pos != std::string::npos )
-				{
-					size_t end_pos = mMessage.find_first_of( " \n\r\t", start_pos );
-					if ( end_pos != std::string::npos )
-						url_to_open = mMessage.substr( start_pos, end_pos - start_pos );
-					else
-						url_to_open = mMessage.substr( start_pos );
-
-					LLWeb::loadURLExternal( url_to_open );
-				};
-			};
-			return TRUE;
-		};
-	};
-
-	return LLPanel::handleMouseUp(x, y, mask);
-}
-
 BOOL LLProgressView::handleHover(S32 x, S32 y, MASK mask)
 {
 	if( childrenHandleHover( x, y, mask ) == NULL )
 	{
-		lldebugst(LLERR_USER_INPUT) << "hover handled by LLProgressView" << llendl;
-		if ( mOutlineRect.pointInRect( x, y ) )
-		{
-			gViewerWindow->setCursor(UI_CURSOR_ARROW);
-		}
-		else
-		{
-			gViewerWindow->setCursor(UI_CURSOR_WAIT);
-		}
+		gViewerWindow->setCursor(UI_CURSOR_WAIT);
 	}
 	return TRUE;
 }
@@ -181,7 +135,7 @@ void LLProgressView::setVisible(BOOL visible)
 		setFocus(TRUE);
 		mFadeTimer.stop();
 		mProgressTimer.start();
-		LLView::setVisible(visible);
+		LLPanel::setVisible(visible);
 	}
 }
 
@@ -190,19 +144,6 @@ void LLProgressView::draw()
 {
 	static LLTimer timer;
 
-	if (gNoRender)
-	{
-		return;
-	}
-
-	// Make sure the progress view always fills the entire window.
-	S32 width = gViewerWindow->getWindowWidth();
-	S32 height = gViewerWindow->getWindowHeight();
-	if( (width != getRect().getWidth()) || (height != getRect().getHeight()) )
-	{
-		reshape( width, height );
-	}
-
 	// Paint bitmap if we've got one
 	glPushMatrix();
 	if (gStartImageGL)
@@ -211,6 +152,8 @@ void LLProgressView::draw()
 		gGL.getTexUnit(0)->bind(gStartImageGL);
 		gGL.color4f(1.f, 1.f, 1.f, mFadeTimer.getStarted() ? clamp_rescale(mFadeTimer.getElapsedTimeF32(), 0.f, FADE_IN_TIME, 1.f, 0.f) : 1.f);
 		F32 image_aspect = (F32)gStartImageWidth / (F32)gStartImageHeight;
+		S32 width = getRect().getWidth();
+		S32 height = getRect().getHeight();
 		F32 view_aspect = (F32)width / (F32)height;
 		// stretch image to maintain aspect ratio
 		if (image_aspect > view_aspect)
@@ -237,161 +180,37 @@ void LLProgressView::draw()
 	// Handle fade-in animation
 	if (mFadeTimer.getStarted())
 	{
-		LLView::draw();
+		LLPanel::draw();
 		if (mFadeTimer.getElapsedTimeF32() > FADE_IN_TIME)
 		{
 			gFocusMgr.removeTopCtrlWithoutCallback(this);
-			LLView::setVisible(FALSE);
+			LLPanel::setVisible(FALSE);
 			gStartImageGL = NULL;
 		}
 		return;
 	}
 
-	S32 line_x = getRect().getWidth() / 2;
-	S32 line_one_y = getRect().getHeight() / 2 + 64;
-	const S32 LINE_SPACING = 25;
-	S32 line_two_y = line_one_y - LINE_SPACING;
-	const LLFontGL* font = LLFontGL::sSansSerif;
-
-	LLUIImagePtr shadow_imagep = LLUI::getUIImage("rounded_square_soft.tga");
-	LLUIImagePtr bar_fg_imagep = LLUI::getUIImage("progressbar_fill.tga");
-	LLUIImagePtr bar_bg_imagep = LLUI::getUIImage("progressbar_track.tga");
-	LLUIImagePtr bar_imagep = LLUI::getUIImage("rounded_square.tga");
-	
-	LLColor4 background_color = gColors.getColor("LoginProgressBarBgColor");
-
-	F32 alpha = 0.5f + 0.5f*0.5f*(1.f + (F32)sin(3.f*timer.getElapsedTimeF32()));
-	// background_color.mV[3] = background_color.mV[3]*alpha;
-
-	std::string top_line = LLAppViewer::instance()->getSecondLifeTitle();
-
-	S32 bar_bottom = line_two_y - 30;
-	S32 bar_height = 18;
-	S32 bar_width = getRect().getWidth() * 2 / 3;
-	S32 bar_left = (getRect().getWidth() / 2) - (bar_width / 2);
-
-	// translucent outline box
-	S32 background_box_left = ( ( ( getRect().getWidth() / 2 ) - ( bar_width / 2 ) ) / 4 ) * 3;
-	S32 background_box_top = ( getRect().getHeight() / 2 ) + LINE_SPACING * 5;
-	S32 background_box_right = getRect().getWidth() - background_box_left;
-	S32 background_box_bottom = ( getRect().getHeight() / 2 ) - LINE_SPACING * 5;
-	S32 background_box_width = background_box_right - background_box_left + 1;
-	S32 background_box_height = background_box_top - background_box_bottom + 1;
-
-//	shadow_imagep->draw( background_box_left + 2, 
-//									background_box_bottom - 2, 
-//									background_box_width, 
-//									background_box_height,
-//									gColors.getColor( "LoginProgressBoxShadowColor" ) );
-//	bar_outline_imagep->draw( background_box_left, 
-//									background_box_bottom, 
-//									background_box_width, 
-//									background_box_height,
-//									gColors.getColor("LoginProgressBoxBorderColor") );
-
-	bar_imagep->draw( background_box_left + 1,
-									background_box_bottom + 1, 
-									background_box_width - 2,
-									background_box_height - 2,
-									gColors.getColor("LoginProgressBoxCenterColor") );
-
-	// we'll need this later for catching a click if it looks like it contains a link
-	if ( mMessage.find( "http://" ) != std::string::npos )
-		mOutlineRect.set( background_box_left, background_box_top, background_box_right, background_box_bottom );
-	else
-		mOutlineRect.set( 0, 0, 0, 0 );
-
-	// draw loading bar
-	font->renderUTF8(top_line, 0,
-		line_x, line_one_y,
-		//LLColor4::white,
-		gColors.getColor("LoginProgressBoxTextColor"),
-		LLFontGL::HCENTER, LLFontGL::BASELINE,
-		LLFontGL::DROP_SHADOW);
-	font->renderUTF8(mText, 0,
-		line_x, line_two_y,
-		//LLColor4::white,
-		gColors.getColor("LoginProgressBoxTextColor"),
-		LLFontGL::HCENTER, LLFontGL::BASELINE,
-		LLFontGL::DROP_SHADOW);
-		
-//	shadow_imagep->draw(
-//		bar_left + 2, 
-//		bar_bottom - 2, 
-//		bar_width, 
-//		bar_height,
-//		gColors.getColor("LoginProgressBoxShadowColor"));
-
-//	bar_imagep->draw(
-//		bar_left, 
-//		bar_bottom, 
-//		bar_width, 
-//		bar_height,
-//		LLColor4(0.7f, 0.7f, 0.8f, 1.0f));
-
-	bar_bg_imagep->draw(
-		bar_left + 2, 
-		bar_bottom + 2,
-		bar_width - 4, 
-		bar_height - 4,
-		background_color);
-
-	LLColor4 bar_color = gColors.getColor("LoginProgressBarFgColor");
-	bar_color.mV[3] = alpha;
-	bar_fg_imagep->draw(
-		bar_left + 2, 
-		bar_bottom + 2,
-		llround((bar_width - 4) * (mPercentDone / 100.f)), 
-		bar_height - 4,
-		bar_color);
-
-	S32 line_three_y = line_two_y - LINE_SPACING * 3;
-	
-	// draw the message if there is one
-	if(!mMessage.empty())
-	{
-		LLColor4 text_message_color = gColors.getColor("LoginProgressBoxTextColor");
-		LLWString wmessage = utf8str_to_wstring(mMessage);
-		const F32 MAX_PIXELS = 640.0f;
-		S32 chars_left = wmessage.length();
-		S32 chars_this_time = 0;
-		S32 msgidx = 0;
-		while(chars_left > 0)
-		{
-			chars_this_time = font->maxDrawableChars(wmessage.substr(msgidx).c_str(),
-													 MAX_PIXELS,
-													 MAX_STRING - 1,
-													 TRUE);
-			LLWString wbuffer = wmessage.substr(msgidx, chars_this_time);
-			font->render(wbuffer, 0,
-						 (F32)line_x, (F32)line_three_y,
-						 //LLColor4::white,
-						 gColors.getColor("LoginProgressBoxTextColor"),
-						 LLFontGL::HCENTER, LLFontGL::BASELINE,
-						 LLFontGL::DROP_SHADOW);
-			msgidx += chars_this_time;
-			chars_left -= chars_this_time;
-			line_three_y -= LINE_SPACING;
-		}
-	}
-
 	// draw children
-	LLView::draw();
+	LLPanel::draw();
 }
 
 void LLProgressView::setText(const std::string& text)
 {
-	mText = text;
+	getChild<LLTextBox>("progress_text")->setWrappedText(LLStringExplicit(text));
 }
 
 void LLProgressView::setPercent(const F32 percent)
 {
-	mPercentDone = llclamp(percent, 0.f, 100.f);
+	mProgressBar->setPercent(percent);
 }
 
 void LLProgressView::setMessage(const std::string& msg)
 {
 	mMessage = msg;
+	mURLInMessage = mMessage.find( "http://" ) != std::string::npos;
+
+	getChild<LLTextBox>("message_text")->setWrappedText(LLStringExplicit(mMessage));
+	getChild<LLTextBox>("message_text")->setHoverActive(mURLInMessage);
 }
 
 void LLProgressView::setCancelButtonVisible(BOOL b, const std::string& label)
@@ -416,3 +235,25 @@ void LLProgressView::onCancelButtonClicked(void*)
 		sInstance->setVisible(FALSE);
 	}
 }
+
+// static
+void LLProgressView::onClickMessage(void* data)
+{
+	LLProgressView* viewp = (LLProgressView*)data;
+	if ( ! viewp->mMessage.empty() )
+	{
+		std::string url_to_open( "" );
+
+		size_t start_pos = viewp->mMessage.find( "http://" );
+		if ( start_pos != std::string::npos )
+		{
+			size_t end_pos = viewp->mMessage.find_first_of( " \n\r\t", start_pos );
+			if ( end_pos != std::string::npos )
+				url_to_open = viewp->mMessage.substr( start_pos, end_pos - start_pos );
+			else
+				url_to_open = viewp->mMessage.substr( start_pos );
+
+			LLWeb::loadURLExternal( url_to_open );
+		}
+	}
+}
diff --git a/indra/newview/llprogressview.h b/indra/newview/llprogressview.h
index 84ae8f6e825d69ccd59483cbede6b9289fdc645d..d29439635ee5d59723cd18e06d510097e5ed1aee 100644
--- a/indra/newview/llprogressview.h
+++ b/indra/newview/llprogressview.h
@@ -37,16 +37,17 @@
 
 class LLImageRaw;
 class LLButton;
+class LLProgressBar;
 
 class LLProgressView : public LLPanel
 {
 public:
 	LLProgressView(const std::string& name, const LLRect& rect);
 	virtual ~LLProgressView();
+	
+	BOOL postBuild();
 
 	/*virtual*/ void draw();
-	/*virtual*/ BOOL handleMouseDown(S32 x, S32 y, MASK mask);
-	/*virtual*/ BOOL handleMouseUp(S32 x, S32 y, MASK mask);
 
 	/*virtual*/ BOOL handleHover(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL handleKeyHere(KEY key, MASK mask);
@@ -61,16 +62,18 @@ class LLProgressView : public LLPanel
 	void setCancelButtonVisible(BOOL b, const std::string& label);
 
 	static void onCancelButtonClicked( void* );
+	static void onClickMessage(void*);
 
 protected:
+	LLProgressBar* mProgressBar;
 	F32 mPercentDone;
-	std::string mText;
 	std::string mMessage;
 	LLButton*	mCancelBtn;
 	LLFrameTimer	mFadeTimer;
 	LLFrameTimer mProgressTimer;
 	LLRect mOutlineRect;
 	bool mMouseDownInActiveArea;
+	bool mURLInMessage;
 
 	static LLProgressView* sInstance;
 };
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ca310cf8e47e7ab615e27f6bde0a63c24a97525b..3de0cf80ce5849e10662d39106c90559ad40773f 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -113,6 +113,7 @@
 #include "llinventorymodel.h"
 #include "llinventoryview.h"
 #include "llkeyboard.h"
+#include "llloginhandler.h"			// gLoginHandler, SLURL support
 #include "llpanellogin.h"
 #include "llmutelist.h"
 #include "llnotify.h"
@@ -654,16 +655,23 @@ bool idle_startup()
 		//
 		// Log on to system
 		//
-		if ((!gLoginHandler.mFirstName.empty() &&
-			 !gLoginHandler.mLastName.empty() &&
-			 !gLoginHandler.mWebLoginKey.isNull())		
-			|| gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand) )
+		if (!LLStartUp::sSLURLCommand.empty())
 		{
-			firstname = gLoginHandler.mFirstName;
-			lastname = gLoginHandler.mLastName;
-			web_login_key = gLoginHandler.mWebLoginKey;
+			// this might be a secondlife:///app/login URL
+			gLoginHandler.parseDirectLogin(LLStartUp::sSLURLCommand);
+		}
+		if (!gLoginHandler.getFirstName().empty()
+			|| !gLoginHandler.getLastName().empty()
+			|| !gLoginHandler.getWebLoginKey().isNull() )
+		{
+			// We have at least some login information on a SLURL
+			firstname = gLoginHandler.getFirstName();
+			lastname = gLoginHandler.getLastName();
+			web_login_key = gLoginHandler.getWebLoginKey();
 
-			show_connect_box = false;
+			// Show the login screen if we don't have everything
+			show_connect_box = 
+				firstname.empty() || lastname.empty() || web_login_key.isNull();
 		}
         else if(gSavedSettings.getLLSD("UserLoginInfo").size() == 3)
         {
@@ -814,11 +822,11 @@ bool idle_startup()
 	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
 	{
 		//reset the values that could have come in from a slurl
-		if (!gLoginHandler.mWebLoginKey.isNull())
+		if (!gLoginHandler.getWebLoginKey().isNull())
 		{
-			firstname = gLoginHandler.mFirstName;
-			lastname = gLoginHandler.mLastName;
-			web_login_key = gLoginHandler.mWebLoginKey;
+			firstname = gLoginHandler.getFirstName();
+			lastname = gLoginHandler.getLastName();
+			web_login_key = gLoginHandler.getWebLoginKey();
 		}
 				
 		if (show_connect_box)
@@ -1779,6 +1787,8 @@ bool idle_startup()
 			gFrameIntervalSeconds = 0.f;
 		}
 
+		// Initialize FOV
+		LLViewerCamera::getInstance()->setView(gSavedSettings.getF32("CameraAngle")); 
 		// Make sure agent knows correct aspect ratio
 		LLViewerCamera::getInstance()->setViewHeightInPixels(gViewerWindow->getWindowDisplayHeight());
 		if (gViewerWindow->mWindow->getFullscreen())
@@ -3947,8 +3957,9 @@ bool LLStartUp::dispatchURL()
 	// ok, if we've gotten this far and have a startup URL
 	if (!sSLURLCommand.empty())
 	{
-		const bool from_external_browser = true;
-		LLURLDispatcher::dispatch(sSLURLCommand, from_external_browser);
+		LLWebBrowserCtrl* web = NULL;
+		const bool trusted_browser = false;
+		LLURLDispatcher::dispatch(sSLURLCommand, web, trusted_browser);
 	}
 	else if (LLURLSimString::parse())
 	{
@@ -3964,8 +3975,9 @@ bool LLStartUp::dispatchURL()
 			|| (dy*dy > SLOP*SLOP) )
 		{
 			std::string url = LLURLSimString::getURL();
-			const bool from_external_browser = true;
-			LLURLDispatcher::dispatch(url, from_external_browser);
+			LLWebBrowserCtrl* web = NULL;
+			const bool trusted_browser = false;
+			LLURLDispatcher::dispatch(url, web, trusted_browser);
 		}
 		return true;
 	}
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index ac80f1b66924317a0ead67b6811b89908249081c..278f7ea9d140662a4e740c97a158e8c68c551fc3 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -757,7 +757,7 @@ static void onClickParcelInfo(void* data)
 
 static void onClickBalance(void* data)
 {
-	LLFloaterBuyCurrency::buyCurrency();
+	onClickBuyCurrency(data);
 }
 
 static void onClickBuyCurrency(void* data)
diff --git a/indra/newview/llstylemap.cpp b/indra/newview/llstylemap.cpp
index 2d3fb566e0816acdc645aff9fb0161cb6be8900f..bc8c353de04d8b5a4216c4bc877f3f530d022ac2 100644
--- a/indra/newview/llstylemap.cpp
+++ b/indra/newview/llstylemap.cpp
@@ -47,13 +47,13 @@ LLStyleMap::~LLStyleMap()
 
 LLStyleMap &LLStyleMap::instance()
 {
-	static LLStyleMap mStyleMap;
-	return mStyleMap;
+	static LLStyleMap style_map;
+	return style_map;
 }
 
 // This is similar to the [] accessor except that if the entry doesn't already exist,
 // then this will create the entry.
-const LLStyleSP &LLStyleMap::lookup(const LLUUID &source)
+const LLStyleSP &LLStyleMap::lookupAgent(const LLUUID &source)
 {
 	// Find this style in the map or add it if not.  This map holds links to residents' profiles.
 	if (find(source) == end())
@@ -77,6 +77,37 @@ const LLStyleSP &LLStyleMap::lookup(const LLUUID &source)
 	return (*this)[source];
 }
 
+// This is similar to lookupAgent for any generic URL encoded style.
+const LLStyleSP &LLStyleMap::lookup(const LLUUID& id, const std::string& link)
+{
+	// Find this style in the map or add it if not.
+	iterator iter = find(id);
+	if (iter == end())
+	{
+		LLStyleSP style(new LLStyle);
+		style->setVisible(true);
+		style->setFontName(LLStringUtil::null);
+		if (id != LLUUID::null && !link.empty())
+		{
+			style->setColor(gSavedSettings.getColor4("HTMLLinkColor"));
+			style->setLinkHREF(link);
+		}
+		else
+			style->setColor(LLColor4::white);
+		(*this)[id] = style;
+	}
+	else 
+	{
+		LLStyleSP style = (*iter).second;
+		if ( style->getLinkHREF() != link )
+		{
+			style->setLinkHREF(link);
+		}
+	}
+
+	return (*this)[id];
+}
+
 void LLStyleMap::update()
 {
 	for (style_map_t::iterator iter = begin(); iter != end(); ++iter)
diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h
index fbf12a04a38b761e21fea7ba3c423476d7641eaf..8d9da8e3b24103e1f6a4b34413e48e2cb99974f5 100644
--- a/indra/newview/llstylemap.h
+++ b/indra/newview/llstylemap.h
@@ -47,7 +47,8 @@ class LLStyleMap : public style_map_t
 	LLStyleMap();
 	~LLStyleMap();
 	// Just like the [] accessor but it will add the entry in if it doesn't exist.
-	const LLStyleSP &lookup(const LLUUID &source); 
+	const LLStyleSP &lookupAgent(const LLUUID &source); 
+	const LLStyleSP &lookup(const LLUUID &source, const std::string& link); 
 	static LLStyleMap &instance();
 
 	// Forces refresh of the entries, call when something changes (e.g. link color).
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 7bdea15ac449e25912abc913c8754d23d498811f..29dbc08fae107d025d8a5c1c7780ca571dc56a2f 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -111,7 +111,9 @@ class LLFloaterTexturePicker : public LLFloater
 		const std::string& label,
 		PermissionMask immediate_filter_perm_mask,
 		PermissionMask non_immediate_filter_perm_mask,
-		BOOL can_apply_immediately);
+		BOOL can_apply_immediately,
+		const std::string& fallback_image_name);
+
 	virtual ~LLFloaterTexturePicker();
 
 	// LLView overrides
@@ -164,12 +166,13 @@ class LLFloaterTexturePicker : public LLFloater
 	LLTextureCtrl*		mOwner;
 
 	LLUUID				mImageAssetID; // Currently selected texture
+	std::string			mFallbackImageName; // What to show if currently selected texture is null.
 
 	LLUUID				mWhiteImageAssetID;
 	LLUUID				mSpecialCurrentImageAssetID;  // Used when the asset id has no corresponding texture in the user's inventory.
 	LLUUID				mOriginalImageAssetID;
 
-	std::string         mLabel;
+	std::string			mLabel;
 
 	LLTextBox*			mTentativeLabel;
 	LLTextBox*			mResolutionLabel;
@@ -194,7 +197,8 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 	const std::string& label,
 	PermissionMask immediate_filter_perm_mask,
 	PermissionMask non_immediate_filter_perm_mask,
-	BOOL can_apply_immediately)
+	BOOL can_apply_immediately,
+	const std::string& fallback_image_name)
 	:
 	LLFloater( std::string("texture picker"),
 		rect,
@@ -203,6 +207,7 @@ LLFloaterTexturePicker::LLFloaterTexturePicker(
 		TEX_PICKER_MIN_WIDTH, TEX_PICKER_MIN_HEIGHT ),
 	mOwner( owner ),
 	mImageAssetID( owner->getImageAssetID() ),
+	mFallbackImageName( fallback_image_name ),
 	mWhiteImageAssetID( gSavedSettings.getString( "UIImgWhiteUUID" ) ),
 	mOriginalImageAssetID(owner->getImageAssetID()),
 	mLabel(label),
@@ -549,6 +554,11 @@ void LLFloaterTexturePicker::draw()
 			mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
 			mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
 		}
+		else if (!mFallbackImageName.empty())
+		{
+			mTexturep = gImageList.getImageFromFile(mFallbackImageName);
+			mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+		}
 
 		if (mTentativeLabel)
 		{
@@ -1130,7 +1140,9 @@ void LLTextureCtrl::showPicker(BOOL take_focus)
 			mLabel,
 			mImmediateFilterPermMask,
 			mNonImmediateFilterPermMask,
-			mCanApplyImmediately);
+			mCanApplyImmediately,
+			mFallbackImageName);
+
 		mFloaterHandle = floaterp->getHandle();
 
 		gFloaterView->getParentFloater(this)->addDependentFloater(floaterp);
@@ -1289,15 +1301,21 @@ void LLTextureCtrl::draw()
 {
 	mBorder->setKeyboardFocusHighlight(hasFocus());
 
-	if (mImageAssetID.isNull() || !mValid)
+	if (!mValid)
 	{
 		mTexturep = NULL;
 	}
-	else
+	else if (!mImageAssetID.isNull())
 	{
 		mTexturep = gImageList.getImage(mImageAssetID, MIPMAP_YES, IMMEDIATE_NO);
 		mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
 	}
+	else if (!mFallbackImageName.empty())
+	{
+		// Show fallback image.
+		mTexturep = gImageList.getImageFromFile(mFallbackImageName);
+		mTexturep->setBoostLevel(LLViewerImage::BOOST_PREVIEW);
+	}
 	
 	// Border
 	LLRect border( 0, getRect().getHeight(), getRect().getWidth(), BTN_HEIGHT_SMALL );
diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h
index cf83c628b84d2b12a1570d4d1e23e7c0ab021436..5e369ec29ec2b3ea1b4b83a118b05c497a755377 100644
--- a/indra/newview/lltexturectrl.h
+++ b/indra/newview/lltexturectrl.h
@@ -115,9 +115,12 @@ class LLTextureCtrl
 	const LLUUID&	getImageAssetID() const						{ return mImageAssetID; }
 
 	void			setDefaultImageAssetID( const LLUUID& id )	{ mDefaultImageAssetID = id; }
+	const LLUUID&	getDefaultImageAssetID() const { return mDefaultImageAssetID; }
 
 	const std::string&	getDefaultImageName() const					{ return mDefaultImageName; }
-	const LLUUID&	getDefaultImageAssetID() const				{ return mDefaultImageAssetID; }
+
+	void			setFallbackImageName( const std::string& name ) { mFallbackImageName = name; }			
+	const std::string& 	getFallbackImageName() const { return mFallbackImageName; }	   
 
 	void			setCaption(const std::string& caption);
 	void			setCanApplyImmediately(BOOL b);
@@ -163,6 +166,7 @@ class LLTextureCtrl
 	LLUUID					 mImageItemID;
 	LLUUID					 mImageAssetID;
 	LLUUID					 mDefaultImageAssetID;
+	std::string				 mFallbackImageName;
 	std::string				 mDefaultImageName;
 	LLHandle<LLFloater>			 mFloaterHandle;
 	LLTextBox*				 mTentativeLabel;
diff --git a/indra/newview/llurldispatcher.cpp b/indra/newview/llurldispatcher.cpp
index 5f26155bc0eb574513b2d7be7d8829c6761f723e..477146a473b45dcd4c206e550da89984930f8740 100644
--- a/indra/newview/llurldispatcher.cpp
+++ b/indra/newview/llurldispatcher.cpp
@@ -64,26 +64,33 @@ class LLURLDispatcherImpl
 
 	static bool isSLURLCommand(const std::string& url);
 
-	static bool dispatch(const std::string& url, bool from_external_browser);
+	static bool dispatch(const std::string& url,
+						 LLWebBrowserCtrl* web,
+						 bool trusted_browser);
 		// returns true if handled or explicitly blocked.
 
 	static bool dispatchRightClick(const std::string& url);
 
 private:
 	static bool dispatchCore(const std::string& url, 
-		bool from_external_browser, bool right_mouse);
+							 bool right_mouse,
+							 LLWebBrowserCtrl* web,
+							 bool trusted_browser);
 		// handles both left and right click
 
-	static bool dispatchHelp(const std::string& url, BOOL right_mouse);
+	static bool dispatchHelp(const std::string& url, bool right_mouse);
 		// Handles sl://app.floater.html.help by showing Help floater.
 		// Returns true if handled.
 
-	static bool dispatchApp(const std::string& url, bool from_external_browser, BOOL right_mouse);
+	static bool dispatchApp(const std::string& url,
+							bool right_mouse,
+							LLWebBrowserCtrl* web,
+							bool trusted_browser);
 		// Handles secondlife:///app/agent/<agent_id>/about and similar
 		// by showing panel in Search floater.
 		// Returns true if handled or explicitly blocked.
 
-	static bool dispatchRegion(const std::string& url, BOOL right_mouse);
+	static bool dispatchRegion(const std::string& url, bool right_mouse);
 		// handles secondlife://Ahern/123/45/67/
 		// Returns true if handled.
 
@@ -127,11 +134,14 @@ bool LLURLDispatcherImpl::isSLURLCommand(const std::string& url)
 }
 
 // static
-bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool from_external_browser, bool right_mouse)
+bool LLURLDispatcherImpl::dispatchCore(const std::string& url,
+									   bool right_mouse,
+									   LLWebBrowserCtrl* web,
+									   bool trusted_browser)
 {
 	if (url.empty()) return false;
 	if (dispatchHelp(url, right_mouse)) return true;
-	if (dispatchApp(url, from_external_browser, right_mouse)) return true;
+	if (dispatchApp(url, right_mouse, web, trusted_browser)) return true;
 	if (dispatchRegion(url, right_mouse)) return true;
 
 	/*
@@ -145,23 +155,27 @@ bool LLURLDispatcherImpl::dispatchCore(const std::string& url, bool from_externa
 }
 
 // static
-bool LLURLDispatcherImpl::dispatch(const std::string& url, bool from_external_browser)
+bool LLURLDispatcherImpl::dispatch(const std::string& url,
+								   LLWebBrowserCtrl* web,
+								   bool trusted_browser)
 {
 	llinfos << "url: " << url << llendl;
 	const bool right_click = false;
-	return dispatchCore(url, from_external_browser, right_click);
+	return dispatchCore(url, right_click, web, trusted_browser);
 }
 
 // static
 bool LLURLDispatcherImpl::dispatchRightClick(const std::string& url)
 {
 	llinfos << "url: " << url << llendl;
-	const bool from_external_browser = false;
 	const bool right_click = true;
-	return dispatchCore(url, from_external_browser, right_click);
+	LLWebBrowserCtrl* web = NULL;
+	const bool trusted_browser = false;
+	return dispatchCore(url, right_click, web, trusted_browser);
 }
+
 // static
-bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse)
+bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, bool right_mouse)
 {
 #if LL_LIBXUL_ENABLED
 	if (matchPrefix(url, SLURL_SL_HELP_PREFIX))
@@ -175,8 +189,9 @@ bool LLURLDispatcherImpl::dispatchHelp(const std::string& url, BOOL right_mouse)
 
 // static
 bool LLURLDispatcherImpl::dispatchApp(const std::string& url, 
-									  bool from_external_browser,
-									  BOOL right_mouse)
+									  bool right_mouse,
+									  LLWebBrowserCtrl* web,
+									  bool trusted_browser)
 {
 	if (!isSLURL(url))
 	{
@@ -189,12 +204,12 @@ bool LLURLDispatcherImpl::dispatchApp(const std::string& url,
 	std::string cmd = pathArray.get(0);
 	pathArray.erase(0); // erase "cmd"
 	bool handled = LLCommandDispatcher::dispatch(
-			cmd, from_external_browser, pathArray, uri.queryMap());
+			cmd, pathArray, uri.queryMap(), web, trusted_browser);
 	return handled;
 }
 
 // static
-bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, BOOL right_mouse)
+bool LLURLDispatcherImpl::dispatchRegion(const std::string& url, bool right_mouse)
 {
 	if (!isSLURL(url))
 	{
@@ -359,10 +374,13 @@ std::string LLURLDispatcherImpl::stripProtocol(const std::string& url)
 class LLTeleportHandler : public LLCommandHandler
 {
 public:
-	// not allowed from outside the app
-	LLTeleportHandler() : LLCommandHandler("teleport", false) { }
+	// Teleport requests *must* come from a trusted browser
+	// inside the app, otherwise a malicious web page could
+	// cause a constant teleport loop.  JC
+	LLTeleportHandler() : LLCommandHandler("teleport", true) { }
 
-	bool handle(const LLSD& tokens, const LLSD& queryMap)
+	bool handle(const LLSD& tokens, const LLSD& query_map,
+				LLWebBrowserCtrl* web)
 	{
 		// construct a "normal" SLURL, resolve the region to
 		// a global position, and teleport to it
@@ -401,10 +419,13 @@ bool LLURLDispatcher::isSLURLCommand(const std::string& url)
 }
 
 // static
-bool LLURLDispatcher::dispatch(const std::string& url, bool from_external_browser)
+bool LLURLDispatcher::dispatch(const std::string& url,
+							   LLWebBrowserCtrl* web,
+							   bool trusted_browser)
 {
-	return LLURLDispatcherImpl::dispatch(url, from_external_browser);
+	return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
 }
+
 // static
 bool LLURLDispatcher::dispatchRightClick(const std::string& url)
 {
@@ -414,13 +435,20 @@ bool LLURLDispatcher::dispatchRightClick(const std::string& url)
 // static
 bool LLURLDispatcher::dispatchFromTextEditor(const std::string& url)
 {
-	// text editors are by definition internal to our code
-	const bool from_external_browser = false;
-	return LLURLDispatcherImpl::dispatch(url, from_external_browser);
+	// *NOTE: Text editors are considered sources of trusted URLs
+	// in order to make objectim and avatar profile links in chat
+	// history work.  While a malicious resident could chat an app
+	// SLURL, the receiving resident will see it and must affirmatively
+	// click on it.
+	// *TODO: Make this trust model more refined.  JC
+	const bool trusted_browser = true;
+	LLWebBrowserCtrl* web = NULL;
+	return LLURLDispatcherImpl::dispatch(url, web, trusted_browser);
 }
 
 // static
-std::string LLURLDispatcher::buildSLURL(const std::string& regionname, S32 x, S32 y, S32 z)
+std::string LLURLDispatcher::buildSLURL(const std::string& regionname,
+										S32 x, S32 y, S32 z)
 {
 	std::string slurl = SLURL_SLURL_PREFIX + regionname + llformat("/%d/%d/%d",x,y,z); 
 	slurl = LLWeb::escapeURL( slurl );
diff --git a/indra/newview/llurldispatcher.h b/indra/newview/llurldispatcher.h
index a8629626b1b74f5609f134b0c948fefe28bd672e..6640ca11b359426a32ab69af50ea569bb76405c5 100644
--- a/indra/newview/llurldispatcher.h
+++ b/indra/newview/llurldispatcher.h
@@ -31,6 +31,9 @@
 #ifndef LLURLDISPATCHER_H
 #define LLURLDISPATCHER_H
 
+class LLWebBrowserCtrl;
+
+
 class LLURLDispatcher
 {
 public:
@@ -40,13 +43,20 @@ class LLURLDispatcher
 	static bool isSLURLCommand(const std::string& url);
 		// Is this a special secondlife://app/ URL?
 
-	static bool dispatch(const std::string& url, bool from_external_browser);
+	static bool dispatch(const std::string& url,
+						 LLWebBrowserCtrl* web,
+						 bool trusted_browser);
 		// At startup time and on clicks in internal web browsers,
 		// teleport, open map, or run requested command.
-		// Handles:
+		// @param url
 		//   secondlife://RegionName/123/45/67/
 		//   secondlife:///app/agent/3d6181b0-6a4b-97ef-18d8-722652995cf1/show
 		//   sl://app/foo/bar
+		// @param web
+		//	 Pointer to LLWebBrowserCtrl sending URL, can be NULL
+		// @param trusted_browser
+		//   True if coming inside the app AND from a brower instance
+		//   that navigates to trusted (Linden Lab) pages.
 		// Returns true if someone handled the URL.
 
 	static bool dispatchRightClick(const std::string& url);
diff --git a/indra/newview/llviewercamera.cpp b/indra/newview/llviewercamera.cpp
index 5f6fcb70e3c7a6116cf4860042089f66274ea6d4..f9ced0f53fdc0bd7b03b999494b9ba5c5a23e85f 100644
--- a/indra/newview/llviewercamera.cpp
+++ b/indra/newview/llviewercamera.cpp
@@ -138,9 +138,9 @@ void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
 	mVelocityStat.addValue(dpos);
 	mAngularVelocityStat.addValue(drot);
 	// update pixel meter ratio using default fov, not modified one
-	mPixelMeterRatio = mViewHeightInPixels / (2.f*tanf(mCameraFOVDefault*0.5));
+	mPixelMeterRatio = getViewHeightInPixels()/ (2.f*tanf(mCameraFOVDefault*0.5));
 	// update screen pixel area
-	mScreenPixelArea =(S32)((F32)mViewHeightInPixels * ((F32)mViewHeightInPixels * mAspect));
+	mScreenPixelArea =(S32)((F32)getViewHeightInPixels() * ((F32)getViewHeightInPixels() * getAspect()));
 }
 
 const LLMatrix4 &LLViewerCamera::getProjection() const
@@ -732,3 +732,38 @@ BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
 	}
 	return all_verts;
 }
+
+// changes local camera and broadcasts change
+/* virtual */ void LLViewerCamera::setView(F32 vertical_fov_rads)
+{
+	F32 old_fov = LLViewerCamera::getInstance()->getDefaultFOV();
+
+	// cap the FoV
+	vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
+
+	if (vertical_fov_rads == old_fov) return;
+
+	// send the new value to the simulator
+	LLMessageSystem* msg = gMessageSystem;
+	msg->newMessageFast(_PREHASH_AgentFOV);
+	msg->nextBlockFast(_PREHASH_AgentData);
+	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
+	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
+	msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
+
+	msg->nextBlockFast(_PREHASH_FOVBlock);
+	msg->addU32Fast(_PREHASH_GenCounter, 0);
+	msg->addF32Fast(_PREHASH_VerticalAngle, vertical_fov_rads);
+
+	gAgent.sendReliableMessage();
+
+	// sync the camera with the new value
+	LLCamera::setView(vertical_fov_rads); // call base implementation
+}
+
+void LLViewerCamera::setDefaultFOV(F32 vertical_fov_rads) {
+	vertical_fov_rads = llclamp(vertical_fov_rads, getMinView(), getMaxView());
+	setView(vertical_fov_rads);
+	mCameraFOVDefault = vertical_fov_rads; 
+}
+
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index cc37851d050667b1132b965a9b0fef7ff55fb651..8aec405bf0da74432e930353d76d08b47fbecd7b 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -55,9 +55,6 @@ class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
 public:
 	LLViewerCamera();
 
-//	const LLVector3 &getPositionAgent() const;
-//	const LLVector3d &getPositionGlobal() const;
-
 	void updateCameraLocation(const LLVector3 &center,
 								const LLVector3 &up_direction,
 								const LLVector3 &point_of_interest);
@@ -80,7 +77,10 @@ class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
 	void getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right);
 	LLVector3 roundToPixel(const LLVector3 &pos_agent);
 
-	void setDefaultFOV(F32 fov) { mCameraFOVDefault = fov; }
+	// Sets the current matrix
+	/* virtual */ void setView(F32 vertical_fov_rads);
+	// Sets the current matrix AND remembers result as default view
+	void setDefaultFOV(F32 vertical_fov_rads);
 	F32 getDefaultFOV() { return mCameraFOVDefault; }
 
 	BOOL cameraUnderWater() const;
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index e8ce3e02eac9f2812d9116760d15e5f7f68bc116..6e37e6253f07d0676de2f4b1f7e3c194d5c4e932 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -107,6 +107,7 @@
 #include "llfloatergroups.h"
 #include "llfloaterhtml.h"
 #include "llfloaterhtmlhelp.h"
+#include "llfloaterhtmlsimple.h"
 #include "llfloaterhud.h"
 #include "llfloaterinspect.h"
 #include "llfloaterlagmeter.h"
@@ -116,6 +117,7 @@
 #include "llfloatermute.h"
 #include "llfloateropenobject.h"
 #include "llfloaterpermissionsmgr.h"
+#include "llfloaterperms.h"
 #include "llfloaterpostprocess.h"
 #include "llfloaterpreference.h"
 #include "llfloaterregioninfo.h"
@@ -329,7 +331,6 @@ void handle_agent_stop_moving(void*);
 void print_packets_lost(void*);
 void drop_packet(void*);
 void velocity_interpolate( void* data );
-void update_fov(S32 increments);
 void toggle_wind_audio(void);
 void toggle_water_audio(void);
 void handle_rebake_textures(void*);
@@ -358,7 +359,8 @@ void run_vectorize_perf_test(void *)
 
 // Debug UI
 void handle_web_search_demo(void*);
-void handle_slurl_test(void*);
+void handle_web_browser_test(void*);
+void handle_buy_currency_test(void*);
 void handle_save_to_xml(void*);
 void handle_load_from_xml(void*);
 
@@ -1018,7 +1020,8 @@ extern BOOL gDebugSelectMgr;
 
 void init_debug_ui_menu(LLMenuGL* menu)
 {
-	menu->append(new LLMenuItemCallGL("SLURL Test", &handle_slurl_test));
+	menu->append(new LLMenuItemCallGL("Web Browser Test", &handle_web_browser_test));
+	menu->append(new LLMenuItemCallGL("Buy Currency Test", &handle_buy_currency_test));
 	menu->append(new LLMenuItemCallGL("Editable UI", &edit_ui));
 	menu->append(new LLMenuItemToggleGL("Async Keystrokes", &gHandleKeysAsync));
 	menu->append(new LLMenuItemCallGL( "Dump SelectMgr", &dump_select_mgr));
@@ -3048,86 +3051,6 @@ void velocity_interpolate( void* data )
 }
 
 
-void update_fov(S32 increments)
-{
-	F32 old_fov = LLViewerCamera::getInstance()->getDefaultFOV();
-	// for each increment, FoV is 20% bigger
-	F32 new_fov = old_fov * pow(1.2f, increments);
-
-	// cap the FoV
-	new_fov = llclamp(new_fov, MIN_FIELD_OF_VIEW, MAX_FIELD_OF_VIEW);
-
-	if (new_fov != old_fov)
-	{
-		LLMessageSystem* msg = gMessageSystem;
-		msg->newMessageFast(_PREHASH_AgentFOV);
-		msg->nextBlockFast(_PREHASH_AgentData);
-		msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-		msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-		msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
-
-		msg->nextBlockFast(_PREHASH_FOVBlock);
-		msg->addU32Fast(_PREHASH_GenCounter, 0);
-		msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
-
-		gAgent.sendReliableMessage();
-
-		// force agent to update dirty patches
-		LLViewerCamera::getInstance()->setDefaultFOV(new_fov);
-		LLViewerCamera::getInstance()->setView(new_fov);
-	}
-}
-
-class LLViewZoomOut : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		update_fov(1);
-		return true;
-	}
-};
-
-class LLViewZoomIn : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		update_fov(-1);
-		return true;
-	}
-};
-
-class LLViewZoomDefault : public view_listener_t
-{
-	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
-	{
-		F32 old_fov = LLViewerCamera::getInstance()->getView();
-		// for each increment, FoV is 20% bigger
-		F32 new_fov = DEFAULT_FIELD_OF_VIEW;
-
-		if (new_fov != old_fov)
-		{
-			LLMessageSystem* msg = gMessageSystem;
-			msg->newMessageFast(_PREHASH_AgentFOV);
-			msg->nextBlockFast(_PREHASH_AgentData);
-			msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-			msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-			msg->addU32Fast(_PREHASH_CircuitCode, gMessageSystem->mOurCircuitCode);
-			msg->nextBlockFast(_PREHASH_FOVBlock);
-			msg->addU32Fast(_PREHASH_GenCounter, 0);
-			msg->addF32Fast(_PREHASH_VerticalAngle, new_fov);
-
-			gAgent.sendReliableMessage();
-
-			// force agent to update dirty patches
-			LLViewerCamera::getInstance()->setDefaultFOV(new_fov);
-			LLViewerCamera::getInstance()->setView(new_fov);
-		}
-		return true;
-	}
-};
-
-
-
 void toggle_wind_audio(void)
 {
 	if (gAudiop)
@@ -4291,12 +4214,7 @@ class LLToolsStopAllAnimations : public view_listener_t
 {
 	bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
 	{
-		LLVOAvatar* avatarp = gAgent.getAvatarObject();		
-		if (avatarp)
-		{
-			avatarp->deactivateAllMotions();	
-			avatarp->startDefaultMotions();
-		}
+		gAgent.stopCurrentAnimations();
 		return true;
 	}
 };
@@ -5291,6 +5209,10 @@ class LLShowFloater : public view_listener_t
 		{
 			LLFloaterBeacons::toggleInstance(LLSD());
 		}
+		else if (floater_name == "perm prefs")
+		{
+			LLFloaterPerms::toggleInstance(LLSD());
+		}
 		return true;
 	}
 };
@@ -5474,7 +5396,6 @@ class LLLandEdit : public view_listener_t
 
 		LLViewerParcelMgr::getInstance()->selectParcelAt( LLToolPie::getInstance()->getPick().mPosGlobal );
 
-		gFloaterTools->showMore(TRUE);
 		gFloaterView->bringToFront( gFloaterTools );
 
 		// Switch to land edit toolset
@@ -7003,7 +6924,7 @@ void handle_save_to_xml(void*)
 	LLFloater* frontmost = gFloaterView->getFrontmost();
 	if (!frontmost)
 	{
-        gViewerWindow->alertXml("NoFrontmostFloater");
+		gViewerWindow->alertXml("NoFrontmostFloater");
 		return;
 	}
 
@@ -7036,17 +6957,54 @@ void handle_load_from_xml(void*)
 	}
 }
 
-void handle_slurl_test(void*)
+void handle_web_browser_test(void*)
 {
 	const bool open_links_externally = false;
 	const bool open_app_slurls = true;
 	LLFloaterHtml::getInstance()->show(
 		"http://secondlife.com/app/search/slurls.html",
-		"SLURL Test", 
+		"Web Browser Test", 
 		open_links_externally, 
 		open_app_slurls);
 }
 
+void handle_buy_currency_test(void*)
+{
+	std::string url =
+		"http://sarahd-sl-13041.webdev.lindenlab.com/app/lindex/index.php?agent_id=[AGENT_ID]&secure_session_id=[SESSION_ID]&lang=[LANGUAGE]";
+
+	LLStringUtil::format_map_t replace;
+	replace["[AGENT_ID]"] = gAgent.getID().asString();
+	replace["[SESSION_ID]"] = gAgent.getSecureSessionID().asString();
+
+	// *TODO: Replace with call to LLUI::getLanguage() after windows-setup
+	// branch merges in. JC
+	std::string language = "en-us";
+	language = gSavedSettings.getString("Language");
+	if (language.empty() || language == "default")
+	{
+		language = gSavedSettings.getString("InstallLanguage");
+	}
+	if (language.empty() || language == "default")
+	{
+		language = gSavedSettings.getString("SystemLanguage");
+	}
+	if (language.empty() || language == "default")
+	{
+		language = "en-us";
+	}
+
+	replace["[LANGUAGE]"] = language;
+	LLStringUtil::format(url, replace);
+
+	llinfos << "buy currency url " << url << llendl;
+
+	LLFloaterHtmlSimple* floater = LLFloaterHtmlSimple::showInstance(url);
+	// Needed so we can use secondlife:///app/floater/self/close SLURLs
+	floater->setTrusted(true);
+	floater->center();
+}
+
 void handle_rebake_textures(void*)
 {
 	LLVOAvatar* avatar = gAgent.getAvatarObject();
@@ -7418,6 +7376,24 @@ static void addMenu(view_listener_t *menu, const std::string& name)
 
 void initialize_menus()
 {
+	// A parameterized event handler used as ctrl-8/9/0 zoom controls below.
+	class LLZoomer : public view_listener_t
+	{
+	public:
+		// The "mult" parameter says whether "val" is a multiplier or used to set the value.
+		LLZoomer(F32 val, bool mult=true) : mVal(val), mMult(mult) {}
+		bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata)
+		{
+			F32 new_fov_rad = mMult ? LLViewerCamera::getInstance()->getDefaultFOV() * mVal : mVal;
+			LLViewerCamera::getInstance()->setDefaultFOV(new_fov_rad);
+			gSavedSettings.setF32("CameraAngle", LLViewerCamera::getInstance()->getView()); // setView may have clamped it.
+			return true;
+		}
+	private:
+		F32 mVal;
+		bool mMult;
+	};
+
 	// File menu
 	init_menu_file();
 
@@ -7457,9 +7433,9 @@ void initialize_menus()
 	addMenu(new LLViewHighlightTransparent(), "View.HighlightTransparent");
 	addMenu(new LLViewToggleRenderType(), "View.ToggleRenderType");
 	addMenu(new LLViewShowHUDAttachments(), "View.ShowHUDAttachments");
-	addMenu(new LLViewZoomOut(), "View.ZoomOut");
-	addMenu(new LLViewZoomIn(), "View.ZoomIn");
-	addMenu(new LLViewZoomDefault(), "View.ZoomDefault");
+	addMenu(new LLZoomer(1.2f), "View.ZoomOut");
+	addMenu(new LLZoomer(1/1.2f), "View.ZoomIn");
+	addMenu(new LLZoomer(DEFAULT_FIELD_OF_VIEW, false), "View.ZoomDefault");
 	addMenu(new LLViewFullscreen(), "View.Fullscreen");
 	addMenu(new LLViewDefaultUISize(), "View.DefaultUISize");
 
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 27badfb1ddccd44c7f1f122ed58e8fe3d638a18b..9448a00e68d7ce3434325e1b654b9de02ae44da1 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -43,6 +43,7 @@
 #include "llfloatersnapshot.h"
 #include "llinventorymodel.h"	// gInventory
 #include "llresourcedata.h"
+#include "llfloaterperms.h"
 #include "llstatusbar.h"
 #include "llviewercontrol.h"	// gSavedSettings
 #include "llviewerimagelist.h"
@@ -322,7 +323,9 @@ class LLFileUploadBulk : public view_listener_t
 			LLStringUtil::stripNonprintable(asset_name);
 			LLStringUtil::trim(asset_name);
 			
-			upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE); // file
+			upload_new_resource(filename, asset_name, asset_name, 0, LLAssetType::AT_NONE, LLInventoryType::IT_NONE,
+				LLFloaterPerms::getNextOwnerPerms(), LLFloaterPerms::getGroupPerms(), LLFloaterPerms::getEveryonePerms());
+
 			// *NOTE: Ew, we don't iterate over the file list here,
 			// we handle the next files in upload_done_callback()
 		}
@@ -515,7 +518,9 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 						 std::string desc, S32 compression_info,
 						 LLAssetType::EType destination_folder_type,
 						 LLInventoryType::EType inv_type,
-						 U32 next_owner_perm,
+						 U32 next_owner_perms,
+						 U32 group_perms,
+						 U32 everyone_perms,
 						 const std::string& display_name,
 						 LLAssetStorage::LLStoreAssetCallback callback,
 						 void *userdata)
@@ -803,7 +808,7 @@ void upload_new_resource(const std::string& src_filename, std::string name,
 			t_disp_name = src_filename;
 		}
 		upload_new_resource(tid, asset_type, name, desc, compression_info, // tid
-							destination_folder_type, inv_type, next_owner_perm,
+							destination_folder_type, inv_type, next_owner_perms, group_perms, everyone_perms,
 							display_name, callback, userdata);
 	}
 	else
@@ -875,15 +880,15 @@ void upload_done_callback(const LLUUID& uuid, void* user_data, S32 result, LLExt
 			LLUUID folder_id(gInventory.findCategoryUUIDForType(dest_loc));
 			if(folder_id.notNull())
 			{
-				U32 next_owner_perm = data->mNextOwnerPerm;
-				if(PERM_NONE == next_owner_perm)
+				U32 next_owner_perms = data->mNextOwnerPerm;
+				if(PERM_NONE == next_owner_perms)
 				{
-					next_owner_perm = PERM_MOVE | PERM_TRANSFER;
+					next_owner_perms = PERM_MOVE | PERM_TRANSFER;
 				}
 				create_inventory_item(gAgent.getID(), gAgent.getSessionID(),
 					folder_id, data->mAssetInfo.mTransactionID, data->mAssetInfo.getName(),
 					data->mAssetInfo.getDescription(), data->mAssetInfo.mType,
-					data->mInventoryType, NOT_WEARABLE, next_owner_perm,
+					data->mInventoryType, NOT_WEARABLE, next_owner_perms,
 					LLPointer<LLInventoryCallback>(NULL));
 			}
 			else
@@ -925,7 +930,9 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
 						 std::string desc, S32 compression_info,
 						 LLAssetType::EType destination_folder_type,
 						 LLInventoryType::EType inv_type,
-						 U32 next_owner_perm,
+						 U32 next_owner_perms,
+						 U32 group_perms,
+						 U32 everyone_perms,
 						 const std::string& display_name,
 						 LLAssetStorage::LLStoreAssetCallback callback,
 						 void *userdata)
@@ -984,10 +991,14 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
 		body["inventory_type"] = LLInventoryType::lookup(inv_type);
 		body["name"] = name;
 		body["description"] = desc;
+		body["next_owner_mask"] = LLSD::Integer(next_owner_perms);
+		body["group_mask"] = LLSD::Integer(group_perms);
+		body["everyone_mask"] = LLSD::Integer(everyone_perms);
 		
-		std::ostringstream llsdxml;
-		LLSDSerialize::toXML(body, llsdxml);
-		lldebugs << "posting body to capability: " << llsdxml.str() << llendl;
+		//std::ostringstream llsdxml;
+		//LLSDSerialize::toPrettyXML(body, llsdxml);
+		//llinfos << "posting body to capability: " << llsdxml.str() << llendl;
+
 		LLHTTPClient::post(url, body, new LLNewAgentInventoryResponder(body, uuid, asset_type));
 	}
 	else
@@ -1015,7 +1026,7 @@ void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType asset_ty
 		data->mAssetInfo.mType = asset_type;
 		data->mAssetInfo.mCreatorID = gAgentID;
 		data->mInventoryType = inv_type;
-		data->mNextOwnerPerm = next_owner_perm;
+		data->mNextOwnerPerm = next_owner_perms;
 		data->mUserData = userdata;
 		data->mAssetInfo.setName(name);
 		data->mAssetInfo.setDescription(desc);
diff --git a/indra/newview/llviewermenufile.h b/indra/newview/llviewermenufile.h
index f43e5bfc92c63b7a9644da5c7fc1bb32165e0a05..36dd1d78b79a63a1c2080fd5afb2ff16481177d1 100644
--- a/indra/newview/llviewermenufile.h
+++ b/indra/newview/llviewermenufile.h
@@ -40,21 +40,29 @@ class LLTransactionID;
 
 void init_menu_file();
 
-void upload_new_resource(const std::string& src_filename, std::string name,
-						 std::string desc, S32 compression_info,
+void upload_new_resource(const std::string& src_filename, 
+						 std::string name,
+						 std::string desc, 
+						 S32 compression_info,
 						 LLAssetType::EType destination_folder_type,
 						 LLInventoryType::EType inv_type,
-						 U32 next_owner_perm = 0x0,	// PERM_NONE
+						 U32 next_owner_perms = 0x0,	// PERM_NONE
+						 U32 group_perms = 0x0,	// PERM_NONE
+						 U32 everyone_perms = 0x0,	// PERM_NONE
 						 const std::string& display_name = LLStringUtil::null,
 						 LLAssetStorage::LLStoreAssetCallback callback = NULL,
 						 void *userdata = NULL);
 
-void upload_new_resource(const LLTransactionID &tid, LLAssetType::EType type,
+void upload_new_resource(const LLTransactionID &tid, 
+						 LLAssetType::EType type,
 						 std::string name,
-						 std::string desc, S32 compression_info,
+						 std::string desc, 
+						 S32 compression_info,
 						 LLAssetType::EType destination_folder_type,
 						 LLInventoryType::EType inv_type,
-						 U32 next_owner_perm = 0x0,	// PERM_NONE
+						 U32 next_owner_perms = 0x0,	// PERM_NONE
+						 U32 group_perms = 0x0,	// PERM_NONE
+						 U32 everyone_perms = 0x0,	// PERM_NONE
 						 const std::string& display_name = LLStringUtil::null,
 						 LLAssetStorage::LLStoreAssetCallback callback = NULL,
 						 void *userdata = NULL);
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 426edb37cafb36b1ffc2bf5120f8d2bc8ab1209b..eeedb9825059851e05a07df4f0a7a62b5253907c 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1803,15 +1803,51 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 	break;
 
 	case IM_FROM_TASK:
-		if (is_busy && !is_owned_by_me)
 		{
-			return;
+			if (is_busy && !is_owned_by_me)
+			{
+				return;
+			}
+			chat.mText = name + separator_string + message.substr(message_offset);
+			chat.mFromName = name;
+
+			// Build a link to open the object IM info window.
+			std::string location = ll_safe_string((char*)binary_bucket,binary_bucket_size);
+			
+			LLSD query_string;
+			query_string["owner"] = from_id;
+			query_string["slurl"] = location.c_str();
+			query_string["name"] = name;
+			if (from_group)
+			{
+				query_string["groupowned"] = "true";
+			}	
+
+			if (session_id.notNull())
+			{
+				chat.mFromID = session_id;
+			}
+			else
+			{
+				// This message originated on a region without the updated code for task id and slurl information.
+				// We just need a unique ID for this object that isn't the owner ID.
+				// If it is the owner ID it will overwrite the style that contains the link to that owner's profile.
+				// This isn't ideal - it will make 1 style for all objects owned by the the same person/group.
+				// This works because the only thing we can really do in this case is show the owner name and link to their profile.
+				chat.mFromID = from_id ^ gAgent.getSessionID();
+			}
+
+			std::ostringstream link;
+			link << "secondlife:///app/objectim/" << session_id
+					<< LLURI::mapToQueryString(query_string);
+
+			chat.mURL = link.str();
+
+			// Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
+			// IMs from objcts don't open IM sessions.
+			chat.mSourceType = CHAT_SOURCE_OBJECT;
+			LLFloaterChat::addChat(chat, FALSE, FALSE);
 		}
-		chat.mText = name + separator_string + message.substr(message_offset);
-		// Note: lie to LLFloaterChat::addChat(), pretending that this is NOT an IM, because
-		// IMs from objcts don't open IM sessions.
-		chat.mSourceType = CHAT_SOURCE_OBJECT;
-		LLFloaterChat::addChat(chat, FALSE, FALSE);
 		break;
 	case IM_FROM_TASK_AS_ALERT:
 		if (is_busy && !is_owned_by_me)
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 38e376b511e1ae87ac249566c49c3cf8f917f7cf..edb339eab4824a5649f340f018b9a7901db98439 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1342,8 +1342,9 @@ void LLViewerWindow::handleDataCopy(LLWindow *window, S32 data_type, void *data)
 	case SLURL_MESSAGE_TYPE:
 		// received URL
 		std::string url = (const char*)data;
-		const bool from_external_browser = true;
-		if (LLURLDispatcher::dispatch(url, from_external_browser))
+		LLWebBrowserCtrl* web = NULL;
+		const bool trusted_browser = false;
+		if (LLURLDispatcher::dispatch(url, web, trusted_browser))
 		{
 			// bring window to foreground, as it has just been "launched" from a URL
 			mWindow->bringToFront();
diff --git a/indra/newview/skins/default/textures/default_land_picture.j2c b/indra/newview/skins/default/textures/default_land_picture.j2c
new file mode 100644
index 0000000000000000000000000000000000000000..34df0291ae08c9303151a2d68942f473d718dd32
Binary files /dev/null and b/indra/newview/skins/default/textures/default_land_picture.j2c differ
diff --git a/indra/newview/skins/default/textures/default_profile_picture.j2c b/indra/newview/skins/default/textures/default_profile_picture.j2c
new file mode 100644
index 0000000000000000000000000000000000000000..c53a22e8165c6e9fb1e6039644b113273a9b79b4
Binary files /dev/null and b/indra/newview/skins/default/textures/default_profile_picture.j2c differ
diff --git a/indra/newview/skins/default/textures/locked_image.j2c b/indra/newview/skins/default/textures/locked_image.j2c
new file mode 100644
index 0000000000000000000000000000000000000000..9e8998d675954d2592b9753bcf461d967a01c4f3
Binary files /dev/null and b/indra/newview/skins/default/textures/locked_image.j2c differ
diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml
index 9e1d9b5196d75ed47b97775bc48a4a1402a0bd89..34c9dea7e64fc878fef538bdcc372e562bcdac21 100644
--- a/indra/newview/skins/default/textures/textures.xml
+++ b/indra/newview/skins/default/textures/textures.xml
@@ -369,4 +369,8 @@
   
   <texture name="skin_thumbnail_default.png" preload="true" />
   <texture name="skin_thumbnail_silver.png" preload="true" />
+
+  <texture name="default_land_picture.j2c"/>
+  <texture name="default_profile_picture.j2c"/>
+  <texture name="locked_image.j2c"/>
 </textures>