diff --git a/.hgtags b/.hgtags
index 3f2adaf5dde08ee35f60aa9be0f5079230a1ab4a..90a21a647f41df70b02fb313365b3c80481e0de8 100755
--- a/.hgtags
+++ b/.hgtags
@@ -527,3 +527,4 @@ cea1632c002c065985ebea15eeeb4aac90f50545 5.0.2-release
 02c24e9f4f7d8aa0de75f27817dda098582f4936 5.0.3-release
 022709ef76a331cac1ba6ef1a6da8a5e9ef63f5a 5.0.4-release
 b4d76b5590fdf8bab72c64442353753a527cbc44 5.0.5-release
+3e5035dfd8af49bd4c0009f0a76ef46a15991a45 5.0.6-release
diff --git a/doc/contributions.txt b/doc/contributions.txt
index eb012ee31846d3af4edb2ce49f55e2a49483b9c5..79ff7161f64dc02918d70647ed74c53d384ec5e1 100755
--- a/doc/contributions.txt
+++ b/doc/contributions.txt
@@ -1302,6 +1302,7 @@ Sovereign Engineer
     MAINT-6218
     MAINT-6913
     STORM-2143
+    MAINT-7343
 SpacedOut Frye
 	VWR-34
 	VWR-45
diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h
index 3a4b5dad18cfaae843090ed95809a4921a7b4de7..b849be9f16ad3a02474c7334631cf418f2b286e2 100644
--- a/indra/llcommon/llassettype.h
+++ b/indra/llcommon/llassettype.h
@@ -152,7 +152,7 @@ class LL_COMMON_API LLAssetType
 
 	static bool 				lookupIsAssetFetchByIDAllowed(EType asset_type); // the asset allows direct download
 	static bool 				lookupIsAssetIDKnowable(EType asset_type); // asset data can be known by the viewer
-	
+
 	static const std::string&	badLookup(); // error string when a lookup fails
 
 protected:
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index e6407ecf220b0df466bb3542a745df6c1ab415d8..9c49f7eff4dc6fb73c503b988cda57d4cff58b70 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -572,7 +572,7 @@ namespace LLError
 		mFunctionString += std::string(mFunction) + ":";
 		for (size_t i = 0; i < mTagCount; i++)
 		{
-			mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? "" : ",");
+			mTagString += std::string("#") + mTags[i] + ((i == mTagCount - 1) ? " " : ",");
 		}
 	}
 
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index bcf4e52b8f9440cc11961ba59406be32ca2af14b..596d57c7b7b838bdf3450fbd4d91ae9e9a47961a 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -60,64 +60,60 @@ static LLTrace::CountStatHandle<> sFailedDownloadCount("faileddownloads", "Numbe
 
 const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010"));
 
-const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);		// microseconds
-
-LLTempAssetStorage::~LLTempAssetStorage()
-{
-}
+const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);       // microseconds
 
 ///----------------------------------------------------------------------------
 /// LLAssetInfo
 ///----------------------------------------------------------------------------
 
 LLAssetInfo::LLAssetInfo( void )
-:	mDescription(),
-	mName(),
-	mUuid(),
-	mCreatorID(),
-	mType( LLAssetType::AT_NONE )
+    :   mDescription(),
+        mName(),
+        mUuid(),
+        mCreatorID(),
+        mType( LLAssetType::AT_NONE )
 { }
 
 LLAssetInfo::LLAssetInfo( const LLUUID& object_id, const LLUUID& creator_id,
-						  LLAssetType::EType type, const char* name,
-						  const char* desc )
-:	mUuid( object_id ), 
-	mCreatorID( creator_id ), 
-	mType( type )
+                          LLAssetType::EType type, const char* name,
+                          const char* desc )
+    :   mUuid( object_id ), 
+        mCreatorID( creator_id ), 
+        mType( type )
 {
-	setName( name );
-	setDescription( desc );
+    setName( name );
+    setDescription( desc );
 }
 
 LLAssetInfo::LLAssetInfo( const LLNameValue& nv )
 {
-	setFromNameValue( nv );
+    setFromNameValue( nv );
 }
 
 // make sure the name is short enough, and strip all pipes since they
 // are reserved characters in our inventory tracking system.
 void LLAssetInfo::setName( const std::string& name )
 {
-	if( !name.empty() )
-	{
-		mName.assign( name, 0, llmin((U32)name.size(), (U32)DB_INV_ITEM_NAME_STR_LEN) );
-		mName.erase( std::remove(mName.begin(), mName.end(), '|'),
-					 mName.end() );
-	}
+    if( !name.empty() )
+    {
+        mName.assign( name, 0, llmin((U32)name.size(), (U32)DB_INV_ITEM_NAME_STR_LEN) );
+        mName.erase( std::remove(mName.begin(), mName.end(), '|'),
+                     mName.end() );
+    }
 }
 
 // make sure the name is short enough, and strip all pipes since they
 // are reserved characters in our inventory tracking system.
 void LLAssetInfo::setDescription( const std::string& desc )
 {
-	if( !desc.empty() )
-	{
-		mDescription.assign( desc, 0, llmin((U32)desc.size(),
-										 (U32)DB_INV_ITEM_DESC_STR_LEN) );
-		mDescription.erase( std::remove(mDescription.begin(),
-										mDescription.end(), '|'),
-							mDescription.end() );
-	}
+    if( !desc.empty() )
+    {
+        mDescription.assign( desc, 0, llmin((U32)desc.size(),
+                                            (U32)DB_INV_ITEM_DESC_STR_LEN) );
+        mDescription.erase( std::remove(mDescription.begin(),
+                                        mDescription.end(), '|'),
+                            mDescription.end() );
+    }
 }
 
 // Assets (aka potential inventory items) can be applied to an
@@ -130,31 +126,31 @@ void LLAssetInfo::setDescription( const std::string& desc )
 //   value=<creatorid>|<name>|<description>|
 void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
 {
-	std::string str;
-	std::string buf;
-	std::string::size_type pos1;
-	std::string::size_type pos2;
-
-	// convert the name to useful information
-	str.assign( nv.mName );
-	pos1 = str.find('|');
-	buf.assign( str, 0, pos1++ );
-	mType = LLAssetType::lookup( buf );
-	buf.assign( str, pos1, std::string::npos );
-	mUuid.set( buf );
-
-	// convert the value to useful information
-	str.assign( nv.getAsset() );
-	pos1 = str.find('|');
-	buf.assign( str, 0, pos1++ );
-	mCreatorID.set( buf );
-	pos2 = str.find( '|', pos1 );
-	buf.assign( str, pos1, (pos2++) - pos1 );
-	setName( buf );
-	buf.assign( str, pos2, std::string::npos );
-	setDescription( buf );
-	LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << LL_ENDL;
-	LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << LL_ENDL;
+    std::string str;
+    std::string buf;
+    std::string::size_type pos1;
+    std::string::size_type pos2;
+
+    // convert the name to useful information
+    str.assign( nv.mName );
+    pos1 = str.find('|');
+    buf.assign( str, 0, pos1++ );
+    mType = LLAssetType::lookup( buf );
+    buf.assign( str, pos1, std::string::npos );
+    mUuid.set( buf );
+
+    // convert the value to useful information
+    str.assign( nv.getAsset() );
+    pos1 = str.find('|');
+    buf.assign( str, 0, pos1++ );
+    mCreatorID.set( buf );
+    pos2 = str.find( '|', pos1 );
+    buf.assign( str, pos1, (pos2++) - pos1 );
+    setName( buf );
+    buf.assign( str, pos2, std::string::npos );
+    setDescription( buf );
+    LL_DEBUGS("AssetStorage") << "uuid: " << mUuid << LL_ENDL;
+    LL_DEBUGS("AssetStorage") << "creator: " << mCreatorID << LL_ENDL;
 }
 
 ///----------------------------------------------------------------------------
@@ -162,15 +158,15 @@ void LLAssetInfo::setFromNameValue( const LLNameValue& nv )
 ///----------------------------------------------------------------------------
 
 LLBaseDownloadRequest::LLBaseDownloadRequest(const LLUUID &uuid, const LLAssetType::EType type)
-: mUUID(uuid),
-mType(type),
-mDownCallback(NULL),
-mUserData(NULL),
-mHost(),
-mIsTemp(FALSE),
-mIsPriority(FALSE),
-mDataSentInFirstPacket(FALSE),
-mDataIsInVFS(FALSE)
+    : mUUID(uuid),
+      mType(type),
+      mDownCallback(NULL),
+      mUserData(NULL),
+      mHost(),
+      mIsTemp(FALSE),
+      mIsPriority(FALSE),
+      mDataSentInFirstPacket(FALSE),
+      mDataIsInVFS(FALSE)
 {
     // Need to guarantee that this time is up to date, we may be creating a circuit even though we haven't been
     //  running a message system loop.
@@ -194,12 +190,13 @@ LLBaseDownloadRequest* LLBaseDownloadRequest::getCopy()
 ///----------------------------------------------------------------------------
 
 LLAssetRequest::LLAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
-:	LLBaseDownloadRequest(uuid, type),
-	mUpCallback( NULL ),
-	mInfoCallback( NULL ),
-	mIsLocal(FALSE),
-	mIsUserWaiting(FALSE),
-	mTimeout(LL_ASSET_STORAGE_TIMEOUT)
+    :   LLBaseDownloadRequest(uuid, type),
+        mUpCallback( NULL ),
+        mInfoCallback( NULL ),
+        mIsLocal(FALSE),
+        mIsUserWaiting(FALSE),
+        mTimeout(LL_ASSET_STORAGE_TIMEOUT),
+        mBytesFetched(0)
 {
 }
 
@@ -211,31 +208,31 @@ LLAssetRequest::~LLAssetRequest()
 // virtual
 LLSD LLAssetRequest::getTerseDetails() const
 {
-	LLSD sd;
-	sd["asset_id"] = getUUID();
-	sd["type_long"] = LLAssetType::lookupHumanReadable(getType());
-	sd["type"] = LLAssetType::lookup(getType());
-	sd["time"] = mTime.value();
-	time_t timestamp = (time_t) mTime.value();
-	std::ostringstream time_string;
-	time_string << ctime(&timestamp);
-	sd["time_string"] = time_string.str();
-	return sd;
+    LLSD sd;
+    sd["asset_id"] = getUUID();
+    sd["type_long"] = LLAssetType::lookupHumanReadable(getType());
+    sd["type"] = LLAssetType::lookup(getType());
+    sd["time"] = mTime.value();
+    time_t timestamp = (time_t) mTime.value();
+    std::ostringstream time_string;
+    time_string << ctime(&timestamp);
+    sd["time_string"] = time_string.str();
+    return sd;
 }
 
 // virtual
 LLSD LLAssetRequest::getFullDetails() const
 {
-	LLSD sd = getTerseDetails();
-	sd["host"] = mHost.getIPandPort();
-	sd["requesting_agent"] = mRequestingAgentID;
-	sd["is_temp"] = mIsTemp;
-	sd["is_local"] = mIsLocal;
-	sd["is_priority"] = mIsPriority;
-	sd["data_send_in_first_packet"] = mDataSentInFirstPacket;
-	sd["data_is_in_vfs"] = mDataIsInVFS;
-
-	return sd;
+    LLSD sd = getTerseDetails();
+    sd["host"] = mHost.getIPandPort();
+    sd["requesting_agent"] = mRequestingAgentID;
+    sd["is_temp"] = mIsTemp;
+    sd["is_local"] = mIsLocal;
+    sd["is_priority"] = mIsPriority;
+    sd["data_send_in_first_packet"] = mDataSentInFirstPacket;
+    sd["data_is_in_vfs"] = mDataIsInVFS;
+
+    return sd;
 }
 
 LLBaseDownloadRequest* LLAssetRequest::getCopy()
@@ -248,7 +245,7 @@ LLBaseDownloadRequest* LLAssetRequest::getCopy()
 ///----------------------------------------------------------------------------
 
 LLInvItemRequest::LLInvItemRequest(const LLUUID &uuid, const LLAssetType::EType type)
-:	LLBaseDownloadRequest(uuid, type)
+    :   LLBaseDownloadRequest(uuid, type)
 {
 }
 
@@ -267,9 +264,9 @@ LLBaseDownloadRequest* LLInvItemRequest::getCopy()
 ///----------------------------------------------------------------------------
 
 LLEstateAssetRequest::LLEstateAssetRequest(const LLUUID &uuid, const LLAssetType::EType atype,
-										   EstateAssetType etype)
-:	LLBaseDownloadRequest(uuid, atype),
-	mEstateAssetType(etype)
+                                           EstateAssetType etype)
+    :   LLBaseDownloadRequest(uuid, atype),
+        mEstateAssetType(etype)
 {
 }
 
@@ -299,152 +296,150 @@ LLBaseDownloadRequest* LLEstateAssetRequest::getCopy()
 
 LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer, LLVFS *vfs, LLVFS *static_vfs, const LLHost &upstream_host)
 {
-	_init(msg, xfer, vfs, static_vfs, upstream_host);
+    _init(msg, xfer, vfs, static_vfs, upstream_host);
 }
 
-
 LLAssetStorage::LLAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
-							   LLVFS *vfs, LLVFS *static_vfs)
+                               LLVFS *vfs, LLVFS *static_vfs)
 {
-	_init(msg, xfer, vfs, static_vfs, LLHost());
+    _init(msg, xfer, vfs, static_vfs, LLHost());
 }
 
-
 void LLAssetStorage::_init(LLMessageSystem *msg,
-						   LLXferManager *xfer,
-						   LLVFS *vfs,
-						   LLVFS *static_vfs,
-						   const LLHost &upstream_host)
+                           LLXferManager *xfer,
+                           LLVFS *vfs,
+                           LLVFS *static_vfs,
+                           const LLHost &upstream_host)
 {
-	mShutDown = FALSE;
-	mMessageSys = msg;
-	mXferManager = xfer;
-	mVFS = vfs;
-	mStaticVFS = static_vfs;
-
-	setUpstream(upstream_host);
-	msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);
+    mShutDown = FALSE;
+    mMessageSys = msg;
+    mXferManager = xfer;
+    mVFS = vfs;
+    mStaticVFS = static_vfs;
+
+    setUpstream(upstream_host);
+    msg->setHandlerFuncFast(_PREHASH_AssetUploadComplete, processUploadComplete, (void **)this);
 }
 
 LLAssetStorage::~LLAssetStorage()
 {
-	mShutDown = TRUE;
-	
-	_cleanupRequests(TRUE, LL_ERR_CIRCUIT_GONE);
-
-	if (gMessageSystem)
-	{
-		// Warning!  This won't work if there's more than one asset storage.
-		// unregister our callbacks with the message system
-		gMessageSystem->setHandlerFuncFast(_PREHASH_AssetUploadComplete, NULL, NULL);
-	}
-
-	// Clear the toxic asset map
-	mToxicAssetMap.clear();
+    mShutDown = TRUE;
+    
+    _cleanupRequests(TRUE, LL_ERR_CIRCUIT_GONE);
+
+    if (gMessageSystem)
+    {
+        // Warning!  This won't work if there's more than one asset storage.
+        // unregister our callbacks with the message system
+        gMessageSystem->setHandlerFuncFast(_PREHASH_AssetUploadComplete, NULL, NULL);
+    }
+
+    // Clear the toxic asset map
+    mToxicAssetMap.clear();
 }
 
 void LLAssetStorage::setUpstream(const LLHost &upstream_host)
 {
-	LL_DEBUGS("AppInit") << "AssetStorage: Setting upstream provider to " << upstream_host << LL_ENDL;
-	
-	mUpstreamHost = upstream_host;
+    LL_DEBUGS("AppInit") << "AssetStorage: Setting upstream provider to " << upstream_host << LL_ENDL;
+    
+    mUpstreamHost = upstream_host;
 }
 
 void LLAssetStorage::checkForTimeouts()
 {
-	_cleanupRequests(FALSE, LL_ERR_TCP_TIMEOUT);
+    _cleanupRequests(FALSE, LL_ERR_TCP_TIMEOUT);
 }
 
 void LLAssetStorage::_cleanupRequests(BOOL all, S32 error)
 {
-	F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds();
-
-	request_list_t timed_out;
-	S32 rt;
-	for (rt = 0; rt < RT_COUNT; rt++)
-	{
-		request_list_t* requests = getRequestList((ERequestType)rt);
-		for (request_list_t::iterator iter = requests->begin();
-			 iter != requests->end(); )
-		{
-			request_list_t::iterator curiter = iter++;
-			LLAssetRequest* tmp = *curiter;
-			// if all is true, we want to clean up everything
-			// otherwise just check for timed out requests
-			// EXCEPT for upload timeouts
-			if (all 
-				|| ((RT_DOWNLOAD == rt)
-					&& LL_ASSET_STORAGE_TIMEOUT < (mt_secs - tmp->mTime)))
-			{
-				LL_WARNS() << "Asset " << getRequestName((ERequestType)rt) << " request "
-						<< (all ? "aborted" : "timed out") << " for "
-						<< tmp->getUUID() << "."
-						<< LLAssetType::lookup(tmp->getType()) << LL_ENDL;
-
-				timed_out.push_front(tmp);
-				iter = requests->erase(curiter);
-			}
-		}
-	}
-
-	LLAssetInfo	info;
-	for (request_list_t::iterator iter = timed_out.begin();
-		 iter != timed_out.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* tmp = *curiter;
-		if (tmp->mUpCallback)
-		{
-			tmp->mUpCallback(tmp->getUUID(), tmp->mUserData, error, LL_EXSTAT_NONE);
-		}
-		if (tmp->mDownCallback)
-		{
-			tmp->mDownCallback(mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LL_EXSTAT_NONE);
-		}
-		if (tmp->mInfoCallback)
-		{
-			tmp->mInfoCallback(&info, tmp->mUserData, error);
-		}
-		delete tmp;
-	}
+    F64Seconds mt_secs = LLMessageSystem::getMessageTimeSeconds();
+
+    request_list_t timed_out;
+    S32 rt;
+    for (rt = 0; rt < RT_COUNT; rt++)
+    {
+        request_list_t* requests = getRequestList((ERequestType)rt);
+        for (request_list_t::iterator iter = requests->begin();
+             iter != requests->end(); )
+        {
+            request_list_t::iterator curiter = iter++;
+            LLAssetRequest* tmp = *curiter;
+            // if all is true, we want to clean up everything
+            // otherwise just check for timed out requests
+            // EXCEPT for upload timeouts
+            if (all 
+                || ((RT_DOWNLOAD == rt)
+                    && LL_ASSET_STORAGE_TIMEOUT < (mt_secs - tmp->mTime)))
+            {
+                LL_WARNS("AssetStorage") << "Asset " << getRequestName((ERequestType)rt) << " request "
+                                         << (all ? "aborted" : "timed out") << " for "
+                                         << tmp->getUUID() << "."
+                                         << LLAssetType::lookup(tmp->getType()) << LL_ENDL;
+                
+                timed_out.push_front(tmp);
+                iter = requests->erase(curiter);
+            }
+        }
+    }
+
+    LLAssetInfo     info;
+    for (request_list_t::iterator iter = timed_out.begin();
+         iter != timed_out.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* tmp = *curiter;
+        if (tmp->mUpCallback)
+        {
+            tmp->mUpCallback(tmp->getUUID(), tmp->mUserData, error, LL_EXSTAT_NONE);
+        }
+        if (tmp->mDownCallback)
+        {
+            tmp->mDownCallback(mVFS, tmp->getUUID(), tmp->getType(), tmp->mUserData, error, LL_EXSTAT_NONE);
+        }
+        if (tmp->mInfoCallback)
+        {
+            tmp->mInfoCallback(&info, tmp->mUserData, error);
+        }
+        delete tmp;
+    }
 
 }
 
 BOOL LLAssetStorage::hasLocalAsset(const LLUUID &uuid, const LLAssetType::EType type)
 {
-	return mStaticVFS->getExists(uuid, type) || mVFS->getExists(uuid, type);
+    return mStaticVFS->getExists(uuid, type) || mVFS->getExists(uuid, type);
 }
 
 bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
-													  LLGetAssetCallback callback, void *user_data)
-{
-	if (user_data)
-	{
-		// The *user_data should not be passed without a callback to clean it up.
-		llassert(callback != NULL);
-	}
-
-	BOOL exists = mStaticVFS->getExists(uuid, type);
-	if (exists)
-	{
-		LLVFile file(mStaticVFS, uuid, type);
-		U32 size = file.getSize();
-		if (size > 0)
-		{
-			// we've already got the file
-			if (callback)
-			{
-				callback(mStaticVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
-			}
-			return true;
-		}
-		else
-		{
-			LL_WARNS() << "Asset vfile " << uuid << ":" << type
-					<< " found in static cache with bad size " << file.getSize() << ", ignoring" << LL_ENDL;
-		}
-	}
-	return false;
+                                                      LLGetAssetCallback callback, void *user_data)
+{
+    if (user_data)
+    {
+        // The *user_data should not be passed without a callback to clean it up.
+        llassert(callback != NULL);
+    }
+
+    BOOL exists = mStaticVFS->getExists(uuid, type);
+    if (exists)
+    {
+        LLVFile file(mStaticVFS, uuid, type);
+        U32 size = file.getSize();
+        if (size > 0)
+        {
+            // we've already got the file
+            if (callback)
+            {
+                callback(mStaticVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
+            }
+            return true;
+        }
+        else
+        {
+            LL_WARNS("AssetStorage") << "Asset vfile " << uuid << ":" << type
+                                     << " found in static cache with bad size " << file.getSize() << ", ignoring" << LL_ENDL;
+        }
+    }
+    return false;
 }
 
 ///////////////////////////////////////////////////////////////////////////
@@ -452,526 +447,506 @@ bool LLAssetStorage::findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAsse
 ///////////////////////////////////////////////////////////////////////////
 
 // IW - uuid is passed by value to avoid side effects, please don't re-add &    
-void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LLGetAssetCallback callback, void *user_data, BOOL is_priority)
-{
-	LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL;
-
-	LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL;
-
-	if (user_data)
-	{
-		// The *user_data should not be passed without a callback to clean it up.
-		llassert(callback != NULL);
-	}
-
-	if (mShutDown)
-	{
-		LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << LL_ENDL;
-
-		if (callback)
-		{
-			add(sFailedDownloadCount, 1);
-			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE);
-		}
-		return;
-	}
-
-	if (uuid.isNull())
-	{
-		// Special case early out for NULL uuid and for shutting down
-		if (callback)
-		{
-			add(sFailedDownloadCount, 1);
-			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
-		}
-		return;
-	}
-
-	// Try static VFS first.
-	if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data))
-	{
-		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << LL_ENDL;
-		return;
-	}
-
-	BOOL exists = mVFS->getExists(uuid, type);
-	LLVFile file(mVFS, uuid, type);
-	U32 size = exists ? file.getSize() : 0;
-	
-	if (size > 0)
-	{
-		// we've already got the file
-		// theoretically, partial files w/o a pending request shouldn't happen
-		// unless there's a weird error
-		if (callback)
-		{
-			callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
-		}
-
-		LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << LL_ENDL;
-	}
-	else
-	{
-		if (exists)
-		{
-			LL_WARNS() << "Asset vfile " << uuid << ":" << type << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
-			file.remove();
-		}
-		
-		BOOL duplicate = FALSE;
-		
-		// check to see if there's a pending download of this uuid already
-		for (request_list_t::iterator iter = mPendingDownloads.begin();
-			 iter != mPendingDownloads.end(); ++iter )
-		{
-			LLAssetRequest  *tmp = *iter;
-			if ((type == tmp->getType()) && (uuid == tmp->getUUID()))
-			{
-				if (callback == tmp->mDownCallback && user_data == tmp->mUserData)
-				{
-					// this is a duplicate from the same subsystem - throw it away
-					LL_WARNS() << "Discarding duplicate request for asset " << uuid
-							<< "." << LLAssetType::lookup(type) << LL_ENDL;
-					return;
-				}
-				
-				// this is a duplicate request
-				// queue the request, but don't actually ask for it again
-				duplicate = TRUE;
-			}
-		}
-		if (duplicate)
-		{
-			LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid 
-					<< "." << LLAssetType::lookup(type) << LL_ENDL;
-		}
-		
-		// This can be overridden by subclasses
-		_queueDataRequest(uuid, type, callback, user_data, duplicate, is_priority);	
-	}
-
+void LLAssetStorage::getAssetData(const LLUUID uuid,
+                                  LLAssetType::EType type, 
+                                  LLGetAssetCallback callback, 
+                                  void *user_data, 
+                                  BOOL is_priority)
+{
+    LL_DEBUGS("AssetStorage") << "LLAssetStorage::getAssetData() - " << uuid << "," << LLAssetType::lookup(type) << LL_ENDL;
+
+    LL_DEBUGS("AssetStorage") << "ASSET_TRACE requesting " << uuid << " type " << LLAssetType::lookup(type) << LL_ENDL;
+
+    if (user_data)
+    {
+        // The *user_data should not be passed without a callback to clean it up.
+        llassert(callback != NULL);
+    }
+
+    if (mShutDown)
+    {
+        LL_DEBUGS("AssetStorage") << "ASSET_TRACE cancelled " << uuid << " type " << LLAssetType::lookup(type) << " shutting down" << LL_ENDL;
+
+        if (callback)
+        {
+            add(sFailedDownloadCount, 1);
+            callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE);
+        }
+        return;
+    }
+
+    if (uuid.isNull())
+    {
+        // Special case early out for NULL uuid and for shutting down
+        if (callback)
+        {
+            add(sFailedDownloadCount, 1);
+            callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
+        }
+        return;
+    }
+
+    // Try static VFS first.
+    if (findInStaticVFSAndInvokeCallback(uuid,type,callback,user_data))
+    {
+        LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in static VFS" << LL_ENDL;
+        return;
+    }
+
+    BOOL exists = mVFS->getExists(uuid, type);
+    LLVFile file(mVFS, uuid, type);
+    U32 size = exists ? file.getSize() : 0;
+    
+    if (size > 0)
+    {
+        // we've already got the file
+        // theoretically, partial files w/o a pending request shouldn't happen
+        // unless there's a weird error
+        if (callback)
+        {
+            callback(mVFS, uuid, type, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
+        }
+
+        LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << uuid << " found in VFS" << LL_ENDL;
+    }
+    else
+    {
+        if (exists)
+        {
+            LL_WARNS("AssetStorage") << "Asset vfile " << uuid << ":" << type << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
+            file.remove();
+        }
+        
+        BOOL duplicate = FALSE;
+        
+        // check to see if there's a pending download of this uuid already
+        for (request_list_t::iterator iter = mPendingDownloads.begin();
+             iter != mPendingDownloads.end(); ++iter )
+        {
+            LLAssetRequest  *tmp = *iter;
+            if ((type == tmp->getType()) && (uuid == tmp->getUUID()))
+            {
+                if (callback == tmp->mDownCallback && user_data == tmp->mUserData)
+                {
+                    // this is a duplicate from the same subsystem - throw it away
+                    LL_WARNS("AssetStorage") << "Discarding duplicate request for asset " << uuid
+                                             << "." << LLAssetType::lookup(type) << LL_ENDL;
+                    return;
+                }
+                
+                // this is a duplicate request
+                // queue the request, but don't actually ask for it again
+                duplicate = TRUE;
+            }
+        }
+        if (duplicate)
+        {
+            LL_DEBUGS("AssetStorage") << "Adding additional non-duplicate request for asset " << uuid 
+                                      << "." << LLAssetType::lookup(type) << LL_ENDL;
+        }
+        
+        _queueDataRequest(uuid, type, callback, user_data, duplicate, is_priority);     
+    }
 }
 
-//
-// *NOTE:  Logic here is replicated in LLViewerAssetStorage::_queueDataRequest.
-// Changes here may need to be replicated in the viewer's derived class.
-//
-void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType atype,
-									   LLGetAssetCallback callback,
-									   void *user_data, BOOL duplicate,
-									   BOOL is_priority)
-{
-	if (mUpstreamHost.isOk())
-	{
-		// stash the callback info so we can find it after we get the response message
-		LLAssetRequest *req = new LLAssetRequest(uuid, atype);
-		req->mDownCallback = callback;
-		req->mUserData = user_data;
-		req->mIsPriority = is_priority;
-	
-		mPendingDownloads.push_back(req);
-	
-		if (!duplicate)
-		{
-			// send request message to our upstream data provider
-			// Create a new asset transfer.
-			LLTransferSourceParamsAsset spa;
-			spa.setAsset(uuid, atype);
-
-			// Set our destination file, and the completion callback.
-			LLTransferTargetParamsVFile tpvf;
-			tpvf.setAsset(uuid, atype);
-			tpvf.setCallback(downloadCompleteCallback, *req);
-
-			//LL_INFOS() << "Starting transfer for " << uuid << LL_ENDL;
-			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
-			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
-		}
-	}
-	else
-	{
-		// uh-oh, we shouldn't have gotten here
-		LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
-		if (callback)
-		{
-			add(sFailedDownloadCount, 1);
-			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
-		}
-	}
+// static
+void LLAssetStorage::removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,
+                                                       const LLUUID& callback_id, LLAssetType::EType callback_type,
+                                                       S32 result_code, LLExtStat ext_status)
+{
+    // find and callback ALL pending requests for this UUID
+    // SJB: We process the callbacks in reverse order, I do not know if this is important,
+    //      but I didn't want to mess with it.
+    request_list_t requests;
+    for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin();
+         iter != gAssetStorage->mPendingDownloads.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* tmp = *curiter;
+        if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type))
+        {
+            requests.push_front(tmp);
+            iter = gAssetStorage->mPendingDownloads.erase(curiter);
+        }
+    }
+    for (request_list_t::iterator iter = requests.begin();
+         iter != requests.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* tmp = *curiter;
+        if (tmp->mDownCallback)
+        {
+            if (result_code!= LL_ERR_NOERR)
+            {
+                add(sFailedDownloadCount, 1);
+            }
+            tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result_code, ext_status);
+        }
+        delete tmp;
+    }
 }
 
-
 void LLAssetStorage::downloadCompleteCallback(
-	S32 result,
-	const LLUUID& file_id,
-	LLAssetType::EType file_type,
-	LLBaseDownloadRequest* user_data, LLExtStat ext_status)
-{
-	LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << LL_ENDL;
-
-	LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id
-		 << "," << LLAssetType::lookup(file_type) << LL_ENDL;
-	LLAssetRequest* req = (LLAssetRequest*)user_data;
-	if(!req)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without"
-			"a valid request." << LL_ENDL;
-		return;
-	}
-	if (!gAssetStorage)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL;
-		return;
-	}
-
-	LLUUID callback_id;
-	LLAssetType::EType callback_type;
-
-	// Inefficient since we're doing a find through a list that may have thousands of elements.
-	// This is due for refactoring; we will probably change mPendingDownloads into a set.
-	request_list_t::iterator download_iter = std::find(gAssetStorage->mPendingDownloads.begin(), 
-													   gAssetStorage->mPendingDownloads.end(),
-													   req);
-
-	if (download_iter != gAssetStorage->mPendingDownloads.end())
-	{
-		callback_id = file_id;
-		callback_type = file_type;
-	}
-	else
-	{
-		// either has already been deleted by _cleanupRequests or it's a transfer.
-		callback_id = req->getUUID();
-		callback_type = req->getType();
-	}
-
-	if (LL_ERR_NOERR == result)
-	{
-		// we might have gotten a zero-size file
-		LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type);
-		if (vfile.getSize() <= 0)
-		{
-			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;
-			
-			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
-			vfile.remove();
-		}
-	}
-
-	// find and callback ALL pending requests for this UUID
-	// SJB: We process the callbacks in reverse order, I do not know if this is important,
-	//      but I didn't want to mess with it.
-	request_list_t requests;
-	for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin();
-		 iter != gAssetStorage->mPendingDownloads.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* tmp = *curiter;
-		if ((tmp->getUUID() == file_id) && (tmp->getType()== file_type))
-		{
-			requests.push_front(tmp);
-			iter = gAssetStorage->mPendingDownloads.erase(curiter);
-		}
-	}
-	for (request_list_t::iterator iter = requests.begin();
-		 iter != requests.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* tmp = *curiter;
-		if (tmp->mDownCallback)
-		{
-			if (result != LL_ERR_NOERR)
-			{
-				add(sFailedDownloadCount, 1);
-			}
-			tmp->mDownCallback(gAssetStorage->mVFS, callback_id, callback_type, tmp->mUserData, result, ext_status);
-		}
-		delete tmp;
-	}
-}
-
-void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
-									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype,
-									 LLGetAssetCallback callback, void *user_data, BOOL is_priority)
-{
-	LL_DEBUGS() << "LLAssetStorage::getEstateAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << ", estatetype " << etype << LL_ENDL;
-
-	//
-	// Probably will get rid of this early out?
-	//
-	if (asset_id.isNull())
-	{
-		// Special case early out for NULL uuid
-		if (callback)
-		{
-			add(sFailedDownloadCount, 1);
-			callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
-		}
-		return;
-	}
-
-	// Try static VFS first.
-	if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data))
-	{
-		return;
-	}
-	
-	BOOL exists = mVFS->getExists(asset_id, atype);
-	LLVFile file(mVFS, asset_id, atype);
-	U32 size = exists ? file.getSize() : 0;
-
-	if (size > 0)
-	{
-		// we've already got the file
-		// theoretically, partial files w/o a pending request shouldn't happen
-		// unless there's a weird error
-		if (callback)
-		{
-			callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
-		}
-	}
-	else
-	{
-		if (exists)
-		{
-			LL_WARNS() << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
-			file.remove();
-		}
-
-		// See whether we should talk to the object's originating sim, or the upstream provider.
-		LLHost source_host;
-		if (object_sim.isOk())
-		{
-			source_host = object_sim;
-		}
-		else
-		{
-			source_host = mUpstreamHost;
-		}
-		if (source_host.isOk())
-		{
-			// stash the callback info so we can find it after we get the response message
-			LLEstateAssetRequest req(asset_id, atype, etype);
-			req.mDownCallback = callback;
-			req.mUserData = user_data;
-			req.mIsPriority = is_priority;
-
-			// send request message to our upstream data provider
-			// Create a new asset transfer.
-			LLTransferSourceParamsEstate spe;
-			spe.setAgentSession(agent_id, session_id);
-			spe.setEstateAssetType(etype);
-
-			// Set our destination file, and the completion callback.
-			LLTransferTargetParamsVFile tpvf;
-			tpvf.setAsset(asset_id, atype);
-			tpvf.setCallback(downloadEstateAssetCompleteCallback, req);
-
-			LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << LL_ENDL;
-			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
-			ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f));
-		}
-		else
-		{
-			// uh-oh, we shouldn't have gotten here
-			LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
-			if (callback)
-			{
-				add(sFailedDownloadCount, 1);
-				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
-			}
-		}
-	}
+    S32 result,
+    const LLUUID& file_id,
+    LLAssetType::EType file_type,
+    LLBaseDownloadRequest* user_data,
+    LLExtStat ext_status)
+{
+    LL_DEBUGS("AssetStorage") << "ASSET_TRACE asset " << file_id << " downloadCompleteCallback" << LL_ENDL;
+
+    LL_DEBUGS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback() for " << file_id
+                              << "," << LLAssetType::lookup(file_type) << LL_ENDL;
+    LLAssetRequest* req = (LLAssetRequest*)user_data;
+    if(!req)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without"
+            "a valid request." << LL_ENDL;
+        return;
+    }
+    if (!gAssetStorage)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL;
+        return;
+    }
+
+    LLUUID callback_id;
+    LLAssetType::EType callback_type;
+
+    // Inefficient since we're doing a find through a list that may have thousands of elements.
+    // This is due for refactoring; we will probably change mPendingDownloads into a set.
+    request_list_t::iterator download_iter = std::find(gAssetStorage->mPendingDownloads.begin(), 
+                                                       gAssetStorage->mPendingDownloads.end(),
+                                                       req);
+
+    if (download_iter != gAssetStorage->mPendingDownloads.end())
+    {
+        callback_id = file_id;
+        callback_type = file_type;
+    }
+    else
+    {
+        // either has already been deleted by _cleanupRequests or it's a transfer.
+        callback_id = req->getUUID();
+        callback_type = req->getType();
+    }
+
+    if (LL_ERR_NOERR == result)
+    {
+        // we might have gotten a zero-size file
+        LLVFile vfile(gAssetStorage->mVFS, callback_id, callback_type);
+        if (vfile.getSize() <= 0)
+        {
+            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset " << callback_id << LL_ENDL;
+            
+            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
+            vfile.remove();
+        }
+        else
+        {
+#if 1
+            for (request_list_t::iterator iter = gAssetStorage->mPendingDownloads.begin();
+                 iter != gAssetStorage->mPendingDownloads.end(); ++iter  )
+            {
+                LLAssetRequest* dlreq = *iter;
+                if ((dlreq->getUUID() == file_id) && (dlreq->getType()== file_type))
+                {
+                    dlreq->mBytesFetched = vfile.getSize();
+                }
+            }
+#endif
+        }
+    }
+
+    removeAndCallbackPendingDownloads(file_id, file_type, callback_id, callback_type, ext_status, result);
+}
+
+void LLAssetStorage::getEstateAsset(
+    const LLHost &object_sim,
+    const LLUUID &agent_id, 
+    const LLUUID &session_id,
+    const LLUUID &asset_id, 
+    LLAssetType::EType atype, 
+    EstateAssetType etype,
+    LLGetAssetCallback callback, 
+    void *user_data, 
+    BOOL is_priority)
+{
+    LL_DEBUGS() << "LLAssetStorage::getEstateAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << ", estatetype " << etype << LL_ENDL;
+
+    //
+    // Probably will get rid of this early out?
+    //
+    if (asset_id.isNull())
+    {
+        // Special case early out for NULL uuid
+        if (callback)
+        {
+            add(sFailedDownloadCount, 1);
+            callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
+        }
+        return;
+    }
+
+    // Try static VFS first.
+    if (findInStaticVFSAndInvokeCallback(asset_id,atype,callback,user_data))
+    {
+        return;
+    }
+    
+    BOOL exists = mVFS->getExists(asset_id, atype);
+    LLVFile file(mVFS, asset_id, atype);
+    U32 size = exists ? file.getSize() : 0;
+
+    if (size > 0)
+    {
+        // we've already got the file
+        // theoretically, partial files w/o a pending request shouldn't happen
+        // unless there's a weird error
+        if (callback)
+        {
+            callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
+        }
+    }
+    else
+    {
+        if (exists)
+        {
+            LL_WARNS("AssetStorage") << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
+            file.remove();
+        }
+
+        // See whether we should talk to the object's originating sim, or the upstream provider.
+        LLHost source_host;
+        if (object_sim.isOk())
+        {
+            source_host = object_sim;
+        }
+        else
+        {
+            source_host = mUpstreamHost;
+        }
+        if (source_host.isOk())
+        {
+            // stash the callback info so we can find it after we get the response message
+            LLEstateAssetRequest req(asset_id, atype, etype);
+            req.mDownCallback = callback;
+            req.mUserData = user_data;
+            req.mIsPriority = is_priority;
+
+            // send request message to our upstream data provider
+            // Create a new asset transfer.
+            LLTransferSourceParamsEstate spe;
+            spe.setAgentSession(agent_id, session_id);
+            spe.setEstateAssetType(etype);
+
+            // Set our destination file, and the completion callback.
+            LLTransferTargetParamsVFile tpvf;
+            tpvf.setAsset(asset_id, atype);
+            tpvf.setCallback(downloadEstateAssetCompleteCallback, req);
+
+            LL_DEBUGS("AssetStorage") << "Starting transfer for " << asset_id << LL_ENDL;
+            LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
+            ttcp->requestTransfer(spe, tpvf, 100.f + (is_priority ? 1.f : 0.f));
+        }
+        else
+        {
+            // uh-oh, we shouldn't have gotten here
+            LL_WARNS("AssetStorage") << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
+            if (callback)
+            {
+                add(sFailedDownloadCount, 1);
+                callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
+            }
+        }
+    }
 }
 
 void LLAssetStorage::downloadEstateAssetCompleteCallback(
-	S32 result,
-	const LLUUID& file_id,
-	LLAssetType::EType file_type,
-	LLBaseDownloadRequest* user_data,
-	LLExtStat ext_status)
-{
-	LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
-	if(!req)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
-			" without a valid request." << LL_ENDL;
-		return;
-	}
-	if (!gAssetStorage)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
-			" without any asset system, aborting!" << LL_ENDL;
-		return;
-	}
-
-	req->setUUID(file_id);
-	req->setType(file_type);
-	if (LL_ERR_NOERR == result)
-	{
-		// we might have gotten a zero-size file
-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
-		if (vfile.getSize() <= 0)
-		{
-			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
-
-			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
-			vfile.remove();
-		}
-	}
-
-	if (result != LL_ERR_NOERR)
-	{
-		add(sFailedDownloadCount, 1);
-	}
-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
-}
-
-void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
-									 const LLUUID &owner_id, const LLUUID &task_id, const LLUUID &item_id,
-									 const LLUUID &asset_id, LLAssetType::EType atype,
-									 LLGetAssetCallback callback, void *user_data, BOOL is_priority)
-{
-	LL_DEBUGS() << "LLAssetStorage::getInvItemAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << LL_ENDL;
-
-	//
-	// Probably will get rid of this early out?
-	//
-	//if (asset_id.isNull())
-	//{
-	//	// Special case early out for NULL uuid
-	//	if (callback)
-	//	{
-	//		callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE);
-	//	}
-	//	return;
-	//}
-
-	bool exists = false; 
-	U32 size = 0;
-
-	if(asset_id.notNull())
-	{
-		// Try static VFS first.
-		if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data))
-		{
-			return;
-		}
-
-		exists = mVFS->getExists(asset_id, atype);
-		LLVFile file(mVFS, asset_id, atype);
-		size = exists ? file.getSize() : 0;
-		if(exists && size < 1)
-		{
-			LL_WARNS() << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
-			file.remove();
-		}
-
-	}
-
-	if (size > 0)
-	{
-		// we've already got the file
-		// theoretically, partial files w/o a pending request shouldn't happen
-		// unless there's a weird error
-		if (callback)
-		{
-			callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
-		}
-	}
-	else
-	{
-		// See whether we should talk to the object's originating sim,
-		// or the upstream provider.
-		LLHost source_host;
-		if (object_sim.isOk())
-		{
-			source_host = object_sim;
-		}
-		else
-		{
-			source_host = mUpstreamHost;
-		}
-		if (source_host.isOk())
-		{
-			// stash the callback info so we can find it after we get the response message
-			LLInvItemRequest req(asset_id, atype);
-			req.mDownCallback = callback;
-			req.mUserData = user_data;
-			req.mIsPriority = is_priority;
-
-			// send request message to our upstream data provider
-			// Create a new asset transfer.
-			LLTransferSourceParamsInvItem spi;
-			spi.setAgentSession(agent_id, session_id);
-			spi.setInvItem(owner_id, task_id, item_id);
-			spi.setAsset(asset_id, atype);
-
-			// Set our destination file, and the completion callback.
-			LLTransferTargetParamsVFile tpvf;
-			tpvf.setAsset(asset_id, atype);
-			tpvf.setCallback(downloadInvItemCompleteCallback, req);
-
-			LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset "
-				<< item_id << " owned by " << owner_id << "," << task_id
-				<< LL_ENDL;
-			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
-			ttcp->requestTransfer(spi, tpvf, 100.f + (is_priority ? 1.f : 0.f));
-		}
-		else
-		{
-			// uh-oh, we shouldn't have gotten here
-			LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
-			if (callback)
-			{
-				add(sFailedDownloadCount, 1);
-				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
-			}
-		}
-	}
+    S32 result,
+    const LLUUID& file_id,
+    LLAssetType::EType file_type,
+    LLBaseDownloadRequest* user_data,
+    LLExtStat ext_status)
+{
+    LLEstateAssetRequest *req = (LLEstateAssetRequest*)user_data;
+    if(!req)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+            " without a valid request." << LL_ENDL;
+        return;
+    }
+    if (!gAssetStorage)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+            " without any asset system, aborting!" << LL_ENDL;
+        return;
+    }
+
+    req->setUUID(file_id);
+    req->setType(file_type);
+    if (LL_ERR_NOERR == result)
+    {
+        // we might have gotten a zero-size file
+        LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getAType());
+        if (vfile.getSize() <= 0)
+        {
+            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
+
+            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
+            vfile.remove();
+        }
+    }
+
+    if (result != LL_ERR_NOERR)
+    {
+        add(sFailedDownloadCount, 1);
+    }
+    req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
+}
+
+void LLAssetStorage::getInvItemAsset(
+    const LLHost &object_sim, 
+    const LLUUID &agent_id, 
+    const LLUUID &session_id,
+    const LLUUID &owner_id,
+    const LLUUID &task_id, 
+    const LLUUID &item_id,
+    const LLUUID &asset_id, 
+    LLAssetType::EType atype,
+    LLGetAssetCallback callback, 
+    void *user_data, 
+    BOOL is_priority)
+{
+    LL_DEBUGS() << "LLAssetStorage::getInvItemAsset() - " << asset_id << "," << LLAssetType::lookup(atype) << LL_ENDL;
+
+    bool exists = false; 
+    U32 size = 0;
+
+    if(asset_id.notNull())
+    {
+        // Try static VFS first.
+        if (findInStaticVFSAndInvokeCallback( asset_id, atype, callback, user_data))
+        {
+            return;
+        }
+
+        exists = mVFS->getExists(asset_id, atype);
+        LLVFile file(mVFS, asset_id, atype);
+        size = exists ? file.getSize() : 0;
+        if(exists && size < 1)
+        {
+            LL_WARNS("AssetStorage") << "Asset vfile " << asset_id << ":" << atype << " found with bad size " << file.getSize() << ", removing" << LL_ENDL;
+            file.remove();
+        }
+
+    }
+
+    if (size > 0)
+    {
+        // we've already got the file
+        // theoretically, partial files w/o a pending request shouldn't happen
+        // unless there's a weird error
+        if (callback)
+        {
+            callback(mVFS, asset_id, atype, user_data, LL_ERR_NOERR, LL_EXSTAT_VFS_CACHED);
+        }
+    }
+    else
+    {
+        // See whether we should talk to the object's originating sim,
+        // or the upstream provider.
+        LLHost source_host;
+        if (object_sim.isOk())
+        {
+            source_host = object_sim;
+        }
+        else
+        {
+            source_host = mUpstreamHost;
+        }
+        if (source_host.isOk())
+        {
+            // stash the callback info so we can find it after we get the response message
+            LLInvItemRequest req(asset_id, atype);
+            req.mDownCallback = callback;
+            req.mUserData = user_data;
+            req.mIsPriority = is_priority;
+
+            // send request message to our upstream data provider
+            // Create a new asset transfer.
+            LLTransferSourceParamsInvItem spi;
+            spi.setAgentSession(agent_id, session_id);
+            spi.setInvItem(owner_id, task_id, item_id);
+            spi.setAsset(asset_id, atype);
+
+            LL_DEBUGS("ViewerAsset") << "requesting inv item id " << item_id << " asset_id " << asset_id << " type " << LLAssetType::lookup(atype) << LL_ENDL;
+            
+            // Set our destination file, and the completion callback.
+            LLTransferTargetParamsVFile tpvf;
+            tpvf.setAsset(asset_id, atype);
+            tpvf.setCallback(downloadInvItemCompleteCallback, req);
+
+            LL_DEBUGS("AssetStorage") << "Starting transfer for inventory asset "
+                                      << item_id << " owned by " << owner_id << "," << task_id
+                                      << LL_ENDL;
+            LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(source_host, LLTCT_ASSET);
+            ttcp->requestTransfer(spi, tpvf, 100.f + (is_priority ? 1.f : 0.f));
+        }
+        else
+        {
+            // uh-oh, we shouldn't have gotten here
+            LL_WARNS("AssetStorage") << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
+            if (callback)
+            {
+                add(sFailedDownloadCount, 1);
+                callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
+            }
+        }
+    }
 }
 
 
 void LLAssetStorage::downloadInvItemCompleteCallback(
-	S32 result,
-	const LLUUID& file_id,
-	LLAssetType::EType file_type,
-	LLBaseDownloadRequest* user_data,
-	LLExtStat ext_status)
-{
-	LLInvItemRequest *req = (LLInvItemRequest*)user_data;
-	if(!req)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
-			" without a valid request." << LL_ENDL;
-		return;
-	}
-	if (!gAssetStorage)
-	{
-		LL_WARNS() << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL;
-		return;
-	}
-
-	req->setUUID(file_id);
-	req->setType(file_type);
-	if (LL_ERR_NOERR == result)
-	{
-		// we might have gotten a zero-size file
-		LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
-		if (vfile.getSize() <= 0)
-		{
-			LL_WARNS() << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
-
-			result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
-			vfile.remove();
-		}
-	}
-
-	if (result != LL_ERR_NOERR)
-	{
-		add(sFailedDownloadCount, 1);
-	}
-	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
+    S32 result,
+    const LLUUID& file_id,
+    LLAssetType::EType file_type,
+    LLBaseDownloadRequest* user_data,
+    LLExtStat ext_status)
+{
+    LLInvItemRequest *req = (LLInvItemRequest*)user_data;
+    if(!req)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadEstateAssetCompleteCallback called"
+            " without a valid request." << LL_ENDL;
+        return;
+    }
+    if (!gAssetStorage)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::downloadCompleteCallback called without any asset system, aborting!" << LL_ENDL;
+        return;
+    }
+
+    req->setUUID(file_id);
+    req->setType(file_type);
+    if (LL_ERR_NOERR == result)
+    {
+        // we might have gotten a zero-size file
+        LLVFile vfile(gAssetStorage->mVFS, req->getUUID(), req->getType());
+        if (vfile.getSize() <= 0)
+        {
+            LL_WARNS("AssetStorage") << "downloadCompleteCallback has non-existent or zero-size asset!" << LL_ENDL;
+
+            result = LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE;
+            vfile.remove();
+        }
+    }
+
+    if (result != LL_ERR_NOERR)
+    {
+        add(sFailedDownloadCount, 1);
+    }
+    req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
 }
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -979,654 +954,558 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 // static
-void LLAssetStorage::uploadCompleteCallback(const LLUUID& uuid, void *user_data, S32 result, LLExtStat ext_status) // StoreAssetData callback (fixed)
-{
-	if (!gAssetStorage)
-	{
-		LL_WARNS() << "LLAssetStorage::uploadCompleteCallback has no gAssetStorage!" << LL_ENDL;
-		return;
-	}
-	LLAssetRequest	*req	 = (LLAssetRequest *)user_data;
-	BOOL			success  = TRUE;
-
-	if (result)
-	{
-		LL_WARNS() << "LLAssetStorage::uploadCompleteCallback " << result << ":" << getErrorString(result) << " trying to upload file to upstream provider" << LL_ENDL;
-		success = FALSE;
-	}
-
-	// we're done grabbing the file, tell the client
-	gAssetStorage->mMessageSys->newMessageFast(_PREHASH_AssetUploadComplete);
-	gAssetStorage->mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
-	gAssetStorage->mMessageSys->addUUIDFast(_PREHASH_UUID, uuid);
-	gAssetStorage->mMessageSys->addS8Fast(_PREHASH_Type, req->getType());
-	gAssetStorage->mMessageSys->addBOOLFast(_PREHASH_Success, success);
-	gAssetStorage->mMessageSys->sendReliable(req->mHost);
-
-	delete req;
+void LLAssetStorage::uploadCompleteCallback(
+    const LLUUID& uuid, 
+    void *user_data, 
+    S32 result, 
+    LLExtStat ext_status) // StoreAssetData callback (fixed)
+{
+    if (!gAssetStorage)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::uploadCompleteCallback has no gAssetStorage!" << LL_ENDL;
+        return;
+    }
+    LLAssetRequest  *req     = (LLAssetRequest *)user_data;
+    BOOL            success  = TRUE;
+
+    if (result)
+    {
+        LL_WARNS("AssetStorage") << "LLAssetStorage::uploadCompleteCallback " << result << ":" << getErrorString(result) << " trying to upload file to upstream provider" << LL_ENDL;
+        success = FALSE;
+    }
+
+    // we're done grabbing the file, tell the client
+    gAssetStorage->mMessageSys->newMessageFast(_PREHASH_AssetUploadComplete);
+    gAssetStorage->mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
+    gAssetStorage->mMessageSys->addUUIDFast(_PREHASH_UUID, uuid);
+    gAssetStorage->mMessageSys->addS8Fast(_PREHASH_Type, req->getType());
+    gAssetStorage->mMessageSys->addBOOLFast(_PREHASH_Success, success);
+    gAssetStorage->mMessageSys->sendReliable(req->mHost);
+
+    delete req;
 }
 
 void LLAssetStorage::processUploadComplete(LLMessageSystem *msg, void **user_data)
 {
-	LLAssetStorage	*this_ptr = (LLAssetStorage *)user_data;
-	LLUUID			uuid;
-	S8				asset_type_s8;
-	LLAssetType::EType asset_type;
-	BOOL			success = FALSE;
-
-	msg->getUUIDFast(_PREHASH_AssetBlock, _PREHASH_UUID, uuid);
-	msg->getS8Fast(_PREHASH_AssetBlock, _PREHASH_Type, asset_type_s8);
-	msg->getBOOLFast(_PREHASH_AssetBlock, _PREHASH_Success, success);
-
-	asset_type = (LLAssetType::EType)asset_type_s8;
-	this_ptr->_callUploadCallbacks(uuid, asset_type, success, LL_EXSTAT_NONE);
+    LLAssetStorage  *this_ptr = (LLAssetStorage *)user_data;
+    LLUUID          uuid;
+    S8              asset_type_s8;
+    LLAssetType::EType asset_type;
+    BOOL            success = FALSE;
+
+    msg->getUUIDFast(_PREHASH_AssetBlock, _PREHASH_UUID, uuid);
+    msg->getS8Fast(_PREHASH_AssetBlock, _PREHASH_Type, asset_type_s8);
+    msg->getBOOLFast(_PREHASH_AssetBlock, _PREHASH_Success, success);
+
+    asset_type = (LLAssetType::EType)asset_type_s8;
+    this_ptr->_callUploadCallbacks(uuid, asset_type, success, LL_EXSTAT_NONE);
 }
 
 void LLAssetStorage::_callUploadCallbacks(const LLUUID &uuid, LLAssetType::EType asset_type, BOOL success, LLExtStat ext_status )
 {
-	// SJB: We process the callbacks in reverse order, I do not know if this is important,
-	//      but I didn't want to mess with it.
-	request_list_t requests;
-	for (request_list_t::iterator iter = mPendingUploads.begin();
-		 iter != mPendingUploads.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* req = *curiter;
-		if ((req->getUUID() == uuid) && (req->getType() == asset_type))
-		{
-			requests.push_front(req);
-			iter = mPendingUploads.erase(curiter);
-		}
-	}
-	for (request_list_t::iterator iter = mPendingLocalUploads.begin();
-		 iter != mPendingLocalUploads.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* req = *curiter;
-		if ((req->getUUID() == uuid) && (req->getType() == asset_type))
-		{
-			requests.push_front(req);
-			iter = mPendingLocalUploads.erase(curiter);
-		}
-	}
-	for (request_list_t::iterator iter = requests.begin();
-		 iter != requests.end();  )
-	{
-		request_list_t::iterator curiter = iter++;
-		LLAssetRequest* req = *curiter;
-		if (req->mUpCallback)
-		{
-			req->mUpCallback(uuid, req->mUserData, (success ?  LL_ERR_NOERR :  LL_ERR_ASSET_REQUEST_FAILED ), ext_status );
-		}
-		delete req;
-	}
+    // SJB: We process the callbacks in reverse order, I do not know if this is important,
+    //      but I didn't want to mess with it.
+    request_list_t requests;
+    for (request_list_t::iterator iter = mPendingUploads.begin();
+         iter != mPendingUploads.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* req = *curiter;
+        if ((req->getUUID() == uuid) && (req->getType() == asset_type))
+        {
+            requests.push_front(req);
+            iter = mPendingUploads.erase(curiter);
+        }
+    }
+    for (request_list_t::iterator iter = mPendingLocalUploads.begin();
+         iter != mPendingLocalUploads.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* req = *curiter;
+        if ((req->getUUID() == uuid) && (req->getType() == asset_type))
+        {
+            requests.push_front(req);
+            iter = mPendingLocalUploads.erase(curiter);
+        }
+    }
+    for (request_list_t::iterator iter = requests.begin();
+         iter != requests.end();  )
+    {
+        request_list_t::iterator curiter = iter++;
+        LLAssetRequest* req = *curiter;
+        if (req->mUpCallback)
+        {
+            req->mUpCallback(uuid, req->mUserData, (success ?  LL_ERR_NOERR :  LL_ERR_ASSET_REQUEST_FAILED ), ext_status );
+        }
+        delete req;
+    }
 }
 
 LLAssetStorage::request_list_t* LLAssetStorage::getRequestList(LLAssetStorage::ERequestType rt)
 {
-	switch (rt)
-	{
-	case RT_DOWNLOAD:
-		return &mPendingDownloads;
-	case RT_UPLOAD:
-		return &mPendingUploads;
-	case RT_LOCALUPLOAD:
-		return &mPendingLocalUploads;
-	default:
-		LL_WARNS() << "Unable to find request list for request type '" << rt << "'" << LL_ENDL;
-		return NULL;
-	}
+    switch (rt)
+    {
+        case RT_DOWNLOAD:
+            return &mPendingDownloads;
+        case RT_UPLOAD:
+            return &mPendingUploads;
+        case RT_LOCALUPLOAD:
+            return &mPendingLocalUploads;
+        default:
+            LL_WARNS("AssetStorage") << "Unable to find request list for request type '" << rt << "'" << LL_ENDL;
+            return NULL;
+    }
 }
 
 const LLAssetStorage::request_list_t* LLAssetStorage::getRequestList(LLAssetStorage::ERequestType rt) const
 {
-	switch (rt)
-	{
-	case RT_DOWNLOAD:
-		return &mPendingDownloads;
-	case RT_UPLOAD:
-		return &mPendingUploads;
-	case RT_LOCALUPLOAD:
-		return &mPendingLocalUploads;
-	default:
-		LL_WARNS() << "Unable to find request list for request type '" << rt << "'" << LL_ENDL;
-		return NULL;
-	}
+    switch (rt)
+    {
+        case RT_DOWNLOAD:
+            return &mPendingDownloads;
+        case RT_UPLOAD:
+            return &mPendingUploads;
+        case RT_LOCALUPLOAD:
+            return &mPendingLocalUploads;
+        default:
+            LL_WARNS("AssetStorage") << "Unable to find request list for request type '" << rt << "'" << LL_ENDL;
+            return NULL;
+    }
 }
 
 // static
 std::string LLAssetStorage::getRequestName(LLAssetStorage::ERequestType rt)
 {
-	switch (rt)
-	{
-	case RT_DOWNLOAD:
-		return "download";
-	case RT_UPLOAD:
-		return "upload";
-	case RT_LOCALUPLOAD:
-		return "localupload";
-	default:
-		LL_WARNS() << "Unable to find request name for request type '" << rt << "'" << LL_ENDL;
-		return "";
-	}
+    switch (rt)
+    {
+        case RT_DOWNLOAD:
+            return "download";
+        case RT_UPLOAD:
+            return "upload";
+        case RT_LOCALUPLOAD:
+            return "localupload";
+        default:
+            LL_WARNS("AssetStorage") << "Unable to find request name for request type '" << rt << "'" << LL_ENDL;
+            return "";
+    }
 }
 
 S32 LLAssetStorage::getNumPending(LLAssetStorage::ERequestType rt) const
 {
-	const request_list_t* requests = getRequestList(rt);
-	S32 num_pending = -1;
-	if (requests)
-	{
-		num_pending = requests->size();
-	}
-	return num_pending;
+    const request_list_t* requests = getRequestList(rt);
+    S32 num_pending = -1;
+    if (requests)
+    {
+        num_pending = requests->size();
+    }
+    return num_pending;
 }
 
 S32 LLAssetStorage::getNumPendingDownloads() const
 {
-	return getNumPending(RT_DOWNLOAD);
+    return getNumPending(RT_DOWNLOAD);
 }
 
 S32 LLAssetStorage::getNumPendingUploads() const
 {
-	return getNumPending(RT_UPLOAD);
+    return getNumPending(RT_UPLOAD);
 }
 
 S32 LLAssetStorage::getNumPendingLocalUploads()
 {
-	return getNumPending(RT_LOCALUPLOAD);
+    return getNumPending(RT_LOCALUPLOAD);
 }
 
-// virtual
 LLSD LLAssetStorage::getPendingDetails(LLAssetStorage::ERequestType rt,
-										LLAssetType::EType asset_type,
-										const std::string& detail_prefix) const
+                                       LLAssetType::EType asset_type,
+                                       const std::string& detail_prefix) const
 {
-	const request_list_t* requests = getRequestList(rt);
-	LLSD sd;
-	sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix);
-	return sd;
+    const request_list_t* requests = getRequestList(rt);
+    LLSD sd;
+    sd["requests"] = getPendingDetailsImpl(requests, asset_type, detail_prefix);
+    return sd;
 }
 
-// virtual
 LLSD LLAssetStorage::getPendingDetailsImpl(const LLAssetStorage::request_list_t* requests,
-										LLAssetType::EType asset_type,
-										const std::string& detail_prefix) const
-{
-	LLSD details;
-	if (requests)
-	{
-		request_list_t::const_iterator it = requests->begin();
-		request_list_t::const_iterator end = requests->end();
-		for ( ; it != end; ++it)
-		{
-			LLAssetRequest* req = *it;
-			if (   (LLAssetType::AT_NONE == asset_type)
-				|| (req->getType() == asset_type) )
-			{
-				LLSD row = req->getTerseDetails();
-
-				std::ostringstream detail;
-				detail	<< detail_prefix << "/" << LLAssetType::lookup(req->getType())
-						<< "/" << req->getUUID();
-				row["detail"] = LLURI(detail.str());
-
-				details.append(row);
-			}
-		}
-	}
-	return details;
+                                           LLAssetType::EType asset_type,
+                                           const std::string& detail_prefix) const
+{
+    LLSD details;
+    if (requests)
+    {
+        request_list_t::const_iterator it = requests->begin();
+        request_list_t::const_iterator end = requests->end();
+        for ( ; it != end; ++it)
+        {
+            LLAssetRequest* req = *it;
+            if (   (LLAssetType::AT_NONE == asset_type)
+                   || (req->getType() == asset_type) )
+            {
+                LLSD row = req->getTerseDetails();
+
+                std::ostringstream detail;
+                detail  << detail_prefix << "/" << LLAssetType::lookup(req->getType())
+                        << "/" << req->getUUID();
+                row["detail"] = LLURI(detail.str());
+
+                details.append(row);
+            }
+        }
+    }
+    return details;
 }
 
 
 // static
 const LLAssetRequest* LLAssetStorage::findRequest(const LLAssetStorage::request_list_t* requests,
-										LLAssetType::EType asset_type,
-										const LLUUID& asset_id)
-{
-	if (requests) 
-	{
-		// Search the requests list for the asset.
-		request_list_t::const_iterator iter = requests->begin();
-		request_list_t::const_iterator end  = requests->end();
-		for (; iter != end; ++iter)
-		{
-			const LLAssetRequest* req = *iter;
-			if (asset_type == req->getType() &&
-				asset_id == req->getUUID() )
-			{
-				return req;
-			}
-		}
-	}
-	return NULL;
+                                                  LLAssetType::EType asset_type,
+                                                  const LLUUID& asset_id)
+{
+    if (requests) 
+    {
+        // Search the requests list for the asset.
+        request_list_t::const_iterator iter = requests->begin();
+        request_list_t::const_iterator end  = requests->end();
+        for (; iter != end; ++iter)
+        {
+            const LLAssetRequest* req = *iter;
+            if (asset_type == req->getType() &&
+                asset_id == req->getUUID() )
+            {
+                return req;
+            }
+        }
+    }
+    return NULL;
 }
 
 // static
 LLAssetRequest* LLAssetStorage::findRequest(LLAssetStorage::request_list_t* requests,
-										LLAssetType::EType asset_type,
-										const LLUUID& asset_id)
-{
-	if (requests) 
-	{
-		// Search the requests list for the asset.
-		request_list_t::iterator iter = requests->begin();
-		request_list_t::iterator end  = requests->end();
-		for (; iter != end; ++iter)
-		{
-			LLAssetRequest* req = *iter;
-			if (asset_type == req->getType() &&
-				asset_id == req->getUUID() )
-			{
-				return req;
-			}
-		}
-	}
-	return NULL;
+                                            LLAssetType::EType asset_type,
+                                            const LLUUID& asset_id)
+{
+    if (requests) 
+    {
+        // Search the requests list for the asset.
+        request_list_t::iterator iter = requests->begin();
+        request_list_t::iterator end  = requests->end();
+        for (; iter != end; ++iter)
+        {
+            LLAssetRequest* req = *iter;
+            if (asset_type == req->getType() &&
+                asset_id == req->getUUID() )
+            {
+                return req;
+            }
+        }
+    }
+    return NULL;
 }
 
 
-// virtual
 LLSD LLAssetStorage::getPendingRequest(LLAssetStorage::ERequestType rt,
-										LLAssetType::EType asset_type,
-										const LLUUID& asset_id) const
+                                       LLAssetType::EType asset_type,
+                                       const LLUUID& asset_id) const
 {
-	const request_list_t* requests = getRequestList(rt);
-	return getPendingRequestImpl(requests, asset_type, asset_id);
+    const request_list_t* requests = getRequestList(rt);
+    return getPendingRequestImpl(requests, asset_type, asset_id);
 }
 
-// virtual
 LLSD LLAssetStorage::getPendingRequestImpl(const LLAssetStorage::request_list_t* requests,
-										LLAssetType::EType asset_type,
-										const LLUUID& asset_id) const
+                                           LLAssetType::EType asset_type,
+                                           const LLUUID& asset_id) const
 {
-	LLSD sd;
-	const LLAssetRequest* req = findRequest(requests, asset_type, asset_id);
-	if (req)
-	{
-		sd = req->getFullDetails();
-	}
-	return sd;
+    LLSD sd;
+    const LLAssetRequest* req = findRequest(requests, asset_type, asset_id);
+    if (req)
+    {
+        sd = req->getFullDetails();
+    }
+    return sd;
 }
 
-// virtual
 bool LLAssetStorage::deletePendingRequest(LLAssetStorage::ERequestType rt,
-											LLAssetType::EType asset_type,
-											const LLUUID& asset_id)
+                                          LLAssetType::EType asset_type,
+                                          const LLUUID& asset_id)
 {
-	request_list_t* requests = getRequestList(rt);
-	if (deletePendingRequestImpl(requests, asset_type, asset_id))
-	{
-		LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for "
-				<< asset_id << "." << LLAssetType::lookup(asset_type)
-				<< " removed from pending queue." << LL_ENDL;
-		return true;
-	}
-	return false;
+    request_list_t* requests = getRequestList(rt);
+    if (deletePendingRequestImpl(requests, asset_type, asset_id))
+    {
+        LL_DEBUGS("AssetStorage") << "Asset " << getRequestName(rt) << " request for "
+                                  << asset_id << "." << LLAssetType::lookup(asset_type)
+                                  << " removed from pending queue." << LL_ENDL;
+        return true;
+    }
+    return false;
 }
 
-// virtual
 bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* requests,
-											LLAssetType::EType asset_type,
-											const LLUUID& asset_id)
-{
-	LLAssetRequest* req = findRequest(requests, asset_type, asset_id);
-	if (req)
-	{
-		// Remove the request from this list.
-		requests->remove(req);
-		S32 error = LL_ERR_TCP_TIMEOUT;
-		// Run callbacks.
-		if (req->mUpCallback)
-		{
-			req->mUpCallback(req->getUUID(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
-		}
-		if (req->mDownCallback)
-		{
-			add(sFailedDownloadCount, 1);
-			req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
-		}
-		if (req->mInfoCallback)
-		{
-			LLAssetInfo info;
-			req->mInfoCallback(&info, req->mUserData, error);
-		}
-		delete req;
-		return true;
-	}
-	
-	return false;
+                                              LLAssetType::EType asset_type,
+                                              const LLUUID& asset_id)
+{
+    LLAssetRequest* req = findRequest(requests, asset_type, asset_id);
+    if (req)
+    {
+        // Remove the request from this list.
+        requests->remove(req);
+        S32 error = LL_ERR_TCP_TIMEOUT;
+        // Run callbacks.
+        if (req->mUpCallback)
+        {
+            req->mUpCallback(req->getUUID(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
+        }
+        if (req->mDownCallback)
+        {
+            add(sFailedDownloadCount, 1);
+            req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
+        }
+        if (req->mInfoCallback)
+        {
+            LLAssetInfo info;
+            req->mInfoCallback(&info, req->mUserData, error);
+        }
+        delete req;
+        return true;
+    }
+    
+    return false;
 }
 
 // static
 const char* LLAssetStorage::getErrorString(S32 status)
 {
-	switch( status )
-	{
-	case LL_ERR_NOERR:
-		return "No error";
+    switch( status )
+    {
+        case LL_ERR_NOERR:
+            return "No error";
 
-	case LL_ERR_ASSET_REQUEST_FAILED:
-		return "Asset request: failed";
+        case LL_ERR_ASSET_REQUEST_FAILED:
+            return "Asset request: failed";
 
-	case LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE:
-		return "Asset request: non-existent file";
+        case LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE:
+            return "Asset request: non-existent file";
 
-	case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
-		return "Asset request: asset not found in database";
+        case LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE:
+            return "Asset request: asset not found in database";
 
-	case LL_ERR_EOF:
-		return "End of file";
+        case LL_ERR_EOF:
+            return "End of file";
 
-	case LL_ERR_CANNOT_OPEN_FILE:
-		return "Cannot open file";
+        case LL_ERR_CANNOT_OPEN_FILE:
+            return "Cannot open file";
 
-	case LL_ERR_FILE_NOT_FOUND:
-		return "File not found";
+        case LL_ERR_FILE_NOT_FOUND:
+            return "File not found";
 
-	case LL_ERR_TCP_TIMEOUT:
-		return "File transfer timeout";
+        case LL_ERR_TCP_TIMEOUT:
+            return "File transfer timeout";
 
-	case LL_ERR_CIRCUIT_GONE:
-		return "Circuit gone";
+        case LL_ERR_CIRCUIT_GONE:
+            return "Circuit gone";
 
-	case LL_ERR_PRICE_MISMATCH:
-		return "Viewer and server do not agree on price";
+        case LL_ERR_PRICE_MISMATCH:
+            return "Viewer and server do not agree on price";
 
-	default:
-		return "Unknown status";
-	}
+        default:
+            return "Unknown status";
+    }
 }
 
-
-
-void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, BOOL is_priority)
+void LLAssetStorage::getAssetData(const LLUUID uuid, 
+                                  LLAssetType::EType type, 
+                                  void (*callback)(const char*, 
+                                                   const LLUUID&, 
+                                                   void *, 
+                                                   S32, 
+                                                   LLExtStat), 
+                                  void *user_data, 
+                                  BOOL is_priority)
 {
-	// check for duplicates here, since we're about to fool the normal duplicate checker
-	for (request_list_t::iterator iter = mPendingDownloads.begin();
-		 iter != mPendingDownloads.end();  )
-	{
-		LLAssetRequest* tmp = *iter++;
-		if (type == tmp->getType() && 
-			uuid == tmp->getUUID() &&
-			legacyGetDataCallback == tmp->mDownCallback &&
-			callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback &&
-			user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
-		{
-			// this is a duplicate from the same subsystem - throw it away
-			LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << LL_ENDL;
-			return;
-		}
-	}
-	
-	
-	LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
-
-	legacy->mDownCallback = callback;
-	legacy->mUserData = user_data;
-
-	getAssetData(uuid, type, legacyGetDataCallback, (void **)legacy,
-				 is_priority);
-}
+    // check for duplicates here, since we're about to fool the normal duplicate checker
+    for (request_list_t::iterator iter = mPendingDownloads.begin();
+         iter != mPendingDownloads.end();  )
+    {
+        LLAssetRequest* tmp = *iter++;
+        if (type == tmp->getType() && 
+            uuid == tmp->getUUID() &&
+            legacyGetDataCallback == tmp->mDownCallback &&
+            callback == ((LLLegacyAssetRequest *)tmp->mUserData)->mDownCallback &&
+            user_data == ((LLLegacyAssetRequest *)tmp->mUserData)->mUserData)
+        {
+            // this is a duplicate from the same subsystem - throw it away
+            LL_DEBUGS("AssetStorage") << "Discarding duplicate request for UUID " << uuid << LL_ENDL;
+            return;
+        }
+    }
+    
+    
+    LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
 
-// static
-void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType type, void *user_data, S32 status, LLExtStat ext_status)
-{
-	LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data;
-	std::string filename;
-
-	// Check if the asset is marked toxic, and don't load bad stuff
-	BOOL toxic = gAssetStorage->isAssetToxic( uuid );
-
-	if ( !status
-		&& !toxic )
-	{
-		LLVFile file(vfs, uuid, type);
-
-		std::string uuid_str;
-
-		uuid.toString(uuid_str);
-		filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type));
-
-		LLFILE* fp = LLFile::fopen(filename, "wb");	/* Flawfinder: ignore */ 
-		if (fp)
-		{
-			const S32 buf_size = 65536;
-			U8 copy_buf[buf_size];
-			while (file.read(copy_buf, buf_size))	/* Flawfinder: ignore */
-			{
-				if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1)
-				{
-					// return a bad file error if we can't write the whole thing
-					status = LL_ERR_CANNOT_OPEN_FILE;
-				}
-			}
-
-			fclose(fp);
-		}
-		else
-		{
-			status = LL_ERR_CANNOT_OPEN_FILE;
-		}
-	}
-
-	if (status != LL_ERR_NOERR)
-	{
-		add(sFailedDownloadCount, 1);
-	}
-	legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status);
-	delete legacy;
-}
-
-// this is overridden on the viewer and the sim, so it doesn't really do anything
-// virtual 
-void LLAssetStorage::storeAssetData(
-	const LLTransactionID& tid,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file,
-	bool is_priority,
-	bool store_local,
-	bool user_waiting,
-	F64Seconds timeout)
-{
-	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL;
-	// LLAssetStorage metric: Virtual base call
-	reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 1" );
-}
-
-// virtual
-// this does nothing, viewer and sim both override this.
-void LLAssetStorage::storeAssetData(
-	const LLUUID& asset_id,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file ,
-	bool is_priority,
-	bool store_local,
-	const LLUUID& requesting_agent_id,
-	bool user_waiting,
-	F64Seconds timeout)
-{
-	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL;
-	// LLAssetStorage metric: Virtual base call
-	reportMetric( asset_id, asset_type, LLStringUtil::null, requesting_agent_id, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 2" );
-}
+    legacy->mDownCallback = callback;
+    legacy->mUserData = user_data;
 
-// virtual
-// this does nothing, viewer and sim both override this.
-void LLAssetStorage::storeAssetData(
-	const std::string& filename,
-	const LLUUID& asset_id,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file,
-	bool is_priority,
-	bool user_waiting,
-	F64Seconds timeout)
-{
-	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL;
-	// LLAssetStorage metric: Virtual base call
-	reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 3" );
+    getAssetData(uuid, type, legacyGetDataCallback, (void **)legacy,
+                 is_priority);
 }
 
-// virtual
-// this does nothing, viewer and sim both override this.
-void LLAssetStorage::storeAssetData(
-	const std::string& filename,
-	const LLTransactionID &transactoin_id,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file,
-	bool is_priority,
-	bool user_waiting,
-	F64Seconds timeout)
-{
-	LL_WARNS() << "storeAssetData: wrong version called" << LL_ENDL;
-	// LLAssetStorage metric: Virtual base call
-	reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_BAD_FUNCTION, __FILE__, __LINE__, "Illegal call to base: LLAssetStorage::storeAssetData 4" );
+// static
+void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs,
+                                           const LLUUID &uuid, 
+                                           LLAssetType::EType type,
+                                           void *user_data, 
+                                           S32 status, 
+                                           LLExtStat ext_status)
+{
+    LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data;
+    std::string filename;
+
+    // Check if the asset is marked toxic, and don't load bad stuff
+    BOOL toxic = gAssetStorage->isAssetToxic( uuid );
+
+    if ( !status
+         && !toxic )
+    {
+        LLVFile file(vfs, uuid, type);
+
+        std::string uuid_str;
+
+        uuid.toString(uuid_str);
+        filename = llformat("%s.%s",gDirUtilp->getExpandedFilename(LL_PATH_CACHE,uuid_str).c_str(),LLAssetType::lookup(type));
+
+        LLFILE* fp = LLFile::fopen(filename, "wb");     /* Flawfinder: ignore */ 
+        if (fp)
+        {
+            const S32 buf_size = 65536;
+            U8 copy_buf[buf_size];
+            while (file.read(copy_buf, buf_size))   /* Flawfinder: ignore */
+            {
+                if (fwrite(copy_buf, file.getLastBytesRead(), 1, fp) < 1)
+                {
+                    // return a bad file error if we can't write the whole thing
+                    status = LL_ERR_CANNOT_OPEN_FILE;
+                }
+            }
+
+            fclose(fp);
+        }
+        else
+        {
+            status = LL_ERR_CANNOT_OPEN_FILE;
+        }
+    }
+
+    if (status != LL_ERR_NOERR)
+    {
+        add(sFailedDownloadCount, 1);
+    }
+    legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status);
+    delete legacy;
 }
 
 // static
 void LLAssetStorage::legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status)
 {
-	LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data;
-	if (legacy && legacy->mUpCallback)
-	{
-		legacy->mUpCallback(uuid, legacy->mUserData, status, ext_status);
-	}
-	delete legacy;
+    LLLegacyAssetRequest *legacy = (LLLegacyAssetRequest *)user_data;
+    if (legacy && legacy->mUpCallback)
+    {
+        legacy->mUpCallback(uuid, legacy->mUserData, status, ext_status);
+    }
+    delete legacy;
 }
 
-// virtual
-void LLAssetStorage::addTempAssetData(const LLUUID& asset_id, const LLUUID& agent_id, const std::string& host_name) 
-{ }
-
-// virtual
-BOOL LLAssetStorage::hasTempAssetData(const LLUUID& texture_id) const 
-{ return FALSE; }
-
-// virtual
-std::string LLAssetStorage::getTempAssetHostName(const LLUUID& texture_id) const 
-{ return std::string(); }
-
-// virtual
-LLUUID LLAssetStorage::getTempAssetAgentID(const LLUUID& texture_id) const 
-{ return LLUUID::null; }
-
-// virtual
-void LLAssetStorage::removeTempAssetData(const LLUUID& asset_id) 
-{ }
-
-// virtual
-void LLAssetStorage::removeTempAssetDataByAgentID(const LLUUID& agent_id) 
-{ }
-
-// virtual
-void LLAssetStorage::dumpTempAssetData(const LLUUID& avatar_id) const 
-{ }
-
-// virtual
-void LLAssetStorage::clearTempAssetData() 
-{ }
-
 // static
 void LLAssetStorage::reportMetric( const LLUUID& asset_id, const LLAssetType::EType asset_type, const std::string& in_filename,
-								   const LLUUID& agent_id, S32 asset_size, EMetricResult result,
-								   const char *file, const S32 line, const std::string& in_message )
-{
-	if( !metric_recipient )
-	{
-		LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << LL_ENDL;
-		return;
-	}
-
-	std::string filename(in_filename);
-	if (filename.empty())
-		filename = ll_safe_string(file);
-	
-	// Create revised message - new_message = "in_message :: file:line"
-	std::stringstream new_message;
-	new_message << in_message << " :: " << filename << ":" << line;
-
-	// Change always_report to true if debugging... do not check it in this way
-	static bool always_report = false;
-	const char *metric_name = "LLAssetStorage::Metrics";
-
-	bool success = result == MR_OKAY;
-
-	if( (!success) || always_report )
-	{
-		LLSD stats;
-		stats["asset_id"] = asset_id;
-		stats["asset_type"] = asset_type;
-		stats["filename"] = filename;
-		stats["agent_id"] = agent_id;
-		stats["asset_size"] = (S32)asset_size;
-		stats["result"] = (S32)result;
-
-		metric_recipient->recordEventDetails( metric_name, new_message.str(), success, stats);
-	}
-	else
-	{
-		metric_recipient->recordEvent(metric_name, new_message.str(), success);
-	}
+                                   const LLUUID& agent_id, S32 asset_size, EMetricResult result,
+                                   const char *file, const S32 line, const std::string& in_message )
+{
+    if( !metric_recipient )
+    {
+        LL_DEBUGS("AssetStorage") << "Couldn't store LLAssetStoreage::reportMetric - no metrics_recipient" << LL_ENDL;
+        return;
+    }
+
+    std::string filename(in_filename);
+    if (filename.empty())
+        filename = ll_safe_string(file);
+    
+    // Create revised message - new_message = "in_message :: file:line"
+    std::stringstream new_message;
+    new_message << in_message << " :: " << filename << ":" << line;
+
+    // Change always_report to true if debugging... do not check it in this way
+    static bool always_report = false;
+    const char *metric_name = "LLAssetStorage::Metrics";
+
+    bool success = result == MR_OKAY;
+
+    if( (!success) || always_report )
+    {
+        LLSD stats;
+        stats["asset_id"] = asset_id;
+        stats["asset_type"] = asset_type;
+        stats["filename"] = filename;
+        stats["agent_id"] = agent_id;
+        stats["asset_size"] = (S32)asset_size;
+        stats["result"] = (S32)result;
+
+        metric_recipient->recordEventDetails( metric_name, new_message.str(), success, stats);
+    }
+    else
+    {
+        metric_recipient->recordEvent(metric_name, new_message.str(), success);
+    }
 }
 
 
 // Check if an asset is in the toxic map.  If it is, the entry is updated
-BOOL	LLAssetStorage::isAssetToxic( const LLUUID& uuid )
+BOOL LLAssetStorage::isAssetToxic( const LLUUID& uuid )
 {
-	BOOL is_toxic = FALSE;
-
-	if ( !uuid.isNull() )
-	{
-		toxic_asset_map_t::iterator iter = mToxicAssetMap.find( uuid );
-		if ( iter != mToxicAssetMap.end() )
-		{	// Found toxic asset
-			(*iter).second = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
-			is_toxic = TRUE;
-		} 
-	}
-	return is_toxic;
+    BOOL is_toxic = FALSE;
+
+    if ( !uuid.isNull() )
+    {
+        toxic_asset_map_t::iterator iter = mToxicAssetMap.find( uuid );
+        if ( iter != mToxicAssetMap.end() )
+        {   // Found toxic asset
+            (*iter).second = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
+            is_toxic = TRUE;
+        } 
+    }
+    return is_toxic;
 }
 
 
 
 
 // Clean the toxic asset list, remove old entries
-void	LLAssetStorage::flushOldToxicAssets( BOOL force_it )
-{
-	// Scan and look for old entries
-	U64 now = LLFrameTimer::getTotalTime();
-	toxic_asset_map_t::iterator iter = mToxicAssetMap.begin();
-	while ( iter != mToxicAssetMap.end() )
-	{
-		if ( force_it
-			|| (*iter).second < now )
-		{	// Too old - remove it
-			mToxicAssetMap.erase( iter++ );
-		}
-		else
-		{
-			iter++;
-		}
-	}
+void LLAssetStorage::flushOldToxicAssets( BOOL force_it )
+{
+    // Scan and look for old entries
+    U64 now = LLFrameTimer::getTotalTime();
+    toxic_asset_map_t::iterator iter = mToxicAssetMap.begin();
+    while ( iter != mToxicAssetMap.end() )
+    {
+        if ( force_it
+             || (*iter).second < now )
+        {   // Too old - remove it
+            mToxicAssetMap.erase( iter++ );
+        }
+        else
+        {
+            iter++;
+        }
+    }
 }
 
 
 // Add an item to the toxic asset map
-void	LLAssetStorage::markAssetToxic( const LLUUID& uuid )
-{	
-	if ( !uuid.isNull() )
-	{
-		// Set the value to the current time.  Creates a new entry if needed
-		mToxicAssetMap[ uuid ] = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
-	}
+void LLAssetStorage::markAssetToxic( const LLUUID& uuid )
+{   
+    if ( !uuid.isNull() )
+    {
+        // Set the value to the current time.  Creates a new entry if needed
+        mToxicAssetMap[ uuid ] = LLFrameTimer::getTotalTime() + TOXIC_ASSET_LIFETIME;
+    }
 }
 
 
diff --git a/indra/llmessage/llassetstorage.h b/indra/llmessage/llassetstorage.h
index 0f237540969fc8a620717168b76985aaa62a0b10..33b88473b9d2e343515745bc842ef9c8a34d86bb 100644
--- a/indra/llmessage/llassetstorage.h
+++ b/indra/llmessage/llassetstorage.h
@@ -138,6 +138,7 @@ class LLAssetRequest : public LLBaseDownloadRequest
 	BOOL	mIsUserWaiting;		// We don't want to try forever if a user is waiting for a result.
 	F64Seconds		mTimeout;			// Amount of time before timing out.
 	LLUUID	mRequestingAgentID;	// Only valid for uploads from an agent
+    F64	mBytesFetched;
 
 	virtual LLSD getTerseDetails() const;
 	virtual LLSD getFullDetails() const;
@@ -186,18 +187,9 @@ typedef std::map<LLUUID,U64,lluuid_less> toxic_asset_map_t;
 // we can use bind and remove the userData parameter.
 // 
 typedef void (*LLGetAssetCallback)(LLVFS *vfs, const LLUUID &asset_id,
-										 LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
+                                   LLAssetType::EType asset_type, void *user_data, S32 status, LLExtStat ext_status);
 
-class LLTempAssetStorage
-{
-public:
-	virtual ~LLTempAssetStorage() =0;
-	virtual void addTempAssetData(const LLUUID& asset_id,
-								  const LLUUID& agent_id,
-								  const std::string& host_name) = 0;
-};
-
-class LLAssetStorage : public LLTempAssetStorage
+class LLAssetStorage
 {
 public:
 	// VFS member is public because static child methods need it :(
@@ -240,12 +232,11 @@ class LLAssetStorage : public LLTempAssetStorage
 
 	void setUpstream(const LLHost &upstream_host);
 
-	virtual BOOL hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type);
+	BOOL hasLocalAsset(const LLUUID &uuid, LLAssetType::EType type);
 
 	// public interface methods
 	// note that your callback may get called BEFORE the function returns
-
-	virtual void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE);
+	void getAssetData(const LLUUID uuid, LLAssetType::EType atype, LLGetAssetCallback cb, void *user_data, BOOL is_priority = FALSE);
 
 	/*
 	 * TransactionID version
@@ -260,25 +251,11 @@ class LLAssetStorage : public LLTempAssetStorage
 		bool is_priority = false,
 		bool store_local = false,
 		bool user_waiting= false,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
-
-	/*
-	 * AssetID version
-	 * Sim needs both store_local and requesting_agent_id.
-	 */
-	virtual	void storeAssetData(
-		const LLUUID& asset_id,
-		LLAssetType::EType asset_type,
-		LLStoreAssetCallback callback,
-		void* user_data,
-		bool temp_file = false,
-		bool is_priority = false,
-		bool store_local = false,
-		const LLUUID& requesting_agent_id = LLUUID::null,
-		bool user_waiting= false,
-		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
+		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT) = 0;
 
-	virtual void checkForTimeouts();
+    virtual void logAssetStorageInfo() = 0;
+    
+	void checkForTimeouts();
 
 	void getEstateAsset(const LLHost &object_sim, const LLUUID &agent_id, const LLUUID &session_id,
 									const LLUUID &asset_id, LLAssetType::EType atype, EstateAssetType etype,
@@ -303,17 +280,17 @@ class LLAssetStorage : public LLTempAssetStorage
 	bool findInStaticVFSAndInvokeCallback(const LLUUID& uuid, LLAssetType::EType type,
 										  LLGetAssetCallback callback, void *user_data);
 
-	virtual LLSD getPendingDetailsImpl(const request_list_t* requests,
-	 				LLAssetType::EType asset_type,
-	 				const std::string& detail_prefix) const;
+	LLSD getPendingDetailsImpl(const request_list_t* requests,
+                               LLAssetType::EType asset_type,
+                               const std::string& detail_prefix) const;
 
-	virtual LLSD getPendingRequestImpl(const request_list_t* requests,
-							LLAssetType::EType asset_type,
-							const LLUUID& asset_id) const;
+	LLSD getPendingRequestImpl(const request_list_t* requests,
+                               LLAssetType::EType asset_type,
+                               const LLUUID& asset_id) const;
 
-	virtual bool deletePendingRequestImpl(request_list_t* requests,
-							LLAssetType::EType asset_type,
-							const LLUUID& asset_id);
+	bool deletePendingRequestImpl(request_list_t* requests,
+                                  LLAssetType::EType asset_type,
+                                  const LLUUID& asset_id);
 
 public:
 	static const LLAssetRequest* findRequest(const request_list_t* requests,
@@ -332,19 +309,23 @@ class LLAssetStorage : public LLTempAssetStorage
 	S32 getNumPendingLocalUploads();
 	S32 getNumPending(ERequestType rt) const;
 
-	virtual LLSD getPendingDetails(ERequestType rt,
-	 				LLAssetType::EType asset_type,
-	 				const std::string& detail_prefix) const;
+	LLSD getPendingDetails(ERequestType rt,
+                           LLAssetType::EType asset_type,
+                           const std::string& detail_prefix) const;
 
-	virtual LLSD getPendingRequest(ERequestType rt,
-							LLAssetType::EType asset_type,
-							const LLUUID& asset_id) const;
+	LLSD getPendingRequest(ERequestType rt,
+                           LLAssetType::EType asset_type,
+                           const LLUUID& asset_id) const;
 
-	virtual bool deletePendingRequest(ERequestType rt,
-							LLAssetType::EType asset_type,
-							const LLUUID& asset_id);
+	bool deletePendingRequest(ERequestType rt,
+                              LLAssetType::EType asset_type,
+                              const LLUUID& asset_id);
 
 
+    static void removeAndCallbackPendingDownloads(const LLUUID& file_id, LLAssetType::EType file_type,
+                                                  const LLUUID& callback_id, LLAssetType::EType callback_type,
+                                                  S32 result_code, LLExtStat ext_status);
+    
 	// download process callbacks
 	static void downloadCompleteCallback(
 		S32 result,
@@ -370,22 +351,9 @@ class LLAssetStorage : public LLTempAssetStorage
 	static const char* getErrorString( S32 status );
 
 	// deprecated file-based methods
+    // Not overriden
 	void getAssetData(const LLUUID uuid, LLAssetType::EType type, void (*callback)(const char*, const LLUUID&, void *, S32, LLExtStat), void *user_data, BOOL is_priority = FALSE);
 
-	/*
-	 * AssetID version.
-	 */
-	virtual void storeAssetData(
-		const std::string& filename,
-		const LLUUID& asset_id,
-		LLAssetType::EType type,
-		LLStoreAssetCallback callback,
-		void* user_data,
-		bool temp_file = false,
-		bool is_priority = false,
-		bool user_waiting = false,
-		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT);
-
 	/*
 	 * TransactionID version
 	 */
@@ -398,23 +366,11 @@ class LLAssetStorage : public LLTempAssetStorage
 		bool temp_file = false,
 		bool is_priority = false,
 		bool user_waiting = false,
-		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT);
+		F64Seconds timeout  = LL_ASSET_STORAGE_TIMEOUT) = 0;
 
 	static void legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAssetType::EType, void *user_data, S32 status, LLExtStat ext_status);
 	static void legacyStoreDataCallback(const LLUUID &uuid, void *user_data, S32 status, LLExtStat ext_status);
 
-	// Temp assets are stored on sim nodes, they have agent ID and location data associated with them.
-	// This is a no-op for non-http asset systems
-	virtual void addTempAssetData(const LLUUID& asset_id, const LLUUID& agent_id, const std::string& host_name);
-	virtual BOOL hasTempAssetData(const LLUUID& texture_id) const;
-	virtual std::string getTempAssetHostName(const LLUUID& texture_id) const;
-	virtual LLUUID getTempAssetAgentID(const LLUUID& texture_id) const;
-	virtual void removeTempAssetData(const LLUUID& asset_id);
-	virtual void removeTempAssetDataByAgentID(const LLUUID& agent_id);
-	// Pass LLUUID::null for all
-	virtual void dumpTempAssetData(const LLUUID& avatar_id) const;
-	virtual void clearTempAssetData();
-
 	// add extra methods to handle metadata
 
 protected:
@@ -424,7 +380,7 @@ class LLAssetStorage : public LLTempAssetStorage
 	virtual void _queueDataRequest(const LLUUID& uuid, LLAssetType::EType type,
 								   void (*callback)(LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
 								   void *user_data, BOOL duplicate,
-								   BOOL is_priority);
+								   BOOL is_priority) = 0;
 
 private:
 	void _init(LLMessageSystem *msg,
diff --git a/indra/newview/VIEWER_VERSION.txt b/indra/newview/VIEWER_VERSION.txt
index c20c645d7e49c40c6c3dc9bb4d3ae80b2cc37935..00433367c8897f3c3e3639002d04ef67a620f5aa 100644
--- a/indra/newview/VIEWER_VERSION.txt
+++ b/indra/newview/VIEWER_VERSION.txt
@@ -1 +1 @@
-5.0.6
+5.0.7
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index f4905514065710557e387b8ad40e5a5190ff817f..c544205df0a3ca7890d49a118da7f14e9f10df73 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -14705,6 +14705,17 @@
       <key>Value</key>
       <integer>0</integer>
     </map>
+    <key>AssetStorageLogFrequency</key>
+        <map>
+        <key>Comment</key>
+        <string>Seconds between display of AssetStorage info in log (0 for never)</string>
+        <key>Persist</key>
+        <integer>1</integer>
+        <key>Type</key>
+        <string>F32</string>
+        <key>Value</key>
+        <real>60.0</real>
+        </map>
     <key>LogWearableAssetSave</key>
     <map>
       <key>Comment</key>
@@ -14778,6 +14789,15 @@
         <key>Value</key>
             <real>1</real>
         </map>
+    <key>PoolSizeAssetStorage</key>
+        <map>
+        <key>Comment</key>
+            <string>Coroutine Pool size for AssetStorage requests</string>
+        <key>Type</key>
+            <string>U32</string>
+        <key>Value</key>
+            <real>12</real>
+        </map>
 
     <!-- Settings below are for back compatibility only.
     They are not used in current viewer anymore. But they can't be removed to avoid
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index f53ba01d37c7864a370f067cff3014c0829e6131..cfdc752db41e7158f92383ff33888ef9c1009343 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -844,12 +844,6 @@ bool LLAppViewer::init()
     LLMachineID::init();
 	
 	{
-		// Viewer metrics initialization
-		//static LLCachedControl<bool> metrics_submode(gSavedSettings,
-		//											 "QAModeMetrics",
-		//											 false,
-		//											 "Enables QA features (logging, faster cycling) for metrics collector");
-
 		if (gSavedSettings.getBOOL("QAModeMetrics"))
 		{
 			app_metrics_qa_mode = true;
@@ -5919,23 +5913,14 @@ void LLAppViewer::metricsSend(bool enable_reporting)
 		{
 			std::string	caps_url = regionp->getCapability("ViewerMetrics");
 
-            if (gSavedSettings.getBOOL("QAModeMetrics"))
-            {
-                dump_sequential_xml("metric_asset_stats",gViewerAssetStats->asLLSD(true));
-            }
-            
-			// Make a copy of the main stats to send into another thread.
-			// Receiving thread takes ownership.
-			LLViewerAssetStats * main_stats(new LLViewerAssetStats(*gViewerAssetStats));
-			main_stats->stop();
-			
+            LLSD sd = gViewerAssetStats->asLLSD(true);
+
 			// Send a report request into 'thread1' to get the rest of the data
 			// and provide some additional parameters while here.
 			LLAppViewer::sTextureFetch->commandSendMetrics(caps_url,
 														   gAgentSessionID,
 														   gAgentID,
-														   main_stats);
-			main_stats = 0;		// Ownership transferred
+														   sd);
 		}
 		else
 		{
diff --git a/indra/newview/llmeshrepository.cpp b/indra/newview/llmeshrepository.cpp
index f7e0e32256d6dea67c4785d73ac30cc96d0dedef..c4d1917567438d7d9497cf7692310daf3dbcb2c3 100644
--- a/indra/newview/llmeshrepository.cpp
+++ b/indra/newview/llmeshrepository.cpp
@@ -343,10 +343,6 @@ LLMeshRepository gMeshRepo;
 
 const S32 MESH_HEADER_SIZE = 4096;                      // Important:  assumption is that headers fit in this space
 
-const S32 REQUEST_HIGH_WATER_MIN = 32;					// Limits for GetMesh regions
-const S32 REQUEST_HIGH_WATER_MAX = 150;					// Should remain under 2X throttle
-const S32 REQUEST_LOW_WATER_MIN = 16;
-const S32 REQUEST_LOW_WATER_MAX = 75;
 
 const S32 REQUEST2_HIGH_WATER_MIN = 32;					// Limits for GetMesh2 regions
 const S32 REQUEST2_HIGH_WATER_MAX = 100;
@@ -808,10 +804,8 @@ LLMeshRepoThread::LLMeshRepoThread()
   mHttpLargeOptions(),
   mHttpHeaders(),
   mHttpPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-  mHttpLegacyPolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
   mHttpLargePolicyClass(LLCore::HttpRequest::DEFAULT_POLICY_ID),
-  mHttpPriority(0),
-  mGetMeshVersion(2)
+  mHttpPriority(0)
 {
 	LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
 
@@ -828,7 +822,6 @@ LLMeshRepoThread::LLMeshRepoThread()
 	mHttpHeaders = LLCore::HttpHeaders::ptr_t(new LLCore::HttpHeaders);
 	mHttpHeaders->append(HTTP_OUT_HEADER_ACCEPT, HTTP_CONTENT_VND_LL_MESH);
 	mHttpPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH2);
-	mHttpLegacyPolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_MESH1);
 	mHttpLargePolicyClass = app_core_http.getPolicy(LLAppCoreHttp::AP_LARGE_MESH);
 }
 
@@ -1103,13 +1096,9 @@ void LLMeshRepoThread::loadMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 }
 
 // Mutex:  must be holding mMutex when called
-void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1,
-									  const std::string & get_mesh2,
-									  int pref_version)
+void LLMeshRepoThread::setGetMeshCap(const std::string & mesh_cap)
 {
-	mGetMeshCapability = get_mesh1;
-	mGetMesh2Capability = get_mesh2;
-	mGetMeshVersion = pref_version;
+	mGetMeshCapability = mesh_cap;
 }
 
 
@@ -1117,29 +1106,14 @@ void LLMeshRepoThread::setGetMeshCaps(const std::string & get_mesh1,
 // over a GetMesh cap.
 //
 // Mutex:  acquires mMutex
-void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * version)
+void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url)
 {
 	std::string res_url;
-	int res_version(2);
 	
 	if (gAgent.getRegion())
 	{
 		LLMutexLock lock(mMutex);
-
-		// Get a consistent pair of (cap string, version).  The
-		// locking could be eliminated here without loss of safety
-		// by using a set of staging values in setGetMeshCaps().
-		
-		if (! mGetMesh2Capability.empty() && mGetMeshVersion > 1)
-		{
-			res_url = mGetMesh2Capability;
-			res_version = 2;
-		}
-		else
-		{
-			res_url = mGetMeshCapability;
-			res_version = 1;
-		}
+        res_url = mGetMeshCapability;
 	}
 
 	if (! res_url.empty())
@@ -1149,19 +1123,15 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver
 	}
 	else
 	{
-		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have GetMesh capability!  Cannot load "
+		LL_WARNS_ONCE(LOG_MESH) << "Current region does not have ViewerAsset capability!  Cannot load "
 								<< mesh_id << ".mesh" << LL_ENDL;
 	}
 
 	*url = res_url;
-	*version = res_version;
 }
 
 // Issue an HTTP GET request with byte range using the right
-// policy class.  Large requests go to the large request class.
-// If the current region supports GetMesh2, we prefer that for
-// smaller requests otherwise we try to use the traditional
-// GetMesh capability and connection concurrency.
+// policy class.  
 //
 // @return		Valid handle or LLCORE_HTTP_HANDLE_INVALID.
 //				If the latter, actual status is found in
@@ -1169,7 +1139,7 @@ void LLMeshRepoThread::constructUrl(LLUUID mesh_id, std::string * url, int * ver
 //				next call to this method.
 //
 // Thread:  repo
-LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int cap_version,
+LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url,
 												  size_t offset, size_t len,
 												  const LLCore::HttpHandler::ptr_t &handler)
 {
@@ -1180,16 +1150,14 @@ LLCore::HttpHandle LLMeshRepoThread::getByteRange(const std::string & url, int c
 	
 	if (len < LARGE_MESH_FETCH_THRESHOLD)
 	{
-		handle = mHttpRequest->requestGetByteRange((2 == cap_version
-													? mHttpPolicyClass
-													: mHttpLegacyPolicyClass),
-												   mHttpPriority,
-												   url,
-												   (disable_range_req ? size_t(0) : offset),
-												   (disable_range_req ? size_t(0) : len),
-												   mHttpOptions,
-												   mHttpHeaders,
-												   handler);
+		handle = mHttpRequest->requestGetByteRange( mHttpPolicyClass,
+                                                    mHttpPriority,
+                                                    url,
+                                                    (disable_range_req ? size_t(0) : offset),
+                                                    (disable_range_req ? size_t(0) : len),
+                                                    mHttpOptions,
+                                                    mHttpHeaders,
+                                                    handler);
 		if (LLCORE_HTTP_HANDLE_INVALID != handle)
 		{
 			++LLMeshRepository::sHTTPRequestCount;
@@ -1279,14 +1247,13 @@ bool LLMeshRepoThread::fetchMeshSkinInfo(const LLUUID& mesh_id)
 			}
 
 			//reading from VFS failed for whatever reason, fetch from sim
-			int cap_version(2);
 			std::string http_url;
-			constructUrl(mesh_id, &http_url, &cap_version);
+			constructUrl(mesh_id, &http_url);
 
 			if (!http_url.empty())
 			{
                 LLMeshHandlerBase::ptr_t handler(new LLMeshSkinInfoHandler(mesh_id, offset, size));
-				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
+				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
 					LL_WARNS(LOG_MESH) << "HTTP GET request failed for skin info on mesh " << mID
@@ -1372,14 +1339,13 @@ bool LLMeshRepoThread::fetchMeshDecomposition(const LLUUID& mesh_id)
 			}
 
 			//reading from VFS failed for whatever reason, fetch from sim
-			int cap_version(2);
 			std::string http_url;
-			constructUrl(mesh_id, &http_url, &cap_version);
+			constructUrl(mesh_id, &http_url);
 			
 			if (!http_url.empty())
 			{
                 LLMeshHandlerBase::ptr_t handler(new LLMeshDecompositionHandler(mesh_id, offset, size));
-				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
+				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
 					LL_WARNS(LOG_MESH) << "HTTP GET request failed for decomposition mesh " << mID
@@ -1464,14 +1430,13 @@ bool LLMeshRepoThread::fetchMeshPhysicsShape(const LLUUID& mesh_id)
 			}
 
 			//reading from VFS failed for whatever reason, fetch from sim
-			int cap_version(2);
 			std::string http_url;
-			constructUrl(mesh_id, &http_url, &cap_version);
+			constructUrl(mesh_id, &http_url);
 			
 			if (!http_url.empty())
 			{
                 LLMeshHandlerBase::ptr_t handler(new LLMeshPhysicsShapeHandler(mesh_id, offset, size));
-				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
+				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
 					LL_WARNS(LOG_MESH) << "HTTP GET request failed for physics shape on mesh " << mID
@@ -1558,9 +1523,8 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
 
 	//either cache entry doesn't exist or is corrupt, request header from simulator	
 	bool retval = true;
-	int cap_version(2);
 	std::string http_url;
-	constructUrl(mesh_params.getSculptID(), &http_url, &cap_version);
+	constructUrl(mesh_params.getSculptID(), &http_url);
 	
 	if (!http_url.empty())
 	{
@@ -1569,7 +1533,7 @@ bool LLMeshRepoThread::fetchMeshHeader(const LLVolumeParams& mesh_params)
 		//NOTE -- this will break of headers ever exceed 4KB		
 
         LLMeshHandlerBase::ptr_t handler(new LLMeshHeaderHandler(mesh_params, 0, MESH_HEADER_SIZE));
-		LLCore::HttpHandle handle = getByteRange(http_url, cap_version, 0, MESH_HEADER_SIZE, handler);
+		LLCore::HttpHandle handle = getByteRange(http_url, 0, MESH_HEADER_SIZE, handler);
 		if (LLCORE_HTTP_HANDLE_INVALID == handle)
 		{
 			LL_WARNS(LOG_MESH) << "HTTP GET request failed for mesh header " << mID
@@ -1645,14 +1609,13 @@ bool LLMeshRepoThread::fetchMeshLOD(const LLVolumeParams& mesh_params, S32 lod)
 			}
 
 			//reading from VFS failed for whatever reason, fetch from sim
-			int cap_version(2);
 			std::string http_url;
-			constructUrl(mesh_id, &http_url, &cap_version);
+			constructUrl(mesh_id, &http_url);
 			
 			if (!http_url.empty())
 			{
                 LLMeshHandlerBase::ptr_t handler(new LLMeshLODHandler(mesh_params, lod, offset, size));
-				LLCore::HttpHandle handle = getByteRange(http_url, cap_version, offset, size, handler);
+				LLCore::HttpHandle handle = getByteRange(http_url, offset, size, handler);
 				if (LLCORE_HTTP_HANDLE_INVALID == handle)
 				{
 					LL_WARNS(LOG_MESH) << "HTTP GET request failed for LOD on mesh " << mID
@@ -3292,8 +3255,7 @@ void LLMeshPhysicsShapeHandler::processData(LLCore::BufferArray * /* body */, S3
 LLMeshRepository::LLMeshRepository()
 : mMeshMutex(NULL),
   mMeshThreadCount(0),
-  mThread(NULL),
-  mGetMeshVersion(2)
+  mThread(NULL)
 {
 
 }
@@ -3476,35 +3438,21 @@ void LLMeshRepository::notifyLoadedMeshes()
 { //called from main thread
 	LL_RECORD_BLOCK_TIME(FTM_MESH_FETCH);
 
-	if (1 == mGetMeshVersion)
-	{
-		// Legacy GetMesh operation with high connection concurrency
-		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("MeshMaxConcurrentRequests");
-		LLMeshRepoThread::sRequestHighWater = llclamp(2 * S32(LLMeshRepoThread::sMaxConcurrentRequests),
-													  REQUEST_HIGH_WATER_MIN,
-													  REQUEST_HIGH_WATER_MAX);
-		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2,
-													 REQUEST_LOW_WATER_MIN,
-													 REQUEST_LOW_WATER_MAX);
-	}
-	else
-	{
-		// GetMesh2 operation with keepalives, etc.  With pipelining,
-		// we'll increase this.  See llappcorehttp and llcorehttp for
-		// discussion on connection strategies.
-		LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
-		S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2)
-				  ? (2 * LLAppCoreHttp::PIPELINING_DEPTH)
-				  : 5);
-
-		LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests");
-		LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests),
-													  REQUEST2_HIGH_WATER_MIN,
-													  REQUEST2_HIGH_WATER_MAX);
-		LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2,
-													 REQUEST2_LOW_WATER_MIN,
-													 REQUEST2_LOW_WATER_MAX);
-	}
+    // GetMesh2 operation with keepalives, etc.  With pipelining,
+    // we'll increase this.  See llappcorehttp and llcorehttp for
+    // discussion on connection strategies.
+    LLAppCoreHttp & app_core_http(LLAppViewer::instance()->getAppCoreHttp());
+    S32 scale(app_core_http.isPipelined(LLAppCoreHttp::AP_MESH2)
+              ? (2 * LLAppCoreHttp::PIPELINING_DEPTH)
+              : 5);
+
+    LLMeshRepoThread::sMaxConcurrentRequests = gSavedSettings.getU32("Mesh2MaxConcurrentRequests");
+    LLMeshRepoThread::sRequestHighWater = llclamp(scale * S32(LLMeshRepoThread::sMaxConcurrentRequests),
+                                                  REQUEST2_HIGH_WATER_MIN,
+                                                  REQUEST2_HIGH_WATER_MAX);
+    LLMeshRepoThread::sRequestLowWater = llclamp(LLMeshRepoThread::sRequestHighWater / 2,
+                                                 REQUEST2_LOW_WATER_MIN,
+                                                 REQUEST2_LOW_WATER_MAX);
 	
 	//clean up completed upload threads
 	for (std::vector<LLMeshUploadThread*>::iterator iter = mUploads.begin(); iter != mUploads.end(); )
@@ -3610,15 +3558,10 @@ void LLMeshRepository::notifyLoadedMeshes()
 			if (gAgent.getRegion()->getName() != region_name && gAgent.getRegion()->capabilitiesReceived())
 			{
 				region_name = gAgent.getRegion()->getName();
-				const bool use_v1(gSavedSettings.getBOOL("MeshUseGetMesh1"));
-				const std::string mesh1(gAgent.getRegion()->getCapability("GetMesh"));
-				const std::string mesh2(gAgent.getRegion()->getCapability("GetMesh2"));
-				mGetMeshVersion = (mesh2.empty() || use_v1) ? 1 : 2;
-				mThread->setGetMeshCaps(mesh1, mesh2, mGetMeshVersion);
+				const std::string mesh_cap(gAgent.getRegion()->getViewerAssetUrl());
+				mThread->setGetMeshCap(mesh_cap);
 				LL_DEBUGS(LOG_MESH) << "Retrieving caps for region '" << region_name
-									<< "', GetMesh2:  " << mesh2
-									<< ", GetMesh:  " << mesh1
-									<< ", using version:  " << mGetMeshVersion
+									<< "', ViewerAsset cap:  " << mesh_cap
 									<< LL_ENDL;
 			}
 		}
diff --git a/indra/newview/llmeshrepository.h b/indra/newview/llmeshrepository.h
index 30f042845ad137a6ddbb36eaad610422cb6d9354..23af837f6fdda3b4a2951c70814245785bced769 100644
--- a/indra/newview/llmeshrepository.h
+++ b/indra/newview/llmeshrepository.h
@@ -279,7 +279,6 @@ class LLMeshRepoThread : public LLThread
 	LLCore::HttpOptions::ptr_t			mHttpLargeOptions;
 	LLCore::HttpHeaders::ptr_t			mHttpHeaders;
 	LLCore::HttpRequest::policy_t		mHttpPolicyClass;
-	LLCore::HttpRequest::policy_t		mHttpLegacyPolicyClass;
 	LLCore::HttpRequest::policy_t		mHttpLargePolicyClass;
 	LLCore::HttpRequest::priority_t		mHttpPriority;
 
@@ -287,8 +286,6 @@ class LLMeshRepoThread : public LLThread
 	http_request_set					mHttpRequestSet;			// Outstanding HTTP requests
 
 	std::string mGetMeshCapability;
-	std::string mGetMesh2Capability;
-	int mGetMeshVersion;
 
 	LLMeshRepoThread();
 	~LLMeshRepoThread();
@@ -335,12 +332,10 @@ class LLMeshRepoThread : public LLThread
 	// mesh fetch URLs.
 	//
 	// Mutex:  must be holding mMutex when called
-	void setGetMeshCaps(const std::string & get_mesh1,
-						const std::string & get_mesh2,
-						int pref_version);
+	void setGetMeshCap(const std::string & get_mesh);
 
 	// Mutex:  acquires mMutex
-	void constructUrl(LLUUID mesh_id, std::string * url, int * version);
+	void constructUrl(LLUUID mesh_id, std::string * url);
 
 private:
 	// Issue a GET request to a URL with 'Range' header using
@@ -349,7 +344,7 @@ class LLMeshRepoThread : public LLThread
 	// or dispose of handler.
 	//
 	// Threads:  Repo thread only
-	LLCore::HttpHandle getByteRange(const std::string & url, int cap_version,
+	LLCore::HttpHandle getByteRange(const std::string & url, 
 									size_t offset, size_t len, 
 									const LLCore::HttpHandler::ptr_t &handler);
 };
@@ -585,8 +580,6 @@ class LLMeshRepository
 
 	void uploadError(LLSD& args);
 	void updateInventory(inventory_data data);
-
-	int mGetMeshVersion;		// Shadows value in LLMeshRepoThread
 };
 
 extern LLMeshRepository gMeshRepo;
diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp
index 07b3dc1aa48634a3c4bfba468ac20491ca329510..b78d0b51d53c4b9f623772d9cdae49be78612399 100644
--- a/indra/newview/lltexturefetch.cpp
+++ b/indra/newview/lltexturefetch.cpp
@@ -30,8 +30,6 @@
 #include <map>
 #include <algorithm>
 
-#include "llstl.h"
-
 #include "lltexturefetch.h"
 
 #include "lldir.h"
@@ -485,7 +483,7 @@ class LLTextureFetchWorker : public LLWorkerClass, public LLCore::HttpHandler
 	void recordTextureStart(bool is_http);
 
 	// Threads:  Ttf
-	void recordTextureDone(bool is_http);
+	void recordTextureDone(bool is_http, F64 byte_count);
 
 	void lockWorkMutex() { mWorkMutex.lock(); }
 	void unlockWorkMutex() { mWorkMutex.unlock(); }
@@ -824,7 +822,7 @@ class TFReqSendMetrics : public LLTextureFetch::TFRequest
     TFReqSendMetrics(const std::string & caps_url,
         const LLUUID & session_id,
         const LLUUID & agent_id,
-        LLViewerAssetStats * main_stats);
+        LLSD& stats_sd);
 	TFReqSendMetrics & operator=(const TFReqSendMetrics &);	// Not defined
 
 	virtual ~TFReqSendMetrics();
@@ -835,7 +833,7 @@ class TFReqSendMetrics : public LLTextureFetch::TFRequest
 	const std::string mCapsURL;
 	const LLUUID mSessionID;
 	const LLUUID mAgentID;
-	LLViewerAssetStats * mMainStats;
+    LLSD mStatsSD;
 
 private:
     LLCore::HttpHandler::ptr_t  mHandler;
@@ -1351,7 +1349,7 @@ bool LLTextureFetchWorker::doWork(S32 param)
 
 			if (region)
 			{
-				std::string http_url = region->getHttpUrl() ;
+				std::string http_url = region->getViewerAssetUrl();
 				if (!http_url.empty())
 				{
 					if (mFTType != FTT_DEFAULT)
@@ -1426,6 +1424,20 @@ bool LLTextureFetchWorker::doWork(S32 param)
 		}
 		if (processSimulatorPackets())
 		{
+            // Capture some measure of total size for metrics
+            F64 byte_count = 0;
+            if (mLastPacket >= mFirstPacket)
+            {
+                for (S32 i=mFirstPacket; i<=mLastPacket; i++)
+                {
+                    llassert_always((i>=0) && (i<mPackets.size()));
+                    if (mPackets[i])
+                    {
+                        byte_count += mPackets[i]->mSize;
+                    }
+                }
+            }
+
 			LL_DEBUGS(LOG_TXT) << mID << ": Loaded from Sim. Bytes: " << mFormattedImage->getDataSize() << LL_ENDL;
 			mFetcher->removeFromNetworkQueue(this, false);
 			if (mFormattedImage.isNull() || !mFormattedImage->getDataSize())
@@ -1443,7 +1455,8 @@ bool LLTextureFetchWorker::doWork(S32 param)
 			}
 			setState(DECODE_IMAGE);
 			mWriteToCacheState = SHOULD_WRITE;
-			recordTextureDone(false);
+
+			recordTextureDone(false, byte_count);
 		}
 		else
 		{
@@ -2093,7 +2106,7 @@ void LLTextureFetchWorker::onCompleted(LLCore::HttpHandle handle, LLCore::HttpRe
 
 	mFetcher->removeFromHTTPQueue(mID, data_size);
 	
-	recordTextureDone(true);
+	recordTextureDone(true, data_size);
 }																		// -Mw
 
 
@@ -2222,6 +2235,7 @@ bool LLTextureFetchWorker::processSimulatorPackets()
 		S32 buffer_size = mFormattedImage->getDataSize();
 		for (S32 i = mFirstPacket; i<=mLastPacket; i++)
 		{
+            llassert_always((i>=0) && (i<mPackets.size()));
 			llassert_always(mPackets[i]);
 			buffer_size += mPackets[i]->mSize;
 		}
@@ -2493,14 +2507,15 @@ void LLTextureFetchWorker::recordTextureStart(bool is_http)
 
 
 // Threads:  Ttf
-void LLTextureFetchWorker::recordTextureDone(bool is_http)
+void LLTextureFetchWorker::recordTextureDone(bool is_http, F64 byte_count)
 {
 	if (mMetricsStartTime.value())
 	{
 		LLViewerAssetStatsFF::record_response(LLViewerAssetType::AT_TEXTURE,
-													  is_http,
-													  LLImageBase::TYPE_AVATAR_BAKE == mType,
-													  LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime);
+                                              is_http,
+                                              LLImageBase::TYPE_AVATAR_BAKE == mType,
+                                              LLViewerAssetStatsFF::get_timestamp() - mMetricsStartTime,
+                                              byte_count);
 		mMetricsStartTime = (U32Seconds)0;
 	}
 	LLViewerAssetStatsFF::record_dequeue(LLViewerAssetType::AT_TEXTURE,
@@ -3863,9 +3878,9 @@ void LLTextureFetch::commandSetRegion(U64 region_handle)
 void LLTextureFetch::commandSendMetrics(const std::string & caps_url,
 										const LLUUID & session_id,
 										const LLUUID & agent_id,
-										LLViewerAssetStats * main_stats)
+										LLSD& stats_sd)
 {
-	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, main_stats);
+	TFReqSendMetrics * req = new TFReqSendMetrics(caps_url, session_id, agent_id, stats_sd);
 
 	cmdEnqueue(req);
 }
@@ -3974,22 +3989,20 @@ TFReqSetRegion::doWork(LLTextureFetch *)
 }
 
 TFReqSendMetrics::TFReqSendMetrics(const std::string & caps_url,
-        const LLUUID & session_id,
-        const LLUUID & agent_id,
-        LLViewerAssetStats * main_stats): 
+                                   const LLUUID & session_id,
+                                   const LLUUID & agent_id,
+                                   LLSD& stats_sd):
     LLTextureFetch::TFRequest(),
     mCapsURL(caps_url),
     mSessionID(session_id),
     mAgentID(agent_id),
-    mMainStats(main_stats),
+    mStatsSD(stats_sd),
     mHandler(new AssetReportHandler)
 {}
 
 
 TFReqSendMetrics::~TFReqSendMetrics()
 {
-	delete mMainStats;
-	mMainStats = 0;
 }
 
 
@@ -4010,26 +4023,19 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 	static volatile bool reporting_started(false);
 	static volatile S32 report_sequence(0);
     
-	// We've taken over ownership of the stats copy at this
-	// point.  Get a working reference to it for merging here
-	// but leave it in 'this'.  Destructor will rid us of it.
-	LLViewerAssetStats & main_stats = *mMainStats;
-
-	LLViewerAssetStats::AssetStats stats;
-	main_stats.getStats(stats, true);
-	//LLSD merged_llsd = main_stats.asLLSD();
+	// In mStatsSD, we have a copy we own of the LLSD representation
+	// of the asset stats. Add some additional fields and ship it off.
 
+    static const S32 metrics_data_version = 2;
+    
 	bool initial_report = !reporting_started;
-	stats.session_id = mSessionID;
-	stats.agent_id = mAgentID;
-	stats.message = "ViewerAssetMetrics";
-	stats.sequence = static_cast<bool>(report_sequence);
-	stats.initial = initial_report;
-	stats.break_ = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);
-
-	LLSD sd;
-	LLParamSDParser parser;
-	parser.writeSD(sd, stats);
+	mStatsSD["session_id"] = mSessionID;
+	mStatsSD["agent_id"] = mAgentID;
+	mStatsSD["message"] = "ViewerAssetMetrics";
+	mStatsSD["sequence"] = report_sequence;
+	mStatsSD["initial"] = initial_report;
+	mStatsSD["version"] = metrics_data_version;
+	mStatsSD["break"] = static_cast<bool>(LLTextureFetch::svMetricsDataBreak);
 		
 	// Update sequence number
 	if (S32_MAX == ++report_sequence)
@@ -4040,8 +4046,13 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 	
 	// Limit the size of the stats report if necessary.
 	
-	sd["truncated"] = truncate_viewer_metrics(10, sd);
+	mStatsSD["truncated"] = truncate_viewer_metrics(10, mStatsSD);
 
+    if (gSavedSettings.getBOOL("QAModeMetrics"))
+    {
+        dump_sequential_xml("metric_asset_stats",mStatsSD);
+    }
+            
 	if (! mCapsURL.empty())
 	{
 		// Don't care about handle, this is a fire-and-forget operation.  
@@ -4049,7 +4060,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 											fetcher->getMetricsPolicyClass(),
 											report_priority,
 											mCapsURL,
-											sd,
+											mStatsSD,
 											LLCore::HttpOptions::ptr_t(),
 											fetcher->getMetricsHeaders(),
 											mHandler);
@@ -4063,7 +4074,7 @@ TFReqSendMetrics::doWork(LLTextureFetch * fetcher)
 	// In QA mode, Metrics submode, log the result for ease of testing
 	if (fetcher->isQAMode())
 	{
-		LL_INFOS(LOG_TXT) << ll_pretty_print_sd(sd) << LL_ENDL;
+		LL_INFOS(LOG_TXT) << "ViewerAssetMetrics as submitted\n" << ll_pretty_print_sd(mStatsSD) << LL_ENDL;
 	}
 
 	return true;
@@ -4580,7 +4591,7 @@ void LLTextureFetchDebugger::debugHTTP()
 		return;
 	}
 	
-	mHTTPUrl = region->getHttpUrl();
+	mHTTPUrl = region->getViewerAssetUrl();
 	if (mHTTPUrl.empty())
 	{
 		LL_INFOS(LOG_TXT) << "Fetch Debugger : Current region URL undefined. Cannot fetch textures through HTTP." << LL_ENDL;
diff --git a/indra/newview/lltexturefetch.h b/indra/newview/lltexturefetch.h
index 072e6a330742256fb8be808668ed27479a05aebd..cfa312ccd95b2dabd94a3cb2b960aabce98cc155 100644
--- a/indra/newview/lltexturefetch.h
+++ b/indra/newview/lltexturefetch.h
@@ -160,7 +160,7 @@ class LLTextureFetch : public LLWorkerThread
 	void commandSendMetrics(const std::string & caps_url,
 							const LLUUID & session_id,
 							const LLUUID & agent_id,
-							LLViewerAssetStats * main_stats);
+							LLSD& stats_sd);
 
 	// Threads:  T*
 	void commandDataBreak();
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index 54ac29723f6cef497803737c3a63df7650b7968c..14e05fd44098ad8abc7b59e77444ab81212d9a36 100644
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -80,6 +80,47 @@
  *
  */
 
+namespace LLTrace
+{
+// This little bit of shimmery is to allow the creation of
+// default-constructed stat and event handles so we can make arrays of
+// the things.
+
+// The only sensible way to use this function is to immediately make a
+// copy of the contents, since it always returns the same pointer.
+const char *makeNewAutoName()
+{
+    static char name[64];
+    static S32 auto_namer_number = 0;
+    snprintf(name,64,"auto_name_%d",auto_namer_number);
+    auto_namer_number++;
+    return name;
+}
+
+template <typename T = F64>
+class DCCountStatHandle:
+        public CountStatHandle<T>
+{
+public:
+    DCCountStatHandle(const char *name = makeNewAutoName(), const char *description=NULL):
+        CountStatHandle<T>(name,description)
+    {
+    }
+};
+
+template <typename T = F64>
+class DCEventStatHandle:
+        public EventStatHandle<T>
+{
+public:
+    DCEventStatHandle(const char *name = makeNewAutoName(), const char *description=NULL):
+        EventStatHandle<T>(name,description)
+    {
+    }
+};
+
+}
+
 namespace LLViewerAssetStatsFF
 {
 	static EViewerAssetCategories asset_type_to_category(const LLViewerAssetType::EType at, bool with_http, bool is_temp)
@@ -90,176 +131,45 @@ namespace LLViewerAssetStatsFF
 		//  - wearables (clothing, bodyparts) which directly affect
 		//    user experiences when they log in
 		//  - sounds
-		//  - gestures
+		//  - gestures, including animations
 		//  - everything else.
 		//
-		llassert_always(50 == LLViewerAssetType::AT_COUNT);
 
-		// Multiple asset definitions are floating around so this requires some
-		// maintenance and attention.
-		static const EViewerAssetCategories asset_to_bin_map[LLViewerAssetType::AT_COUNT] =
-		{
-			EVACTextureTempHTTPGet,			// (0) AT_TEXTURE
-			EVACSoundUDPGet,				// AT_SOUND
-			EVACOtherGet,					// AT_CALLINGCARD
-			EVACOtherGet,					// AT_LANDMARK
-			EVACOtherGet,					// AT_SCRIPT
-			EVACWearableUDPGet,				// AT_CLOTHING
-			EVACOtherGet,					// AT_OBJECT
-			EVACOtherGet,					// AT_NOTECARD
-			EVACOtherGet,					// AT_CATEGORY
-			EVACOtherGet,					// AT_ROOT_CATEGORY
-			EVACOtherGet,					// (10) AT_LSL_TEXT
-			EVACOtherGet,					// AT_LSL_BYTECODE
-			EVACOtherGet,					// AT_TEXTURE_TGA
-			EVACWearableUDPGet,				// AT_BODYPART
-			EVACOtherGet,					// AT_TRASH
-			EVACOtherGet,					// AT_SNAPSHOT_CATEGORY
-			EVACOtherGet,					// AT_LOST_AND_FOUND
-			EVACSoundUDPGet,				// AT_SOUND_WAV
-			EVACOtherGet,					// AT_IMAGE_TGA
-			EVACOtherGet,					// AT_IMAGE_JPEG
-			EVACGestureUDPGet,				// (20) AT_ANIMATION
-			EVACGestureUDPGet,				// AT_GESTURE
-			EVACOtherGet,					// AT_SIMSTATE
-			EVACOtherGet,					// AT_FAVORITE
-			EVACOtherGet,					// AT_LINK
-			EVACOtherGet,					// AT_LINK_FOLDER
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// (30)
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// (40)
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					//
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// 
-			EVACOtherGet,					// AT_MESH
-			// (50)
-		};
-
-		if (at < 0 || at >= LLViewerAssetType::AT_COUNT)
-		{
-			return EVACOtherGet;
-		}
-		EViewerAssetCategories ret(asset_to_bin_map[at]);
-		if (EVACTextureTempHTTPGet == ret)
-		{
-			// Indexed with [is_temp][with_http]
-			static const EViewerAssetCategories texture_bin_map[2][2] =
-			{
-				{
-					EVACTextureNonTempUDPGet,
-					EVACTextureNonTempHTTPGet,
-				},
-				{
-					EVACTextureTempUDPGet,
-					EVACTextureTempHTTPGet,
-				}
-			};
-	
-			ret = texture_bin_map[is_temp][with_http];
-		}
+        EViewerAssetCategories ret;
+        switch (at)
+        {
+            case LLAssetType::AT_TEXTURE:
+                if (is_temp)
+                    ret = with_http ? EVACTextureTempHTTPGet : EVACTextureTempUDPGet;
+                else
+                    ret = with_http ? EVACTextureNonTempHTTPGet : EVACTextureNonTempUDPGet;
+                break;
+            case LLAssetType::AT_SOUND:
+            case LLAssetType::AT_SOUND_WAV:
+                ret = with_http ? EVACSoundHTTPGet : EVACSoundUDPGet;
+                break;
+            case LLAssetType::AT_CLOTHING:
+            case LLAssetType::AT_BODYPART:
+                ret = with_http ? EVACWearableHTTPGet : EVACWearableUDPGet;
+                break;
+            case LLAssetType::AT_ANIMATION:
+            case LLAssetType::AT_GESTURE:
+                ret = with_http ? EVACGestureHTTPGet : EVACGestureUDPGet;
+                break;
+            case LLAssetType::AT_LANDMARK:
+                ret = with_http ? EVACLandmarkHTTPGet : EVACLandmarkUDPGet;
+                break;
+            default:
+                ret = with_http ? EVACOtherHTTPGet : EVACOtherUDPGet;
+                break;
+        }
 		return ret;
 	}
 
-	static LLTrace::CountStatHandle<> sEnqueueAssetRequestsTempTextureHTTP   ("enqueuedassetrequeststemptexturehttp", 
-																	"Number of temporary texture asset http requests enqueued"),
-							sEnqueueAssetRequestsTempTextureUDP    ("enqueuedassetrequeststemptextureudp", 
-																	"Number of temporary texture asset udp requests enqueued"),
-							sEnqueueAssetRequestsNonTempTextureHTTP("enqueuedassetrequestsnontemptexturehttp", 
-																	"Number of texture asset http requests enqueued"),
-							sEnqueueAssetRequestsNonTempTextureUDP ("enqueuedassetrequestsnontemptextureudp", 
-																	"Number of texture asset udp requests enqueued"),
-							sEnqueuedAssetRequestsWearableUdp      ("enqueuedassetrequestswearableudp", 
-																	"Number of wearable asset requests enqueued"),
-							sEnqueuedAssetRequestsSoundUdp         ("enqueuedassetrequestssoundudp", 
-																	"Number of sound asset requests enqueued"),
-							sEnqueuedAssetRequestsGestureUdp       ("enqueuedassetrequestsgestureudp", 
-																	"Number of gesture asset requests enqueued"),
-							sEnqueuedAssetRequestsOther            ("enqueuedassetrequestsother", 
-																	"Number of other asset requests enqueued");
-
-	static LLTrace::CountStatHandle<>* sEnqueued[EVACCount] = {		
-		&sEnqueueAssetRequestsTempTextureHTTP,   
-		&sEnqueueAssetRequestsTempTextureUDP,  
-		&sEnqueueAssetRequestsNonTempTextureHTTP,
-		&sEnqueueAssetRequestsNonTempTextureUDP,
-		&sEnqueuedAssetRequestsWearableUdp,
-		&sEnqueuedAssetRequestsSoundUdp,
-		&sEnqueuedAssetRequestsGestureUdp,
-		&sEnqueuedAssetRequestsOther            
-	};
-	
-	static LLTrace::CountStatHandle<> sDequeueAssetRequestsTempTextureHTTP   ("dequeuedassetrequeststemptexturehttp", 
-																	"Number of temporary texture asset http requests dequeued"),
-							sDequeueAssetRequestsTempTextureUDP    ("dequeuedassetrequeststemptextureudp", 
-																	"Number of temporary texture asset udp requests dequeued"),
-							sDequeueAssetRequestsNonTempTextureHTTP("dequeuedassetrequestsnontemptexturehttp", 
-																	"Number of texture asset http requests dequeued"),
-							sDequeueAssetRequestsNonTempTextureUDP ("dequeuedassetrequestsnontemptextureudp", 
-																	"Number of texture asset udp requests dequeued"),
-							sDequeuedAssetRequestsWearableUdp      ("dequeuedassetrequestswearableudp", 
-																	"Number of wearable asset requests dequeued"),
-							sDequeuedAssetRequestsSoundUdp         ("dequeuedassetrequestssoundudp", 
-																	"Number of sound asset requests dequeued"),
-							sDequeuedAssetRequestsGestureUdp       ("dequeuedassetrequestsgestureudp", 
-																	"Number of gesture asset requests dequeued"),
-							sDequeuedAssetRequestsOther            ("dequeuedassetrequestsother", 
-																	"Number of other asset requests dequeued");
-
-	static LLTrace::CountStatHandle<>* sDequeued[EVACCount] = {
-		&sDequeueAssetRequestsTempTextureHTTP,   
-		&sDequeueAssetRequestsTempTextureUDP,  
-		&sDequeueAssetRequestsNonTempTextureHTTP,
-		&sDequeueAssetRequestsNonTempTextureUDP,
-		&sDequeuedAssetRequestsWearableUdp,
-		&sDequeuedAssetRequestsSoundUdp,
-		&sDequeuedAssetRequestsGestureUdp,
-		&sDequeuedAssetRequestsOther            
-	};
-
-	static LLTrace::EventStatHandle<F64Seconds >	sResponseAssetRequestsTempTextureHTTP   ("assetresponsetimestemptexturehttp",
-																							"Time spent responding to temporary texture asset http requests"),
-													sResponseAssetRequestsTempTextureUDP    ("assetresponsetimestemptextureudp", 
-																							"Time spent responding to temporary texture asset udp requests"),
-													sResponseAssetRequestsNonTempTextureHTTP("assetresponsetimesnontemptexturehttp", 
-																							"Time spent responding to texture asset http requests"),
-													sResponseAssetRequestsNonTempTextureUDP ("assetresponsetimesnontemptextureudp", 
-																							"Time spent responding to texture asset udp requests"),
-													sResponsedAssetRequestsWearableUdp      ("assetresponsetimeswearableudp", 
-																							"Time spent responding to wearable asset requests"),
-													sResponsedAssetRequestsSoundUdp         ("assetresponsetimessoundudp", 
-																							"Time spent responding to sound asset requests"),
-													sResponsedAssetRequestsGestureUdp       ("assetresponsetimesgestureudp", 
-																							"Time spent responding to gesture asset requests"),
-													sResponsedAssetRequestsOther            ("assetresponsetimesother", 
-																							"Time spent responding to other asset requests");
-
-	static LLTrace::EventStatHandle<F64Seconds >* sResponse[EVACCount] = {
-		&sResponseAssetRequestsTempTextureHTTP,   
-		&sResponseAssetRequestsTempTextureUDP,  
-		&sResponseAssetRequestsNonTempTextureHTTP,
-		&sResponseAssetRequestsNonTempTextureUDP,
-		&sResponsedAssetRequestsWearableUdp,
-		&sResponsedAssetRequestsSoundUdp,
-		&sResponsedAssetRequestsGestureUdp,
-		&sResponsedAssetRequestsOther            
-	};
+	static LLTrace::DCCountStatHandle<> sEnqueued[EVACCount];
+	static LLTrace::DCCountStatHandle<> sDequeued[EVACCount];
+	static LLTrace::DCEventStatHandle<> sBytesFetched[EVACCount];
+	static LLTrace::DCEventStatHandle<F64Seconds > sResponse[EVACCount];
 }
 
 // ------------------------------------------------------
@@ -353,6 +263,26 @@ void LLViewerAssetStats::setRegion(region_handle_t region_handle)
 	mRegionHandle = region_handle;
 }
 
+template <typename T>
+void LLViewerAssetStats::getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output)
+{
+	using namespace LLViewerAssetStatsFF;
+
+    if (!compact_output
+        || rec.getSampleCount(sEnqueued[cat]) 
+        || rec.getSampleCount(sDequeued[cat])
+        || rec.getSampleCount(sResponse[cat]))
+    {
+        req	.enqueued(rec.getSampleCount(sEnqueued[cat]))
+            .dequeued(rec.getSampleCount(sDequeued[cat]))
+            .resp_count(rec.getSampleCount(sResponse[cat]))
+            .resp_min(rec.getMin(sResponse[cat]).value())
+            .resp_max(rec.getMax(sResponse[cat]).value())
+            .resp_mean(rec.getMean(sResponse[cat]).value())
+            .resp_mean_bytes(rec.getMean(sBytesFetched[cat]));
+    }
+}
+
 void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
 {
 	using namespace LLViewerAssetStatsFF;
@@ -365,108 +295,22 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
 	{
 		RegionStats& r = stats.regions.add();
 		LLTrace::Recording& rec = it->second;
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACTextureTempHTTPGet]) 
-			|| rec.getSum(*sDequeued[EVACTextureTempHTTPGet])
-			|| rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value())
-		{
-			r.get_texture_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempHTTPGet]))
-									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempHTTPGet]))
-									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempHTTPGet]).value())
-									.resp_min(rec.getMin(*sResponse[EVACTextureTempHTTPGet]).value())
-									.resp_max(rec.getMax(*sResponse[EVACTextureTempHTTPGet]).value())
-									.resp_mean(rec.getMean(*sResponse[EVACTextureTempHTTPGet]).value());
-		}
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACTextureTempUDPGet]) 
-			|| rec.getSum(*sDequeued[EVACTextureTempUDPGet])
-			|| rec.getSum(*sResponse[EVACTextureTempUDPGet]).value())
-		{
-			r.get_texture_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureTempUDPGet]))
-									.dequeued((S32)rec.getSum(*sDequeued[EVACTextureTempUDPGet]))
-									.resp_count((S32)rec.getSum(*sResponse[EVACTextureTempUDPGet]).value())
-									.resp_min(rec.getMin(*sResponse[EVACTextureTempUDPGet]).value())
-									.resp_max(rec.getMax(*sResponse[EVACTextureTempUDPGet]).value())
-									.resp_mean(rec.getMean(*sResponse[EVACTextureTempUDPGet]).value());
-		}
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet]) 
-			|| rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet])
-			|| rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value())
-		{
-			r.get_texture_non_temp_http	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempHTTPGet]))
-										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempHTTPGet]))
-										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempHTTPGet]).value())
-										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempHTTPGet]).value())
-										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempHTTPGet]).value())
-										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempHTTPGet]).value());
-		}
-
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet]) 
-			|| rec.getSum(*sDequeued[EVACTextureNonTempUDPGet])
-			|| rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value())
-		{
-			r.get_texture_non_temp_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACTextureNonTempUDPGet]))
-										.dequeued((S32)rec.getSum(*sDequeued[EVACTextureNonTempUDPGet]))
-										.resp_count((S32)rec.getSum(*sResponse[EVACTextureNonTempUDPGet]).value())
-										.resp_min(rec.getMin(*sResponse[EVACTextureNonTempUDPGet]).value())
-										.resp_max(rec.getMax(*sResponse[EVACTextureNonTempUDPGet]).value())
-										.resp_mean(rec.getMean(*sResponse[EVACTextureNonTempUDPGet]).value());
-		}
-
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACWearableUDPGet]) 
-			|| rec.getSum(*sDequeued[EVACWearableUDPGet])
-			|| rec.getSum(*sResponse[EVACWearableUDPGet]).value())
-		{
-			r.get_wearable_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACWearableUDPGet]))
-								.dequeued((S32)rec.getSum(*sDequeued[EVACWearableUDPGet]))
-								.resp_count((S32)rec.getSum(*sResponse[EVACWearableUDPGet]).value())
-								.resp_min(rec.getMin(*sResponse[EVACWearableUDPGet]).value())
-								.resp_max(rec.getMax(*sResponse[EVACWearableUDPGet]).value())
-								.resp_mean(rec.getMean(*sResponse[EVACWearableUDPGet]).value());
-		}
-
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACSoundUDPGet]) 
-			|| rec.getSum(*sDequeued[EVACSoundUDPGet])
-			|| rec.getSum(*sResponse[EVACSoundUDPGet]).value())
-		{
-			r.get_sound_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACSoundUDPGet]))
-							.dequeued((S32)rec.getSum(*sDequeued[EVACSoundUDPGet]))
-							.resp_count((S32)rec.getSum(*sResponse[EVACSoundUDPGet]).value())
-							.resp_min(rec.getMin(*sResponse[EVACSoundUDPGet]).value())
-							.resp_max(rec.getMax(*sResponse[EVACSoundUDPGet]).value())
-							.resp_mean(rec.getMean(*sResponse[EVACSoundUDPGet]).value());
-		}
-
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACGestureUDPGet]) 
-			|| rec.getSum(*sDequeued[EVACGestureUDPGet])
-			|| rec.getSum(*sResponse[EVACGestureUDPGet]).value())
-		{
-			r.get_gesture_udp	.enqueued((S32)rec.getSum(*sEnqueued[EVACGestureUDPGet]))
-								.dequeued((S32)rec.getSum(*sDequeued[EVACGestureUDPGet]))
-								.resp_count((S32)rec.getSum(*sResponse[EVACGestureUDPGet]).value())
-								.resp_min(rec.getMin(*sResponse[EVACGestureUDPGet]).value())
-								.resp_max(rec.getMax(*sResponse[EVACGestureUDPGet]).value())
-								.resp_mean(rec.getMean(*sResponse[EVACGestureUDPGet]).value());
-		}
-			
-		if (!compact_output
-			|| rec.getSum(*sEnqueued[EVACOtherGet]) 
-			|| rec.getSum(*sDequeued[EVACOtherGet])
-			|| rec.getSum(*sResponse[EVACOtherGet]).value())
-			{
-			r.get_other	.enqueued((S32)rec.getSum(*sEnqueued[EVACOtherGet]))
-						.dequeued((S32)rec.getSum(*sDequeued[EVACOtherGet]))
-						.resp_count((S32)rec.getSum(*sResponse[EVACOtherGet]).value())
-						.resp_min(rec.getMin(*sResponse[EVACOtherGet]).value())
-						.resp_max(rec.getMax(*sResponse[EVACOtherGet]).value())
-						.resp_mean(rec.getMean(*sResponse[EVACOtherGet]).value());
-		}
 
+        getStat(rec, r.get_texture_temp_http, EVACTextureTempHTTPGet, compact_output);
+        getStat(rec, r.get_texture_temp_udp, EVACTextureTempUDPGet, compact_output);
+        getStat(rec, r.get_texture_non_temp_http, EVACTextureNonTempHTTPGet, compact_output);
+        getStat(rec, r.get_texture_non_temp_udp, EVACTextureNonTempUDPGet, compact_output);
+        getStat(rec, r.get_wearable_http, EVACWearableHTTPGet, compact_output);
+        getStat(rec, r.get_wearable_udp, EVACWearableUDPGet, compact_output);
+        getStat(rec, r.get_sound_http, EVACSoundHTTPGet, compact_output);
+        getStat(rec, r.get_sound_udp, EVACSoundUDPGet, compact_output);
+        getStat(rec, r.get_gesture_http, EVACGestureHTTPGet, compact_output);
+        getStat(rec, r.get_gesture_udp, EVACGestureUDPGet, compact_output);
+        getStat(rec, r.get_landmark_http, EVACLandmarkHTTPGet, compact_output);
+        getStat(rec, r.get_landmark_udp, EVACLandmarkUDPGet, compact_output);
+        getStat(rec, r.get_other_http, EVACOtherHTTPGet, compact_output);
+        getStat(rec, r.get_other_udp, EVACOtherUDPGet, compact_output);
+        
 		S32 fps = (S32)rec.getLastValue(LLStatViewer::FPS_SAMPLE);
 		if (!compact_output || fps != 0)
 		{
@@ -479,10 +323,10 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
 		grid_from_region_handle(it->first, &grid_x, &grid_y);
 		r	.grid_x(grid_x)
 			.grid_y(grid_y)
-			.duration(F64Microseconds(rec.getDuration()).value());
+			.duration(F64Seconds(rec.getDuration()).value());
 	}
 
-	stats.duration(mCurRecording ? F64Microseconds(mCurRecording->getDuration()).value() : 0.0);
+	stats.duration(mCurRecording ? F64Seconds(mCurRecording->getDuration()).value() : 0.0);
 }
 
 LLSD LLViewerAssetStats::asLLSD(bool compact_output)
@@ -518,21 +362,22 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
 {
 	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
 
-	add(*sEnqueued[int(eac)], 1);
+	add(sEnqueued[int(eac)], 1);
 }
 
 void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp)
 {
 	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
 
-	add(*sDequeued[int(eac)], 1);
+	add(sDequeued[int(eac)], 1);
 }
 
-void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration)
+void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp, LLViewerAssetStats::duration_t duration, F64 bytes)
 {
 	const EViewerAssetCategories eac(asset_type_to_category(at, with_http, is_temp));
 
-	record(*sResponse[int(eac)], F64Microseconds(duration));
+	record(sResponse[int(eac)], F64Seconds(duration));
+	record(sBytesFetched[int(eac)], bytes);
 }
 
 void init()
@@ -561,7 +406,8 @@ LLViewerAssetStats::AssetRequestType::AssetRequestType()
 	resp_count("resp_count"),
 	resp_min("resp_min"),
 	resp_max("resp_max"),
-	resp_mean("resp_mean")
+	resp_mean("resp_mean"),
+    resp_mean_bytes("resp_mean_bytes")
 {}
 	
 LLViewerAssetStats::FPSStats::FPSStats() 
@@ -576,10 +422,16 @@ LLViewerAssetStats::RegionStats::RegionStats()
 	get_texture_temp_udp("get_texture_temp_udp"),
 	get_texture_non_temp_http("get_texture_non_temp_http"),
 	get_texture_non_temp_udp("get_texture_non_temp_udp"),
+	get_wearable_http("get_wearable_http"),
 	get_wearable_udp("get_wearable_udp"),
+	get_sound_http("get_sound_http"),
 	get_sound_udp("get_sound_udp"),
+	get_gesture_http("get_gesture_http"),
 	get_gesture_udp("get_gesture_udp"),
-	get_other("get_other"),
+	get_landmark_http("get_landmark_http"),
+	get_landmark_udp("get_landmark_udp"),
+	get_other_http("get_other_http"),
+	get_other_udp("get_other_udp"),
 	fps("fps"),
 	grid_x("grid_x"),
 	grid_y("grid_y"),
diff --git a/indra/newview/llviewerassetstats.h b/indra/newview/llviewerassetstats.h
index 9d425c82fc97be4dc96bfc08ade7b45f5d688f83..718c2842247551431d1e99966926c00d6cfb1710 100644
--- a/indra/newview/llviewerassetstats.h
+++ b/indra/newview/llviewerassetstats.h
@@ -39,6 +39,29 @@
 #include "lltrace.h"
 #include "llinitparam.h"
 
+namespace LLViewerAssetStatsFF
+{
+	enum EViewerAssetCategories
+	{
+		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP
+		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP
+		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP
+		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP
+		EVACWearableHTTPGet,			//< Wearable GETs HTTP
+		EVACWearableUDPGet,				//< Wearable GETs UDP
+		EVACSoundHTTPGet,				//< Sound GETs HTTP
+		EVACSoundUDPGet,				//< Sound GETs UDP
+		EVACGestureHTTPGet,				//< Gesture GETs HTTP
+		EVACGestureUDPGet,				//< Gesture GETs UDP
+		EVACLandmarkHTTPGet,			//< Landmark GETs HTTP
+		EVACLandmarkUDPGet,				//< Landmark GETs UDP
+		EVACOtherHTTPGet,				//< Other GETs HTTP
+		EVACOtherUDPGet,				//< Other GETs UDP
+
+		EVACCount						// Must be last
+	};
+}
+
 /**
  * @class LLViewerAssetStats
  * @brief Records performance aspects of asset access operations.
@@ -74,6 +97,7 @@
  * LLViewerAssetStatsFF is provided for conditional test-and-call
  * operations.
  */
+
 class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>
 {
 public:
@@ -98,13 +122,14 @@ class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>
 						resp_count;
 		Mandatory<F64>	resp_min,
 						resp_max,
-						resp_mean;
+						resp_mean,
+						resp_mean_bytes;
 	
 		AssetRequestType();
 	};
 
 	struct FPSStats : public LLInitParam::Block<FPSStats>
-			{
+    {
 		Mandatory<S32>	count;
 		Mandatory<F64>	min,
 						max,
@@ -113,15 +138,21 @@ class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>
 	};
 
 	struct RegionStats : public LLInitParam::Block<RegionStats>
-				{
+    {
 		Optional<AssetRequestType>	get_texture_temp_http,
 									get_texture_temp_udp,
 									get_texture_non_temp_http,
 									get_texture_non_temp_udp,
+									get_wearable_http,
 									get_wearable_udp,
+									get_sound_http,
 									get_sound_udp,
+									get_gesture_http,
 									get_gesture_udp,
-									get_other;
+									get_landmark_http,
+									get_landmark_udp,
+									get_other_http,
+									get_other_udp;
 		Optional<FPSStats>			fps;
 		Optional<S32>				grid_x,
 									grid_y;
@@ -165,6 +196,11 @@ class LLViewerAssetStats : public LLStopWatchControlsMixin<LLViewerAssetStats>
 	// Retrieve current metrics for all visited regions (NULL region UUID/handle excluded)
     // Uses AssetStats structure seen above
 	void getStats(AssetStats& stats, bool compact_output);
+
+    // Retrieve a single asset request type (taken from a single region)
+    template <typename T>
+    void getStat(LLTrace::Recording& rec, T& req, LLViewerAssetStatsFF::EViewerAssetCategories cat, bool compact_output);
+
 	LLSD asLLSD(bool compact_output);
 
 protected:
@@ -205,19 +241,6 @@ extern LLViewerAssetStats * gViewerAssetStats;
 
 namespace LLViewerAssetStatsFF
 {
-	enum EViewerAssetCategories
-	{
-		EVACTextureTempHTTPGet,			//< Texture GETs - temp/baked, HTTP
-		EVACTextureTempUDPGet,			//< Texture GETs - temp/baked, UDP
-		EVACTextureNonTempHTTPGet,		//< Texture GETs - perm, HTTP
-		EVACTextureNonTempUDPGet,		//< Texture GETs - perm, UDP
-		EVACWearableUDPGet,				//< Wearable GETs
-		EVACSoundUDPGet,				//< Sound GETs
-		EVACGestureUDPGet,				//< Gesture GETs
-		EVACOtherGet,					//< Other GETs
-
-		EVACCount						// Must be last
-	};
 
 /**
  * @brief Allocation and deallocation of globals.
@@ -250,7 +273,7 @@ void record_enqueue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
 void record_dequeue(LLViewerAssetType::EType at, bool with_http, bool is_temp);
 
 void record_response(LLViewerAssetType::EType at, bool with_http, bool is_temp,
-						  LLViewerAssetStats::duration_t duration);
+                     LLViewerAssetStats::duration_t duration, F64 bytes=0);
 
 void record_avatar_stats();
 
diff --git a/indra/newview/llviewerassetstorage.cpp b/indra/newview/llviewerassetstorage.cpp
index 2db9c7e67c7d5a3867f5657c3613292027d0aa0c..e0b64403eff83099168a429174f36443ad7d82dc 100644
--- a/indra/newview/llviewerassetstorage.cpp
+++ b/indra/newview/llviewerassetstorage.cpp
@@ -33,9 +33,17 @@
 #include "message.h"
 
 #include "llagent.h"
+#include "llappcorehttp.h"
+#include "llviewerregion.h"
+
 #include "lltransfersourceasset.h"
 #include "lltransfertargetvfile.h"
 #include "llviewerassetstats.h"
+#include "llcoros.h"
+#include "llcoproceduremanager.h"
+#include "lleventcoro.h"
+#include "llsdutil.h"
+#include "llworld.h"
 
 ///----------------------------------------------------------------------------
 /// LLViewerAssetRequest
@@ -51,267 +59,283 @@
 class LLViewerAssetRequest : public LLAssetRequest
 {
 public:
-	LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type)
-		: LLAssetRequest(uuid, type),
-		  mMetricsStartTime(0)
-		{
-		}
-	
-	LLViewerAssetRequest & operator=(const LLViewerAssetRequest &);	// Not defined
-	// Default assignment operator valid
-	
-	// virtual
-	~LLViewerAssetRequest()
-		{
-			recordMetrics();
-		}
+    LLViewerAssetRequest(const LLUUID &uuid, const LLAssetType::EType type, bool with_http)
+        : LLAssetRequest(uuid, type),
+          mMetricsStartTime(0),
+          mWithHTTP(with_http)
+    {
+    }
+    
+    LLViewerAssetRequest & operator=(const LLViewerAssetRequest &); // Not defined
+    // Default assignment operator valid
+    
+    // virtual
+    ~LLViewerAssetRequest()
+    {
+        recordMetrics();
+    }
 
 protected:
-	void recordMetrics()
-		{
-			if (mMetricsStartTime.value())
-			{
-				// Okay, it appears this request was used for useful things.  Record
-				// the expected dequeue and duration of request processing.
-				LLViewerAssetStatsFF::record_dequeue(mType, false, false);
-				LLViewerAssetStatsFF::record_response(mType, false, false,
-														   (LLViewerAssetStatsFF::get_timestamp()
-															- mMetricsStartTime));
-				mMetricsStartTime = (U32Seconds)0;
-			}
-		}
-	
+    void recordMetrics()
+    {
+        if (mMetricsStartTime.value())
+        {
+            // Okay, it appears this request was used for useful things.  Record
+            // the expected dequeue and duration of request processing.
+            LLViewerAssetStatsFF::record_dequeue(mType, mWithHTTP, false);
+            LLViewerAssetStatsFF::record_response(mType, mWithHTTP, false,
+                                                  (LLViewerAssetStatsFF::get_timestamp()
+                                                   - mMetricsStartTime),
+                                                  mBytesFetched);
+            mMetricsStartTime = (U32Seconds)0;
+        }
+    }
+    
 public:
-	LLViewerAssetStats::duration_t		mMetricsStartTime;
+    LLViewerAssetStats::duration_t      mMetricsStartTime;
+    bool mWithHTTP;
 };
 
 ///----------------------------------------------------------------------------
 /// LLViewerAssetStorage
 ///----------------------------------------------------------------------------
 
+// Unused?
 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
-										   LLVFS *vfs, LLVFS *static_vfs, 
-										   const LLHost &upstream_host)
-		: LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host)
+                                           LLVFS *vfs, LLVFS *static_vfs, 
+                                           const LLHost &upstream_host)
+    : LLAssetStorage(msg, xfer, vfs, static_vfs, upstream_host),
+      mAssetCoroCount(0),
+      mCountRequests(0),
+      mCountStarted(0),
+      mCountCompleted(0),
+      mCountSucceeded(0),
+      mTotalBytesFetched(0)
 {
 }
 
 
 LLViewerAssetStorage::LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
-										   LLVFS *vfs, LLVFS *static_vfs)
-		: LLAssetStorage(msg, xfer, vfs, static_vfs)
+                                           LLVFS *vfs, LLVFS *static_vfs)
+    : LLAssetStorage(msg, xfer, vfs, static_vfs),
+      mAssetCoroCount(0),
+      mCountRequests(0),
+      mCountStarted(0),
+      mCountCompleted(0),
+      mCountSucceeded(0),
+      mTotalBytesFetched(0)
 {
 }
 
 // virtual 
 void LLViewerAssetStorage::storeAssetData(
-	const LLTransactionID& tid,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file,
-	bool is_priority,
-	bool store_local,
-	bool user_waiting,
-	F64Seconds timeout)
+    const LLTransactionID& tid,
+    LLAssetType::EType asset_type,
+    LLStoreAssetCallback callback,
+    void* user_data,
+    bool temp_file,
+    bool is_priority,
+    bool store_local,
+    bool user_waiting,
+    F64Seconds timeout)
 {
-	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
-			<< " ASSET_ID: " << asset_id << LL_ENDL;
-	
-	if (mUpstreamHost.isOk())
-	{
-		if (mVFS->getExists(asset_id, asset_type))
-		{
-			// Pack data into this packet if we can fit it.
-			U8 buffer[MTUBYTES];
-			buffer[0] = 0;
-
-			LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
-			S32 asset_size = vfile.getSize();
-
-			LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
-			req->mUpCallback = callback;
-			req->mUserData = user_data;
-
-			if (asset_size < 1)
-			{
-				// This can happen if there's a bug in our code or if the VFS has been corrupted.
-				LL_WARNS() << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL;
-				// LLAssetStorage metric: Zero size VFS
-				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
-
-				delete req;
-				if (callback)
-				{
-					callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
-				}
-				return;
-			}
-			else
-			{
-				// LLAssetStorage metric: Successful Request
-				S32 size = mVFS->getSize(asset_id, asset_type);
-				const char *message = "Added to upload queue";
-				reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
-
-				if(is_priority)
-				{
-					mPendingUploads.push_front(req);
-				}
-				else
-				{
-					mPendingUploads.push_back(req);
-				}
-			}
-
-			// Read the data from the VFS if it'll fit in this packet.
-			if (asset_size + 100 < MTUBYTES)
-			{
-				BOOL res = vfile.read(buffer, asset_size);		/* Flawfinder: ignore */
-				S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
-				
-				if( bytes_read == asset_size )
-				{
-					req->mDataSentInFirstPacket = TRUE;
-					//LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL;
-				}
-				else
-				{
-					LL_WARNS() << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL;
-
-					// LLAssetStorage metric: VFS corrupt - bogus size
-					reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" );
-
-					if (callback)
-					{
-						callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
-					}
-					return;
-				}
-			}
-			else
-			{
-				// Too big, do an xfer
-				buffer[0] = 0;
-				asset_size = 0;
-			}
-			mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
-			mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
-			mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
-			mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
-			mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
-			mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
-			mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
-			mMessageSys->sendReliable(mUpstreamHost);
-		}
-		else
-		{
-			LL_WARNS() << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL;
-			// LLAssetStorage metric: Zero size VFS
-			reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
-			if (callback)
-			{
-				callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
-			}
-		}
-	}
-	else
-	{
-		LL_WARNS() << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL;
-		// LLAssetStorage metric: Upstream provider dead
-		reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
-		if (callback)
-		{
-			callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
-		}
-	}
+    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy) " << tid << ":" << LLAssetType::lookup(asset_type)
+                              << " ASSET_ID: " << asset_id << LL_ENDL;
+    
+    if (mUpstreamHost.isOk())
+    {
+        if (mVFS->getExists(asset_id, asset_type))
+        {
+            // Pack data into this packet if we can fit it.
+            U8 buffer[MTUBYTES];
+            buffer[0] = 0;
+
+            LLVFile vfile(mVFS, asset_id, asset_type, LLVFile::READ);
+            S32 asset_size = vfile.getSize();
+
+            LLAssetRequest *req = new LLAssetRequest(asset_id, asset_type);
+            req->mUpCallback = callback;
+            req->mUserData = user_data;
+
+            if (asset_size < 1)
+            {
+                // This can happen if there's a bug in our code or if the VFS has been corrupted.
+                LL_WARNS("AssetStorage") << "LLViewerAssetStorage::storeAssetData()  Data _should_ already be in the VFS, but it's not! " << asset_id << LL_ENDL;
+                // LLAssetStorage metric: Zero size VFS
+                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
+
+                delete req;
+                if (callback)
+                {
+                    callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_VFS_CORRUPT);
+                }
+                return;
+            }
+            else
+            {
+                // LLAssetStorage metric: Successful Request
+                S32 size = mVFS->getSize(asset_id, asset_type);
+                const char *message = "Added to upload queue";
+                reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, size, MR_OKAY, __FILE__, __LINE__, message );
+
+                if(is_priority)
+                {
+                    mPendingUploads.push_front(req);
+                }
+                else
+                {
+                    mPendingUploads.push_back(req);
+                }
+            }
+
+            // Read the data from the VFS if it'll fit in this packet.
+            if (asset_size + 100 < MTUBYTES)
+            {
+                BOOL res = vfile.read(buffer, asset_size);      /* Flawfinder: ignore */
+                S32 bytes_read = res ? vfile.getLastBytesRead() : 0;
+                
+                if( bytes_read == asset_size )
+                {
+                    req->mDataSentInFirstPacket = TRUE;
+                    //LL_INFOS() << "LLViewerAssetStorage::createAsset sending data in first packet" << LL_ENDL;
+                }
+                else
+                {
+                    LL_WARNS("AssetStorage") << "Probable corruption in VFS file, aborting store asset data" << LL_ENDL;
+
+                    // LLAssetStorage metric: VFS corrupt - bogus size
+                    reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, asset_size, MR_VFS_CORRUPTION, __FILE__, __LINE__, "VFS corruption" );
+
+                    if (callback)
+                    {
+                        callback(asset_id, user_data, LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_VFS_CORRUPT);
+                    }
+                    return;
+                }
+            }
+            else
+            {
+                // Too big, do an xfer
+                buffer[0] = 0;
+                asset_size = 0;
+            }
+            mMessageSys->newMessageFast(_PREHASH_AssetUploadRequest);
+            mMessageSys->nextBlockFast(_PREHASH_AssetBlock);
+            mMessageSys->addUUIDFast(_PREHASH_TransactionID, tid);
+            mMessageSys->addS8Fast(_PREHASH_Type, (S8)asset_type);
+            mMessageSys->addBOOLFast(_PREHASH_Tempfile, temp_file);
+            mMessageSys->addBOOLFast(_PREHASH_StoreLocal, store_local);
+            mMessageSys->addBinaryDataFast( _PREHASH_AssetData, buffer, asset_size );
+            mMessageSys->sendReliable(mUpstreamHost);
+        }
+        else
+        {
+            LL_WARNS("AssetStorage") << "AssetStorage: attempt to upload non-existent vfile " << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL;
+            // LLAssetStorage metric: Zero size VFS
+            reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file didn't exist or was zero length (VFS - can't tell which)" );
+            if (callback)
+            {
+                callback(asset_id, user_data,  LL_ERR_ASSET_REQUEST_NONEXISTENT_FILE, LL_EXSTAT_NONEXISTENT_FILE);
+            }
+        }
+    }
+    else
+    {
+        LL_WARNS("AssetStorage") << "Attempt to move asset store request upstream w/o valid upstream provider" << LL_ENDL;
+        // LLAssetStorage metric: Upstream provider dead
+        reportMetric( asset_id, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_NO_UPSTREAM, __FILE__, __LINE__, "No upstream provider" );
+        if (callback)
+        {
+            callback(asset_id, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
+        }
+    }
 }
 
 void LLViewerAssetStorage::storeAssetData(
-	const std::string& filename,
-	const LLTransactionID& tid,
-	LLAssetType::EType asset_type,
-	LLStoreAssetCallback callback,
-	void* user_data,
-	bool temp_file,
-	bool is_priority,
-	bool user_waiting,
-	F64Seconds timeout)
+    const std::string& filename,
+    const LLTransactionID& tid,
+    LLAssetType::EType asset_type,
+    LLStoreAssetCallback callback,
+    void* user_data,
+    bool temp_file,
+    bool is_priority,
+    bool user_waiting,
+    F64Seconds timeout)
 {
-	if(filename.empty())
-	{
-		// LLAssetStorage metric: no filename
-		reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" );
-		LL_ERRS() << "No filename specified" << LL_ENDL;
-		return;
-	}
-	
-	LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
-	LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL;
-
-	LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL;
-
-	S32 size = 0;
-	LLFILE* fp = LLFile::fopen(filename, "rb");
-	if (fp)
-	{
-		fseek(fp, 0, SEEK_END);
-		size = ftell(fp);
-		fseek(fp, 0, SEEK_SET);
-	}
-	if( size )
-	{
-		LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
-		
-		legacy->mUpCallback = callback;
-		legacy->mUserData = user_data;
-
-		LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
-
-		file.setMaxSize(size);
-
-		const S32 buf_size = 65536;
-		U8 copy_buf[buf_size];
-		while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
-		{
-			file.write(copy_buf, size);
-		}
-		fclose(fp);
-
-		// if this upload fails, the caller needs to setup a new tempfile for us
-		if (temp_file)
-		{
-			LLFile::remove(filename);
-		}
-
-		// LLAssetStorage metric: Success not needed; handled in the overloaded method here:
-
-		LLViewerAssetStorage::storeAssetData(
-			tid,
-			asset_type,
-			legacyStoreDataCallback,
-			(void**)legacy,
-			temp_file,
-			is_priority);
-	}
-	else // size == 0 (but previous block changes size)
-	{
-		if( fp )
-		{
-			// LLAssetStorage metric: Zero size
-			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" );
-		}
-		else
-		{
-			// LLAssetStorage metric: Missing File
-			reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" );
-		}
-		if (callback)
-		{
-			callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
-		}
-	}
+    if(filename.empty())
+    {
+        // LLAssetStorage metric: no filename
+        reportMetric( LLUUID::null, asset_type, LLStringUtil::null, LLUUID::null, 0, MR_VFS_CORRUPTION, __FILE__, __LINE__, "Filename missing" );
+        LL_ERRS() << "No filename specified" << LL_ENDL;
+        return;
+    }
+    
+    LLAssetID asset_id = tid.makeAssetID(gAgent.getSecureSessionID());
+    LL_DEBUGS("AssetStorage") << "LLViewerAssetStorage::storeAssetData (legacy)" << asset_id << ":" << LLAssetType::lookup(asset_type) << LL_ENDL;
+
+    LL_DEBUGS("AssetStorage") << "ASSET_ID: " << asset_id << LL_ENDL;
+
+    S32 size = 0;
+    LLFILE* fp = LLFile::fopen(filename, "rb");
+    if (fp)
+    {
+        fseek(fp, 0, SEEK_END);
+        size = ftell(fp);
+        fseek(fp, 0, SEEK_SET);
+    }
+    if( size )
+    {
+        LLLegacyAssetRequest *legacy = new LLLegacyAssetRequest;
+        
+        legacy->mUpCallback = callback;
+        legacy->mUserData = user_data;
+
+        LLVFile file(mVFS, asset_id, asset_type, LLVFile::WRITE);
+
+        file.setMaxSize(size);
+
+        const S32 buf_size = 65536;
+        U8 copy_buf[buf_size];
+        while ((size = (S32)fread(copy_buf, 1, buf_size, fp)))
+        {
+            file.write(copy_buf, size);
+        }
+        fclose(fp);
+
+        // if this upload fails, the caller needs to setup a new tempfile for us
+        if (temp_file)
+        {
+            LLFile::remove(filename);
+        }
+
+        // LLAssetStorage metric: Success not needed; handled in the overloaded method here:
+
+        LLViewerAssetStorage::storeAssetData(
+            tid,
+            asset_type,
+            legacyStoreDataCallback,
+            (void**)legacy,
+            temp_file,
+            is_priority);
+    }
+    else // size == 0 (but previous block changes size)
+    {
+        if( fp )
+        {
+            // LLAssetStorage metric: Zero size
+            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_ZERO_SIZE, __FILE__, __LINE__, "The file was zero length" );
+        }
+        else
+        {
+            // LLAssetStorage metric: Missing File
+            reportMetric( asset_id, asset_type, filename, LLUUID::null, 0, MR_FILE_NONEXIST, __FILE__, __LINE__, "The file didn't exist" );
+        }
+        if (callback)
+        {
+            callback(asset_id, user_data, LL_ERR_CANNOT_OPEN_FILE, LL_EXSTAT_BLOCKED_FILE);
+        }
+    }
 }
 
 
@@ -334,56 +358,218 @@ void LLViewerAssetStorage::storeAssetData(
 
 // virtual
 void LLViewerAssetStorage::_queueDataRequest(
-	const LLUUID& uuid,
-	LLAssetType::EType atype,
-	LLGetAssetCallback callback,
-	void *user_data,
-	BOOL duplicate,
-	BOOL is_priority)
+    const LLUUID& uuid,
+    LLAssetType::EType atype,
+    LLGetAssetCallback callback,
+    void *user_data,
+    BOOL duplicate,
+    BOOL is_priority)
+{
+    mCountRequests++;
+    queueRequestHttp(uuid, atype, callback, user_data, duplicate, is_priority);
+}
+
+void LLViewerAssetStorage::queueRequestHttp(
+    const LLUUID& uuid,
+    LLAssetType::EType atype,
+    LLGetAssetCallback callback,
+    void *user_data,
+    BOOL duplicate,
+    BOOL is_priority)
 {
-	if (mUpstreamHost.isOk())
-	{
-		// stash the callback info so we can find it after we get the response message
-		LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype);
-		req->mDownCallback = callback;
-		req->mUserData = user_data;
-		req->mIsPriority = is_priority;
-		if (!duplicate)
-		{
-			// Only collect metrics for non-duplicate requests.  Others 
-			// are piggy-backing and will artificially lower averages.
-			req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
-		}
-		
-		mPendingDownloads.push_back(req);
-	
-		if (!duplicate)
-		{
-			// send request message to our upstream data provider
-			// Create a new asset transfer.
-			LLTransferSourceParamsAsset spa;
-			spa.setAsset(uuid, atype);
-
-			// Set our destination file, and the completion callback.
-			LLTransferTargetParamsVFile tpvf;
-			tpvf.setAsset(uuid, atype);
-			tpvf.setCallback(downloadCompleteCallback, *req);
-
-			LL_DEBUGS("AssetStorage") << "Starting transfer for " << uuid << LL_ENDL;
-			LLTransferTargetChannel *ttcp = gTransferManager.getTargetChannel(mUpstreamHost, LLTCT_ASSET);
-			ttcp->requestTransfer(spa, tpvf, 100.f + (is_priority ? 1.f : 0.f));
-
-			LLViewerAssetStatsFF::record_enqueue(atype, false, false);
-		}
-	}
-	else
-	{
-		// uh-oh, we shouldn't have gotten here
-		LL_WARNS() << "Attempt to move asset data request upstream w/o valid upstream provider" << LL_ENDL;
-		if (callback)
-		{
-			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
-		}
-	}
+    LL_DEBUGS("ViewerAsset") << "Request asset via HTTP " << uuid << " type " << LLAssetType::lookup(atype) << LL_ENDL;
+
+    bool with_http = true;
+    LLViewerAssetRequest *req = new LLViewerAssetRequest(uuid, atype, with_http);
+    req->mDownCallback = callback;
+    req->mUserData = user_data;
+    req->mIsPriority = is_priority;
+    if (!duplicate)
+    {
+        // Only collect metrics for non-duplicate requests.  Others 
+        // are piggy-backing and will artificially lower averages.
+        req->mMetricsStartTime = LLViewerAssetStatsFF::get_timestamp();
+    }
+    mPendingDownloads.push_back(req);
+
+    // This is the same as the current UDP logic - don't re-request a duplicate.
+    if (!duplicate)
+    {
+        bool with_http = true;
+        bool is_temp = false;
+        LLViewerAssetStatsFF::record_enqueue(atype, with_http, is_temp);
+
+        LLCoprocedureManager::instance().enqueueCoprocedure("AssetStorage","LLViewerAssetStorage::assetRequestCoro",
+            boost::bind(&LLViewerAssetStorage::assetRequestCoro, this, req, uuid, atype, callback, user_data));
+    }
 }
 
+void LLViewerAssetStorage::capsRecvForRegion(const LLUUID& region_id, std::string pumpname)
+{
+    LLViewerRegion *regionp = LLWorld::instance().getRegionFromID(region_id);
+    if (!regionp)
+    {
+        LL_WARNS("ViewerAsset") << "region not found for region_id " << region_id << LL_ENDL;
+    }
+    else
+    {
+        mViewerAssetUrl = regionp->getViewerAssetUrl();
+    }
+
+    LLEventPumps::instance().obtain(pumpname).post(LLSD());
+}
+
+struct LLScopedIncrement
+{
+    LLScopedIncrement(S32& counter):
+        mCounter(counter)
+    {
+        ++mCounter;
+    }
+    ~LLScopedIncrement()
+    {
+        --mCounter;
+    }
+    S32& mCounter;
+};
+
+void LLViewerAssetStorage::assetRequestCoro(
+    LLViewerAssetRequest *req,
+    const LLUUID uuid,
+    LLAssetType::EType atype,
+    LLGetAssetCallback callback,
+    void *user_data)
+{
+    LLScopedIncrement coro_count_boost(mAssetCoroCount);
+    mCountStarted++;
+    
+    S32 result_code = LL_ERR_NOERR;
+    LLExtStat ext_status = LL_EXSTAT_NONE;
+
+    if (!gAgent.getRegion())
+    {
+        LL_WARNS_ONCE("ViewerAsset") << "Asset request fails: no region set" << LL_ENDL;
+        result_code = LL_ERR_ASSET_REQUEST_FAILED;
+        ext_status = LL_EXSTAT_NONE;
+        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);
+		return;
+    }
+    else if (!gAgent.getRegion()->capabilitiesReceived())
+    {
+        LL_WARNS_ONCE("ViewerAsset") << "Waiting for capabilities" << LL_ENDL;
+
+        LLEventStream capsRecv("waitForCaps", true);
+
+        gAgent.getRegion()->setCapabilitiesReceivedCallback(
+            boost::bind(&LLViewerAssetStorage::capsRecvForRegion, this, _1, capsRecv.getName()));
+        
+        llcoro::suspendUntilEventOn(capsRecv);
+        LL_WARNS_ONCE("ViewerAsset") << "capsRecv got event" << LL_ENDL;
+        LL_WARNS_ONCE("ViewerAsset") << "region " << gAgent.getRegion() << " mViewerAssetUrl " << mViewerAssetUrl << LL_ENDL;
+    }
+    if (mViewerAssetUrl.empty() && gAgent.getRegion())
+    {
+        mViewerAssetUrl = gAgent.getRegion()->getViewerAssetUrl();
+    }
+    if (mViewerAssetUrl.empty())
+    {
+        LL_WARNS_ONCE("ViewerAsset") << "asset request fails: caps received but no viewer asset cap found" << LL_ENDL;
+        result_code = LL_ERR_ASSET_REQUEST_FAILED;
+        ext_status = LL_EXSTAT_NONE;
+        removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);
+		return;
+    }
+    std::string url = getAssetURL(mViewerAssetUrl, uuid,atype);
+    LL_DEBUGS("ViewerAsset") << "request url: " << url << LL_ENDL;
+
+    LLCore::HttpRequest::policy_t httpPolicy(LLAppCoreHttp::AP_TEXTURE);
+    LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t
+        httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("assetRequestCoro", httpPolicy));
+    LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest);
+    LLCore::HttpOptions::ptr_t httpOpts = LLCore::HttpOptions::ptr_t(new LLCore::HttpOptions);
+
+    LLSD result = httpAdapter->getRawAndSuspend(httpRequest, url, httpOpts);
+
+    if (LLApp::isQuitting())
+    {
+        // Bail out if result arrives after shutdown has been started.
+        return;
+    }
+
+    mCountCompleted++;
+    
+    LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS];
+    LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults);
+    if (!status)
+    {
+        LL_DEBUGS("ViewerAsset") << "request failed, status " << status.toTerseString() << LL_ENDL;
+        result_code = LL_ERR_ASSET_REQUEST_FAILED;
+        ext_status = LL_EXSTAT_NONE;
+    }
+    else
+    {
+        LL_DEBUGS("ViewerAsset") << "request succeeded, url " << url << LL_ENDL;
+
+        const LLSD::Binary &raw = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS_RAW].asBinary();
+
+        S32 size = raw.size();
+        if (size > 0)
+        {
+            mTotalBytesFetched += size;
+            
+			// This create-then-rename flow is modeled on
+			// LLTransferTargetVFile, which is what was used in the UDP
+			// case.
+            LLUUID temp_id;
+            temp_id.generate();
+            LLVFile vf(gAssetStorage->mVFS, temp_id, atype, LLVFile::WRITE);
+            vf.setMaxSize(size);
+            req->mBytesFetched = size;
+            if (!vf.write(raw.data(),size))
+            {
+                // TODO asset-http: handle error
+                LL_WARNS("ViewerAsset") << "Failure in vf.write()" << LL_ENDL;
+                result_code = LL_ERR_ASSET_REQUEST_FAILED;
+                ext_status = LL_EXSTAT_VFS_CORRUPT;
+            }
+            else if (!vf.rename(uuid, atype))
+            {
+                LL_WARNS("ViewerAsset") << "rename failed" << LL_ENDL;
+                result_code = LL_ERR_ASSET_REQUEST_FAILED;
+                ext_status = LL_EXSTAT_VFS_CORRUPT;
+            }
+            else
+            {
+                mCountSucceeded++;
+            }
+        }
+        else
+        {
+            // TODO asset-http: handle invalid size case
+			LL_WARNS("ViewerAsset") << "bad size" << LL_ENDL;
+            result_code = LL_ERR_ASSET_REQUEST_FAILED;
+            ext_status = LL_EXSTAT_NONE;
+        }
+    }
+
+    // Clean up pending downloads and trigger callbacks
+    removeAndCallbackPendingDownloads(uuid, atype, uuid, atype, result_code, ext_status);
+}
+
+std::string LLViewerAssetStorage::getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype)
+{
+    std::string type_name = LLAssetType::lookup(atype);
+    std::string url = cap_url + "/?" + type_name + "_id=" + uuid.asString();
+    return url;
+}
+
+void LLViewerAssetStorage::logAssetStorageInfo()
+{
+    LLMemory::logMemoryInfo(true);
+    LL_INFOS("AssetStorage") << "Active coros " << mAssetCoroCount << LL_ENDL;
+    LL_INFOS("AssetStorage") << "mPendingDownloads size " << mPendingDownloads.size() << LL_ENDL;
+    LL_INFOS("AssetStorage") << "mCountStarted " << mCountStarted << LL_ENDL;
+    LL_INFOS("AssetStorage") << "mCountCompleted " << mCountCompleted << LL_ENDL;
+    LL_INFOS("AssetStorage") << "mCountSucceeded " << mCountSucceeded << LL_ENDL;
+    LL_INFOS("AssetStorage") << "mTotalBytesFetched " << mTotalBytesFetched << LL_ENDL;
+}
diff --git a/indra/newview/llviewerassetstorage.h b/indra/newview/llviewerassetstorage.h
index 6baec647e60e0886cb6a0e9e5f3cb1ac33338eee..50131682e7f98f7a3f1d476ce7b4714564bf004d 100644
--- a/indra/newview/llviewerassetstorage.h
+++ b/indra/newview/llviewerassetstorage.h
@@ -28,10 +28,12 @@
 #define LLVIEWERASSETSTORAGE_H
 
 #include "llassetstorage.h"
-//#include "curl/curl.h"
+#include "llcorehttputil.h"
 
 class LLVFile;
 
+class LLViewerAssetRequest;
+
 class LLViewerAssetStorage : public LLAssetStorage
 {
 public:
@@ -41,7 +43,6 @@ class LLViewerAssetStorage : public LLAssetStorage
 	LLViewerAssetStorage(LLMessageSystem *msg, LLXferManager *xfer,
 				   LLVFS *vfs, LLVFS *static_vfs);
 
-	using LLAssetStorage::storeAssetData;
 	virtual void storeAssetData(
 		const LLTransactionID& tid,
 		LLAssetType::EType atype,
@@ -65,8 +66,6 @@ class LLViewerAssetStorage : public LLAssetStorage
 		F64Seconds timeout=LL_ASSET_STORAGE_TIMEOUT);
 
 protected:
-	using LLAssetStorage::_queueDataRequest;
-
 	// virtual
 	void _queueDataRequest(const LLUUID& uuid,
 						   LLAssetType::EType type,
@@ -74,6 +73,33 @@ class LLViewerAssetStorage : public LLAssetStorage
 						   void *user_data,
 						   BOOL duplicate,
 						   BOOL is_priority);
+
+    void queueRequestHttp(const LLUUID& uuid,
+                          LLAssetType::EType type,
+                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+                          void *user_data,
+                          BOOL duplicate,
+                          BOOL is_priority);
+
+    void capsRecvForRegion(const LLUUID& region_id, std::string pumpname);
+    
+    void assetRequestCoro(LLViewerAssetRequest *req,
+                          const LLUUID uuid,
+                          LLAssetType::EType atype,
+                          void (*callback) (LLVFS *vfs, const LLUUID&, LLAssetType::EType, void *, S32, LLExtStat),
+                          void *user_data);
+
+    std::string getAssetURL(const std::string& cap_url, const LLUUID& uuid, LLAssetType::EType atype);
+
+    void logAssetStorageInfo();
+    
+    std::string mViewerAssetUrl;
+    S32 mAssetCoroCount;
+    S32 mCountRequests;
+    S32 mCountStarted;
+    S32 mCountCompleted;
+    S32 mCountSucceeded;
+    S64 mTotalBytesFetched;
 };
 
 #endif
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index afa00e3e6e54dd6c68fe34250eda3c5536381e7b..bfa9fa03fa812411239e430460bb25f0a217db02 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -106,6 +106,7 @@ const F32 TELEPORT_EXPIRY_PER_ATTACHMENT = 3.f;
 U32 gRecentFrameCount = 0; // number of 'recent' frames
 LLFrameTimer gRecentFPSTime;
 LLFrameTimer gRecentMemoryTime;
+LLFrameTimer gAssetStorageLogTime;
 
 // Rendering stuff
 void pre_show_depth_buffer();
@@ -226,6 +227,12 @@ void display_stats()
 		LLMemory::logMemoryInfo(TRUE) ;
 		gRecentMemoryTime.reset();
 	}
+    F32 asset_storage_log_freq = gSavedSettings.getF32("AssetStorageLogFrequency");
+    if (asset_storage_log_freq > 0.f && gAssetStorageLogTime.getElapsedTimeF32() >= asset_storage_log_freq)
+    {
+        gAssetStorageLogTime.reset();
+        gAssetStorage->logAssetStorageInfo();
+    }
 }
 
 static LLTrace::BlockTimerStatHandle FTM_PICK("Picking");
diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp
index 899ab3a3717efe7984672cdb251f9a46fc256e06..eb37613c955e64f2aa31186e89ea3aa8df4fc38b 100644
--- a/indra/newview/llviewerregion.cpp
+++ b/indra/newview/llviewerregion.cpp
@@ -521,7 +521,7 @@ LLViewerRegion::LLViewerRegion(const U64 &handle,
 	mColoName("unknown"),
 	mProductSKU("unknown"),
 	mProductName("unknown"),
-	mHttpUrl(""),
+	mViewerAssetUrl(""),
 	mCacheLoaded(FALSE),
 	mCacheDirty(FALSE),
 	mReleaseNotesRequested(FALSE),
@@ -2843,12 +2843,9 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("IsExperienceAdmin");
 	capabilityNames.append("IsExperienceContributor");
 	capabilityNames.append("RegionExperiences");
-	capabilityNames.append("GetMesh");
-	capabilityNames.append("GetMesh2");
 	capabilityNames.append("GetMetadata");
 	capabilityNames.append("GetObjectCost");
 	capabilityNames.append("GetObjectPhysicsData");
-	capabilityNames.append("GetTexture");
 	capabilityNames.append("GroupAPIv1");
 	capabilityNames.append("GroupMemberData");
 	capabilityNames.append("GroupProposalBallot");
@@ -2895,6 +2892,7 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames)
 	capabilityNames.append("UpdateScriptAgent");
 	capabilityNames.append("UpdateScriptTask");
 	capabilityNames.append("UploadBakedTexture");
+	capabilityNames.append("ViewerAsset"); 
 	capabilityNames.append("ViewerMetrics");
 	capabilityNames.append("ViewerStartAuction");
 	capabilityNames.append("ViewerStats");
@@ -2961,9 +2959,9 @@ void LLViewerRegion::setCapability(const std::string& name, const std::string& u
 	else
 	{
 		mImpl->mCapabilities[name] = url;
-		if(name == "GetTexture")
+		if(name == "ViewerAsset")
 		{
-			mHttpUrl = url ;
+			mViewerAssetUrl = url;
 		}
 	}
 }
@@ -2974,9 +2972,9 @@ void LLViewerRegion::setCapabilityDebug(const std::string& name, const std::stri
 	if ( ! ( name == "EventQueueGet" || name == "UntrustedSimulatorMessage" || name == "SimulatorFeatures" ) )
 	{
 		mImpl->mSecondCapabilitiesTracker[name] = url;
-		if(name == "GetTexture")
+		if(name == "ViewerAsset")
 		{
-			mHttpUrl = url ;
+			mViewerAssetUrl = url;
 		}
 	}
 }
diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h
index a7bb546d2cc079e376b75a8e70d26c0673c3ac93..61ce5b454d84be9faf61a35b97f774ec184ef670 100644
--- a/indra/newview/llviewerregion.h
+++ b/indra/newview/llviewerregion.h
@@ -354,7 +354,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	friend std::ostream& operator<<(std::ostream &s, const LLViewerRegion &region);
     /// implements LLCapabilityProvider
     virtual std::string getDescription() const;
-	std::string getHttpUrl() const { return mHttpUrl ;}
+    std::string getViewerAssetUrl() const { return mViewerAssetUrl; }
 
 	U32 getNumOfVisibleGroups() const;
 	U32 getNumOfActiveCachedObjects() const;
@@ -506,7 +506,7 @@ class LLViewerRegion: public LLCapabilityProvider // implements this interface
 	std::string mColoName;
 	std::string mProductSKU;
 	std::string mProductName;
-	std::string mHttpUrl ;
+	std::string mViewerAssetUrl ;
 	
 	// Maps local ids to cache entries.
 	// Regions can have order 10,000 objects, so assume
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index c1b0f42c84cda6f04fbc31a861a8738077994185..beb6f08899f06eaaeec0b8271a0fda928bc0bf73 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -9456,6 +9456,3 @@ BOOL LLVOAvatar::isTextureVisible(LLAvatarAppearanceDefines::ETextureIndex type,
 	// non-self avatars don't have wearables
 	return FALSE;
 }
-
-
-
diff --git a/indra/newview/tests/llviewerassetstats_test.cpp b/indra/newview/tests/llviewerassetstats_test.cpp
index a08e32cb49fc2b0c714a9511814354638fcd380e..e2e7f09c3b4279b633e438400e6b82beec5c7a62 100644
--- a/indra/newview/tests/llviewerassetstats_test.cpp
+++ b/indra/newview/tests/llviewerassetstats_test.cpp
@@ -71,25 +71,33 @@ static const char * all_keys[] =
 {
 	"duration",
 	"fps",
-	"get_other",
+	"get_other_http",
+	"get_other_udp",
 	"get_texture_temp_http",
 	"get_texture_temp_udp",
 	"get_texture_non_temp_http",
 	"get_texture_non_temp_udp",
+	"get_wearable_http",
 	"get_wearable_udp",
+	"get_sound_http",
 	"get_sound_udp",
+	"get_gesture_http",
 	"get_gesture_udp"
 };
 
 static const char * resp_keys[] = 
 {
-	"get_other",
+	"get_other_http",
+	"get_other_udp",
 	"get_texture_temp_http",
 	"get_texture_temp_udp",
 	"get_texture_non_temp_http",
 	"get_texture_non_temp_udp",
+	"get_wearable_http",
 	"get_wearable_udp",
+	"get_sound_http",
 	"get_sound_udp",
+	"get_gesture_http",
 	"get_gesture_udp"
 };
 
@@ -540,11 +548,17 @@ namespace tut
 		ensure("sd[get_gesture_udp][enqueued] is 0", (0 == sd["get_gesture_udp"]["enqueued"].asInteger()));
 		ensure("sd[get_gesture_udp][dequeued] is 0", (0 == sd["get_gesture_udp"]["dequeued"].asInteger()));
 
-		ensure("sd[get_wearable_udp][enqueued] is 4", (4 == sd["get_wearable_udp"]["enqueued"].asInteger()));
-		ensure("sd[get_wearable_udp][dequeued] is 4", (4 == sd["get_wearable_udp"]["dequeued"].asInteger()));
+		ensure("sd[get_wearable_http][enqueued] is 2", (2 == sd["get_wearable_http"]["enqueued"].asInteger()));
+		ensure("sd[get_wearable_http][dequeued] is 2", (2 == sd["get_wearable_http"]["dequeued"].asInteger()));
 
-		ensure("sd[get_other][enqueued] is 4", (4 == sd["get_other"]["enqueued"].asInteger()));
-		ensure("sd[get_other][dequeued] is 0", (0 == sd["get_other"]["dequeued"].asInteger()));
+		ensure("sd[get_wearable_udp][enqueued] is 2", (2 == sd["get_wearable_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_wearable_udp][dequeued] is 2", (2 == sd["get_wearable_udp"]["dequeued"].asInteger()));
+
+		ensure("sd[get_other_http][enqueued] is 2", (2 == sd["get_other_http"]["enqueued"].asInteger()));
+		ensure("sd[get_other_http][dequeued] is 0", (0 == sd["get_other_http"]["dequeued"].asInteger()));
+
+		ensure("sd[get_other_udp][enqueued] is 2", (2 == sd["get_other_udp"]["enqueued"].asInteger()));
+		ensure("sd[get_other_udp][dequeued] is 0", (0 == sd["get_other_udp"]["dequeued"].asInteger()));
 
 		// Reset and check zeros...
 		// Reset leaves current region in place
diff --git a/indra/test/test.cpp b/indra/test/test.cpp
index e42374d56bb503ce20cd82871c356f729f92d237..630af2b73bb9145af9f653e966e5067ae69ea001 100644
--- a/indra/test/test.cpp
+++ b/indra/test/test.cpp
@@ -34,6 +34,7 @@
  *
  */
 
+
 #include "linden_common.h"
 #include "llerrorcontrol.h"
 #include "lltut.h"
@@ -684,4 +685,5 @@ int main(int argc, char **argv)
 	return retval;
 
 	//delete mycallback;
+
 }
diff --git a/scripts/metrics/viewer_asset_logs.py b/scripts/metrics/viewer_asset_logs.py
new file mode 100644
index 0000000000000000000000000000000000000000..e48286f696d19c05cf79e241aa447e3298a10a08
--- /dev/null
+++ b/scripts/metrics/viewer_asset_logs.py
@@ -0,0 +1,102 @@
+#!runpy.sh
+
+"""\
+
+This module contains tools for analyzing viewer asset metrics logs produced by the viewer.
+
+$LicenseInfo:firstyear=2016&license=viewerlgpl$
+Second Life Viewer Source Code
+Copyright (C) 2016, Linden Research, Inc.
+
+This library is free software; you can redistribute it and/or
+modify it under the terms of the GNU Lesser General Public
+License as published by the Free Software Foundation;
+version 2.1 of the License only.
+
+This library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public
+License along with this library; if not, write to the Free Software
+Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+
+Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
+$/LicenseInfo$
+"""
+
+import argparse
+from lxml import etree
+from llbase import llsd
+
+def get_metrics_record(infiles):
+    for filename in args.infiles:
+        f = open(filename)
+        # get an iterable
+        context = etree.iterparse(f, events=("start", "end"))
+
+        # turn it into an iterator
+        context = iter(context)
+
+        # get the root element
+        event, root = context.next()
+        try:
+            for event, elem in context:
+                if event == "end" and elem.tag == "llsd":
+                    xmlstr = etree.tostring(elem, encoding="utf8", method="xml")
+                    sd = llsd.parse_xml(xmlstr)
+                    yield sd
+        except etree.XMLSyntaxError:
+            print "Fell off end of document"
+
+        f.close()
+
+def update_stats(stats,rec):
+    for region in rec["regions"]:
+        region_key = (region["grid_x"],region["grid_y"])
+        #print "region",region_key
+        for field, val in region.iteritems():
+            if field in ["duration","grid_x","grid_y"]:
+                continue
+            if field == "fps":
+                # handle fps record as special case
+                pass
+            else:
+                #print "field",field 
+                stats.setdefault(field,{})
+                type_stats = stats.get(field)
+                newcount = val["resp_count"]
+                #print "field",field,"add count",newcount
+                type_stats["count"] = type_stats.get("count",0) + val["resp_count"]
+                #print "field",field,"count",type_stats["count"]
+                if (newcount>0):
+                    type_stats["sum"] = type_stats.get("sum",0) + val["resp_count"] * val["resp_mean"]
+                    type_stats["sum_bytes"] = type_stats.get("sum_bytes",0) + val["resp_count"] * val.get("resp_mean_bytes",0)
+                type_stats["enqueued"] = type_stats.get("enqueued",0) + val["enqueued"]
+                type_stats["dequeued"] = type_stats.get("dequeued",0) + val["dequeued"]
+                
+            
+    
+if __name__ == "__main__":
+
+    parser = argparse.ArgumentParser(description="process metric xml files for viewer asset fetching")
+    parser.add_argument("--verbose", action="store_true",help="verbose flag")
+    parser.add_argument("infiles", nargs="+", help="name of .xml files to process")
+    args = parser.parse_args()
+
+    #print "process files:",args.infiles
+
+    stats = {}
+    for rec in get_metrics_record(args.infiles):
+        #print "record",rec
+
+        update_stats(stats,rec)
+
+    for key in sorted(stats.keys()):
+        val = stats[key]
+        if val["count"] > 0:
+            print key,"count",val["count"],"mean_time",val["sum"]/val["count"],"mean_bytes",val["sum_bytes"]/val["count"],"net bytes/sec",val["sum_bytes"]/val["sum"],"enqueued",val["enqueued"],"dequeued",val["dequeued"]
+        else:
+            print key,"count",val["count"],"enqueued",val["enqueued"],"dequeued",val["dequeued"]
+