diff --git a/doc/contributions.txt b/doc/contributions.txt
index 0206ced94934366f5a1436aa99db10cd5e9d4499..4fb1de87eb10b4519d6a33d971ee203a5266d231 100644
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -143,7 +143,9 @@ Gigs Taggart
 	VWR-1434
 	VWR-1987
 	VWR-2065
+	VWR-2491
 	VWR-2502
+	VWR-2331
 Ginko Bayliss
 	VWR-4
 Grazer Kline
@@ -154,6 +156,7 @@ Gudmund Shepherd
 Hamncheese Omlet
 	VWR-333
 Henri Beauchamp
+	VWR-1320
 	VWR-1406
 	VWR-4157
 Hikkoshi Sakai
@@ -262,6 +265,7 @@ Nicholaz Beresford
 	VWR-1721
 	VWR-1723
 	VWR-1732
+	VWR-1754
 	VWR-1769
 	VWR-1808
 	VWR-1861
diff --git a/etc/message.xml b/etc/message.xml
index 701d049678272ca00ea973bb0bbfe57e3707be56..f6f43bd0fff9ed9b48d300444198d671df555d88 100644
--- a/etc/message.xml
+++ b/etc/message.xml
@@ -360,6 +360,14 @@
 					<boolean>true</boolean>
 				</map>
 				
+				<key>ParcelObjectOwnersReply</key>
+				<map>
+					<key>flavor</key>
+					<string>llsd</string>
+					<key>trusted-sender</key>
+					<boolean>true</boolean>
+				</map>
+
 				<key>ParcelProperties</key>
 				<map>
 					<key>flavor</key>
@@ -368,6 +376,14 @@
 					<boolean>true</boolean>
 				</map>
 
+				<key>LandStatReply</key>
+				<map>
+					<key>flavor</key>
+					<string>llsd</string>
+					<key>trusted-sender</key>
+					<boolean>true</boolean>
+				</map>
+
 				<key>avatarnotesrequest</key>
 				<map>
 					<key>service_name</key>
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 1c8fb4234fb6b27fe424fc87addac2ad4811a353..d7ae9611fc03e49b0a3242c4ef43d55f45071c7b 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -40,9 +40,7 @@
 #include "llimagebmp.h"
 #include "llimagetga.h"
 #include "llimagej2c.h"
-#if JPEG_SUPPORT
 #include "llimagejpeg.h"
-#endif
 #include "llimagepng.h"
 #include "llimagedxt.h"
 
@@ -1192,11 +1190,9 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
 	  case IMG_CODEC_TGA:
 		image = new LLImageTGA();
 		break;
-#if JPEG_SUPPORT
 	  case IMG_CODEC_JPEG:
 		image = new LLImageJPEG();
 		break;
-#endif
 	  case IMG_CODEC_J2C:
 		image = new LLImageJ2C();
 		break;
@@ -1280,20 +1276,18 @@ LLImageFormatted* LLImageFormatted::createFromType(S8 codec)
 	  case IMG_CODEC_TGA:
 		image = new LLImageTGA();
 		break;
-#if JPEG_SUPPORT
 	  case IMG_CODEC_JPEG:
 		image = new LLImageJPEG();
 		break;
-#endif
+	  case IMG_CODEC_PNG:
+		image = new LLImagePNG();
+		break;
 	  case IMG_CODEC_J2C:
 		image = new LLImageJ2C();
 		break;
 	  case IMG_CODEC_DXT:
 		image = new LLImageDXT();
 		break;
-	  case IMG_CODEC_PNG:
-		image = new LLImagePNG();
-		break;
 	  default:
 		image = NULL;
 		break;
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 98a86ad755fd3e82d1f86814720da72473b1d886..c4fd66197683fcedc7dfc8d7333a6a9f53caee3c 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -255,6 +255,8 @@ class LLImageFormatted : public LLImageBase
 
 	// New methods
 public:
+	// subclasses must return a prefered file extension (lowercase without a leading dot)
+	virtual std::string getExtension() = 0;
 	// calcHeaderSize() returns the maximum size of header;
 	//   0 indicates we don't know have a header and have to lead the entire file
 	virtual S32 calcHeaderSize() { return 0; };
diff --git a/indra/llimage/llimagebmp.cpp b/indra/llimage/llimagebmp.cpp
index f8423000a819ca7cf68828733f60f454eef4a656..b6b1d695d12c49e05b6257d40656cf93d7e65c8c 100644
--- a/indra/llimage/llimagebmp.cpp
+++ b/indra/llimage/llimagebmp.cpp
@@ -644,10 +644,10 @@ BOOL LLImageBMP::encode(const LLImageRaw* raw_image, F32 encode_time)
 				break;
 			}
 
-			for( S32 i = 0; i < alignment_bytes; i++ )
-			{
-				*dst++ = 0;
-			}
+		}
+		for( S32 i = 0; i < alignment_bytes; i++ )
+		{
+			*dst++ = 0;
 		}
 	}
 
diff --git a/indra/llimage/llimagebmp.h b/indra/llimage/llimagebmp.h
index 00d3e957e44763ff1ee2c52b98751c65d69d39f9..6ad1fac4aed2be8a6418714a1582a18d95ade1cc 100644
--- a/indra/llimage/llimagebmp.h
+++ b/indra/llimage/llimagebmp.h
@@ -44,6 +44,7 @@ class LLImageBMP : public LLImageFormatted
 public:
 	LLImageBMP();
 
+	/*virtual*/ std::string getExtension() { return std::string("bmp"); }
 	/*virtual*/ BOOL updateData();
 	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
 	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
diff --git a/indra/llimage/llimagedxt.h b/indra/llimage/llimagedxt.h
index b6df09845672ebdca9446d998fd3c7c0f83a6578..c994a8578b0cc3a317d7a664477f7bc65386ec0e 100644
--- a/indra/llimage/llimagedxt.h
+++ b/indra/llimage/llimagedxt.h
@@ -102,6 +102,7 @@ class LLImageDXT : public LLImageFormatted
 public:
 	LLImageDXT();
 
+	/*virtual*/ std::string getExtension() { return std::string("dxt"); }
 	/*virtual*/ BOOL updateData();
 
 	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
diff --git a/indra/llimage/llimagej2c.h b/indra/llimage/llimagej2c.h
index 8d01eceb54a7366ddff4d78e67ad9ce6275d4dd8..03172d344ffd8233331ec0b1a5eda0e70d994654 100644
--- a/indra/llimage/llimagej2c.h
+++ b/indra/llimage/llimagej2c.h
@@ -45,6 +45,7 @@ class LLImageJ2C : public LLImageFormatted
 	LLImageJ2C();
 
 	// Base class overrides
+	/*virtual*/ std::string getExtension() { return std::string("j2c"); }
 	/*virtual*/ BOOL updateData();
 	/*virtual*/ BOOL decode(LLImageRaw *raw_imagep, F32 decode_time);
 	/*virtual*/ BOOL decodeChannels(LLImageRaw *raw_imagep, F32 decode_time, S32 first_channel, S32 max_channel_count);
diff --git a/indra/llimage/llimagejpeg.cpp b/indra/llimage/llimagejpeg.cpp
index aebe87d626205a2094722d4d6b41adbb18197506..1bddd7a051c4ed416bda1334f3c272b1be5d4fd1 100644
--- a/indra/llimage/llimagejpeg.cpp
+++ b/indra/llimage/llimagejpeg.cpp
@@ -35,13 +35,15 @@
 
 #include "llerror.h"
 
-LLImageJPEG::LLImageJPEG() 
+LLImageJPEG::LLImageJPEG(S32 quality) 
 	:
 	LLImageFormatted(IMG_CODEC_JPEG),
 	mOutputBuffer( NULL ),
 	mOutputBufferSize( 0 ),
-	mEncodeQuality( 75 ) // on a scale from 1 to 100
+	mEncodeQuality( quality ) // on a scale from 1 to 100
 {
+	// Including in initializer list above generates warning on VC2005
+	memset(mSetjmpBuffer, 0, sizeof(mSetjmpBuffer));
 }
 
 LLImageJPEG::~LLImageJPEG()
diff --git a/indra/llimage/llimagejpeg.h b/indra/llimage/llimagejpeg.h
index 054ddad9bc64cd35f333c2b449165ff88e26cf55..36d3454d4ba601827d4c0d523a2a81cd3dd64610 100644
--- a/indra/llimage/llimagejpeg.h
+++ b/indra/llimage/llimagejpeg.h
@@ -52,8 +52,9 @@ class LLImageJPEG : public LLImageFormatted
 	virtual ~LLImageJPEG();
 	
 public:
-	LLImageJPEG();
+	LLImageJPEG(S32 quality = 75);
 
+	/*virtual*/ std::string getExtension() { return std::string("jpg"); }
 	/*virtual*/ BOOL updateData();
 	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
 	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
diff --git a/indra/llimage/llimagepng.h b/indra/llimage/llimagepng.h
index 027caf9780c2e15c2505cc5cfae621feb8963563..38af80f2dd6c8dbdf98f494aa706ec21b55849bc 100644
--- a/indra/llimage/llimagepng.h
+++ b/indra/llimage/llimagepng.h
@@ -42,9 +42,10 @@ class LLImagePNG : public LLImageFormatted
 public:
 	LLImagePNG();
 
-	BOOL updateData();
-	BOOL decode(LLImageRaw* raw_image, F32 decode_time);
-	BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
+	/*virtual*/ std::string getExtension() { return std::string("png"); }
+	/*virtual*/ BOOL updateData();
+	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time);
+	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time);
 
 private:
 	U8* mTmpWriteBuffer;
diff --git a/indra/llimage/llimagetga.h b/indra/llimage/llimagetga.h
index d1178ffb7370daeeea519cba8e22c7166d4eafaf..e8f9672778b97e999108c71af61e6d943a108f62 100644
--- a/indra/llimage/llimagetga.h
+++ b/indra/llimage/llimagetga.h
@@ -45,6 +45,7 @@ class LLImageTGA : public LLImageFormatted
 	LLImageTGA();
 	LLImageTGA(const std::string& file_name);
 
+	/*virtual*/ std::string getExtension() { return std::string("tga"); }
 	/*virtual*/ BOOL updateData();
 	/*virtual*/ BOOL decode(LLImageRaw* raw_image, F32 decode_time=0.0);
 	/*virtual*/ BOOL encode(const LLImageRaw* raw_image, F32 encode_time=0.0);
diff --git a/indra/llmath/llmath.h b/indra/llmath/llmath.h
index fde210ef5031732b44a121d735339c578d440606..0372bae1068926bd298c8f4af1926ab244589c0c 100644
--- a/indra/llmath/llmath.h
+++ b/indra/llmath/llmath.h
@@ -477,8 +477,8 @@ inline F32 llsimple_angle(F32 angle)
 	return angle;
 }
 
-//calculate the nearesr power of two number for val, bounded by max_power_two
-inline U32 get_nearest_power_two(U32 val, U32 max_power_two)
+//SDK - Renamed this to get_lower_power_two, since this is what this actually does.
+inline U32 get_lower_power_two(U32 val, U32 max_power_two)
 {
 	if(!max_power_two)
 	{
@@ -493,4 +493,34 @@ inline U32 get_nearest_power_two(U32 val, U32 max_power_two)
 	
 	return max_power_two ;
 }
+
+// calculate next highest power of two, limited by max_power_two
+// This is taken from a brilliant little code snipped on http://acius2.blogspot.com/2007/11/calculating-next-power-of-2.html
+// Basically we convert the binary to a solid string of 1's with the same
+// number of digits, then add one.  We subtract 1 initially to handle
+// the case where the number passed in is actually a power of two.
+// WARNING: this only works with 32 bit ints.
+inline U32 get_next_power_two(U32 val, U32 max_power_two)
+{
+	if(!max_power_two)
+	{
+		max_power_two = 1 << 31 ;
+	}
+
+	if(val >= max_power_two)
+	{
+		return max_power_two;
+	}
+
+	val--;
+	val = (val >> 1) | val;
+	val = (val >> 2) | val;
+	val = (val >> 4) | val;
+	val = (val >> 8) | val;
+	val = (val >> 16) | val;
+	val++;
+
+	return val;
+}
+
 #endif
diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp
index 18ffbdfbcdadba95192bbe5d74d9be69b2897798..838f6fa193c964d26e21fce6b3436cbf50adf017 100644
--- a/indra/llui/llfloater.cpp
+++ b/indra/llui/llfloater.cpp
@@ -1082,38 +1082,37 @@ void LLFloater::removeDependentFloater(LLFloater* floaterp)
 	floaterp->mDependeeHandle = LLHandle<LLFloater>();
 }
 
-// virtual
-BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLFloater::offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index)
 {
-	if( mMinimized )
+	if( mButtonsEnabled[index] )
 	{
-		// Offer the click to the close button.
-		if( mButtonsEnabled[BUTTON_CLOSE] )
-		{
-			S32 local_x = x - mButtons[BUTTON_CLOSE]->getRect().mLeft;
-			S32 local_y = y - mButtons[BUTTON_CLOSE]->getRect().mBottom;
+		LLButton* my_butt = mButtons[index];
+		S32 local_x = x - my_butt->getRect().mLeft;
+		S32 local_y = y - my_butt->getRect().mBottom;
 
-			if (mButtons[BUTTON_CLOSE]->pointInView(local_x, local_y)
-				&& mButtons[BUTTON_CLOSE]->handleMouseDown(local_x, local_y, mask))
-			{
-				// close button handled it, return
-				return TRUE;
-			}
-		}
-
-		// Offer the click to the restore button.
-		if( mButtonsEnabled[BUTTON_RESTORE] )
+		if (
+			my_butt->pointInView(local_x, local_y) &&
+			my_butt->handleMouseDown(local_x, local_y, mask))
 		{
-			S32 local_x = x - mButtons[BUTTON_RESTORE]->getRect().mLeft;
-			S32 local_y = y - mButtons[BUTTON_RESTORE]->getRect().mBottom;
-
-			if (mButtons[BUTTON_RESTORE]->pointInView(local_x, local_y)
-				&& mButtons[BUTTON_RESTORE]->handleMouseDown(local_x, local_y, mask))
-			{
-				// restore button handled it, return
-				return TRUE;
-			}
+			// the button handled it
+			return TRUE;
 		}
+	}
+	return FALSE;
+}
+
+// virtual
+BOOL LLFloater::handleMouseDown(S32 x, S32 y, MASK mask)
+{
+	if( mMinimized )
+	{
+		// Offer the click to titlebar buttons.
+		// Note: this block and the offerClickToButton helper method can be removed
+		// because the parent container will handle it for us but we'll keep it here
+		// for safety until after reworking the panel code to manage hidden children.
+		if(offerClickToButton(x, y, mask, BUTTON_CLOSE)) return TRUE;
+		if(offerClickToButton(x, y, mask, BUTTON_RESTORE)) return TRUE;
+		if(offerClickToButton(x, y, mask, BUTTON_TEAR_OFF)) return TRUE;
 
 		// Otherwise pass to drag handle for movement
 		return mDragHandle->handleMouseDown(x, y, mask);
@@ -1248,6 +1247,7 @@ void LLFloater::onClickTearOff(void *userdata)
 		LLMultiFloater* new_host = (LLMultiFloater*)self->mLastHostHandle.get();
 		if (new_host)
 		{
+			self->setMinimized(FALSE); // to reenable minimize button if it was minimized
 			new_host->showFloater(self);
 			// make sure host is visible
 			new_host->open();
@@ -1420,31 +1420,15 @@ void LLFloater::draw()
 
 void	LLFloater::setCanMinimize(BOOL can_minimize)
 {
-	// removing minimize/restore button programmatically,
-	// go ahead and uniminimize floater
+	// if removing minimize/restore button programmatically,
+	// go ahead and unminimize floater
 	if (!can_minimize)
 	{
 		setMinimized(FALSE);
 	}
 
-	if (can_minimize)
-	{
-		if (isMinimized())
-		{
-			mButtonsEnabled[BUTTON_MINIMIZE] = FALSE;
-			mButtonsEnabled[BUTTON_RESTORE] = TRUE;
-		}
-		else
-		{
-			mButtonsEnabled[BUTTON_MINIMIZE] = TRUE;
-			mButtonsEnabled[BUTTON_RESTORE] = FALSE;
-		}
-	}
-	else
-	{
-		mButtonsEnabled[BUTTON_MINIMIZE] = FALSE;
-		mButtonsEnabled[BUTTON_RESTORE] = FALSE;
-	}
+	mButtonsEnabled[BUTTON_MINIMIZE] = can_minimize && !isMinimized();
+	mButtonsEnabled[BUTTON_RESTORE]  = can_minimize &&  isMinimized();
 
 	updateButtons();
 }
diff --git a/indra/llui/llfloater.h b/indra/llui/llfloater.h
index cb21036ef4481db0f1e1cfed4d561ef688c2b42e..e467d6f92152285ee0341a931b680d066bc0d73d 100644
--- a/indra/llui/llfloater.h
+++ b/indra/llui/llfloater.h
@@ -151,8 +151,8 @@ friend class LLFloaterView;
 	void			moveResizeHandlesToFront();
 	void			addDependentFloater(LLFloater* dependent, BOOL reposition = TRUE);
 	void			addDependentFloater(LLHandle<LLFloater> dependent_handle, BOOL reposition = TRUE);
-	LLFloater*      getDependee() { return (LLFloater*)mDependeeHandle.get(); }
-	void            removeDependentFloater(LLFloater* dependent);
+	LLFloater*		getDependee() { return (LLFloater*)mDependeeHandle.get(); }
+	void		removeDependentFloater(LLFloater* dependent);
 	BOOL			isMinimized()					{ return mMinimized; }
 	BOOL			isFrontmost();
 	BOOL			isDependent()					{ return !mDependeeHandle.isDead(); }
@@ -221,8 +221,8 @@ friend class LLFloaterView;
 	virtual void	bringToFront(S32 x, S32 y);
 	virtual void	setVisibleAndFrontmost(BOOL take_focus=TRUE);    
 	
-	void            setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
-    const LLRect&    getExpandedRect() const { return mExpandedRect; }
+	void		setExpandedRect(const LLRect& rect) { mExpandedRect = rect; } // size when not minimized
+	const LLRect&	getExpandedRect() const { return mExpandedRect; }
 
 	void			setAutoFocus(BOOL focus) { mAutoFocus = focus; } // whether to automatically take focus when opened
 	LLDragHandle*	getDragHandle() const { return mDragHandle; }
@@ -236,11 +236,12 @@ friend class LLFloaterView;
 	void			createMinimizeButton();
 	void			updateButtons();
 	void			buildButtons();
+	BOOL			offerClickToButton(S32 x, S32 y, MASK mask, EFloaterButtons index);
 
 	LLRect			mExpandedRect;
 	LLDragHandle*	mDragHandle;
 	LLResizeBar*	mResizeBar[4];
-	LLResizeHandle* mResizeHandle[4];
+	LLResizeHandle*	mResizeHandle[4];
 	LLButton		*mMinimizeButton;
 	BOOL			mCanTearOff;
 	BOOL			mMinimized;
@@ -259,7 +260,7 @@ friend class LLFloaterView;
 	typedef std::set<LLHandle<LLFloater> > handle_set_t;
 	typedef std::set<LLHandle<LLFloater> >::iterator handle_set_iter_t;
 	handle_set_t	mDependents;
-	bool            mDragOnLeft;
+	bool			mDragOnLeft;
 
 	BOOL			mButtonsEnabled[BUTTON_COUNT];
 	LLButton*		mButtons[BUTTON_COUNT];
@@ -387,8 +388,8 @@ class LLMultiFloater : public LLFloater
 	virtual void selectNextFloater();
 	virtual void selectPrevFloater();
 
-	virtual LLFloater* getActiveFloater();
-	virtual BOOL       isFloaterFlashing(LLFloater* floaterp);
+	virtual LLFloater*	getActiveFloater();
+	virtual BOOL		isFloaterFlashing(LLFloater* floaterp);
 	virtual S32			getFloaterCount();
 
 	virtual void setFloaterFlashing(LLFloater* floaterp, BOOL flashing);
diff --git a/indra/llui/llscrolllistctrl.cpp b/indra/llui/llscrolllistctrl.cpp
index 0bc5bc60de86bf918f780d5fe40aa72ed7d80f08..3c29795cb4fe48de5ecb9a1e4880e478e400026d 100644
--- a/indra/llui/llscrolllistctrl.cpp
+++ b/indra/llui/llscrolllistctrl.cpp
@@ -3242,11 +3242,19 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
 		S32 index = columnp->mIndex;
 		S32 width = columnp->mWidth;
 		LLFontGL::HAlign font_alignment = columnp->mFontAlignment;
-
+		LLColor4 fcolor = LLColor4::black;
+		
 		LLSD value = (*itor)["value"];
 		std::string fontname = (*itor)["font"].asString();
 		std::string fontstyle = (*itor)["font-style"].asString();
 		std::string type = (*itor)["type"].asString();
+		
+		if ((*itor).has("font-color"))
+		{
+			LLSD sd_color = (*itor)["font-color"];
+			fcolor.setValue(sd_color);
+		}
+		
 		BOOL has_color = (*itor).has("color");
 		LLColor4 color = ((*itor)["color"]);
 		BOOL enabled = !(*itor).has("enabled") || (*itor)["enabled"].asBoolean() == true;
@@ -3291,7 +3299,7 @@ LLScrollListItem* LLScrollListCtrl::addElement(const LLSD& value, EAddPosition p
 		}
 		else
 		{
-			LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment);
+			LLScrollListText* cell = new LLScrollListText(value.asString(), font, width, font_style, font_alignment, fcolor, TRUE);
 			if (has_color)
 			{
 				cell->setColor(color);
diff --git a/indra/llui/llspinctrl.cpp b/indra/llui/llspinctrl.cpp
index e7fc10912e9d3d295df3cdd2decf6d77d0b14fc3..505202c48e263b51fef188677515ae0a0d2b02a7 100644
--- a/indra/llui/llspinctrl.cpp
+++ b/indra/llui/llspinctrl.cpp
@@ -396,6 +396,12 @@ void LLSpinCtrl::setLabel(const LLStringExplicit& label)
 	}
 }
 
+void LLSpinCtrl::setAllowEdit(BOOL allow_edit)
+{
+	mEditor->setEnabled(allow_edit);
+	mAllowEdit = allow_edit;
+}
+
 void LLSpinCtrl::onTabInto()
 {
 	mEditor->onTabInto(); 
@@ -520,6 +526,9 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
 	S32 label_width = llmin(40, rect.getWidth() - 40);
 	node->getAttributeS32("label_width", label_width);
 
+	BOOL allow_text_entry = TRUE;
+	node->getAttributeBOOL("allow_text_entry", allow_text_entry);
+
 	LLUICtrlCallback callback = NULL;
 
 	if(label.empty())
@@ -543,6 +552,7 @@ LLView* LLSpinCtrl::fromXML(LLXMLNodePtr node, LLView *parent, LLUICtrlFactory *
 	spinner->setPrecision(precision);
 
 	spinner->initFromXML(node, parent);
+	spinner->setAllowEdit(allow_text_entry);
 
 	return spinner;
 }
diff --git a/indra/llui/llspinctrl.h b/indra/llui/llspinctrl.h
index 1ed9462f009e01991190f096e050b4e692e779d3..a9a9ef50736a821f26989ba5e6db77ec1fc4e09d 100644
--- a/indra/llui/llspinctrl.h
+++ b/indra/llui/llspinctrl.h
@@ -93,6 +93,7 @@ class LLSpinCtrl
 	void			setLabel(const LLStringExplicit& label);
 	void			setLabelColor(const LLColor4& c)			{ mTextEnabledColor = c; }
 	void			setDisabledLabelColor(const LLColor4& c)	{ mTextDisabledColor = c; }
+	void			setAllowEdit(BOOL allow_edit);
 
 	virtual void	onTabInto();
 
@@ -134,6 +135,7 @@ class LLSpinCtrl
 	class LLButton*		mDownBtn;
 
 	BOOL			mbHasBeenSet;
+	BOOL			mAllowEdit;
 };
 
 #endif  // LL_LLSPINCTRL_H
diff --git a/indra/llui/lltexteditor.cpp b/indra/llui/lltexteditor.cpp
index a2063358bdc7b5f44b93688b2bf0e63d1c994190..b70ad4c53cf5eb98ba8b5845b541c252c47448c4 100644
--- a/indra/llui/lltexteditor.cpp
+++ b/indra/llui/lltexteditor.cpp
@@ -257,6 +257,7 @@ LLTextEditor::LLTextEditor(
 	mIsSelecting( FALSE ),
 	mSelectionStart( 0 ),
 	mSelectionEnd( 0 ),
+	mScrolledToBottom( FALSE ),
 	mOnScrollEndCallback( NULL ),
 	mOnScrollEndData( NULL ),
 	mCursorColor(		LLUI::sColorsGroup->getColor( "TextCursorColor" ) ),
@@ -3361,20 +3362,26 @@ void LLTextEditor::reshape(S32 width, S32 height, BOOL called_from_parent)
 {
 	LLView::reshape( width, height, called_from_parent );
 
-	// if scrolled to bottom, stay at bottom
-	// unless user is editing text
-	if (mScrolledToBottom && mTrackBottom && !hasFocus())
-	{
-		endOfDoc();
-	}
-
+	// do this first after reshape, because other things depend on
+	// up-to-date mTextRect
 	updateTextRect();
+	
+	updateLineStartList();
+
+	// propagate shape information to scrollbar
+	mScrollbar->setDocSize( getLineCount() );
 
 	S32 line_height = llround( mGLFont->getLineHeight() );
 	S32 page_lines = mTextRect.getHeight() / line_height;
 	mScrollbar->setPageSize( page_lines );
 
-	updateLineStartList();
+	// if scrolled to bottom, stay at bottom
+	// unless user is editing text
+	// do this after updating page size
+	if (mScrolledToBottom && mTrackBottom && !hasFocus())
+	{
+		endOfDoc();
+	}
 }
 
 void LLTextEditor::autoIndent()
@@ -3540,6 +3547,10 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
 	{
 		mSelectionStart = selection_start;
 		mSelectionEnd = selection_end;
+
+
+
+
 		mIsSelecting = was_selecting;
 		setCursorPos(cursor_pos);
 	}
@@ -3556,6 +3567,14 @@ void LLTextEditor::appendText(const std::string &new_text, bool allow_undo, bool
 	{
 		blockUndo();
 	}
+
+	// if scrolled to bottom, stay at bottom
+	// unless user is editing text
+	// do this after updating page size
+	if (mScrolledToBottom && mTrackBottom && !hasFocus())
+	{
+		endOfDoc();
+	}
 }
 
 void LLTextEditor::removeTextFromEnd(S32 num_chars)
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 23030b559de2c04134fd9d47dc0425504e1ba1d7..42a9144d58a84f582fe7c322ef83186ae29df80a 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -64,7 +64,10 @@ extern "C" {
 
 extern BOOL gDebugWindowProc;
 
-const S32	MAX_NUM_RESOLUTIONS = 32;
+const S32 MAX_NUM_RESOLUTIONS = 200;
+
+// static variable for ATI mouse cursor crash work-around:
+static bool ATIbug = false;
 
 //
 // LLWindowSDL
@@ -1735,7 +1738,7 @@ LLWindow::LLWindowResolution* LLWindowSDL::getSupportedResolutions(S32 &num_reso
         if ( (modes != NULL) && (modes != ((SDL_Rect **) -1)) )
         {
             int count = 0;
-            while (*modes)  // they're sorted biggest to smallest, so find end...
+            while (*modes && count<MAX_NUM_RESOLUTIONS)  // they're sorted biggest to smallest, so find end...
             {
                 modes++;
                 count++;
@@ -2275,6 +2278,12 @@ static SDL_Cursor *makeSDLCursorFromBMP(const char *filename, int hotx, int hoty
 
 void LLWindowSDL::setCursor(ECursorType cursor)
 {
+	if (ATIbug) {
+		// cursor-updating is very flaky when this bug is
+		// present; do nothing.
+		return;
+	}
+
 	if (mCurrentCursor != cursor)
 	{
 		if (cursor < UI_CURSOR_COUNT)
@@ -2347,6 +2356,11 @@ void LLWindowSDL::initCursors()
 	mSDLCursors[UI_CURSOR_TOOLPAUSE] = makeSDLCursorFromBMP("toolpause.BMP",0,0);
 	mSDLCursors[UI_CURSOR_TOOLMEDIAOPEN] = makeSDLCursorFromBMP("toolmediaopen.BMP",0,0);
 	mSDLCursors[UI_CURSOR_PIPETTE] = makeSDLCursorFromBMP("lltoolpipette.BMP",2,28);
+
+	if (getenv("LL_ATI_MOUSE_CURSOR_BUG") != NULL) {
+		llinfos << "Disabling cursor updating due to LL_ATI_MOUSE_CURSOR_BUG" << llendl;
+		ATIbug = true;
+	}
 }
 
 void LLWindowSDL::quitCursors()
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index e185d96c98d9f4b948ad5032b62e7f96ca3f74c9..0269e256584d187a9b00051a7fd5d679fab2343b 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -1079,16 +1079,16 @@
       <real>0.5</real>
     </map>
     <key>ChatFontSize</key>
-    <map>
-      <key>Comment</key>
-      <string>Size of chat text in chat console (0 = small, 1 = big)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>S32</string>
-      <key>Value</key>
-      <integer>1</integer>
-    </map>
+        <map>
+        <key>Comment</key>
+            <string>Size of chat text in chat console (0 = small, 1 = medium, 2 = big)</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>1</integer>
+        </map>
     <key>ChatFullWidth</key>
     <map>
       <key>Comment</key>
@@ -1123,16 +1123,16 @@
       <integer>1</integer>
     </map>
     <key>ChatPersistTime</key>
-    <map>
-      <key>Comment</key>
-      <string>Time for which chat stays visible in console (seconds)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>15.0</real>
-    </map>
+        <map>
+        <key>Comment</key>
+            <string>Time for which chat stays visible in console (seconds)</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>F32</string>
+        <key>Value</key>
+            <real>20</real>
+        </map>
     <key>ChatShowTimestamps</key>
     <map>
       <key>Comment</key>
@@ -1856,16 +1856,16 @@
       <integer>0</integer>
     </map>
     <key>ConsoleBackgroundOpacity</key>
-    <map>
-      <key>Comment</key>
-      <string>Opacity of chat console (0.0 = completely transparent, 1.0 = completely opaque)</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>F32</string>
-      <key>Value</key>
-      <real>0.40000000596</real>
-    </map>
+        <map>
+        <key>Comment</key>
+            <string>Opacity of chat console (0.0 = completely transparent, 1.0 = completely opaque)</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>F32</string>
+        <key>Value</key>
+            <real>0.700</real>
+        </map>
     <key>ConsoleBufferSize</key>
     <map>
       <key>Comment</key>
@@ -5046,21 +5046,21 @@
       <integer>0</integer>
     </map>
     <key>ObjectChatColor</key>
-    <map>
-      <key>Comment</key>
-      <string>Color of chat messages from objects</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Color4</string>
-      <key>Value</key>
-      <array>
-        <real>0.699999988079</real>
-        <real>0.899999976158</real>
-        <real>0.699999988079</real>
-        <real>1.0</real>
-      </array>
-    </map>
+        <map>
+        <key>Comment</key>
+            <string>Color of chat messages from objects</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>Color4</string>
+        <key>Value</key>
+            <array>
+                <real>1</real>
+                <real>0.5</real>
+                <real>0.0</real>
+                <real>1</real>
+            </array>
+        </map>
     <key>OpenDebugStatAdvanced</key>
     <map>
       <key>Comment</key>
@@ -5599,6 +5599,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>LandBrushForce</key>
+        <map>
+        <key>Comment</key>
+            <string>Multiplier for land modification brush force.</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>F32</string>
+        <key>Value</key>
+            <real>1.0</real>
+        </map>
     <key>RecentItemsSortOrder</key>
     <map>
       <key>Comment</key>
@@ -6999,16 +7010,16 @@
       <integer>1</integer>
     </map>
     <key>ShowObjectUpdates</key>
-    <map>
-      <key>Comment</key>
-      <string>Show when update messages are received for individual objects</string>
-      <key>Persist</key>
-      <integer>1</integer>
-      <key>Type</key>
-      <string>Boolean</string>
-      <key>Value</key>
-      <integer>0</integer>
-    </map>
+        <map>
+        <key>Comment</key>
+            <string>Show when update messages are received for individual objects</string>
+        <key>Persist</key>
+            <integer>0</integer>
+        <key>Type</key>
+            <string>Boolean</string>
+        <key>Value</key>
+            <integer>0</integer>
+        </map>
     <key>ShowOverlayTitle</key>
     <map>
       <key>Comment</key>
@@ -7346,6 +7357,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>SnapshotFormat</key>
+        <map>
+        <key>Comment</key>
+            <string>Save snapshots in this format (0 = PNG, 1 = JPEG, 2 = BMP)</string>
+        <key>Persist</key>
+            <integer>1</integer>
+        <key>Type</key>
+            <string>S32</string>
+        <key>Value</key>
+            <integer>0</integer>
+        </map>
     <key>SnapshotPostcardLastResolution</key>
     <map>
       <key>Comment</key>
diff --git a/indra/newview/linux_tools/wrapper.sh b/indra/newview/linux_tools/wrapper.sh
index eaa2f61dce8e31187ded37c22bf90058812e10e7..9d2e06b31e4eb9e55c94bdc3a90005a8654ab25b 100755
--- a/indra/newview/linux_tools/wrapper.sh
+++ b/indra/newview/linux_tools/wrapper.sh
@@ -33,6 +33,11 @@
 ##   LL_GL_BLACKLIST which solves your problems.
 #export LL_GL_BLACKLIST=abcdefghijklmno
 
+## - Some ATI/Radeon users report random X server crashes when the mouse
+##   cursor changes shape.  If you suspect that you are a victim of this
+##   driver bug, try enabling this option and report whether it helps:
+#export LL_ATI_MOUSE_CURSOR_BUG=x
+
 
 ## Everything below this line is just for advanced troubleshooters.
 ##-------------------------------------------------------------------
@@ -56,6 +61,12 @@ if [ "$GTK_IM_MODULE" = "scim" ]; then
     export GTK_IM_MODULE=xim
 fi
 
+## - Automatically work around the ATI mouse cursor crash bug:
+## (this workaround is disabled as most fglrx users do not see the bug)
+#if lsmod | grep fglrx &>/dev/null ; then
+#	export LL_ATI_MOUSE_CURSOR_BUG=x
+#fi
+
 
 ## Nothing worth editing below this line.
 ##-------------------------------------------------------------------
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index e926e97f7688d80821c3c458b527a4c9fd5e372a..7fb9e57507bcd54fd59217ff704b753245c01172 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -6438,20 +6438,9 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
 {
 	// We should only receive this message a single time.  Ignore subsequent AgentWearablesUpdates
 	// that may result from AgentWearablesRequest having been sent more than once. 
-	static BOOL first = TRUE;
-	if( first )
-	{
-		first = FALSE;
-	}
-	else
-	{
-		return;
-	}
-	
-	if (gNoRender)
-	{
-		return;
-	}
+	static bool first = true;
+	if (!first) return;
+	first = false;
 
 	LLUUID agent_id;
 	gMessageSystem->getUUIDFast(_PREHASH_AgentData, _PREHASH_AgentID, agent_id );
@@ -6467,16 +6456,6 @@ void LLAgent::processAgentInitialWearablesUpdate( LLMessageSystem* mesgsys, void
 			// Transitional state.  Avatars should always have at least their body parts (hair, eyes, shape and skin).
 			// The fact that they don't have any here (only a dummy is sent) implies that this account existed
 			// before we had wearables, or that the database has gotten messed up.
-			// Deal with this by creating new body parts.
-			//avatar->createStandardWearables();
-
-			// no, deal with it by noting that we need to choose a
-			// gender, but only if an initial outfit load isn't happening.
-			// This whole check (num_wearables < 4) can probably be deleted. JC
-			if (gInitialOutfit.empty())
-			{
-				gAgent.setGenderChosen(FALSE);
-			}
 			return;
 		}
 
diff --git a/indra/newview/lldebugview.cpp b/indra/newview/lldebugview.cpp
index dc160a29ac13ffa446398520fecd321e1284cd3d..ebd708736e9d840ecd7266e8ad6987508263baef 100644
--- a/indra/newview/lldebugview.cpp
+++ b/indra/newview/lldebugview.cpp
@@ -60,7 +60,7 @@ LLDebugView::LLDebugView(const std::string& name, const LLRect &rect)
 {
 	LLRect r;
 
-	r.set(0, rect.getHeight() - 100, rect.getWidth()/2, 100);
+	r.set(10, rect.getHeight() - 100, rect.getWidth()/2, 100);
 	mDebugConsolep = new LLConsole("debug console", 20, r, -1, 0.f );
 	mDebugConsolep->setFollowsBottom();
 	mDebugConsolep->setFollowsLeft();
diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp
index 344917150f115b57ce01d3af5d9fb377f6c4b1af..0f180472fd71b8bc4e5d6f514855d6eec59ff214 100644
--- a/indra/newview/llfilepicker.cpp
+++ b/indra/newview/llfilepicker.cpp
@@ -357,6 +357,26 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename)
 			L"Bitmap Images (*.bmp)\0*.bmp\0" \
 			L"\0";
 		break;
+	case FFSAVE_PNG:
+		if (filename.empty())
+		{
+			wcsncpy( mFilesW,L"untitled.png", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/
+		}
+		mOFN.lpstrDefExt = L"png";
+		mOFN.lpstrFilter =
+			L"PNG Images (*.png)\0*.png\0" \
+			L"\0";
+		break;
+	case FFSAVE_JPEG:
+		if (filename.empty())
+		{
+			wcsncpy( mFilesW,L"untitled.jpeg", FILENAME_BUFFER_SIZE);	/*Flawfinder: ignore*/
+		}
+		mOFN.lpstrDefExt = L"jpeg";
+		mOFN.lpstrFilter =
+			L"JPEG Images (*.jpeg)\0*.jpeg\0" \
+			L"\0";
+		break;
 	case FFSAVE_AVI:
 		if (filename.empty())
 		{
@@ -642,7 +662,16 @@ OSStatus	LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& fi
 			creator = 'prvw';
 			extension = CFSTR(".bmp");
 			break;
-		
+		case FFSAVE_JPEG:
+			type = 'JPEG';
+			creator = 'prvw';
+			extension = CFSTR(".jpeg");
+			break;
+		case FFSAVE_PNG:
+			type = 'PNG ';
+			creator = 'prvw';
+			extension = CFSTR(".png");
+			break;
 		case FFSAVE_AVI:
 			type = '\?\?\?\?';
 			creator = '\?\?\?\?';
diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h
index 012524a5410b0d673b5b5d46c2d59c14cbd51414..83a935752342508d4e65562667e155e209aa2d28 100644
--- a/indra/newview/llfilepicker.h
+++ b/indra/newview/llfilepicker.h
@@ -107,6 +107,8 @@ class LLFilePicker
 		FFSAVE_COLLADA = 10,
 		FFSAVE_RAW = 11,
 		FFSAVE_J2C = 12,
+		FFSAVE_PNG = 13,
+		FFSAVE_JPEG = 14,
 	};
 
 	// open the dialog. This is a modal operation
diff --git a/indra/newview/llfloaterland.cpp b/indra/newview/llfloaterland.cpp
index 58ad07c5bb177d45bf41cc16d2690dcd8f88a489..5dfbee73a432c408e58f9ca3e72f8ded90d81c7c 100644
--- a/indra/newview/llfloaterland.cpp
+++ b/indra/newview/llfloaterland.cpp
@@ -434,7 +434,7 @@ void LLPanelLandGeneral::refresh()
 		mEditName->setText(LLStringUtil::null);
 
 		mEditDesc->setEnabled(FALSE);
-		mEditDesc->setText(LLStringUtil::null);
+		mEditDesc->setText(getString("no_selection_text"));
 
 		mTextSalePending->setText(LLStringUtil::null);
 		mTextSalePending->setEnabled(FALSE);
@@ -1430,6 +1430,7 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
 	LLUUID	owner_id;
 	BOOL	is_group_owned;
 	S32		object_count;
+	U32		most_recent_time = 0;
 	BOOL	is_online;
 	std::string object_count_str;
 	//BOOL b_need_refresh = FALSE;
@@ -1447,7 +1448,10 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
 		msg->getBOOLFast(_PREHASH_Data, _PREHASH_IsGroupOwned,	is_group_owned,	i);
 		msg->getS32Fast (_PREHASH_Data, _PREHASH_Count,			object_count,	i);
 		msg->getBOOLFast(_PREHASH_Data, _PREHASH_OnlineStatus,	is_online,		i);
-
+		if(msg->getNumberOfBlocks("DataExtended"))
+		{
+			msg->getU32("DataExtended", "TimeStamp", most_recent_time, i);
+		}
 		if (owner_id.isNull())
 		{
 			continue;
@@ -1474,6 +1478,9 @@ void LLPanelLandObjects::processParcelObjectOwnersReply(LLMessageSystem *msg, vo
 
 		object_count_str = llformat("%d", object_count);
 		row->addColumn(object_count_str, FONT);
+		
+		row->addColumn(formatted_time((time_t)most_recent_time), FONT);
+
 
 		if (is_group_owned)
 		{
@@ -2165,7 +2172,6 @@ LLPanelLandAccess::LLPanelLandAccess(LLParcelSelectionHandle& parcel)
 }
 
 
-
 BOOL LLPanelLandAccess::postBuild()
 {
 	childSetCommitCallback("public_access", onCommitPublicAccess, this);
@@ -2427,12 +2433,14 @@ void LLPanelLandAccess::refresh_ui()
 		childSetEnabled("AccessList", can_manage_allowed);
 		S32 allowed_list_count = parcel->mAccessList.size();
 		childSetEnabled("add_allowed", can_manage_allowed && allowed_list_count < PARCEL_MAX_ACCESS_LIST);
-		childSetEnabled("remove_allowed", can_manage_allowed && allowed_list_count > 0);
+		BOOL has_selected = mListAccess->getSelectionInterface()->getFirstSelectedIndex() >= 0;
+		childSetEnabled("remove_allowed", can_manage_allowed && has_selected);
 		
 		childSetEnabled("BannedList", can_manage_banned);
 		S32 banned_list_count = parcel->mBanList.size();
 		childSetEnabled("add_banned", can_manage_banned && banned_list_count < PARCEL_MAX_ACCESS_LIST);
-		childSetEnabled("remove_banned", can_manage_banned && banned_list_count > 0);
+		has_selected = mListBanned->getSelectionInterface()->getFirstSelectedIndex() >= 0;
+		childSetEnabled("remove_banned", can_manage_banned && has_selected);
 	}
 }
 		
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index fc3c0952cb2bdc760e40064b9b3e51ee59d2d1f5..3b2fb43f6193571cc991b6566783791824735e4b 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -816,8 +816,7 @@ BOOL LLPanelRegionDebugInfo::postBuild()
 	initHelpBtn("restart_help",				"HelpRegionRestart");
 
 	childSetAction("choose_avatar_btn", onClickChooseAvatar, this);
-	childSetAction("return_scripted_other_land_btn", onClickReturnScriptedOtherLand, this);
-	childSetAction("return_scripted_all_btn", onClickReturnScriptedAll, this);
+	childSetAction("return_btn", onClickReturn, this);
 	childSetAction("top_colliders_btn", onClickTopColliders, this);
 	childSetAction("top_scripts_btn", onClickTopScripts, this);
 	childSetAction("restart_btn", onClickRestart, this);
@@ -832,10 +831,13 @@ bool LLPanelRegionDebugInfo::refreshFromRegion(LLViewerRegion* region)
 	BOOL allow_modify = gAgent.isGodlike() || (region && region->canManageEstate());
 	setCtrlsEnabled(allow_modify);
 	childDisable("apply_btn");
-
+	childDisable("target_avatar_name");
+	
 	childSetEnabled("choose_avatar_btn", allow_modify);
-	childSetEnabled("return_scripted_other_land_btn", allow_modify && !mTargetAvatar.isNull());
-	childSetEnabled("return_scripted_all_btn", allow_modify && !mTargetAvatar.isNull());
+	childSetEnabled("return_scripts", allow_modify && !mTargetAvatar.isNull());
+	childSetEnabled("return_other_land", allow_modify && !mTargetAvatar.isNull());
+	childSetEnabled("return_estate_wide", allow_modify && !mTargetAvatar.isNull());
+	childSetEnabled("return_btn", allow_modify && !mTargetAvatar.isNull());
 	childSetEnabled("top_colliders_btn", allow_modify);
 	childSetEnabled("top_scripts_btn", allow_modify);
 	childSetEnabled("restart_btn", allow_modify);
@@ -881,61 +883,56 @@ void LLPanelRegionDebugInfo::callbackAvatarID(const std::vector<std::string>& na
 }
 
 // static
-void LLPanelRegionDebugInfo::onClickReturnScriptedOtherLand(void* data)
+void LLPanelRegionDebugInfo::onClickReturn(void* data)
 {
 	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
 	if (panelp->mTargetAvatar.isNull()) return;
 
 	LLStringUtil::format_map_t args;
 	args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
-	gViewerWindow->alertXml("ReturnScriptedOnOthersLand", args, callbackReturnScriptedOtherLand, data);
+	gViewerWindow->alertXml("EstateObjectReturn", args, callbackReturn, data);
 }
 
 // static
-void LLPanelRegionDebugInfo::callbackReturnScriptedOtherLand( S32 option, void* userdata )
+void LLPanelRegionDebugInfo::callbackReturn( S32 option, void* userdata )
 {
 	if (option != 0) return;
 
 	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata;
 	if (!self->mTargetAvatar.isNull())
 	{
-		U32 flags = 0;
-		flags = flags | SWD_OTHERS_LAND_ONLY;
-		flags = flags | SWD_ALWAYS_RETURN_OBJECTS;
-		flags |= SWD_SCRIPTED_ONLY;
-
-		send_sim_wide_deletes(self->mTargetAvatar, flags);
-	}
-}
+		U32 flags = SWD_ALWAYS_RETURN_OBJECTS;
 
-// static
-void LLPanelRegionDebugInfo::onClickReturnScriptedAll(void* data)
-{
-	LLPanelRegionDebugInfo* panelp = (LLPanelRegionDebugInfo*) data;
-	if (panelp->mTargetAvatar.isNull()) return;
-	
-	
-	LLStringUtil::format_map_t args;
-	args["[USER_NAME]"] = panelp->childGetValue("target_avatar_name").asString();
-	gViewerWindow->alertXml("ReturnScriptedOnAllLand", args, callbackReturnScriptedAll, data);
-}
-
-// static
-void LLPanelRegionDebugInfo::callbackReturnScriptedAll( S32 option, void* userdata )
-{
-	if (option != 0) return;
+		if (self->childGetValue("return_scripts").asBoolean())
+		{
+			flags |= SWD_SCRIPTED_ONLY;
+		}
+		
+		if (self->childGetValue("return_other_land").asBoolean())
+		{
+			flags |= SWD_OTHERS_LAND_ONLY;
+		}
 
-	LLPanelRegionDebugInfo* self = (LLPanelRegionDebugInfo*) userdata;
-	if (!self->mTargetAvatar.isNull())
-	{
-		U32 flags = 0;
-		flags |= SWD_ALWAYS_RETURN_OBJECTS;
-		flags |= SWD_SCRIPTED_ONLY;
+		if (self->childGetValue("return_estate_wide").asBoolean())
+		{
+			// send as estate message - routed by spaceserver to all regions in estate
+			strings_t strings;
+			strings.push_back(llformat("%d", flags));
+			strings.push_back(self->mTargetAvatar.asString());
 
-		send_sim_wide_deletes(self->mTargetAvatar, flags);
+			LLUUID invoice(LLFloaterRegionInfo::getLastInvoice());
+		
+			self->sendEstateOwnerMessage(gMessageSystem, "estateobjectreturn", invoice, strings);
+		}
+		else
+		{
+			// send to this simulator only
+			send_sim_wide_deletes(self->mTargetAvatar, flags);
+		}
 	}
 }
 
+
 // static
 void LLPanelRegionDebugInfo::onClickTopColliders(void* data)
 {
diff --git a/indra/newview/llfloaterregioninfo.h b/indra/newview/llfloaterregioninfo.h
index 7d05ffa5bc52644902cbd44ed556af0ec763ca15..8bcab111b593c5985665842ac7eb4392fd866dd1 100644
--- a/indra/newview/llfloaterregioninfo.h
+++ b/indra/newview/llfloaterregioninfo.h
@@ -186,10 +186,8 @@ class LLPanelRegionDebugInfo : public LLPanelRegionInfo
 
 	static void onClickChooseAvatar(void*);
 	static void callbackAvatarID(const std::vector<std::string>& names, const std::vector<LLUUID>& ids, void* data);
-	static void onClickReturnScriptedOtherLand(void*);
-	static void callbackReturnScriptedOtherLand(S32 option, void*);
-	static void onClickReturnScriptedAll(void*);
-	static void callbackReturnScriptedAll(S32 option, void*);
+	static void onClickReturn(void *);
+	static void callbackReturn(S32 option, void*);
 	static void onClickTopColliders(void*);
 	static void onClickTopScripts(void*);
 	static void onClickRestart(void* data);
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index 1f601e6dc1474890419c3b0acf55ace662928ab3..811fc4eb0334a261143a6d3d10ebf79982122090 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -68,6 +68,8 @@
 #include "llgl.h"
 #include "llglheaders.h"
 #include "llimagejpeg.h"
+#include "llimagepng.h"
+#include "llimagebmp.h"
 #include "llimagej2c.h"
 #include "llvfile.h"
 #include "llvfs.h"
@@ -83,7 +85,7 @@ LLSnapshotFloaterView* gSnapshotFloaterView = NULL;
 
 LLFloaterSnapshot* LLFloaterSnapshot::sInstance = NULL;
 
-const F32 SNAPSHOT_TIME_DELAY = 1.f;
+const F32 AUTO_SNAPSHOT_TIME_DELAY = 1.f;
 
 F32 SHINE_TIME = 0.5f;
 F32 SHINE_WIDTH = 0.6f;
@@ -93,6 +95,7 @@ S32 BORDER_WIDTH = 6;
 
 const S32 MAX_POSTCARD_DATASIZE = 1024 * 1024; // one megabyte
 const S32 MAX_TEXTURE_SIZE = 512 ; //max upload texture size 512 * 512
+
 ///----------------------------------------------------------------------------
 /// Class LLSnapshotLivePreview 
 ///----------------------------------------------------------------------------
@@ -103,9 +106,10 @@ class LLSnapshotLivePreview : public LLView
 	{
 		SNAPSHOT_POSTCARD,
 		SNAPSHOT_TEXTURE,
-		SNAPSHOT_BITMAP
+		SNAPSHOT_LOCAL
 	};
 
+
 	LLSnapshotLivePreview(const LLRect& rect);
 	~LLSnapshotLivePreview();
 
@@ -119,6 +123,7 @@ class LLSnapshotLivePreview : public LLView
 	S32  getMaxImageSize() {return mMaxImageSize ;}
 	
 	ESnapshotType getSnapshotType() const { return mSnapshotType; }
+	LLFloaterSnapshot::ESnapshotFormat getSnapshotFormat() const { return mSnapshotFormat; }
 	BOOL getSnapshotUpToDate() const { return mSnapshotUpToDate; }
 	BOOL isSnapshotActive() { return mSnapshotActive; }
 	LLImageGL* getThumbnailImage() const { return mThumbnailImage ; }
@@ -133,9 +138,10 @@ class LLSnapshotLivePreview : public LLView
 	BOOL isImageScaled();
 	
 	void setSnapshotType(ESnapshotType type) { mSnapshotType = type; }
+	void setSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat type) { mSnapshotFormat = type; }
 	void setSnapshotQuality(S32 quality);
 	void setSnapshotBufferType(LLViewerWindow::ESnapshotType type) { mSnapshotBufferType = type; }
-	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE);
+	void updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail = FALSE, F32 delay = 0.f);
 	LLFloaterPostcard* savePostcard();
 	void saveTexture();
 	BOOL saveLocal();
@@ -147,7 +153,7 @@ class LLSnapshotLivePreview : public LLView
 
 	static void onIdle( void* snapshot_preview );
 
-protected:
+private:
 	LLColor4					mColor;
 	LLPointer<LLImageGL>		mViewerImage[2];
 	LLRect						mImageRect[2];
@@ -165,9 +171,9 @@ class LLSnapshotLivePreview : public LLView
 	BOOL                        mThumbnailUpToDate ;
 
 	S32							mCurImageIndex;
-	LLPointer<LLImageRaw>		mRawImage;
-	LLPointer<LLImageRaw>		mRawImageEncoded;
-	LLPointer<LLImageJPEG>		mJPEGImage;
+	LLPointer<LLImageRaw>		mPreviewImage;
+	LLPointer<LLImageRaw>		mPreviewImageEncoded;
+	LLPointer<LLImageFormatted>	mFormattedImage;
 	LLFrameTimer				mSnapshotDelayTimer;
 	S32							mShineCountdown;
 	LLFrameTimer				mShineAnimTimer;
@@ -177,6 +183,7 @@ class LLSnapshotLivePreview : public LLView
 	S32							mSnapshotQuality;
 	S32							mDataSize;
 	ESnapshotType				mSnapshotType;
+	LLFloaterSnapshot::ESnapshotFormat	mSnapshotFormat;
 	BOOL						mSnapshotUpToDate;
 	LLFrameTimer				mFallAnimTimer;
 	LLVector3					mCameraPos;
@@ -195,16 +202,17 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
 	LLView(std::string("snapshot_live_preview"), rect, FALSE), 
 	mColor(1.f, 0.f, 0.f, 0.5f), 
 	mCurImageIndex(0),
-	mRawImage(NULL),
+	mPreviewImage(NULL),
 	mThumbnailImage(NULL) ,
-	mRawImageEncoded(NULL),
-	mJPEGImage(NULL),
+	mPreviewImageEncoded(NULL),
+	mFormattedImage(NULL),
 	mShineCountdown(0),
 	mFlashAlpha(0.f),
 	mNeedsFlash(TRUE),
 	mSnapshotQuality(gSavedSettings.getS32("SnapshotQuality")),
 	mDataSize(0),
 	mSnapshotType(SNAPSHOT_POSTCARD),
+	mSnapshotFormat(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat"))),
 	mSnapshotUpToDate(FALSE),
 	mCameraPos(LLViewerCamera::getInstance()->getOrigin()),
 	mCameraRot(LLViewerCamera::getInstance()->getQuaternion()),
@@ -212,6 +220,7 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
 	mSnapshotBufferType(LLViewerWindow::SNAPSHOT_TYPE_COLOR),
 	mSnapshotSoundPlayed(false)
 {
+	setSnapshotQuality(gSavedSettings.getS32("SnapshotQuality"));
 	mSnapshotDelayTimer.setTimerExpirySec(0.0f);
 	mSnapshotDelayTimer.start();
 // 	gIdleCallbacks.addFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
@@ -233,9 +242,9 @@ LLSnapshotLivePreview::LLSnapshotLivePreview (const LLRect& rect) :
 LLSnapshotLivePreview::~LLSnapshotLivePreview()
 {
 	// delete images
-	mRawImage = NULL;
-	mRawImageEncoded = NULL;
-	mJPEGImage = NULL;
+	mPreviewImage = NULL;
+	mPreviewImageEncoded = NULL;
+	mFormattedImage = NULL;
 
 // 	gIdleCallbacks.deleteFunction( &LLSnapshotLivePreview::onIdle, (void*)this );
 	sList.erase(this);
@@ -293,7 +302,7 @@ BOOL LLSnapshotLivePreview::isImageScaled()
 	return mImageScaled[mCurImageIndex];
 }
 
-void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail) 
+void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail, F32 delay) 
 { 
 	if (mSnapshotUpToDate)
 	{
@@ -333,7 +342,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
 	if (new_snapshot)
 	{
 		mSnapshotDelayTimer.start();
-		mSnapshotDelayTimer.setTimerExpirySec(SNAPSHOT_TIME_DELAY);
+		mSnapshotDelayTimer.setTimerExpirySec(delay);
 	}
 	else if(new_thumbnail)
 	{
@@ -347,6 +356,7 @@ void LLSnapshotLivePreview::updateSnapshot(BOOL new_snapshot, BOOL new_thumbnail
 
 void LLSnapshotLivePreview::setSnapshotQuality(S32 quality)
 {
+	llclamp(quality, 0, 100);
 	if (quality != mSnapshotQuality)
 	{
 		mSnapshotQuality = quality;
@@ -396,7 +406,7 @@ void LLSnapshotLivePreview::drawPreviewRect(S32 offset_x, S32 offset_y)
 void LLSnapshotLivePreview::draw()
 {
 	if (mViewerImage[mCurImageIndex].notNull() &&
-	    mRawImageEncoded.notNull() &&
+	    mPreviewImageEncoded.notNull() &&
 	    mSnapshotUpToDate)
 	{
 		LLColor4 bg_color(0.f, 0.f, 0.3f, 0.4f);
@@ -685,8 +695,8 @@ void LLSnapshotLivePreview::generateThumbnailImage(BOOL force_update)
 
 	LLPointer<LLImageRaw> raw = NULL ;
 	S32 w , h ;
-	w = get_nearest_power_two(mThumbnailWidth, 512) * 2 ;
-	h = get_nearest_power_two(mThumbnailHeight, 512) * 2 ;
+	w = get_lower_power_two(mThumbnailWidth, 512) * 2 ;
+	h = get_lower_power_two(mThumbnailHeight, 512) * 2 ;
 
 	{
 		raw = new LLImageRaw ;
@@ -723,131 +733,155 @@ void LLSnapshotLivePreview::onIdle( void* snapshot_preview )
 		previewp->mCameraPos = new_camera_pos;
 		previewp->mCameraRot = new_camera_rot;
 		// request a new snapshot whenever the camera moves, with a time delay
- 		previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"));
+		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
+		previewp->updateSnapshot(autosnap, FALSE, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
+	}
+
+	// see if it's time yet to snap the shot and bomb out otherwise.
+	previewp->mSnapshotActive = 
+		(previewp->mSnapshotDelayTimer.getStarted() &&	previewp->mSnapshotDelayTimer.hasExpired())
+		&& !LLToolCamera::getInstance()->hasMouseCapture(); // don't take snapshots while ALT-zoom active
+	if ( ! previewp->mSnapshotActive)
+	{
+		return;
 	}
 
-	previewp->mSnapshotActive = (previewp->mSnapshotDelayTimer.getStarted() &&	
-								 previewp->mSnapshotDelayTimer.hasExpired());
+	// time to produce a snapshot
 
-	// don't take snapshots while ALT-zoom active
-	if (LLToolCamera::getInstance()->hasMouseCapture())
+	if (!previewp->mPreviewImage)
 	{
-		previewp->mSnapshotActive = FALSE;
+		previewp->mPreviewImage = new LLImageRaw;
 	}
 
-	if (previewp->mSnapshotActive)
+	if (!previewp->mPreviewImageEncoded)
 	{
-		if (!previewp->mRawImage)
-		{
-			previewp->mRawImage = new LLImageRaw;
-		}
+		previewp->mPreviewImageEncoded = new LLImageRaw;
+	}
 
-		if (!previewp->mRawImageEncoded)
+	previewp->setVisible(FALSE);
+	previewp->setEnabled(FALSE);
+	
+	previewp->getWindow()->incBusyCount();
+	previewp->mImageScaled[previewp->mCurImageIndex] = FALSE;
+
+	// grab the raw image and encode it into desired format
+	if(gViewerWindow->rawSnapshot(
+							previewp->mPreviewImage,
+							previewp->mWidth[previewp->mCurImageIndex],
+							previewp->mHeight[previewp->mCurImageIndex],
+							previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
+							previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
+							gSavedSettings.getBOOL("RenderUIInSnapshot"),
+							FALSE,
+							previewp->mSnapshotBufferType,
+							previewp->getMaxImageSize()))
+	{
+		previewp->mPreviewImageEncoded->resize(
+			previewp->mPreviewImage->getWidth(), 
+			previewp->mPreviewImage->getHeight(), 
+			previewp->mPreviewImage->getComponents());
+
+		if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
 		{
-			previewp->mRawImageEncoded = new LLImageRaw;
+			// Always play the sound once, on window open.
+			// Don't keep playing if automatic
+			// updates are enabled. It's too invasive. JC
+			if (!previewp->mSnapshotSoundPlayed
+				|| !gSavedSettings.getBOOL("AutoSnapshot") )
+			{
+				gViewerWindow->playSnapshotAnimAndSound();
+				previewp->mSnapshotSoundPlayed = true;
+			}
 		}
-
-		previewp->setVisible(FALSE);
-		previewp->setEnabled(FALSE);
 		
-		previewp->getWindow()->incBusyCount();
-		previewp->mImageScaled[previewp->mCurImageIndex] = FALSE;
-
-		// do update
-		if(gViewerWindow->rawSnapshot(previewp->mRawImage,
-								previewp->mWidth[previewp->mCurImageIndex],
-								previewp->mHeight[previewp->mCurImageIndex],
-								previewp->mKeepAspectRatio,//gSavedSettings.getBOOL("KeepAspectForSnapshot"),
-								previewp->getSnapshotType() == LLSnapshotLivePreview::SNAPSHOT_TEXTURE,
-								gSavedSettings.getBOOL("RenderUIInSnapshot"),
-								FALSE,
-								previewp->mSnapshotBufferType,
-								previewp->getMaxImageSize()))
+		if(previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
 		{
-			previewp->mRawImageEncoded->resize(previewp->mRawImage->getWidth(), previewp->mRawImage->getHeight(), previewp->mRawImage->getComponents());
-
-			if (!gSavedSettings.getBOOL("QuietSnapshotsToDisk"))
+			LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
+			LLPointer<LLImageRaw> scaled = new LLImageRaw(
+				previewp->mPreviewImage->getData(),
+				previewp->mPreviewImage->getWidth(),
+				previewp->mPreviewImage->getHeight(),
+				previewp->mPreviewImage->getComponents());
+		
+			scaled->biasedScaleToPowerOfTwo(512);
+			previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
+			if (formatted->encode(scaled, 0.f))
 			{
-				// Always play the sound once, on window open.
-				// Don't keep playing if automatic
-				// updates are enabled. It's too invasive. JC
-				if (!previewp->mSnapshotSoundPlayed
-					|| !gSavedSettings.getBOOL("AutoSnapshot") )
-				{
-					gViewerWindow->playSnapshotAnimAndSound();
-					previewp->mSnapshotSoundPlayed = true;
-				}
+				previewp->mDataSize = formatted->getDataSize();
+				formatted->decode(previewp->mPreviewImageEncoded, 0);
 			}
-
-			if (previewp->getSnapshotType() == SNAPSHOT_POSTCARD)
+		}
+		else
+		{
+			// delete any existing image
+			previewp->mFormattedImage = NULL;
+			// now create the new one of the appropriate format.
+			// note: postcards hardcoded to use jpeg always.
+			LLFloaterSnapshot::ESnapshotFormat format = previewp->getSnapshotType() == SNAPSHOT_POSTCARD
+				? LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG : previewp->getSnapshotFormat();
+			switch(format)
 			{
-				// *FIX: just resize and reuse existing jpeg?
-				previewp->mJPEGImage = NULL; // deletes image
-				previewp->mJPEGImage = new LLImageJPEG();
-				previewp->mJPEGImage->setEncodeQuality(llclamp(previewp->mSnapshotQuality, 0, 100));
-				if (previewp->mJPEGImage->encode(previewp->mRawImage, 0.0f))
-				{
-					previewp->mDataSize = previewp->mJPEGImage->getDataSize();
-					previewp->mJPEGImage->decode(previewp->mRawImageEncoded, 0.0f);
-				}
+			case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+				previewp->mFormattedImage = new LLImagePNG(); 
+				break;
+			case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+				previewp->mFormattedImage = new LLImageJPEG(previewp->mSnapshotQuality); 
+				break;
+			case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP:
+				previewp->mFormattedImage = new LLImageBMP(); 
+				break;
 			}
-			else if (previewp->getSnapshotType() == SNAPSHOT_TEXTURE)
+			if (previewp->mFormattedImage->encode(previewp->mPreviewImage, 0))
 			{
-				LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
-				LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImage->getData(),
-															  previewp->mRawImage->getWidth(),
-															  previewp->mRawImage->getHeight(),
-															  previewp->mRawImage->getComponents());
-			
-				scaled->biasedScaleToPowerOfTwo(512);
-				previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
-				if (formatted->encode(scaled, 0.0f))
+				// special case BMP to copy instead of decode otherwise decode will crash.
+				if(format == LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP)
 				{
-					previewp->mDataSize = formatted->getDataSize();
-					formatted->decode(previewp->mRawImageEncoded, 0.0f);
+					previewp->mPreviewImageEncoded->copy(previewp->mPreviewImage);
+				}
+				else
+				{
+					previewp->mDataSize = previewp->mFormattedImage->getDataSize();
+					previewp->mFormattedImage->decode(previewp->mPreviewImageEncoded, 0);
 				}
 			}
-			else
-			{
-				previewp->mRawImageEncoded->copy(previewp->mRawImage);
-				previewp->mDataSize = previewp->mRawImage->getDataSize();
-			}
+		}
 
-			LLPointer<LLImageRaw> scaled = new LLImageRaw(previewp->mRawImageEncoded->getData(),
-														  previewp->mRawImageEncoded->getWidth(),
-														  previewp->mRawImageEncoded->getHeight(),
-														  previewp->mRawImageEncoded->getComponents());
-			
-			// leave original image dimensions, just scale up texture buffer
-			if (previewp->mRawImageEncoded->getWidth() > 1024 || previewp->mRawImageEncoded->getHeight() > 1024)
-			{
-				// go ahead and shrink image to appropriate power of 2 for display
-				scaled->biasedScaleToPowerOfTwo(1024);
-				previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
-			}
-			else
-			{
-				// expand image but keep original image data intact
-				scaled->expandToPowerOfTwo(1024, FALSE);
-			}
+		LLPointer<LLImageRaw> scaled = new LLImageRaw(
+			previewp->mPreviewImageEncoded->getData(),
+			previewp->mPreviewImageEncoded->getWidth(),
+			previewp->mPreviewImageEncoded->getHeight(),
+			previewp->mPreviewImageEncoded->getComponents());
+		
+		// leave original image dimensions, just scale up texture buffer
+		if (previewp->mPreviewImageEncoded->getWidth() > 1024 || previewp->mPreviewImageEncoded->getHeight() > 1024)
+		{
+			// go ahead and shrink image to appropriate power of 2 for display
+			scaled->biasedScaleToPowerOfTwo(1024);
+			previewp->mImageScaled[previewp->mCurImageIndex] = TRUE;
+		}
+		else
+		{
+			// expand image but keep original image data intact
+			scaled->expandToPowerOfTwo(1024, FALSE);
+		}
 
-			previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
-			previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
-			LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
-			previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
+		previewp->mViewerImage[previewp->mCurImageIndex] = new LLImageGL(scaled, FALSE);
+		previewp->mViewerImage[previewp->mCurImageIndex]->setMipFilterNearest(previewp->getSnapshotType() != SNAPSHOT_TEXTURE);
+		LLViewerImage::bindTexture(previewp->mViewerImage[previewp->mCurImageIndex]);
+		previewp->mViewerImage[previewp->mCurImageIndex]->setClamp(TRUE, TRUE);
 
-			previewp->mSnapshotUpToDate = TRUE;
-			previewp->generateThumbnailImage(TRUE) ;
+		previewp->mSnapshotUpToDate = TRUE;
+		previewp->generateThumbnailImage(TRUE) ;
 
-			previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
-			previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
-		}
-		previewp->getWindow()->decBusyCount();
-		// only show fullscreen preview when in freeze frame mode
-		previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
-		previewp->mSnapshotDelayTimer.stop();
-		previewp->mSnapshotActive = FALSE;
+		previewp->mPosTakenGlobal = gAgent.getCameraPositionGlobal();
+		previewp->mShineCountdown = 4; // wait a few frames to avoid animation glitch due to readback this frame
 	}
+	previewp->getWindow()->decBusyCount();
+	// only show fullscreen preview when in freeze frame mode
+	previewp->setVisible(gSavedSettings.getBOOL("UseFreezeFrame"));
+	previewp->mSnapshotDelayTimer.stop();
+	previewp->mSnapshotActive = FALSE;
+
 	if(!previewp->getThumbnailUpToDate())
 	{
 		previewp->generateThumbnailImage() ;
@@ -876,11 +910,16 @@ LLFloaterPostcard* LLSnapshotLivePreview::savePostcard()
 		image_scale.setVec(llmin(1.f, (F32)mWidth[mCurImageIndex] / (F32)getCurrentImage()->getWidth()), llmin(1.f, (F32)mHeight[mCurImageIndex] / (F32)getCurrentImage()->getHeight()));
 	}
 
-
-	LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(mJPEGImage, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);
+	LLImageJPEG* jpg = dynamic_cast<LLImageJPEG*>(mFormattedImage.get());
+	if(!jpg)
+	{
+		llwarns << "Formatted image not a JPEG" << llendl;
+		return NULL;
+	}
+	LLFloaterPostcard* floater = LLFloaterPostcard::showFromSnapshot(jpg, mViewerImage[mCurImageIndex], image_scale, mPosTakenGlobal);
 	// relinquish lifetime of viewerimage and jpeg image to postcard floater
 	mViewerImage[mCurImageIndex] = NULL;
-	mJPEGImage = NULL;
+	mFormattedImage = NULL;
 
 	return floater;
 }
@@ -893,10 +932,10 @@ void LLSnapshotLivePreview::saveTexture()
 	LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
 		
 	LLPointer<LLImageJ2C> formatted = new LLImageJ2C;
-	LLPointer<LLImageRaw> scaled = new LLImageRaw(mRawImage->getData(),
-												  mRawImage->getWidth(),
-												  mRawImage->getHeight(),
-												  mRawImage->getComponents());
+	LLPointer<LLImageRaw> scaled = new LLImageRaw(mPreviewImage->getData(),
+												  mPreviewImage->getWidth(),
+												  mPreviewImage->getHeight(),
+												  mPreviewImage->getComponents());
 	
 	scaled->biasedScaleToPowerOfTwo(512);
 			
@@ -928,7 +967,7 @@ void LLSnapshotLivePreview::saveTexture()
 
 BOOL LLSnapshotLivePreview::saveLocal()
 {
-	return gViewerWindow->saveImageNumbered(mRawImage);
+	return gViewerWindow->saveImageNumbered(mFormattedImage);
 }
 
 ///----------------------------------------------------------------------------
@@ -951,6 +990,7 @@ class LLFloaterSnapshot::Impl
 	}
 	static void onClickDiscard(void* data);
 	static void onClickKeep(void* data);
+	static void onCommitSave(LLUICtrl* ctrl, void* data);
 	static void onClickNewSnapshot(void* data);
 	static void onClickAutoSnap(LLUICtrl *ctrl, void* data);
 	//static void onClickAdvanceSnap(LLUICtrl *ctrl, void* data);
@@ -965,6 +1005,7 @@ class LLFloaterSnapshot::Impl
 	static void onCommitFreezeFrame(LLUICtrl* ctrl, void* data);
 	static void onCommitLayerTypes(LLUICtrl* ctrl, void*data);
 	static void onCommitSnapshotType(LLUICtrl* ctrl, void* data);
+	static void onCommitSnapshotFormat(LLUICtrl* ctrl, void* data);
 	static void onCommitCustomResolution(LLUICtrl *ctrl, void* data);
 	static void resetSnapshotSizeOnUI(LLFloaterSnapshot *view, S32 width, S32 height) ;
 	static BOOL checkImageSize(LLSnapshotLivePreview* previewp, S32& width, S32& height, BOOL isWidthChanged, S32 max_value);
@@ -973,12 +1014,14 @@ class LLFloaterSnapshot::Impl
 	static void setResolution(LLFloaterSnapshot* floater, const std::string& comboname);
 	static void updateControls(LLFloaterSnapshot* floater);
 	static void updateLayout(LLFloaterSnapshot* floater);
+	static void updateResolutionTextEntry(LLFloaterSnapshot* floater);
 
 	static LLHandle<LLView> sPreviewHandle;
 	static BOOL         sAspectRatioCheckOff ;
 	
 private:
 	static LLSnapshotLivePreview::ESnapshotType getTypeIndex(LLFloaterSnapshot* floater);
+	static ESnapshotFormat getFormatIndex(LLFloaterSnapshot* floater);
 	static LLViewerWindow::ESnapshotType getLayerType(LLFloaterSnapshot* floater);
 	static void comboSetCustom(LLFloaterSnapshot *floater, const std::string& comboname);
 	static void checkAutoSnapshot(LLSnapshotLivePreview* floater, BOOL update_thumbnail = FALSE);
@@ -995,6 +1038,7 @@ LLHandle<LLView> LLFloaterSnapshot::Impl::sPreviewHandle;
 
 //static 
 BOOL LLFloaterSnapshot::Impl::sAspectRatioCheckOff = FALSE ;
+
 // static
 LLSnapshotLivePreview* LLFloaterSnapshot::Impl::getPreviewView(LLFloaterSnapshot *floater)
 {
@@ -1013,10 +1057,28 @@ LLSnapshotLivePreview::ESnapshotType LLFloaterSnapshot::Impl::getTypeIndex(LLFlo
 	else if (id == "texture")
 		index = LLSnapshotLivePreview::SNAPSHOT_TEXTURE;
 	else if (id == "local")
-		index = LLSnapshotLivePreview::SNAPSHOT_BITMAP;
+		index = LLSnapshotLivePreview::SNAPSHOT_LOCAL;
+	return index;
+}
+
+
+// static
+LLFloaterSnapshot::ESnapshotFormat LLFloaterSnapshot::Impl::getFormatIndex(LLFloaterSnapshot* floater)
+{
+	ESnapshotFormat index = SNAPSHOT_FORMAT_PNG;
+	LLSD value = floater->childGetValue("local_format_combo");
+	const std::string id = value.asString();
+	if (id == "PNG")
+		index = SNAPSHOT_FORMAT_PNG;
+	else if (id == "JPEG")
+		index = SNAPSHOT_FORMAT_JPEG;
+	else if (id == "BMP")
+		index = SNAPSHOT_FORMAT_BMP;
 	return index;
 }
 
+
+
 // static
 LLViewerWindow::ESnapshotType LLFloaterSnapshot::Impl::getLayerType(LLFloaterSnapshot* floater)
 {
@@ -1141,10 +1203,10 @@ void LLFloaterSnapshot::Impl::updateLayout(LLFloaterSnapshot* floaterp)
 // static
 void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 {
-	BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot") ;
 	LLRadioGroup* snapshot_type_radio = floater->getChild<LLRadioGroup>("snapshot_type_radio");
 	snapshot_type_radio->setSelectedIndex(gSavedSettings.getS32("LastSnapshotType"));
 	LLSnapshotLivePreview::ESnapshotType shot_type = getTypeIndex(floater);
+	ESnapshotFormat shot_format = (ESnapshotFormat)gSavedSettings.getS32("SnapshotFormat"); //getFormatIndex(floater);	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
 	LLViewerWindow::ESnapshotType layer_type = getLayerType(floater);
 
 	floater->childSetVisible("postcard_size_combo", FALSE);
@@ -1158,114 +1220,102 @@ void LLFloaterSnapshot::Impl::updateControls(LLFloaterSnapshot* floater)
 	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotTextureLastResolution"));
 	combo = floater->getChild<LLComboBox>("local_size_combo");
 	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotLocalLastResolution"));
-
-	floater->childSetVisible("upload_btn", FALSE);
-	floater->childSetVisible("send_btn", FALSE);
-	floater->childSetVisible("save_btn", FALSE);
-	floater->childSetEnabled("keep_aspect_check", FALSE) ;
+	combo = floater->getChild<LLComboBox>("local_format_combo");
+	if (combo) combo->selectNthItem(gSavedSettings.getS32("SnapshotFormat"));
+
+	floater->childSetVisible("upload_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_TEXTURE);
+	floater->childSetVisible("send_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD);
+	floater->childSetVisible("save_btn",			shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
+	floater->childSetEnabled("keep_aspect_check",	shot_type != LLSnapshotLivePreview::SNAPSHOT_TEXTURE && !sAspectRatioCheckOff);
+	floater->childSetEnabled("layer_types",			shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL);
+
+	BOOL is_advance = gSavedSettings.getBOOL("AdvanceSnapshot");
+	BOOL is_local = shot_type == LLSnapshotLivePreview::SNAPSHOT_LOCAL;
+	BOOL show_slider = 
+		shot_type == LLSnapshotLivePreview::SNAPSHOT_POSTCARD
+		|| (is_local && shot_format == LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG);
+
+	floater->childSetVisible("more_btn", !is_advance); // the only item hidden in advanced mode
+	floater->childSetVisible("less_btn",				is_advance);
+	floater->childSetVisible("type_label2",				is_advance);
+	floater->childSetVisible("format_label",			is_advance && is_local);
+	floater->childSetVisible("local_format_combo",		is_advance && is_local);
+	floater->childSetVisible("layer_types",				is_advance);
+	floater->childSetVisible("layer_type_label",		is_advance);
+	floater->childSetVisible("snapshot_width",			is_advance);
+	floater->childSetVisible("snapshot_height",			is_advance);
+	floater->childSetVisible("keep_aspect_check",		is_advance);
+	floater->childSetVisible("ui_check",				is_advance);
+	floater->childSetVisible("hud_check",				is_advance);
+	floater->childSetVisible("keep_open_check",			is_advance);
+	floater->childSetVisible("freeze_frame_check",		is_advance);
+	floater->childSetVisible("auto_snapshot_check",		is_advance);
+	floater->childSetVisible("image_quality_slider",	is_advance && show_slider);
 
 	switch(shot_type)
 	{
 	  case LLSnapshotLivePreview::SNAPSHOT_POSTCARD:
 		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 		floater->childSetValue("layer_types", "colors");
-		floater->childSetEnabled("layer_types", FALSE);
-		
 		if(is_advance)
 		{			
-			floater->childSetEnabled("image_quality_slider", TRUE);
 			setResolution(floater, "postcard_size_combo");
-
-			if(!sAspectRatioCheckOff)
-			{
-				floater->childSetEnabled("keep_aspect_check", TRUE) ;
-			}
 		}
-
-		floater->childSetVisible("send_btn", TRUE);
 		break;
 	  case LLSnapshotLivePreview::SNAPSHOT_TEXTURE:
 		layer_type = LLViewerWindow::SNAPSHOT_TYPE_COLOR;
 		floater->childSetValue("layer_types", "colors");
-		floater->childSetEnabled("layer_types", FALSE);
-		floater->childSetEnabled("image_quality_slider", FALSE);
-
 		if(is_advance)
 		{
 			setResolution(floater, "texture_size_combo");			
 		}
-
-		floater->childSetVisible("upload_btn", TRUE);
 		break;
-	  case LLSnapshotLivePreview::SNAPSHOT_BITMAP:
-		floater->childSetEnabled("layer_types", TRUE);
-		floater->childSetEnabled("image_quality_slider", FALSE);
-		
+	  case  LLSnapshotLivePreview::SNAPSHOT_LOCAL:
 		if(is_advance)
 		{
 			setResolution(floater, "local_size_combo");
-
-			if(!sAspectRatioCheckOff)
-			{
-				floater->childSetEnabled("keep_aspect_check", TRUE) ;
-			}
 		}
-
-		floater->childSetVisible("save_btn", TRUE);
 		break;
 	  default:
 		break;
 	}
 
-	if(is_advance)
-	{
-		floater->childSetVisible("type_label2", TRUE) ;
-		floater->childSetVisible("layer_types", TRUE) ;
-		floater->childSetVisible("layer_type_label", TRUE) ;
-		floater->childSetVisible("snapshot_width", TRUE) ;
-		floater->childSetVisible("snapshot_height", TRUE) ;
-		floater->childSetVisible("keep_aspect_check", TRUE) ;
-		floater->childSetVisible("ui_check", TRUE) ;
-		floater->childSetVisible("hud_check", TRUE) ;
-		floater->childSetVisible("keep_open_check", TRUE) ;
-		floater->childSetVisible("freeze_frame_check", TRUE) ;
-		floater->childSetVisible("auto_snapshot_check", TRUE) ;
-		floater->childSetVisible("image_quality_slider", TRUE);
-		floater->childSetVisible("more_btn", FALSE);
-		floater->childSetVisible("less_btn", TRUE);
-	}
-	else
-	{
-		floater->childSetVisible("type_label2", FALSE) ;
-		floater->childSetVisible("layer_types", FALSE) ;
-		floater->childSetVisible("layer_type_label", FALSE) ;
-		floater->childSetVisible("snapshot_width", FALSE) ;
-		floater->childSetVisible("snapshot_height", FALSE) ;
-		floater->childSetVisible("keep_aspect_check", FALSE) ;
-		floater->childSetVisible("ui_check", FALSE) ;
-		floater->childSetVisible("hud_check", FALSE) ;
-		floater->childSetVisible("keep_open_check", FALSE) ;
-		floater->childSetVisible("freeze_frame_check", FALSE) ;
-		floater->childSetVisible("auto_snapshot_check", FALSE) ;
-		floater->childSetVisible("image_quality_slider", FALSE);
-		floater->childSetVisible("more_btn", TRUE);
-		floater->childSetVisible("less_btn", FALSE);
-	}
+	updateResolutionTextEntry(floater);
 
 	LLSnapshotLivePreview* previewp = getPreviewView(floater);
 	if (previewp)
 	{
 		previewp->setSnapshotType(shot_type);
+		previewp->setSnapshotFormat(shot_format);
 		previewp->setSnapshotBufferType(layer_type);
 	}
 }
 
+// static
+void LLFloaterSnapshot::Impl::updateResolutionTextEntry(LLFloaterSnapshot* floater)
+{
+	LLSpinCtrl* width_spinner = floater->getChild<LLSpinCtrl>("snapshot_width");
+	LLSpinCtrl* height_spinner = floater->getChild<LLSpinCtrl>("snapshot_height");
+
+	if(getTypeIndex(floater) == LLSnapshotLivePreview::SNAPSHOT_TEXTURE)
+	{
+		width_spinner->setAllowEdit(FALSE);
+		height_spinner->setAllowEdit(FALSE);
+	}
+	else
+	{
+		width_spinner->setAllowEdit(TRUE);
+		height_spinner->setAllowEdit(TRUE);
+	}
+}
+
 // static
 void LLFloaterSnapshot::Impl::checkAutoSnapshot(LLSnapshotLivePreview* previewp, BOOL update_thumbnail)
 {
 	if (previewp)
-	{		
-		previewp->updateSnapshot(gSavedSettings.getBOOL("AutoSnapshot"), update_thumbnail);
+	{
+		BOOL autosnap = gSavedSettings.getBOOL("AutoSnapshot");
+		previewp->updateSnapshot(autosnap, update_thumbnail, autosnap ? AUTO_SNAPSHOT_TIME_DELAY : 0.f);
 	}
 }
 
@@ -1279,6 +1329,17 @@ void LLFloaterSnapshot::Impl::onClickDiscard(void* data)
 	}
 }
 
+
+// static
+void LLFloaterSnapshot::Impl::onCommitSave(LLUICtrl* ctrl, void* data)
+{
+	if (ctrl->getValue().asString() == "save as")
+	{
+		gViewerWindow->resetSnapshotLoc();
+	}
+	onClickKeep(data);
+}
+
 // static
 void LLFloaterSnapshot::Impl::onClickKeep(void* data)
 {
@@ -1294,7 +1355,7 @@ void LLFloaterSnapshot::Impl::onClickKeep(void* data)
 			LLFloaterPostcard* floater = previewp->savePostcard();
 			// if still in snapshot mode, put postcard floater in snapshot floaterview
 			// and link it to snapshot floater
-			if (!gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
+			if (floater && !gSavedSettings.getBOOL("CloseSnapshotOnKeep"))
 			{
 				gFloaterView->removeChild(floater);
 				gSnapshotFloaterView->addChild(floater);
@@ -1610,6 +1671,22 @@ void LLFloaterSnapshot::Impl::onCommitSnapshotType(LLUICtrl* ctrl, void* data)
 	}
 }
 
+
+//static 
+void LLFloaterSnapshot::Impl::onCommitSnapshotFormat(LLUICtrl* ctrl, void* data)
+{
+	LLFloaterSnapshot *view = (LLFloaterSnapshot *)data;		
+	if (view)
+	{
+		gSavedSettings.setS32("SnapshotFormat", getFormatIndex(view));
+		getPreviewView(view)->updateSnapshot(TRUE);
+		updateControls(view);
+	}
+}
+
+
+
+
 // static
 void LLFloaterSnapshot::Impl::comboSetCustom(LLFloaterSnapshot* floater, const std::string& comboname)
 {
@@ -1642,9 +1719,21 @@ BOOL LLFloaterSnapshot::Impl::checkImageSize(LLSnapshotLivePreview* previewp, S3
 			height = max_value ;
 		}
 
-		//round to nearest power of 2
-		width = get_nearest_power_two(width, MAX_TEXTURE_SIZE) ;
-		height = get_nearest_power_two(height, MAX_TEXTURE_SIZE) ;
+		//round to nearest power of 2 based on the direction of movement
+		// i.e. higher power of two if increasing texture resolution
+		if(gSavedSettings.getS32("LastSnapshotWidth") < width ||
+			gSavedSettings.getS32("LastSnapshotHeight") < height)
+		{
+			// Up arrow pressed
+			width = get_next_power_two(width, MAX_TEXTURE_SIZE) ;
+			height = get_next_power_two(height, MAX_TEXTURE_SIZE) ;
+		}
+		else
+		{
+			// Down or no change
+			width = get_lower_power_two(width, MAX_TEXTURE_SIZE) ;
+			height = get_lower_power_two(height, MAX_TEXTURE_SIZE) ;
+		}
 	}
 	else if(previewp && previewp->mKeepAspectRatio)
 	{
@@ -1716,9 +1805,6 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
 		S32 w = llfloor((F32)view->childGetValue("snapshot_width").asReal());
 		S32 h = llfloor((F32)view->childGetValue("snapshot_height").asReal());
 
-		gSavedSettings.setS32("LastSnapshotWidth", w);
-		gSavedSettings.setS32("LastSnapshotHeight", h);
-
 		LLSnapshotLivePreview* previewp = getPreviewView(view);
 		if (previewp)
 		{
@@ -1750,7 +1836,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
 				}
 
 				previewp->setMaxImageSize((S32)((LLSpinCtrl *)ctrl)->getMaxValue()) ;
-				if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize()) || update_)
+				
+				// Check image size changes the value of height and width
+				if(checkImageSize(previewp, w, h, w != curw, previewp->getMaxImageSize())
+					|| update_)
 				{
 					resetSnapshotSizeOnUI(view, w, h) ;
 				}
@@ -1762,6 +1851,10 @@ void LLFloaterSnapshot::Impl::onCommitCustomResolution(LLUICtrl *ctrl, void* dat
 				comboSetCustom(view, "local_size_combo");
 			}
 		}
+
+		gSavedSettings.setS32("LastSnapshotWidth", w);
+		gSavedSettings.setS32("LastSnapshotHeight", h);
+
 	}
 }
 
@@ -1800,6 +1893,7 @@ LLFloaterSnapshot::~LLFloaterSnapshot()
 BOOL LLFloaterSnapshot::postBuild()
 {
 	childSetCommitCallback("snapshot_type_radio", Impl::onCommitSnapshotType, this);
+	childSetCommitCallback("local_format_combo", Impl::onCommitSnapshotFormat, this);
 	
 	childSetAction("new_snapshot_btn", Impl::onClickNewSnapshot, this);
 
@@ -1813,7 +1907,7 @@ BOOL LLFloaterSnapshot::postBuild()
 
 	childSetAction("upload_btn", Impl::onClickKeep, this);
 	childSetAction("send_btn", Impl::onClickKeep, this);
-	childSetAction("save_btn", Impl::onClickKeep, this);
+	childSetCommitCallback("save_btn", Impl::onCommitSave, this);
 	childSetAction("discard_btn", Impl::onClickDiscard, this);
 
 	childSetCommitCallback("image_quality_slider", Impl::onCommitQuality, this);
@@ -1860,7 +1954,7 @@ BOOL LLFloaterSnapshot::postBuild()
 
 	impl.updateControls(this);
 	
-    return TRUE;
+	return TRUE;
 }
 
 void LLFloaterSnapshot::draw()
@@ -1922,45 +2016,6 @@ void LLFloaterSnapshot::draw()
 
 	LLFloater::draw();
 
-	// draw snapshot thumbnail if not in fullscreen preview mode
-	/*if (previewp && previewp->getCurrentImage() && previewp->getSnapshotUpToDate())
-	{
-		F32 aspect = previewp->getImageAspect();
-		// UI size for thumbnail
-		S32 max_width = getRect().getWidth() - 20;
-		S32 max_height = 90;
-
-		S32 img_render_width = 0;
-		S32 img_render_height = 0;
-		if (aspect > max_width / max_height)
-		{
-			// image too wide, shrink to width
-			img_render_width = max_width;
-			img_render_height = llround((F32)max_width / aspect);
-		}
-		else
-		{
-			// image too tall, shrink to height
-			img_render_height = max_height;
-			img_render_width = llround((F32)max_height * aspect);
-		}
-		S32 image_width, image_height;
-		previewp->getSize(image_width, image_height);
-		glMatrixMode(GL_TEXTURE);
-		glPushMatrix();
-		{
-			// handle case where image is only a portion of image buffer
-			if (!previewp->isImageScaled())
-			{
-				glScalef(llmin(1.f, (F32)image_width / (F32)previewp->getCurrentImage()->getWidth()), llmin(1.f, (F32)image_height / (F32)previewp->getCurrentImage()->getHeight()), 1.f);
-			}
-			glMatrixMode(GL_MODELVIEW);
-			gl_draw_scaled_image((getRect().getWidth() - img_render_width) / 2, getRect().getHeight() - 205 + (max_height - img_render_height) / 2, img_render_width, img_render_height, previewp->getCurrentImage(), LLColor4::white);
-		}
-		glMatrixMode(GL_TEXTURE);
-		glPopMatrix();
-		glMatrixMode(GL_MODELVIEW);
-	}*/
 	if (previewp)
 	{		
 		if(previewp->getThumbnailImage())
@@ -1990,7 +2045,6 @@ void LLFloaterSnapshot::show(void*)
 	if (!sInstance)
 	{
 		sInstance = new LLFloaterSnapshot();
-
 		LLUICtrlFactory::getInstance()->buildFloater(sInstance, "floater_snapshot.xml", NULL, FALSE);
 		//move snapshot floater to special purpose snapshotfloaterview
 		gFloaterView->removeChild(sInstance);
@@ -1998,6 +2052,14 @@ void LLFloaterSnapshot::show(void*)
 
 		sInstance->impl.updateLayout(sInstance);
 	}
+	else // just refresh the snapshot in the existing floater instance (DEV-12255)
+	{
+		LLSnapshotLivePreview* preview = LLFloaterSnapshot::Impl::getPreviewView(sInstance);
+		if(preview)
+		{
+			preview->updateSnapshot(TRUE);
+		}
+	}
 	
 	sInstance->open();		/* Flawfinder: ignore */
 	sInstance->focusFirstItem(FALSE);
@@ -2023,7 +2085,10 @@ void LLFloaterSnapshot::update()
 	}
 }
 
-//============================================================================
+
+///----------------------------------------------------------------------------
+/// Class LLSnapshotFloaterView
+///----------------------------------------------------------------------------
 
 LLSnapshotFloaterView::LLSnapshotFloaterView( const std::string& name, const LLRect& rect ) : LLFloaterView(name, rect)
 {
diff --git a/indra/newview/llfloatersnapshot.h b/indra/newview/llfloatersnapshot.h
index a7aee1143c76a365a1d13c70fccb1387404b2dc1..bbf5c9e40bc3c002e69e6f82ebfc29994f2f596f 100644
--- a/indra/newview/llfloatersnapshot.h
+++ b/indra/newview/llfloatersnapshot.h
@@ -38,15 +38,23 @@
 #include "llimagegl.h"
 #include "llcharacter.h"
 
+
 class LLFloaterSnapshot : public LLFloater
 {
 public:
+	typedef enum e_snapshot_format
+	{
+		SNAPSHOT_FORMAT_PNG,
+		SNAPSHOT_FORMAT_JPEG,
+		SNAPSHOT_FORMAT_BMP
+	} ESnapshotFormat;
+
     LLFloaterSnapshot();
 	virtual ~LLFloaterSnapshot();
 
-	virtual BOOL postBuild();
-	virtual void draw();
-	virtual void onClose(bool app_quitting);
+	/*virtual*/ BOOL postBuild();
+	/*virtual*/ void draw();
+	/*virtual*/ void onClose(bool app_quitting);
 
 	static void show(void*);
 	static void hide(void*);
@@ -79,4 +87,5 @@ class LLSnapshotFloaterView : public LLFloaterView
 };
 
 extern LLSnapshotFloaterView* gSnapshotFloaterView;
+
 #endif // LL_LLFLOATERSNAPSHOT_H
diff --git a/indra/newview/llfloatertools.cpp b/indra/newview/llfloatertools.cpp
index a8192e544c37be6988cc830f69e3c546569e4eab..d193685432daa4efbf42ed01d8ce47df50d4c9b0 100644
--- a/indra/newview/llfloatertools.cpp
+++ b/indra/newview/llfloatertools.cpp
@@ -54,6 +54,7 @@
 #include "llpanelvolume.h"
 #include "llpanelpermissions.h"
 #include "llselectmgr.h"
+#include "llslider.h"
 #include "llstatusbar.h"
 #include "lltabcontainer.h"
 #include "lltextbox.h"
@@ -106,6 +107,7 @@ 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_force(LLUICtrl *, void*);
 void click_dozer_size(LLUICtrl *, void*);
 void click_apply_to_selection(void*);
 void commit_radio_zoom(LLUICtrl *, void*);
@@ -308,6 +310,12 @@ BOOL	LLFloaterTools::postBuild()
 	childSetAction("button apply to selection",click_apply_to_selection,  (void*)0);
 	mCheckShowOwners = getChild<LLCheckBoxCtrl>("checkbox show owners");
 	childSetValue("checkbox show owners",gSavedSettings.getBOOL("ShowParcelOwners"));
+
+	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");
@@ -741,6 +749,11 @@ void LLFloaterTools::updatePopup(LLCoordGL center, MASK mask)
 	{
 		mCheckShowOwners	->setVisible( land_visible );
 	}
+	if (mSliderDozerForce)
+	{
+		mSliderDozerForce	->setVisible( land_visible );
+		childSetVisible("Strength:", land_visible);
+	}
 
 	//
 	// More panel visibility
@@ -939,6 +952,16 @@ void click_dozer_size(LLUICtrl *ctrl, void *user)
 	gSavedSettings.setS32("RadioLandBrushSize", size);
 }
 
+void commit_slider_dozer_force(LLUICtrl *ctrl, void*)
+{
+	// the slider is logarithmic, so we exponentiate to get the actual force multiplier
+	F32 dozer_force = pow(10.f, (F32)ctrl->getValue().asReal());
+	gSavedSettings.setF32("LandBrushForce", dozer_force);
+}
+
+
+
+
 void click_apply_to_selection(void* user)
 {
 	LLToolBrushLand::getInstance()->modifyLandInSelectionGlobal();
diff --git a/indra/newview/llfloatertools.h b/indra/newview/llfloatertools.h
index a6fdc76d9ffeba8482a17e158f3f3f1a9f51e357..81e40c04085c48ebbff93e9f3637010aeeef2766 100644
--- a/indra/newview/llfloatertools.h
+++ b/indra/newview/llfloatertools.h
@@ -48,6 +48,7 @@ class LLPanelContents;
 class LLPanelFace;
 class LLPanelLandInfo;
 class LLComboBox;
+class LLSlider;
 class LLParcelSelection;
 class LLObjectSelection;
 
@@ -167,6 +168,7 @@ class LLFloaterTools
 	LLCheckBoxCtrl	*mRadioDozerSmooth;
 	LLCheckBoxCtrl	*mRadioDozerNoise;
 	LLCheckBoxCtrl	*mRadioDozerRevert;
+	LLSlider		*mSliderDozerForce;
 
 	LLComboBox		*mComboDozerSize;
 	LLButton		*mBtnApplyToSelection;
diff --git a/indra/newview/llfloatertopobjects.cpp b/indra/newview/llfloatertopobjects.cpp
index 93622ed94e5ee0730b7ba86924a3134698e8b650..3c1b89d04b3d71a1ddf16bf91ed5a1775da91524 100644
--- a/indra/newview/llfloatertopobjects.cpp
+++ b/indra/newview/llfloatertopobjects.cpp
@@ -44,6 +44,7 @@
 #include "lllineeditor.h"
 #include "lltextbox.h"
 #include "lltracker.h"
+#include "llviewermessage.h"
 #include "llviewerparcelmgr.h"
 #include "llviewerregion.h"
 #include "lluictrlfactory.h"
@@ -51,6 +52,8 @@
 
 LLFloaterTopObjects* LLFloaterTopObjects::sInstance = NULL;
 
+// Globals
+// const U32 TIME_STR_LENGTH = 30;
 
 // static
 void LLFloaterTopObjects::show()
@@ -161,6 +164,7 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 	for (S32 block = 0; block < block_count; ++block)
 	{
 		U32 task_local_id;
+		U32 time_stamp = 0;
 		LLUUID task_id;
 		F32 location_x, location_y, location_z;
 		F32 score;
@@ -175,7 +179,11 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		msg->getF32Fast(_PREHASH_ReportData, _PREHASH_Score, score, block);
 		msg->getStringFast(_PREHASH_ReportData, _PREHASH_TaskName, name_buf, block);
 		msg->getStringFast(_PREHASH_ReportData, _PREHASH_OwnerName, owner_buf, block);
-		
+		if(msg->getNumberOfBlocks("DataExtended"))
+		{
+			msg->getU32("DataExtended", "TimeStamp", time_stamp, block);
+		}
+
 		LLSD element;
 
 		element["id"] = task_id;
@@ -193,7 +201,10 @@ void LLFloaterTopObjects::handleReply(LLMessageSystem *msg, void** data)
 		element["columns"][3]["column"] = "location";
 		element["columns"][3]["value"] = llformat("<%0.1f,%0.1f,%0.1f>", location_x, location_y, location_z);
 		element["columns"][3]["font"] = "SANSSERIF";
-
+		element["columns"][3]["column"] = "time";
+		element["columns"][3]["value"] = formatted_time((time_t)time_stamp);
+		element["columns"][3]["font"] = "SANSSERIF";
+		
 		list->addElement(element);
 		
 		mObjectListData.append(element);
diff --git a/indra/newview/llimpanel.cpp b/indra/newview/llimpanel.cpp
index 9d8641eb2f46a22da32d0bddb667fa93a2b0b1ea..a88a6bbffe9beb3f5095213616934c54e08ef041 100644
--- a/indra/newview/llimpanel.cpp
+++ b/indra/newview/llimpanel.cpp
@@ -1644,12 +1644,13 @@ BOOL LLFloaterIMPanel::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop,
 					if(drop)
 					{
 						LLToolDragAndDrop::giveInventory(mOtherParticipantUUID, inv_item);
+						LLStringUtil::format_map_t args;
+						gIMMgr->addSystemMessage(mSessionUUID, "inventory_item_offered", args);
 					}
 				}
 			}
 			break;
 		}
-		
 	default:
 		break;
 	}
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ada8ab5fdcefef119c916db8bcf6fe27caab39b1..60e6197bf765325062584deae3f8209a1485ef54 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -209,8 +209,8 @@ static LLHost gAgentSimHost;
 static BOOL gSkipOptionalUpdate = FALSE;
 
 static bool gGotUseCircuitCodeAck = false;
-std::string gInitialOutfit;
-std::string gInitialOutfitGender;	// "male" or "female"
+static std::string sInitialOutfit;
+static std::string sInitialOutfitGender;	// "male" or "female"
 
 static bool gUseCircuitCallbackCalled = false;
 
@@ -348,8 +348,6 @@ BOOL idle_startup()
 
 	static BOOL samename = FALSE;
 
-	BOOL do_normal_idle = FALSE;
-
 	// HACK: These are things from the main loop that usually aren't done
 	// until initialization is complete, but need to be done here for things
 	// to work.
@@ -634,34 +632,26 @@ BOOL idle_startup()
 
 
 		// Go to the next startup state
-		LLStartUp::setStartupState( STATE_MEDIA_INIT );
-		return do_normal_idle;
+		LLStartUp::setStartupState( STATE_BROWSER_INIT );
+		return FALSE;
 	}
 
 	
-	//---------------------------------------------------------------------
-	// LLMediaEngine Init
-	//---------------------------------------------------------------------
-	if (STATE_MEDIA_INIT == LLStartUp::getStartupState())
+	if (STATE_BROWSER_INIT == LLStartUp::getStartupState())
 	{
-		LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL;
-		set_startup_status(0.03f, "Initializing Multimedia...", gAgent.mMOTD);
+		LL_DEBUGS("AppInit") << "STATE_BROWSER_INIT" << LL_ENDL;
+		std::string msg = LLTrans::getString("LoginInitializingBrowser");
+		set_startup_status(0.03f, msg.c_str(), gAgent.mMOTD.c_str());
 		display_startup();
-		LLViewerMedia::initClass();
-		LLViewerParcelMedia::initClass();
-
-		if (gViewerWindow)
-		{
-			audio_update_volume(true);
-		}
+		LLViewerMedia::initBrowser();
 
 		LLStartUp::setStartupState( STATE_LOGIN_SHOW );
-		return do_normal_idle;
+		return FALSE;
 	}
 
-	if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
-	{		
 
+	if (STATE_LOGIN_SHOW == LLStartUp::getStartupState())
+	{
 		LL_DEBUGS("AppInit") << "Initializing Window" << LL_ENDL;
 		
 		gViewerWindow->getWindow()->setCursor(UI_CURSOR_ARROW);
@@ -723,7 +713,7 @@ BOOL idle_startup()
 		gLoginMenuBarView->setEnabled( TRUE );
 
 		timeout.reset();
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if (STATE_LOGIN_WAIT == LLStartUp::getStartupState())
@@ -733,7 +723,7 @@ BOOL idle_startup()
 
 		// Sleep so we don't spin the CPU
 		ms_sleep(1);
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if (STATE_LOGIN_CLEANUP == LLStartUp::getStartupState())
@@ -894,13 +884,13 @@ BOOL idle_startup()
 		// skipping over STATE_UPDATE_CHECK because that just waits for input
 		LLStartUp::setStartupState( STATE_LOGIN_AUTH_INIT );
 
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if (STATE_UPDATE_CHECK == LLStartUp::getStartupState())
 	{
 		// wait for user to give input via dialog box
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if(STATE_LOGIN_AUTH_INIT == LLStartUp::getStartupState())
@@ -1015,7 +1005,7 @@ BOOL idle_startup()
 		gAcceptTOS = FALSE;
 		gAcceptCriticalMessage = FALSE;
 		LLStartUp::setStartupState( STATE_LOGIN_NO_DATA_YET );
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if(STATE_LOGIN_NO_DATA_YET == LLStartUp::getStartupState())
@@ -1035,12 +1025,12 @@ BOOL idle_startup()
 		if(LLUserAuth::E_NO_RESPONSE_YET == error)
 		{
 			LL_DEBUGS("AppInit") << "waiting..." << LL_ENDL;
-			return do_normal_idle;
+			return FALSE;
 		}
 		LLStartUp::setStartupState( STATE_LOGIN_DOWNLOADING );
 		progress += 0.01f;
 		set_startup_status(progress, auth_desc, auth_message);
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if(STATE_LOGIN_DOWNLOADING == LLStartUp::getStartupState())
@@ -1056,12 +1046,12 @@ BOOL idle_startup()
 		if(LLUserAuth::E_DOWNLOADING == error)
 		{
 			LL_DEBUGS("AppInit") << "downloading..." << LL_ENDL;
-			return do_normal_idle;
+			return FALSE;
 		}
 		LLStartUp::setStartupState( STATE_LOGIN_PROCESS_RESPONSE );
 		progress += 0.01f;
 		set_startup_status(progress, LLTrans::getString("LoginProcessingResponse"), auth_message);
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if(STATE_LOGIN_PROCESS_RESPONSE == LLStartUp::getStartupState())
@@ -1104,7 +1094,7 @@ BOOL idle_startup()
 				// ignoring the duration & options array for now.
 				// Go back to authenticate.
 				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
-				return do_normal_idle;
+				return FALSE;
 			}
 			else
 			{
@@ -1216,7 +1206,7 @@ BOOL idle_startup()
 				args["[NUMBER]"] = llformat("%d", sAuthUriNum + 1);
 				auth_desc = LLTrans::getString("LoginAttempt", args);
 				LLStartUp::setStartupState( STATE_LOGIN_AUTHENTICATE );
-				return do_normal_idle;
+				return FALSE;
 			}
 			break;
 		}
@@ -1391,12 +1381,14 @@ BOOL idle_startup()
 				it = options[0].find("folder_name");
 				if(it != it_end)
 				{
-					gInitialOutfit = (*it).second;
+					// Initial outfit is a folder in your inventory,
+					// must be an exact folder-name match.
+					sInitialOutfit = (*it).second;
 				}
 				it = options[0].find("gender");
 				if (it != it_end)
 				{
-					gInitialOutfitGender = (*it).second;
+					sInitialOutfitGender = (*it).second;
 				}
 			}
 
@@ -1475,7 +1467,7 @@ BOOL idle_startup()
 			// Don't save an incorrect password to disk.
 			save_password_to_disk(NULL);
 		}
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	//---------------------------------------------------------------------
@@ -1533,7 +1525,6 @@ BOOL idle_startup()
 		LLViewerRegion *regionp = LLWorld::getInstance()->getRegionFromHandle(first_sim_handle);
 		LL_INFOS("AppInit") << "Adding initial simulator " << regionp->getOriginGlobal() << LL_ENDL;
 		
-		LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
 		regionp->setSeedCapability(first_sim_seed_cap);
 		LL_DEBUGS("AppInit") << "Waiting for seed grant ...." << LL_ENDL;
 		
@@ -1545,16 +1536,28 @@ BOOL idle_startup()
 		gAgent.setPositionAgent(agent_start_position_region);
 
 		display_startup();
-		return do_normal_idle;
+		LLStartUp::setStartupState( STATE_MULTIMEDIA_INIT );
+		return FALSE;
 	}
 
 
+	//---------------------------------------------------------------------
+	// Load QuickTime/GStreamer and other multimedia engines, can be slow.
+	// Do it while we're waiting on the network for our seed capability. JC
+	//---------------------------------------------------------------------
+	if (STATE_MULTIMEDIA_INIT == LLStartUp::getStartupState())
+	{
+		LLStartUp::multimediaInit();
+		LLStartUp::setStartupState( STATE_SEED_GRANTED_WAIT );
+		return FALSE;
+	}
+
 	//---------------------------------------------------------------------
 	// Wait for Seed Cap Grant
 	//---------------------------------------------------------------------
 	if(STATE_SEED_GRANTED_WAIT == LLStartUp::getStartupState())
 	{
-		return do_normal_idle;
+		return FALSE;
 	}
 
 
@@ -1733,7 +1736,7 @@ BOOL idle_startup()
 
 		timeout.reset();
 
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	//---------------------------------------------------------------------
@@ -1752,7 +1755,7 @@ BOOL idle_startup()
 		{
 		}
 		msg->processAcks();
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	//---------------------------------------------------------------------
@@ -1791,7 +1794,7 @@ BOOL idle_startup()
 		LLStartUp::setStartupState( STATE_AGENT_WAIT );		// Go to STATE_AGENT_WAIT
 
 		timeout.reset();
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	//---------------------------------------------------------------------
@@ -1823,7 +1826,7 @@ BOOL idle_startup()
 			LLStartUp::setStartupState( STATE_INVENTORY_SEND );
 		}
 
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	//---------------------------------------------------------------------
@@ -2011,7 +2014,7 @@ BOOL idle_startup()
 		}
 
 		LLStartUp::setStartupState( STATE_MISC );
-		return do_normal_idle;
+		return FALSE;
 	}
 
 
@@ -2202,26 +2205,27 @@ BOOL idle_startup()
 
 		LLStartUp::setStartupState( STATE_PRECACHE );
 		timeout.reset();
-		return do_normal_idle;
+		return FALSE;
 	}
 
 	if (STATE_PRECACHE == LLStartUp::getStartupState())
 	{
-		do_normal_idle = TRUE;
-		
-		// Avoid generic Ruth avatar in Orientation Island by starting
-		// our outfit load as soon as possible.  This will be replaced
-		// with a more definitive patch from featurettes-4 later. JC
+		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
+
+		// We now have an inventory skeleton, so if this is a user's first
+		// login, we can start setting up their clothing and avatar 
+		// appearance.  This helps to avoid the generic "Ruth" avatar in
+		// the orientation island tutorial experience. JC
 		if (gAgent.isFirstLogin()
-			&& !gInitialOutfit.empty()  // registration set up an outfit
-			&& gAgent.getAvatarObject()	// can't wear clothes until have obj
-			&& !gAgent.isGenderChosen() ) // nothing already loaded
+			&& !sInitialOutfit.empty()    // registration set up an outfit
+			&& !sInitialOutfitGender.empty() // and a gender
+			&& gAgent.getAvatarObject()	  // can't wear clothes without object
+			&& !gAgent.isGenderChosen() ) // nothing already loading
 		{
-			llinfos << "Wearing initial outfit " << gInitialOutfit << llendl;
-			callback_choose_gender(-1, NULL);
+			// Start loading the wearables, textures, gestures
+			LLStartUp::loadInitialOutfit( sInitialOutfit, sInitialOutfitGender );
 		}
 
-		F32 timeout_frac = timeout.getElapsedTimeF32()/PRECACHING_DELAY;
 		// wait precache-delay and for agent's avatar or a lot longer.
 		if(((timeout_frac > 1.f) && gAgent.getAvatarObject())
 		   || (timeout_frac > 3.f))
@@ -2231,49 +2235,80 @@ BOOL idle_startup()
 		else
 		{
 			update_texture_fetch();
-			set_startup_status(0.60f + 0.20f * timeout_frac,
+			set_startup_status(0.60f + 0.30f * timeout_frac,
 				"Loading world...",
 					gAgent.mMOTD);
 		}
 
-		return do_normal_idle;
+		return TRUE;
 	}
 
 	if (STATE_WEARABLES_WAIT == LLStartUp::getStartupState())
 	{
-		do_normal_idle = TRUE;
-
 		static LLFrameTimer wearables_timer;
 
 		const F32 wearables_time = wearables_timer.getElapsedTimeF32();
 		const F32 MAX_WEARABLES_TIME = 10.f;
 
-		if(gAgent.getWearablesLoaded() || !gAgent.isGenderChosen())
+		if (!gAgent.isGenderChosen())
 		{
+			// No point in waiting for clothing, we don't even
+			// know what gender we are.  Pop a dialog to ask and
+			// proceed to draw the world. JC
+			//
+			// *NOTE: We might hit this case even if we have an
+			// initial outfit, but if the load hasn't started
+			// already then something is wrong so fall back
+			// to generic outfits. JC
+			gViewerWindow->alertXml("WelcomeChooseSex",
+				callback_choose_gender, NULL);
 			LLStartUp::setStartupState( STATE_CLEANUP );
+			return TRUE;
 		}
-		else if (wearables_time > MAX_WEARABLES_TIME)
+		
+		if (wearables_time > MAX_WEARABLES_TIME)
 		{
+			// It's taken too long to load, show the world
 			gViewerWindow->alertXml("ClothingLoading");
 			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
 			LLStartUp::setStartupState( STATE_CLEANUP );
+			return TRUE;
+		}
+
+		if (gAgent.isFirstLogin())
+		{
+			// wait for avatar to be completely loaded
+			if (gAgent.getAvatarObject()
+				&& gAgent.getAvatarObject()->isFullyLoaded())
+			{
+				//llinfos << "avatar fully loaded" << llendl;
+				LLStartUp::setStartupState( STATE_CLEANUP );
+				return TRUE;
+			}
 		}
 		else
 		{
-			update_texture_fetch();
-			set_startup_status(0.80f + 0.20f * wearables_time / MAX_WEARABLES_TIME,
-							 LLTrans::getString("LoginDownloadingClothing"),
-							 gAgent.mMOTD);
+			// OK to just get the wearables
+			if ( gAgent.getWearablesLoaded() )
+			{
+				// We have our clothing, proceed.
+				//llinfos << "wearables loaded" << llendl;
+				LLStartUp::setStartupState( STATE_CLEANUP );
+				return TRUE;
+			}
 		}
-		return do_normal_idle;
+
+		update_texture_fetch();
+		set_startup_status(0.9f + 0.1f * wearables_time / MAX_WEARABLES_TIME,
+						 LLTrans::getString("LoginDownloadingClothing").c_str(),
+						 gAgent.mMOTD.c_str());
+		return TRUE;
 	}
 
 	if (STATE_CLEANUP == LLStartUp::getStartupState())
 	{
 		set_startup_status(1.0, "", "");
 
-		do_normal_idle = TRUE;
-
 		// Let the map know about the inventory.
 		if(gFloaterWorldMap)
 		{
@@ -2299,9 +2334,6 @@ BOOL idle_startup()
 			gAgent.requestEnterGodMode();
 		}
 		
-		// On first start, ask user for gender
-		dialog_choose_gender_first_start();
-
 		// Start automatic replay if the flag is set.
 		if (gSavedSettings.getBOOL("StatsAutoRun"))
 		{
@@ -2335,11 +2367,11 @@ BOOL idle_startup()
 
 		LLAppViewer::instance()->initMainloopTimeout("Mainloop Init");
 
-		return do_normal_idle;
+		return TRUE;
 	}
 
 	LL_WARNS("AppInit") << "Reached end of idle_startup for state " << LLStartUp::getStartupState() << LL_ENDL;
-	return do_normal_idle;
+	return TRUE;
 }
 
 //
@@ -3548,55 +3580,47 @@ const std::string MALE_GESTURES_FOLDER = "Male Gestures";
 const std::string FEMALE_GESTURES_FOLDER = "Female Gestures";
 const std::string MALE_OUTFIT_FOLDER = "Male Shape & Outfit";
 const std::string FEMALE_OUTFIT_FOLDER = "Female Shape & Outfit";
-const S32 OPT_USE_INITIAL_OUTFIT = -2;
 const S32 OPT_CLOSED_WINDOW = -1;
 const S32 OPT_MALE = 0;
 const S32 OPT_FEMALE = 1;
 
 void callback_choose_gender(S32 option, void* userdata)
 {
-	S32 gender = OPT_FEMALE;
-	std::string outfit;
+	switch(option)
+	{
+	case OPT_MALE:
+		LLStartUp::loadInitialOutfit( MALE_OUTFIT_FOLDER, "male" );
+		break;
+
+	case OPT_FEMALE:
+	case OPT_CLOSED_WINDOW:
+	default:
+		LLStartUp::loadInitialOutfit( FEMALE_OUTFIT_FOLDER, "female" );
+		break;
+	}
+}
+
+void LLStartUp::loadInitialOutfit( const std::string& outfit_folder_name,
+								   const std::string& gender_name )
+{
+	S32 gender = 0;
 	std::string gestures;
-	if (!gInitialOutfit.empty())
+	if (gender_name == "male")
 	{
-		outfit = gInitialOutfit;
-		if (gInitialOutfitGender == "male")
-		{
-			gender = OPT_MALE;
-			gestures = MALE_GESTURES_FOLDER;
-		}
-		else
-		{
-			gender = OPT_FEMALE;
-			gestures = FEMALE_GESTURES_FOLDER;
-		}
+		gender = OPT_MALE;
+		gestures = MALE_GESTURES_FOLDER;
 	}
 	else
 	{
-		switch(option)
-		{
-		case OPT_MALE:
-			gender = OPT_MALE;
-			outfit = MALE_OUTFIT_FOLDER;
-			gestures = MALE_GESTURES_FOLDER;
-			break;
-
-		case OPT_FEMALE:
-		case OPT_CLOSED_WINDOW:
-		default:
-			gender = OPT_FEMALE;
-			outfit = FEMALE_OUTFIT_FOLDER;
-			gestures = FEMALE_GESTURES_FOLDER;
-			break;
-		}
+		gender = OPT_FEMALE;
+		gestures = FEMALE_GESTURES_FOLDER;
 	}
 
 	// try to find the outfit - if not there, create some default
 	// wearables.
 	LLInventoryModel::cat_array_t cat_array;
 	LLInventoryModel::item_array_t item_array;
-	LLNameCategoryCollector has_name(outfit);
+	LLNameCategoryCollector has_name(outfit_folder_name);
 	gInventory.collectDescendentsIf(LLUUID::null,
 									cat_array,
 									item_array,
@@ -3608,36 +3632,16 @@ void callback_choose_gender(S32 option, void* userdata)
 	}
 	else
 	{
-		wear_outfit_by_name(outfit);
+		wear_outfit_by_name(outfit_folder_name);
 	}
 	wear_outfit_by_name(gestures);
 	wear_outfit_by_name(COMMON_GESTURES_FOLDER);
 
-	typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
-	item_map_t::iterator gestureIterator;
-
-	// Must be here so they aren't invisible if they close the window.
+	// This is really misnamed -- it means we have started loading
+	// an outfit/shape that will give the avatar a gender eventually. JC
 	gAgent.setGenderChosen(TRUE);
 }
-
-void dialog_choose_gender_first_start()
-{
-	if (!gNoRender
-		&& (!gAgent.isGenderChosen()))
-	{
-		if (!gInitialOutfit.empty())
-		{
-			gViewerWindow->alertXml("WelcomeNoClothes",
-				callback_choose_gender, NULL);
-		}
-		else
-		{	
-			gViewerWindow->alertXml("WelcomeChooseSex",
-				callback_choose_gender, NULL);
 			
-		}
-	}
-}
 
 // Loads a bitmap to display during load
 // location_id = 0 => last position
@@ -3736,6 +3740,19 @@ bool LLStartUp::canGoFullscreen()
 	return gStartupState >= STATE_WORLD_INIT;
 }
 
+// Initialize all plug-ins except the web browser (which was initialized
+// early, before the login screen). JC
+void LLStartUp::multimediaInit()
+{
+	LL_DEBUGS("AppInit") << "Initializing Multimedia...." << LL_ENDL;
+	std::string msg = LLTrans::getString("LoginInitializingMultimedia");
+	set_startup_status(0.50f, msg.c_str(), gAgent.mMOTD.c_str());
+	display_startup();
+
+	LLViewerMedia::initClass();
+	LLViewerParcelMedia::initClass();
+}
+
 bool LLStartUp::dispatchURL()
 {
 	// ok, if we've gotten this far and have a startup URL
diff --git a/indra/newview/llstartup.h b/indra/newview/llstartup.h
index 38319c8d8aa63b6207be60606922001f20237502..ea568395d445e787722cb8369c46963997a8d34c 100644
--- a/indra/newview/llstartup.h
+++ b/indra/newview/llstartup.h
@@ -46,7 +46,7 @@ extern std::string SCREEN_LAST_FILENAME;
 
 enum EStartupState{
 	STATE_FIRST,					// Initial startup
-	STATE_MEDIA_INIT,               // Initialzie media library
+	STATE_BROWSER_INIT,             // Initialize web browser for login screen
 	STATE_LOGIN_SHOW,				// Show login screen
 	STATE_LOGIN_WAIT,				// Wait for user input at login screen
 	STATE_LOGIN_CLEANUP,			// Get rid of login screen and start login
@@ -57,6 +57,7 @@ enum EStartupState{
 	STATE_LOGIN_DOWNLOADING,		// Waiting for authentication replies to download
 	STATE_LOGIN_PROCESS_RESPONSE,	// Check authentication reply
 	STATE_WORLD_INIT,				// Start building the world
+	STATE_MULTIMEDIA_INIT,			// Init the rest of multimedia library
 	STATE_SEED_GRANTED_WAIT,		// Wait for seed cap grant
 	STATE_SEED_CAP_GRANTED,			// Have seed cap grant 
 	STATE_WORLD_WAIT,				// Waiting for simulator
@@ -87,6 +88,15 @@ class LLStartUp
 	static void	setStartupState( S32 state );
 	static S32	getStartupState()				{ return gStartupState;		};
 
+	static void multimediaInit();
+		// Initialize LLViewerMedia multimedia engine.
+
+	// outfit_folder_name can be a folder anywhere in your inventory, 
+	// but the name must be a case-sensitive exact match.
+	// gender_name is either "male" or "female"
+	static void loadInitialOutfit( const std::string& outfit_folder_name,
+								   const std::string& gender_name );
+
 	static bool dispatchURL();
 		// if we have a SLURL or sim string ("Ahern/123/45") that started
 		// the viewer, dispatch it
diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp
index 421f0196e3db980e09befcef5c9f315b4e7b76ff..c522bd069745403d3e0a7e302ceda6dad1406ffa 100644
--- a/indra/newview/lltexturectrl.cpp
+++ b/indra/newview/lltexturectrl.cpp
@@ -910,7 +910,7 @@ LLTextureCtrl::LLTextureCtrl(
 	mNeedsRawImageData( FALSE ),
 	mValid( TRUE ),
 	mDirty( FALSE ),
-	mShowLoadingPlaceholder( FALSE )
+	mShowLoadingPlaceholder( TRUE )
 {
 	mCaption = new LLTextBox( label, 
 		LLRect( 0, BTN_HEIGHT_SMALL, getRect().getWidth(), 0 ),
@@ -1327,6 +1327,10 @@ void LLTextureCtrl::draw()
 
 	mTentativeLabel->setVisible( !mTexturep.isNull() && getTentative() );
 	
+	
+	// Show "Loading..." string on the top left corner while this texture is loading.
+	// Using the discard level, do not show the string if the texture is almost but not 
+	// fully loaded.
 	if ( mTexturep.notNull() &&
 		 (mShowLoadingPlaceholder == TRUE) && 
 		 (mTexturep->getDiscardLevel() != 1) &&
diff --git a/indra/newview/lltoolbrush.cpp b/indra/newview/lltoolbrush.cpp
index 1b006822c199a6106e1b4ff860d69c6dddaef8c8..b644e43a647165a9cf5d294611ff9f74d15c523d 100644
--- a/indra/newview/lltoolbrush.cpp
+++ b/indra/newview/lltoolbrush.cpp
@@ -154,7 +154,7 @@ void LLToolBrushLand::modifyLandAtPointGlobal(const LLVector3d &pos_global,
 		regionp->forceUpdate();
 
 		// tell the simulator what we've done
-		F32 seconds = 1.0f / gFPSClamped;
+		F32 seconds = (1.0f / gFPSClamped) * gSavedSettings.getF32("LandBrushForce");
 		F32 x_pos = (F32)pos_region.mV[VX];
 		F32 y_pos = (F32)pos_region.mV[VY];
 		U8 brush_size = (U8)mBrushIndex;
@@ -242,7 +242,7 @@ void LLToolBrushLand::modifyLandInSelectionGlobal()
 	
 		min_region.clamp(0.f, regionp->getWidth());
 		max_region.clamp(0.f, regionp->getWidth());
-		F32 seconds = 1.0f;
+		F32 seconds = gSavedSettings.getF32("LandBrushForce");
 
 		LLSurface &land = regionp->getLand();
 		char action = E_LAND_LEVEL;
@@ -251,21 +251,23 @@ void LLToolBrushLand::modifyLandInSelectionGlobal()
 		case 0:
 		//	// average toward mStartingZ
 			action = E_LAND_LEVEL;
-			seconds = 1.f;
+			seconds *= 0.25f;
 			break;
 		case 1:
 			action = E_LAND_RAISE;
+			seconds *= 0.25f;
 			break;
 		case 2:
 			action = E_LAND_LOWER;
+			seconds *= 0.25f;
 			break;
 		case 3:
 			action = E_LAND_SMOOTH;
-			seconds = 10.f;
+			seconds *= 5.0f;
 			break;
 		case 4:
 			action = E_LAND_NOISE;
-			seconds = 0.5f;
+			seconds *= 0.5f;
 			break;
 		case 5:
 			action = E_LAND_REVERT;
diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp
index f803ef3a3e63c60bc7db2a2cb73373296fb59fc5..f80eb6e486210be9261832c4b7f48d69c9dadd48 100644
--- a/indra/newview/llviewermedia.cpp
+++ b/indra/newview/llviewermedia.cpp
@@ -415,12 +415,44 @@ LLUUID LLViewerMediaImpl::getMediaTextureID()
 // Wrapper class
 //////////////////////////////////////////////////////////////////////////////////////////
 
+
+//////////////////////////////////////////////////////////////////////////////////////////
+// The viewer takes a long time to load the start screen.  Part of the problem
+// is media initialization -- in particular, QuickTime loads many DLLs and
+// hits the disk heavily.  So we initialize only the browser component before
+// the login screen, then do the rest later when we have a progress bar. JC
+// static
+void LLViewerMedia::initBrowser()
+{
+	LLMediaManagerData* init_data = new LLMediaManagerData;
+	buildMediaManagerData( init_data );
+	LLMediaManager::initBrowser( init_data );
+	delete init_data;
+}
+
 //////////////////////////////////////////////////////////////////////////////////////////
 // static
 void LLViewerMedia::initClass()
 {
 	LLMediaManagerData* init_data = new LLMediaManagerData;
+	buildMediaManagerData( init_data );
+	LLMediaManager::initClass( init_data );
+	delete init_data;
+
+	LLMediaManager* mm = LLMediaManager::getInstance();
+	LLMIMETypes::mime_info_map_t::const_iterator it;
+	for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it)
+	{
+		const std::string& mime_type = it->first;
+		const LLMIMETypes::LLMIMEInfo& info = it->second;
+		mm->addMimeTypeImplNameMap( mime_type, info.mImpl );
+	}
+}
 
+//////////////////////////////////////////////////////////////////////////////////////////
+// static
+void LLViewerMedia::buildMediaManagerData( LLMediaManagerData* init_data )
+{
 //	std::string executable_dir = std::string( arg0 ).substr( 0, std::string( arg0 ).find_last_of("\\/") );
 //	std::string component_dir = std::string( executable_dir ).substr( 0, std::string( executable_dir ).find_last_of("\\/") );
 //	component_dir = std::string( component_dir ).substr( 0, std::string( component_dir ).find_last_of("\\/") );
@@ -467,17 +499,6 @@ void LLViewerMedia::initClass()
 	std::string profile_name("Second Life");
 	init_data->setBrowserProfileName( profile_name );
 	init_data->setBrowserParentWindow( gViewerWindow->getPlatformWindow() );
-
-	LLMediaManager::initClass( init_data );
-
-	LLMediaManager* mm = LLMediaManager::getInstance();
-	LLMIMETypes::mime_info_map_t::const_iterator it;
-	for (it = LLMIMETypes::sMap.begin(); it != LLMIMETypes::sMap.end(); ++it)
-	{
-		const std::string& mime_type = it->first;
-		const LLMIMETypes::LLMIMEInfo& info = it->second;
-		mm->addMimeTypeImplNameMap( mime_type, info.mImpl );
-	}
 }
 
 //////////////////////////////////////////////////////////////////////////////////////////
diff --git a/indra/newview/llviewermedia.h b/indra/newview/llviewermedia.h
index 67a75c7b0fc0a8dc7c6ade903639d063127d06f9..3f012fef76d961147a62b7eeb7ffec050cbbeaad 100644
--- a/indra/newview/llviewermedia.h
+++ b/indra/newview/llviewermedia.h
@@ -34,11 +34,16 @@
 
 #include "llmediabase.h"	// for status codes
 
+class LLMediaManagerData;
 class LLUUID;
 
 class LLViewerMedia
 {
 	public:
+		// Special case early init for just web browser component
+		// so we can show login screen.  See .cpp file for details. JC
+		static void initBrowser();
+
 		static void initClass();
 		static void cleanupClass();
 
@@ -67,6 +72,10 @@ class LLViewerMedia
 		static void setMimeType(std::string mime_type);
 
 		static void updateImagesMediaStreams();
+
+	private:
+		// Fill in initialization data for LLMediaManager::initClass()
+		static void buildMediaManagerData( LLMediaManagerData* init_data );
 };
 
 #endif	// LLVIEWERMEDIA_H
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 00cc94c3d390523b3435b6d4fcb31d673d968901..7db03c9db400d835121a4d46fd64d6613fe4c4d3 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -436,9 +436,29 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
 			{
 				gViewerWindow->playSnapshotAnimAndSound();
 			}
+			
 			LLImageBase::setSizeOverride(TRUE);
-			gViewerWindow->saveImageNumbered(raw);
+			LLPointer<LLImageFormatted> formatted;
+			switch(LLFloaterSnapshot::ESnapshotFormat(gSavedSettings.getS32("SnapshotFormat")))
+			{
+			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_JPEG:
+				formatted = new LLImageJPEG(gSavedSettings.getS32("SnapshotQuality"));
+				break;
+			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_PNG:
+				formatted = new LLImagePNG;
+				break;
+			  case LLFloaterSnapshot::SNAPSHOT_FORMAT_BMP: 
+				formatted = new LLImageBMP;
+				break;
+			  default: 
+				llwarns << "Unknown Local Snapshot format" << llendl;
+				LLImageBase::setSizeOverride(FALSE);
+				return true;
+			}
+
+			formatted->encode(raw, 0);
 			LLImageBase::setSizeOverride(FALSE);
+			gViewerWindow->saveImageNumbered(formatted);
 		}
 		return true;
 	}
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 114707791b811b07e25e0189fa088c1f9d9cd958..a082d6f1b5df3802c40d405aa6f58155c9733d3e 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -1175,8 +1175,17 @@ void inventory_offer_handler(LLOfferInfo* info, BOOL from_task)
 		return;
 	}
 
+	// Strip any SLURL from the message display. (DEV-2754)
+	std::string msg = info->mDesc;
+	int indx = msg.find(" ( http://slurl.com/secondlife/");
+	if(indx >= 0)
+	{
+		LLStringUtil::truncate(msg, indx);
+	}
+	
 	LLStringUtil::format_map_t args;
-	args["[OBJECTNAME]"] = info->mDesc;
+	args["[OBJECTNAME]"] = msg;
+
 	// must protect against a NULL return from lookupHumanReadable()
 	std::string typestr = ll_safe_string(LLAssetType::lookupHumanReadable(info->mType));
 	if (!typestr.empty())
diff --git a/indra/newview/llviewerprecompiledheaders.h b/indra/newview/llviewerprecompiledheaders.h
index ce0fe2c8368431c3de36099cd0b19f4375389e24..4ab0508fba0f71d11847bfacf3252f69bdd8ef22 100644
--- a/indra/newview/llviewerprecompiledheaders.h
+++ b/indra/newview/llviewerprecompiledheaders.h
@@ -122,6 +122,7 @@
 //#include "llblockencoder.h"
 #include "llimage.h"
 #include "llimagebmp.h"
+#include "llimagepng.h"
 #include "llimagej2c.h"
 #include "llimagejpeg.h"
 #include "llimagetga.h"
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index b37b66effafc3db88ab605846898b0f85110c8d3..be9e9d4d68fa41307514c8ebb5627d7126ad5046 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1517,7 +1517,6 @@ LLViewerWindow::LLViewerWindow(
 	LLViewerWindow::sMovieBaseName = "SLmovie";
 	LLViewerWindow::sSnapshotDir.clear();
 
-
 	// create window
 	mWindow = LLWindowManager::createWindow(
 		title, name, x, y, width, height, 0,
@@ -4049,14 +4048,14 @@ BOOL LLViewerWindow::mousePointOnLandGlobal(const S32 x, const S32 y, LLVector3d
 }
 
 // Saves an image to the harddrive as "SnapshotX" where X >= 1.
-BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& extension_in)
+BOOL LLViewerWindow::saveImageNumbered(LLImageFormatted *image)
 {
-	if (! raw)
+	if (!image)
 	{
 		return FALSE;
 	}
 
-	std::string extension(extension_in);
+	std::string extension("." + image->getExtension());
 	if (extension.empty())
 	{
 		extension = (gSavedSettings.getBOOL("CompressSnapshotsToDisk")) ? ".j2c" : ".bmp";
@@ -4067,6 +4066,10 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& exten
 		pick_type = LLFilePicker::FFSAVE_J2C;
 	else if (extension == ".bmp")
 		pick_type = LLFilePicker::FFSAVE_BMP;
+	else if (extension == ".jpg")
+		pick_type = LLFilePicker::FFSAVE_JPEG;
+	else if (extension == ".png")
+		pick_type = LLFilePicker::FFSAVE_PNG;
 	else if (extension == ".tga")
 		pick_type = LLFilePicker::FFSAVE_TGA;
 	else
@@ -4112,22 +4115,13 @@ BOOL LLViewerWindow::saveImageNumbered(LLImageRaw *raw, const std::string& exten
 	}
 	while( -1 != err );  // search until the file is not found (i.e., stat() gives an error).
 
-	LLPointer<LLImageFormatted> formatted_image = LLImageFormatted::createFromExtension(extension);
-	LLImageBase::setSizeOverride(TRUE);
-	BOOL success = formatted_image->encode(raw, 0.0f);
-	if( success )
-	{
-		success = formatted_image->save(filepath);
-	}
-	else
-	{
-		llwarns << "Unable to encode bmp snapshot" << llendl;
-	}
-	LLImageBase::setSizeOverride(FALSE);
-
-	return success;
+	return image->save(filepath);
 }
 
+void LLViewerWindow::resetSnapshotLoc()
+{
+	sSnapshotDir.clear();
+}
 
 static S32 BORDERHEIGHT = 0;
 static S32 BORDERWIDTH = 0;
@@ -4430,7 +4424,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 		image_buffer_x = llfloor(snapshot_width*scale_factor) ;
 		image_buffer_y = llfloor(snapshot_height *scale_factor) ;
 	}
-	raw->resize(image_buffer_x, image_buffer_y, type == SNAPSHOT_TYPE_DEPTH ? 4 : 3);
+	raw->resize(image_buffer_x, image_buffer_y, 3);
 	if(raw->isBufferInvalid())
 	{
 		return FALSE ;
@@ -4476,7 +4470,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 			}
 			else
 			{
-				display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), use_fbo);
+				display(do_rebuild, scale_factor, subimage_x+(subimage_y*llceil(scale_factor)), TRUE);
+				// Required for showing the GUI in snapshots?  See DEV-16350 for details. JC
+				render_ui_and_swap();
 			}
 
 			S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
@@ -4485,49 +4481,43 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 									llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
 			for(U32 out_y = 0; out_y < read_height ; out_y++)
 			{
+				S32 output_buffer_offset = ( 
+							(out_y * (raw->getWidth())) // ...plus iterated y...
+							+ (window_width * subimage_x) // ...plus subimage start in x...
+							+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
+							- output_buffer_offset_x // ...minus buffer padding x...
+							- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y...
+						) * raw->getComponents();
 				if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)
 				{
 					glReadPixels(
 						subimage_x_offset, out_y + subimage_y_offset,
 						read_width, 1,
 						GL_RGB, GL_UNSIGNED_BYTE,
-						raw->getData() + // current output pixel is beginning of buffer...
-							( 
-								(out_y * (raw->getWidth())) // ...plus iterated y...
-								+ (window_width * subimage_x) // ...plus subimage start in x...
-								+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
-								- output_buffer_offset_x // ...minus buffer padding x...
-								- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y...
-							) * 3 // times 3 bytes per pixel
+						raw->getData() + output_buffer_offset
 					);
 				}
 				else // SNAPSHOT_TYPE_DEPTH
 				{
-					S32 output_buffer_offset = ( 
-								(out_y * (raw->getWidth())) // ...plus iterated y...
-								+ (window_width * subimage_x) // ...plus subimage start in x...
-								+ (raw->getWidth() * window_height * subimage_y) // ...plus subimage start in y...
-								- output_buffer_offset_x // ...minus buffer padding x...
-								- (output_buffer_offset_y * (raw->getWidth()))  // ...minus buffer padding y...
-							) * 4; // times 4 bytes per pixel
-
+					LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GL_FLOAT)); // need to store floating point values
 					glReadPixels(
 						subimage_x_offset, out_y + subimage_y_offset,
 						read_width, 1,
 						GL_DEPTH_COMPONENT, GL_FLOAT,
-						raw->getData() + output_buffer_offset// current output pixel is beginning of buffer...
+						depth_line_buffer->getData()// current output pixel is beginning of buffer...
 					);
 
-					for (S32 i = output_buffer_offset; i < output_buffer_offset + (S32)read_width * 4; i += 4)
+					for (S32 i = 0; i < (S32)read_width; i++)
 					{
-						F32 depth_float = *(F32*)(raw->getData() + i);
+						F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32)));
 					
 						F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2));
 						U8 depth_byte = F32_to_U8(linear_depth_float, LLViewerCamera::getInstance()->getNear(), LLViewerCamera::getInstance()->getFar());
-						*(raw->getData() + i + 0) = depth_byte;
-						*(raw->getData() + i + 1) = depth_byte;
-						*(raw->getData() + i + 2) = depth_byte;
-						*(raw->getData() + i + 3) = 255;
+						//write converted scanline out to result image
+						for(S32 j = 0; j < raw->getComponents(); j++)
+						{
+							*(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byte;
+						}
 					}
 				}
 			}
@@ -4565,7 +4555,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
 
 	// Pre-pad image to number of pixels such that the line length is a multiple of 4 bytes (for BMP encoding)
 	// Note: this formula depends on the number of components being 3.  Not obvious, but it's correct.	
-	image_width += (image_width * (type == SNAPSHOT_TYPE_DEPTH ? 4 : 3)) % 4 ;	
+	image_width += (image_width * 3) % 4;
 
 	// Resize image
 	if(llabs(image_width - image_buffer_x) > 4 || llabs(image_height - image_buffer_y) > 4)
diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h
index 997ac21dfdbf38597aa504282273526db00f83ef..5c0eae61be61c06c8ff6c07554379ed8ecb48bd2 100644
--- a/indra/newview/llviewerwindow.h
+++ b/indra/newview/llviewerwindow.h
@@ -192,7 +192,7 @@ class LLViewerWindow : public LLWindowCallbacks
 
 	// Hide normal UI when a logon fails, re-show everything when logon is attempted again
 	void			setNormalControlsVisible( BOOL visible );
-    void            setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
+	void			setMenuBackgroundColor(bool god_mode = false, bool dev_grid = false);
 
 	// Handle the application becoming active (frontmost) or inactive
 	//BOOL			handleActivate(BOOL activate);
@@ -219,18 +219,24 @@ class LLViewerWindow : public LLWindowCallbacks
 
 	static void		movieSize(S32 new_width, S32 new_height);
 
+	// snapshot functionality.
+	// perhaps some of this should move to llfloatershapshot?  -MG
 	typedef enum e_snapshot_type
 	{
 		SNAPSHOT_TYPE_COLOR,
 		SNAPSHOT_TYPE_DEPTH,
 		SNAPSHOT_TYPE_OBJECT_ID
 	} ESnapshotType;
-
 	BOOL			saveSnapshot(const std::string&  filename, S32 image_width, S32 image_height, BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR);
 	BOOL			rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_height, BOOL keep_window_aspect = TRUE, BOOL is_texture = FALSE,
 								BOOL show_ui = TRUE, BOOL do_rebuild = FALSE, ESnapshotType type = SNAPSHOT_TYPE_COLOR, S32 max_size = MAX_IMAGE_SIZE );
-	BOOL            thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
-	BOOL		    saveImageNumbered(LLImageRaw *raw, const std::string& extension = std::string());
+
+	BOOL			thumbnailSnapshot(LLImageRaw *raw, S32 preview_width, S32 preview_height, BOOL show_ui, BOOL do_rebuild, ESnapshotType type) ;
+	BOOL		    saveImageNumbered(LLImageFormatted *image);
+
+	// Reset the directory where snapshots are saved.
+	// Client will open directory picker on next snapshot save.
+	void resetSnapshotLoc();
 
 	void			playSnapshotAnimAndSound();
 	
diff --git a/install.xml b/install.xml
index 4b377d90b7d271a46dd42c8582dba3b7db9615b6..2475a2a5e49f5555d62b4fe60d4ae864b47f3b12 100644
--- a/install.xml
+++ b/install.xml
@@ -503,16 +503,16 @@
           <key>darwin</key>
           <map>
             <key>md5sum</key>
-            <string>4db422310f3b35710e44f69ecda19195</string>
+            <string>9a91ecd80203a24fb347b1436155b013</string>
             <key>url</key>
-            <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-5.2.1-darwin-20080613.tar.bz2</uri>
+            <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-5.2.1-darwin-20080716.tar.bz2</uri>
           </map>
           <key>linux</key>
           <map>
             <key>md5sum</key>
-            <string>5a70296632fa973e6484f60de067088c</string>
+            <string>daadd8c268e16f8c5f6145be8596b8b8</string>
             <key>url</key>
-            <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-5.2.1-linux-20080613.tar.bz2</uri>
+            <uri>scp:install-packages.lindenlab.com:/local/www/install-packages/doc/kdu-5.2.1-linux-20080716.tar.bz2</uri>
           </map>
           <key>windows</key>
           <map>
diff --git a/scripts/install.py b/scripts/install.py
index adb1b24e2587a81caa9d3f834ec998ee5b384611..dd8ffa84011fd767f2ba07a85f80fc3d720c30a9 100755
--- a/scripts/install.py
+++ b/scripts/install.py
@@ -560,6 +560,62 @@ def install(self, installables, platform, install_dir, cache_dir):
             ifile.fetch_local()
         self._install(to_install, install_dir)
 
+    def do_install(self, installables, platform, install_dir, cache_dir=None, 
+                   check_license=True, scp=None):
+        """Determine what installables should be installed. If they were
+        passed in on the command line, use them, otherwise install
+        all known installables.
+        """
+        if not cache_dir: 
+            cache_dir = _default_installable_cache()
+        all_installables = self.list_installables()
+        if not len(installables):
+            install_installables = all_installables
+        else:
+            # passed in on the command line. We'll need to verify we
+            # know about them here.
+            install_installables = installables
+            for installable in install_installables:
+                if installable not in all_installables:
+                    raise RuntimeError('Unknown installable: %s' % 
+                                       (installable,))
+        if check_license:
+            # *TODO: check against a list of 'known good' licenses.
+            # *TODO: check for urls which conflict -- will lead to
+            # problems.
+            for installable in install_installables:
+                if not self.is_valid_license(installable):
+                    return 1
+    
+        # Set up the 'scp' handler
+        opener = urllib2.build_opener()
+        scp_or_http = SCPOrHTTPHandler(scp)
+        opener.add_handler(scp_or_http)
+        urllib2.install_opener(opener)
+    
+        # Do the work of installing the requested installables.
+        self.install(
+            install_installables,
+            platform,
+            install_dir,
+            cache_dir)
+        scp_or_http.cleanup()
+    
+    def do_uninstall(self, installables, install_dir):
+        # Do not bother to check license if we're uninstalling.
+        all_installed = self.list_installed()
+        if not len(installables):
+            uninstall_installables = all_installed
+        else:
+            # passed in on the command line. We'll need to verify we
+            # know about them here.
+            uninstall_installables = installables
+            for installable in uninstall_installables:
+                if installable not in all_installed:
+                    raise RuntimeError('Installable not installed: %s' % 
+                                       (installable,))
+        self.uninstall(uninstall_installables, install_dir)
+
 class SCPOrHTTPHandler(urllib2.BaseHandler):
     """Evil hack to allow both the build system and developers consume
     proprietary binaries.
@@ -696,7 +752,6 @@ def _default_installable_cache():
                                  'install.cache.%s' % user)
     return cache_dir
 
-
 def parse_args():
     parser = optparse.OptionParser(
         usage="usage: %prog [options] [installable1 [installable2...]]",
@@ -954,7 +1009,7 @@ def main():
             print "Detail on installable",options.detail_installable+":"
             pprint.pprint(detail)
         except KeyError:
-            print "Binary '"+options.detail_installable+"' not found in",
+            print "Installable '"+options.detail_installable+"' not found in",
             print "install file."
         return 0
     if options.list_licenses:
@@ -1016,55 +1071,11 @@ def main():
             md5sum=options.package_md5):
             return 1
     elif options.uninstall:
-        # Do not bother to check license if we're uninstalling.
-        all_installed = installer.list_installed()
-        if not len(args):
-            uninstall_installables = all_installed
-        else:
-            # passed in on the command line. We'll need to verify we
-            # know about them here.
-            uninstall_installables = args
-            for installable in uninstall_installables:
-                if installable not in all_installed:
-                    raise RuntimeError('Binary not installed: %s' % 
-                                       (installable,))
-        installer.uninstall(uninstall_installables, options.install_dir)
+        installer.do_uninstall(args, options.install_dir)
     else:
-        # Determine what installables should be installed. If they were
-        # passed in on the command line, use them, otherwise install
-        # all known installables.
-        all_installables = installer.list_installables()
-        if not len(args):
-            install_installables = all_installables
-        else:
-            # passed in on the command line. We'll need to verify we
-            # know about them here.
-            install_installables = args
-            for installable in install_installables:
-                if installable not in all_installables:
-                    raise RuntimeError('Unknown installable: %s' % 
-                                       (installable,))
-        if options.check_license:
-            # *TODO: check against a list of 'known good' licenses.
-            # *TODO: check for urls which conflict -- will lead to
-            # problems.
-            for installable in install_installables:
-                if not installer.is_valid_license(installable):
-                    return 1
-
-        # Set up the 'scp' handler
-        opener = urllib2.build_opener()
-        scp_or_http = SCPOrHTTPHandler(options.scp)
-        opener.add_handler(scp_or_http)
-        urllib2.install_opener(opener)
-
-        # Do the work of installing the requested installables.
-        installer.install(
-            install_installables,
-            options.platform,
-            options.install_dir,
-            options.cache_dir)
-        scp_or_http.cleanup()
+        installer.do_install(args, options.platform, options.install_dir, 
+                             options.cache_dir, options.check_license, 
+                             options.scp) 
 
     # save out any changes
     installer.save()
diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg
index abd25bfb296dd7960d9546cd6a2265100f3cdc22..776128323954dd7f4583ac0bc8714cb2243820af 100644
--- a/scripts/messages/message_template.msg
+++ b/scripts/messages/message_template.msg
@@ -1179,7 +1179,7 @@ version 2.0
 // simulator -> viewer
 // reliable
 {
-	ParcelObjectOwnersReply Low 57 Trusted Zerocoded
+	ParcelObjectOwnersReply Low 57 Trusted Zerocoded UDPDeprecated
 	{
 		Data			Variable
 		{	OwnerID			LLUUID			}
@@ -8767,7 +8767,7 @@ version 2.0
 // LandStatReply
 // Sent by the simulator in response to LandStatRequest
 {
-	LandStatReply Low 422 Trusted Unencoded
+	LandStatReply Low 422 Trusted Unencoded UDPDeprecated
 	{
 		RequestData	Single
 		{	ReportType			U32				}