diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 0fa77ff7c2ad544e556b892ffaa53344d5207d9f..d2e55f88a0e3cd3313775536605619c528a1bf64 100644
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -3585,7 +3585,13 @@ void LLAgent::sendAgentSetAppearance()
 		llinfos << "TAT: Sending cached texture data" << llendl;
 		for (U8 baked_index = 0; baked_index < BAKED_NUM_INDICES; baked_index++)
 		{
-			LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index);
+			BOOL generate_valid_hash = TRUE;
+			if (isAgentAvatarValid() && !gAgentAvatarp->isBakedTextureFinal((LLVOAvatarDefines::EBakedTextureIndex)baked_index))
+			{
+				generate_valid_hash = FALSE;
+			}
+
+			LLUUID hash = gAgentWearables.computeBakedTextureHash((EBakedTextureIndex) baked_index, generate_valid_hash);
 
 			if (hash.notNull())
 			{
diff --git a/indra/newview/llagentwearables.cpp b/indra/newview/llagentwearables.cpp
index d2a01aba16d549068d487a2472f64489e019580e..e0104eddf0a2c9cb0522017aa6b37881b0f6519a 100644
--- a/indra/newview/llagentwearables.cpp
+++ b/indra/newview/llagentwearables.cpp
@@ -1445,6 +1445,8 @@ void LLAgentWearables::setWearableOutfit(const LLInventoryItem::item_array_t& it
 	queryWearableCache();
 	updateServer();
 
+	gAgentAvatarp->dumpAvatarTEs("setWearableOutfit");
+
 	lldebugs << "setWearableOutfit() end" << llendl;
 }
 
@@ -1617,13 +1619,13 @@ void LLAgentWearables::queryWearableCache()
 	gAgentQueryManager.mWearablesCacheQueryID++;
 }
 
-LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index)
+LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
+												 BOOL generate_valid_hash) // Set to false if you want to upload the baked texture w/o putting it in the cache
 {
 	LLUUID hash_id;
 	bool hash_computed = false;
 	LLMD5 hash;
-
-	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(index);
+	const LLVOAvatarDictionary::BakedEntry *baked_dict = LLVOAvatarDictionary::getInstance()->getBakedTexture(baked_index);
 
 	for (U8 i=0; i < baked_dict->mWearables.size(); i++)
 	{
@@ -1636,6 +1638,10 @@ LLUUID LLAgentWearables::computeBakedTextureHash(LLVOAvatarDefines::EBakedTextur
 			{
 				LLUUID asset_id = wearable->getAssetID();
 				hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+				if (!generate_valid_hash)
+				{
+					hash.update((const unsigned char*)asset_id.mData, UUID_BYTES);
+				}
 				hash_computed = true;
 			}
 		}
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index 6d379746baefe8fc73896cda065c6a7317dab06d..679ecefa6fa76553e157a415f402c826b5d0ed1c 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -165,7 +165,8 @@ class LLAgentWearables
 public:
 	// Processes the initial wearables update message (if necessary, since the outfit folder makes it redundant)
 	static void		processAgentInitialWearablesUpdate(LLMessageSystem* mesgsys, void** user_data);
-	LLUUID			computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex index);
+	LLUUID			computeBakedTextureHash(LLVOAvatarDefines::EBakedTextureIndex baked_index,
+											BOOL generate_valid_hash = TRUE);
 
 protected:
 	void			sendAgentWearablesUpdate();
diff --git a/indra/newview/llassetuploadresponders.h b/indra/newview/llassetuploadresponders.h
index ade9c967580a8ae9ecddbf120fd72aed863e64a9..2358aeb39d0d70c69fb0a791e44e330490df5ea6 100644
--- a/indra/newview/llassetuploadresponders.h
+++ b/indra/newview/llassetuploadresponders.h
@@ -78,7 +78,7 @@ class LLNewAgentInventoryResponder : public LLAssetUploadResponder
 	boost::function<void(const LLUUID& uuid)> mCallback;
 };
 
-class LLBakedUploadData;
+struct LLBakedUploadData;
 class LLSendTexLayerResponder : public LLAssetUploadResponder
 {
 public:
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index b13f9e3898098b219e605a61dbfeead7a610b402..1d74a7be8c6043332bc2891a2f58d47023290e90 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -57,17 +57,52 @@
 
 using namespace LLVOAvatarDefines;
 
+class LLTexLayerInfo
+{
+	friend class LLTexLayer;
+	friend class LLTexLayerTemplate;
+	friend class LLTexLayerInterface;
+public:
+	LLTexLayerInfo();
+	~LLTexLayerInfo();
+
+	BOOL parseXml(LLXmlTreeNode* node);
+	BOOL createVisualParams(LLVOAvatar *avatar);
+	BOOL isUserSettable() { return mLocalTexture != -1;	}
+	S32  getLocalTexture() const { return mLocalTexture; }
+	BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
+	std::string getName() const { return mName;	}
+
+private:
+	std::string				mName;
+	
+	BOOL					mWriteAllChannels; // Don't use masking.  Just write RGBA into buffer,
+	LLTexLayerInterface::ERenderPass mRenderPass;
+
+	std::string				mGlobalColor;
+	LLColor4				mFixedColor;
+
+	S32						mLocalTexture;
+	std::string				mStaticImageFileName;
+	BOOL					mStaticImageIsMask;
+	BOOL					mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture.  Use alpha as a mask
+	BOOL					mIsVisibilityMask;
+
+	typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t;
+	morph_name_list_t		    mMorphNameList;
+	param_color_info_list_t		mParamColorInfoList;
+	param_alpha_info_list_t		mParamAlphaInfoList;
+};
+
 //-----------------------------------------------------------------------------
 // LLBakedUploadData()
 //-----------------------------------------------------------------------------
 LLBakedUploadData::LLBakedUploadData(const LLVOAvatarSelf* avatar,
 									 LLTexLayerSet* layerset,
-									 const LLUUID& id,
-									 BOOL highest_lod) : 
+									 const LLUUID& id) : 
 	mAvatar(avatar),
 	mTexLayerSet(layerset),
 	mID(id),
-	mHighestLOD(highest_lod),
 	mStartTime(LLFrameTimer::getTotalTime())		// Record starting time
 { 
 }
@@ -87,7 +122,7 @@ LLTexLayerSetBuffer::LLTexLayerSetBuffer(LLTexLayerSet* const owner,
 	mNeedsUpdate(TRUE),
 	mNeedsUpload(FALSE),
 	mUploadPending(FALSE), // Not used for any logic here, just to sync sending of updates
-	mDebugNumLowresUploads(0),
+	mNumLowresUploads(0),
 	mTexLayerSet(owner)
 {
 	LLTexLayerSetBuffer::sGLByteCount += getSize();
@@ -141,12 +176,12 @@ void LLTexLayerSetBuffer::requestUpload()
 	// If we requested a new upload but haven't even uploaded
 	// a low res version of our last upload request, then
 	// keep the timer ticking instead of resetting it.
-	if (mNeedsUpload && (mDebugNumLowresUploads == 0))
+	if (mNeedsUpload && (mNumLowresUploads == 0))
 	{
 		mNeedsUploadTimer.reset();
 	}
 	mNeedsUpload = TRUE;
-	mDebugNumLowresUploads = 0;
+	mNumLowresUploads = 0;
 	mUploadPending = TRUE;
 	mNeedsUploadTimer.unpause();
 }
@@ -289,8 +324,12 @@ BOOL LLTexLayerSetBuffer::isReadyToUpload() const
 	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout");
 	if (texture_timeout)
 	{
+		// The timeout period increases exponentially between every lowres upload in order to prevent
+		// spamming the server with frequent uploads.
+		const U32 texture_timeout_threshold = texture_timeout*(1 << mNumLowresUploads);
+
 		// If we hit our timeout and have textures available at even lower resolution, then upload.
-		const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout;
+		const BOOL is_upload_textures_timeout = mNeedsUploadTimer.getElapsedTimeF32() >= texture_timeout_threshold;
 		const BOOL has_lower_lod = mTexLayerSet->isLocalTextureDataAvailable();
 		if (has_lower_lod && is_upload_textures_timeout) return TRUE; 
 	}
@@ -387,14 +426,13 @@ void LLTexLayerSetBuffer::readBackAndUpload()
 			
 			if( valid )
 			{
-				const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();
 				// baked_upload_data is owned by the responder and deleted after the request completes
 				LLBakedUploadData* baked_upload_data = new LLBakedUploadData(gAgentAvatarp, 
 																			 this->mTexLayerSet, 
-																			 asset_id,
-																			 highest_lod);
+																			 asset_id);
 				mUploadID = asset_id;
-				
+				const BOOL highest_lod = mTexLayerSet->isLocalTextureDataFinal();	
+
 				// upload the image
 				std::string url = gAgent.getRegion()->getCapability("UploadBakedTexture");
 
@@ -431,19 +469,19 @@ void LLTexLayerSetBuffer::readBackAndUpload()
 					LLNotificationsUtil::add("AvatarRezSelfBakeNotification",args);
 					llinfos << "Uploading [ name: " << mTexLayerSet->getBodyRegionName() << " res:" << lod_str << " time:" << (U32)mNeedsUploadTimer.getElapsedTimeF32() << " ]" << llendl;
 				}
-		
+
 				if (highest_lod)
 				{
-					// Got the final LOD for the baked texture.
+					// Sending the final LOD for the baked texture.
 					// All done, pause the upload timer so we know how long it took.
 					mNeedsUpload = FALSE;
 					mNeedsUploadTimer.pause();
 				}
 				else
 				{
-					// Got a lower level LOD for the baked texture.
+					// Sending a lower level LOD for the baked texture.
 					// Restart the upload timer.
-					mDebugNumLowresUploads++;
+					mNumLowresUploads++;
 					mNeedsUploadTimer.unpause();
 					mNeedsUploadTimer.reset();
 				}
@@ -973,11 +1011,11 @@ void LLTexLayerSet::applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_
 	mAvatar->applyMorphMask(tex_data, width, height, num_components, mBakedTexIndex);
 }
 
-BOOL LLTexLayerSet::isMorphValid()
+BOOL LLTexLayerSet::isMorphValid() const
 {
-	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+	for(layer_list_t::const_iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
-		LLTexLayerInterface* layer = *iter;
+		const LLTexLayerInterface* layer = *iter;
 		if (layer && !layer->isMorphValid())
 		{
 			return FALSE;
@@ -1193,7 +1231,6 @@ BOOL LLTexLayerInfo::createVisualParams(LLVOAvatar *avatar)
 LLTexLayerInterface::LLTexLayerInterface(LLTexLayerSet* const layer_set):
 	mTexLayerSet( layer_set ),
 	mMorphMasksValid( FALSE ),
-	mStaticImageInvalid( FALSE ),
 	mInfo(NULL),
 	mHasMorph(FALSE)
 {
@@ -1307,17 +1344,17 @@ void LLTexLayerInterface::invalidateMorphMasks()
 	mMorphMasksValid = FALSE;
 }
 
-LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index)
+LLViewerVisualParam* LLTexLayerInterface::getVisualParamPtr(S32 index) const
 {
 	LLViewerVisualParam *result = NULL;
-	for (param_color_list_t::iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter)
+	for (param_color_list_t::const_iterator color_iter = mParamColorList.begin(); color_iter != mParamColorList.end() && !result; ++color_iter)
 	{
 		if ((*color_iter)->getID() == index)
 		{
 			result = *color_iter;
 		}
 	}
-	for (param_alpha_list_t::iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter)
+	for (param_alpha_list_t::const_iterator alpha_iter = mParamAlphaList.begin(); alpha_iter != mParamAlphaList.end() && !result; ++alpha_iter)
 	{
 		if ((*alpha_iter)->getID() == index)
 		{
@@ -1571,7 +1608,7 @@ BOOL LLTexLayer::render(S32 x, S32 y, S32 width, S32 height)
 	return success;
 }
 
-U8*	LLTexLayer::getAlphaData()
+const U8*	LLTexLayer::getAlphaData() const
 {
 	LLCRC alpha_mask_crc;
 	const LLUUID& uuid = getUUID();
@@ -1587,7 +1624,7 @@ U8*	LLTexLayer::getAlphaData()
 
 	U32 cache_index = alpha_mask_crc.getCRC();
 
-	alpha_cache_t::iterator iter2 = mAlphaCache.find(cache_index);
+	alpha_cache_t::const_iterator iter2 = mAlphaCache.find(cache_index);
 	return (iter2 == mAlphaCache.end()) ? 0 : iter2->second;
 }
 
@@ -1810,7 +1847,7 @@ BOOL LLTexLayer::renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLC
 void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height)
 {
 	S32 size = width * height;
-	U8* alphaData = getAlphaData();
+	const U8* alphaData = getAlphaData();
 	if (!alphaData && hasAlphaParams())
 	{
 		LLColor4 net_color;
@@ -1833,7 +1870,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 	}
 }
 
-/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask()
+/*virtual*/ BOOL LLTexLayer::isInvisibleAlphaMask() const
 {
 	if (mLocalTextureObject)
 	{
@@ -1846,8 +1883,7 @@ void LLTexLayer::addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32
 	return FALSE;
 }
 
-// private helper function
-LLUUID LLTexLayer::getUUID()
+LLUUID LLTexLayer::getUUID() const
 {
 	LLUUID uuid;
 	if( getInfo()->mLocalTexture != -1 )
@@ -1906,7 +1942,7 @@ LLTexLayerTemplate::~LLTexLayerTemplate()
 	return LLTexLayerInterface::setInfo(info, wearable);
 }
 
-U32 LLTexLayerTemplate::updateWearableCache()
+U32 LLTexLayerTemplate::updateWearableCache() const
 {
 	mWearableCache.clear();
 
@@ -1931,7 +1967,7 @@ U32 LLTexLayerTemplate::updateWearableCache()
 	}
 	return added;
 }
-LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
+LLTexLayer* LLTexLayerTemplate::getLayer(U32 i) const
 {
 	if (mWearableCache.size() <= i)
 	{
@@ -2040,7 +2076,7 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 	}
 }
 
-/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask()
+/*virtual*/ BOOL LLTexLayerTemplate::isInvisibleAlphaMask() const
 {
 	U32 num_wearables = updateWearableCache();
 	for (U32 i = 0; i < num_wearables; i++)
@@ -2064,19 +2100,17 @@ LLTexLayer* LLTexLayerTemplate::getLayer(U32 i)
 //-----------------------------------------------------------------------------
 LLTexLayerInterface*  LLTexLayerSet::findLayerByName(const std::string& name)
 {
-	for( layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
+	for (layer_list_t::iterator iter = mLayerList.begin(); iter != mLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-
 		if (layer->getName() == name)
 		{
 			return layer;
 		}
 	}
-	for( layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
+	for (layer_list_t::iterator iter = mMaskLayerList.begin(); iter != mMaskLayerList.end(); iter++ )
 	{
 		LLTexLayerInterface* layer = *iter;
-
 		if (layer->getName() == name)
 		{
 			return layer;
@@ -2121,7 +2155,7 @@ LLTexLayerStaticImageList::~LLTexLayerStaticImageList()
 	deleteCachedImages();
 }
 
-void LLTexLayerStaticImageList::dumpByteCount()
+void LLTexLayerStaticImageList::dumpByteCount() const
 {
 	llinfos << "Avatar Static Textures " <<
 		"KB GL:" << (mGLBytes / 1024) <<
@@ -2241,11 +2275,13 @@ const std::string LLTexLayerSetBuffer::dumpTextureInfo() const
 	if (!isAgentAvatarValid()) return "";
 
 	const BOOL is_high_res = !mNeedsUpload;
-	const U32 num_low_res = mDebugNumLowresUploads;
+	const U32 num_low_res = mNumLowresUploads;
 	const U32 upload_time = (U32)mNeedsUploadTimer.getElapsedTimeF32();
+	const BOOL is_uploaded = !mUploadPending;
 	const std::string local_texture_info = gAgentAvatarp->debugDumpLocalTextureDataInfo(mTexLayerSet);
-	std::string text = llformat("[ HiRes:%d LoRes:%d Timer:%d ] %s",
-								is_high_res, num_low_res, upload_time, 
+	std::string text = llformat("[ HiRes:%d LoRes:%d Uploaded:%d ] [ Timer:%d ] %s",
+								is_high_res, num_low_res, is_uploaded,
+								upload_time, 
 								local_texture_info.c_str());
 	return text;
 }
diff --git a/indra/newview/lltexlayer.h b/indra/newview/lltexlayer.h
index 313c5f24e1ac6331a94184fa7db220d29d7a4a66..2ee609fe600cf6bc5e6662ba217a9d829be3c455 100644
--- a/indra/newview/lltexlayer.h
+++ b/indra/newview/lltexlayer.h
@@ -1,6 +1,6 @@
 /** 
  * @file lltexlayer.h
- * @brief A texture layer. Used for avatars.
+ * @brief Texture layer classes. Used for avatars.
  *
  * $LicenseInfo:firstyear=2002&license=viewergpl$
  * 
@@ -35,40 +35,31 @@
 
 #include <deque>
 #include "lldynamictexture.h"
-#include "llwearable.h"
 #include "llvoavatardefines.h"
+#include "lltexlayerparams.h"
 
 class LLVOAvatar;
 class LLVOAvatarSelf;
 class LLImageTGA;
 class LLImageRaw;
 class LLXmlTreeNode;
-class LLPolyMorphTarget;
 class LLTexLayerSet;
 class LLTexLayerSetInfo;
 class LLTexLayerInfo;
 class LLTexLayerSetBuffer;
-class LLTexLayerParamColor;
-class LLTexLayerParamColorInfo;
-class LLTexLayerParamAlpha;
-class LLTexLayerParamAlphaInfo;
 class LLWearable;
 class LLViewerVisualParam;
 
-typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
-typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
-typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
-typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
-
-
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerInterface
-// Interface class to generalize functionality shared by LLTexLayer and LLTexLayerTemplate.
-
+//
+// Interface class to generalize functionality shared by LLTexLayer 
+// and LLTexLayerTemplate.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerInterface 
 {
 public:
-	enum ERenderPass 
+	enum ERenderPass
 	{
 		RP_COLOR,
 		RP_BUMP,
@@ -79,84 +70,78 @@ class LLTexLayerInterface
 	LLTexLayerInterface(const LLTexLayerInterface &layer, LLWearable *wearable);
 	virtual ~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) = 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; }
+	virtual BOOL			blendAlphaTexture(S32 x, S32 y, S32 width, S32 height) = 0;
+	virtual BOOL			isInvisibleAlphaMask() const = 0;
+
+	const LLTexLayerInfo* 	getInfo() const 			{ return mInfo; }
+	virtual BOOL			setInfo(const LLTexLayerInfo *info, LLWearable* wearable); // sets mInfo, calls initialization functions
 
 	const std::string&		getName() const;
-	ERenderPass				getRenderPass() const;
-	const std::string&		getGlobalColor() const;
+	const LLTexLayerSet* const getTexLayerSet() const 	{ return mTexLayerSet; }
+	LLTexLayerSet* const 	getTexLayerSet() 			{ return mTexLayerSet; }
 
-	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) = 0;
-	BOOL					hasAlphaParams() const { return !mParamAlphaList.empty(); }
-	BOOL					isVisibilityMask() const;
-	virtual BOOL			isInvisibleAlphaMask() = 0;
+	void					invalidateMorphMasks();
+	virtual void			setHasMorph(BOOL newval) 	{ mHasMorph = newval; }
+	BOOL					hasMorph() const			{ return mHasMorph; }
+	BOOL					isMorphValid() const		{ return mMorphMasksValid; }
 
-	LLTexLayerSet*			getLayerSet() {return mTexLayerSet;}
+	void					requestUpdate();
+	virtual void			gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height) = 0;
+	BOOL					hasAlphaParams() const 		{ return !mParamAlphaList.empty(); }
 
-	LLViewerVisualParam*	getVisualParamPtr(S32 index);
+	ERenderPass				getRenderPass() const;
+	BOOL					isVisibilityMask() const;
 
+protected:
+	const std::string&		getGlobalColor() const;
+	LLViewerVisualParam*	getVisualParamPtr(S32 index) const;
 
 protected:
-	LLTexLayerSet*			const mTexLayerSet;
+	LLTexLayerSet* const	mTexLayerSet;
+	const LLTexLayerInfo*	mInfo;
+	BOOL					mMorphMasksValid;
+	BOOL					mHasMorph;
 
 	// Layers can have either mParamColorList, mGlobalColor, or mFixedColor.  They are looked for in that order.
 	param_color_list_t		mParamColorList;
+	param_alpha_list_t		mParamAlphaList;
 	// 						mGlobalColor name stored in mInfo
 	// 						mFixedColor value stored in mInfo
-	param_alpha_list_t		mParamAlphaList;
-
-	BOOL					mMorphMasksValid;
-	BOOL					mStaticImageInvalid;
-
-	BOOL					mHasMorph;
-
-	const LLTexLayerInfo			*mInfo;
-
 };
 
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerTemplate
-// Template class 
-// Only exists for llvoavatarself
-
+//
+// Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerTemplate : public LLTexLayerInterface
 {
 public:
 	LLTexLayerTemplate(LLTexLayerSet* const layer_set);
 	LLTexLayerTemplate(const LLTexLayerTemplate &layer);
 	/*virtual*/ ~LLTexLayerTemplate();
-
 	/*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*/ 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);
 	/*virtual*/ void		setHasMorph(BOOL newval);
 	/*virtual*/ void		deleteCaches();
-	/*virtual*/ BOOL		isInvisibleAlphaMask();
-
+	/*virtual*/ BOOL		isInvisibleAlphaMask() const;
+protected:
+	U32 					updateWearableCache() const;
+	LLTexLayer* 			getLayer(U32 i) const;
 private:
-	U32 	updateWearableCache();
-	LLTexLayer* getLayer(U32 i);
 	typedef std::vector<LLWearable*> wearable_cache_t;
-	wearable_cache_t mWearableCache;
-
+	mutable wearable_cache_t mWearableCache; // mutable b/c most get- require updating this cache
 };
 
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayer
-// A single texture layer
-// Only exists for llvoavatarself
-
+//
+// A single texture layer.  Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayer : public LLTexLayerInterface
 {
 public:
@@ -165,79 +150,37 @@ class LLTexLayer : public LLTexLayerInterface
 	LLTexLayer(const LLTexLayerTemplate &layer_template, LLLocalTextureObject *lto, LLWearable *wearable);
 	/*virtual*/ ~LLTexLayer();
 
-	/*virtual*/ BOOL		setInfo(const LLTexLayerInfo *info, LLWearable* wearable ); // This sets mInfo and calls initialization functions
+	/*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);
 
 	/*virtual*/ void		deleteCaches();
-	U8*						getAlphaData();
+	const U8*				getAlphaData() const;
 
 	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*/ BOOL		blendAlphaTexture(S32 x, S32 y, S32 width, S32 height); // Multiplies a single alpha texture against the frame buffer
 	/*virtual*/ void		gatherAlphaMasks(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
 	BOOL					renderMorphMasks(S32 x, S32 y, S32 width, S32 height, const LLColor4 &layer_color);
 	void					addAlphaMask(U8 *data, S32 originX, S32 originY, S32 width, S32 height);
-	/*virtual*/ BOOL		isInvisibleAlphaMask();
-
-	void					setLTO(LLLocalTextureObject *lto) { mLocalTextureObject = lto; }
-	LLLocalTextureObject* 	getLTO() { return mLocalTextureObject; }
+	/*virtual*/ BOOL		isInvisibleAlphaMask() const;
 
-	static void calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
+	void					setLTO(LLLocalTextureObject *lto) 	{ mLocalTextureObject = lto; }
+	LLLocalTextureObject* 	getLTO() 							{ return mLocalTextureObject; }
 
+	static void 			calculateTexLayerColor(const param_color_list_t &param_list, LLColor4 &net_color);
+protected:
+	LLUUID					getUUID() const;
 private:
-	LLUUID					getUUID();
-
 	typedef std::map<U32, U8*> alpha_cache_t;
 	alpha_cache_t			mAlphaCache;
-	LLLocalTextureObject 	*mLocalTextureObject;
-};
-
-// Make private
-class LLTexLayerInfo
-{
-	friend class LLTexLayer;
-	friend class LLTexLayerTemplate;
-	friend class LLTexLayerInterface;
-public:
-	LLTexLayerInfo();
-	~LLTexLayerInfo();
-
-	BOOL parseXml(LLXmlTreeNode* node);
-	BOOL createVisualParams(LLVOAvatar *avatar);
-	BOOL isUserSettable() { return mLocalTexture != -1;	}
-	S32  getLocalTexture() const { return mLocalTexture; }
-	BOOL getOnlyAlpha() const { return mUseLocalTextureAlphaOnly; }
-	std::string getName() const { return mName;	}
-
-private:
-	std::string				mName;
-	
-	BOOL					mWriteAllChannels; // Don't use masking.  Just write RGBA into buffer,
-	LLTexLayer::ERenderPass				mRenderPass;
-
-	std::string				mGlobalColor;
-	LLColor4				mFixedColor;
-
-	S32						mLocalTexture;
-	std::string				mStaticImageFileName;
-	BOOL					mStaticImageIsMask;
-	BOOL					mUseLocalTextureAlphaOnly; // Ignore RGB channels from the input texture.  Use alpha as a mask
-	BOOL					mIsVisibilityMask;
-
-	typedef std::vector< std::pair< std::string,BOOL > > morph_name_list_t;
-	morph_name_list_t		    mMorphNameList;
-	param_color_info_list_t		mParamColorInfoList;
-	param_alpha_info_list_t		mParamAlphaInfoList;
+	LLLocalTextureObject* 	mLocalTextureObject;
 };
 
-//
-// LLTexLayer
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerSet
-// An ordered set of texture layers that get composited into a single texture.
-// Only exists for llvoavatarself
-
+//
+// An ordered set of texture layers that gets composited into a single texture.
+// Only exists for llvoavatarself.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerSet
 {
 	friend class LLTexLayerSetBuffer;
@@ -245,186 +188,163 @@ class LLTexLayerSet
 	LLTexLayerSet(LLVOAvatarSelf* const avatar);
 	~LLTexLayerSet();
 
-	const LLTexLayerSetInfo* 		getInfo() const { return mInfo; }
-	BOOL					setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
-
-	BOOL					render(S32 x, S32 y, S32 width, S32 height);
-	void					renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
-
-	BOOL					isBodyRegion(const std::string& region) const;
-	LLTexLayerSetBuffer*	getComposite();
-	const LLTexLayerSetBuffer* getComposite() const; // Do not create one if it doesn't exist.
-	void					requestUpdate();
-	void					requestUpload();
-	void					cancelUpload();
-	void					updateComposite();
-	BOOL					isLocalTextureDataAvailable() const;
-	BOOL					isLocalTextureDataFinal() const;
-	void					createComposite();
-	void					destroyComposite();
-	void					setUpdatesEnabled(BOOL b);
-	BOOL					getUpdatesEnabled()	const { return mUpdatesEnabled; }
-	void					deleteCaches();
-	void					gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
-	void					applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
-	BOOL					isMorphValid();
-	void					invalidateMorphMasks();
-	LLTexLayerInterface*	findLayerByName(const std::string& name);
-	void					cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
+	const LLTexLayerSetInfo* 	getInfo() const 			{ return mInfo; }
+	BOOL						setInfo(const LLTexLayerSetInfo *info); // This sets mInfo and calls initialization functions
+
+	BOOL						render(S32 x, S32 y, S32 width, S32 height);
+	void						renderAlphaMaskTextures(S32 x, S32 y, S32 width, S32 height, bool forceClear = false);
+
+	BOOL						isBodyRegion(const std::string& region) const;
+	LLTexLayerSetBuffer*		getComposite();
+	const LLTexLayerSetBuffer* 	getComposite() const; // Do not create one if it doesn't exist.
+	void						requestUpdate();
+	void						requestUpload();
+	void						cancelUpload();
+	void						updateComposite();
+	BOOL						isLocalTextureDataAvailable() const;
+	BOOL						isLocalTextureDataFinal() const;
+	void						createComposite();
+	void						destroyComposite();
+	void						setUpdatesEnabled(BOOL b);
+	BOOL						getUpdatesEnabled()	const 	{ return mUpdatesEnabled; }
+	void						deleteCaches();
+	void						gatherMorphMaskAlpha(U8 *data, S32 width, S32 height);
+	void						applyMorphMask(U8* tex_data, S32 width, S32 height, S32 num_components);
+	BOOL						isMorphValid() const;
+	void						invalidateMorphMasks();
+	LLTexLayerInterface*		findLayerByName(const std::string& name);
+	void						cloneTemplates(LLLocalTextureObject *lto, LLVOAvatarDefines::ETextureIndex tex_index, LLWearable* wearable);
 	
-	LLVOAvatarSelf*		    getAvatar()	const { return mAvatar; }
-	const std::string		getBodyRegionName() const;
-	BOOL					hasComposite() const { return (mComposite.notNull()); }
+	LLVOAvatarSelf*		    	getAvatar()	const 			{ return mAvatar; }
+	const std::string			getBodyRegionName() const;
+	BOOL						hasComposite() const 		{ return (mComposite.notNull()); }
 	LLVOAvatarDefines::EBakedTextureIndex getBakedTexIndex() { return mBakedTexIndex; }
-	void					setBakedTexIndex( LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
-	BOOL					isVisible() const { return mIsVisible; }
+	void						setBakedTexIndex(LLVOAvatarDefines::EBakedTextureIndex index) { mBakedTexIndex = index; }
+	BOOL						isVisible() const 			{ return mIsVisible; }
 
-public:
-	static BOOL		sHasCaches;
-
-	typedef std::vector<LLTexLayerInterface *> layer_list_t;
+	static BOOL					sHasCaches;
 
 private:
-	layer_list_t			mLayerList;
-	layer_list_t			mMaskLayerList;
+	typedef std::vector<LLTexLayerInterface *> layer_list_t;
+	layer_list_t				mLayerList;
+	layer_list_t				mMaskLayerList;
 	LLPointer<LLTexLayerSetBuffer>	mComposite;
-	LLVOAvatarSelf*	const	mAvatar; // Backlink only; don't make this an LLPointer.
-	BOOL					mUpdatesEnabled;
-	BOOL					mIsVisible;
+	LLVOAvatarSelf*	const		mAvatar; // note: backlink only; don't make this an LLPointer.
+	BOOL						mUpdatesEnabled;
+	BOOL						mIsVisible;
 
 	LLVOAvatarDefines::EBakedTextureIndex mBakedTexIndex;
-
-	const LLTexLayerSetInfo 		*mInfo;
+	const LLTexLayerSetInfo* 	mInfo;
 };
 
-// Contains shared layer set data
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSetInfo
+//
+// Contains shared layer set data.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerSetInfo
 {
 	friend class LLTexLayerSet;
 public:
 	LLTexLayerSetInfo();
 	~LLTexLayerSetInfo();
-	
 	BOOL parseXml(LLXmlTreeNode* node);
 	void createVisualParams(LLVOAvatar *avatar);
-
 private:
 	std::string				mBodyRegion;
 	S32						mWidth;
 	S32						mHeight;
 	std::string				mStaticAlphaFileName;
 	BOOL					mClearAlpha; // Set alpha to 1 for this layerset (if there is no mStaticAlphaFileName)
-	
 	typedef std::vector<LLTexLayerInfo*> layer_info_list_t;
 	layer_info_list_t		mLayerInfoList;
 };
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerSetBuffer
+//
 // The composite image that a LLTexLayerSet writes to.  Each LLTexLayerSet has one.
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerSetBuffer : public LLViewerDynamicTexture
 {
 public:
 	LLTexLayerSetBuffer(LLTexLayerSet* const owner, S32 width, S32 height);
 	virtual ~LLTexLayerSetBuffer();
-
-	/*virtual*/ S8          getType() const ;
+	/*virtual*/ S8          getType() const;
 	virtual void			preRender(BOOL clear_depth);
 	virtual void			postRender(BOOL success);
 	virtual BOOL			render();
 	BOOL					updateImmediate();
 	bool					isInitialized(void) const;
-	BOOL					needsRender();
+	/*virtual*/ BOOL		needsRender();
 	void					requestUpdate();
 	void					requestUpload();
 	void					cancelUpload();
-	BOOL					uploadPending() { return mUploadPending; }
-	BOOL					render( S32 x, S32 y, S32 width, S32 height );
+	BOOL					uploadPending() const { return mUploadPending; }
+	BOOL					render(S32 x, S32 y, S32 width, S32 height);
 	void					readBackAndUpload();
-
 	static void				onTextureUploadComplete(const LLUUID& uuid,
 													void* userdata,
 													S32 result, LLExtStat ext_status);
 	static void				dumpTotalByteCount();
-
 	const std::string		dumpTextureInfo() const;
-
-	virtual void restoreGLTexture();
-	virtual void destroyGLTexture();
-
+	virtual void 			restoreGLTexture();
+	virtual void 			destroyGLTexture();
 protected:
 	void					pushProjection() const;
 	void					popProjection() const;
 	BOOL					isReadyToUpload() const;
-	
 private:
 	LLTexLayerSet* const    mTexLayerSet;
-
-	BOOL					mNeedsUpdate; // Whether we need to update our baked textures
-	BOOL					mNeedsUpload; // Whether we need to send our baked textures to the server
-	U32						mDebugNumLowresUploads; // Number of times we've sent a lowres version of our baked textures to the server
-	BOOL					mUploadPending; // Whether we have received back the new baked textures
-	LLUUID					mUploadID; // Identifies the current upload process (null if none).  Used to avoid overlaps (eg, when the user rapidly makes two changes outside of Face Edit)
-
+	BOOL					mNeedsUpdate; // whether we need to update our baked textures
+	BOOL					mNeedsUpload; // whether we need to send our baked textures to the server
+	U32						mNumLowresUploads; // mumber of times we've sent a lowres version of our baked textures to the server
+	BOOL					mUploadPending; // whether we have received back the new baked textures
+	LLUUID					mUploadID; // the current upload process (null if none).  Used to avoid overlaps, e.g. when the user rapidly makes two changes outside of Face Edit.
 	static S32				sGLByteCount;
-	
 	LLFrameTimer    		mNeedsUploadTimer; // Tracks time since upload was requested
-
 };
 
-//
-// LLTexLayerSet
-//-----------------------------------------------------------------------------
-
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerStaticImageList
 //
-
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 {
 public:
 	LLTexLayerStaticImageList();
 	~LLTexLayerStaticImageList();
-
 	LLViewerTexture*	getTexture(const std::string& file_name, BOOL is_mask);
-	LLImageTGA*	getImageTGA(const std::string& file_name);
-
-	void		deleteCachedImages();
-	void		dumpByteCount();
-
-private:
-	BOOL		loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
-
+	LLImageTGA*			getImageTGA(const std::string& file_name);
+	void				deleteCachedImages();
+	void				dumpByteCount() const;
+protected:
+	BOOL				loadImageRaw(const std::string& file_name, LLImageRaw* image_raw);
 private:
-	LLStringTable mImageNames;
-
-	typedef std::map< const char*, LLPointer<LLViewerTexture> > texture_map_t;
-	texture_map_t mStaticImageList;
-	typedef std::map< const char*, LLPointer<LLImageTGA> > image_tga_map_t;
-	image_tga_map_t mStaticImageListTGA;
-
-	S32 mGLBytes;
-	S32 mTGABytes;
+	LLStringTable 		mImageNames;
+	typedef std::map<const char*, LLPointer<LLViewerTexture> > texture_map_t;
+	texture_map_t 		mStaticImageList;
+	typedef std::map<const char*, LLPointer<LLImageTGA> > image_tga_map_t;
+	image_tga_map_t 	mStaticImageListTGA;
+	S32 				mGLBytes;
+	S32 				mTGABytes;
 };
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLBakedUploadData
+//
 // Used by LLTexLayerSetBuffer for a callback.
-// Note to anyone merging branches - this supercedes the previous fix
-// for DEV-31590 "Heap corruption and crash after outfit changes",
-// here and in lltexlayer.cpp. Equally correct and a bit simpler.
-class LLBakedUploadData
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+struct LLBakedUploadData
 {
-public:
 	LLBakedUploadData(const LLVOAvatarSelf* avatar, 
 					  LLTexLayerSet* layerset, 
-					  const LLUUID& id,
-					  BOOL highest_lod);
+					  const LLUUID& id);
 	~LLBakedUploadData() {}
-
 	const LLUUID				mID;
-	const LLVOAvatarSelf*		mAvatar;	 // just backlink, don't LLPointer 
+	const LLVOAvatarSelf*		mAvatar; // note: backlink only; don't LLPointer 
 	LLTexLayerSet*				mTexLayerSet;
-   	const U64					mStartTime;		// Used to measure time baked texture upload requires
-	BOOL						mHighestLOD;
-
+   	const U64					mStartTime;	// for measuring baked texture upload time
 };
 
-
 #endif  // LL_LLTEXLAYER_H
diff --git a/indra/newview/lltexlayerparams.h b/indra/newview/lltexlayerparams.h
index 93d01352d48d920882eaa0346d2bc29ba4d179ef..7747ee1ebf99e5a1ad4ca01b35c7c1fa5ad6a4fc 100644
--- a/indra/newview/lltexlayerparams.h
+++ b/indra/newview/lltexlayerparams.h
@@ -42,6 +42,10 @@ class LLViewerTexture;
 class LLVOAvatar;
 class LLWearable;
 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+// LLTexLayerParam
+// 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerParam : public LLViewerVisualParam
 {
 public: 
@@ -55,9 +59,10 @@ class LLTexLayerParam : public LLViewerVisualParam
 	LLVOAvatar*             mAvatar;
 };
 
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerParamAlpha
 // 
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerParamAlpha : public LLTexLayerParam
 {
 public:
@@ -124,9 +129,10 @@ class LLTexLayerParamAlphaInfo : public LLViewerVisualParamInfo
 // LLTexLayerParamAlpha
 //-----------------------------------------------------------------------------
 
-//-----------------------------------------------------------------------------
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 // LLTexLayerParamColor
 //
+//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerParamColor : public LLTexLayerParam
 {
 public:
@@ -184,8 +190,9 @@ class LLTexLayerParamColorInfo : public LLViewerVisualParamInfo
 	S32					mNumColors;
 };
 
-//
-// LLTexLayerParamColor
-//-----------------------------------------------------------------------------
+typedef std::vector<LLTexLayerParamColor *> param_color_list_t;
+typedef std::vector<LLTexLayerParamAlpha *> param_alpha_list_t;
+typedef std::vector<LLTexLayerParamColorInfo *> param_color_info_list_t;
+typedef std::vector<LLTexLayerParamAlphaInfo *> param_alpha_info_list_t;
 
 #endif
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index 7a8b6557bb52636464c1ed202c2d238b85b5c832..377449cc8bc7246f2d5281f5030562ff22253da6 100644
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -65,6 +65,8 @@ LLTextureView *gTextureView = NULL;
 LLTextureSizeView *gTextureSizeView = NULL;
 LLTextureSizeView *gTextureCategoryView = NULL;
 
+#define HIGH_PRIORITY 100000000.f
+
 //static
 std::set<LLViewerFetchedTexture*> LLTextureView::sDebugImages;
 
@@ -415,13 +417,14 @@ void LLAvatarTexBar::draw()
 	if (!avatarp) return;
 
 	const S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-	const S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 2.5f);
+	const S32 v_offset = 0;
+
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
 	LLColor4 text_color(1.f, 1.f, 1.f, 1.f);
 	LLColor4 color;
 	
-	U32 line_num = 6;
+	U32 line_num = 1;
 	for (LLVOAvatarDefines::LLVOAvatarDictionary::BakedTextures::const_iterator baked_iter = LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().begin();
 		 baked_iter != LLVOAvatarDefines::LLVOAvatarDictionary::getInstance()->getBakedTextures().end();
 		 ++baked_iter)
@@ -433,7 +436,7 @@ void LLAvatarTexBar::draw()
 		if (!layerset_buffer) continue;
 		std::string text = layerset_buffer->dumpTextureInfo();
 		LLFontGL::getFontMonospace()->renderUTF8(text, 0, 0, v_offset + line_height*line_num,
-												 text_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
+												 text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
 		line_num++;
 	}
 	const U32 texture_timeout = gSavedSettings.getU32("AvatarBakedTextureTimeout");
@@ -443,7 +446,7 @@ void LLAvatarTexBar::draw()
 	const std::string override_tex_discard_level_str = override_tex_discard_level ? llformat("%d",override_tex_discard_level) : "Disabled";
 	std::string header_text = llformat("[ Timeout('AvatarBakedTextureTimeout'):%s ] [ LOD_Override('TextureDiscardLevel'):%s ]", texture_timeout_str.c_str(), override_tex_discard_level_str.c_str());
 	LLFontGL::getFontMonospace()->renderUTF8(header_text, 0, 0, v_offset + line_height*line_num,
-											 text_color, LLFontGL::LEFT, LLFontGL::TOP, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
+											 text_color, LLFontGL::LEFT, LLFontGL::TOP); //, LLFontGL::BOLD, LLFontGL::DROP_SHADOW_SOFT);
 }
 
 BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask)
@@ -454,7 +457,8 @@ BOOL LLAvatarTexBar::handleMouseDown(S32 x, S32 y, MASK mask)
 LLRect LLAvatarTexBar::getRequiredRect()
 {
 	LLRect rect;
-	rect.mTop = 8;
+	rect.mTop = 85;
+	if (!gSavedSettings.getBOOL("DebugAvatarRezTime")) rect.mTop = 0;
 	return rect;
 }
 
@@ -497,7 +501,7 @@ void LLGLTexMemBar::draw()
 	F32 cache_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getUsage()) ;
 	F32 cache_max_usage = (F32)BYTES_TO_MEGA_BYTES(LLAppViewer::getTextureCache()->getMaxUsage()) ;
 	S32 line_height = (S32)(LLFontGL::getFontMonospace()->getLineHeight() + .5f);
-	S32 v_offset = (S32)((texture_bar_height + 2.5f) * mTextureView->mNumTextureBars + 5.0f);
+	S32 v_offset = (S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
 	LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);
@@ -649,7 +653,8 @@ BOOL LLGLTexMemBar::handleMouseDown(S32 x, S32 y, MASK mask)
 LLRect LLGLTexMemBar::getRequiredRect()
 {
 	LLRect rect;
-	rect.mTop = 8;
+	//rect.mTop = 50;
+	rect.mTop = 0;
 	return rect;
 }
 
@@ -808,7 +813,7 @@ void LLTextureView::draw()
 			{
 				S32 tex_mem = imagep->hasGLTexture() ? imagep->getTextureMemory() : 0 ;
 				llinfos << imagep->getID()
-					<< "\t" << tex_mem
+						<< "\t" << tex_mem
 						<< "\t" << imagep->getBoostLevel()
 						<< "\t" << imagep->getDecodePriority()
 						<< "\t" << imagep->getWidth()
@@ -823,19 +828,6 @@ void LLTextureView::draw()
 				++debug_count; // for breakpoints
 			}
 			
-#if 0
-			if (imagep->getDontDiscard())
-			{
-				continue;
-			}
-
-			if (imagep->isMissingAsset())
-			{
-				continue;
-			}
-#endif
-
-#define HIGH_PRIORITY 100000000.f
 			F32 pri;
 			if (mOrderFetch)
 			{
@@ -854,59 +846,55 @@ void LLTextureView::draw()
 
 			if (!mOrderFetch)
 			{
-#if 1
-			if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance())
-			{
-				struct f : public LLSelectedTEFunctor
+				if (pri < HIGH_PRIORITY && LLSelectMgr::getInstance())
 				{
-					LLViewerFetchedTexture* mImage;
-					f(LLViewerFetchedTexture* image) : mImage(image) {}
-					virtual bool apply(LLViewerObject* object, S32 te)
+					struct f : public LLSelectedTEFunctor
+					{
+						LLViewerFetchedTexture* mImage;
+						f(LLViewerFetchedTexture* image) : mImage(image) {}
+						virtual bool apply(LLViewerObject* object, S32 te)
+						{
+							return (mImage == object->getTEImage(te));
+						}
+					} func(imagep);
+					const bool firstonly = true;
+					bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly);
+					if (match)
 					{
-						return (mImage == object->getTEImage(te));
+						pri += 3*HIGH_PRIORITY;
 					}
-				} func(imagep);
-				const bool firstonly = true;
-				bool match = LLSelectMgr::getInstance()->getSelection()->applyToTEs(&func, firstonly);
-				if (match)
-				{
-					pri += 3*HIGH_PRIORITY;
 				}
-			}
-#endif
-#if 1
-			if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard))
-			{
-				LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode();
-				if (hover_node)
+
+				if (pri < HIGH_PRIORITY && (cur_discard< 0 || desired_discard < cur_discard))
 				{
-					LLViewerObject *objectp = hover_node->getObject();
-					if (objectp)
+					LLSelectNode* hover_node = LLSelectMgr::instance().getHoverNode();
+					if (hover_node)
 					{
-						S32 tex_count = objectp->getNumTEs();
-						for (S32 i = 0; i < tex_count; i++)
+						LLViewerObject *objectp = hover_node->getObject();
+						if (objectp)
 						{
-							if (imagep == objectp->getTEImage(i))
+							S32 tex_count = objectp->getNumTEs();
+							for (S32 i = 0; i < tex_count; i++)
 							{
-								pri += 2*HIGH_PRIORITY;
-								break;
+								if (imagep == objectp->getTEImage(i))
+								{
+									pri += 2*HIGH_PRIORITY;
+									break;
+								}
 							}
 						}
 					}
 				}
-			}
-#endif
-#if 1
-			if (pri > 0.f && pri < HIGH_PRIORITY)
-			{
-				if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f ||
-					imagep->mFetchDeltaTime < 0.25f)
+
+				if (pri > 0.f && pri < HIGH_PRIORITY)
 				{
-					pri += 1*HIGH_PRIORITY;
+					if (imagep->mLastPacketTimer.getElapsedTimeF32() < 1.f ||
+						imagep->mFetchDeltaTime < 0.25f)
+					{
+						pri += 1*HIGH_PRIORITY;
+					}
 				}
 			}
-#endif
-			}
 			
 	 		if (pri > 0.0f)
 			{
@@ -947,18 +935,21 @@ void LLTextureView::draw()
 			sortChildren(LLTextureBar::sort());
 
 		LLGLTexMemBar::Params tmbp;
+		LLRect tmbr;
 		tmbp.name("gl texmem bar");
+		tmbp.rect(tmbr);
 		tmbp.texture_view(this);
 		mGLTexMemBar = LLUICtrlFactory::create<LLGLTexMemBar>(tmbp);
-		addChild(mGLTexMemBar);
+		addChildInBack(mGLTexMemBar);
 
 		LLAvatarTexBar::Params atbp;
+		LLRect atbr;
 		atbp.name("gl avatartex bar");
 		atbp.texture_view(this);
+		atbp.rect(atbr);
 		mAvatarTexBar = LLUICtrlFactory::create<LLAvatarTexBar>(atbp);
 		addChild(mAvatarTexBar);
 
-
 		reshape(getRect().getWidth(), getRect().getHeight(), TRUE);
 
 		/*
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index bb6afcc84d0b5e1b14a23b9ae413badde7123ca1..1fa953f1577ef99083c2146d7366b59c837bac87 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -6498,16 +6498,13 @@ LLColor4 LLVOAvatar::getDummyColor()
 
 void LLVOAvatar::dumpAvatarTEs( const std::string& context ) const
 {	
-	/* const char* te_name[] = {
-			"TEX_HEAD_BODYPAINT   ",
-			"TEX_UPPER_SHIRT      ", */
 	llinfos << (isSelf() ? "Self: " : "Other: ") << context << llendl;
 	for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
 		 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
 		 ++iter)
 	{
 		const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
-		// TODO: handle multiple textures for self
+		// TODO: MULTI-WEARABLE: handle multiple textures for self
 		const LLViewerTexture* te_image = getImage(iter->first,0);
 		if( !te_image )
 		{
@@ -7915,6 +7912,8 @@ void LLVOAvatar::idleUpdateRenderCost()
 	static const U32 ARC_BODY_PART_COST = 20;
 	static const U32 ARC_LIMIT = 2048;
 
+	static std::set<LLUUID> all_textures;
+
 	if (!gPipeline.hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHAME))
 	{
 		return;
@@ -7960,7 +7959,45 @@ void LLVOAvatar::idleUpdateRenderCost()
 			}
 		}
 	}
+	// Diagnostic output to identify all avatar-related textures.
+	// Does not affect rendering cost calculation.
+	// Could be wrapped in a debug option if output becomes problematic.
+	if (isSelf())
+	{
+		// print any attachment textures we didn't already know about.
+		for (std::set<LLUUID>::iterator it = textures.begin(); it != textures.end(); ++it)
+		{
+			LLUUID image_id = *it;
+			if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+				continue;
+			if (all_textures.find(image_id) == all_textures.end())
+			{
+				// attachment texture not previously seen.
+				llinfos << "attachment_texture: " << image_id.asString() << llendl;
+				all_textures.insert(image_id);
+			}
+		}
 
+		// print any avatar textures we didn't already know about
+		for (LLVOAvatarDictionary::Textures::const_iterator iter = LLVOAvatarDictionary::getInstance()->getTextures().begin();
+			 iter != LLVOAvatarDictionary::getInstance()->getTextures().end();
+			 ++iter)
+		{
+			const LLVOAvatarDictionary::TextureEntry *texture_dict = iter->second;
+			// TODO: MULTI-WEARABLE: handle multiple textures for self
+			const LLViewerTexture* te_image = getImage(iter->first,0);
+			if (!te_image)
+				continue;
+			LLUUID image_id = te_image->getID();
+			if( image_id.isNull() || image_id == IMG_DEFAULT || image_id == IMG_DEFAULT_AVATAR)
+				continue;
+			if (all_textures.find(image_id) == all_textures.end())
+			{
+				llinfos << "local_texture: " << texture_dict->mName << ": " << image_id << llendl;
+				all_textures.insert(image_id);
+			}
+		}
+	}
 	cost += textures.size() * LLVOVolume::ARC_TEXTURE_COST;
 
 	setDebugText(llformat("%d", cost));
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index ce8f64404e494792a6710e2be91022ef826a7726..462c442954653e4af7fc535bafff1eac99adc83c 100644
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -1328,6 +1328,15 @@ BOOL LLVOAvatarSelf::isAllLocalTextureDataFinal() const
 	return TRUE;
 }
 
+BOOL LLVOAvatarSelf::isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const
+{
+	const LLTexLayerSet *layerset = mBakedTextureDatas[index].mTexLayerSet;
+	if (!layerset) return FALSE;
+	const LLTexLayerSetBuffer *layerset_buffer = layerset->getComposite();
+	if (!layerset_buffer) return FALSE;
+	return !layerset_buffer->uploadPending();
+}
+
 BOOL LLVOAvatarSelf::isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const
 {
 	LLUUID id;
diff --git a/indra/newview/llvoavatarself.h b/indra/newview/llvoavatarself.h
index e461dc07da80f22cdab83ab974f390e3c6052f62..55b4fd87c821a0f0d0525e8cee259cbd3aae8faa 100644
--- a/indra/newview/llvoavatarself.h
+++ b/indra/newview/llvoavatarself.h
@@ -177,6 +177,7 @@ class LLVOAvatarSelf :
 	bool				areTexturesCurrent() const;
 	BOOL				isLocalTextureDataAvailable(const LLTexLayerSet* layerset) const;
 	BOOL				isLocalTextureDataFinal(const LLTexLayerSet* layerset) const;
+	BOOL				isBakedTextureFinal(const LLVOAvatarDefines::EBakedTextureIndex index) const;
 	// If you want to check all textures of a given type, pass gAgentWearables.getWearableCount() for index
 	/*virtual*/ BOOL    isTextureDefined(LLVOAvatarDefines::ETextureIndex type, U32 index) const;
 	/*virtual*/ BOOL	isTextureVisible(LLVOAvatarDefines::ETextureIndex type, U32 index = 0) const;
diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py
index 2a966f4adf6a84592c13ea1e080813335891ef6a..c887097575ba8b8236dbccc0e4dc13544c30eb6d 100755
--- a/indra/newview/viewer_manifest.py
+++ b/indra/newview/viewer_manifest.py
@@ -105,6 +105,12 @@ def construct(self):
                             self.end_prefix("*/html")
                     self.end_prefix("skins")
 
+            # local_assets dir (for pre-cached textures)
+            if self.prefix(src="local_assets"):
+                self.path("*.j2c")
+                self.path("*.tga")
+                self.end_prefix("local_assets")
+
             # Files in the newview/ directory
             self.path("gpu_table.txt")