diff --git a/indra/llcommon/llstatenums.h b/indra/llcommon/llstatenums.h
index 81c4085d16829a5f73f640e787e20cf46d58b319..ab9b6709e8045dba63fb4154997fcd0598bc5753 100644
--- a/indra/llcommon/llstatenums.h
+++ b/indra/llcommon/llstatenums.h
@@ -26,7 +26,7 @@
 #ifndef LL_LLSTATENUMS_H
 #define LL_LLSTATENUMS_H
 
-enum
+enum ESimStatID
 {
 	LL_SIM_STAT_TIME_DILATION         =  0,
 	LL_SIM_STAT_FPS                   =  1,
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index 221c226ad13c38acef2d8a22e75969e5f476c312..3e19c83bd7fcc16b2c2e7a17df23385fc779793a 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -282,6 +282,7 @@ namespace LLTrace
 		T	getLastValue() const { return mLastValue; }
 		F64	getMean() const { return mMean; }
 		F64 getStandardDeviation() const { return sqrtf(mVarianceSum / mNumSamples); }
+		U32 getSampleCount() const { return mNumSamples; }
 
 	private:
 		T	mSum,
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index d9ac8c327ab2edfa5275eb47b77a8e5d0e92288a..bd4b944e5a4e7f12329270445c703806b8fc15f1 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -168,6 +168,12 @@ namespace LLTrace
 			return (typename Measurement<T, IS_UNIT>::base_unit_t)stat.getAccumulator(mMeasurements).getLastValue();
 		}
 
+		template <typename T, typename IS_UNIT>
+		U32 getSampleCount(const Measurement<T, IS_UNIT>& stat) const
+		{
+			return stat.getAccumulator(mMeasurements).getSampleCount();
+		}
+
 		F64 getDuration() const { return mElapsedSeconds; }
 
 		// implementation for LLVCRControlsMixin
@@ -208,7 +214,7 @@ namespace LLTrace
 			return mRecordingPeriods[(mCurPeriod + mNumPeriods - 1) % mNumPeriods];
 		}
 
-		Recording& getCurRecordingPeriod()
+		Recording getCurRecordingPeriod()
 		{
 			return mRecordingPeriods[mCurPeriod];
 		}
@@ -218,6 +224,13 @@ namespace LLTrace
 			return mRecordingPeriods[mCurPeriod];
 		}
 
+		Recording snapshotCurRecordingPeriod() const
+		{
+			Recording recording_copy(getCurRecordingPeriod());
+			recording_copy.stop();
+			return recording_copy;
+		}
+
 		Recording& getTotalRecording();
 
 	private:
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 090e42607e1f6d5b8c2ff08129835d83d7aced12..e8f6b2b2bae41b1bdbed3ac62bfc5f983f56a22d 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -261,6 +261,10 @@ namespace LLUnits
 	LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds,	(1.f / (1000000.f)));
 	LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds,	(1.f / (1000000000.f)));
 
+	LL_DECLARE_BASE_UNIT(Meters);
+	LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000);
+	LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, 1 / 100);
+	LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, 1 / 1000);
 }
 
 #endif // LL_LLUNIT_H
diff --git a/indra/llmessage/llassetstorage.cpp b/indra/llmessage/llassetstorage.cpp
index 9b86daebe5d93441a6541c8f47be17bd3356518f..328d15b4bc55a285d19fed733638b44374dad02f 100644
--- a/indra/llmessage/llassetstorage.cpp
+++ b/indra/llmessage/llassetstorage.cpp
@@ -50,10 +50,14 @@
 #include "lltransfertargetvfile.h" // For debugging
 
 #include "llmetrics.h"
+#include "lltrace.h"
 
 LLAssetStorage *gAssetStorage = NULL;
 LLMetrics *LLAssetStorage::metric_recipient = NULL;
 
+static LLTrace::Count<> sFailedDownloadCount("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed");
+
+
 const LLUUID CATEGORIZE_LOST_AND_FOUND_ID(std::string("00000000-0000-0000-0000-000000000010"));
 
 const U64 TOXIC_ASSET_LIFETIME = (120 * 1000000);		// microseconds
@@ -450,6 +454,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 
 		if (callback)
 		{
+			sFailedDownloadCount.add(1);
 			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_FAILED, LL_EXSTAT_NONE);
 		}
 		return;
@@ -460,6 +465,7 @@ void LLAssetStorage::getAssetData(const LLUUID uuid, LLAssetType::EType type, LL
 		// Special case early out for NULL uuid and for shutting down
 		if (callback)
 		{
+			sFailedDownloadCount.add(1);
 			callback(mVFS, uuid, type, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
 		}
 		return;
@@ -572,6 +578,7 @@ void LLAssetStorage::_queueDataRequest(const LLUUID& uuid, LLAssetType::EType at
 		llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
 		if (callback)
 		{
+			sFailedDownloadCount.add(1);
 			callback(mVFS, uuid, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
 		}
 	}
@@ -649,6 +656,10 @@ void LLAssetStorage::downloadCompleteCallback(
 		LLAssetRequest* tmp = *curiter;
 		if (tmp->mDownCallback)
 		{
+			if (result != LL_ERR_NOERR)
+			{
+				sFailedDownloadCount.add(1);
+			}
 			tmp->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), tmp->mUserData, result, ext_status);
 		}
 		delete tmp;
@@ -669,6 +680,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
 		// Special case early out for NULL uuid
 		if (callback)
 		{
+			sFailedDownloadCount.add(1);
 			callback(mVFS, asset_id, atype, user_data, LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE, LL_EXSTAT_NULL_UUID);
 		}
 		return;
@@ -741,6 +753,7 @@ void LLAssetStorage::getEstateAsset(const LLHost &object_sim, const LLUUID &agen
 			llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
 			if (callback)
 			{
+				sFailedDownloadCount.add(1);
 				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
 			}
 		}
@@ -783,6 +796,10 @@ void LLAssetStorage::downloadEstateAssetCompleteCallback(
 		}
 	}
 
+	if (result != LL_ERR_NOERR)
+	{
+		sFailedDownloadCount.add(1);
+	}
 	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getAType(), req->mUserData, result, ext_status);
 }
 
@@ -883,6 +900,7 @@ void LLAssetStorage::getInvItemAsset(const LLHost &object_sim, const LLUUID &age
 			llwarns << "Attempt to move asset data request upstream w/o valid upstream provider" << llendl;
 			if (callback)
 			{
+				sFailedDownloadCount.add(1);
 				callback(mVFS, asset_id, atype, user_data, LL_ERR_CIRCUIT_GONE, LL_EXSTAT_NO_UPSTREAM);
 			}
 		}
@@ -925,6 +943,10 @@ void LLAssetStorage::downloadInvItemCompleteCallback(
 		}
 	}
 
+	if (result != LL_ERR_NOERR)
+	{
+		sFailedDownloadCount.add(1);
+	}
 	req->mDownCallback(gAssetStorage->mVFS, req->getUUID(), req->getType(), req->mUserData, result, ext_status);
 }
 
@@ -1237,6 +1259,7 @@ bool LLAssetStorage::deletePendingRequestImpl(LLAssetStorage::request_list_t* re
 		}
 		if (req->mDownCallback)
 		{
+			sFailedDownloadCount.add(1);
 			req->mDownCallback(mVFS, req->getUUID(), req->getType(), req->mUserData, error, LL_EXSTAT_REQUEST_DROPPED);
 		}
 		if (req->mInfoCallback)
@@ -1363,6 +1386,10 @@ void LLAssetStorage::legacyGetDataCallback(LLVFS *vfs, const LLUUID &uuid, LLAss
 		}
 	}
 
+	if (status != LL_ERR_NOERR)
+	{
+		sFailedDownloadCount.add(1);
+	}
 	legacy->mDownCallback(filename.c_str(), uuid, legacy->mUserData, status, ext_status);
 	delete legacy;
 }
diff --git a/indra/llui/llstatgraph.cpp b/indra/llui/llstatgraph.cpp
index be3baeea76362f504618b9186b47498d106fc410..e961e7d3c01cc49b78a0c84c2181176bfb51a00a 100644
--- a/indra/llui/llstatgraph.cpp
+++ b/indra/llui/llstatgraph.cpp
@@ -49,7 +49,7 @@ LLStatGraph::LLStatGraph(const Params& p)
 	mPrecision(p.precision),
 	mValue(p.value),
 	mStatp(p.stat.legacy_stat),
-	mNewStatp(p.stat.rate_stat)
+	mNewStatp(p.stat.count_stat)
 {
 	setToolTip(p.name());
 
diff --git a/indra/llui/llstatgraph.h b/indra/llui/llstatgraph.h
index 54a959f49e366b53ad1fcdc7f9a43b9a07db5e1e..5bbd9e9d24c4575f807169d72b244a4922b6dfc0 100644
--- a/indra/llui/llstatgraph.h
+++ b/indra/llui/llstatgraph.h
@@ -60,7 +60,8 @@ public:
 	struct StatParams : public LLInitParam::ChoiceBlock<StatParams>
 	{
 		Alternative<LLStat*>				legacy_stat;
-		Alternative<LLTrace::Count<>* >		rate_stat;
+		Alternative<LLTrace::Count<>* >		count_stat;
+		Alternative<LLTrace::Measurement<>* >	measurement_stat;
 	};
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp
index 447836910d2044400e742d7b1cf75db882702f04..a41efbe0b2b6ec5929a20066e05557cd7fc35890 100755
--- a/indra/newview/llagent.cpp
+++ b/indra/newview/llagent.cpp
@@ -753,7 +753,8 @@ void LLAgent::setFlying(BOOL fly)
 		}
 		if( !was_flying )
 		{
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
+			LLStatViewer::FLY.add(1);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_FLY_COUNT);
 		}
 		setControlFlags(AGENT_CONTROL_FLY);
 	}
@@ -3809,7 +3810,8 @@ bool LLAgent::teleportCore(bool is_local)
 	gAgentCamera.resetView(FALSE);
 
 	// local logic
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
+	LLStatViewer::TELEPORT.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TELEPORT_COUNT);
 	if (is_local)
 	{
 		gAgent.setTeleportState( LLAgent::TELEPORT_LOCAL );
@@ -4120,7 +4122,7 @@ void LLAgent::setTeleportState(ETeleportState state)
 
 		case TELEPORT_ARRIVING:
 		// First two position updates after a teleport tend to be weird
-		LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
+		//LLViewerStats::getInstance()->mAgentPositionSnaps.mCountOfNextUpdatesToIgnore = 2;
 
 		// Let the interested parties know we've teleported.
 		LLViewerParcelMgr::getInstance()->onTeleportFinished(false, getPositionGlobal());
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index a43776912c2d5c17da04f8d06bc957e091039019..6e0b298b2a8e7263963863cd525de44aa13d066f 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -4810,7 +4810,8 @@ void LLAppViewer::idleNetwork()
 			gPrintMessagesThisFrame = FALSE;
 		}
 	}
-	LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
+	LLStatViewer::NUM_NEW_OBJECTS.sample(gObjectList.mNumNewObjects);
+	//LLViewerStats::getInstance()->mNumNewObjectsStat.addValue(gObjectList.mNumNewObjects);
 
 	// Retransmit unacknowledged packets.
 	gXferManager->retransmitUnackedPackets();
diff --git a/indra/newview/llchatbar.cpp b/indra/newview/llchatbar.cpp
index d6095cce07d541e48297146c7c1e2164b96b6e77..f6bad18070283f067e24ebea159a84b0a3894e5e 100644
--- a/indra/newview/llchatbar.cpp
+++ b/indra/newview/llchatbar.cpp
@@ -618,24 +618,6 @@ void LLChatBar::sendChatFromViewer(const LLWString &wtext, EChatType type, BOOL
 
 	send_chat_from_viewer(utf8_out_text, type, channel);
 }
-/*
-void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32 channel)
-{
-	LLMessageSystem* msg = gMessageSystem;
-	msg->newMessageFast(_PREHASH_ChatFromViewer);
-	msg->nextBlockFast(_PREHASH_AgentData);
-	msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
-	msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
-	msg->nextBlockFast(_PREHASH_ChatData);
-	msg->addStringFast(_PREHASH_Message, utf8_out_text);
-	msg->addU8Fast(_PREHASH_Type, type);
-	msg->addS32("Channel", channel);
-
-	gAgent.sendReliableMessage();
-
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
-}
-*/
 
 void LLChatBar::onCommitGesture(LLUICtrl* ctrl)
 {
diff --git a/indra/newview/llcompilequeue.cpp b/indra/newview/llcompilequeue.cpp
index 4f5f9e22b69ddfe6ef1256d37bd945ec07b6789b..6739910c38bb294cd03c3b0ab6a902924015a2c3 100644
--- a/indra/newview/llcompilequeue.cpp
+++ b/indra/newview/llcompilequeue.cpp
@@ -436,7 +436,7 @@ void LLFloaterCompileQueue::scriptArrived(LLVFS *vfs, const LLUUID& asset_id,
 	}
 	else
 	{
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
 		{
diff --git a/indra/newview/llfloaterabout.cpp b/indra/newview/llfloaterabout.cpp
index 83fb887d81b3e2ad2c19fa193886d19e7ba3aa3e..58701ca3c91d4af0f797391f0e1da2042c1df19e 100644
--- a/indra/newview/llfloaterabout.cpp
+++ b/indra/newview/llfloaterabout.cpp
@@ -296,7 +296,8 @@ LLSD LLFloaterAbout::getInfo()
 
 	if (gPacketsIn > 0)
 	{
-		info["PACKETS_LOST"] = LLViewerStats::getInstance()->mPacketsLostStat.getCurrent();
+		LLTrace::Recording cur_frame = LLTrace::get_frame_recording().snapshotCurRecordingPeriod();
+		info["PACKETS_LOST"] = cur_frame.getSum(LLStatViewer::PACKETS_LOST);
 		info["PACKETS_IN"] = F32(gPacketsIn);
 		info["PACKETS_PCT"] = 100.f*info["PACKETS_LOST"].asReal() / info["PACKETS_IN"].asReal();
 	}
diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp
index fe29bb38c73b67061731273bf1fa08f84cf77f96..8234841966b3cf05ed1197c8aa667d0341c70248 100644
--- a/indra/newview/llfloaterregioninfo.cpp
+++ b/indra/newview/llfloaterregioninfo.cpp
@@ -2491,7 +2491,7 @@ void LLPanelEstateCovenant::onLoadComplete(LLVFS *vfs,
 		}
 		else
 		{
-			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+			//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp
index d8d62e5bbbee6d422889cce9408079e61b0638eb..4a58e0186caef4326dcf2a94e08d1b4b33e46ee5 100644
--- a/indra/newview/llfloatersnapshot.cpp
+++ b/indra/newview/llfloatersnapshot.cpp
@@ -992,7 +992,8 @@ void LLSnapshotLivePreview::saveTexture()
 		llwarns << "Error encoding snapshot" << llendl;
 	}
 
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
+	LLStatViewer::SNAPSHOT.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_SNAPSHOT_COUNT );
 	
 	mDataSize = 0;
 }
diff --git a/indra/newview/llgesturemgr.cpp b/indra/newview/llgesturemgr.cpp
index 66ca76bfb07bdc34de04202c538f647699456c44..63ef8c3d21d0ab9090d699b4b0463f47fbbc4210 100644
--- a/indra/newview/llgesturemgr.cpp
+++ b/indra/newview/llgesturemgr.cpp
@@ -1137,7 +1137,7 @@ void LLGestureMgr::onLoadComplete(LLVFS *vfs,
 	}
 	else
 	{
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 			LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/lllandmarklist.cpp b/indra/newview/lllandmarklist.cpp
index dd402de394a9564037492d74123440e8d417c7d8..1666425cbec553a2e3beb7b7308f25100855e4bc 100644
--- a/indra/newview/lllandmarklist.cpp
+++ b/indra/newview/lllandmarklist.cpp
@@ -141,7 +141,7 @@ void LLLandmarkList::processGetAssetReply(
 	}
 	else
 	{
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 		// SJB: No use case for a notification here. Use lldebugs instead
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status )
 		{
diff --git a/indra/newview/llnearbychatbar.cpp b/indra/newview/llnearbychatbar.cpp
index c00dc4bc89dd70a5b99b9b70dcb92d4f74f23234..0aced5c5759c1c4cdce585809590cefea107c2ad 100644
--- a/indra/newview/llnearbychatbar.cpp
+++ b/indra/newview/llnearbychatbar.cpp
@@ -638,7 +638,8 @@ void send_chat_from_viewer(const std::string& utf8_out_text, EChatType type, S32
 
 	gAgent.sendReliableMessage();
 
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
+	LLStatViewer::CHAT_COUNT.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CHAT_COUNT);
 }
 
 class LLChatCommandHandler : public LLCommandHandler
diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp
index 202be9671b4d4bdb092b69391c7f518de57fecba..52ed24f06d6172400e602a517decaf762c38ff2d 100644
--- a/indra/newview/llpanelface.cpp
+++ b/indra/newview/llpanelface.cpp
@@ -1049,7 +1049,8 @@ BOOL LLPanelFace::onDragTexture(LLUICtrl*, LLInventoryItem* item)
 
 void LLPanelFace::onCommitTexture( const LLSD& data )
 {
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+	LLStatViewer::EDIT_TEXTURE.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
 	sendTexture();
 }
 
diff --git a/indra/newview/llpreviewgesture.cpp b/indra/newview/llpreviewgesture.cpp
index f47928b1314896c7eabdd84c5d985ea727aa6393..4082d272f2391c47fb1bbe0a707f89e8d2394271 100644
--- a/indra/newview/llpreviewgesture.cpp
+++ b/indra/newview/llpreviewgesture.cpp
@@ -883,7 +883,7 @@ void LLPreviewGesture::onLoadComplete(LLVFS *vfs,
 		}
 		else
 		{
-			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+			//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/llpreviewnotecard.cpp b/indra/newview/llpreviewnotecard.cpp
index 3a9360fd23dbab67252ce95890ef83fb87fe83da..b93b97f1e0348c8306cc2e91a61abc5a2f1b640e 100644
--- a/indra/newview/llpreviewnotecard.cpp
+++ b/indra/newview/llpreviewnotecard.cpp
@@ -339,7 +339,7 @@ void LLPreviewNotecard::onLoadComplete(LLVFS *vfs,
 		}
 		else
 		{
-			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+			//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/llpreviewscript.cpp b/indra/newview/llpreviewscript.cpp
index 88727bf59b4fa58b46150072a5df4e4beb6188bf..059d5d4061f309a5acc0ff277315ff7f993f7472 100644
--- a/indra/newview/llpreviewscript.cpp
+++ b/indra/newview/llpreviewscript.cpp
@@ -942,7 +942,8 @@ void LLScriptEdCore::onBtnInsertFunction(LLUICtrl *ui, void* userdata)
 
 void LLScriptEdCore::doSave( BOOL close_after_save )
 {
-	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+	LLStatViewer::LSL_SAVES.add(1);
+	//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
 
 	if( mSaveCallback )
 	{
@@ -1146,8 +1147,8 @@ void LLScriptEdCore::onBtnLoadFromFile( void* data )
 
 void LLScriptEdCore::onBtnSaveToFile( void* userdata )
 {
-
-	LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
+	LLStatViewer::LSL_SAVES.add(1);
+	//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_LSL_SAVE_COUNT );
 
 	LLScriptEdCore* self = (LLScriptEdCore*) userdata;
 
@@ -1670,7 +1671,7 @@ void LLPreviewLSL::onLoadComplete( LLVFS *vfs, const LLUUID& asset_uuid, LLAsset
 		}
 		else
 		{
-			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+			//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
@@ -1902,7 +1903,7 @@ void LLLiveLSLEditor::onLoadComplete(LLVFS *vfs, const LLUUID& asset_id,
 		}
 		else
 		{
-			LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+			//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 			if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 				LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp
index c3c37141ed4005944fd0134a65226afa801756b3..fd03d7c0be941716441ae5943aa8dde29e299021 100644
--- a/indra/newview/llselectmgr.cpp
+++ b/indra/newview/llselectmgr.cpp
@@ -1550,7 +1550,8 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item)
 				}
 
 				// apply texture for the selected faces
-				LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+				LLStatViewer::EDIT_TEXTURE.add(1);
+				//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
 				object->setTEImage(te, image);
 				dialog_refresh_all();
 
@@ -3424,9 +3425,7 @@ bool LLSelectMgr::confirmDelete(const LLSD& notification, const LLSD& response,
 			gAgentCamera.setLookAt(LOOKAT_TARGET_CLEAR);
 
 			// Keep track of how many objects have been deleted.
-			F64 obj_delete_count = LLViewerStats::getInstance()->getStat(LLViewerStats::ST_OBJECT_DELETE_COUNT);
-			obj_delete_count += LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount();
-			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_OBJECT_DELETE_COUNT, obj_delete_count );
+			LLStatViewer::DELETE_OBJECT.add(LLSelectMgr::getInstance()->mSelectedObjects->getObjectCount());
 		}
 		break;
 	case 1:
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 1e7c325d308e5ff1187cf02243f97cac2921a3fb..cb3c90ea2af7eb5c6232c684c53f59f7f7ad53c4 100755
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -2071,7 +2071,8 @@ bool idle_startup()
 		if (wearables_time > MAX_WEARABLES_TIME)
 		{
 			LLNotificationsUtil::add("ClothingLoading");
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
+			LLStatViewer::LOADING_WEARABLES_LONG_DELAY.add(1);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_WEARABLES_TOO_LONG);
 			LLStartUp::setStartupState( STATE_CLEANUP );
 			return TRUE;
 		}
diff --git a/indra/newview/llstatusbar.cpp b/indra/newview/llstatusbar.cpp
index 6f2a0de894b1a09089eca0941f4d5f7f439a3530..5720395d05276b388e15b447dbdb922d11f1a86f 100644
--- a/indra/newview/llstatusbar.cpp
+++ b/indra/newview/llstatusbar.cpp
@@ -198,7 +198,7 @@ BOOL LLStatusBar::postBuild()
 	sgp.rect(r);
 	sgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
 	sgp.mouse_opaque(false);
-	sgp.stat.rate_stat(&LLStatViewer::KBIT);
+	sgp.stat.count_stat(&LLStatViewer::KBIT);
 	sgp.units("Kbps");
 	sgp.precision(0);
 	mSGBandwidth = LLUICtrlFactory::create<LLStatGraph>(sgp);
@@ -212,7 +212,7 @@ BOOL LLStatusBar::postBuild()
 	pgp.rect(r);
 	pgp.follows.flags(FOLLOWS_BOTTOM | FOLLOWS_RIGHT);
 	pgp.mouse_opaque(false);
-	pgp.stat.legacy_stat(&LLViewerStats::getInstance()->mPacketsLostPercentStat);
+	pgp.stat.measurement_stat(&LLStatViewer::PACKETS_LOST_PERCENT);
 	pgp.units("%");
 	pgp.min(0.f);
 	pgp.max(5.f);
diff --git a/indra/newview/lltexlayer.cpp b/indra/newview/lltexlayer.cpp
index 467115c92849b6ad9bc2c8e7d637c752ba9d6b8e..e354a5c59de0b02c1407fe3c2954b207622076ce 100644
--- a/indra/newview/lltexlayer.cpp
+++ b/indra/newview/lltexlayer.cpp
@@ -460,7 +460,8 @@ BOOL LLTexLayerSetBuffer::requestUpdateImmediate()
 void LLTexLayerSetBuffer::doUpload()
 {
 	llinfos << "Uploading baked " << mTexLayerSet->getBodyRegionName() << llendl;
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
+	LLStatViewer::TEX_BAKES.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_BAKES);
 
 	// Don't need caches since we're baked now.  (note: we won't *really* be baked 
 	// until this image is sent to the server and the Avatar Appearance message is received.)
diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp
index c69999981ce66c46e3ea2aed366558d21cdeb3bf..791da59a1a2ecd804e2e942d2e9667f3a0574b94 100644
--- a/indra/newview/lltooldraganddrop.cpp
+++ b/indra/newview/lltooldraganddrop.cpp
@@ -1062,7 +1062,8 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj,
 		return;
 	}
 	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+	LLStatViewer::EDIT_TEXTURE.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
 	S32 num_faces = hit_obj->getNumTEs();
 	for( S32 face = 0; face < num_faces; face++ )
 	{
@@ -1130,7 +1131,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj,
 	}
 	// update viewer side image in anticipation of update from simulator
 	LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(asset_id);
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
+	LLStatViewer::EDIT_TEXTURE.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_EDIT_TEXTURE_COUNT );
 	hit_obj->setTEImage(hit_face, image);
 	dialog_refresh_all();
 
@@ -1354,7 +1356,8 @@ void LLToolDragAndDrop::dropObject(LLViewerObject* raycast_target,
 	effectp->setDuration(LL_HUD_DUR_SHORT);
 	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
 
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT);
+	LLStatViewer::OBJECT_REZ.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_REZ_COUNT);
 }
 
 void LLToolDragAndDrop::dropInventory(LLViewerObject* hit_obj,
diff --git a/indra/newview/lltoolplacer.cpp b/indra/newview/lltoolplacer.cpp
index 93ba3b25587c79ecd6334255ccd5bec27a1b467e..cf5a6e37627617dcde154a02622ce01e7ca76949 100644
--- a/indra/newview/lltoolplacer.cpp
+++ b/indra/newview/lltoolplacer.cpp
@@ -433,7 +433,8 @@ BOOL LLToolPlacer::addObject( LLPCode pcode, S32 x, S32 y, U8 use_physics )
 	effectp->setDuration(LL_HUD_DUR_SHORT);
 	effectp->setColor(LLColor4U(gAgent.getEffectColor()));
 
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT);
+	LLStatViewer::OBJECT_CREATE.add(1);
+	//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_CREATE_COUNT);
 
 	return TRUE;
 }
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 4ec498dc338a55f8adb3f980e9c5d0078f8e812a..219e01fe810734e79455f2919fef1324ee9ae8e0 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -3973,72 +3973,6 @@ void handle_duplicate_in_place(void*)
 	LLSelectMgr::getInstance()->selectDuplicate(offset, TRUE);
 }
 
-/* dead code 30-apr-2008
-void handle_deed_object_to_group(void*)
-{
-	LLUUID group_id;
-	
-	LLSelectMgr::getInstance()->selectGetGroup(group_id);
-	LLSelectMgr::getInstance()->sendOwner(LLUUID::null, group_id, FALSE);
-	LLViewerStats::getInstance()->incStat(LLViewerStats::ST_RELEASE_COUNT);
-}
-
-BOOL enable_deed_object_to_group(void*)
-{
-	if(LLSelectMgr::getInstance()->getSelection()->isEmpty()) return FALSE;
-	LLPermissions perm;
-	LLUUID group_id;
-
-	if (LLSelectMgr::getInstance()->selectGetGroup(group_id) &&
-		gAgent.hasPowerInGroup(group_id, GP_OBJECT_DEED) &&
-		LLSelectMgr::getInstance()->selectGetPermissions(perm) &&
-		perm.deedToGroup(gAgent.getID(), group_id))
-	{
-		return TRUE;
-	}
-	return FALSE;
-}
-
-*/
-
-
-/*
- * No longer able to support viewer side manipulations in this way
- *
-void god_force_inv_owner_permissive(LLViewerObject* object,
-									LLInventoryObject::object_list_t* inventory,
-									S32 serial_num,
-									void*)
-{
-	typedef std::vector<LLPointer<LLViewerInventoryItem> > item_array_t;
-	item_array_t items;
-
-	LLInventoryObject::object_list_t::const_iterator inv_it = inventory->begin();
-	LLInventoryObject::object_list_t::const_iterator inv_end = inventory->end();
-	for ( ; inv_it != inv_end; ++inv_it)
-	{
-		if(((*inv_it)->getType() != LLAssetType::AT_CATEGORY))
-		{
-			LLInventoryObject* obj = *inv_it;
-			LLPointer<LLViewerInventoryItem> new_item = new LLViewerInventoryItem((LLViewerInventoryItem*)obj);
-			LLPermissions perm(new_item->getPermissions());
-			perm.setMaskBase(PERM_ALL);
-			perm.setMaskOwner(PERM_ALL);
-			new_item->setPermissions(perm);
-			items.push_back(new_item);
-		}
-	}
-	item_array_t::iterator end = items.end();
-	item_array_t::iterator it;
-	for(it = items.begin(); it != end; ++it)
-	{
-		// since we have the inventory item in the callback, it should not
-		// invalidate iteration through the selection manager.
-		object->updateInventory((*it), TASK_INVENTORY_ITEM_KEY, false);
-	}
-}
-*/
-
 void handle_object_owner_permissive(void*)
 {
 	// only send this if they're a god.
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index be78603e2d628be3c212098af58c5b1593b4177d..7ce8cdcfd890109bb14144b32f71f478fb423dbe 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -1096,17 +1096,20 @@ void upload_new_resource(
 	
 	if( LLAssetType::AT_SOUND == asset_type )
 	{
-		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+		LLStatViewer::UPLOAD_SOUND.add(1);
+		//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_SOUND_COUNT );
 	}
 	else
 	if( LLAssetType::AT_TEXTURE == asset_type )
 	{
-		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+		LLStatViewer::UPLOAD_TEXTURE.add(1);
+		//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
 	}
 	else
 	if( LLAssetType::AT_ANIMATION == asset_type)
 	{
-		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+		LLStatViewer::ANIMATION_UPLOADS.add(1);
+		//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_UPLOAD_ANIM_COUNT );
 	}
 
 	if(LLInventoryType::IT_NONE == inv_type)
@@ -1231,18 +1234,21 @@ void increase_new_upload_stats(LLAssetType::EType asset_type)
 {
 	if ( LLAssetType::AT_SOUND == asset_type )
 	{
-		LLViewerStats::getInstance()->incStat(
-			LLViewerStats::ST_UPLOAD_SOUND_COUNT );
+		LLStatViewer::UPLOAD_SOUND.add(1);
+		//LLViewerStats::getInstance()->incStat(
+		//	LLViewerStats::ST_UPLOAD_SOUND_COUNT );
 	}
 	else if ( LLAssetType::AT_TEXTURE == asset_type )
 	{
-		LLViewerStats::getInstance()->incStat(
-			LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
+		LLStatViewer::UPLOAD_TEXTURE.add(1);
+		//LLViewerStats::getInstance()->incStat(
+		//	LLViewerStats::ST_UPLOAD_TEXTURE_COUNT );
 	}
 	else if ( LLAssetType::AT_ANIMATION == asset_type )
 	{
-		LLViewerStats::getInstance()->incStat(
-			LLViewerStats::ST_UPLOAD_ANIM_COUNT );
+		LLStatViewer::ANIMATION_UPLOADS.add(1);
+		//LLViewerStats::getInstance()->incStat(
+		//	LLViewerStats::ST_UPLOAD_ANIM_COUNT );
 	}
 }
 
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index ec7d91ec4f94b880f27426ccc21c0325ea43602f..b3e1c9bdbeec1cba3e65213437c289820ec02ca4 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -4753,125 +4753,150 @@ void process_sim_stats(LLMessageSystem *msg, void **user_data)
 		F32 stat_value;
 		msg->getU32("Stat", "StatID", stat_id, i);
 		msg->getF32("Stat", "StatValue", stat_value, i);
-		switch (stat_id)
+		LLStatViewer::SimMeasurementSampler* measurementp = LLStatViewer::SimMeasurementSampler::getInstance((ESimStatID)stat_id);
+		
+		if (measurementp )
 		{
-		case LL_SIM_STAT_TIME_DILATION:
-			LLStatViewer::SIM_TIME_DILATION.sample(stat_value);
-			//LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_FPS:
-			LLStatViewer::SIM_FPS.sample(stat_value);
-			//LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PHYSFPS:
-			LLStatViewer::SIM_PHYSICS_FPS.sample(stat_value);
-			//LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_AGENTUPS:
-			LLStatViewer::SIM_AGENT_UPS.sample(stat_value);
-			//LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_FRAMEMS:
-			LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NETMS:
-			LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMOTHERMS:
-			LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_AGENTMS:
-			LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_IMAGESMS:
-			LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SCRIPTMS:
-			LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMTASKS:
-			LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMTASKSACTIVE:
-			LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMAGENTMAIN:
-			LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMAGENTCHILD:
-			LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_NUMSCRIPTSACTIVE:
-			LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SCRIPT_EPS:
-			LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_INPPS:
-			LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_OUTPPS:
-			LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_DOWNLOADS:
-			LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_UPLOADS:
-			LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
-			LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
-			LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
-			break;
-		case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
-			LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PHYSICS_LOD_TASKS:
-			LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSSTEPMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSOTHERMS:
-			LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMPHYSICSMEMORY:
-			LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMSPARETIME:
-			LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMSLEEPTIME:
-			LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_IOPUMPTIME:
-			LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PCTSCRIPTSRUN:
-			LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SIMAISTEPTIMEMS:
-			LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS:
-			LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value);
-			break;
-		case LL_SIM_STAT_PCTSTEPPEDCHARACTERS:
-			LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value);
-			break;
-		default:
-			// Used to be a commented out warning.
- 			LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
-		  break;
+			measurementp->sample(stat_value);
 		}
+		else
+		{
+			llwarns << "Unknown sim stat identifier: " << stat_id << llendl;
+		}
+		//switch (stat_id)
+		//{
+		//case LL_SIM_STAT_TIME_DILATION:
+		//	LLStatViewer::SIM_TIME_DILATION.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimTimeDilation.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_FPS:
+		//	LLStatViewer::SIM_FPS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimFPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PHYSFPS:
+		//	LLStatViewer::SIM_PHYSICS_FPS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimPhysicsFPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_AGENTUPS:
+		//	LLStatViewer::SIM_AGENT_UPS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimAgentUPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_FRAMEMS:
+		//	LLStatViewer::SIM_FRAME_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimFrameMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NETMS:
+		//	LLStatViewer::SIM_NET_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimNetMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMOTHERMS:
+		//	LLStatViewer::SIM_PHYSICS_OTHER_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimSimOtherMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMPHYSICSMS:
+		//	LLStatViewer::SIM_PHYSICS_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimSimPhysicsMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_AGENTMS:
+		//	LLStatViewer::SIM_AGENTS_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimAgentMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_IMAGESMS:
+		//	LLStatViewer::SIM_IMAGES_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimImagesMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SCRIPTMS:
+		//	LLStatViewer::SIM_SCRIPTS_TIME.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimScriptMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NUMTASKS:
+		//	LLStatViewer::SIM_OBJECTS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimObjects.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NUMTASKSACTIVE:
+		//	LLStatViewer::SIM_ACTIVE_OBJECTS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimActiveObjects.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NUMAGENTMAIN:
+		//	LLStatViewer::SIM_MAIN_AGENTS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimMainAgents.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NUMAGENTCHILD:
+		//	LLStatViewer::SIM_CHILD_AGENTS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimChildAgents.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_NUMSCRIPTSACTIVE:
+		//	LLStatViewer::SIM_ACTIVE_SCRIPTS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimActiveScripts.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SCRIPT_EPS:
+		//	LLStatViewer::SIM_SCRIPT_EPS.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimScriptEPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_INPPS:
+		//	LLStatViewer::SIM_IN_PACKETS_PER_SEC.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimInPPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_OUTPPS:
+		//	LLStatViewer::SIM_OUT_PACKETS_PER_SEC.sample(stat_value);
+		//	//LLViewerStats::getInstance()->mSimOutPPS.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PENDING_DOWNLOADS:
+		//	LLViewerStats::getInstance()->mSimPendingDownloads.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PENDING_UPLOADS:
+		//	LLViewerStats::getInstance()->mSimPendingUploads.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PENDING_LOCAL_UPLOADS:
+		//	LLViewerStats::getInstance()->mSimPendingLocalUploads.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_TOTAL_UNACKED_BYTES:
+		//	LLViewerStats::getInstance()->mSimTotalUnackedBytes.addValue(stat_value / 1024.f);
+		//	break;
+		//case LL_SIM_STAT_PHYSICS_PINNED_TASKS:
+		//	LLViewerStats::getInstance()->mPhysicsPinnedTasks.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PHYSICS_LOD_TASKS:
+		//	LLViewerStats::getInstance()->mPhysicsLODTasks.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMPHYSICSSTEPMS:
+		//	LLViewerStats::getInstance()->mSimSimPhysicsStepMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMPHYSICSSHAPEMS:
+		//	LLViewerStats::getInstance()->mSimSimPhysicsShapeUpdateMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMPHYSICSOTHERMS:
+		//	LLViewerStats::getInstance()->mSimSimPhysicsOtherMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMPHYSICSMEMORY:
+		//	LLViewerStats::getInstance()->mPhysicsMemoryAllocated.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMSPARETIME:
+		//	LLViewerStats::getInstance()->mSimSpareMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMSLEEPTIME:
+		//	LLViewerStats::getInstance()->mSimSleepMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_IOPUMPTIME:
+		//	LLViewerStats::getInstance()->mSimPumpIOMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PCTSCRIPTSRUN:
+		//	LLViewerStats::getInstance()->mSimPctScriptsRun.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SIMAISTEPTIMEMS:
+		//	LLViewerStats::getInstance()->mSimSimAIStepMsec.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_SKIPPEDAISILSTEPS_PS:
+		//	LLViewerStats::getInstance()->mSimSimSkippedSilhouetteSteps.addValue(stat_value);
+		//	break;
+		//case LL_SIM_STAT_PCTSTEPPEDCHARACTERS:
+		//	LLViewerStats::getInstance()->mSimSimPctSteppedCharacters.addValue(stat_value);
+		//	break;
+		//default:
+		//	// Used to be a commented out warning.
+ 	//		LL_DEBUGS("Messaging") << "Unknown stat id" << stat_id << LL_ENDL;
+		//  break;
+		//}
 	}
 
 	/*
@@ -5942,7 +5967,8 @@ void process_alert_core(const std::string& message, BOOL modal)
 	// HACK -- handle callbacks for specific alerts. It also is localized in notifications.xml
 	if ( message == "You died and have been teleported to your home location")
 	{
-		LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
+		LLStatViewer::KILLED.add(1);
+		//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_KILLED_COUNT);
 	}
 	else if( message == "Home position set." )
 	{
@@ -7369,7 +7395,7 @@ void onCovenantLoadComplete(LLVFS *vfs,
 	}
 	else
 	{
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 		
 		if( LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status ||
 		    LL_ERR_FILE_EMPTY == status)
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index aba1d131e1d05616516505afdfc5b28c9104d27d..989a1c4e5ae260f0777e063557fa9d1c860bbe9a 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -2033,7 +2033,8 @@ U32 LLViewerObject::processUpdateMessage(LLMessageSystem *mesgsys,
 		// If we're snapping the position by more than 0.5m, update LLViewerStats::mAgentPositionSnaps
 		if ( asAvatar() && asAvatar()->isSelf() && (mag_sqr > 0.25f) )
 		{
-			LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
+			LLStatViewer::AGENT_POSITION_SNAP.sample<LLUnits::Meters>(diff.length());
+			//LLViewerStats::getInstance()->mAgentPositionSnaps.push( diff.length() );
 		}
 	}
 
diff --git a/indra/newview/llviewerobjectlist.cpp b/indra/newview/llviewerobjectlist.cpp
index 88bb087742ad2b1d51814aa0d83bb923bf0529fa..2f171f89d7cae4726e7f39830ee464e9ea5ad480 100644
--- a/indra/newview/llviewerobjectlist.cpp
+++ b/indra/newview/llviewerobjectlist.cpp
@@ -1029,10 +1029,14 @@ void LLViewerObjectList::update(LLAgent &agent, LLWorld &world)
 	}
 	*/
 
-	LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
-	LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count);
-	LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
-	LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
+	LLStatViewer::NUM_OBJECTS.sample(mObjects.size());
+	LLStatViewer::NUM_ACTIVE_OBJECTS.sample(idle_count);
+	LLStatViewer::NUM_SIZE_CULLED.sample(mNumSizeCulled);
+	LLStatViewer::NUM_VIS_CULLED.sample(mNumVisCulled);
+	//LLViewerStats::getInstance()->mNumObjectsStat.addValue((S32) mObjects.size());
+	//LLViewerStats::getInstance()->mNumActiveObjectsStat.addValue(idle_count);
+	//LLViewerStats::getInstance()->mNumSizeCulledStat.addValue(mNumSizeCulled);
+	//LLViewerStats::getInstance()->mNumVisCulledStat.addValue(mNumVisCulled);
 }
 
 void LLViewerObjectList::fetchObjectCosts()
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index a3d04d655a11f65867f78a8f8cff794258667f27..f0ad04e0ba3e272ff75668e415f2c62bbb9f34ce 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -76,7 +76,6 @@ LLTrace::Count<>	FPS("fpsstat"),
 					OBJECT_REZ("objectrez", "Object rez count"),
 					LOADING_WEARABLES_LONG_DELAY("loadingwearableslongdelay", "Wearables took too long to load"),
 					LOGIN_TIMEOUTS("logintimeouts", "Number of login attempts that timed out"),
-					FAILED_DOWNLOADS("faileddownloads", "Number of times LLAssetStorage::getAssetData() has failed"),
 					LSL_SAVES("lslsaves", "Number of times user has saved a script"),
 					ANIMATION_UPLOADS("animationuploads", "Animations uploaded"),
 					FLY("fly", "Fly count"),
@@ -108,28 +107,28 @@ LLTrace::Count<LLUnits::Seconds> AVATAR_EDIT_TIME("avataredittime", "Seconds in
 								SIM_PHYSICS_20_FPS_TIME("simphysics20fpstime", "Seconds with physics FPS below 20"),
 								LOSS_5_PERCENT_TIME("loss5percenttime", "Seconds with packet loss > 5%");
 
-LLTrace::Measurement<>		SIM_TIME_DILATION("simtimedilation"),
-							SIM_FPS("simfps"),
-							SIM_PHYSICS_FPS("simphysicsfps"),
-							SIM_AGENT_UPS("simagentups"),
-							SIM_SCRIPT_EPS("simscripteps"),
-							SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps"),
-							SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters"),
-							SIM_MAIN_AGENTS("simmainagents"),
-							SIM_CHILD_AGENTS("simchildagents"),
-							SIM_OBJECTS("simobjects"),
-							SIM_ACTIVE_OBJECTS("simactiveobjects"),
-							SIM_ACTIVE_SCRIPTS("simactivescripts"),
-							SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun"),
-							SIM_IN_PACKETS_PER_SEC("siminpps"),
-							SIM_OUT_PACKETS_PER_SEC("simoutpps"),
-							SIM_PENDING_DOWNLOADS("simpendingdownloads"),
-							SIM_PENDING_UPLOADS("simpendinguploads"),
-							SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads"),
-							SIM_PENDING_VFS_OPERATIONS("vfspendingoperations"), 
-							SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks"),
-							SIM_PHYSICS_LOD_TASKS("physicslodtasks"),
-							NUM_IMAGES("numimagesstat"),
+SimMeasurement<>			SIM_TIME_DILATION("simtimedilation", "", LL_SIM_STAT_TIME_DILATION),
+							SIM_FPS("simfps", "", LL_SIM_STAT_FPS),
+							SIM_PHYSICS_FPS("simphysicsfps", "", LL_SIM_STAT_PHYSFPS),
+							SIM_AGENT_UPS("simagentups", "", LL_SIM_STAT_AGENTUPS),
+							SIM_SCRIPT_EPS("simscripteps", "", LL_SIM_STAT_SCRIPT_EPS),
+							SIM_SKIPPED_SILHOUETTE("simsimskippedsilhouettesteps", "", LL_SIM_STAT_SKIPPEDAISILSTEPS_PS),
+							SIM_SKIPPED_CHARACTERS_PERCENTAGE("simsimpctsteppedcharacters", "", LL_SIM_STAT_PCTSTEPPEDCHARACTERS),
+							SIM_MAIN_AGENTS("simmainagents", "", LL_SIM_STAT_NUMAGENTMAIN),
+							SIM_CHILD_AGENTS("simchildagents", "", LL_SIM_STAT_NUMAGENTCHILD),
+							SIM_OBJECTS("simobjects", "", LL_SIM_STAT_NUMTASKS),
+							SIM_ACTIVE_OBJECTS("simactiveobjects", "", LL_SIM_STAT_NUMTASKSACTIVE),
+							SIM_ACTIVE_SCRIPTS("simactivescripts", "", LL_SIM_STAT_NUMSCRIPTSACTIVE),
+							SIM_PERCENTAGE_SCRIPTS_RUN("simpctscriptsrun", "", LL_SIM_STAT_PCTSCRIPTSRUN),
+							SIM_IN_PACKETS_PER_SEC("siminpps", "", LL_SIM_STAT_INPPS),
+							SIM_OUT_PACKETS_PER_SEC("simoutpps", "", LL_SIM_STAT_OUTPPS),
+							SIM_PENDING_DOWNLOADS("simpendingdownloads", "", LL_SIM_STAT_PENDING_DOWNLOADS),
+							SIM_PENDING_UPLOADS("simpendinguploads", "", LL_SIM_STAT_PENDING_UPLOADS),
+							SIM_PENDING_LOCAL_UPLOADS("simpendinglocaluploads", "", LL_SIM_STAT_PENDING_LOCAL_UPLOADS),
+							SIM_PHYSICS_PINNED_TASKS("physicspinnedtasks", "", LL_SIM_STAT_PHYSICS_PINNED_TASKS),
+							SIM_PHYSICS_LOD_TASKS("physicslodtasks", "", LL_SIM_STAT_PHYSICS_LOD_TASKS);
+
+LLTrace::Measurement<>		NUM_IMAGES("numimagesstat"),
 							NUM_RAW_IMAGES("numrawimagesstat"),
 							NUM_OBJECTS("numobjectsstat"),
 							NUM_ACTIVE_OBJECTS("numactiveobjectsstat"),
@@ -137,134 +136,61 @@ LLTrace::Measurement<>		SIM_TIME_DILATION("simtimedilation"),
 							NUM_SIZE_CULLED("numsizeculledstat"),
 							NUM_VIS_CULLED("numvisculledstat"),
 							ENABLE_VBO("enablevbo", "Vertex Buffers Enabled"),
-							DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
-							MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting"),
 							LIGHTING_DETAIL("lightingdetail", "Lighting Detail"),
 							VISIBLE_AVATARS("visibleavatars", "Visible Avatars"),
 							SHADER_OBJECTS("shaderobjects", "Object Shaders"),
 							DRAW_DISTANCE("drawdistance", "Draw Distance"),
 							CHAT_BUBBLES("chatbubbles", "Chat Bubbles Enabled"),
+							PENDING_VFS_OPERATIONS("vfspendingoperations"), 
+							PACKETS_LOST_PERCENT("packetslostpercentstat"),
 							WINDOW_WIDTH("windowwidth", "Window width"),
 							WINDOW_HEIGHT("windowheight", "Window height");
 
+LLTrace::Measurement<LLUnits::Meters> AGENT_POSITION_SNAP("agentpositionsnap", "agent position corrections");
+
+
 LLTrace::Measurement<LLUnits::Bytes>	SIM_UNACKED_BYTES("simtotalunackedbytes"),
 										SIM_PHYSICS_MEM("physicsmemoryallocated"),
 										GL_TEX_MEM("gltexmemstat"),
 										GL_BOUND_MEM("glboundmemstat"),
 										RAW_MEM("rawmemstat"),
-										FORMATTED_MEM("formattedmemstat");
-
-
-LLTrace::Measurement<LLUnits::Seconds> SIM_PHYSICS_TIME("simsimphysicsmsec"),
-										SIM_PHYSICS_STEP_TIME("simsimphysicsstepmsec"),
-										SIM_PHYSICS_SHAPE_UPDATE_TIME("simsimphysicsshapeupdatemsec"),
-										SIM_PHYSICS_OTHER_TIME("simsimphysicsothermsec"),
-										SIM_AI_TIME("simsimaistepmsec"),
-										SIM_AGENTS_TIME("simagentmsec"),
-										SIM_IMAGES_TIME("simimagesmsec"),
-										SIM_SCRIPTS_TIME("simscriptmsec"),
-										SIM_SPARE_TIME("simsparemsec"),
-										SIM_SLEEP_TIME("simsleepmsec"),
-										SIM_PUMP_IO_TIME("simpumpiomsec"),
-										SIM_PING("simpingstat"),
-										FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
-										FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
-										LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"),
-										REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"),
-										FRAME_STACKTIME("framestacktime", "FRAME_SECS"),
-										UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"),
-										NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"),
-										IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"),
-										REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"),
-										RENDER_STACKTIME("renderstacktime", "RENDER_SECS");
-}
+										FORMATTED_MEM("formattedmemstat"),
+										DELTA_BANDWIDTH("deltabandwidth", "Increase/Decrease in bandwidth based on packet loss"),
+										MAX_BANDWIDTH("maxbandwidth", "Max bandwidth setting");
+
+
+SimMeasurement<LLUnits::Milliseconds> SIM_FRAME_TIME("simframemsec", "", LL_SIM_STAT_FRAMEMS),
+										SIM_NET_TIME("simnetmsec", "", LL_SIM_STAT_NETMS),
+										SIM_OTHER_TIME("simsimothermsec", "", LL_SIM_STAT_SIMOTHERMS),
+										SIM_PHYSICS_TIME("simsimphysicsmsec", "", LL_SIM_STAT_SIMPHYSICSMS),
+										SIM_PHYSICS_STEP_TIME("simsimphysicsstepmsec", "", LL_SIM_STAT_SIMPHYSICSSTEPMS),
+										SIM_PHYSICS_SHAPE_UPDATE_TIME("simsimphysicsshapeupdatemsec", "", LL_SIM_STAT_SIMPHYSICSSHAPEMS),
+										SIM_PHYSICS_OTHER_TIME("simsimphysicsothermsec", "", LL_SIM_STAT_SIMPHYSICSOTHERMS),
+										SIM_AI_TIME("simsimaistepmsec", "", LL_SIM_STAT_SIMAISTEPTIMEMS),
+										SIM_AGENTS_TIME("simagentmsec", "", LL_SIM_STAT_AGENTMS),
+										SIM_IMAGES_TIME("simimagesmsec", "", LL_SIM_STAT_IMAGESMS),
+										SIM_SCRIPTS_TIME("simscriptmsec", "", LL_SIM_STAT_SCRIPTMS),
+										SIM_SPARE_TIME("simsparemsec", "", LL_SIM_STAT_SIMSPARETIME),
+										SIM_SLEEP_TIME("simsleepmsec", "", LL_SIM_STAT_SIMSLEEPTIME),
+										SIM_PUMP_IO_TIME("simpumpiomsec", "", LL_SIM_STAT_IOPUMPTIME);
+
+LLTrace::Measurement<LLUnits::Milliseconds>	FRAMETIME_JITTER("frametimejitter", "Average delta between successive frame times"),
+											FRAMETIME_SLEW("frametimeslew", "Average delta between frame time and mean"),
+											LOGIN_SECONDS("loginseconds", "Time between LoginRequest and LoginReply"),
+											REGION_CROSSING_TIME("regioncrossingtime", "CROSSING_AVG"),
+											FRAME_STACKTIME("framestacktime", "FRAME_SECS"),
+											UPDATE_STACKTIME("updatestacktime", "UPDATE_SECS"),
+											NETWORK_STACKTIME("networkstacktime", "NETWORK_SECS"),
+											IMAGE_STACKTIME("imagestacktime", "IMAGE_SECS"),
+											REBUILD_STACKTIME("rebuildstacktime", "REBUILD_SECS"),
+											RENDER_STACKTIME("renderstacktime", "RENDER_SECS"),
+											SIM_PING("simpingstat");
 
-class StatAttributes
-{
-public:
-	StatAttributes(const char* name,
-				   const BOOL enabled)
-	:	mName(name),
-		mEnabled(enabled)
-	{
-	}
-	
-	std::string mName;
-	BOOL mEnabled;
-};
+}
 
-LLViewerStats::LLViewerStats() :
-	//mVFSPendingOperations("vfspendingoperations"),
-	//mFPSStat("fpsstat"),
-	//mPacketsInStat("packetsinstat"),
-	//mPacketsLostStat("packetsloststat"),
-	//mPacketsOutStat("packetsoutstat"),
-	//mPacketsLostPercentStat("packetslostpercentstat"),
-	//mTexturePacketsStat("texturepacketsstat"),
-	//mActualInKBitStat("actualinkbitstat"),
-	//mActualOutKBitStat("actualoutkbitstat"),
-	//mTrianglesDrawnStat("trianglesdrawnstat"),
-	//mSimTimeDilation("simtimedilation"),
-	mSimFPS("simfps"),
-	mSimPhysicsFPS("simphysicsfps"),
-	mSimAgentUPS("simagentups"),
-	mSimScriptEPS("simscripteps"),
-	mSimFrameMsec("simframemsec"),
-	mSimNetMsec("simnetmsec"),
-	mSimSimOtherMsec("simsimothermsec"),
-	mSimSimPhysicsMsec("simsimphysicsmsec"),
-	mSimSimPhysicsStepMsec("simsimphysicsstepmsec"),
-	mSimSimPhysicsShapeUpdateMsec("simsimphysicsshapeupdatemsec"),
-	mSimSimPhysicsOtherMsec("simsimphysicsothermsec"),
-	mSimSimAIStepMsec("simsimaistepmsec"),
-	mSimSimSkippedSilhouetteSteps("simsimskippedsilhouettesteps"),
-	mSimSimPctSteppedCharacters("simsimpctsteppedcharacters"),
-	mSimAgentMsec("simagentmsec"),
-	mSimImagesMsec("simimagesmsec"),
-	mSimScriptMsec("simscriptmsec"),
-	mSimSpareMsec("simsparemsec"),
-	mSimSleepMsec("simsleepmsec"),
-	mSimPumpIOMsec("simpumpiomsec"),
-	mSimMainAgents("simmainagents"),
-	mSimChildAgents("simchildagents"),
-	mSimObjects("simobjects"),
-	mSimActiveObjects("simactiveobjects"),
-	mSimActiveScripts("simactivescripts"),
-	mSimPctScriptsRun("simpctscriptsrun"),
-	mSimInPPS("siminpps"),
-	mSimOutPPS("simoutpps"),
-	mSimPendingDownloads("simpendingdownloads"),
-	mSimPendingUploads("simpendinguploads"),
-	mSimPendingLocalUploads("simpendinglocaluploads"),
-	mSimTotalUnackedBytes("simtotalunackedbytes"),
-	mPhysicsPinnedTasks("physicspinnedtasks"),
-	mPhysicsLODTasks("physicslodtasks"),
-	mPhysicsMemoryAllocated("physicsmemoryallocated"),
-	mSimPingStat("simpingstat"),
-	mNumImagesStat("numimagesstat", TRUE),
-	mNumRawImagesStat("numrawimagesstat", TRUE),
-	mGLTexMemStat("gltexmemstat", TRUE),
-	mGLBoundMemStat("glboundmemstat", TRUE),
-	mRawMemStat("rawmemstat", TRUE),
-	mFormattedMemStat("formattedmemstat", TRUE),
-	mNumObjectsStat("numobjectsstat"),
-	mNumActiveObjectsStat("numactiveobjectsstat"),
-	mNumNewObjectsStat("numnewobjectsstat"),
-	mNumSizeCulledStat("numsizeculledstat"),
-	mNumVisCulledStat("numvisculledstat"),
-	mLastTimeDiff(0.0)
+LLViewerStats::LLViewerStats() 
+:	mLastTimeDiff(0.0)
 {
-	for (S32 i = 0; i < ST_COUNT; i++)
-	{
-		mStats[i] = 0.0;
-	}
-	
-	if (LLTimer::knownBadTimer())
-	{
-		mStats[ST_HAS_BAD_TIMER] = 1.0;
-	}	
-	
-	mAgentPositionSnaps.reset();
 	mRecording.start();
 	LLTrace::get_frame_recording().start();
 }
@@ -275,93 +201,80 @@ LLViewerStats::~LLViewerStats()
 
 void LLViewerStats::resetStats()
 {
-	LLViewerStats& stats = LLViewerStats::instance();
-	stats.mRecording.reset();
-	//stats.mVFSPendingOperations.reset();
-	//stats.mPacketsInStat.reset();
-	//stats.mPacketsLostStat.reset();
-	//stats.mPacketsOutStat.reset();
-	//stats.mFPSStat.reset();
-	//stats.mTexturePacketsStat.reset();
-	//stats.mAgentPositionSnaps.reset();
-}
-
-
-F64 LLViewerStats::getStat(EStatType type) const
-{
-	return mStats[type];
-}
-
-F64 LLViewerStats::setStat(EStatType type, F64 value)
-{
-	mStats[type] = value;
-	return mStats[type];
-}
-
-F64 LLViewerStats::incStat(EStatType type, F64 value)
-{
-	mStats[type] += value;
-	return mStats[type];
+	LLViewerStats::instance().mRecording.reset();
 }
 
 void LLViewerStats::updateFrameStats(const F64 time_diff)
 {
-	if (mPacketsLostPercentStat.getCurrent() > 5.0)
+	if (getRecording().getLastValue(LLStatViewer::PACKETS_LOST_PERCENT) > 5.0)
 	{
-		incStat(ST_LOSS_05_SECONDS, time_diff);
+		LLStatViewer::LOSS_5_PERCENT_TIME.add(time_diff);
+		//incStat(ST_LOSS_05_SECONDS, time_diff);
 	}
 	
-	if (mSimFPS.getCurrent() < 20.f && mSimFPS.getCurrent() > 0.f)
+	F32 sim_fps = getRecording().getLastValue(LLStatViewer::SIM_FPS);
+	if (0.f < sim_fps && sim_fps < 20.f)
 	{
-		incStat(ST_SIM_FPS_20_SECONDS, time_diff);
+		LLStatViewer::SIM_20_FPS_TIME.add(time_diff);
+		//incStat(ST_SIM_FPS_20_SECONDS, time_diff);
 	}
 	
-	if (mSimPhysicsFPS.getCurrent() < 20.f && mSimPhysicsFPS.getCurrent() > 0.f)
+	F32 sim_physics_fps = getRecording().getLastValue(LLStatViewer::SIM_PHYSICS_FPS);
+
+	if (0.f < sim_physics_fps && sim_physics_fps < 20.f)
 	{
-		incStat(ST_PHYS_FPS_20_SECONDS, time_diff);
+		LLStatViewer::SIM_PHYSICS_20_FPS_TIME.add(time_diff);
+		//incStat(ST_PHYS_FPS_20_SECONDS, time_diff);
 	}
 		
 	if (time_diff >= 0.5)
 	{
-		incStat(ST_FPS_2_SECONDS, time_diff);
+		LLStatViewer::FPS_2_TIME.add(time_diff);
+		//incStat(ST_FPS_2_SECONDS, time_diff);
 	}
 	if (time_diff >= 0.125)
 	{
-		incStat(ST_FPS_8_SECONDS, time_diff);
+		LLStatViewer::FPS_8_TIME.add(time_diff);
+		//incStat(ST_FPS_8_SECONDS, time_diff);
 	}
 	if (time_diff >= 0.1)
 	{
-		incStat(ST_FPS_10_SECONDS, time_diff);
+		LLStatViewer::FPS_10_TIME.add(time_diff);
+		//incStat(ST_FPS_10_SECONDS, time_diff);
 	}
 
 	if (gFrameCount && mLastTimeDiff > 0.0)
 	{
 		// new "stutter" meter
-		setStat(ST_FPS_DROP_50_RATIO,
-				(getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + 
-				 (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
+		LLStatViewer::FRAMETIME_DOUBLED.add(time_diff >= 2.0 * mLastTimeDiff ? 1 : 0);
+		//setStat(ST_FPS_DROP_50_RATIO,
+		//		(getStat(ST_FPS_DROP_50_RATIO) * (F64)(gFrameCount - 1) + 
+		//		 (time_diff >= 2.0 * mLastTimeDiff ? 1.0 : 0.0)) / gFrameCount);
 			
 
 		// old stats that were never really used
-		setStat(ST_FRAMETIME_JITTER,
-				(getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + 
-				 fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
+		LLStatViewer::FRAMETIME_JITTER.sample(mLastTimeDiff - time_diff);
+		//setStat(ST_FRAMETIME_JITTER,
+		//		(getStat(ST_FRAMETIME_JITTER) * (gFrameCount - 1) + 
+		//		 fabs(mLastTimeDiff - time_diff) / mLastTimeDiff) / gFrameCount);
 			
 		F32 average_frametime = gRenderStartTime.getElapsedTimeF32() / (F32)gFrameCount;
-		setStat(ST_FRAMETIME_SLEW,
-				(getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + 
-				 fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
+		LLStatViewer::FRAMETIME_SLEW.sample(average_frametime - time_diff);
+		//setStat(ST_FRAMETIME_SLEW,
+		//		(getStat(ST_FRAMETIME_SLEW) * (gFrameCount - 1) + 
+		//		 fabs(average_frametime - time_diff) / average_frametime) / gFrameCount);
 
 		F32 max_bandwidth = gViewerThrottle.getMaxBandwidth();
 		F32 delta_bandwidth = gViewerThrottle.getCurrentBandwidth() - max_bandwidth;
-		setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
+		LLStatViewer::DELTA_BANDWIDTH.sample<LLUnits::Bits>(delta_bandwidth);
+		//setStat(ST_DELTA_BANDWIDTH, delta_bandwidth / 1024.f);
 
-		setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
+		LLStatViewer::MAX_BANDWIDTH.sample<LLUnits::Bits>(max_bandwidth);
+		//setStat(ST_MAX_BANDWIDTH, max_bandwidth / 1024.f);
 		
 	}
 	
 	mLastTimeDiff = time_diff;
-
 }
 
 void LLViewerStats::addToMessage(LLSD &body) const
@@ -370,11 +283,11 @@ void LLViewerStats::addToMessage(LLSD &body) const
 	
 	misc["Version"] = TRUE;
 	//TODO RN: get last value, not mean
-	misc["Vertex Buffers Enabled"] = mRecording.getMean(LLStatViewer::ENABLE_VBO);
+	misc["Vertex Buffers Enabled"] = getRecording().getMean(LLStatViewer::ENABLE_VBO);
 	
-	body["AgentPositionSnaps"] = mAgentPositionSnaps.asLLSD();
-	llinfos << "STAT: AgentPositionSnaps: Mean = " << mAgentPositionSnaps.getMean() << "; StdDev = " << mAgentPositionSnaps.getStdDev() 
-			<< "; Count = " << mAgentPositionSnaps.getCount() << llendl;
+	body["AgentPositionSnaps"] = getRecording().getSum(LLStatViewer::AGENT_POSITION_SNAP).value(); //mAgentPositionSnaps.asLLSD();
+	llinfos << "STAT: AgentPositionSnaps: Mean = " << getRecording().getMean(LLStatViewer::AGENT_POSITION_SNAP).value() << "; StdDev = " << getRecording().getStandardDeviation(LLStatViewer::AGENT_POSITION_SNAP).value() 
+			<< "; Count = " << getRecording().getSampleCount(LLStatViewer::AGENT_POSITION_SNAP) << llendl;
 }
 
 // *NOTE:Mani The following methods used to exist in viewer.cpp
@@ -386,8 +299,6 @@ F32		gAveLandCompression = 0.f, gAveWaterCompression = 0.f;
 F32		gBestLandCompression = 1.f, gBestWaterCompression = 1.f;
 F32		gWorstLandCompression = 0.f, gWorstWaterCompression = 0.f;
 
-
-
 U32		gTotalWorldBytes = 0, gTotalObjectBytes = 0, gTotalTextureBytes = 0, gSimPingCount = 0;
 U32		gObjectBits = 0;
 F32		gAvgSimPing = 0.f;
@@ -403,51 +314,61 @@ void update_statistics()
 	gTotalWorldBytes += gVLManager.getTotalBytes();
 	gTotalObjectBytes += gObjectBits / 8;
 
-	LLViewerStats& stats = LLViewerStats::instance();
-
 	// make sure we have a valid time delta for this frame
 	if (gFrameIntervalSeconds > 0.f)
 	{
 		if (gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
 		{
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
+			LLStatViewer::MOUSELOOK_TIME.add(gFrameIntervalSeconds);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_MOUSELOOK_SECONDS, gFrameIntervalSeconds);
 		}
 		else if (gAgentCamera.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
 		{
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
+			LLStatViewer::AVATAR_EDIT_TIME.add(gFrameIntervalSeconds);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_AVATAR_EDIT_SECONDS, gFrameIntervalSeconds);
 		}
 		else if (LLFloaterReg::instanceVisible("build"))
 		{
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
+			LLStatViewer::TOOLBOX_TIME.add(gFrameIntervalSeconds);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TOOLBOX_SECONDS, gFrameIntervalSeconds);
 		}
 	}
-	stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
-	stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
-	stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
-	stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
-
-	stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
+	LLStatViewer::ENABLE_VBO.sample((F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+	//stats.setStat(LLViewerStats::ST_ENABLE_VBO, (F64)gSavedSettings.getBOOL("RenderVBOEnable"));
+	LLStatViewer::LIGHTING_DETAIL.sample((F64)gPipeline.getLightingDetail());
+	//stats.setStat(LLViewerStats::ST_LIGHTING_DETAIL, (F64)gPipeline.getLightingDetail());
+	LLStatViewer::DRAW_DISTANCE.sample((F64)gSavedSettings.getF32("RenderFarClip"));
+	//stats.setStat(LLViewerStats::ST_DRAW_DIST, (F64)gSavedSettings.getF32("RenderFarClip"));
+	LLStatViewer::CHAT_BUBBLES.sample((F64)gSavedSettings.getBOOL("UseChatBubbles"));
+	//stats.setStat(LLViewerStats::ST_CHAT_BUBBLES, (F64)gSavedSettings.getBOOL("UseChatBubbles"));
+
+	LLStatViewer::FRAME_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Frame"));
+	//stats.setStat(LLViewerStats::ST_FRAME_SECS, gDebugView->mFastTimerView->getTime("Frame"));
 	F64 idle_secs = gDebugView->mFastTimerView->getTime("Idle");
 	F64 network_secs = gDebugView->mFastTimerView->getTime("Network");
-	stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
-	stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
-	stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
-	stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
-	stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
+	LLStatViewer::UPDATE_STACKTIME.sample(idle_secs - network_secs);
+	//stats.setStat(LLViewerStats::ST_UPDATE_SECS, idle_secs - network_secs);
+	LLStatViewer::NETWORK_STACKTIME.sample(network_secs);
+	//stats.setStat(LLViewerStats::ST_NETWORK_SECS, network_secs);
+	LLStatViewer::IMAGE_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Update Images"));
+	//stats.setStat(LLViewerStats::ST_IMAGE_SECS, gDebugView->mFastTimerView->getTime("Update Images"));
+	LLStatViewer::REBUILD_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Sort Draw State"));
+	//stats.setStat(LLViewerStats::ST_REBUILD_SECS, gDebugView->mFastTimerView->getTime("Sort Draw State"));
+	LLStatViewer::RENDER_STACKTIME.sample(gDebugView->mFastTimerView->getTime("Geometry"));
+	//stats.setStat(LLViewerStats::ST_RENDER_SECS, gDebugView->mFastTimerView->getTime("Geometry"));
 		
 	LLCircuitData *cdp = gMessageSystem->mCircuitInfo.findCircuit(gAgent.getRegion()->getHost());
 	if (cdp)
 	{
 		LLStatViewer::SIM_PING.sample<LLUnits::Seconds>(cdp->getPingDelay());
-		stats.mSimPingStat.addValue(cdp->getPingDelay());
+		//stats.mSimPingStat.addValue(cdp->getPingDelay());
 		gAvgSimPing = ((gAvgSimPing * (F32)gSimPingCount) + (F32)(cdp->getPingDelay())) / ((F32)gSimPingCount + 1);
 		gSimPingCount++;
 	}
 	else
 	{
-		LLUnits::Seconds i(10000);
-		LLStatViewer::SIM_PING.sample(i);//<LLUnits::Seconds<U32> >(10000);
-		stats.mSimPingStat.addValue(10000);
+		LLStatViewer::SIM_PING.sample<LLUnits::Seconds>(10000);
+		//stats.mSimPingStat.addValue(10000);
 	}
 
 	//stats.mFPSStat.addValue(1);
@@ -458,7 +379,7 @@ void update_statistics()
 	LLStatViewer::OBJECT_KBIT.add<LLUnits::Bits>(gObjectBits);
 	//stats.mObjectKBitStat.addValue(gObjectBits/1024.f);
 	//stats.mVFSPendingOperations.addValue(LLVFile::getVFSThread()->getPending());
-	LLStatViewer::SIM_PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending());
+	LLStatViewer::PENDING_VFS_OPERATIONS.sample(LLVFile::getVFSThread()->getPending());
 	LLStatViewer::ASSET_KBIT.add<LLUnits::Bits>(gTransferManager.getTransferBitsIn(LLTCT_ASSET));
 	//stats.mAssetKBitStat.addValue(gTransferManager.getTransferBitsIn(LLTCT_ASSET)/1024.f);
 	gTransferManager.resetTransferBitsIn(LLTCT_ASSET);
@@ -481,7 +402,8 @@ void update_statistics()
 			visible_avatar_frames = 1.f;
 			avg_visible_avatars = (avg_visible_avatars * (F32)(visible_avatar_frames - 1.f) + visible_avatars) / visible_avatar_frames;
 		}
-		stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
+		LLStatViewer::VISIBLE_AVATARS.sample((F64)avg_visible_avatars);
+		//stats.setStat(LLViewerStats::ST_VISIBLE_AVATARS, (F64)avg_visible_avatars);
 	}
 	LLWorld::getInstance()->updateNetStats();
 	LLWorld::getInstance()->requestCacheMisses();
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 5412294cf2cd26ac39faf6d480f94c0ca04c5b8f..40109bcea386dc17af67682f86991d51f6e169bc 100755
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -28,12 +28,39 @@
 #define LL_LLVIEWERSTATS_H
 
 #include "llstat.h"
+#include "llstatenums.h"
 #include "lltextureinfo.h"
 #include "lltracerecording.h"
 #include "lltrace.h"
 
 namespace LLStatViewer
 {
+
+struct SimMeasurementSampler : public LLInstanceTracker<SimMeasurementSampler, ESimStatID>
+{
+	SimMeasurementSampler(ESimStatID id)
+	:	LLInstanceTracker(id)
+	{}
+	virtual ~SimMeasurementSampler() {}
+	virtual void sample(F64 value) = 0;
+};
+
+template<typename T = F64>
+struct SimMeasurement : public LLTrace::Measurement<T>, public SimMeasurementSampler
+{
+	SimMeasurement(const char* name, const char* description, ESimStatID stat_id)
+	:	LLTrace::Measurement<T>(name, description),
+		SimMeasurementSampler(stat_id)	
+	{}
+
+	using SimMeasurementSampler::getInstance;
+
+	/*virtual*/ void sample(F64 value)
+	{
+		LLTrace::Measurement<T>::sample(value);
+	}
+};
+
 extern LLTrace::Count<>						FPS,
 											PACKETS_IN,
 											PACKETS_LOST,
@@ -46,7 +73,6 @@ extern LLTrace::Count<>						FPS,
 											OBJECT_REZ,
 											LOADING_WEARABLES_LONG_DELAY,
 											LOGIN_TIMEOUTS,
-											FAILED_DOWNLOADS,
 											LSL_SAVES,
 											ANIMATION_UPLOADS,
 											FLY,
@@ -80,7 +106,7 @@ extern LLTrace::Count<LLUnits::Seconds>		AVATAR_EDIT_TIME,
 											SIM_PHYSICS_20_FPS_TIME,
 											LOSS_5_PERCENT_TIME;
 
-extern LLTrace::Measurement<>				SIM_TIME_DILATION,
+extern SimMeasurement<>						SIM_TIME_DILATION,
 											SIM_FPS,
 											SIM_PHYSICS_FPS,
 											SIM_AGENT_UPS,
@@ -98,10 +124,10 @@ extern LLTrace::Measurement<>				SIM_TIME_DILATION,
 											SIM_PENDING_DOWNLOADS,
 											SIM_PENDING_UPLOADS,
 											SIM_PENDING_LOCAL_UPLOADS,
-											SIM_PENDING_VFS_OPERATIONS,
 											SIM_PHYSICS_PINNED_TASKS,
-											SIM_PHYSICS_LOD_TASKS,
-											NUM_IMAGES,
+											SIM_PHYSICS_LOD_TASKS;
+
+extern LLTrace::Measurement<>				NUM_IMAGES,
 											NUM_RAW_IMAGES,
 											NUM_OBJECTS,
 											NUM_ACTIVE_OBJECTS,
@@ -109,25 +135,31 @@ extern LLTrace::Measurement<>				SIM_TIME_DILATION,
 											NUM_SIZE_CULLED,
 											NUM_VIS_CULLED,
 											ENABLE_VBO,
-											DELTA_BANDWIDTH,
-											MAX_BANDWIDTH,
 											LIGHTING_DETAIL,
 											VISIBLE_AVATARS,
 											SHADER_OBJECTS,
 											DRAW_DISTANCE,
 											CHAT_BUBBLES,
+											PENDING_VFS_OPERATIONS,
+											PACKETS_LOST_PERCENT,
 											WINDOW_WIDTH,
 											WINDOW_HEIGHT;
 
+extern LLTrace::Measurement<LLUnits::Meters> AGENT_POSITION_SNAP;
+
 extern LLTrace::Measurement<LLUnits::Bytes>	SIM_UNACKED_BYTES,
+											DELTA_BANDWIDTH,
+											MAX_BANDWIDTH,
 											SIM_PHYSICS_MEM,
 											GL_TEX_MEM,
 											GL_BOUND_MEM,
 											RAW_MEM,
 											FORMATTED_MEM;
 
-
-extern LLTrace::Measurement<LLUnits::Seconds>	SIM_PHYSICS_TIME,
+extern SimMeasurement<LLUnits::Milliseconds>	SIM_FRAME_TIME,
+												SIM_NET_TIME,
+												SIM_OTHER_TIME,
+												SIM_PHYSICS_TIME,
 												SIM_PHYSICS_STEP_TIME,
 												SIM_PHYSICS_SHAPE_UPDATE_TIME,
 												SIM_PHYSICS_OTHER_TIME,
@@ -137,171 +169,32 @@ extern LLTrace::Measurement<LLUnits::Seconds>	SIM_PHYSICS_TIME,
 												SIM_SCRIPTS_TIME,
 												SIM_SPARE_TIME,
 												SIM_SLEEP_TIME,
-												SIM_PUMP_IO_TIME,
-												SIM_PING,
-												FRAMETIME_JITTER,
-												FRAMETIME_SLEW,
-												LOGIN_SECONDS,
-												REGION_CROSSING_TIME,
-												FRAME_STACKTIME,
-												UPDATE_STACKTIME,
-												NETWORK_STACKTIME,
-												IMAGE_STACKTIME,
-												REBUILD_STACKTIME,
-												RENDER_STACKTIME;
+												SIM_PUMP_IO_TIME;
+
+
+extern LLTrace::Measurement<LLUnits::Milliseconds>	FRAMETIME_JITTER,
+													FRAMETIME_SLEW,
+													LOGIN_SECONDS,
+													REGION_CROSSING_TIME,
+													FRAME_STACKTIME,
+													UPDATE_STACKTIME,
+													NETWORK_STACKTIME,
+													IMAGE_STACKTIME,
+													REBUILD_STACKTIME,
+													RENDER_STACKTIME,
+													SIM_PING;
 }
 
 class LLViewerStats : public LLSingleton<LLViewerStats>
 {
 public:
-	LLStat	mVFSPendingOperations,
-			mFPSStat,
-			mPacketsInStat,
-			mPacketsLostStat,
-			mPacketsOutStat,
-			mPacketsLostPercentStat,
-			mTexturePacketsStat,
-			mActualInKBitStat,	// From the packet ring (when faking a bad connection)
-			mActualOutKBitStat,	// From the packet ring (when faking a bad connection)
-			mTrianglesDrawnStat;
-
-	// Simulator stats
-	LLStat	mSimTimeDilation;
-
-	LLStat	mSimFPS,
-			mSimPhysicsFPS,
-			mSimAgentUPS,
-			mSimScriptEPS;
-
-	LLStat	mSimFrameMsec,
-			mSimNetMsec,
-			mSimSimOtherMsec,
-			mSimSimPhysicsMsec;
-
-	LLStat	mSimSimPhysicsStepMsec,
-			mSimSimPhysicsShapeUpdateMsec,
-			mSimSimPhysicsOtherMsec,
-			mSimSimAIStepMsec,
-			mSimSimSkippedSilhouetteSteps,
-			mSimSimPctSteppedCharacters;
-
-	LLStat	mSimAgentMsec,
-			mSimImagesMsec,
-			mSimScriptMsec,
-			mSimSpareMsec,
-			mSimSleepMsec,
-			mSimPumpIOMsec;
-
-	LLStat	mSimMainAgents,
-			mSimChildAgents,
-			mSimObjects,
-			mSimActiveObjects,
-			mSimActiveScripts,
-			mSimPctScriptsRun;
-
-	LLStat	mSimInPPS,
-			mSimOutPPS,
-			mSimPendingDownloads,
-			mSimPendingUploads,
-			mSimPendingLocalUploads,
-			mSimTotalUnackedBytes;
-
-	LLStat	mPhysicsPinnedTasks,
-			mPhysicsLODTasks,
-			mPhysicsMemoryAllocated;
-
-	LLStat	mSimPingStat;
-
-	LLStat	mNumImagesStat,
-			mNumRawImagesStat,
-			mGLTexMemStat,
-			mGLBoundMemStat,
-			mRawMemStat,
-			mFormattedMemStat;
-
-	LLStat	mNumObjectsStat,
-			mNumActiveObjectsStat,
-			mNumNewObjectsStat,
-			mNumSizeCulledStat,
-			mNumVisCulledStat;
-
 	void resetStats();
 
 public:
 
-	// If you change this, please also add a corresponding text label in llviewerstats.cpp
-	enum EStatType
-	{
-		ST_VERSION = 0,
-		ST_AVATAR_EDIT_SECONDS = 1,
-		ST_TOOLBOX_SECONDS = 2,
-		ST_CHAT_COUNT = 3,
-		ST_IM_COUNT = 4,
-		ST_FULLSCREEN_BOOL = 5,
-		ST_RELEASE_COUNT= 6,
-		ST_CREATE_COUNT = 7,
-		ST_REZ_COUNT = 8,
-		ST_FPS_10_SECONDS = 9,
-		ST_FPS_2_SECONDS = 10,
-		ST_MOUSELOOK_SECONDS = 11,
-		ST_FLY_COUNT = 12,
-		ST_TELEPORT_COUNT = 13,
-		ST_OBJECT_DELETE_COUNT = 14,
-		ST_SNAPSHOT_COUNT = 15,
-		ST_UPLOAD_SOUND_COUNT = 16,
-		ST_UPLOAD_TEXTURE_COUNT = 17,
-		ST_EDIT_TEXTURE_COUNT = 18,
-		ST_KILLED_COUNT = 19,
-		ST_FRAMETIME_JITTER = 20,
-		ST_FRAMETIME_SLEW = 21,
-		ST_INVENTORY_TOO_LONG = 22,
-		ST_WEARABLES_TOO_LONG = 23,
-		ST_LOGIN_SECONDS = 24,
-		ST_LOGIN_TIMEOUT_COUNT = 25,
-		ST_HAS_BAD_TIMER = 26,
-		ST_DOWNLOAD_FAILED = 27,
-		ST_LSL_SAVE_COUNT = 28,
-		ST_UPLOAD_ANIM_COUNT = 29,
-		ST_FPS_8_SECONDS = 30,
-		ST_SIM_FPS_20_SECONDS = 31,
-		ST_PHYS_FPS_20_SECONDS = 32,
-		ST_LOSS_05_SECONDS = 33,
-		ST_FPS_DROP_50_RATIO = 34,
-		ST_ENABLE_VBO = 35,
-		ST_DELTA_BANDWIDTH = 36,
-		ST_MAX_BANDWIDTH = 37,
-		ST_LIGHTING_DETAIL = 38,
-		ST_VISIBLE_AVATARS = 39,
-		ST_SHADER_OBJECTS = 40,
-		ST_SHADER_ENVIRONMENT = 41,
-		ST_DRAW_DIST = 42,
-		ST_CHAT_BUBBLES = 43,
-		ST_SHADER_AVATAR = 44,
-		ST_FRAME_SECS = 45,
-		ST_UPDATE_SECS = 46,
-		ST_NETWORK_SECS = 47,
-		ST_IMAGE_SECS = 48,
-		ST_REBUILD_SECS = 49,
-		ST_RENDER_SECS = 50,
-		ST_CROSSING_AVG = 51,
-		ST_CROSSING_MAX = 52,
-		ST_LIBXUL_WIDGET_USED = 53, // Unused
-		ST_WINDOW_WIDTH = 54,
-		ST_WINDOW_HEIGHT = 55,
-		ST_TEX_BAKES = 56,
-		ST_TEX_REBAKES = 57,
-		
-		ST_COUNT = 58
-	};
-
 	LLViewerStats();
 	~LLViewerStats();
 
-	// all return latest value of given stat
-	F64 getStat(EStatType type) const;
-	F64 setStat(EStatType type, F64 value);		// set the stat to value
-	F64 incStat(EStatType type, F64 value = 1.f);	// add value to the stat
-
 	void updateFrameStats(const F64 time_diff);
 	
 	void addToMessage(LLSD &body) const;
@@ -388,8 +281,6 @@ public:
 		}
 	};
 
-	StatsAccumulator mAgentPositionSnaps;
-
 	// Phase tracking (originally put in for avatar rezzing), tracking
 	// progress of active/completed phases for activities like outfit changing.
 	typedef std::map<std::string,LLFrameTimer>	phase_map_t;
@@ -412,9 +303,9 @@ public:
 	};
 
 	LLTrace::Recording& getRecording() { return mRecording; }
+	const LLTrace::Recording& getRecording() const { return mRecording; }
 
 private:
-	F64								mStats[ST_COUNT];
 	LLTrace::Recording				mRecording;
 
 	F64								mLastTimeDiff;  // used for time stat updates
diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp
index ccfedd8881dee15ee3972cd52d9fe36a404046e4..56ccf3b1f029396c54521208600a806c9417b4a4 100644
--- a/indra/newview/llviewertexturelist.cpp
+++ b/indra/newview/llviewertexturelist.cpp
@@ -66,12 +66,6 @@
 void (*LLViewerTextureList::sUUIDCallback)(void **, const LLUUID&) = NULL;
 
 S32 LLViewerTextureList::sNumImages = 0;
-LLStat LLViewerTextureList::sNumImagesStat("Num Images", TRUE);
-LLStat LLViewerTextureList::sNumRawImagesStat("Num Raw Images", TRUE);
-LLStat LLViewerTextureList::sGLTexMemStat("GL Texture Mem", TRUE);
-LLStat LLViewerTextureList::sGLBoundMemStat("GL Bound Mem", TRUE);
-LLStat LLViewerTextureList::sRawMemStat("Raw Image Mem", TRUE);
-LLStat LLViewerTextureList::sFormattedMemStat("Formatted Image Mem", TRUE);
 
 LLViewerTextureList gTextureList;
 static LLFastTimer::DeclareTimer FTM_PROCESS_IMAGES("Process Images");
@@ -625,12 +619,15 @@ void LLViewerTextureList::updateImages(F32 max_time)
 
 	LLAppViewer::getTextureFetch()->setTextureBandwidth(recording.getPerSec(LLStatViewer::TEXTURE_KBIT).value());
 
-	LLViewerStats::getInstance()->mNumImagesStat.addValue(sNumImages);
-	LLViewerStats::getInstance()->mNumRawImagesStat.addValue(LLImageRaw::sRawImageCount);
-	LLViewerStats::getInstance()->mGLTexMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sGlobalTextureMemoryInBytes));
-	LLViewerStats::getInstance()->mGLBoundMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageGL::sBoundTextureMemoryInBytes));
-	LLViewerStats::getInstance()->mRawMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageRaw::sGlobalRawMemory));
-	LLViewerStats::getInstance()->mFormattedMemStat.addValue((F32)BYTES_TO_MEGA_BYTES(LLImageFormatted::sGlobalFormattedMemory));
+	{
+		using namespace LLStatViewer;
+		NUM_IMAGES.sample(sNumImages);
+		NUM_RAW_IMAGES.sample(LLImageRaw::sRawImageCount);
+		GL_TEX_MEM.sample<LLUnits::Bytes>(LLImageGL::sGlobalTextureMemoryInBytes);
+		GL_BOUND_MEM.sample<LLUnits::Bytes>(LLImageGL::sBoundTextureMemoryInBytes);
+		RAW_MEM.sample<LLUnits::Bytes>(LLImageRaw::sGlobalRawMemory);
+		FORMATTED_MEM.sample<LLUnits::Bytes>(LLImageFormatted::sGlobalFormattedMemory);
+	}
 
 	{
 		//loading from fast cache 
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index ab6f009e289b7895e2f62d9d9f9d9d3e2368e7bc..a00f48b5a2dd15be8a672e42e0ea40623a4ea3af 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -1,5 +1,5 @@
 /** 
- * @file llviewertexturelist.h
+ * @file llviewertexturelinumimagest.h
  * @brief Object for managing the list of images within a region
  *
  * $LicenseInfo:firstyear=2000&license=viewerlgpl$
@@ -200,14 +200,6 @@ private:
 	S32 mMaxTotalTextureMemInMegaBytes;
 	LLFrameTimer mForceDecodeTimer;
 	
-public:
-	static LLStat sNumImagesStat;
-	static LLStat sNumRawImagesStat;
-	static LLStat sGLTexMemStat;
-	static LLStat sGLBoundMemStat;
-	static LLStat sRawMemStat;
-	static LLStat sFormattedMemStat;
-
 private:
 	static S32 sNumImages;
 	static void (*sUUIDCallback)(void**, const LLUUID &);
diff --git a/indra/newview/llviewerthrottle.cpp b/indra/newview/llviewerthrottle.cpp
index 5147272122e6c0d5d4f1b1809302c7675e0916bd..34f2c8f6e6f6052b6d26b42e0c2efaffc693aedd 100644
--- a/indra/newview/llviewerthrottle.cpp
+++ b/indra/newview/llviewerthrottle.cpp
@@ -304,7 +304,8 @@ void LLViewerThrottle::updateDynamicThrottle()
 	}
 	mUpdateTimer.reset();
 
-	if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() > TIGHTEN_THROTTLE_THRESHOLD)
+	F32 mean_packets_lost = LLViewerStats::instance().getRecording().getMean(LLStatViewer::PACKETS_LOST_PERCENT);
+	if (mean_packets_lost > TIGHTEN_THROTTLE_THRESHOLD)
 	{
 		if (mThrottleFrac <= MIN_FRACTIONAL || mCurrentBandwidth / 1024.0f <= MIN_BANDWIDTH)
 		{
@@ -317,7 +318,7 @@ void LLViewerThrottle::updateDynamicThrottle()
 		mCurrent.sendToSim();
 		llinfos << "Tightening network throttle to " << mCurrentBandwidth << llendl;
 	}
-	else if (LLViewerStats::getInstance()->mPacketsLostPercentStat.getMean() <= EASE_THROTTLE_THRESHOLD)
+	else if (mean_packets_lost <= EASE_THROTTLE_THRESHOLD)
 	{
 		if (mThrottleFrac >= MAX_FRACTIONAL || mCurrentBandwidth / 1024.0f >= MAX_BANDWIDTH)
 		{
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 4ad7c49d4b5d94eb7e576816ba3aece4575be635..8161caf5e4745f396d52bdddf7cee94a613e77c7 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -2184,8 +2184,10 @@ void LLViewerWindow::reshape(S32 width, S32 height)
 			}
 		}
 
-		LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
-		LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
+		LLStatViewer::WINDOW_WIDTH.sample((F64)width);
+		//LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_WIDTH, (F64)width);
+		LLStatViewer::WINDOW_HEIGHT.sample((F64)height);
+		//LLViewerStats::getInstance()->setStat(LLViewerStats::ST_WINDOW_HEIGHT, (F64)height);
 
 		LLLayoutStack::updateClass();
 	}
diff --git a/indra/newview/llvoavatarself.cpp b/indra/newview/llvoavatarself.cpp
index fd892db3d365a2c1602202fa0c90bd11de793a40..3e8b07b6dc37d1a568d620a100a0fc1ea6a6662f 100755
--- a/indra/newview/llvoavatarself.cpp
+++ b/indra/newview/llvoavatarself.cpp
@@ -911,13 +911,14 @@ void LLVOAvatarSelf::updateRegion(LLViewerRegion *regionp)
 		{
 			++mRegionCrossingCount;
 			F64 delta = (F64)mRegionCrossingTimer.getElapsedTimeF32();
-			F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG);
-			F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
-			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
-			
-			F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
-			max = llmax(delta, max);
-			LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
+			//F64 avg = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_AVG);
+			//F64 delta_avg = (delta + avg*(mRegionCrossingCount-1)) / mRegionCrossingCount;
+			LLStatViewer::REGION_CROSSING_TIME.sample(delta);
+			//LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_AVG, delta_avg);
+			//
+			//F64 max = (mRegionCrossingCount == 1) ? 0 : LLViewerStats::getInstance()->getStat(LLViewerStats::ST_CROSSING_MAX);
+			//max = llmax(delta, max);
+			//LLViewerStats::getInstance()->setStat(LLViewerStats::ST_CROSSING_MAX, max);
 
 			// Diagnostics
 			llinfos << "Region crossing took " << (F32)(delta * 1000.0) << " ms " << llendl;
@@ -2587,7 +2588,8 @@ void LLVOAvatarSelf::processRebakeAvatarTextures(LLMessageSystem* msg, void**)
 					llinfos << "TAT: rebake - matched entry " << (S32)index << llendl;
 					gAgentAvatarp->invalidateComposite(layer_set, TRUE);
 					found = TRUE;
-					LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+					LLStatViewer::TEX_REBAKES.add(1);
+					//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
 				}
 			}
 		}
@@ -2632,7 +2634,8 @@ void LLVOAvatarSelf::forceBakeAllTextures(bool slam_for_debug)
 			}
 
 			invalidateComposite(layer_set, TRUE);
-			LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
+			LLStatViewer::TEX_REBAKES.add(1);
+			//LLViewerStats::getInstance()->incStat(LLViewerStats::ST_TEX_REBAKES);
 		}
 		else
 		{
diff --git a/indra/newview/llwearablelist.cpp b/indra/newview/llwearablelist.cpp
index 6f6411ce3cc5337a841b7ba573cef9da803ae76d..20033d6fe4dd6168af959748cca591490d6ce6e7 100644
--- a/indra/newview/llwearablelist.cpp
+++ b/indra/newview/llwearablelist.cpp
@@ -136,7 +136,7 @@ void LLWearableList::processGetAssetReply( const char* filename, const LLAssetID
 		{
 			LLFile::remove(std::string(filename));
 		}
-		LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
+		//LLViewerStats::getInstance()->incStat( LLViewerStats::ST_DOWNLOAD_FAILED );
 
 		LL_WARNS("Wearable") << "Wearable download failed: " << LLAssetStorage::getErrorString( status ) << " " << uuid << LL_ENDL;
 		switch( status )
diff --git a/indra/newview/llworld.cpp b/indra/newview/llworld.cpp
index 9e495c46b11c0665911d6639881b7a61c0d896ee..604741ff27efccab44dd3c92b18fc42c46724326 100644
--- a/indra/newview/llworld.cpp
+++ b/indra/newview/llworld.cpp
@@ -712,13 +712,15 @@ void LLWorld::updateNetStats()
 	LLStatViewer::PACKETS_IN.add(packets_in);
 	LLStatViewer::PACKETS_OUT.add(packets_out);
 	LLStatViewer::PACKETS_LOST.add(packets_lost);
+	LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in));
 	//LLViewerStats::getInstance()->mPacketsInStat.addValue(packets_in);
 	//LLViewerStats::getInstance()->mPacketsOutStat.addValue(packets_out);
 	//LLViewerStats::getInstance()->mPacketsLostStat.addValue(gMessageSystem->mDroppedPackets);
-	//if (packets_in)
-	//{
+	if (packets_in)
+	{
+		LLStatViewer::PACKETS_LOST_PERCENT.sample(100.f*((F32)packets_lost/(F32)packets_in));
 	//	LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(100.f*((F32)packets_lost/(F32)packets_in));
-	//}
+	}
 	//else
 	//{
 	//	LLViewerStats::getInstance()->mPacketsLostPercentStat.addValue(0.f);