diff --git a/indra/cmake/WebKitLibPlugin.cmake b/indra/cmake/WebKitLibPlugin.cmake
index 9ec23e80ca13677c175e16a9128197e65319885c..1c572ab27f285176d8b6c3d262abaf349673c5bd 100644
--- a/indra/cmake/WebKitLibPlugin.cmake
+++ b/indra/cmake/WebKitLibPlugin.cmake
@@ -51,6 +51,7 @@ elseif (LINUX)
         QtGui
         QtCore
 
+        jpeg
         fontconfig
         X11
         Xrender
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 9bbc55509dd8f48809426d69cbfbe0d0c9bf5d0d..73c23fa8d8158879cdf7774aaf893f22dc5150b3 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1223,25 +1223,28 @@ bool LLImageRaw::createFromFile(const std::string &filename, bool j2c_lowest_mip
 	ifs.read ((char*)buffer, length);
 	ifs.close();
 	
-	image->updateData();
-	
-	if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
+	BOOL success;
+
+	success = image->updateData();
+	if (success)
 	{
-		S32 width = image->getWidth();
-		S32 height = image->getHeight();
-		S32 discard_level = 0;
-		while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
+		if (j2c_lowest_mip_only && codec == IMG_CODEC_J2C)
 		{
-			width >>= 1;
-			height >>= 1;
-			discard_level++;
+			S32 width = image->getWidth();
+			S32 height = image->getHeight();
+			S32 discard_level = 0;
+			while (width > 1 && height > 1 && discard_level < MAX_DISCARD_LEVEL)
+			{
+				width >>= 1;
+				height >>= 1;
+				discard_level++;
+			}
+			((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
 		}
-		((LLImageJ2C *)((LLImageFormatted*)image))->setDiscardLevel(discard_level);
+		success = image->decode(this, 100000.0f);
 	}
-	
-	BOOL success = image->decode(this, 100000.0f);
-	image = NULL; // deletes image
 
+	image = NULL; // deletes image
 	if (!success)
 	{
 		deleteData();
diff --git a/indra/newview/llfloaterworldmap.cpp b/indra/newview/llfloaterworldmap.cpp
index 6567c1a649f9e2865e3e4a244c3508534a22dfbf..412011e76ade31ab76b0602211925edb6028e2b7 100644
--- a/indra/newview/llfloaterworldmap.cpp
+++ b/indra/newview/llfloaterworldmap.cpp
@@ -457,7 +457,7 @@ void LLFloaterWorldMap::draw()
 		{
 			F64 seconds = LLTimer::getElapsedSeconds();
 			double value = fmod(seconds, 2);
-			value = 0.5 + 0.5*cos(value * 3.14159f);
+			value = 0.5 + 0.5*cos(value * F_PI);
 			LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
 			childSetColor("location_icon", loading_color);
 		}
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 5d9046ac905c19af80d44ce21f2143d005218afe..73340cbc03df84476f79e8d4dd7347044d5d03cc 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -670,8 +670,6 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 	LLGLDepthTest gls_depth(GL_FALSE, GL_FALSE);
 	gGL.setColorMask(true, true);
 
-	BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex);
-
 	// clear buffer area to ensure we don't pick up UI elements
 	{
 		gGL.flush();
@@ -691,12 +689,8 @@ BOOL LLTexLayerSet::render( S32 x, S32 y, S32 width, S32 height )
 		if (layer->getRenderPass() == LLTexLayer::RP_COLOR)
 		{
 			gGL.flush();
-			success &= layer->render(x, y, width, height, render_morph);
+			success &= layer->render(x, y, width, height);
 			gGL.flush();
-			if (layer->isMorphValid())
-			{
-				mAvatar->setMorphMasksValid(TRUE, mBakedTexIndex);
-			}
 		}
 	}
 	
@@ -786,12 +780,10 @@ void LLTexLayerSet::gatherMorphMaskAlpha(U8 *data, S32 width, S32 height)
 {
 	memset(data, 255, width * height);
 
-	BOOL render_morph = mAvatar->morphMaskNeedsUpdate(mBakedTexIndex);
-
 	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-		layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height, render_morph);
+		layer->gatherAlphaMasks(data, mComposite->getOriginX(),mComposite->getOriginY(), width, height);
 	}
 	
 	// Set alpha back to that of our alpha masks.
@@ -863,6 +855,31 @@ void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_
 	mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
 }
 
+BOOL LLTexLayerSet::isMorphValid()
+{
+	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+	{
+		LLTexLayerInterface* layer = *iter;
+		if (layer && !layer->isMorphValid())
+		{
+			return FALSE;
+		}
+	}
+	return TRUE;
+}
+
+void LLTexLayerSet::invalidateMorphMasks()
+{
+	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+	{
+		LLTexLayerInterface* layer = *iter;
+		if (layer)
+		{
+			layer->invalidateMorphMasks();
+		}
+	}
+}
+
 
 //-----------------------------------------------------------------------------
 // LLTexLayerInfo
@@ -1282,7 +1299,7 @@ void LLTexLayer::calculateTexLayerColor(const param_color_list_t &param_list, LL
 	}
 }
 
-BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
+BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 {
 	LLGLEnable color_mat(GL_COLOR_MATERIAL);
 	gPipeline.disableLights();
@@ -1333,7 +1350,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
 			}
 		}//*/
 
-		renderMorphMasks(x, y, width, height, net_color, render_morph);
+		renderMorphMasks(x, y, width, height, net_color);
 		alpha_mask_specified = TRUE;
 		gGL.flush();
 		gGL.blendFunc(LLRender::BF_DEST_ALPHA, LLRender::BF_ONE_MINUS_DEST_ALPHA);
@@ -1534,12 +1551,12 @@ BOOL LLTexLayer::blendAlphaTexture(S32 x, S32 y, S32 width, S32 height)
 	return success;
 }
 
-/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph)
+/*virtual*/ void LLTexLayer::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
-	addAlphaMask(data, originX, originY, width, height, render_morph);
+	addAlphaMask(data, originX, originY, width, height);
 }
 
-BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph)
+BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color)
 {
 	BOOL success = TRUE;
 
@@ -1578,46 +1595,38 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	// Accumulate the alpha component of the texture
 	if( getInfo()->mLocalTexture != -1 )
 	{
-			LLViewerTexture* tex = mLocalTextureObject->getImage();
-			if( tex && (tex->getComponents() == 4) )
-			{
-				LLGLSNoAlphaTest gls_no_alpha_test;
+		LLViewerTexture* tex = mLocalTextureObject->getImage();
+		if( tex && (tex->getComponents() == 4) )
+		{
+			LLGLSNoAlphaTest gls_no_alpha_test;
 
-				LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
-				
-				gGL.getTexUnit(0)->bind(tex);
-				gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
+			LLTexUnit::eTextureAddressMode old_mode = tex->getAddressMode();
+			
+			gGL.getTexUnit(0)->bind(tex);
+			gGL.getTexUnit(0)->setTextureAddressMode(LLTexUnit::TAM_CLAMP);
 
-				gl_rect_2d_simple_tex( width, height );
+			gl_rect_2d_simple_tex( width, height );
 
-				gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
-				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-			}
-			else
-			{
-				success = FALSE;
-			}
+			gGL.getTexUnit(0)->setTextureAddressMode(old_mode);
+			gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 		}
+	}
 
 	if( !getInfo()->mStaticImageFileName.empty() )
 	{
-			LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
-			if( tex )
-			{
-				if(	(tex->getComponents() == 4) ||
-					( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
-				{
-					LLGLSNoAlphaTest gls_no_alpha_test;
-					gGL.getTexUnit(0)->bind(tex);
-					gl_rect_2d_simple_tex( width, height );
-					gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
-				}
-			}
-			else
+		LLViewerTexture* tex = LLTexLayerStaticImageList::getInstance()->getTexture(getInfo()->mStaticImageFileName, getInfo()->mStaticImageIsMask);
+		if( tex )
+		{
+			if(	(tex->getComponents() == 4) ||
+				( (tex->getComponents() == 1) && getInfo()->mStaticImageIsMask ) )
 			{
-				success = FALSE;
+				LLGLSNoAlphaTest gls_no_alpha_test;
+				gGL.getTexUnit(0)->bind(tex);
+				gl_rect_2d_simple_tex( width, height );
+				gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE);
 			}
 		}
+	}
 
 	// Draw a rectangle with the layer color to multiply the alpha by that color's alpha.
 	// Note: we're still using gGL.blendFunc( GL_DST_ALPHA, GL_ZERO );
@@ -1634,7 +1643,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 
 	gGL.setColorMask(true, true);
 	
-	if (render_morph && mHasMorph && success)
+	if (hasMorph() && success)
 	{
 		LLCRC alpha_mask_crc;
 		const LLUUID& uuid = getUUID();
@@ -1674,7 +1683,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 	return success;
 }
 
-void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph)
+void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
 	S32 size = width * height;
 	U8* alphaData = getAlphaData();
@@ -1684,7 +1693,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 		findNetColor( &net_color );
 		// TODO: eliminate need for layer morph mask valid flag
 		invalidateMorphMasks();
-		renderMorphMasks(originX, originY, width, height, net_color, render_morph);
+		renderMorphMasks(originX, originY, width, height, net_color);
 		alphaData = getAlphaData();
 	}
 	if (alphaData)
@@ -1805,7 +1814,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 	return layer;
 }
 
-/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph)
+/*virtual*/ BOOL LLTexLayerTemplate::render(S32 x, S32 y, S32 width, S32 height)
 {
 	BOOL success = TRUE;
 	updateWearableCache();
@@ -1827,7 +1836,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 		{
 			wearable->writeToAvatar(FALSE, FALSE);
 			layer->setLTO(lto);
-			success &= layer->render(x,y,width,height,render_morph);
+			success &= layer->render(x,y,width,height);
 		}
 	}
 
@@ -1849,7 +1858,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 	return success;
 }
 
-/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph)
+/*virtual*/ void LLTexLayerTemplate::gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
 	U32 num_wearables = updateWearableCache();
 	for (U32 i = 0; i < num_wearables; i++)
@@ -1857,7 +1866,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 		LLTexLayer *layer = getLayer(i);
 		if (layer)
 		{
-			layer->addAlphaMask(data, originX, originY, width, height, render_morph);
+			layer->addAlphaMask(data, originX, originY, width, height);
 		}
 	}
 }
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index e4a6e82ba5b03fffc80485c48f66b1a8df2467b7..cd8f27a96b4934eac8eaea9d2f9171ccd06176fc 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -81,13 +81,14 @@ class LLTexLayerInterface
 
 	const LLTexLayerInfo* 	getInfo() const { return mInfo; }
 	virtual BOOL			setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions
-	virtual BOOL			render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph) = 0;
+	virtual BOOL			render(S32 x, S32 y, S32 width, S32 height) = 0;
 	void					requestUpdate();
 	LLTexLayerSet*			const getTexLayerSet() const { return mTexLayerSet; }
 
 	virtual void			deleteCaches() = 0;
 	void					invalidateMorphMasks();
 	virtual void			setHasMorph(BOOL newval) { mHasMorph = newval; }
+	BOOL					hasMorph()				 { return mHasMorph; }
 	BOOL					isMorphValid()			 { return mMorphMasksValid; }
 
 	const std::string&		getName() const;
@@ -95,7 +96,7 @@ class LLTexLayerInterface
 	const std::string&		getGlobalColor() const;
 
 	virtual BOOL			blendAlphaTexture( S32 x, S32 y, S32 width, S32 height) = 0;
-	virtual void			gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph) = 0;
+	virtual void			gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
 	BOOL					hasAlphaParams() const { return !mParamAlphaList.empty(); }
 	BOOL					isVisibilityMask() const;
 
@@ -134,10 +135,10 @@ class LLTexLayerTemplate : public LLTexLayerInterface
 	LLTexLayerTemplate(const LLTexLayerTemplate &layer);
 	/*virtual*/ ~LLTexLayerTemplate();
 
-	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph);
+	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height);
 	/*virtual*/ BOOL		setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions
 	/*virtual*/ BOOL		blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
-	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph);
+	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
 	/*virtual*/ void		setHasMorph(BOOL newval);
 	/*virtual*/ void		deleteCaches();
 private:
@@ -162,16 +163,16 @@ class LLTexLayer : public LLTexLayerInterface
 	/*virtual*/ ~LLTexLayer();
 
 	/*virtual*/ BOOL		setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions
-	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height, BOOL render_morph);
+	/*virtual*/ BOOL		render(S32 x, S32 y, S32 width, S32 height);
 
 	/*virtual*/ void		deleteCaches();
 	U8*						getAlphaData();
 
 	BOOL					findNetColor(LLColor4* color) const;
 	/*virtual*/ BOOL		blendAlphaTexture( S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
-	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph);
-	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color, BOOL render_morph);
-	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height, BOOL render_morph);
+	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
+	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
+	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
 
 	void					setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
 	LLLocalTextureObject* 	getLTO() { return mLocalTextureObject; }
@@ -261,6 +262,8 @@ class LLTexLayerSet
 	void					deleteCaches();
 	void					gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
 	void					applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
+	BOOL					isMorphValid();
+	void					invalidateMorphMasks();
 	LLTexLayerInterface*	findLayerByName(const std::string& name);
 	void					cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
 	
diff --git a/indra/newview/lltoastalertpanel.cpp b/indra/newview/lltoastalertpanel.cpp
index e4a3f8603b856f4f4ac8c3bbc8e04bcde02a45bc..beb31bc83342f9b6f62ea94d052cbf5560c0cba4 100644
--- a/indra/newview/lltoastalertpanel.cpp
+++ b/indra/newview/lltoastalertpanel.cpp
@@ -30,6 +30,9 @@
  * $/LicenseInfo$
  */
 
+// *NOTE: this module is a copy-paste of llui/llalertdialog.h
+// Can we re-implement this as a subclass of LLAlertDialog and
+// avoid all this code duplication? It already caused EXT-2232.
 
 #include "llviewerprecompiledheaders.h" // must be first include
 
@@ -56,7 +59,7 @@ const F32 DEFAULT_BUTTON_DELAY = 0.5f;
 const S32 MSG_PAD = 8;
 
 /*static*/ LLControlGroup* LLToastAlertPanel::sSettings = NULL;
-/*static*/ LLToastAlertPanel::URLLoader* LLToastAlertPanel::sURLLoader;
+/*static*/ LLAlertURLLoader* LLToastAlertPanel::sURLLoader;
 
 //-----------------------------------------------------------------------------
 // Private methods
diff --git a/indra/newview/lltoastalertpanel.h b/indra/newview/lltoastalertpanel.h
index af0c9a9ddd9525ce631848c999b5732bad3f787c..840143a2a933e388e3f92463adc151710fa434ce 100644
--- a/indra/newview/lltoastalertpanel.h
+++ b/indra/newview/lltoastalertpanel.h
@@ -30,6 +30,10 @@
  * $/LicenseInfo$
  */
 
+// *NOTE: this module is a copy-paste of llui/llalertdialog.h
+// Can we re-implement this as a subclass of LLAlertDialog and
+// avoid all this code duplication? It already caused EXT-2232.
+
 #ifndef LL_TOASTALERTPANEL_H
 #define LL_TOASTALERTPANEL_H
 
@@ -37,6 +41,7 @@
 #include "llfloater.h"
 #include "llui.h"
 #include "llnotifications.h"
+#include "llalertdialog.h"
 
 class LLButton;
 class LLCheckBoxCtrl;
@@ -57,14 +62,7 @@ class LLToastAlertPanel
 public:
 	typedef bool (*display_callback_t)(S32 modal);
 
-	class URLLoader
-	{
-	public:
-		virtual void load(const std::string& url,  bool force_open_externally = 0 ) = 0;
-		virtual ~URLLoader() {}
-	};
-	
-	static void setURLLoader(URLLoader* loader)
+	static void setURLLoader(LLAlertURLLoader* loader)
 	{
 		sURLLoader = loader;
 	}
@@ -97,7 +95,7 @@ class LLToastAlertPanel
 	BOOL hasTitleBar() const;
 
 private:
-	static URLLoader* sURLLoader;
+	static LLAlertURLLoader* sURLLoader;
 	static LLControlGroup* sSettings;
 
 	struct ButtonData
diff --git a/indra/newview/lltracker.cpp b/indra/newview/lltracker.cpp
index 5929ecd928a5a358683ffb85203b2847f137c507..1a6171765880bb5b7e90f34df9b8f7acc80f4837 100644
--- a/indra/newview/lltracker.cpp
+++ b/indra/newview/lltracker.cpp
@@ -416,10 +416,10 @@ F32 pulse_func(F32 t, F32 z)
 		return 0.f;
 	}
 	
-	t *= 3.14159f;
+	t *= F_PI;
 	z -= t*64.f - 256.f;
 	
-	F32 a = cosf(z*3.14159/512.f)*10.0f;
+	F32 a = cosf(z*F_PI/512.f)*10.0f;
 	a = llmax(a, 9.9f);
 	a -= 9.9f;
 	a *= 10.f;
@@ -433,7 +433,7 @@ void draw_shockwave(F32 center_z, F32 t, S32 steps, LLColor4 color)
 		return;
 	}
 	
-	t *= 0.6284f/3.14159f;
+	t *= 0.6284f/F_PI;
 	
 	t -= (F32) (S32) t;	
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index d8e6c52c8ccfbdea4a2d6834c3daea5346d1e374..ea1097c47794aa8c03956684e35f75a66c9a8e0b 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2914,46 +2914,37 @@ void process_agent_movement_complete(LLMessageSystem* msg, void**)
 
 	if (!gLastVersionChannel.empty())
 	{
-		LLSD payload;
-		payload["message"] = version_channel;
-		LLNotifications::instance().add("ServerVersionChanged", LLSD(), payload, server_version_changed_callback);
-	}
-
-	gLastVersionChannel = version_channel;
-}
-
-bool server_version_changed_callback(const LLSD& notification, const LLSD& response)
-{
-	if(notification["payload"]["message"].asString() =="")
-		return false;
-	std::string url ="http://wiki.secondlife.com/wiki/Release_Notes/";
-	//parse the msg string
-	std::string server_version = notification["payload"]["message"].asString();
-	std::vector<std::string> s_vect;
-	boost::algorithm::split(s_vect, server_version, isspace);
-	for(U32 i = 0; i < s_vect.size(); i++)
-	{
-    	if (i != (s_vect.size() - 1))
-		{
-			if(i != (s_vect.size() - 2))
+		// work out the URL for this server's Release Notes
+		std::string url ="http://wiki.secondlife.com/wiki/Release_Notes/";
+		std::string server_version = version_channel;
+		std::vector<std::string> s_vect;
+		boost::algorithm::split(s_vect, server_version, isspace);
+		for(U32 i = 0; i < s_vect.size(); i++)
+		{
+			if (i != (s_vect.size() - 1))
 			{
-			   url += s_vect[i] + "_";
+				if(i != (s_vect.size() - 2))
+				{
+				   url += s_vect[i] + "_";
+				}
+				else
+				{
+					url += s_vect[i] + "/";
+				}
 			}
 			else
 			{
-				url += s_vect[i] + "/";
+				url += s_vect[i].substr(0,4);
 			}
 		}
-		else
-		{
-			url += s_vect[i].substr(0,4);
-		}
+
+		LLSD args;
+		args["URL"] = url;
+		LLNotifications::instance().add("ServerVersionChanged", args);
 	}
-	
-	LLWeb::loadURL(url);
-	return false;
-}
 
+	gLastVersionChannel = version_channel;
+}
 
 void process_crossed_region(LLMessageSystem* msg, void**)
 {
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index c15e5df675a717ccc06bf0c4477d6e553babdc21..e24da2013d19c6b4189413230c96248258468065 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -132,7 +132,6 @@ void container_inventory_arrived(LLViewerObject* object,
 // agent movement
 void send_complete_agent_movement(const LLHost& sim_host);
 void process_agent_movement_complete(LLMessageSystem* msg, void**);
-bool server_version_changed_callback(const LLSD& notification, const LLSD& response);
 void process_crossed_region(LLMessageSystem* msg, void**);
 void process_teleport_start(LLMessageSystem* msg, void**);
 void process_teleport_progress(LLMessageSystem* msg, void**);
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index 240f87d104e312ee02620c3b39e8106439c0949d..acf1222455364ca57cae1a8fe6ee7df302500260 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -689,7 +689,6 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
 		mBakedTextureDatas[i].mIsUsed = false;
 		mBakedTextureDatas[i].mMaskTexName = 0;
 		mBakedTextureDatas[i].mTextureIndex = LLVOAvatarDictionary::bakedToLocalTextureIndex((EBakedTextureIndex)i);
-		mBakedTextureDatas[i].mMorphMasksValid = FALSE;
 	}
 
 	mDirtyMesh = TRUE;	// Dirty geometry, need to regenerate.
@@ -2385,7 +2384,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
 			F32 old_angle = mImpostorAngle.mV[i];
 			F32 angle_diff = fabsf(cur_angle-old_angle);
 		
-			if (angle_diff > 3.14159f/512.f*distance*mUpdatePeriod)
+			if (angle_diff > F_PI/512.f*distance*mUpdatePeriod)
 			{
 				mNeedsImpostorUpdate = TRUE;
 			}
@@ -2557,7 +2556,7 @@ void LLVOAvatar::idleUpdateLoadingEffect()
 			particle_parameters.mPartImageID                 = cloud->getID();
 			particle_parameters.mMaxAge                      = 0.f;
 			particle_parameters.mPattern                     = LLPartSysData::LL_PART_SRC_PATTERN_ANGLE_CONE;
-			particle_parameters.mInnerAngle                  = 3.14159f;
+			particle_parameters.mInnerAngle                  = F_PI;
 			particle_parameters.mOuterAngle                  = 0.f;
 			particle_parameters.mBurstRate                   = 0.02f;
 			particle_parameters.mBurstRadius                 = 0.0f;
@@ -6091,28 +6090,6 @@ void LLVOAvatar::addMaskedMorph(EBakedTextureIndex index, LLPolyMorphTarget* mor
 	}
 }
 
-// invalidates morph masks for a given layer. Don't pass a parameter to invalidate all morph masks.
-void LLVOAvatar::invalidateMorphMasks(LLVOAvatarDefines::EBakedTextureIndex index)
-{
-	setMorphMasksValid(FALSE, index);
-}
-
-// updates morph masks to be a value for a given layer. Don't pass an argument to set value for all morph masks
-void LLVOAvatar::setMorphMasksValid(BOOL new_status, LLVOAvatarDefines::EBakedTextureIndex index)
-{
-	if (index == BAKED_NUM_INDICES)
-	{
-		for (U8 tex = 0; tex < (U8)BAKED_NUM_INDICES; tex++)
-		{
-			mBakedTextureDatas[tex].mMorphMasksValid = new_status;
-		}
-	} 
-	else if (index < BAKED_NUM_INDICES) 
-	{
-		mBakedTextureDatas[index].mMorphMasksValid = new_status;
-	}
-}
-
 // returns TRUE if morph masks are present and not valid for a given baked texture, FALSE otherwise
 BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index)
 {
@@ -6121,9 +6098,20 @@ BOOL LLVOAvatar::morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex inde
 		return FALSE;
 	}
 
-	if (!mBakedTextureDatas[index].mMaskedMorphs.empty() && !mBakedTextureDatas[index].mMorphMasksValid)
+	if (!mBakedTextureDatas[index].mMaskedMorphs.empty())
 	{
-		return TRUE;
+		if (isSelf())
+		{
+			LLTexLayerSet *layer_set = mBakedTextureDatas[index].mTexLayerSet;
+			if (layer_set)
+			{
+				return !layer_set->isMorphValid();
+			}
+		}
+		else
+		{
+			return FALSE;
+		}
 	}
 
 	return FALSE;
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index f7c794defeb48da8f521cc2e6f927d982d29b65e..cf86612ce6a31594d110df2c607e55922ca187bc 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -355,10 +355,8 @@ class LLVOAvatar :
 	// Morph masks
 	//--------------------------------------------------------------------
 public:
-	void 		invalidateMorphMasks(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
 	BOOL 		morphMaskNeedsUpdate(LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
 	void 		addMaskedMorph(LLVOAvatarDefines::EBakedTextureIndex index, LLPolyMorphTarget* morph_target, BOOL invert, std::string layer);
-	void 		setMorphMasksValid(BOOL new_status, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
 	void 		applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components, LLVOAvatarDefines::EBakedTextureIndex index = LLVOAvatarDefines::BAKED_NUM_INDICES);
 
 	//--------------------------------------------------------------------
@@ -489,7 +487,6 @@ class LLVOAvatar :
 		// Stores pointers to the joint meshes that this baked texture deals with
 		std::vector< LLViewerJointMesh * > 	mMeshes;  // std::vector<LLViewerJointMesh> mJoints[i]->mMeshParts
 		morph_list_t						mMaskedMorphs;
-		BOOL								mMorphMasksValid;
 	};
 	typedef std::vector<BakedTextureData> 	bakedtexturedata_vec_t;
 	bakedtexturedata_vec_t 					mBakedTextureDatas;
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index 85a68fdd3f5b1ef5d5bfcc771586c0c3fb3d2918..6c3348b247f2df467d7b72f92b8a61e5ecfeaa8e 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1387,8 +1387,8 @@ void LLVOAvatarSelf::invalidateComposite( LLTexLayerSet* layerset, BOOL set_by_u
 	}
 	// llinfos << "LLVOAvatar::invalidComposite() " << layerset->getBodyRegion() << llendl;
 
-	invalidateMorphMasks(layerset->getBakedTexIndex());
 	layerset->requestUpdate();
+	layerset->invalidateMorphMasks();
 
 	if( set_by_user )
 	{
diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp
index caeda3d1db6a931d24956a4c13e69f0d1a148bc4..f6343b41347e767e2dc2f28afef10dacaf3a798e 100644
--- a/indra/newview/llvovolume.cpp
+++ b/indra/newview/llvovolume.cpp
@@ -739,15 +739,15 @@ F32 LLVOVolume::getTextureVirtualSize(LLFace* face)
 
 	face->setPixelArea(face_area);
 
-	if (face_area <= 0)
+	if (face_area <= 0.f)
 	{
 		return 0.f;
 	}
 
 	//get area of circle in texture space
 	LLVector2 tdim = face->mTexExtents[1] - face->mTexExtents[0];
-	F32 texel_area = (tdim * 0.5f).lengthSquared()*3.14159f;
-	if (texel_area <= 0)
+	F32 texel_area = (tdim * 0.5f).lengthSquared()*F_PI;
+	if (texel_area <= 0.f)
 	{
 		// Probably animated, use default
 		texel_area = 1.f;
@@ -1036,7 +1036,7 @@ BOOL LLVOVolume::calcLOD()
 	}
 	
 	// DON'T Compensate for field of view changing on FOV zoom.
-	distance *= 3.14159f/3.f;
+	distance *= F_PI/3.f;
 
 	cur_detail = computeLODDetail(llround(distance, 0.01f), 
 									llround(radius, 0.01f));
diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp
index 7a7538ae6298b50b32b37721fa140484de502a0c..d3238f16a8aa62ded405f7e4d2e325e74c718449 100644
--- a/indra/newview/llvowlsky.cpp
+++ b/indra/newview/llvowlsky.cpp
@@ -49,12 +49,12 @@ const U32 LLVOWLSky::MAX_SKY_DETAIL = 180;
 
 inline U32 LLVOWLSky::getNumStacks(void)
 {
-	return min(MAX_SKY_DETAIL, max(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
+	return llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
 }
 
 inline U32 LLVOWLSky::getNumSlices(void)
 {
-	return 2 * min(MAX_SKY_DETAIL, max(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
+	return 2 * llmin(MAX_SKY_DETAIL, llmax(MIN_SKY_DETAIL, gSavedSettings.getU32("WLSkyDetail")));
 }
 
 inline U32 LLVOWLSky::getFanNumVerts(void)
diff --git a/indra/newview/llweb.cpp b/indra/newview/llweb.cpp
index 3204c2d264208624c1c6b8fb53fa28b3901e5ec0..72431bd22f2c7aa148e031cb0bcc617bf19c5f03 100644
--- a/indra/newview/llweb.cpp
+++ b/indra/newview/llweb.cpp
@@ -43,8 +43,9 @@
 #include "llfloatermediabrowser.h"
 #include "llfloaterreg.h"
 #include "llalertdialog.h"
+#include "lltoastalertpanel.h"
 
-class URLLoader : public LLAlertDialog::URLLoader
+class URLLoader : public LLAlertURLLoader
 {
 	virtual void load(const std::string& url , bool force_open_externally)
 	{
@@ -65,6 +66,7 @@ static URLLoader sAlertURLLoader;
 void LLWeb::initClass()
 {
 	LLAlertDialog::setURLLoader(&sAlertURLLoader);
+	LLToastAlertPanel::setURLLoader(&sAlertURLLoader);
 }
 
 
diff --git a/indra/newview/llworldmapview.cpp b/indra/newview/llworldmapview.cpp
index 920415873e9fea716ff608483ed6ca968309a714..9a249d14f8f6ab293f6a4c44246cdf08c00a411f 100644
--- a/indra/newview/llworldmapview.cpp
+++ b/indra/newview/llworldmapview.cpp
@@ -822,7 +822,7 @@ void LLWorldMapView::draw()
 		else
 		{
 			double value = fmod(current_time, 2);
-			value = 0.5 + 0.5*cos(value * 3.14159f);
+			value = 0.5 + 0.5*cos(value * F_PI);
 			LLColor4 loading_color(0.0, F32(value/2), F32(value), 1.0);
 			drawTracking( LLWorldMap::getInstance()->mUnknownLocation, loading_color, TRUE, getString("Loading"), "");
 		}
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 0dc1a88ee8912ffe0b8dd8e623e2302a235f878f..3390463aa69d39a97af2cf93c6b7790431964f44 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1474,7 +1474,7 @@ F32 LLPipeline::calcPixelArea(LLVector3 center, LLVector3 size, LLCamera &camera
 	//get area of circle around node
 	F32 app_angle = atanf(size.length()/dist);
 	F32 radius = app_angle*LLDrawable::sCurPixelAngle;
-	return radius*radius * 3.14159f;
+	return radius*radius * F_PI;
 }
 
 void LLPipeline::grabReferences(LLCullResult& result)
diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml
index f26a4d09d4567a60ca1c9b4a7d475c50243c5b84..989dc8885127499e1566013aa5a601aafa90ed86 100644
--- a/indra/newview/skins/default/xui/en/notifications.xml
+++ b/indra/newview/skins/default/xui/en/notifications.xml
@@ -5669,7 +5669,7 @@ An error has occurred while trying to connect to voice chat for [VOICE_CHANNEL_N
    name="ServerVersionChanged"
    priority="high"
    type="notifytip">
-You just entered a region using a different server version, which may affect performance. Click to see the release notes.
+You just entered a region using a different server version, which may affect performance. [[URL] View the release notes.]
   </notification>
 
   <notification