diff --git a/indra/llcommon/lldate.cpp b/indra/llcommon/lldate.cpp
index d8b3dfe6c67a5947049f23a39e98f1e33228cf1a..5569b4102d655929a40b536c550d8a3d4344ea1e 100644
--- a/indra/llcommon/lldate.cpp
+++ b/indra/llcommon/lldate.cpp
@@ -54,8 +54,8 @@ LLDate::LLDate(const LLDate& date) :
 	mSecondsSinceEpoch(date.mSecondsSinceEpoch)
 {}
 
-LLDate::LLDate(LLUnit::Seconds<F64> seconds_since_epoch) :
-	mSecondsSinceEpoch(seconds_since_epoch)
+LLDate::LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch) :
+	mSecondsSinceEpoch(seconds_since_epoch.value())
 {}
 
 LLDate::LLDate(const std::string& iso8601_date)
diff --git a/indra/llcommon/lldate.h b/indra/llcommon/lldate.h
index 0500b1dcd817e20c0a6dfc63f4859b2bd79b4b34..b62a8461479e34036882384219a0ac0437ec9da2 100644
--- a/indra/llcommon/lldate.h
+++ b/indra/llcommon/lldate.h
@@ -57,9 +57,9 @@ class LL_COMMON_API LLDate
 	/** 
 	 * @brief Construct a date from a seconds since epoch value.
 	 *
-	 * @pararm seconds_since_epoch The number of seconds since UTC epoch.
+	 * @param seconds_since_epoch The number of seconds since UTC epoch.
 	 */
-	LLDate(LLUnit::Seconds<F64> seconds_since_epoch);
+	LLDate(LLUnit<LLUnits::Seconds, F64> seconds_since_epoch);
 
 	/** 
 	 * @brief Construct a date from a string representation
diff --git a/indra/llcommon/lldefs.h b/indra/llcommon/lldefs.h
index 5a4b8325f427dd2bb7f5f72a04097f7487015eb7..d57b9dccff1549ed8de0a38f4cff4204bb91dc0f 100644
--- a/indra/llcommon/lldefs.h
+++ b/indra/llcommon/lldefs.h
@@ -244,5 +244,8 @@ inline void llswap(LLDATATYPE& lhs, LLDATATYPE& rhs)
 	rhs = tmp;
 }
 
+#define LL_GLUE_IMPL(x, y) x##y
+#define LL_GLUE_TOKENS(x, y) LL_GLUE_IMPL(x, y)
+
 #endif // LL_LLDEFS_H
 
diff --git a/indra/llcommon/llerrorlegacy.h b/indra/llcommon/llerrorlegacy.h
index 37cee579cd2171f8d2378932df6181b45316adb6..58cc2899afa84ecea89d9ee30861b0bf87431986 100644
--- a/indra/llcommon/llerrorlegacy.h
+++ b/indra/llcommon/llerrorlegacy.h
@@ -29,6 +29,7 @@
 #define LL_LLERRORLEGACY_H
 
 #include "llpreprocessor.h"
+#include <boost/static_assert.hpp>
 
 /*
 	LEGACY -- DO NOT USE THIS STUFF ANYMORE
@@ -111,6 +112,12 @@ const int LL_ERR_PRICE_MISMATCH = -23018;
 #define llverify(func)			do {if (func) {}} while(0)
 #endif
 
+#ifdef LL_WINDOWS
+#define llstatic_assert(func, msg) static_assert(func, msg)
+#else
+#define llstatic_assert(func, msg) BOOST_STATIC_ASSERT(func)
+#endif
+
 // handy compile-time assert - enforce those template parameters! 
 #define cassert(expn) typedef char __C_ASSERT__[(expn)?1:-1]   /* Flawfinder: ignore */
 	//XXX: used in two places in llcommon/llskipmap.h
diff --git a/indra/llcommon/lltimer.cpp b/indra/llcommon/lltimer.cpp
index 05f6b789e40e4f7a6d8c78f381bbc85e579b425d..23cebf4336783a8b9d5f5362b3dbf06eea91bca5 100644
--- a/indra/llcommon/lltimer.cpp
+++ b/indra/llcommon/lltimer.cpp
@@ -287,15 +287,14 @@ LLTimer::~LLTimer()
 }
 
 // static
-LLUnit::Microseconds<U64> LLTimer::getTotalTime()
+LLUnit<LLUnits::Microseconds, U64> LLTimer::getTotalTime()
 {
-	LLUnit::Seconds<F64> sec = LLUnit::Milliseconds<U32>(2000) + LLUnit::Hours<F32>(1.f / 360.f);
 	// simply call into the implementation function.
 	return totalTime();
 }	
 
 // static
-LLUnit::Seconds<F64> LLTimer::getTotalSeconds()
+LLUnit<LLUnits::Seconds, F64> LLTimer::getTotalSeconds()
 {
 	return U64_to_F64(getTotalTime()) * USEC_TO_SEC_F64;
 }
@@ -344,23 +343,23 @@ U64 getElapsedTimeAndUpdate(U64& lastClockCount)
 }
 
 
-LLUnit::Seconds<F64> LLTimer::getElapsedTimeF64() const
+LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeF64() const
 {
 	U64 last = mLastClockCount;
 	return (F64)getElapsedTimeAndUpdate(last) * gClockFrequencyInv;
 }
 
-LLUnit::Seconds<F32> LLTimer::getElapsedTimeF32() const
+LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeF32() const
 {
 	return (F32)getElapsedTimeF64();
 }
 
-LLUnit::Seconds<F64> LLTimer::getElapsedTimeAndResetF64()
+LLUnit<LLUnits::Seconds, F64> LLTimer::getElapsedTimeAndResetF64()
 {
 	return (F64)getElapsedTimeAndUpdate(mLastClockCount) * gClockFrequencyInv;
 }
 
-LLUnit::Seconds<F32> LLTimer::getElapsedTimeAndResetF32()
+LLUnit<LLUnits::Seconds, F32> LLTimer::getElapsedTimeAndResetF32()
 {
 	return (F32)getElapsedTimeAndResetF64();
 }
@@ -373,7 +372,7 @@ void  LLTimer::setTimerExpirySec(F32 expiration)
 		+ (U64)((F32)(expiration * gClockFrequency));
 }
 
-LLUnit::Seconds<F32> LLTimer::getRemainingTimeF32() const
+LLUnit<LLUnits::Seconds, F32> LLTimer::getRemainingTimeF32() const
 {
 	U64 cur_ticks = get_clock_count();
 	if (cur_ticks > mExpirationTicks)
diff --git a/indra/llcommon/lltimer.h b/indra/llcommon/lltimer.h
index e0a880a34647c4f0526625a315569c881654f68a..5cb2b181110099a1dfd6d2dfb02b6901f7cc7baf 100644
--- a/indra/llcommon/lltimer.h
+++ b/indra/llcommon/lltimer.h
@@ -67,16 +67,16 @@ class LL_COMMON_API LLTimer
 
 	// Return a high precision number of seconds since the start of
 	// this application instance.
-	static LLUnit::Seconds<F64> getElapsedSeconds()
+	static LLUnit<LLUnits::Seconds, F64> getElapsedSeconds()
 	{
 		return sTimer->getElapsedTimeF64();
 	}
 
 	// Return a high precision usec since epoch
-	static LLUnit::Microseconds<U64> getTotalTime();
+	static LLUnit<LLUnits::Microseconds, U64> getTotalTime();
 
 	// Return a high precision seconds since epoch
-	static LLUnit::Seconds<F64> getTotalSeconds();
+	static LLUnit<LLUnits::Seconds, F64> getTotalSeconds();
 
 
 	// MANIPULATORS
@@ -87,16 +87,16 @@ class LL_COMMON_API LLTimer
 	void setTimerExpirySec(F32 expiration);
 	BOOL checkExpirationAndReset(F32 expiration);
 	BOOL hasExpired() const;
-	LLUnit::Seconds<F32> getElapsedTimeAndResetF32();	// Returns elapsed time in seconds with reset
-	LLUnit::Seconds<F64> getElapsedTimeAndResetF64();
+	LLUnit<LLUnits::Seconds, F32> getElapsedTimeAndResetF32();	// Returns elapsed time in seconds with reset
+	LLUnit<LLUnits::Seconds, F64> getElapsedTimeAndResetF64();
 
-	LLUnit::Seconds<F32> getRemainingTimeF32() const;
+	LLUnit<LLUnits::Seconds, F32> getRemainingTimeF32() const;
 
 	static BOOL knownBadTimer();
 
 	// ACCESSORS
-	LLUnit::Seconds<F32> getElapsedTimeF32() const;			// Returns elapsed time in seconds
-	LLUnit::Seconds<F64> getElapsedTimeF64() const;			// Returns elapsed time in seconds
+	LLUnit<LLUnits::Seconds, F32> getElapsedTimeF32() const;			// Returns elapsed time in seconds
+	LLUnit<LLUnits::Seconds, F64> getElapsedTimeF64() const;			// Returns elapsed time in seconds
 
 	bool getStarted() const { return mStarted; }
 
diff --git a/indra/llcommon/lltrace.h b/indra/llcommon/lltrace.h
index e2530a8a24fec9e487baa5ffb79d46dc7c299741..d289ea9a88c6be4255dd8682ab51d3e035021c12 100644
--- a/indra/llcommon/lltrace.h
+++ b/indra/llcommon/lltrace.h
@@ -38,37 +38,35 @@
 
 #include <list>
 
-#define LL_TOKEN_PASTE_ACTUAL(x, y) x##y
-#define LL_TOKEN_PASTE(x, y) LL_TOKEN_PASTE_ACTUAL(x, y)
-#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_TOKEN_PASTE(block_time_recorder, __COUNTER__)(block_timer);
+#define LL_RECORD_BLOCK_TIME(block_timer) LLTrace::BlockTimer::Recorder LL_GLUE_TOKENS(block_time_recorder, __COUNTER__)(block_timer);
 
 namespace LLTrace
 {
 	class Recording;
 
-	typedef LLUnit::Bytes<F64>			Bytes;
-	typedef LLUnit::Kilobytes<F64>		Kilobytes;
-	typedef LLUnit::Megabytes<F64>		Megabytes;
-	typedef LLUnit::Gigabytes<F64>		Gigabytes;
-	typedef LLUnit::Bits<F64>			Bits;
-	typedef LLUnit::Kilobits<F64>		Kilobits;
-	typedef LLUnit::Megabits<F64>		Megabits;
-	typedef LLUnit::Gigabits<F64>		Gigabits;
-
-	typedef LLUnit::Seconds<F64>		Seconds;
-	typedef LLUnit::Milliseconds<F64>	Milliseconds;
-	typedef LLUnit::Minutes<F64>		Minutes;
-	typedef LLUnit::Hours<F64>			Hours;
-	typedef LLUnit::Days<F64>			Days;
-	typedef LLUnit::Weeks<F64>			Weeks;
-	typedef LLUnit::Milliseconds<F64>	Milliseconds;
-	typedef LLUnit::Microseconds<F64>	Microseconds;
-	typedef LLUnit::Nanoseconds<F64>	Nanoseconds;
-
-	typedef LLUnit::Meters<F64>			Meters;
-	typedef LLUnit::Kilometers<F64>		Kilometers;
-	typedef LLUnit::Centimeters<F64>	Centimeters;
-	typedef LLUnit::Millimeters<F64>	Millimeters;
+	typedef LLUnit<LLUnits::Bytes, F64>			Bytes;
+	typedef LLUnit<LLUnits::Kilobytes, F64>		Kilobytes;
+	typedef LLUnit<LLUnits::Megabytes, F64>		Megabytes;
+	typedef LLUnit<LLUnits::Gigabytes, F64>		Gigabytes;
+	typedef LLUnit<LLUnits::Bits, F64>			Bits;
+	typedef LLUnit<LLUnits::Kilobits, F64>		Kilobits;
+	typedef LLUnit<LLUnits::Megabits, F64>		Megabits;
+	typedef LLUnit<LLUnits::Gigabits, F64>		Gigabits;
+
+	typedef LLUnit<LLUnits::Seconds, F64>		Seconds;
+	typedef LLUnit<LLUnits::Milliseconds, F64>	Milliseconds;
+	typedef LLUnit<LLUnits::Minutes, F64>		Minutes;
+	typedef LLUnit<LLUnits::Hours, F64>			Hours;
+	typedef LLUnit<LLUnits::Days, F64>			Days;
+	typedef LLUnit<LLUnits::Weeks, F64>			Weeks;
+	typedef LLUnit<LLUnits::Milliseconds, F64>	Milliseconds;
+	typedef LLUnit<LLUnits::Microseconds, F64>	Microseconds;
+	typedef LLUnit<LLUnits::Nanoseconds, F64>	Nanoseconds;
+
+	typedef LLUnit<LLUnits::Meters, F64>			Meters;
+	typedef LLUnit<LLUnits::Kilometers, F64>		Kilometers;
+	typedef LLUnit<LLUnits::Centimeters, F64>	Centimeters;
+	typedef LLUnit<LLUnits::Millimeters, F64>	Millimeters;
 
 	void init();
 	void cleanup();
@@ -438,7 +436,7 @@ namespace LLTrace
 		void sample(UNIT_T value)
 		{
 			T converted_value;
-			converted_value.assignFrom(value);
+			converted_value = value;
 			getPrimaryAccumulator().sample((storage_t)converted_value.value());
 		}
 	};
@@ -478,7 +476,7 @@ namespace LLTrace
 		void add(UNIT_T value)
 		{
 			T converted_value;
-			converted_value.assignFrom(value);
+			converted_value = value;
 			getPrimaryAccumulator().add((storage_t)converted_value.value());
 		}
 	};
diff --git a/indra/llcommon/lltracerecording.h b/indra/llcommon/lltracerecording.h
index fc96631ce01fb74a023bc442b47c347cb83f5071..ca9950b78d3c521151ede04d5a1093eadeac4094 100644
--- a/indra/llcommon/lltracerecording.h
+++ b/indra/llcommon/lltracerecording.h
@@ -197,7 +197,7 @@ namespace LLTrace
 		U32 getSampleCount(const TraceType<MeasurementAccumulator<F64> >& stat) const;
 		U32 getSampleCount(const TraceType<MeasurementAccumulator<S64> >& stat) const;
 
-		LLUnit::Seconds<F64> getDuration() const { return mElapsedSeconds; }
+		LLUnit<LLUnits::Seconds, F64> getDuration() const { return mElapsedSeconds; }
 
 	private:
 		friend class ThreadRecorder;
diff --git a/indra/llcommon/llunit.h b/indra/llcommon/llunit.h
index 45199057076941fc83aa3c58ed25cba28b0a8c4b..0dcafbe26e29208ef0615603ce4f64ae0cbdd579 100644
--- a/indra/llcommon/llunit.h
+++ b/indra/llcommon/llunit.h
@@ -30,326 +30,288 @@
 #include "stdtypes.h"
 #include "llpreprocessor.h"
 
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT = BASE_UNIT>
-struct LLUnitType : public BASE_UNIT
+namespace LLUnits
 {
-	typedef DERIVED_UNIT unit_t;
-
-	typedef typename STORAGE_TYPE storage_t;
-	typedef void is_unit_tag_t;
-
-	LLUnitType()
-	{}
-
-	LLUnitType(storage_t value)
-	:	BASE_UNIT(convertToBase(value))
-	{}
-
-	// implicit downcast
-	operator unit_t& ()
-	{
-		return static_cast<unit_t&>(*this);
-	}
-
-	operator storage_t () const
-	{
-		return value();
-	}
-
-	storage_t value() const
-	{
-		return convertToDerived(mBaseValue);
-	}
-
-	template<typename CONVERTED_TYPE>
-	storage_t as() const
-	{
-		return CONVERTED_TYPE(*this).value();
-	}
-
-protected:
-	static storage_t convertToBase(storage_t derived_value)
-	{
-		return (storage_t)((F32)derived_value * unit_t::conversionToBaseFactor());
-	}
-
-	static storage_t convertToDerived(storage_t base_value)
+template<typename DERIVED_UNITS_TAG, typename BASE_UNITS_TAG>
+struct ConversionFactor
+{
+	static F64 get()
 	{
-		return (storage_t)((F32)base_value / unit_t::conversionToBaseFactor());
+		llstatic_assert(sizeof(DERIVED_UNITS_TAG) == 0, "Cannot convert between types.");
 	}
+};
 
+template<typename BASE_UNITS_TAG>
+struct ConversionFactor<BASE_UNITS_TAG, BASE_UNITS_TAG>
+{
+	static F64 get() { return 1.0; }
 };
+}
 
-template<typename STORAGE_TYPE, typename T>
-struct LLUnitType<STORAGE_TYPE, T, T>
+template<typename UNIT_TYPE, typename STORAGE_TYPE>
+struct LLUnit
 {
-	typedef T unit_t;
-	typedef STORAGE_TYPE storage_t;
+	typedef LLUnit<UNIT_TYPE, STORAGE_TYPE> self_t;
+	typedef typename STORAGE_TYPE storage_t;
 	typedef void is_unit_tag_t;
 
-	LLUnitType()
-	:	mBaseValue()
+	LLUnit(storage_t value = storage_t())
+	:	mValue(value)
 	{}
 
-	LLUnitType(storage_t value)
-	:	mBaseValue(value)
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	LLUnit(LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
+	:	mValue(convert(other))
 	{}
 
-	unit_t& operator=(storage_t value)
+	LLUnit(self_t& other)
+	:	mValue(other.mValue)
+	{}
+
+	self_t& operator = (storage_t value)
 	{
-		setBaseValue(value);
+		mValue = value;
 		return *this;
 	}
 
-	//implicit downcast
-	operator unit_t& ()
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	self_t& operator = (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
 	{
-		return static_cast<unit_t&>(*this);
+		mValue = convert(other);
+		return *this;
 	}
 
-	operator storage_t () const
+	operator storage_t() const
 	{
 		return value();
 	}
 
-	storage_t value() const { return mBaseValue; }
-
-	template<typename CONVERTED_TYPE>
-	storage_t as() const
+	storage_t value() const
 	{
-		return CONVERTED_TYPE(*this).value();
+		return mValue;
 	}
 
-	static storage_t convertToBase(storage_t derived_value)
+	void operator += (storage_t value)
 	{
-		return (storage_t)derived_value;
+		mValue += value;
 	}
 
-	static storage_t convertToDerived(storage_t base_value)
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	void operator += (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
 	{
-		return (storage_t)base_value;
+		mValue += convert(other);
 	}
 
-	void operator += (const unit_t other)
+	void operator -= (storage_t value)
 	{
-		mBaseValue += other.mBaseValue;
+		mValue -= value;
 	}
 
-	void operator -= (const unit_t other)
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	void operator -= (LLUnit<OTHER_UNIT, OTHER_STORAGE> other)
 	{
-		mBaseValue -= other.mBaseValue;
+		mValue -= convert(other);
 	}
 
 	void operator *= (storage_t multiplicand)
 	{
-		mBaseValue *= multiplicand;
+		mValue *= multiplicand;
+	}
+
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	void operator *= (LLUnit<OTHER_UNIT, OTHER_STORAGE> multiplicand)
+	{
+		llstatic_assert(sizeof(OTHER_UNIT) == false, "Multiplication of unit types not supported.");
 	}
 
 	void operator /= (storage_t divisor)
 	{
-		mBaseValue /= divisor;
+		mValue /= divisor;
 	}
 
-protected:
-	void setBaseValue(storage_t value)
+	template<typename OTHER_UNIT, typename OTHER_STORAGE>
+	void operator /= (LLUnit<OTHER_UNIT, OTHER_STORAGE> divisor)
 	{
-		mBaseValue = value;
+		llstatic_assert(sizeof(OTHER_UNIT) == false, "Division of unit types not supported.");
 	}
 
-	storage_t mBaseValue;
-};
+	template<typename SOURCE_UNITS, typename SOURCE_VALUE>
+	static storage_t convert(LLUnit<SOURCE_UNITS, SOURCE_VALUE> v) 
+	{ 
+		return (storage_t)(v.value() 
+			* LLUnits::ConversionFactor<SOURCE_UNITS, typename UNIT_TYPE::base_unit_t>::get() 
+			* LLUnits::ConversionFactor<typename UNIT_TYPE::base_unit_t, UNIT_TYPE>::get()); 
+	}
 
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-struct LLUnitTypeWrapper
-:	public LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>
-{
-	typedef LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> unit_t;
-	LLUnitTypeWrapper(const unit_t& other)
-	:	unit_t(other)
-	{}
-};
+protected:
 
+	storage_t mValue;
+};
 
 //
 // operator +
 //
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-DERIVED_UNIT operator + (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE2, BASE_UNIT2, DERIVED_UNIT2> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator + (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
 {
-	return DERIVED_UNIT(first + LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>(second).value());
+	LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+	result += second;
+	return result;
 }
 
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
+{
+	LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+	result += second;
+	return result;
+}
 
-//
-// operator -
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-DERIVED_UNIT operator - (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator + (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
 {
-	return DERIVED_UNIT(first - LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>(second).value());
+	LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+	result += second;
+	return result;
 }
 
 //
-// operator *
+// operator -
 //
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator * (STORAGE_TYPE first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+LLUnit<STORAGE_TYPE1, UNIT_TYPE1> operator - (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second)
 {
-	return DERIVED_UNIT(first * second.value());
+	LLUnit<STORAGE_TYPE1, UNIT_TYPE1> result(first);
+	result -= second;
+	return result;
 }
 
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator * (LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> first, STORAGE_TYPE second)
+
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
 {
-	return DERIVED_UNIT(first.value() * second);
+	LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+	result -= second;
+	return result;
 }
 
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator - (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
+{
+	LLUnit<STORAGE_TYPE, UNIT_TYPE> result(first);
+	result -= second;
+	return result;
+}
 
 //
-// operator /
+// operator *
 //
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator / (STORAGE_TYPE first, LLUnitTypeWrapper<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
 {
-	return DERIVED_UNIT(first / second.value());
+	return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first * second.value());
 }
 
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-DERIVED_UNIT operator / (LLUnitTypeWrapper<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> first, STORAGE_TYPE second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator * (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
 {
-	return DERIVED_UNIT(first.value() / second);
+	return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first.value() * second);
 }
 
-//
-// operator <
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT, typename STORAGE_TYPE2, typename BASE_UNIT2, typename DERIVED_UNIT2>
-
-bool operator < (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+void operator * (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
 {
-	return first < second.value();
+	llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
 }
 
 //
-// operator <=
+// operator /
 //
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator <= (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+SCALAR_TYPE operator / (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)
 {
-	return first <= second.value();
+	return SCALAR_TYPE(first / second.value());
 }
 
-
-//
-// operator >
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator > (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>
+LLUnit<STORAGE_TYPE, UNIT_TYPE> operator / (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)
 {
-	return first > second.value();
+	return LLUnit<STORAGE_TYPE, UNIT_TYPE>(first.value() / second);
 }
 
-//
-// operator >=
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator >= (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>
+void operator / (LLUnit<STORAGE_TYPE1, UNIT_TYPE1>, LLUnit<STORAGE_TYPE2, UNIT_TYPE2>)
 {
-	return first >= second.value();
+	llstatic_assert(sizeof(STORAGE_TYPE1) == false, "Multiplication of unit types results in new unit type - not supported.");
 }
 
-//
-// operator ==
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator == (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
-{
-	return first == second.value();
+#define COMPARISON_OPERATORS(op)                                                                     \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>                            \
+bool operator op (SCALAR_TYPE first, LLUnit<STORAGE_TYPE, UNIT_TYPE> second)                         \
+{                                                                                                    \
+	return first op second.value();                                                                  \
+}                                                                                                    \
+	                                                                                                 \
+template<typename STORAGE_TYPE, typename UNIT_TYPE, typename SCALAR_TYPE>                            \
+bool operator op (LLUnit<STORAGE_TYPE, UNIT_TYPE> first, SCALAR_TYPE second)                         \
+{                                                                                                    \
+	return first.value() op second;                                                                  \
+}                                                                                                    \
+	                                                                                                 \
+template<typename STORAGE_TYPE1, typename UNIT_TYPE1, typename STORAGE_TYPE2, typename UNIT_TYPE2>   \
+bool operator op (LLUnit<STORAGE_TYPE1, UNIT_TYPE1> first, LLUnit<STORAGE_TYPE2, UNIT_TYPE2> second) \
+{                                                                                                    \
+	return first.value() op first.convert(second);                                                   \
 }
 
-//
-// operator !=
-//
-template<typename STORAGE_TYPE, typename BASE_UNIT, typename DERIVED_UNIT>
-bool operator != (typename LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT>::storage_t first, LLUnitType<STORAGE_TYPE, BASE_UNIT, DERIVED_UNIT> second)
+COMPARISON_OPERATORS(<)
+COMPARISON_OPERATORS(<=)
+COMPARISON_OPERATORS(>)
+COMPARISON_OPERATORS(>=)
+COMPARISON_OPERATORS(==)
+COMPARISON_OPERATORS(!=)
+
+namespace LLUnits
 {
-	return first != second.value();
+#define LL_DECLARE_DERIVED_UNIT(base_unit_name, unit_name, conversion_factor)\
+struct unit_name                                                             \
+{                                                                            \
+	typedef base_unit_name base_unit_t;                                      \
+};                                                                           \
+template<>                                                                   \
+struct ConversionFactor<unit_name, base_unit_name>                           \
+{                                                                            \
+	static F64 get() { return (conversion_factor); }                         \
+};                                                                           \
+	                                                                         \
+template<>                                                                   \
+struct ConversionFactor<base_unit_name, unit_name>						     \
+{                                                                            \
+	static F64 get() { return 1.0 / (conversion_factor); }                   \
 }
 
-#define LL_DECLARE_BASE_UNIT(unit_name)                                                                          \
-	template<typename STORAGE>                                                                                   \
-	struct unit_name : public LLUnitType<STORAGE, unit_name<STORAGE>, unit_name<STORAGE> >						 \
-	{                                                                                                            \
-		typedef LLUnitType<STORAGE, unit_name> unit_t;						                                     \
-	                                                                                                             \
-		unit_name(storage_t value = 0)                                                                           \
-		:	LLUnitType(value)                                                                                    \
-		{}                                                                                                       \
-		                                                                                                         \
-		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                                            \
-		unit_name(LLUnitType<SOURCE_STORAGE_TYPE, unit_name<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source)			 \
-		{                                                                                                        \
-			assignFrom(source);			                                                                         \
-		}                                                                                                        \
-		                                                                                                         \
-		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                                            \
-		void assignFrom(LLUnitType<SOURCE_STORAGE_TYPE, unit_name<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source)     \
-		{                                                                                                        \
-			setBaseValue((storage_t)source.unit_name<SOURCE_STORAGE_TYPE>::unit_t::value());                     \
-		}                                                                                                        \
-	                                                                                                             \
-	};                                                                                                           \
-
-#define LL_DECLARE_DERIVED_UNIT(base_unit, derived_unit, conversion_factor)                                      \
-	template<typename STORAGE>	                                                                                 \
-	struct derived_unit : public LLUnitType<STORAGE, base_unit<STORAGE>, derived_unit<STORAGE> >                 \
-	{                                                                                                            \
-		typedef LLUnitType<STORAGE, base_unit<STORAGE>, derived_unit<STORAGE> > unit_t;				             \
-		                                                                                                         \
-		derived_unit(storage_t value = 0)                                                                        \
-		:	LLUnitType(value)                                                                                    \
-		{}                                                                                                       \
-		                                                                                                         \
-		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                                            \
-		derived_unit(LLUnitType<SOURCE_STORAGE_TYPE, base_unit<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source)		 \
-		{                                                                                                        \
-			assignFrom(source);					                                                                 \
-		}                                                                                                        \
-		                                                                                                         \
-		template <typename SOURCE_STORAGE_TYPE, typename SOURCE_TYPE>                                            \
-		void assignFrom(LLUnitType<SOURCE_STORAGE_TYPE, base_unit<SOURCE_STORAGE_TYPE>, SOURCE_TYPE> source)     \
-		{                                                                                                        \
-			setBaseValue((storage_t)source.base_unit<SOURCE_STORAGE_TYPE>::unit_t::value());                     \
-		}                                                                                                        \
-		                                                                                                         \
-		static F32 conversionToBaseFactor() { return (F32)(conversion_factor); }                                 \
-		                                                                                                         \
-	};                                                                                                           \
-
-namespace LLUnit
-{
-	LL_DECLARE_BASE_UNIT(Bytes);
-	LL_DECLARE_DERIVED_UNIT(Bytes, Kilobytes, 1024);
-	LL_DECLARE_DERIVED_UNIT(Bytes, Megabytes, 1024 * 1024);
-	LL_DECLARE_DERIVED_UNIT(Bytes, Gigabytes, 1024 * 1024 * 1024);
-	LL_DECLARE_DERIVED_UNIT(Bytes, Bits,	  (1.f / 8.f));
-	LL_DECLARE_DERIVED_UNIT(Bytes, Kilobits,  (1024 / 8));
-	LL_DECLARE_DERIVED_UNIT(Bytes, Megabits,  (1024 / 8));
-	LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits,  (1024 * 1024 * 1024 / 8));
-
-	LL_DECLARE_BASE_UNIT(Seconds);
-	LL_DECLARE_DERIVED_UNIT(Seconds, Minutes,		60);
-	LL_DECLARE_DERIVED_UNIT(Seconds, Hours,			60 * 60);
-	LL_DECLARE_DERIVED_UNIT(Seconds, Days,			60 * 60 * 24);
-	LL_DECLARE_DERIVED_UNIT(Seconds, Weeks,			60 * 60 * 24 * 7);
-	LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds,	(1.f / 1000.f));
-	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);
+struct Bytes { typedef Bytes base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Bytes, Kilobytes, 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Megabytes, 1024 * 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Gigabytes, 1024 * 1024 * 1024);
+LL_DECLARE_DERIVED_UNIT(Bytes, Bits,	  (1.0 / 8.0));
+LL_DECLARE_DERIVED_UNIT(Bytes, Kilobits,  (1024 / 8));
+LL_DECLARE_DERIVED_UNIT(Bytes, Megabits,  (1024 / 8));
+LL_DECLARE_DERIVED_UNIT(Bytes, Gigabits,  (1024 * 1024 * 1024 / 8));
+
+struct Seconds { typedef Seconds base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Seconds, Minutes,		60);
+LL_DECLARE_DERIVED_UNIT(Seconds, Hours,			60 * 60);
+LL_DECLARE_DERIVED_UNIT(Seconds, Days,			60 * 60 * 24);
+LL_DECLARE_DERIVED_UNIT(Seconds, Weeks,			60 * 60 * 24 * 7);
+LL_DECLARE_DERIVED_UNIT(Seconds, Milliseconds,	(1.0 / 1000.0));
+LL_DECLARE_DERIVED_UNIT(Seconds, Microseconds,	(1.0 / (1000000.0)));
+LL_DECLARE_DERIVED_UNIT(Seconds, Nanoseconds,	(1.0 / (1000000000.0)));
+
+struct Meters { typedef Meters base_unit_t; };
+LL_DECLARE_DERIVED_UNIT(Meters, Kilometers, 1000);
+LL_DECLARE_DERIVED_UNIT(Meters, Centimeters, (1.0 / 100));
+LL_DECLARE_DERIVED_UNIT(Meters, Millimeters, (1.0 / 1000));
 }
 
 #endif // LL_LLUNIT_H
diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h
index 78223e1e6528c61e055202c67b4d0cc43e753b2b..0d632f59be3a180851c0339bf4841f94a4c86c35 100644
--- a/indra/llmath/v4color.h
+++ b/indra/llmath/v4color.h
@@ -49,10 +49,10 @@ class LLColor4
 		LLColor4();						// Initializes LLColor4 to (0, 0, 0, 1)
 		LLColor4(F32 r, F32 g, F32 b);		// Initializes LLColor4 to (r, g, b, 1)
 		LLColor4(F32 r, F32 g, F32 b, F32 a);		// Initializes LLColor4 to (r. g, b, a)
-		explicit LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc))
-		explicit LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
-		explicit LLColor4(const LLColor3 &vec, F32 a = 1.f);	// Initializes LLColor4 to (vec, a)
+		LLColor4(const LLColor3 &vec, F32 a = 1.f);	// Initializes LLColor4 to (vec, a)
 		explicit LLColor4(const LLSD& sd);
+		explicit LLColor4(const F32 *vec);			// Initializes LLColor4 to (vec[0]. vec[1], vec[2], 1)
+		explicit LLColor4(U32 clr);							// Initializes LLColor4 to (r=clr>>24, etc))
 		explicit LLColor4(const LLColor4U& color4u);  // "explicit" to avoid automatic conversion
 		explicit LLColor4(const LLVector4& vector4);  // "explicit" to avoid automatic conversion
 
diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp
index fc1edbe664c8640f12bfdd20843b055a259deea0..5361d8e7bebd118a16cd5cd917c58d8c44373c54 100755
--- a/indra/llrender/llimagegl.cpp
+++ b/indra/llrender/llimagegl.cpp
@@ -50,9 +50,9 @@ U32 wpo2(U32 i);
 
 U32 LLImageGL::sUniqueCount				= 0;
 U32 LLImageGL::sBindCount				= 0;
-LLUnit::Bytes<S32> LLImageGL::sGlobalTextureMemory		= 0;
-LLUnit::Bytes<S32> LLImageGL::sBoundTextureMemory		= 0;
-LLUnit::Bytes<S32> LLImageGL::sCurBoundTextureMemory	= 0;
+LLUnit<LLUnits::Bytes, S32> LLImageGL::sGlobalTextureMemory		= 0;
+LLUnit<LLUnits::Bytes, S32> LLImageGL::sBoundTextureMemory		= 0;
+LLUnit<LLUnits::Bytes, S32> LLImageGL::sCurBoundTextureMemory	= 0;
 S32 LLImageGL::sCount					= 0;
 LLImageGL::dead_texturelist_t LLImageGL::sDeadTextureList[LLTexUnit::TT_NONE];
 U32 LLImageGL::sCurTexName = 1;
diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h
index dfa59f2a34a6cd2e49002931f3bda25014ddb79b..11555e20c4f523c1c2e3beec9fb3cbd98da94005 100755
--- a/indra/llrender/llimagegl.h
+++ b/indra/llrender/llimagegl.h
@@ -246,9 +246,9 @@ class LLImageGL : public LLRefCount
 	static F32 sLastFrameTime;
 
 	// Global memory statistics
-	static LLUnit::Bytes<S32> sGlobalTextureMemory;	// Tracks main memory texmem
-	static LLUnit::Bytes<S32> sBoundTextureMemory;	// Tracks bound texmem for last completed frame
-	static LLUnit::Bytes<S32> sCurBoundTextureMemory;		// Tracks bound texmem for current frame
+	static LLUnit<LLUnits::Bytes, S32> sGlobalTextureMemory;	// Tracks main memory texmem
+	static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory;	// Tracks bound texmem for last completed frame
+	static LLUnit<LLUnits::Bytes, S32> sCurBoundTextureMemory;		// Tracks bound texmem for current frame
 	static U32 sBindCount;					// Tracks number of texture binds for current frame
 	static U32 sUniqueCount;				// Tracks number of unique texture binds for current frame
 	static BOOL sGlobalUseAnisotropic;
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 838a982cb4061e943b23e3d49b6a50f0a4289112..ac659c409b87204653c21bd788c2783c4e0f113b 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -277,7 +277,7 @@ LLPumpIO* gServicePump = NULL;
 
 U64 gFrameTime = 0;
 F32 gFrameTimeSeconds = 0.f;
-LLUnit::Seconds<F32> gFrameIntervalSeconds = 0.f;
+LLUnit<LLUnits::Seconds, F32> gFrameIntervalSeconds = 0.f;
 F32 gFPSClamped = 10.f;						// Pretend we start at target rate.
 F32 gFrameDTClamped = 0.f;					// Time between adjacent checks to network for packets
 U64	gStartTime = 0; // gStartTime is "private", used only to calculate gFrameTimeSeconds
diff --git a/indra/newview/llappviewer.h b/indra/newview/llappviewer.h
index d9d888c6264567eeef1a2e14bd737e2720fcabb5..f2bea7cdb2c38363a06f84bbc28aae603f610a3e 100644
--- a/indra/newview/llappviewer.h
+++ b/indra/newview/llappviewer.h
@@ -322,7 +322,7 @@ extern LLPumpIO* gServicePump;
 
 extern U64      gFrameTime;					// The timestamp of the most-recently-processed frame
 extern F32		gFrameTimeSeconds;			// Loses msec precision after ~4.5 hours...
-extern LLUnit::Seconds<F32>		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds
+extern LLUnit<LLUnits::Seconds, F32>		gFrameIntervalSeconds;		// Elapsed time between current and previous gFrameTimeSeconds
 extern F32		gFPSClamped;				// Frames per second, smoothed, weighted toward last frame
 extern F32		gFrameDTClamped;
 extern U64		gStartTime;
diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp
index 4f6eaa5a5b778b099e53e65cf599ff26d088be7a..61f5ecc46f20a31035d541a2a0404fd5cd69e494 100644
--- a/indra/newview/lldrawpoolwater.cpp
+++ b/indra/newview/lldrawpoolwater.cpp
@@ -463,7 +463,7 @@ void LLDrawPoolWater::renderReflection(LLFace* face)
 
 	gGL.getTexUnit(0)->bind(mHBTex[dr]);
 
-	LLOverrideFaceColor override(this, face->getFaceColor().mV);
+	LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV));
 	face->renderIndexed();
 }
 
diff --git a/indra/newview/lltextureview.cpp b/indra/newview/lltextureview.cpp
index d734620f1042fc736cf455142c8af3c1b5606fba..288c1233e54e179c02a32983a512d6667c253dd8 100755
--- a/indra/newview/lltextureview.cpp
+++ b/indra/newview/lltextureview.cpp
@@ -503,17 +503,17 @@ class LLGLTexMemBar : public LLView
 
 void LLGLTexMemBar::draw()
 {
-	LLUnit::Megabytes<S32> bound_mem = LLViewerTexture::sBoundTextureMemory;
- 	LLUnit::Megabytes<S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem;
-	LLUnit::Megabytes<S32> total_mem = LLViewerTexture::sTotalTextureMemory;
-	LLUnit::Megabytes<S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
+	LLUnit<LLUnits::Megabytes, S32> bound_mem = LLViewerTexture::sBoundTextureMemory;
+ 	LLUnit<LLUnits::Megabytes, S32> max_bound_mem = LLViewerTexture::sMaxBoundTextureMem;
+	LLUnit<LLUnits::Megabytes, S32> total_mem = LLViewerTexture::sTotalTextureMemory;
+	LLUnit<LLUnits::Megabytes, S32> max_total_mem = LLViewerTexture::sMaxTotalTextureMem;
 	F32 discard_bias = LLViewerTexture::sDesiredDiscardBias;
 	F32 cache_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getUsage()).value() ;
 	F32 cache_max_usage = (F32)LLTrace::Megabytes(LLAppViewer::getTextureCache()->getMaxUsage()).value() ;
 	S32 line_height = LLFontGL::getFontMonospace()->getLineHeight();
 	S32 v_offset = 0;//(S32)((texture_bar_height + 2.2f) * mTextureView->mNumTextureBars + 2.0f);
-	LLUnit::Megabytes<F32> total_texture_downloaded = gTotalTextureData;
-	LLUnit::Megabytes<F32> total_object_downloaded = gTotalObjectData;
+	LLUnit<LLUnits::Megabytes, F32> total_texture_downloaded = gTotalTextureData;
+	LLUnit<LLUnits::Megabytes, F32> total_object_downloaded = gTotalObjectData;
 	U32 total_http_requests = LLAppViewer::getTextureFetch()->getCurlRequest().getTotalIssuedRequests() ;
 	//----------------------------------------------------------------------------
 	LLGLSUIDefault gls_ui;
@@ -661,7 +661,7 @@ void LLGLTexSizeBar::draw()
 
 	if(LLImageGL::sCurTexSizeBar == mIndex)
 	{
-		F32 text_color[] = {1.f, 1.f, 1.f, 0.75f};	
+		LLColor4 text_color(1.f, 1.f, 1.f, 0.75f);	
 		std::string text;
 	
 		text = llformat("%d", mTopLoaded) ;
@@ -673,8 +673,8 @@ void LLGLTexSizeBar::draw()
 									 text_color, LLFontGL::LEFT, LLFontGL::TOP);
 	}
 
-	F32 loaded_color[] = {1.0f, 0.0f, 0.0f, 0.75f};
-	F32 bound_color[] = {1.0f, 1.0f, 0.0f, 0.75f};
+	LLColor4 loaded_color(1.0f, 0.0f, 0.0f, 0.75f);
+	LLColor4 bound_color(1.0f, 1.0f, 0.0f, 0.75f);
 	gl_rect_2d(mLeft, mBottom + (S32)(mTopLoaded * mScale), (mLeft + mRight) / 2, mBottom, loaded_color) ;
 	gl_rect_2d((mLeft + mRight) / 2, mBottom + (S32)(mTopBound * mScale), mRight, mBottom, bound_color) ;
 }
diff --git a/indra/newview/llviewerassetstats.cpp b/indra/newview/llviewerassetstats.cpp
index bad2f5b4cddce82fcda0dc5ec8842709ea32ec9a..73a2e24424be0090650a7a38dce7159eb8af677a 100755
--- a/indra/newview/llviewerassetstats.cpp
+++ b/indra/newview/llviewerassetstats.cpp
@@ -430,10 +430,10 @@ void LLViewerAssetStats::getStats(AssetStats& stats, bool compact_output)
 		grid_from_region_handle(it->first, &grid_x, &grid_y);
 		r.grid_x(grid_x);
 		r.grid_y(grid_y);
-		r.duration(LLUnit::Microseconds<F64>(rec.getDuration()).value());
+		r.duration(LLUnit<LLUnits::Microseconds, F64>(rec.getDuration()).value());
 	}
 
-	stats.duration(mCurRecording ? LLUnit::Microseconds<F64>(mCurRecording->getDuration()).value() : 0.0);
+	stats.duration(mCurRecording ? LLUnit<LLUnits::Microseconds, F64>(mCurRecording->getDuration()).value() : 0.0);
 	stats.avatar.setProvided(true);
 
 	for (S32 rez_stat=0; rez_stat < mAvatarRezStates.size(); ++rez_stat)
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index acbe836c2913cf75d9cb5c533ad96d4f823170fa..197d91593c8dd1dec3a9455da574643230c28822 100755
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -2587,7 +2587,7 @@ void process_improved_im(LLMessageSystem *msg, void **user_data)
 				LLSD args;
 				args["SUBJECT"] = subj;
 				args["MESSAGE"] = mes;
-				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(timestamp));
+				LLNotifications::instance().add(LLNotification::Params("GroupNotice").substitutions(args).payload(payload).time_stamp(LLDate(timestamp)));
 			}
 
 			// Also send down the old path for now.
@@ -4416,18 +4416,18 @@ void send_agent_update(BOOL force_send, BOOL send_reliable)
 
 // *TODO: Remove this dependency, or figure out a better way to handle
 // this hack.
-extern LLUnit::Bits<U32> gObjectData;
+extern LLUnit<LLUnits::Bits, U32> gObjectData;
 
 void process_object_update(LLMessageSystem *mesgsys, void **user_data)
 {	
 	// Update the data counters
 	if (mesgsys->getReceiveCompressedSize())
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveCompressedSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();
 	}
 	else
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();
 	}
 
 	// Update the object...
@@ -4439,11 +4439,11 @@ void process_compressed_object_update(LLMessageSystem *mesgsys, void **user_data
 	// Update the data counters
 	if (mesgsys->getReceiveCompressedSize())
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveCompressedSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();
 	}
 	else
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();
 	}
 
 	// Update the object...
@@ -4455,11 +4455,11 @@ void process_cached_object_update(LLMessageSystem *mesgsys, void **user_data)
 	// Update the data counters
 	if (mesgsys->getReceiveCompressedSize())
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveCompressedSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();
 	}
 	else
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();
 	}
 
 	// Update the object...
@@ -4471,11 +4471,11 @@ void process_terse_object_update_improved(LLMessageSystem *mesgsys, void **user_
 {
 	if (mesgsys->getReceiveCompressedSize())
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveCompressedSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveCompressedSize();
 	}
 	else
 	{
-		gObjectData += (LLUnit::Bytes<U32>)mesgsys->getReceiveSize();
+		gObjectData += (LLUnit<LLUnits::Bytes, U32>)mesgsys->getReceiveSize();
 	}
 
 	gObjectList.processCompressedObjectUpdate(mesgsys, user_data, OUT_TERSE_IMPROVED);
diff --git a/indra/newview/llviewerstats.cpp b/indra/newview/llviewerstats.cpp
index 317fe5eaf8e2ad4dc283ff08b9d66dab6cfb2f70..36b1179e0482e363ab52fe3c46ad5ed8a7612a37 100755
--- a/indra/newview/llviewerstats.cpp
+++ b/indra/newview/llviewerstats.cpp
@@ -288,13 +288,13 @@ F32		gAveLandCompression = 0.f,
 		gWorstLandCompression = 0.f, 
 		gWorstWaterCompression = 0.f;
 
-LLUnit::Bytes<U32>		gTotalWorldData = 0, 
+LLUnit<LLUnits::Bytes, U32>		gTotalWorldData = 0, 
 						gTotalObjectData = 0, 
 						gTotalTextureData = 0;
 U32						gSimPingCount = 0;
-LLUnit::Bits<U32>		gObjectData = 0;
+LLUnit<LLUnits::Bits, U32>		gObjectData = 0;
 F32						gAvgSimPing = 0.f;
-LLUnit::Bytes<U32>		gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};
+LLUnit<LLUnits::Bytes, U32>		gTotalTextureBytesPerBoostLevel[LLViewerTexture::MAX_GL_IMAGE_CATEGORY] = {0};
 
 extern U32  gVisCompared;
 extern U32  gVisTested;
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index eda7b3329d95447e44d103352b3ec3984ebbf402..14ee41dba0f2afc80787833c353d26b8b6585f9d 100755
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -319,7 +319,7 @@ void update_statistics();
 void send_stats();
 
 extern LLFrameTimer gTextureTimer;
-extern LLUnit::Bytes<U32>	gTotalTextureData;
-extern LLUnit::Bytes<U32>  gTotalObjectData;
-extern LLUnit::Bytes<U32>  gTotalTextureBytesPerBoostLevel[] ;
+extern LLUnit<LLUnits::Bytes, U32>	gTotalTextureData;
+extern LLUnit<LLUnits::Bytes, U32>  gTotalObjectData;
+extern LLUnit<LLUnits::Bytes, U32>  gTotalTextureBytesPerBoostLevel[] ;
 #endif // LL_LLVIEWERSTATS_H
diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp
index ceb8d3155c472ce742b406e70cd86a114a7a36a9..f4e8e3eae10aaca0ee324f42cb6c399ba1131d2f 100644
--- a/indra/newview/llviewertexture.cpp
+++ b/indra/newview/llviewertexture.cpp
@@ -65,8 +65,8 @@
 ///////////////////////////////////////////////////////////////////////////////
 
 // extern
-const LLUnit::Megabytes<S32> gMinVideoRam = 32;
-const LLUnit::Megabytes<S32> gMaxVideoRam = 512;
+const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam = 32;
+const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam = 512;
 
 
 // statics
@@ -87,11 +87,11 @@ S32 LLViewerTexture::sAuxCount = 0;
 LLFrameTimer LLViewerTexture::sEvaluationTimer;
 F32 LLViewerTexture::sDesiredDiscardBias = 0.f;
 F32 LLViewerTexture::sDesiredDiscardScale = 1.1f;
-LLUnit::Bytes<S32> LLViewerTexture::sBoundTextureMemory = 0;
-LLUnit::Bytes<S32> LLViewerTexture::sTotalTextureMemory = 0;
-LLUnit::Megabytes<S32> LLViewerTexture::sMaxBoundTextureMem = 0;
-LLUnit::Megabytes<S32> LLViewerTexture::sMaxTotalTextureMem = 0;
-LLUnit::Bytes<S32> LLViewerTexture::sMaxDesiredTextureMem = 0 ;
+LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sBoundTextureMemory = 0;
+LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sTotalTextureMemory = 0;
+LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxBoundTextureMem = 0;
+LLUnit<LLUnits::Megabytes, S32> LLViewerTexture::sMaxTotalTextureMem = 0;
+LLUnit<LLUnits::Bytes, S32> LLViewerTexture::sMaxDesiredTextureMem = 0 ;
 S8  LLViewerTexture::sCameraMovingDiscardBias = 0 ;
 F32 LLViewerTexture::sCameraMovingBias = 0.0f ;
 S32 LLViewerTexture::sMaxSculptRez = 128 ; //max sculpt image size
@@ -532,8 +532,8 @@ void LLViewerTexture::updateClass(const F32 velocity, const F32 angular_velocity
 	if (sBoundTextureMemory >= sMaxBoundTextureMem ||
 		sTotalTextureMemory >= sMaxTotalTextureMem)
 	{
-		//when texture memory overflows, lower down the threashold to release the textures more aggressively.
-		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit::Bytes<S32>(gMaxVideoRam));
+		//when texture memory overflows, lower down the threshold to release the textures more aggressively.
+		sMaxDesiredTextureMem = llmin(sMaxDesiredTextureMem * 0.75f, LLUnit<LLUnits::Bytes, S32>(gMaxVideoRam));
 	
 		// If we are using more texture memory than we should,
 		// scale up the desired discard level
diff --git a/indra/newview/llviewertexture.h b/indra/newview/llviewertexture.h
index aa1e2010b4085ae8ee6ce4597868da99831fbe81..e9efb751f8de174c9a18209256d7939b364c0441 100755
--- a/indra/newview/llviewertexture.h
+++ b/indra/newview/llviewertexture.h
@@ -39,8 +39,8 @@
 #include <map>
 #include <list>
 
-extern const LLUnit::Megabytes<S32> gMinVideoRam;
-extern const LLUnit::Megabytes<S32> gMaxVideoRam;
+extern const LLUnit<LLUnits::Megabytes, S32> gMinVideoRam;
+extern const LLUnit<LLUnits::Megabytes, S32> gMaxVideoRam;
 
 class LLFace;
 class LLImageGL ;
@@ -323,11 +323,11 @@ class LLViewerTexture : public LLTexture
 	static LLFrameTimer sEvaluationTimer;
 	static F32 sDesiredDiscardBias;
 	static F32 sDesiredDiscardScale;
-	static LLUnit::Bytes<S32> sBoundTextureMemory;
-	static LLUnit::Bytes<S32> sTotalTextureMemory;
-	static LLUnit::Megabytes<S32> sMaxBoundTextureMem;
-	static LLUnit::Megabytes<S32> sMaxTotalTextureMem;
-	static LLUnit::Bytes<S32> sMaxDesiredTextureMem ;
+	static LLUnit<LLUnits::Bytes, S32> sBoundTextureMemory;
+	static LLUnit<LLUnits::Bytes, S32> sTotalTextureMemory;
+	static LLUnit<LLUnits::Megabytes, S32> sMaxBoundTextureMem;
+	static LLUnit<LLUnits::Megabytes, S32> sMaxTotalTextureMem;
+	static LLUnit<LLUnits::Bytes, S32> sMaxDesiredTextureMem ;
 	static S8  sCameraMovingDiscardBias;
 	static F32 sCameraMovingBias;
 	static S32 sMaxSculptRez ;
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index b7415669bb494f3935e98ed2b843b7ead3c78fd8..8e72ca1d74fb4242215310ffc62d6e097cbbaa01 100755
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -733,7 +733,7 @@ class LLDebugText
 			{
 				if(gTotalTextureBytesPerBoostLevel[i] > 0)
 				{
-					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, LLUnit::Megabytes<F32>(gTotalTextureBytesPerBoostLevel[i]).value()));
+					addText(xpos, ypos, llformat("Boost_Level %d:  %.3f MB", i, LLUnit<LLUnits::Megabytes, F32>(gTotalTextureBytesPerBoostLevel[i]).value()));
 					ypos += y_inc;
 				}
 			}