diff --git a/autobuild.xml b/autobuild.xml
index 19dd39c19b953788c2ef700930ea643844cb44d3..7195c0068041948476b3f5ecc2df06fb33de04a2 100644
--- a/autobuild.xml
+++ b/autobuild.xml
@@ -1254,9 +1254,9 @@
             <key>archive</key>
             <map>
               <key>hash</key>
-              <string>94e9e2224000a575fd80b75db52e54b8</string>
+              <string>02c3a65194635b57a5fff05ff47e62e5</string>
               <key>url</key>
-              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/264762/arch/Linux/installer/llappearanceutility_source-0.1-linux-20120914.tar.bz2</string>
+              <string>http://s3-proxy.lindenlab.com/private-builds-secondlife-com/hg/repo/llappearanceutility-source/rev/265256/arch/Linux/installer/llappearanceutility_source-0.1-linux-20120927.tar.bz2</string>
             </map>
             <key>name</key>
             <string>linux</string>
diff --git a/indra/llappearance/llavatarappearance.h b/indra/llappearance/llavatarappearance.h
index 2aa43d25d2dbc59eb532069c5de0b8bfcc77d1c0..abe3599685a1c5f1efb88887a6fe05ff48642eaf 100755
--- a/indra/llappearance/llavatarappearance.h
+++ b/indra/llappearance/llavatarappearance.h
@@ -37,6 +37,7 @@
 
 class LLTexLayerSet;
 class LLTexGlobalColor;
+class LLTexGlobalColorInfo;
 class LLWearableData;
 class LLAvatarBoneInfo;
 class LLAvatarSkeletonInfo;
@@ -135,13 +136,15 @@ class LLAvatarAppearance : public LLCharacter
 
 	typedef std::map<std::string, LLJoint*> joint_map_t;
 	joint_map_t			mJointMap;
+	
+	void				computeBodySize();
+
 
 protected:
 	static BOOL			parseSkeletonFile(const std::string& filename);
 	virtual void		buildCharacter();
 	virtual BOOL		loadAvatar();
 	virtual void		bodySizeChanged() = 0;
-	void 				computeBodySize();
 
 	BOOL				setupBone(const LLAvatarBoneInfo* info, LLJoint* parent, S32 &current_volume_num, S32 &current_joint_num);
 	BOOL				allocateCharacterJoints(U32 num);
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index e7c94104cc5c19ec6d496c8bf9b616f1ebed2d4c..0351f28429510a6d54bed83acd870ecf3b850787 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -29,9 +29,10 @@
 #define LL_AVATARAPPEARANCE_DEFINES_H
 
 #include <vector>
-#include "llwearable.h"
 #include "lljointpickname.h"
 #include "lldictionary.h"
+#include "llwearabletype.h"
+#include "lluuid.h"
 
 namespace LLAvatarAppearanceDefines
 {
diff --git a/indra/llappearance/lllocaltextureobject.h b/indra/llappearance/lllocaltextureobject.h
index 6f14448cca40bc483ed248f757a46816292d15b5..9b9f41fd1961e0ca30b149a8a0a647734ad36f12 100644
--- a/indra/llappearance/lllocaltextureobject.h
+++ b/indra/llappearance/lllocaltextureobject.h
@@ -32,7 +32,6 @@
 #include "llpointer.h"
 #include "llgltexture.h"
 
-class LLUUID;
 class LLTexLayer;
 class LLTexLayerTemplate;
 class LLWearable;
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index 0d7fad349cbb409c6bdd98293a4f035eb8cb26f8..692cfa1a38fc0bc0966ac1ef5525b45299a81b85 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -36,6 +36,7 @@
 class LLAvatarAppearance;
 class LLImageTGA;
 class LLImageRaw;
+class LLLocalTextureObject;
 class LLXmlTreeNode;
 class LLTexLayerSet;
 class LLTexLayerSetInfo;
diff --git a/indra/llappearance/lltexturemanagerbridge.h b/indra/llappearance/lltexturemanagerbridge.h
index 99c01755d4d00eb5c456ed908d2f8de3fafd47cc..4b814b522dd49ff23dff72fc6da4ab36f7c26e75 100644
--- a/indra/llappearance/lltexturemanagerbridge.h
+++ b/indra/llappearance/lltexturemanagerbridge.h
@@ -27,6 +27,7 @@
 #ifndef LL_TEXTUREMANAGERBRIDGE_H
 #define LL_TEXTUREMANAGERBRIDGE_H
 
+#include "llavatarappearancedefines.h"
 #include "llpointer.h"
 #include "llgltexture.h"
 
diff --git a/indra/llappearance/llwearable.cpp b/indra/llappearance/llwearable.cpp
index 9e73a6669a1f9a945ed65f10e7059098754bfba0..5d53d1ae39f4c9bf0d882bff0898d4612782e177 100755
--- a/indra/llappearance/llwearable.cpp
+++ b/indra/llappearance/llwearable.cpp
@@ -62,52 +62,41 @@ LLAssetType::EType LLWearable::getAssetType() const
 	return LLWearableType::getAssetType(mType);
 }
 
+BOOL LLWearable::exportFile(LLFILE* fp) const
+{
+	llofstream ofs(fp);
+	return exportStream(ofs);
+}
+
 // virtual
-BOOL LLWearable::exportFile(LLFILE* file) const
+BOOL LLWearable::exportStream( std::ostream& output_stream ) const
 {
-	// header and version
-	if( fprintf( file, "LLWearable version %d\n", mDefinitionVersion ) < 0 )
-	{
-		return FALSE;
-	}
+	if (!output_stream.good()) return FALSE;
 
+	// header and version
+	output_stream << "LLWearable version " << mDefinitionVersion  << "\n";
 	// name
-	if( fprintf( file, "%s\n", mName.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-
+	output_stream << mName << "\n";
 	// description
-	if( fprintf( file, "%s\n", mDescription.c_str() ) < 0 )
-	{
-		return FALSE;
-	}
-	
+	output_stream << mDescription << "\n";
+
 	// permissions
-	if( !mPermissions.exportFile( file ) )
+	if( !mPermissions.exportStream( output_stream ) )
 	{
 		return FALSE;
 	}
 
 	// sale info
-	if( !mSaleInfo.exportFile( file ) )
+	if( !mSaleInfo.exportStream( output_stream ) )
 	{
 		return FALSE;
 	}
 
 	// wearable type
-	S32 type = (S32)mType;
-	if( fprintf( file, "type %d\n", type ) < 0 )
-	{
-		return FALSE;
-	}
+	output_stream << "type " << (S32) getType() << "\n";
 
 	// parameters
-	S32 num_parameters = mVisualParamIndexMap.size();
-	if( fprintf( file, "parameters %d\n", num_parameters ) < 0 )
-	{
-		return FALSE;
-	}
+	output_stream << "parameters " << mVisualParamIndexMap.size() << "\n";
 
 	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
 		 iter != mVisualParamIndexMap.end(); 
@@ -116,27 +105,17 @@ BOOL LLWearable::exportFile(LLFILE* file) const
 		S32 param_id = iter->first;
 		const LLVisualParam* param = iter->second;
 		F32 param_weight = param->getWeight();
-		if( fprintf( file, "%d %s\n", param_id, terse_F32_to_string( param_weight ).c_str() ) < 0 )
-		{
-			return FALSE;
-		}
+		output_stream << param_id << " " << terse_F32_to_string( param_weight ) << "\n";
 	}
 
 	// texture entries
-	S32 num_textures = mTEMap.size();
-	if( fprintf( file, "textures %d\n", num_textures ) < 0 )
-	{
-			return FALSE;
-	}
+	output_stream << "textures " << mTEMap.size() << "\n";
 
 	for (te_map_t::const_iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter)
 	{
 			S32 te = iter->first;
 			const LLUUID& image_id = iter->second->getID();
-			if( fprintf( file, "%d %s\n", te, image_id.asString().c_str()) < 0 )
-			{
-					return FALSE;
-			}
+			output_stream << te << " " << image_id << "\n";
 	}
 	return TRUE;
 }
@@ -195,29 +174,49 @@ void LLWearable::createLayers(S32 te, LLAvatarAppearance *avatarp)
 	}
 }
 
+LLWearable::EImportResult LLWearable::importFile(LLFILE* fp, LLAvatarAppearance* avatarp )
+{
+	llifstream ifs(fp);
+	return importStream(ifs, avatarp);
+}
+
 // virtual
-LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp )
+LLWearable::EImportResult LLWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
 {
 	// *NOTE: changing the type or size of this buffer will require
-	// changes in the fscanf() code below. You would be better off
-	// rewriting this to use streams and not require an open FILE.
-	char text_buffer[2048];		/* Flawfinder: ignore */
-	S32 fields_read = 0;
+	// changes in the fscanf() code below.
+	// We are using a local max buffer size here to avoid issues
+	// if MAX_STRING size changes.
+	const U32 PARSE_BUFFER_SIZE = 2048;
+	char buffer[2048];		/* Flawfinder: ignore */
+	char uuid_buffer[37];	/* Flawfinder: ignore */
+
+	// This data is being generated on the viewer.
+	// Impose some sane limits on parameter and texture counts.
+	const S32 MAX_WEARABLE_ASSET_TEXTURES = 100;
+	const S32 MAX_WEARABLE_ASSET_PARAMETERS = 1000;
 
-	// read header and version 
-	fields_read = fscanf( file, "LLWearable version %d\n", &mDefinitionVersion );
-	if( fields_read != 1 )
+	if(!avatarp)
 	{
-		return LLWearable::BAD_HEADER;
+		return LLWearable::FAILURE;
 	}
 
-	if(!avatarp)
+	// read header and version 
+	if (!input_stream.good())
 	{
+		llwarns << "Failed to read wearable asset input stream." << llendl;
 		return LLWearable::FAILURE;
 	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	if ( 1 != sscanf( /* Flawfinder: ignore */
+				buffer,
+				"LLWearable version %d\n",
+				&mDefinitionVersion ) )
+	{
+		return LLWearable::BAD_HEADER;
+	}
 
-
-	// Temporary hack to allow wearables with definition version 24 to still load.
+	// Hack to allow wearables with definition version 24 to still load.
 	// This should only affect lindens and NDA'd testers who have saved wearables in 2.0
 	// the extra check for version == 24 can be removed before release, once internal testers
 	// have loaded these wearables again. See hack pt 2 at bottom of function to ensure that
@@ -229,68 +228,58 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 	}
 
 	// name
-	int next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no name
-		mName = "";
-	}
-	else
+	if (!input_stream.good())
 	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer);
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return LLWearable::FAILURE;
-		}
-		mName = text_buffer;
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading name" << llendl;
+		return LLWearable::FAILURE;
 	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mName = buffer;
 
 	// description
-	next_char = fgetc( file );		/* Flawfinder: ignore */
-	if( '\n' == next_char )
-	{
-		// no description
-		mDescription = "";
-	}
-	else
+	if (!input_stream.good())
 	{
-		ungetc( next_char, file );
-		fields_read = fscanf(	/* Flawfinder: ignore */
-			file,
-			"%2047[^\n]",
-			text_buffer );
-		if( (1 != fields_read) || (fgetc( file ) != '\n') )		/* Flawfinder: ignore */
-		{
-			llwarns << "Bad Wearable asset: early end of file" << llendl;
-			return LLWearable::FAILURE;
-		}
-		mDescription = text_buffer;
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading description" << llendl;
+		return LLWearable::FAILURE;
 	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	mDescription = buffer;
 
 	// permissions
-	S32 perm_version;
-	fields_read = fscanf( file, " permissions %d\n", &perm_version );
-	if( (fields_read != 1) || (perm_version != 0) )
+	if (!input_stream.good())
 	{
-		llwarns << "Bad Wearable asset: missing permissions" << llendl;
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading permissions" << llendl;
 		return LLWearable::FAILURE;
 	}
-	if( !mPermissions.importFile( file ) )
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	S32 perm_version = -1;
+	if ( 1 != sscanf( buffer, " permissions %d\n", &perm_version ) ||
+		 perm_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid permissions" << llendl;
+		return LLWearable::FAILURE;
+	}
+	if( !mPermissions.importStream( input_stream ) )
 	{
 		return LLWearable::FAILURE;
 	}
 
 	// sale info
-	S32 sale_info_version;
-	fields_read = fscanf( file, " sale_info %d\n", &sale_info_version );
-	if( (fields_read != 1) || (sale_info_version != 0) )
+	if (!input_stream.good())
 	{
-		llwarns << "Bad Wearable asset: missing sale_info" << llendl;
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading sale info" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	S32 sale_info_version = -1;
+	if ( 1 != sscanf( buffer, " sale_info %d\n", &sale_info_version ) ||
+		sale_info_version != 0 )
+	{
+		llwarns << "Bad Wearable asset: missing valid sale_info" << llendl;
 		return LLWearable::FAILURE;
 	}
 	// Sale info used to contain next owner perm. It is now in the
@@ -299,7 +288,7 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 	// up the vast majority of the tasks.
 	BOOL has_perm_mask = FALSE;
 	U32 perm_mask = 0;
-	if( !mSaleInfo.importFile(file, has_perm_mask, perm_mask) )
+	if( !mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask) )
 	{
 		return LLWearable::FAILURE;
 	}
@@ -314,9 +303,15 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 	}
 
 	// wearable type
+	if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading type" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
 	S32 type = -1;
-	fields_read = fscanf( file, "type %d\n", &type );
-	if( fields_read != 1 )
+	if ( 1 != sscanf( buffer, "type %d\n", &type ) )
 	{
 		llwarns << "Bad Wearable asset: bad type" << llendl;
 		return LLWearable::FAILURE;
@@ -333,27 +328,48 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 	}
 
 	// parameters header
-	S32 num_parameters = 0;
-	fields_read = fscanf( file, "parameters %d\n", &num_parameters );
-	if( fields_read != 1 )
+	if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading parameters header" << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	S32 num_parameters = -1;
+	if ( 1 != sscanf( buffer, "parameters %d\n", &num_parameters ) )
 	{
 		llwarns << "Bad Wearable asset: missing parameters block" << llendl;
 		return LLWearable::FAILURE;
 	}
-
+	if ( num_parameters > MAX_WEARABLE_ASSET_PARAMETERS )
+	{
+		llwarns << "Bad Wearable asset: too many parameters, "
+				<< num_parameters << llendl;
+		return LLWearable::FAILURE;
+	}
 	if( num_parameters != mVisualParamIndexMap.size() )
 	{
-		llwarns << "Wearable parameter mismatch. Reading in " << num_parameters << " from file, but created " << mVisualParamIndexMap.size() << " from avatar parameters. type: " <<  mType << llendl;
+		llwarns << "Wearable parameter mismatch. Reading in " 
+				<< num_parameters << " from file, but created " 
+				<< mVisualParamIndexMap.size() 
+				<< " from avatar parameters. type: " 
+				<<  getType() << llendl;
 	}
 
 	// parameters
 	S32 i;
 	for( i = 0; i < num_parameters; i++ )
 	{
+		if (!input_stream.good())
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading parameter #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		input_stream.getline(buffer, PARSE_BUFFER_SIZE);
 		S32 param_id = 0;
 		F32 param_weight = 0.f;
-		fields_read = fscanf( file, "%d %f\n", &param_id, &param_weight );
-		if( fields_read != 2 )
+		if ( 2 != sscanf( buffer, "%d %f\n", &param_id, &param_weight ) )
 		{
 			llwarns << "Bad Wearable asset: bad parameter, #" << i << llendl;
 			return LLWearable::FAILURE;
@@ -362,34 +378,53 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 	}
 
 	// textures header
-	S32 num_textures = 0;
-	fields_read = fscanf( file, "textures %d\n", &num_textures);
-	if( fields_read != 1 )
+	if (!input_stream.good())
+	{
+		llwarns << "Bad Wearable asset: early end of input stream " 
+				<< "while reading textures header" << i << llendl;
+		return LLWearable::FAILURE;
+	}
+	input_stream.getline(buffer, PARSE_BUFFER_SIZE);
+	S32 num_textures = -1;
+	if ( 1 != sscanf( buffer, "textures %d\n", &num_textures) )
 	{
 		llwarns << "Bad Wearable asset: missing textures block" << llendl;
 		return LLWearable::FAILURE;
 	}
+	if ( num_textures > MAX_WEARABLE_ASSET_TEXTURES )
+	{
+		llwarns << "Bad Wearable asset: too many textures, "
+				<< num_textures << llendl;
+		return LLWearable::FAILURE;
+	}
 
 	// textures
 	for( i = 0; i < num_textures; i++ )
 	{
+		if (!input_stream.good())
+		{
+			llwarns << "Bad Wearable asset: early end of input stream " 
+					<< "while reading textures #" << i << llendl;
+			return LLWearable::FAILURE;
+		}
+		input_stream.getline(buffer, PARSE_BUFFER_SIZE);
 		S32 te = 0;
-		fields_read = fscanf(   /* Flawfinder: ignore */
-				file,
-				"%d %2047s\n",
-				&te, text_buffer);
-		if( fields_read != 2 )
+		if ( 2 != sscanf(   /* Flawfinder: ignore */
+				buffer,
+				"%d %36s\n",
+				&te, uuid_buffer) )
 		{
 				llwarns << "Bad Wearable asset: bad texture, #" << i << llendl;
 				return LLWearable::FAILURE;
 		}
 	
-		if( !LLUUID::validate( text_buffer ) )
+		if( !LLUUID::validate( uuid_buffer ) )
 		{
-				llwarns << "Bad Wearable asset: bad texture uuid: " << text_buffer << llendl;
+				llwarns << "Bad Wearable asset: bad texture uuid: " 
+						<< uuid_buffer << llendl;
 				return LLWearable::FAILURE;
 		}
-		LLUUID id = LLUUID(text_buffer);
+		LLUUID id = LLUUID(uuid_buffer);
 		LLGLTexture* image = gTextureManagerBridgep->getFetchedTexture( id );
 		if( mTEMap.find(te) != mTEMap.end() )
 		{
@@ -400,12 +435,15 @@ LLWearable::EImportResult LLWearable::importFile( LLFILE* file, LLAvatarAppearan
 				delete mSavedTEMap[te];
 		}
 	
-		LLUUID textureid(text_buffer);
+		LLUUID textureid(uuid_buffer);
 		mTEMap[te] = new LLLocalTextureObject(image, textureid);
 		mSavedTEMap[te] = new LLLocalTextureObject(image, textureid);
 		createLayers(te, avatarp);
 	}
 
+	// copy all saved param values to working params
+	revertValues();
+
 	return LLWearable::SUCCESS;
 }
 
@@ -417,6 +455,173 @@ void LLWearable::setType(LLWearableType::EType type, LLAvatarAppearance *avatarp
 }
 
 
+LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index)
+{
+	te_map_t::iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+const LLLocalTextureObject* LLWearable::getLocalTextureObject(S32 index) const
+{
+	te_map_t::const_iterator iter = mTEMap.find(index);
+	if( iter != mTEMap.end() )
+	{
+		const LLLocalTextureObject* lto = iter->second;
+		return lto;
+	}
+	return NULL;
+}
+
+std::vector<LLLocalTextureObject*> LLWearable::getLocalTextureListSeq()
+{
+	std::vector<LLLocalTextureObject*> result;
+
+	for(te_map_t::const_iterator iter = mTEMap.begin();
+		iter != mTEMap.end(); iter++)
+	{
+		LLLocalTextureObject* lto = iter->second;
+		result.push_back(lto);
+	}
+
+	return result;
+}
+
+void LLWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
+{
+	if( mTEMap.find(index) != mTEMap.end() )
+	{
+		mTEMap.erase(index);
+	}
+	mTEMap[index] = new LLLocalTextureObject(lto);
+}
+
+void LLWearable::revertValues()
+{
+	// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
+
+	//update saved settings so wearable is no longer dirty
+	// non-driver params first
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	//then driver params
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		F32 value = iter->second;
+		LLVisualParam *param = getVisualParam(id);
+		if(param &&  dynamic_cast<LLDriverParam*>(param) )
+		{
+			setVisualParamWeight(id, value, TRUE);
+		}
+	}
+
+	// make sure that saved values are sane
+	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
+	{
+		S32 id = iter->first;
+		LLVisualParam *param = getVisualParam(id);
+		if( param )
+		{
+			mSavedVisualParamMap[id] = param->getWeight();
+		}
+	}
+
+	syncImages(mSavedTEMap, mTEMap);
+}
+
+void LLWearable::saveValues()
+{
+	//update saved settings so wearable is no longer dirty
+	mSavedVisualParamMap.clear();
+	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
+	{
+		S32 id = iter->first;
+		LLVisualParam *wearable_param = iter->second;
+		F32 value = wearable_param->getWeight();
+		mSavedVisualParamMap[id] = value;
+	}
+
+	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
+	syncImages(mTEMap, mSavedTEMap);
+}
+
+void LLWearable::syncImages(te_map_t &src, te_map_t &dst)
+{
+	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
+	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
+	{
+		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
+		{
+			te_map_t::const_iterator iter = src.find(te);
+			LLUUID image_id;
+			LLGLTexture *image = NULL;
+			LLLocalTextureObject *lto = NULL;
+			if(iter != src.end())
+			{
+				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
+				lto = iter->second;
+				image = lto->getImage();
+				image_id = lto->getID();
+			}
+			else
+			{
+				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
+				image_id = getDefaultTextureImageID((ETextureIndex) te);
+				image = gTextureManagerBridgep->getFetchedTexture( image_id );
+			}
+
+			if( dst.find(te) != dst.end() )
+			{
+				// there's already an entry in the destination map for the texture. Just update its values.
+				dst[te]->setImage(image);
+				dst[te]->setID(image_id);
+			}
+			else
+			{
+				// no entry found in the destination map, we need to create a new Local Texture Object
+				dst[te] = new LLLocalTextureObject(image, image_id);
+			}
+
+			if( lto )
+			{
+				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
+				dst[te]->setBakedReady(lto->getBakedReady());
+				dst[te]->setDiscard(lto->getDiscard());
+			}
+		}
+	}
+}
+
+void LLWearable::destroyTextures()
+{
+	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mTEMap.clear();
+	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
+	{
+		LLLocalTextureObject *lto = iter->second;
+		delete lto;
+	}
+	mSavedTEMap.clear();
+}
+
 void LLWearable::addVisualParam(LLVisualParam *param)
 {
 	if( mVisualParamIndexMap[param->getID()] )
diff --git a/indra/llappearance/llwearable.h b/indra/llappearance/llwearable.h
index b8bbf82a6e0837adc126a349b92ddfeb8bfb3940..bc73ed4d8c55fe9a0d72a5f3bc5c82ee9fe4fbcd 100644
--- a/indra/llappearance/llwearable.h
+++ b/indra/llappearance/llwearable.h
@@ -27,6 +27,7 @@
 #ifndef LL_LLWEARABLE_H
 #define LL_LLWEARABLE_H
 
+#include "llavatarappearancedefines.h"
 #include "llextendedstatus.h"
 #include "llpermissions.h"
 #include "llsaleinfo.h"
@@ -79,14 +80,19 @@ class LLWearable
 		SUCCESS,
 		BAD_HEADER
 	};
-	virtual BOOL				exportFile(LLFILE* file) const;
-	virtual EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp);
-
-
+	BOOL				exportFile(LLFILE* file) const;
+	EImportResult		importFile(LLFILE* file, LLAvatarAppearance* avatarp );
+	virtual BOOL				exportStream( std::ostream& output_stream ) const;
+	virtual EImportResult		importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
 
 	static void			setCurrentDefinitionVersion( S32 version ) { LLWearable::sCurrentDefinitionVersion = version; }
+	virtual LLUUID		getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const = 0;
+
+	LLLocalTextureObject* getLocalTextureObject(S32 index);
+	const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
+	std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
 
-	virtual LLLocalTextureObject* getLocalTextureObject(S32 index) = 0;
+	void				setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
 	void				addVisualParam(LLVisualParam *param);
 	void 				setVisualParamWeight(S32 index, F32 value, BOOL upload_bake);
 	F32					getVisualParamWeight(S32 index) const;
@@ -97,6 +103,9 @@ class LLWearable
 	LLColor4			getClothesColor(S32 te) const;
 	void 				setClothesColor( S32 te, const LLColor4& new_color, BOOL upload_bake );
 
+	virtual void		revertValues();
+	virtual void		saveValues();
+
 	// Something happened that requires the wearable to be updated (e.g. worn/unworn).
 	virtual void		setUpdated() const = 0;
 
@@ -104,6 +113,9 @@ class LLWearable
 	virtual void		addToBakedTextureHash(LLMD5& hash) const = 0;
 
 protected:
+	typedef std::map<S32, LLLocalTextureObject*> te_map_t;
+	void				syncImages(te_map_t &src, te_map_t &dst);
+	void				destroyTextures();
 	void			 	createVisualParams(LLAvatarAppearance *avatarp);
 	void 				createLayers(S32 te, LLAvatarAppearance *avatarp);
 
@@ -121,7 +133,6 @@ class LLWearable
 	typedef std::map<S32, LLVisualParam *>    visual_param_index_map_t;
 	visual_param_index_map_t mVisualParamIndexMap;
 
-	typedef std::map<S32, LLLocalTextureObject*> te_map_t;
 	te_map_t mTEMap;				// maps TE to LocalTextureObject
 	te_map_t mSavedTEMap;			// last saved version of TEMap
 };
diff --git a/indra/llappearance/llwearabledata.h b/indra/llappearance/llwearabledata.h
index 2931424131f557f65ff3a9053c7c60c14c36e1b5..379384a989c54612e5fed21497ea4c807ee0af69 100644
--- a/indra/llappearance/llwearabledata.h
+++ b/indra/llappearance/llwearabledata.h
@@ -28,6 +28,7 @@
 #define LL_WEARABLEDATA_H
 
 #include "llavatarappearancedefines.h"
+#include "llwearable.h"
 #include "llerror.h"
 
 class LLAvatarAppearance;
diff --git a/indra/llcommon/lldictionary.h b/indra/llcommon/lldictionary.h
index bc3bc3e74ac1cca5601a425a53891175c3e18555..c752859a3661f1116f8bc41ec43a36282dfc40ad 100644
--- a/indra/llcommon/lldictionary.h
+++ b/indra/llcommon/lldictionary.h
@@ -30,6 +30,8 @@
 #include <map>
 #include <string>
 
+#include "llerror.h"
+
 struct LL_COMMON_API LLDictionaryEntry
 {
 	LLDictionaryEntry(const std::string &name);
diff --git a/indra/llcommon/llfile.cpp b/indra/llcommon/llfile.cpp
index c51d042a3d312d908d5c8b56cd47341ee43dad51..bc615ed39ec593de0cda0d2bd3caa1639d7dad06 100644
--- a/indra/llcommon/llfile.cpp
+++ b/indra/llcommon/llfile.cpp
@@ -56,6 +56,8 @@ std::string strerr(int errn)
 	return buffer;
 }
 
+typedef std::basic_ios<char,std::char_traits < char > > _Myios;
+
 #else
 // On Posix we want to call strerror_r(), but alarmingly, there are two
 // different variants. The one that returns int always populates the passed
@@ -324,9 +326,10 @@ const char *LLFile::tmpdir()
 
 /***************** Modified file stream created to overcome the incorrect behaviour of posix fopen in windows *******************/
 
-#if USE_LLFILESTREAMS
+#if LL_WINDOWS
 
-LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,int)	// protection currently unused
+LLFILE *	LLFile::_Fiopen(const std::string& filename, 
+		std::ios::openmode mode)
 {	// open a file
 	static const char *mods[] =
 	{	// fopen mode strings corresponding to valid[i]
@@ -385,117 +388,681 @@ LLFILE *	LLFile::_Fiopen(const std::string& filename, std::ios::openmode mode,in
 	return (0);
 }
 
-/************** input file stream ********************************/
+#endif /* LL_WINDOWS */
 
-void llifstream::close()
-{	// close the C stream
-	if (_Filebuffer && _Filebuffer->close() == 0)
+/************** llstdio file buffer ********************************/
+
+
+//llstdio_filebuf* llstdio_filebuf::open(const char *_Filename,
+//	ios_base::openmode _Mode)
+//{
+//#if LL_WINDOWS
+//	_Filet *_File;
+//	if (is_open() || (_File = LLFILE::_Fiopen(_Filename, _Mode)) == 0)
+//		return (0);	// open failed
+//
+//	_Init(_File, _Openfl);
+//	_Initcvt(&_USE(_Mysb::getloc(), _Cvt));
+//	return (this);	// open succeeded
+//#else
+//	std::filebuf* _file = std::filebuf::open(_Filename, _Mode);
+//	if (NULL == _file) return NULL;
+//	return this;
+//#endif
+//}
+
+
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+llstdio_filebuf::int_type llstdio_filebuf::overflow(llstdio_filebuf::int_type __c)
+{
+	int_type __ret = traits_type::eof();
+	const bool __testeof = traits_type::eq_int_type(__c, __ret);
+	const bool __testout = _M_mode & ios_base::out;
+	if (__testout && !_M_reading)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
+		if (this->pbase() < this->pptr())
+		{
+			// If appropriate, append the overflow char.
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+
+			// Convert pending sequence to external representation,
+			// and output.
+			if (_convert_to_external(this->pbase(),
+					 this->pptr() - this->pbase()))
+			{
+				_M_set_buffer(0);
+				__ret = traits_type::not_eof(__c);
+			}
+		}
+		else if (_M_buf_size > 1)
+		{
+			// Overflow in 'uncommitted' mode: set _M_writing, set
+			// the buffer to the initial 'write' mode, and put __c
+			// into the buffer.
+			_M_set_buffer(0);
+			_M_writing = true;
+			if (!__testeof)
+			{
+				*this->pptr() = traits_type::to_char_type(__c);
+				this->pbump(1);
+			}
+			__ret = traits_type::not_eof(__c);
+		}
+		else
+		{
+			// Unbuffered.
+			char_type __conv = traits_type::to_char_type(__c);
+			if (__testeof || _convert_to_external(&__conv, 1))
+			{
+				_M_writing = true;
+				__ret = traits_type::not_eof(__c);
+			}
+		}
 	}
+	return __ret;
 }
 
-void llifstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
-{	// open a C stream with specified mode
+bool llstdio_filebuf::_convert_to_external(char_type* __ibuf,
+						std::streamsize __ilen)
+{
+	// Sizes of external and pending output.
+	streamsize __elen;
+	streamsize __plen;
+	if (__check_facet(_M_codecvt).always_noconv())
+	{
+		//__elen = _M_file.xsputn(reinterpret_cast<char*>(__ibuf), __ilen);
+		__elen = fwrite(reinterpret_cast<void*>(__ibuf), 1,
+						__ilen, _M_file.file());
+		__plen = __ilen;
+	}
+	else
+	{
+		// Worst-case number of external bytes needed.
+		// XXX Not done encoding() == -1.
+		streamsize __blen = __ilen * _M_codecvt->max_length();
+		char* __buf = static_cast<char*>(__builtin_alloca(__blen));
 
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::in, _Prot);
-	if(filep == NULL)
+		char* __bend;
+		const char_type* __iend;
+		codecvt_base::result __r;
+		__r = _M_codecvt->out(_M_state_cur, __ibuf, __ibuf + __ilen,
+				__iend, __buf, __buf + __blen, __bend);
+
+		if (__r == codecvt_base::ok || __r == codecvt_base::partial)
+			__blen = __bend - __buf;
+		else if (__r == codecvt_base::noconv)
+		{
+			// Same as the always_noconv case above.
+			__buf = reinterpret_cast<char*>(__ibuf);
+			__blen = __ilen;
+		}
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+									"conversion error"));
+  
+		//__elen = _M_file.xsputn(__buf, __blen);
+		__elen = fwrite(__buf, 1, __blen, _M_file.file());
+		__plen = __blen;
+
+		// Try once more for partial conversions.
+		if (__r == codecvt_base::partial && __elen == __plen)
+		{
+			const char_type* __iresume = __iend;
+			streamsize __rlen = this->pptr() - __iend;
+			__r = _M_codecvt->out(_M_state_cur, __iresume,
+					__iresume + __rlen, __iend, __buf,
+					__buf + __blen, __bend);
+			if (__r != codecvt_base::error)
+			{
+				__rlen = __bend - __buf;
+				//__elen = _M_file.xsputn(__buf, __rlen);
+				__elen = fwrite(__buf, 1, __rlen, _M_file.file());
+				__plen = __rlen;
+			}
+			else
+			{
+				__throw_ios_failure(__N("llstdio_filebuf::_convert_to_external "
+										"conversion error"));
+			}
+		}
+	}
+	return __elen == __plen;
+}
+
+llstdio_filebuf::int_type llstdio_filebuf::underflow()
+{
+	int_type __ret = traits_type::eof();
+	const bool __testin = _M_mode & ios_base::in;
+	if (__testin)
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		if (_M_writing)
+		{
+			if (overflow() == traits_type::eof())
+			return __ret;
+			//_M_set_buffer(-1);
+			//_M_writing = false;
+		}
+		// Check for pback madness, and if so switch back to the
+		// normal buffers and jet outta here before expensive
+		// fileops happen...
+		_M_destroy_pback();
+
+		if (this->gptr() < this->egptr())
+			return traits_type::to_int_type(*this->gptr());
+
+		// Get and convert input sequence.
+		const size_t __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+		// Will be set to true if ::fread() returns 0 indicating EOF.
+		bool __got_eof = false;
+		// Number of internal characters produced.
+		streamsize __ilen = 0;
+		codecvt_base::result __r = codecvt_base::ok;
+		if (__check_facet(_M_codecvt).always_noconv())
+		{
+			//__ilen = _M_file.xsgetn(reinterpret_cast<char*>(this->eback()),
+			//			__buflen);
+			__ilen = fread(reinterpret_cast<void*>(this->eback()), 1,
+						__buflen, _M_file.file());
+			if (__ilen == 0)
+				__got_eof = true;
+		}
+		else
+	    {
+			// Worst-case number of external bytes.
+			// XXX Not done encoding() == -1.
+			const int __enc = _M_codecvt->encoding();
+			streamsize __blen; // Minimum buffer size.
+			streamsize __rlen; // Number of chars to read.
+			if (__enc > 0)
+				__blen = __rlen = __buflen * __enc;
+			else
+			{
+				__blen = __buflen + _M_codecvt->max_length() - 1;
+				__rlen = __buflen;
+			}
+			const streamsize __remainder = _M_ext_end - _M_ext_next;
+			__rlen = __rlen > __remainder ? __rlen - __remainder : 0;
+
+			// An imbue in 'read' mode implies first converting the external
+			// chars already present.
+			if (_M_reading && this->egptr() == this->eback() && __remainder)
+				__rlen = 0;
+
+			// Allocate buffer if necessary and move unconverted
+			// bytes to front.
+			if (_M_ext_buf_size < __blen)
+			{
+				char* __buf = new char[__blen];
+				if (__remainder)
+					__builtin_memcpy(__buf, _M_ext_next, __remainder);
+
+				delete [] _M_ext_buf;
+				_M_ext_buf = __buf;
+				_M_ext_buf_size = __blen;
+			}
+			else if (__remainder)
+				__builtin_memmove(_M_ext_buf, _M_ext_next, __remainder);
+
+			_M_ext_next = _M_ext_buf;
+			_M_ext_end = _M_ext_buf + __remainder;
+			_M_state_last = _M_state_cur;
+
+			do
+			{
+				if (__rlen > 0)
+				{
+					// Sanity check!
+					// This may fail if the return value of
+					// codecvt::max_length() is bogus.
+					if (_M_ext_end - _M_ext_buf + __rlen > _M_ext_buf_size)
+					{
+						__throw_ios_failure(__N("llstdio_filebuf::underflow "
+							"codecvt::max_length() "
+							"is not valid"));
+					}
+					//streamsize __elen = _M_file.xsgetn(_M_ext_end, __rlen);
+					streamsize __elen = fread(_M_ext_end, 1,
+						__rlen, _M_file.file());
+					if (__elen == 0)
+						__got_eof = true;
+					else if (__elen == -1)
+					break;
+					//_M_ext_end += __elen;
+				}
+
+				char_type* __iend = this->eback();
+				if (_M_ext_next < _M_ext_end)
+				{
+					__r = _M_codecvt->in(_M_state_cur, _M_ext_next,
+							_M_ext_end, _M_ext_next,
+							this->eback(),
+							this->eback() + __buflen, __iend);
+				}
+				if (__r == codecvt_base::noconv)
+				{
+					size_t __avail = _M_ext_end - _M_ext_buf;
+					__ilen = std::min(__avail, __buflen);
+					traits_type::copy(this->eback(),
+						reinterpret_cast<char_type*>
+						(_M_ext_buf), __ilen);
+					_M_ext_next = _M_ext_buf + __ilen;
+				}
+				else
+					__ilen = __iend - this->eback();
+
+				// _M_codecvt->in may return error while __ilen > 0: this is
+				// ok, and actually occurs in case of mixed encodings (e.g.,
+				// XML files).
+				if (__r == codecvt_base::error)
+					break;
+
+				__rlen = 1;
+			} while (__ilen == 0 && !__got_eof);
+		}
+
+		if (__ilen > 0)
+		{
+			_M_set_buffer(__ilen);
+			_M_reading = true;
+			__ret = traits_type::to_int_type(*this->gptr());
+		}
+		else if (__got_eof)
+		{
+			// If the actual end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without an
+			// intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+			// However, reaching it while looping on partial means that
+			// the file has got an incomplete character.
+			if (__r == codecvt_base::partial)
+				__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"incomplete character in file"));
+		}
+		else if (__r == codecvt_base::error)
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"invalid byte sequence in file"));
+		else
+			__throw_ios_failure(__N("llstdio_filebuf::underflow "
+					"error reading the file"));
 	}
-	llassert(_Filebuffer == NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+	return __ret;
 }
 
-bool llifstream::is_open() const
-{	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+std::streamsize llstdio_filebuf::xsgetn(char_type* __s, std::streamsize __n)
+{
+	// Clear out pback buffer before going on to the real deal...
+	streamsize __ret = 0;
+	if (_M_pback_init)
+	{
+		if (__n > 0 && this->gptr() == this->eback())
+		{
+			*__s++ = *this->gptr();
+			this->gbump(1);
+			__ret = 1;
+			--__n;
+		}
+		_M_destroy_pback();
+	}
+       
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n > __buflen we read directly instead of using the
+	// buffer repeatedly.
+	const bool __testin = _M_mode & ios_base::in;
+	const streamsize __buflen = _M_buf_size > 1 ? _M_buf_size - 1 : 1;
+
+	if (__n > __buflen && __check_facet(_M_codecvt).always_noconv()
+		&& __testin && !_M_writing)
+	{
+		// First, copy the chars already present in the buffer.
+		const streamsize __avail = this->egptr() - this->gptr();
+		if (__avail != 0)
+		{
+			if (__avail == 1)
+				*__s = *this->gptr();
+			else
+				traits_type::copy(__s, this->gptr(), __avail);
+			__s += __avail;
+			this->gbump(__avail);
+			__ret += __avail;
+			__n -= __avail;
+		}
+
+		// Need to loop in case of short reads (relatively common
+		// with pipes).
+		streamsize __len;
+		for (;;)
+		{
+			//__len = _M_file.xsgetn(reinterpret_cast<char*>(__s), __n);
+			__len = fread(reinterpret_cast<void*>(__s), 1, 
+						__n, _M_file.file());
+			if (__len == -1)
+				__throw_ios_failure(__N("llstdio_filebuf::xsgetn "
+										"error reading the file"));
+			if (__len == 0)
+				break;
+
+			__n -= __len;
+			__ret += __len;
+			if (__n == 0)
+				break;
+
+			__s += __len;
+		}
+
+		if (__n == 0)
+		{
+			_M_set_buffer(0);
+			_M_reading = true;
+		}
+		else if (__len == 0)
+		{
+			// If end of file is reached, set 'uncommitted'
+			// mode, thus allowing an immediate write without
+			// an intervening seek.
+			_M_set_buffer(-1);
+			_M_reading = false;
+		}
+	}
+	else
+		__ret += __streambuf_type::xsgetn(__s, __n);
+
+	return __ret;
 }
-llifstream::~llifstream()
+
+std::streamsize llstdio_filebuf::xsputn(char_type* __s, std::streamsize __n)
 {
-	if (_ShouldClose)
+	// Optimization in the always_noconv() case, to be generalized in the
+	// future: when __n is sufficiently large we write directly instead of
+	// using the buffer.
+	streamsize __ret = 0;
+	const bool __testout = _M_mode & ios_base::out;
+	if (__check_facet(_M_codecvt).always_noconv()
+		&& __testout && !_M_reading)
 	{
-		close();
+		// Measurement would reveal the best choice.
+		const streamsize __chunk = 1ul << 10;
+		streamsize __bufavail = this->epptr() - this->pptr();
+
+		// Don't mistake 'uncommitted' mode buffered with unbuffered.
+		if (!_M_writing && _M_buf_size > 1)
+			__bufavail = _M_buf_size - 1;
+
+		const streamsize __limit = std::min(__chunk, __bufavail);
+		if (__n >= __limit)
+		{
+			const streamsize __buffill = this->pptr() - this->pbase();
+			const char* __buf = reinterpret_cast<const char*>(this->pbase());
+			//__ret = _M_file.xsputn_2(__buf, __buffill,
+			//			reinterpret_cast<const char*>(__s), __n);
+			if (__buffill)
+			{
+				__ret = fwrite(__buf, 1, __buffill, _M_file.file());
+			}
+			if (__ret == __buffill)
+			{
+				__ret += fwrite(reinterpret_cast<const char*>(__s), 1,
+								__n, _M_file.file());
+			}
+			if (__ret == __buffill + __n)
+			{
+				_M_set_buffer(0);
+				_M_writing = true;
+			}
+			if (__ret > __buffill)
+				__ret -= __buffill;
+			else
+				__ret = 0;
+		}
+		else
+			__ret = __streambuf_type::xsputn(__s, __n);
 	}
-	delete _Filebuffer;
+	else
+		__ret = __streambuf_type::xsputn(__s, __n);
+    return __ret;
 }
 
-llifstream::llifstream(const std::string& _Filename,
-	ios_base::openmode _Mode,
-	int _Prot)
-	: std::basic_istream< char , std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
+int llstdio_filebuf::sync()
+{
+	return (_M_file.sync() == 0 ? 0 : -1);
+}
+#endif
+
+/************** input file stream ********************************/
 
-{	// construct with named file and specified mode
-	open(_Filename, _Mode | ios_base::in, _Prot);	/* Flawfinder: ignore */
+
+llifstream::llifstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
+llifstream::llifstream(const std::string& _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
 }
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::in);
+}
+#endif
 
+// explicit
+llifstream::llifstream(const char* _Filename, 
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::in);
+}
+#endif
 
-/************** output file stream ********************************/
 
-bool llofstream::is_open() const
+// explicit
+llifstream::llifstream(_Filet *_File,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::istream(&_M_filebuf) {}
+#else
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+#if !LL_WINDOWS
+// explicit
+llifstream::llifstream(int __fd,
+		ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::istream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llifstream::is_open() const
 {	// test if C stream has been opened
-	if(_Filebuffer)
-		return (_Filebuffer->is_open());
-	return false;
+	return _M_filebuf.is_open();
 }
 
-void llofstream::open(const std::string& _Filename,	/* Flawfinder: ignore */
-	ios_base::openmode _Mode,
-	int _Prot)
+void llifstream::open(const char* _Filename, ios_base::openmode _Mode)
 {	// open a C stream with specified mode
-
-	LLFILE* filep = LLFile::_Fiopen(_Filename,_Mode | ios_base::out, _Prot);
-	if(filep == NULL)
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::in) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		return;
+		_Myios::clear();
 	}
-	llassert(_Filebuffer==NULL);
-	_Filebuffer = new _Myfb(filep);
-	_ShouldClose = true;
-	_Myios::init(_Filebuffer);
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-void llofstream::close()
+void llifstream::close()
 {	// close the C stream
-	if(is_open())
+	if (_M_filebuf.close() == 0)
 	{
-		if (_Filebuffer->close() == 0)
-		{
-			_Myios::setstate(ios_base::failbit);	/*Flawfinder: ignore*/
-		}
-		delete _Filebuffer;
-		_Filebuffer = NULL;
-		_ShouldClose = false;
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
 	}
 }
 
+
+/************** output file stream ********************************/
+
+
+llofstream::llofstream() : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+}
+#endif
+
+// explicit
 llofstream::llofstream(const std::string& _Filename,
-	std::ios_base::openmode _Mode,
-	int _Prot)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-{	// construct with named file and specified mode
-	open(_Filename, _Mode , _Prot);	/* Flawfinder: ignore */
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename.c_str(), _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename.c_str(), _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(const char* _Filename,
+		ios_base::openmode _Mode) : _M_filebuf(),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf)
+{
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
+	this->open(_Filename, _Mode | ios_base::out);
+}
+#endif
+
+// explicit
+llofstream::llofstream(_Filet *_File,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(_File, _Mode, _Size),
+#if LL_WINDOWS
+	std::ostream(&_M_filebuf) {}
+#else
+	std::ostream()
+{
+	this->init(&_M_filebuf);
 }
+#endif
 
-llofstream::~llofstream()
+#if !LL_WINDOWS
+// explicit
+llofstream::llofstream(int __fd,
+			ios_base::openmode _Mode, size_t _Size) :
+	_M_filebuf(__fd, _Mode, _Size),
+	std::ostream()
 {
-	// destroy the object
-	if (_ShouldClose)
+	this->init(&_M_filebuf);
+}
+#endif
+
+bool llofstream::is_open() const
+{	// test if C stream has been opened
+	return _M_filebuf.is_open();
+}
+
+void llofstream::open(const char* _Filename, ios_base::openmode _Mode)
+{	// open a C stream with specified mode
+	if (_M_filebuf.open(_Filename, _Mode | ios_base::out) == 0)
+#if LL_WINDOWS
+	{
+		_Myios::setstate(ios_base::failbit);
+	}
+	else
 	{
-		close();
+		_Myios::clear();
 	}
-	delete _Filebuffer;
+#else
+	{
+		this->setstate(ios_base::failbit);
+	}
+	else
+	{
+		this->clear();
+	}
+#endif
 }
 
-#endif // #if USE_LLFILESTREAMS
+void llofstream::close()
+{	// close the C stream
+	if (_M_filebuf.close() == 0)
+	{
+#if LL_WINDOWS
+		_Myios::setstate(ios_base::failbit);
+#else
+		this->setstate(ios_base::failbit);
+#endif
+	}
+}
 
 /************** helper functions ********************************/
 
diff --git a/indra/llcommon/llfile.h b/indra/llcommon/llfile.h
index dd7d36513a06d13c81638c1d7eafbdac2e60ab9e..9d70db96ea83852d4365cf9f0096454bc2e41cec 100644
--- a/indra/llcommon/llfile.h
+++ b/indra/llcommon/llfile.h
@@ -35,16 +35,9 @@
  * Attempts to mostly mirror the POSIX style IO functions.
  */
 
-typedef FILE	LLFILE;
+typedef FILE LLFILE;
 
 #include <fstream>
-
-#ifdef LL_WINDOWS
-#define	USE_LLFILESTREAMS	1
-#else
-#define	USE_LLFILESTREAMS	0
-#endif
-
 #include <sys/stat.h>
 
 #if LL_WINDOWS
@@ -52,6 +45,8 @@ typedef FILE	LLFILE;
 typedef struct _stat	llstat;
 #else
 typedef struct stat		llstat;
+#include <ext/stdio_filebuf.h>
+#include <bits/postypes.h>
 #endif
 
 #ifndef S_ISREG
@@ -83,142 +78,342 @@ class LL_COMMON_API LLFile
 	static	int		stat(const std::string&	filename,llstat*	file_status);
 	static	bool	isdir(const std::string&	filename);
 	static	bool	isfile(const std::string&	filename);
-	static	LLFILE *	_Fiopen(const std::string& filename, std::ios::openmode mode,int);	// protection currently unused
+	static	LLFILE *	_Fiopen(const std::string& filename, 
+			std::ios::openmode mode);
 
 	static  const char * tmpdir();
 };
 
+/**
+ *  @brief Provides a layer of compatibility for C/POSIX.
+ *
+ *  This is taken from both the GNU __gnu_cxx::stdio_filebuf extension and 
+ *  VC's basic_filebuf implementation.
+ *  This file buffer provides extensions for working with standard C FILE*'s 
+ *  and POSIX file descriptors for platforms that support this.
+*/
+namespace
+{
+#if LL_WINDOWS
+typedef std::filebuf						_Myfb;
+#else
+typedef  __gnu_cxx::stdio_filebuf< char >	_Myfb;
+typedef std::__c_file						_Filet;
+#endif /* LL_WINDOWS */
+}
 
-#if USE_LLFILESTREAMS
-
-class LL_COMMON_API llifstream	:	public	std::basic_istream < char , std::char_traits < char > >
+class LL_COMMON_API llstdio_filebuf : public _Myfb
 {
-	// input stream associated with a C stream
 public:
-	typedef std::basic_ifstream<char,std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf<char,std::char_traits< char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits< char > > _Myios;
-
-	llifstream()
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
+	/**
+	 * deferred initialization / destruction
+	*/
+	llstdio_filebuf() : _Myfb() {}
+	virtual ~llstdio_filebuf() {} 
+
+	/**
+	 *  @param  f  An open @c FILE*.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *                Defaults to system's @c BUFSIZ.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  C @c FILE*.  The @c FILE* will not be automatically closed when the
+	 *  stdio_filebuf is closed/destroyed.
+	*/
+	llstdio_filebuf(_Filet* __f, std::ios_base::openmode __mode,
+		    //size_t __size = static_cast<size_t>(BUFSIZ)) :
+		    size_t __size = static_cast<size_t>(1)) :
+#if LL_WINDOWS
+		_Myfb(__f) {}
+#else
+		_Myfb(__f, __mode, __size) {}
+#endif
 
-	explicit llifstream(const std::string& _Filename,
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);
-
-	explicit llifstream(_Filet *_File)
-		: std::basic_istream<char,std::char_traits< char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-	virtual ~llifstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
-	bool is_open() const;
-	void open(const std::string& _Filename,	/* Flawfinder: ignore */
-		ios_base::openmode _Mode = ios_base::in,
-		int _Prot = (int)ios_base::_Openprot);	
-	void close();
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  s  The name of the file.
+	 *  @param  mode  The open mode flags.
+	 *  @return  @c this on success, NULL on failure
+	 *
+	 *  If a file is already open, this function immediately fails.
+	 *  Otherwise it tries to open the file named @a s using the flags
+	 *  given in @a mode.
+	*/
+	//llstdio_filebuf* open(const char *_Filename,
+	//		std::ios_base::openmode _Mode);
+
+	/**
+	 *  @param  fd  An open file descriptor.
+	 *  @param  mode  Same meaning as in a standard filebuf.
+	 *  @param  size  Optimal or preferred size of internal buffer, in chars.
+	 *
+	 *  This constructor associates a file stream buffer with an open
+	 *  POSIX file descriptor. The file descriptor will be automatically
+	 *  closed when the stdio_filebuf is closed/destroyed.
+	*/
+#if !LL_WINDOWS
+	llstdio_filebuf(int __fd, std::ios_base::openmode __mode,
+		//size_t __size = static_cast<size_t>(BUFSIZ)) :
+		size_t __size = static_cast<size_t>(1)) :
+		_Myfb(__fd, __mode, __size) {}
+#endif
 
-private:
-	_Myfb* _Filebuffer;	// the file buffer
-	bool _ShouldClose;
+// *TODO: Seek the underlying c stream for better cross-platform compatibility?
+#if !LL_WINDOWS
+protected:
+	/** underflow() and uflow() functions are called to get the next
+	 *  character from the real input source when the buffer is empty.
+	 *  Buffered input uses underflow()
+	*/
+	/*virtual*/ int_type underflow();
+
+	/*  Convert internal byte sequence to external, char-based
+	 * sequence via codecvt.
+	*/
+	bool _convert_to_external(char_type*, std::streamsize);
+
+	/** The overflow() function is called to transfer characters to the
+	 *  real output destination when the buffer is full. A call to
+	 *  overflow(c) outputs the contents of the buffer plus the
+	 *  character c.
+	 *  Consume some sequence of the characters in the pending sequence.
+	*/
+	/*virtual*/ int_type overflow(int_type __c = traits_type::eof());
+
+	/** sync() flushes the underlying @c FILE* stream.
+	*/
+	/*virtual*/ int sync();
+
+	std::streamsize xsgetn(char_type*, std::streamsize);
+	std::streamsize xsputn(char_type*, std::streamsize);
+#endif
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::basic_ostream< char , std::char_traits < char > >
+/**
+ *  @brief  Controlling input for files.
+ *
+ *  This class supports reading from named files, using the inherited
+ *  functions from std::basic_istream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llifstream	:	public	std::istream
 {
+	// input stream associated with a C stream
 public:
-	typedef std::basic_ostream< char , std::char_traits < char > > _Myt;
-	typedef std::basic_filebuf< char , std::char_traits < char > > _Myfb;
-	typedef std::basic_ios<char,std::char_traits < char > > _Myios;
-
-	llofstream()
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),_Filebuffer(NULL),_ShouldClose(false)
-	{	// construct unopened
-	}
-
-	explicit llofstream(const std::string& _Filename,
-		std::ios_base::openmode _Mode = ios_base::out,
-		int _Prot = (int)std::ios_base::_Openprot);
-	
-
-	explicit llofstream(_Filet *_File)
-		: std::basic_ostream<char,std::char_traits < char > >(NULL,true),
-			_Filebuffer(new _Myfb(_File)),//_File)
-			_ShouldClose(false)
-	{	// construct with specified C stream
-	}
-
-	virtual ~llofstream();
-
-	_Myfb *rdbuf() const
-	{	// return pointer to file buffer
-		return _Filebuffer;
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llifstream();
+
+	/**
+	 *  @brief  Create an input file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+     *  @c ios_base::in is automatically included in @a mode.
+	*/
+	explicit llifstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+	explicit llifstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llifstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llifstream(int __fd,
+			ios_base::openmode _Mode = ios_base::in,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llifstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
 	bool is_open() const;
 
-	void open(const std::string& _Filename,ios_base::openmode _Mode = ios_base::out,int _Prot = (int)ios_base::_Openprot);	/* Flawfinder: ignore */
-
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|in).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::in)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::in);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
 	void close();
 
 private:
-	_Myfb *_Filebuffer;	// the file buffer
-	bool _ShouldClose;
-};
-
-
-
-#else
-//Use standard file streams on non windows platforms
-//#define	llifstream	std::ifstream
-//#define	llofstream	std::ofstream
-
-class LL_COMMON_API llifstream	:	public	std::ifstream
-{
-public:
-	llifstream() : std::ifstream()
-	{
-	}
-
-	explicit llifstream(const std::string& _Filename, std::_Ios_Openmode _Mode = in)
-		: std::ifstream(_Filename.c_str(), _Mode)
-	{
-	}
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = in)	/* Flawfinder: ignore */
-	{
-		std::ifstream::open(_Filename.c_str(), _Mode);
-	}
+	llstdio_filebuf _M_filebuf;
 };
 
 
-class LL_COMMON_API llofstream	:	public	std::ofstream
+/**
+ *  @brief  Controlling output for files.
+ *
+ *  This class supports writing to named files, using the inherited
+ *  functions from std::basic_ostream.  To control the associated
+ *  sequence, an instance of std::basic_filebuf (or a platform-specific derivative)
+ *  which allows construction using a pre-exisintg file stream buffer. 
+ *  We refer to this std::basic_filebuf (or derivative) as @c sb.
+*/
+class LL_COMMON_API llofstream	:	public	std::ostream
 {
 public:
-	llofstream() : std::ofstream()
-	{
-	}
+	// Constructors:
+	/**
+	 *  @brief  Default constructor.
+	 *
+	 *  Initializes @c sb using its default constructor, and passes
+	 *  @c &sb to the base class initializer.  Does not open any files
+	 *  (you haven't given it a filename to open).
+	*/
+	llofstream();
+
+	/**
+	 *  @brief  Create an output file stream.
+	 *  @param  Filename  String specifying the filename.
+	 *  @param  Mode  Open file in specified mode (see std::ios_base).
+	 *
+	 *  @c ios_base::out|ios_base::trunc is automatically included in
+	 *  @a mode.
+	*/
+	explicit llofstream(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+	explicit llofstream(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Create a stream using an open c file stream.
+	 *  @param  File  An open @c FILE*.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+	explicit llofstream(_Filet *_File,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+
+	/**
+	 *  @brief  Create a stream using an open file descriptor.
+	 *  @param  fd    An open file descriptor.
+        @param  Mode  Same meaning as in a standard filebuf.
+        @param  Size  Optimal or preferred size of internal buffer, in chars.
+                      Defaults to system's @c BUFSIZ.
+	*/
+#if !LL_WINDOWS
+	explicit llofstream(int __fd,
+			ios_base::openmode _Mode = ios_base::out,
+			//size_t _Size = static_cast<size_t>(BUFSIZ));
+			size_t _Size = static_cast<size_t>(1));
+#endif
 
-	explicit llofstream(const std::string& _Filename, std::_Ios_Openmode _Mode = out)
-		: std::ofstream(_Filename.c_str(), _Mode)
-	{
-	}
+	/**
+	 *  @brief  The destructor does nothing.
+	 *
+	 *  The file is closed by the filebuf object, not the formatting
+	 *  stream.
+	*/
+	virtual ~llofstream() {}
+
+	// Members:
+	/**
+	 *  @brief  Accessing the underlying buffer.
+	 *  @return  The current basic_filebuf buffer.
+	 *
+	 *  This hides both signatures of std::basic_ios::rdbuf().
+	*/
+	llstdio_filebuf* rdbuf() const
+	{ return const_cast<llstdio_filebuf*>(&_M_filebuf); }
+
+	/**
+	 *  @brief  Wrapper to test for an open file.
+	 *  @return  @c rdbuf()->is_open()
+	*/
+	bool is_open() const;
 
-	void open(const std::string& _Filename, std::_Ios_Openmode _Mode = out)	/* Flawfinder: ignore */
-	{
-		std::ofstream::open(_Filename.c_str(), _Mode);
-	}
+	/**
+	 *  @brief  Opens an external file.
+	 *  @param  Filename  The name of the file.
+	 *  @param  Node  The open mode flags.
+	 *
+	 *  Calls @c llstdio_filebuf::open(s,mode|out).  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void open(const std::string& _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc)
+	{ open(_Filename.c_str(), _Mode); }
+	void open(const char* _Filename,
+			ios_base::openmode _Mode = ios_base::out|ios_base::trunc);
+
+	/**
+	 *  @brief  Close the file.
+	 *
+	 *  Calls @c llstdio_filebuf::close().  If that function
+	 *  fails, @c failbit is set in the stream's error state.
+	*/
+	void close();
 
+private:
+	llstdio_filebuf _M_filebuf;
 };
 
-#endif
 
 /**
  * @breif filesize helpers.
diff --git a/indra/llinventory/llinventory.cpp b/indra/llinventory/llinventory.cpp
index fbf23bc3f09a760eee88c85f29cf41df9a1a5352..2dbc3310368d3cbf8f601c995627f76a64bb1f96 100644
--- a/indra/llinventory/llinventory.cpp
+++ b/indra/llinventory/llinventory.cpp
@@ -824,7 +824,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
 		}
 		else if(0 == strcmp("permissions", keyword))
 		{
-			success = mPermissions.importLegacyStream(input_stream);
+			success = mPermissions.importStream(input_stream);
 		}
 		else if(0 == strcmp("sale_info", keyword))
 		{
@@ -834,7 +834,7 @@ BOOL LLInventoryItem::importLegacyStream(std::istream& input_stream)
 			// should pick up the vast majority of the tasks.
 			BOOL has_perm_mask = FALSE;
 			U32 perm_mask = 0;
-			success = mSaleInfo.importLegacyStream(input_stream, has_perm_mask, perm_mask);
+			success = mSaleInfo.importStream(input_stream, has_perm_mask, perm_mask);
 			if(has_perm_mask)
 			{
 				if(perm_mask == PERM_NONE)
@@ -950,7 +950,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu
 	output_stream << "\t\titem_id\t" << uuid_str << "\n";
 	mParentUUID.toString(uuid_str);
 	output_stream << "\t\tparent_id\t" << uuid_str << "\n";
-	mPermissions.exportLegacyStream(output_stream);
+	mPermissions.exportStream(output_stream);
 
 	// Check for permissions to see the asset id, and if so write it
 	// out as an asset id. Otherwise, apply our cheesy encryption.
@@ -984,7 +984,7 @@ BOOL LLInventoryItem::exportLegacyStream(std::ostream& output_stream, BOOL inclu
 	std::string buffer;
 	buffer = llformat( "\t\tflags\t%08x\n", mFlags);
 	output_stream << buffer;
-	mSaleInfo.exportLegacyStream(output_stream);
+	mSaleInfo.exportStream(output_stream);
 	output_stream << "\t\tname\t" << mName.c_str() << "|\n";
 	output_stream << "\t\tdesc\t" << mDescription.c_str() << "|\n";
 	output_stream << "\t\tcreation_date\t" << mCreationDate << "\n";
diff --git a/indra/llinventory/llpermissions.cpp b/indra/llinventory/llpermissions.cpp
index 7e013de11a1b90f39d7c781619fe550433dbe250..34354e3e8c5c73a38241cd0239924735c6e4d698 100644
--- a/indra/llinventory/llpermissions.cpp
+++ b/indra/llinventory/llpermissions.cpp
@@ -572,143 +572,17 @@ void LLPermissions::unpackMessage(LLMessageSystem* msg, const char* block, S32 b
 
 BOOL LLPermissions::importFile(LLFILE* fp)
 {
-	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
-	const S32 BUFSIZE = 16384;
-
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[BUFSIZE];	/* Flawfinder: ignore */
-	char keyword[256];	/* Flawfinder: ignore */
-	char valuestr[256];	/* Flawfinder: ignore */
-	char uuid_str[256];	/* Flawfinder: ignore */
-	U32 mask;
-
-	keyword[0]  = '\0';
-	valuestr[0] = '\0';
-
-	while (!feof(fp))
-	{
-		if (fgets(buffer, BUFSIZE, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-		
-		sscanf( /* Flawfinder: ignore */
-			buffer,
-			" %255s %255s",
-			keyword, valuestr);
-		if (!strcmp("{", keyword))
-		{
-			continue;
-		}
-		if (!strcmp("}",keyword))
-		{
-			break;
-		}
-		else if (!strcmp("creator_mask", keyword))
-		{
-			// legacy support for "creator" masks
-			sscanf(valuestr, "%x", &mask);
-			mMaskBase = mask;
-			fixFairUse();
-		}
-		else if (!strcmp("base_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskBase = mask;
-			//fixFairUse();
-		}
-		else if (!strcmp("owner_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskOwner = mask;
-		}
-		else if (!strcmp("group_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskGroup = mask;
-		}
-		else if (!strcmp("everyone_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskEveryone = mask;
-		}
-		else if (!strcmp("next_owner_mask", keyword))
-		{
-			sscanf(valuestr, "%x", &mask);
-			mMaskNextOwner = mask;
-		}
-		else if (!strcmp("creator_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mCreator.set(uuid_str);
-		}
-		else if (!strcmp("owner_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mOwner.set(uuid_str);
-		}
-		else if (!strcmp("last_owner_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mLastOwner.set(uuid_str);
-		}
-		else if (!strcmp("group_id", keyword))
-		{
-			sscanf(valuestr, "%255s", uuid_str); /* Flawfinder: ignore */
-			mGroup.set(uuid_str);
-		}
-		else if (!strcmp("group_owned", keyword))
-		{
-			sscanf(valuestr, "%d", &mask);
-			if(mask) mIsGroupOwned = true;
-			else mIsGroupOwned = false;
-		}
-		else
-		{
-			llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
-		}
-	}
-	fix();
-	return TRUE;
+	llifstream ifs(fp);
+	return importStream(ifs);
 }
 
-
 BOOL LLPermissions::exportFile(LLFILE* fp) const
 {
-	std::string uuid_str;
-
-	fprintf(fp, "\tpermissions 0\n");
-	fprintf(fp, "\t{\n");
-
-	fprintf(fp, "\t\tbase_mask\t%08x\n",		mMaskBase);
-	fprintf(fp, "\t\towner_mask\t%08x\n",		mMaskOwner);
-	fprintf(fp, "\t\tgroup_mask\t%08x\n",		mMaskGroup);
-	fprintf(fp, "\t\teveryone_mask\t%08x\n",	mMaskEveryone);
-	fprintf(fp, "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner);
-
-	mCreator.toString(uuid_str);
-	fprintf(fp, "\t\tcreator_id\t%s\n",			uuid_str.c_str());
-
-	mOwner.toString(uuid_str);
-	fprintf(fp, "\t\towner_id\t%s\n",			uuid_str.c_str());
-
-	mLastOwner.toString(uuid_str);
-	fprintf(fp, "\t\tlast_owner_id\t%s\n",		uuid_str.c_str());
-
-	mGroup.toString(uuid_str);
-	fprintf(fp, "\t\tgroup_id\t%s\n",			uuid_str.c_str());
-
-	if(mIsGroupOwned)
-	{
-		fprintf(fp, "\t\tgroup_owned\t1\n");
-	}
-	fprintf(fp,"\t}\n");
-	return TRUE;
+	llofstream ofs(fp);
+	return exportStream(ofs);
 }
 
-
-BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
+BOOL LLPermissions::importStream(std::istream& input_stream)
 {
 	init(LLUUID::null, LLUUID::null, LLUUID::null, LLUUID::null);
 	const S32 BUFSIZE = 16384;
@@ -727,6 +601,18 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
 	while (input_stream.good())
 	{
 		input_stream.getline(buffer, BUFSIZE);
+		if (input_stream.eof())
+		{
+			llwarns << "Bad permissions: early end of input stream"
+					<< llendl;
+			return FALSE;
+		}
+		if (input_stream.fail())
+		{
+			llwarns << "Bad permissions: failed to read from input stream"
+					<< llendl;
+			return FALSE;
+		}
 		sscanf( /* Flawfinder: ignore */
 			buffer,
 			" %255s %255s",
@@ -800,7 +686,8 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
 		}
 		else
 		{
-			llinfos << "unknown keyword " << keyword << " in permissions import" << llendl;
+			llwarns << "unknown keyword " << keyword 
+					<< " in permissions import" << llendl;
 		}
 	}
 	fix();
@@ -808,36 +695,26 @@ BOOL LLPermissions::importLegacyStream(std::istream& input_stream)
 }
 
 
-BOOL LLPermissions::exportLegacyStream(std::ostream& output_stream) const
+BOOL LLPermissions::exportStream(std::ostream& output_stream) const
 {
-	std::string uuid_str;
-
+	if (!output_stream.good()) return FALSE;
 	output_stream <<  "\tpermissions 0\n";
 	output_stream <<  "\t{\n";
 
-	std::string buffer;
-	buffer = llformat( "\t\tbase_mask\t%08x\n",		mMaskBase);
-	output_stream << buffer;
-	buffer = llformat( "\t\towner_mask\t%08x\n",		mMaskOwner);
-	output_stream << buffer;
-	buffer = llformat( "\t\tgroup_mask\t%08x\n",		mMaskGroup);
-	output_stream << buffer;
-	buffer = llformat( "\t\teveryone_mask\t%08x\n",	mMaskEveryone);
-	output_stream << buffer;
-	buffer = llformat( "\t\tnext_owner_mask\t%08x\n",	mMaskNextOwner);
-	output_stream << buffer;
-
-	mCreator.toString(uuid_str);
-	output_stream <<  "\t\tcreator_id\t" << uuid_str << "\n";
-
-	mOwner.toString(uuid_str);
-	output_stream <<  "\t\towner_id\t" << uuid_str << "\n";
-
-	mLastOwner.toString(uuid_str);
-	output_stream <<  "\t\tlast_owner_id\t" << uuid_str << "\n";
-
-	mGroup.toString(uuid_str);
-	output_stream <<  "\t\tgroup_id\t" << uuid_str << "\n";
+	char prev_fill = output_stream.fill('0');
+	output_stream << std::hex;
+	output_stream << "\t\tbase_mask\t" << std::setw(8) << mMaskBase << "\n";
+	output_stream << "\t\towner_mask\t" << std::setw(8) << mMaskOwner << "\n";
+	output_stream << "\t\tgroup_mask\t" << std::setw(8) << mMaskGroup << "\n";
+	output_stream << "\t\teveryone_mask\t" << std::setw(8) << mMaskEveryone << "\n";
+	output_stream << "\t\tnext_owner_mask\t" << std::setw(8) << mMaskNextOwner << "\n";
+	output_stream << std::dec;
+	output_stream.fill(prev_fill);
+
+	output_stream <<  "\t\tcreator_id\t" << mCreator << "\n";
+	output_stream <<  "\t\towner_id\t" << mOwner << "\n";
+	output_stream <<  "\t\tlast_owner_id\t" << mLastOwner << "\n";
+	output_stream <<  "\t\tgroup_id\t" << mGroup << "\n";
 
 	if(mIsGroupOwned)
 	{
diff --git a/indra/llinventory/llpermissions.h b/indra/llinventory/llpermissions.h
index 3ecc922370a3f3873f644424b8d1854912a0a453..7d3a68d3533cf5aa8cd8b93054235ce306cae901 100644
--- a/indra/llinventory/llpermissions.h
+++ b/indra/llinventory/llpermissions.h
@@ -316,8 +316,8 @@ class LLPermissions : public LLReflective
 	BOOL	importFile(LLFILE* fp);
 	BOOL	exportFile(LLFILE* fp) const;
 
-	BOOL	importLegacyStream(std::istream& input_stream);
-	BOOL	exportLegacyStream(std::ostream& output_stream) const;
+	BOOL	importStream(std::istream& input_stream);
+	BOOL	exportStream(std::ostream& output_stream) const;
 
 	bool operator==(const LLPermissions &rhs) const;
 	bool operator!=(const LLPermissions &rhs) const;
diff --git a/indra/llinventory/llsaleinfo.cpp b/indra/llinventory/llsaleinfo.cpp
index dd408a8efea74ac755d698ecbbbadbb91c9233a3..a8296679337b36e984f2f15d4cac049d1f9187ad 100644
--- a/indra/llinventory/llsaleinfo.cpp
+++ b/indra/llinventory/llsaleinfo.cpp
@@ -81,15 +81,13 @@ U32 LLSaleInfo::getCRC32() const
 
 BOOL LLSaleInfo::exportFile(LLFILE* fp) const
 {
-	fprintf(fp, "\tsale_info\t0\n\t{\n");
-	fprintf(fp, "\t\tsale_type\t%s\n", lookup(mSaleType));
-	fprintf(fp, "\t\tsale_price\t%d\n", mSalePrice);
-	fprintf(fp,"\t}\n");
-	return TRUE;
+	llofstream ofs(fp);
+	return exportStream(ofs);
 }
 
-BOOL LLSaleInfo::exportLegacyStream(std::ostream& output_stream) const
+BOOL LLSaleInfo::exportStream(std::ostream& output_stream) const
 {
+	if (!output_stream.good()) return FALSE;
 	output_stream << "\tsale_info\t0\n\t{\n";
 	output_stream << "\t\tsale_type\t" << lookup(mSaleType) << "\n";
 	output_stream << "\t\tsale_price\t" << mSalePrice << "\n";
@@ -134,80 +132,39 @@ bool LLSaleInfo::fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask)
 
 BOOL LLSaleInfo::importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask)
 {
-	has_perm_mask = FALSE;
-
-	// *NOTE: Changing the buffer size will require changing the scanf
-	// calls below.
-	char buffer[MAX_STRING];	/* Flawfinder: ignore */
-	char keyword[MAX_STRING];	/* Flawfinder: ignore */
-	char valuestr[MAX_STRING];	/* Flawfinder: ignore */
-	BOOL success = TRUE;
-
-	keyword[0] = '\0';
-	valuestr[0] = '\0';
-	while(success && (!feof(fp)))
-	{
-		if (fgets(buffer, MAX_STRING, fp) == NULL)
-		{
-			buffer[0] = '\0';
-		}
-
-		sscanf(	/* Flawfinder: ignore */
-			buffer,
-			" %254s %254s",
-			keyword, valuestr);
-		if(!keyword[0])
-		{
-			continue;
-		}
-		if(0 == strcmp("{",keyword))
-		{
-			continue;
-		}
-		if(0 == strcmp("}", keyword))
-		{
-			break;
-		}
-		else if(0 == strcmp("sale_type", keyword))
-		{
-			mSaleType = lookup(valuestr);
-		}
-		else if(0 == strcmp("sale_price", keyword))
-		{
-			sscanf(valuestr, "%d", &mSalePrice);
-			mSalePrice = llclamp(mSalePrice, 0, S32_MAX);
-		}
-		else if (!strcmp("perm_mask", keyword))
-		{
-			//llinfos << "found deprecated keyword perm_mask" << llendl;
-			has_perm_mask = TRUE;
-			sscanf(valuestr, "%x", &perm_mask);
-		}
-		else
-		{
-			llwarns << "unknown keyword '" << keyword
-					<< "' in sale info import" << llendl;
-		}
-	}
-	return success;
+	llifstream ifs(fp);
+	return importStream(ifs, has_perm_mask, perm_mask);
 }
 
-BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
+BOOL LLSaleInfo::importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask)
 {
 	has_perm_mask = FALSE;
 
+	const S32 BUFSIZE = 16384;
+
 	// *NOTE: Changing the buffer size will require changing the scanf
 	// calls below.
-	char buffer[MAX_STRING];	/* Flawfinder: ignore */
-	char keyword[MAX_STRING];	/* Flawfinder: ignore */
-	char valuestr[MAX_STRING];	/* Flawfinder: ignore */
-	BOOL success = TRUE;
+	char buffer[BUFSIZE];	/* Flawfinder: ignore */
+	char keyword[255];	/* Flawfinder: ignore */
+	char valuestr[255];	/* Flawfinder: ignore */
 
 	keyword[0] = '\0';
 	valuestr[0] = '\0';
-	while(success && input_stream.good())
+	while(input_stream.good())
 	{
 		input_stream.getline(buffer, MAX_STRING);
+		if (input_stream.eof())
+		{
+			llwarns << "Bad sale info: early end of input stream"
+					<< llendl;
+			return FALSE;
+		}
+		if (input_stream.fail())
+		{
+			llwarns << "Bad sale info: failed to read from input stream"
+					<< llendl;
+			return FALSE;
+		}
 		sscanf(	/* Flawfinder: ignore */
 			buffer,
 			" %254s %254s",
@@ -245,7 +202,7 @@ BOOL LLSaleInfo::importLegacyStream(std::istream& input_stream, BOOL& has_perm_m
 					<< "' in sale info import" << llendl;
 		}
 	}
-	return success;
+	return TRUE;
 }
 
 void LLSaleInfo::setSalePrice(S32 price)
diff --git a/indra/llinventory/llsaleinfo.h b/indra/llinventory/llsaleinfo.h
index 4e98ccf6ff4d2e3f88d223aa4f184bd99ad90e7b..f7f3f9269c1d3a9046d320c9618c1fa3e2b64a89 100644
--- a/indra/llinventory/llsaleinfo.h
+++ b/indra/llinventory/llsaleinfo.h
@@ -89,11 +89,11 @@ class LLSaleInfo
 	BOOL exportFile(LLFILE* fp) const;
 	BOOL importFile(LLFILE* fp, BOOL& has_perm_mask, U32& perm_mask);
 
-	BOOL exportLegacyStream(std::ostream& output_stream) const;
+	BOOL exportStream(std::ostream& output_stream) const;
 	LLSD asLLSD() const;
 	operator LLSD() const { return asLLSD(); }
 	bool fromLLSD(const LLSD& sd, BOOL& has_perm_mask, U32& perm_mask);
-	BOOL importLegacyStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
+	BOOL importStream(std::istream& input_stream, BOOL& has_perm_mask, U32& perm_mask);
 
 	LLSD packMessage() const;
 	void unpackMessage(LLSD sales);
diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp
index 0b56b3889c90eed03253981e3bc18ed81496ed30..e28e3157d208a483cdd6162287f14cd47518a23e 100644
--- a/indra/llrender/llgl.cpp
+++ b/indra/llrender/llgl.cpp
@@ -58,13 +58,8 @@
 BOOL gDebugSession = FALSE;
 BOOL gDebugGL = FALSE;
 BOOL gClothRipple = FALSE;
-BOOL gHeadlessClient = FALSE;
 BOOL gGLActive = FALSE;
 
-static const std::string HEADLESS_VENDOR_STRING("Linden Lab");
-static const std::string HEADLESS_RENDERER_STRING("Headless");
-static const std::string HEADLESS_VERSION_STRING("1.0");
-
 std::ofstream gFailLog;
 
 #if GL_ARB_debug_output
@@ -789,19 +784,9 @@ void LLGLManager::setToDebugGPU()
 
 void LLGLManager::getGLInfo(LLSD& info)
 {
-	if (gHeadlessClient)
-	{
-		info["GLInfo"]["GLVendor"] = HEADLESS_VENDOR_STRING;
-		info["GLInfo"]["GLRenderer"] = HEADLESS_RENDERER_STRING;
-		info["GLInfo"]["GLVersion"] = HEADLESS_VERSION_STRING;
-		return;
-	}
-	else
-	{
-		info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
-		info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
-		info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
-	}
+	info["GLInfo"]["GLVendor"] = std::string((const char *)glGetString(GL_VENDOR));
+	info["GLInfo"]["GLRenderer"] = std::string((const char *)glGetString(GL_RENDERER));
+	info["GLInfo"]["GLVersion"] = std::string((const char *)glGetString(GL_VERSION));
 
 #if !LL_MESA_HEADLESS
 	std::string all_exts = ll_safe_string((const char *)gGLHExts.mSysExts);
@@ -818,18 +803,9 @@ std::string LLGLManager::getGLInfoString()
 {
 	std::string info_str;
 
-	if (gHeadlessClient)
-	{
-		info_str += std::string("GL_VENDOR      ") + HEADLESS_VENDOR_STRING + std::string("\n");
-		info_str += std::string("GL_RENDERER    ") + HEADLESS_RENDERER_STRING + std::string("\n");
-		info_str += std::string("GL_VERSION     ") + HEADLESS_VERSION_STRING + std::string("\n");
-	}
-	else
-	{
-		info_str += std::string("GL_VENDOR      ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
-		info_str += std::string("GL_RENDERER    ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
-		info_str += std::string("GL_VERSION     ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
-	}
+	info_str += std::string("GL_VENDOR      ") + ll_safe_string((const char *)glGetString(GL_VENDOR)) + std::string("\n");
+	info_str += std::string("GL_RENDERER    ") + ll_safe_string((const char *)glGetString(GL_RENDERER)) + std::string("\n");
+	info_str += std::string("GL_VERSION     ") + ll_safe_string((const char *)glGetString(GL_VERSION)) + std::string("\n");
 
 #if !LL_MESA_HEADLESS 
 	std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
@@ -842,18 +818,9 @@ std::string LLGLManager::getGLInfoString()
 
 void LLGLManager::printGLInfoString()
 {
-	if (gHeadlessClient)
-	{
-		LL_INFOS("RenderInit") << "GL_VENDOR:     " << HEADLESS_VENDOR_STRING << LL_ENDL;
-		LL_INFOS("RenderInit") << "GL_RENDERER:   " << HEADLESS_RENDERER_STRING << LL_ENDL;
-		LL_INFOS("RenderInit") << "GL_VERSION:    " << HEADLESS_VERSION_STRING << LL_ENDL;
-	}
-	else
-	{
-		LL_INFOS("RenderInit") << "GL_VENDOR:     " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
-		LL_INFOS("RenderInit") << "GL_RENDERER:   " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
-		LL_INFOS("RenderInit") << "GL_VERSION:    " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
-	}
+	LL_INFOS("RenderInit") << "GL_VENDOR:     " << ((const char *)glGetString(GL_VENDOR)) << LL_ENDL;
+	LL_INFOS("RenderInit") << "GL_RENDERER:   " << ((const char *)glGetString(GL_RENDERER)) << LL_ENDL;
+	LL_INFOS("RenderInit") << "GL_VERSION:    " << ((const char *)glGetString(GL_VERSION)) << LL_ENDL;
 
 #if !LL_MESA_HEADLESS
 	std::string all_exts= ll_safe_string(((const char *)gGLHExts.mSysExts));
@@ -865,14 +832,7 @@ void LLGLManager::printGLInfoString()
 std::string LLGLManager::getRawGLString()
 {
 	std::string gl_string;
-	if (gHeadlessClient)
-	{
-		gl_string = HEADLESS_VENDOR_STRING + " " + HEADLESS_RENDERER_STRING;
-	}
-	else
-	{
-		gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
-	}
+	gl_string = ll_safe_string((char*)glGetString(GL_VENDOR)) + " " + ll_safe_string((char*)glGetString(GL_RENDERER));
 	return gl_string;
 }
 
@@ -1991,7 +1951,10 @@ LLGLState::LLGLState(LLGLenum state, S32 enabled) :
 	if (mState)
 	{
 		mWasEnabled = sStateMap[state];
-		llassert(mWasEnabled == glIsEnabled(state));
+		if (gDebugGL)
+		{
+			llassert(mWasEnabled == glIsEnabled(state));
+		}
 		setEnabled(enabled);
 		stop_glerror();
 	}
diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h
index 964495a3abce301eae301d196b1e3d917d0820db..d77c3ede068c4e19e75877d949398060e9554129 100644
--- a/indra/llrender/llgl.h
+++ b/indra/llrender/llgl.h
@@ -453,7 +453,6 @@ void init_glstates();
 void parse_gl_version( S32* major, S32* minor, S32* release, std::string* vendor_specific, std::string* version_string );
 
 extern BOOL gClothRipple;
-extern BOOL gHeadlessClient;
 extern BOOL gGLActive;
 
 // Deal with changing glext.h definitions for newer SDK versions, specifically
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index a4d7872ec25e0091152a4da7de8e60f2df09e5ed..d561f63544b1f2faa07dfa3e2c0e29d035e135b3 100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -1222,7 +1222,6 @@ void LLImageGL::setManualImage(U32 target, S32 miplevel, S32 intformat, S32 widt
 //the texture is assiciate with some image by calling glTexImage outside LLImageGL
 BOOL LLImageGL::createGLTexture()
 {
-	if (gHeadlessClient) return FALSE;
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
@@ -1252,7 +1251,6 @@ BOOL LLImageGL::createGLTexture()
 
 BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S32 usename/*=0*/, BOOL to_create, S32 category)
 {
-	if (gHeadlessClient) return FALSE;
 	if (gGLManager.mIsDisabled)
 	{
 		llwarns << "Trying to create a texture while GL is disabled!" << llendl;
diff --git a/indra/llwindow/llwindow.cpp b/indra/llwindow/llwindow.cpp
index d83278d87588abf63e51ded79bc01892231c79e7..9e4ad310c74a324836d045b6b40dbfa3588d484f 100644
--- a/indra/llwindow/llwindow.cpp
+++ b/indra/llwindow/llwindow.cpp
@@ -388,38 +388,28 @@ LLWindow* LLWindowManager::createWindow(
 	BOOL fullscreen, 
 	BOOL clearBg,
 	BOOL disable_vsync,
-	BOOL use_gl,
 	BOOL ignore_pixel_depth,
 	U32 fsaa_samples)
 {
 	LLWindow* new_window;
 
-	if (use_gl)
-	{
 #if LL_MESA_HEADLESS
-		new_window = new LLWindowMesaHeadless(callbacks,
-			title, name, x, y, width, height, flags, 
-			fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
+	new_window = new LLWindowMesaHeadless(callbacks,
+		title, name, x, y, width, height, flags, 
+		fullscreen, clearBg, disable_vsync, ignore_pixel_depth);
 #elif LL_SDL
-		new_window = new LLWindowSDL(callbacks,
-			title, x, y, width, height, flags, 
-			fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+	new_window = new LLWindowSDL(callbacks,
+		title, x, y, width, height, flags, 
+		fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples);
 #elif LL_WINDOWS
-		new_window = new LLWindowWin32(callbacks,
-			title, name, x, y, width, height, flags, 
-			fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+	new_window = new LLWindowWin32(callbacks,
+		title, name, x, y, width, height, flags, 
+		fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples);
 #elif LL_DARWIN
-		new_window = new LLWindowMacOSX(callbacks,
-			title, name, x, y, width, height, flags, 
-			fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth, fsaa_samples);
+	new_window = new LLWindowMacOSX(callbacks,
+		title, name, x, y, width, height, flags, 
+		fullscreen, clearBg, disable_vsync, ignore_pixel_depth, fsaa_samples);
 #endif
-	}
-	else
-	{
-		new_window = new LLWindowHeadless(callbacks,
-			title, name, x, y, width, height, flags, 
-			fullscreen, clearBg, disable_vsync, use_gl, ignore_pixel_depth);
-	}
 
 	if (FALSE == new_window->isValid())
 	{
diff --git a/indra/llwindow/llwindow.h b/indra/llwindow/llwindow.h
index 4da87f4e068d64d90f5d039b8e9f3ca0fe890db5..e92b0fd387fbaae64ec0953ee44ea29954a6e4b7 100644
--- a/indra/llwindow/llwindow.h
+++ b/indra/llwindow/llwindow.h
@@ -265,7 +265,6 @@ class LLWindowManager
 		BOOL fullscreen = FALSE,
 		BOOL clearBg = FALSE,
 		BOOL disable_vsync = TRUE,
-		BOOL use_gl = TRUE,
 		BOOL ignore_pixel_depth = FALSE,
 		U32 fsaa_samples = 0);
 	static BOOL destroyWindow(LLWindow* window);
diff --git a/indra/llwindow/llwindowheadless.cpp b/indra/llwindow/llwindowheadless.cpp
index e6e6bc67ff0ee0bc9dbf13c0e22f19a2012f463c..dbdb40f5b999d853af7612903d1fe4c15930aa61 100644
--- a/indra/llwindow/llwindowheadless.cpp
+++ b/indra/llwindow/llwindowheadless.cpp
@@ -35,7 +35,7 @@
 //
 LLWindowHeadless::LLWindowHeadless(LLWindowCallbacks* callbacks, const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
 							 U32 flags,  BOOL fullscreen, BOOL clear_background,
-							 BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
+							 BOOL disable_vsync, BOOL ignore_pixel_depth)
 	: LLWindow(callbacks, fullscreen, flags)
 {
 	// Initialize a headless keyboard.
diff --git a/indra/llwindow/llwindowheadless.h b/indra/llwindow/llwindowheadless.h
index 1f767f4c97d65716942ba819684b4fc217478951..72f9684ca38d5178a007c3f841c8743e71bb2a19 100644
--- a/indra/llwindow/llwindowheadless.h
+++ b/indra/llwindow/llwindowheadless.h
@@ -96,7 +96,7 @@ class LLWindowHeadless : public LLWindow
 		S32 x, S32 y, 
 		S32 width, S32 height,
 		U32 flags,  BOOL fullscreen, BOOL clear_background,
-		BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
+		BOOL disable_vsync, BOOL ignore_pixel_depth);
 	virtual ~LLWindowHeadless();
 
 private:
diff --git a/indra/llwindow/llwindowmacosx.cpp b/indra/llwindow/llwindowmacosx.cpp
index 97637c937fe6efe6e236dab40183113e6e8b177e..413a9df6169ec7bb5149a3f481417dd8fd9212ed 100644
--- a/indra/llwindow/llwindowmacosx.cpp
+++ b/indra/llwindow/llwindowmacosx.cpp
@@ -210,7 +210,7 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 							   const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
 							   S32 height, U32 flags,
 							   BOOL fullscreen, BOOL clearBg,
-							   BOOL disable_vsync, BOOL use_gl,
+							   BOOL disable_vsync,
 							   BOOL ignore_pixel_depth,
 							   U32 fsaa_samples)
 	: LLWindow(NULL, fullscreen, flags)
@@ -228,7 +228,6 @@ LLWindowMacOSX::LLWindowMacOSX(LLWindowCallbacks* callbacks,
 	gKeyboard = new LLKeyboardMacOSX();
 	gKeyboard->setCallbacks(callbacks);
 
-	// Ignore use_gl for now, only used for drones on PC
 	mWindow = NULL;
 	mContext = NULL;
 	mPixelFormat = NULL;
diff --git a/indra/llwindow/llwindowmacosx.h b/indra/llwindow/llwindowmacosx.h
index 52ba8b3bf3eb7f43c7044f08317aacc920887482..4484787a4ef571208e534e193f070e9ebf9c0a72 100644
--- a/indra/llwindow/llwindowmacosx.h
+++ b/indra/llwindow/llwindowmacosx.h
@@ -122,7 +122,7 @@ class LLWindowMacOSX : public LLWindow
 protected:
 	LLWindowMacOSX(LLWindowCallbacks* callbacks,
 		const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags,
-		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
+		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync,
 		BOOL ignore_pixel_depth,
 		U32 fsaa_samples);
 	~LLWindowMacOSX();
diff --git a/indra/llwindow/llwindowmesaheadless.cpp b/indra/llwindow/llwindowmesaheadless.cpp
index 11c22ac94e5b41ab1dc0e6c7131dbf1a57cbb01c..2b668d3fc42a70b8e3568bd4b9a22a492c45b974 100644
--- a/indra/llwindow/llwindowmesaheadless.cpp
+++ b/indra/llwindow/llwindowmesaheadless.cpp
@@ -41,28 +41,25 @@ U16 *gMesaBuffer = NULL;
 LLWindowMesaHeadless::LLWindowMesaHeadless(LLWindowCallbacks* callbacks,
                                            const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
 							 U32 flags,  BOOL fullscreen, BOOL clearBg,
-							 BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth)
+							 BOOL disable_vsync, BOOL ignore_pixel_depth)
 	: LLWindow(callbacks, fullscreen, flags)
 {
-	if (use_gl)
-	{
-		llinfos << "MESA Init" << llendl;
-		mMesaContext = OSMesaCreateContextExt( GL_RGBA, 32, 0, 0, NULL );
-
-		/* Allocate the image buffer */
-		mMesaBuffer = new unsigned char [width * height * 4 * MESA_CHANNEL_SIZE];
-		llassert(mMesaBuffer);
+	llinfos << "MESA Init" << llendl;
+	mMesaContext = OSMesaCreateContextExt( GL_RGBA, 32, 0, 0, NULL );
 
-		gMesaBuffer = (U16*)mMesaBuffer;
+	/* Allocate the image buffer */
+	mMesaBuffer = new unsigned char [width * height * 4 * MESA_CHANNEL_SIZE];
+	llassert(mMesaBuffer);
 
-		/* Bind the buffer to the context and make it current */
-		if (!OSMesaMakeCurrent( mMesaContext, mMesaBuffer, MESA_CHANNEL_TYPE, width, height ))
-		{
-			llerrs << "MESA: OSMesaMakeCurrent failed!" << llendl;
-		}
+	gMesaBuffer = (U16*)mMesaBuffer;
 
-		llverify(gGLManager.initGL());
+	/* Bind the buffer to the context and make it current */
+	if (!OSMesaMakeCurrent( mMesaContext, mMesaBuffer, MESA_CHANNEL_TYPE, width, height ))
+	{
+		llerrs << "MESA: OSMesaMakeCurrent failed!" << llendl;
 	}
+
+	llverify(gGLManager.initGL());
 }
 
 
diff --git a/indra/llwindow/llwindowmesaheadless.h b/indra/llwindow/llwindowmesaheadless.h
index bc8e25ec44618993dda5a272e752ee0a983f73c6..c8d2bf2824072804419b04c67a48c164e3c1292b 100644
--- a/indra/llwindow/llwindowmesaheadless.h
+++ b/indra/llwindow/llwindowmesaheadless.h
@@ -98,7 +98,7 @@ class LLWindowMesaHeadless : public LLWindow
 	LLWindowMesaHeadless(LLWindowCallbacks* callbacks,
                          const std::string& title, const std::string& name, S32 x, S32 y, S32 width, S32 height,
 				  U32 flags,  BOOL fullscreen, BOOL clearBg,
-				  BOOL disable_vsync, BOOL use_gl, BOOL ignore_pixel_depth);
+				  BOOL disable_vsync, BOOL ignore_pixel_depth);
 	~LLWindowMesaHeadless();
 
 private:
diff --git a/indra/llwindow/llwindowsdl.cpp b/indra/llwindow/llwindowsdl.cpp
index 3bf4a48cb6ddcb0e037a2662172f6dd164aabf27..de731df228cf1634ad561fd3bf20cd3d48ac4f90 100644
--- a/indra/llwindow/llwindowsdl.cpp
+++ b/indra/llwindow/llwindowsdl.cpp
@@ -186,7 +186,7 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
 			 const std::string& title, S32 x, S32 y, S32 width,
 			 S32 height, U32 flags,
 			 BOOL fullscreen, BOOL clearBg,
-			 BOOL disable_vsync, BOOL use_gl,
+			 BOOL disable_vsync,
 			 BOOL ignore_pixel_depth, U32 fsaa_samples)
 	: LLWindow(callbacks, fullscreen, flags),
 	  Lock_Display(NULL),
@@ -197,7 +197,6 @@ LLWindowSDL::LLWindowSDL(LLWindowCallbacks* callbacks,
 	gKeyboard->setCallbacks(callbacks);
 	// Note that we can't set up key-repeat until after SDL has init'd video
 
-	// Ignore use_gl for now, only used for drones on PC
 	mWindow = NULL;
 	mNeedsResize = FALSE;
 	mOverrideAspectRatio = 0.f;
diff --git a/indra/llwindow/llwindowsdl.h b/indra/llwindow/llwindowsdl.h
index 4e2a269ea33b4587c903662e55106c05e22d8a8d..91ba73a0acf7413453792a4a0a86ecf33728ecb7 100644
--- a/indra/llwindow/llwindowsdl.h
+++ b/indra/llwindow/llwindowsdl.h
@@ -147,7 +147,7 @@ class LLWindowSDL : public LLWindow
 protected:
 	LLWindowSDL(LLWindowCallbacks* callbacks,
 		const std::string& title, int x, int y, int width, int height, U32 flags,
-		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
+		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync,
 		BOOL ignore_pixel_depth, U32 fsaa_samples);
 	~LLWindowSDL();
 
diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp
index 9a4dd41c4e789c87da8b6118ac99d8b16dca75d9..639ffb9d5655471e332adb54cbaa3901fee4b85e 100644
--- a/indra/llwindow/llwindowwin32.cpp
+++ b/indra/llwindow/llwindowwin32.cpp
@@ -362,7 +362,7 @@ LLWindowWin32::LLWindowWin32(LLWindowCallbacks* callbacks,
 							 const std::string& title, const std::string& name, S32 x, S32 y, S32 width,
 							 S32 height, U32 flags, 
 							 BOOL fullscreen, BOOL clearBg,
-							 BOOL disable_vsync, BOOL use_gl,
+							 BOOL disable_vsync,
 							 BOOL ignore_pixel_depth,
 							 U32 fsaa_samples)
 	: LLWindow(callbacks, fullscreen, flags)
diff --git a/indra/llwindow/llwindowwin32.h b/indra/llwindow/llwindowwin32.h
index 54c9ac4d4d182fd52349e67caeaf56fa92999b5c..aa7e2289bb278cbacc84f7f7509844282f11c5a5 100644
--- a/indra/llwindow/llwindowwin32.h
+++ b/indra/llwindow/llwindowwin32.h
@@ -118,7 +118,7 @@ class LLWindowWin32 : public LLWindow
 protected:
 	LLWindowWin32(LLWindowCallbacks* callbacks,
 		const std::string& title, const std::string& name, int x, int y, int width, int height, U32 flags, 
-		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync, BOOL use_gl,
+		BOOL fullscreen, BOOL clearBg, BOOL disable_vsync,
 		BOOL ignore_pixel_depth, U32 fsaa_samples);
 	~LLWindowWin32();
 
diff --git a/indra/newview/llagent.h b/indra/newview/llagent.h
index f784262e90754fc7bae37d5cc804144508bc7163..ae5efb22870f62f1d4184fe31ad5e5f12ab83c1a 100644
--- a/indra/newview/llagent.h
+++ b/indra/newview/llagent.h
@@ -34,6 +34,7 @@
 #include "llcharacter.h"
 #include "llcoordframe.h"			// for mFrameAgent
 #include "llavatarappearancedefines.h"
+#include "llpermissionsflags.h"
 
 #include <boost/function.hpp>
 #include <boost/shared_ptr.hpp>
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 587435301dac1768a11f685732e8281145c17a0f..ce5180c0d29cdc172360a78020b1f821968fa082 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -1319,11 +1319,11 @@ bool LLAppViewer::mainLoop()
 				// Scan keyboard for movement keys.  Command keys and typing
 				// are handled by windows callbacks.  Don't do this until we're
 				// done initializing.  JC
-				if ((gHeadlessClient || gViewerWindow->getWindow()->getVisible())
+				if (gViewerWindow->getWindow()->getVisible()
 					&& gViewerWindow->getActive()
 					&& !gViewerWindow->getWindow()->getMinimized()
 					&& LLStartUp::getStartupState() == STATE_STARTED
-					&& (gHeadlessClient || !gViewerWindow->getShowProgress())
+					&& !gViewerWindow->getShowProgress()
 					&& !gFocusMgr.focusLocked())
 				{
 					LLMemType mjk(LLMemType::MTYPE_JOY_KEY);
@@ -1371,8 +1371,7 @@ bool LLAppViewer::mainLoop()
 				}
 
 				// Render scene.
-				// *TODO: Should we run display() even during gHeadlessClient?  DK 2011-02-18
-				if (!LLApp::isExiting() && !gHeadlessClient)
+				if (!LLApp::isExiting())
 				{
 					pingMainloopTimeout("Main:Display");
 					gGLActive = TRUE;
@@ -2992,9 +2991,6 @@ bool LLAppViewer::initWindow()
 {
 	LL_INFOS("AppInit") << "Initializing window..." << LL_ENDL;
 
-	// store setting in a global for easy access and modification
-	gHeadlessClient = gSavedSettings.getBOOL("HeadlessClient");
-
 	// always start windowed
 	BOOL ignorePixelDepth = gSavedSettings.getBOOL("IgnorePixelDepth");
 
diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h
index ca12fe204577ae63546c879cd7e0b102731ab60f..580b6dfa7e06ffff4ded45e3247b10a59c9bc8e2 100644
--- a/indra/newview/lllocalbitmaps.h
+++ b/indra/newview/lllocalbitmaps.h
@@ -28,9 +28,11 @@
 #ifndef LL_LOCALBITMAPS_H
 #define LL_LOCALBITMAPS_H
 
+#include "llavatarappearancedefines.h"
 #include "lleventtimer.h"
+#include "llimage.h"
+#include "llpointer.h"
 #include "llwearabletype.h"
-#include "llavatarappearancedefines.h"
 
 class LLScrollListCtrl;
 class LLViewerObject;
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index ab06b1f5aa3bb8593711e6d66c1f530fc4e0be36..561734aaaec3c825c5ee9d73600fd56e4435fe56 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -772,10 +772,6 @@ bool idle_startup()
 				gUserCredential = gLoginHandler.initializeLoginInfo();                 
 				display_startup();
 			}     
-			if (gHeadlessClient)
-			{
-				LL_WARNS("AppInit") << "Waiting at connection box in headless client.  Did you mean to add autologin params?" << LL_ENDL;
-			}
 			// Make sure the process dialog doesn't hide things
 			display_startup();
 			gViewerWindow->setShowProgress(FALSE);
@@ -3507,13 +3503,6 @@ bool process_login_success_response()
 
 void transition_back_to_login_panel(const std::string& emsg)
 {
-	if (gHeadlessClient && gSavedSettings.getBOOL("AutoLogin"))
-	{
-		LL_WARNS("AppInit") << "Failed to login!" << LL_ENDL;
-		LL_WARNS("AppInit") << emsg << LL_ENDL;
-		exit(0);
-	}
-
 	// Bounce back to the login screen.
 	reset_login(); // calls LLStartUp::setStartupState( STATE_LOGIN_SHOW );
 	gSavedSettings.setBOOL("AutoLogin", FALSE);
diff --git a/indra/newview/lltoolmorph.cpp b/indra/newview/lltoolmorph.cpp
index 0d5daf129fc51c471e59ef9242ea34111c4d62ef..148e5a015b199b4397c567cf7f36a6b4b2b3e4b5 100644
--- a/indra/newview/lltoolmorph.cpp
+++ b/indra/newview/lltoolmorph.cpp
@@ -34,6 +34,7 @@
 #include "llaudioengine.h"
 #include "llviewercontrol.h"
 #include "llfontgl.h"
+#include "llwearable.h"
 #include "sound_ids.h"
 #include "v3math.h"
 #include "v3color.h"
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index cc697f8510e85282531f3b3e44b2734308fcd3e9..fae20b1c13ae4c161e8f007e73c9f65d05c92396 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -313,24 +313,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
 	// Logic for forcing window updates if we're in drone mode.
 	//
 
-	// *TODO: Investigate running display() during gHeadlessClient.  See if this early exit is needed DK 2011-02-18
-	if (gHeadlessClient) 
-	{
-#if LL_WINDOWS
-		static F32 last_update_time = 0.f;
-		if ((gFrameTimeSeconds - last_update_time) > 1.f)
-		{
-			InvalidateRect((HWND)gViewerWindow->getPlatformWindow(), NULL, FALSE);
-			last_update_time = gFrameTimeSeconds;
-		}
-#elif LL_DARWIN
-		// MBW -- Do something clever here.
-#endif
-		// Not actually rendering, don't bother.
-		return;
-	}
-
-
 	//
 	// Bail out if we're in the startup state and don't want to try to
 	// render the world.
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index c036fcc114152eb5e39cfba03d006fd1d71c2bf0..e399b45cba00d0b799cc03e09346e9bb7ec5e21c 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1524,7 +1524,6 @@ static LLFastTimer::DeclareTimer FTM_REGION_SHIFT("Region Shift");
 
 void LLViewerObjectList::shiftObjects(const LLVector3 &offset)
 {
-	if (gHeadlessClient) return;
 	// This is called when we shift our origin when we cross region boundaries...
 	// We need to update many object caches, I'll document this more as I dig through the code
 	// cleaning things out...
diff --git a/indra/newview/llviewertexlayer.h b/indra/newview/llviewertexlayer.h
index 95c339a5b00b7c3b025e3dab1cea22644fad8c2d..9df9474eff1bef9735d08caabf82a1c48c45796c 100644
--- a/indra/newview/llviewertexlayer.h
+++ b/indra/newview/llviewertexlayer.h
@@ -28,6 +28,7 @@
 #define LL_VIEWER_TEXLAYER_H
 
 #include "lldynamictexture.h"
+#include "llextendedstatus.h"
 #include "lltexlayer.h"
 
 class LLVOAvatarSelf;
diff --git a/indra/newview/llviewerwearable.cpp b/indra/newview/llviewerwearable.cpp
index 9b1d8d79364de32fd3f6962a5dad55c89c8dc930..f3d9b2c678d7506f56c520fc28d8b9f87d8dc846 100755
--- a/indra/newview/llviewerwearable.cpp
+++ b/indra/newview/llviewerwearable.cpp
@@ -91,13 +91,13 @@ LLViewerWearable::~LLViewerWearable()
 }
 
 // virtual
-LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file, LLAvatarAppearance* avatarp )
+LLWearable::EImportResult LLViewerWearable::importStream( std::istream& input_stream, LLAvatarAppearance* avatarp )
 {
 	// suppress texlayerset updates while wearables are being imported. Layersets will be updated
 	// when the wearables are "worn", not loaded. Note state will be restored when this object is destroyed.
 	LLOverrideBakedTextureUpdate stop_bakes(false);
 
-	LLWearable::EImportResult result = LLWearable::importFile(file, avatarp);
+	LLWearable::EImportResult result = LLWearable::importStream(input_stream, avatarp);
 	if (LLWearable::FAILURE == result) return result;
 	if (LLWearable::BAD_HEADER == result)
 	{
@@ -130,9 +130,6 @@ LLWearable::EImportResult LLViewerWearable::importFile( LLFILE* file, LLAvatarAp
 		}
 	}
 
-	// copy all saved param values to working params
-	revertValues();
-
 	return result;
 }
 
@@ -297,8 +294,8 @@ void LLViewerWearable::setTexturesToDefaults()
 }
 
 
-//static
-const LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index)
+// virtual
+LLUUID LLViewerWearable::getDefaultTextureImageID(ETextureIndex index) const
 {
 	const LLAvatarAppearanceDictionary::TextureEntry *texture_dict = LLAvatarAppearanceDictionary::getInstance()->getTexture(index);
 	const std::string &default_image_name = texture_dict->mDefaultImageName;
@@ -477,108 +474,9 @@ void LLViewerWearable::setItemID(const LLUUID& item_id)
 	mItemID = item_id;
 }
 
-
-LLLocalTextureObject* LLViewerWearable::getLocalTextureObject(S32 index)
-{
-	te_map_t::iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-const LLLocalTextureObject* LLViewerWearable::getLocalTextureObject(S32 index) const
-{
-	te_map_t::const_iterator iter = mTEMap.find(index);
-	if( iter != mTEMap.end() )
-	{
-		const LLLocalTextureObject* lto = iter->second;
-		return lto;
-	}
-	return NULL;
-}
-
-std::vector<LLLocalTextureObject*> LLViewerWearable::getLocalTextureListSeq()
-{
-	std::vector<LLLocalTextureObject*> result;
-
-	for(te_map_t::const_iterator iter = mTEMap.begin();
-		iter != mTEMap.end(); iter++)
-	{
-		LLLocalTextureObject* lto = iter->second;
-		result.push_back(lto);
-	}
-
-	return result;
-}
-
-void LLViewerWearable::setLocalTextureObject(S32 index, LLLocalTextureObject &lto)
-{
-	if( mTEMap.find(index) != mTEMap.end() )
-	{
-		mTEMap.erase(index);
-	}
-	mTEMap[index] = new LLLocalTextureObject(lto);
-}
-
-void LLViewerWearable::setVisualParams()
-{
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin();
-		 iter != mVisualParamIndexMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		if (gAgentAvatarp->isUsingLocalAppearance())
-		{
-			gAgentAvatarp->setVisualParamWeight(id, value, FALSE);
-		}
-	}
-}
-
 void LLViewerWearable::revertValues()
 {
-	// FIXME DRANO - this triggers changes to driven params on avatar, potentially clobbering baked appearance.
-
-	//update saved settings so wearable is no longer dirty
-	// non-driver params first
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  !dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	//then driver params
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		F32 value = iter->second;
-		LLVisualParam *param = getVisualParam(id);
-		if(param &&  dynamic_cast<LLDriverParam*>(param) )
-		{
-			setVisualParamWeight(id, value, TRUE);
-		}
-	}
-
-	// make sure that saved values are sane
-	for (param_map_t::const_iterator iter = mSavedVisualParamMap.begin(); iter != mSavedVisualParamMap.end(); iter++)
-	{
-		S32 id = iter->first;
-		LLVisualParam *param = getVisualParam(id);
-		if( param )
-		{
-			mSavedVisualParamMap[id] = param->getWeight();
-		}
-	}
-
-	syncImages(mSavedTEMap, mTEMap);
+	LLWearable::revertValues();
 
 
 	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
@@ -590,19 +488,7 @@ void LLViewerWearable::revertValues()
 
 void LLViewerWearable::saveValues()
 {
-	//update saved settings so wearable is no longer dirty
-	mSavedVisualParamMap.clear();
-	for (visual_param_index_map_t::const_iterator iter = mVisualParamIndexMap.begin(); iter != mVisualParamIndexMap.end(); ++iter)
-	{
-		S32 id = iter->first;
-		LLVisualParam *wearable_param = iter->second;
-		F32 value = wearable_param->getWeight();
-		mSavedVisualParamMap[id] = value;
-	}
-
-	// Deep copy of mTEMap (copies only those tes that are current, filling in defaults where needed)
-	syncImages(mTEMap, mSavedTEMap);
-
+	LLWearable::saveValues();
 
 	LLSidepanelAppearance *panel = dynamic_cast<LLSidepanelAppearance*>(LLFloaterSidePanelContainer::getPanel("appearance"));
 	if( panel )
@@ -611,69 +497,6 @@ void LLViewerWearable::saveValues()
 	}
 }
 
-void LLViewerWearable::syncImages(te_map_t &src, te_map_t &dst)
-{
-	// Deep copy of src (copies only those tes that are current, filling in defaults where needed)
-	for( S32 te = 0; te < TEX_NUM_INDICES; te++ )
-	{
-		if (LLAvatarAppearanceDictionary::getTEWearableType((ETextureIndex) te) == mType)
-		{
-			te_map_t::const_iterator iter = src.find(te);
-			LLUUID image_id;
-			LLViewerFetchedTexture *image = NULL;
-			LLLocalTextureObject *lto = NULL;
-			if(iter != src.end())
-			{
-				// there's a Local Texture Object in the source image map. Use this to populate the values to store in the destination image map.
-				lto = iter->second;
-				image = dynamic_cast<LLViewerFetchedTexture*> (lto->getImage());
-				image_id = lto->getID();
-			}
-			else
-			{
-				// there is no Local Texture Object in the source image map. Get defaults values for populating the destination image map.
-				image_id = getDefaultTextureImageID((ETextureIndex) te);
-				image = LLViewerTextureManager::getFetchedTexture( image_id );
-			}
-
-			if( dst.find(te) != dst.end() )
-			{
-				// there's already an entry in the destination map for the texture. Just update its values.
-				dst[te]->setImage(image);
-				dst[te]->setID(image_id);
-			}
-			else
-			{
-				// no entry found in the destination map, we need to create a new Local Texture Object
-				dst[te] = new LLLocalTextureObject(image, image_id);
-			}
-
-			if( lto )
-			{
-				// If we pulled values from a Local Texture Object in the source map, make sure the proper flags are set in the new (or updated) entry in the destination map.
-				dst[te]->setBakedReady(lto->getBakedReady());
-				dst[te]->setDiscard(lto->getDiscard());
-			}
-		}
-	}
-}
-
-void LLViewerWearable::destroyTextures()
-{
-	for( te_map_t::iterator iter = mTEMap.begin(); iter != mTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mTEMap.clear();
-	for( te_map_t::iterator iter = mSavedTEMap.begin(); iter != mSavedTEMap.end(); ++iter )
-	{
-		LLLocalTextureObject *lto = iter->second;
-		delete lto;
-	}
-	mSavedTEMap.clear();
-}
-
 // virtual
 void LLViewerWearable::setUpdated() const
 { 
diff --git a/indra/newview/llviewerwearable.h b/indra/newview/llviewerwearable.h
index d8412b1c65c0cb9c87355434416cb563331a395f..65566f23a5a9981d6b3a5dc7ecac34a5d8d12a6e 100644
--- a/indra/newview/llviewerwearable.h
+++ b/indra/newview/llviewerwearable.h
@@ -64,12 +64,12 @@ class LLViewerWearable : public LLWearable
 	void				removeFromAvatar( BOOL upload_bake )	{ LLViewerWearable::removeFromAvatar( mType, upload_bake ); }
 	static void			removeFromAvatar( LLWearableType::EType type, BOOL upload_bake ); 
 
-	/*virtual*/ EImportResult	importFile(LLFILE* file, LLAvatarAppearance* avatarp);
+	/*virtual*/ EImportResult	importStream( std::istream& input_stream, LLAvatarAppearance* avatarp );
 	
 	void				setParamsToDefaults();
 	void				setTexturesToDefaults();
 
-	static const LLUUID			getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index);
+	/*virtual*/ LLUUID	getDefaultTextureImageID(LLAvatarAppearanceDefines::ETextureIndex index) const;
 
 
 	void				saveNewAsset() const;
@@ -79,14 +79,8 @@ class LLViewerWearable : public LLWearable
 
 	friend std::ostream& operator<<(std::ostream &s, const LLViewerWearable &w);
 
-	/*virtual*/ LLLocalTextureObject* getLocalTextureObject(S32 index);
-	const LLLocalTextureObject* getLocalTextureObject(S32 index) const;
-	std::vector<LLLocalTextureObject*> getLocalTextureListSeq();
-	void				setLocalTextureObject(S32 index, LLLocalTextureObject &lto);
-	void				setVisualParams();
-
-	void				revertValues();
-	void				saveValues();
+	/*virtual*/ void	revertValues();
+	/*virtual*/ void	saveValues();
 
 	// Something happened that requires the wearable's label to be updated (e.g. worn/unworn).
 	/*virtual*/void		setUpdated() const;
@@ -99,8 +93,6 @@ class LLViewerWearable : public LLWearable
 	/*virtual*/void		addToBakedTextureHash(LLMD5& hash) const;
 
 protected:
-	void				syncImages(te_map_t &src, te_map_t &dst);
-	void				destroyTextures();	
 	LLAssetID			mAssetID;
 	LLTransactionID		mTransactionID;
 
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 209e49940a23caf50377deae5ec1c90fd41d0819..63fe9312dfe4b907f3ce13af495edf164c3f4191 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -1385,43 +1385,6 @@ void LLViewerWindow::handleMenuSelect(LLWindow *window,  S32 menu_item)
 
 BOOL LLViewerWindow::handlePaint(LLWindow *window,  S32 x,  S32 y, S32 width,  S32 height)
 {
-	// *TODO: Enable similar information output for other platforms?  DK 2011-02-18
-#if LL_WINDOWS
-	if (gHeadlessClient)
-	{
-		HWND window_handle = (HWND)window->getPlatformWindow();
-		PAINTSTRUCT ps; 
-		HDC hdc; 
- 
-		RECT wnd_rect;
-		wnd_rect.left = 0;
-		wnd_rect.top = 0;
-		wnd_rect.bottom = 200;
-		wnd_rect.right = 500;
-
-		hdc = BeginPaint(window_handle, &ps); 
-		//SetBKColor(hdc, RGB(255, 255, 255));
-		FillRect(hdc, &wnd_rect, CreateSolidBrush(RGB(255, 255, 255)));
-
-		std::string temp_str;
-		temp_str = llformat( "FPS %3.1f Phy FPS %2.1f Time Dil %1.3f",		/* Flawfinder: ignore */
-				LLViewerStats::getInstance()->mFPSStat.getMeanPerSec(),
-				LLViewerStats::getInstance()->mSimPhysicsFPS.getPrev(0),
-				LLViewerStats::getInstance()->mSimTimeDilation.getPrev(0));
-		S32 len = temp_str.length();
-		TextOutA(hdc, 0, 0, temp_str.c_str(), len); 
-
-
-		LLVector3d pos_global = gAgent.getPositionGlobal();
-		temp_str = llformat( "Avatar pos %6.1lf %6.1lf %6.1lf", pos_global.mdV[0], pos_global.mdV[1], pos_global.mdV[2]);
-		len = temp_str.length();
-		TextOutA(hdc, 0, 25, temp_str.c_str(), len); 
-
-		TextOutA(hdc, 0, 50, "Set \"HeadlessClient FALSE\" in settings.ini file to reenable", 61);
-		EndPaint(window_handle, &ps); 
-		return TRUE;
-	}
-#endif
 	return FALSE;
 }
 
@@ -1568,12 +1531,12 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 	resetSnapshotLoc();
 
 	// create window
+	const BOOL clear_bg = FALSE;
 	mWindow = LLWindowManager::createWindow(this,
 		p.title, p.name, p.x, p.y, p.width, p.height, 0,
 		p.fullscreen, 
-		gHeadlessClient,
+		clear_bg,
 		gSavedSettings.getBOOL("DisableVerticalSync"),
-		!gHeadlessClient,
 		p.ignore_pixel_depth,
 		gSavedSettings.getBOOL("RenderDeferred") ? 0 : gSavedSettings.getU32("RenderFSAASamples")); //don't use window level anti-aliasing if FBOs are enabled
 
@@ -1717,7 +1680,6 @@ LLViewerWindow::LLViewerWindow(const Params& p)
 
 void LLViewerWindow::initGLDefaults()
 {
-	if (gHeadlessClient) return;
 	gGL.setSceneBlendType(LLRender::BT_ALPHA);
 
 	if (!LLGLSLShader::sNoFixedFunction)
@@ -4997,11 +4959,6 @@ bool LLViewerWindow::onAlert(const LLSD& notify)
 {
 	LLNotificationPtr notification = LLNotifications::instance().find(notify["id"].asUUID());
 
-	if (gHeadlessClient)
-	{
-		llinfos << "Alert: " << notification->getName() << llendl;
-	}
-
 	// If we're in mouselook, the mouse is hidden and so the user can't click 
 	// the dialog buttons.  In that case, change to First Person instead.
 	if( gAgentCamera.cameraMouselook() )
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 50beaaec3faa0e273440f01f4645a1b19a1693c3..3dfacd70f3bf97db407ae30f31f92240ba722444 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -112,15 +112,16 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 	else if (status >= 0)
 	{
 		// read the file
-		LLFILE* fp = LLFile::fopen(std::string(filename), "rb");		/*Flawfinder: ignore*/
-		if( !fp )
+		llifstream ifs(filename, llifstream::binary);
+		if( !ifs.is_open() )
 		{
 			LL_WARNS("Wearable") << "Bad Wearable Asset: unable to open file: '" << filename << "'" << LL_ENDL;
 		}
 		else
 		{
 			wearable = new LLViewerWearable(uuid);
-			LLWearable::EImportResult result = wearable->importFile( fp, avatarp );
+			LLWearable::EImportResult result = wearable->importStream(
+												ifs, avatarp );
 			if (LLWearable::SUCCESS != result)
 			{
 				if (wearable->getType() == LLWearableType::WT_COUNT)
@@ -131,7 +132,6 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 				wearable = NULL;
 			}
 
-			fclose( fp );
 			if(filename)
 			{
 				LLFile::remove(std::string(filename));
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index e874373f9e6be30f0a914efaa3e9507bc9450157..61df5bc2ebf8b2e49033f7d7d6c783b1266a3b49 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -1139,7 +1139,6 @@ void LLPipeline::releaseScreenBuffers()
 
 void LLPipeline::createGLBuffers()
 {
-	if (gHeadlessClient) return;
 	stop_glerror();
 	LLMemType mt_cb(LLMemType::MTYPE_PIPELINE_CREATE_BUFFERS);
 	assertInitialized();
diff --git a/indra/test/llpermissions_tut.cpp b/indra/test/llpermissions_tut.cpp
index bf6766424c60264fe999ca7d4d2cf18c9bc663fb..dff8bca53fc64e03679eacc943b35006ca69187a 100644
--- a/indra/test/llpermissions_tut.cpp
+++ b/indra/test/llpermissions_tut.cpp
@@ -407,7 +407,7 @@ namespace tut
 		LLFILE* fp = LLFile::fopen("linden_file.dat","w+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
 		LLPermissions perm,perm1;
@@ -425,15 +425,15 @@ namespace tut
 
 		perm.initMasks(base, ownerp, everyone, groupp, next);
 
-		perm.exportFile(fp);
+		ensure("Permissions export failed", perm.exportFile(fp));
 		fclose(fp);	
 		fp = LLFile::fopen("linden_file.dat","r+");
 		if(!fp)
 		{
-			llerrs << "file coudnt be opened\n" << llendl;
+			llerrs << "file couldn't be opened\n" << llendl;
 			return;
 		}
-		perm1.importFile(fp);
+		ensure("Permissions import failed", perm1.importFile(fp));
 		fclose(fp);
 		ensure_equals("exportFile()/importFile():failed to export and import the data ", perm1, perm);	
 }
@@ -457,11 +457,11 @@ namespace tut
 		perm.initMasks(base, ownerp, everyone, groupp, next);
 
 		std::ostringstream ostream;
-		perm.exportLegacyStream(ostream);
+		perm.exportStream(ostream);
 		std::istringstream istream(ostream.str());
-		perm1.importLegacyStream(istream);
+		perm1.importStream(istream);
 
-		ensure_equals("exportLegacyStream()/importLegacyStream():failed to export and import the data ", perm1, perm);
+		ensure_equals("exportStream()/importStream():failed to export and import the data ", perm1, perm);
 	}
 
 	template<> template<>
diff --git a/indra/test/llsaleinfo_tut.cpp b/indra/test/llsaleinfo_tut.cpp
index 09fca2abbab19013063aaf558fd511c6f861f680..d5468039476fc9cb2eb8d04d9baea3981fad0927 100644
--- a/indra/test/llsaleinfo_tut.cpp
+++ b/indra/test/llsaleinfo_tut.cpp
@@ -146,16 +146,17 @@ namespace tut
 		LLSaleInfo llsaleinfo(LLSaleInfo::FS_ORIGINAL, sale_price);
 		
 		std::ostringstream ostream;
-		llsaleinfo.exportLegacyStream(ostream);
+		llsaleinfo.exportStream(ostream);
 		
 		std::istringstream istream(ostream.str());
 		LLSaleInfo llsaleinfo1;
 		U32 perm_mask = 0;
 		BOOL has_perm_mask = FALSE;
-		llsaleinfo1.importLegacyStream(istream, has_perm_mask, perm_mask);
+		llsaleinfo1.importStream(istream, has_perm_mask, perm_mask);
 					
-		ensure("importLegacyStream() fn failed ", llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
-										       llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());		
+		ensure("importStream() fn failed ",
+			llsaleinfo.getSalePrice() == llsaleinfo1.getSalePrice() &&
+			llsaleinfo.getSaleType() == llsaleinfo1.getSaleType());
 	}
 
 	template<> template<>