diff --git a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
index 3d27b4a5b548c6e699917e15b6888132e60631e0..f4dba16a944076e5e0cb784573b427323b7738c9 100644
--- a/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
+++ b/indra/integration_tests/llimage_libtest/llimage_libtest.cpp
@@ -42,6 +42,7 @@
 #include "lldiriterator.h"
 #include "v4coloru.h"
 #include "llsdserialize.h"
+#include "llcleanup.h"
 
 // system libraries
 #include <iostream>
@@ -634,7 +635,7 @@ int main(int argc, char** argv)
 	}
 	
 	// Cleanup and exit
-	LLImage::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLImage);
 	if (fast_timer_log_thread)
 	{
 		fast_timer_log_thread->shutdown();
diff --git a/indra/llappearance/llavatarappearancedefines.h b/indra/llappearance/llavatarappearancedefines.h
index 8a1d2c4707e735823e94e17018240c4e8ad2fe9b..d6223bb4d24e732ceb01df1627434fd631dcda5f 100644
--- a/indra/llappearance/llavatarappearancedefines.h
+++ b/indra/llappearance/llavatarappearancedefines.h
@@ -127,8 +127,7 @@ class LLAvatarAppearanceDictionary : public LLSingleton<LLAvatarAppearanceDictio
 	//--------------------------------------------------------------------
 	// Constructors and Destructors
 	//--------------------------------------------------------------------
-public:
-	LLAvatarAppearanceDictionary();
+	LLSINGLETON(LLAvatarAppearanceDictionary);
 	virtual ~LLAvatarAppearanceDictionary();
 private:
 	void createAssociations();
diff --git a/indra/llappearance/lltexlayer.h b/indra/llappearance/lltexlayer.h
index 959d6e499abfb348bf8709e2b4c6b618871a9e3c..9318b23fd199b32841d84a7192748634dcf282e2 100644
--- a/indra/llappearance/lltexlayer.h
+++ b/indra/llappearance/lltexlayer.h
@@ -293,9 +293,9 @@ class LLTexLayerSetBuffer : public virtual LLRefCount
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLTexLayerStaticImageList : public LLSingleton<LLTexLayerStaticImageList>
 {
-public:
-	LLTexLayerStaticImageList();
+	LLSINGLETON(LLTexLayerStaticImageList);
 	~LLTexLayerStaticImageList();
+public:
 	LLGLTexture*		getTexture(const std::string& file_name, BOOL is_mask);
 	LLImageTGA*			getImageTGA(const std::string& file_name);
 	void				deleteCachedImages();
diff --git a/indra/llappearance/llwearabletype.cpp b/indra/llappearance/llwearabletype.cpp
index 87109a5906ec7263b5d1957f4c6bcbe2781fc476..207e0c4011f2e9c9496ea6c34b487d991b92f8a8 100644
--- a/indra/llappearance/llwearabletype.cpp
+++ b/indra/llappearance/llwearabletype.cpp
@@ -71,8 +71,7 @@ struct WearableEntry : public LLDictionaryEntry
 class LLWearableDictionary : public LLSingleton<LLWearableDictionary>,
 							 public LLDictionary<LLWearableType::EType, WearableEntry>
 {
-public:
-	LLWearableDictionary();
+	LLSINGLETON(LLWearableDictionary);
 };
 
 LLWearableDictionary::LLWearableDictionary()
diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt
index 410a5819b3bdc8309db86a19719e6dc6889d1a39..d9ab7c1b38023bce51b2c2991048274f22b99c02 100644
--- a/indra/llcommon/CMakeLists.txt
+++ b/indra/llcommon/CMakeLists.txt
@@ -40,8 +40,10 @@ set(llcommon_SOURCE_FILES
     llbase64.cpp
     llbitpack.cpp
     llcallbacklist.cpp
+    llcleanup.cpp
     llcommon.cpp
     llcommonutils.cpp
+    llcoro_get_id.cpp
     llcoros.cpp
     llcrc.cpp
     llcriticaldamp.cpp
@@ -66,7 +68,9 @@ set(llcommon_SOURCE_FILES
     llformat.cpp
     llframetimer.cpp
     llheartbeat.cpp
+    llheteromap.cpp
     llinitparam.cpp
+    llinitdestroyclass.cpp
     llinstancetracker.cpp
     llleap.cpp
     llleaplistener.cpp
@@ -135,8 +139,10 @@ set(llcommon_HEADER_FILES
     llbitpack.h
     llboost.h
     llcallbacklist.h
+    llcleanup.h
     llcommon.h
     llcommonutils.h
+    llcoro_get_id.h
     llcoros.h
     llcrc.h
     llcriticaldamp.h
@@ -168,7 +174,9 @@ set(llcommon_HEADER_FILES
     llhandle.h
     llhash.h
     llheartbeat.h
+    llheteromap.h
     llindexedvector.h
+    llinitdestroyclass.h
     llinitparam.h
     llinstancetracker.h
     llkeythrottle.h
@@ -185,6 +193,7 @@ set(llcommon_HEADER_FILES
     llmortician.h
     llnametable.h
     llpointer.h
+    llpounceable.h
     llpredicate.h
     llpreprocessor.h
     llpriqueuemap.h
@@ -329,6 +338,8 @@ if (LL_TESTS)
   LL_ADD_INTEGRATION_TEST(llprocess "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llleap "" "${test_libs}")
   LL_ADD_INTEGRATION_TEST(llstreamqueue "" "${test_libs}")
+  LL_ADD_INTEGRATION_TEST(llpounceable "" "${test_libs}")
+  LL_ADD_INTEGRATION_TEST(llheteromap "" "${test_libs}")
 
 ## llexception_test.cpp isn't a regression test, and doesn't need to be run
 ## every build. It's to help a developer make implementation choices about
diff --git a/indra/llcommon/llapp.cpp b/indra/llcommon/llapp.cpp
index eb0699ad4186d1427ad1f37242b586574b51ea71..2c76f2902000e752e203280ed93a96b41d2c6360 100644
--- a/indra/llcommon/llapp.cpp
+++ b/indra/llcommon/llapp.cpp
@@ -48,6 +48,7 @@
 #include "lleventtimer.h"
 #include "google_breakpad/exception_handler.h"
 #include "stringize.h"
+#include "llcleanup.h"
 
 //
 // Signal handling
@@ -177,7 +178,7 @@ LLApp::~LLApp()
 	
 	if(mExceptionHandler != 0) delete mExceptionHandler;
 
-	LLCommon::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLCommon);
 }
 
 // static
diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp
index 5ae2df39945b6b2517fae061c6895a578c0a8b65..4304db36bea26b30380a85184f47cc5f45dbd8f7 100644
--- a/indra/llcommon/llassettype.cpp
+++ b/indra/llcommon/llassettype.cpp
@@ -63,8 +63,7 @@ struct AssetEntry : public LLDictionaryEntry
 class LLAssetDictionary : public LLSingleton<LLAssetDictionary>,
 						  public LLDictionary<LLAssetType::EType, AssetEntry>
 {
-public:
-	LLAssetDictionary();
+	LLSINGLETON(LLAssetDictionary);
 };
 
 LLAssetDictionary::LLAssetDictionary()
diff --git a/indra/llcommon/llcleanup.cpp b/indra/llcommon/llcleanup.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..c5283507bfc0d8831aeeae7b6a0cff8e0946c2ec
--- /dev/null
+++ b/indra/llcommon/llcleanup.cpp
@@ -0,0 +1,29 @@
+/**
+ * @file   llcleanup.cpp
+ * @author Nat Goodspeed
+ * @date   2016-08-30
+ * @brief  Implementation for llcleanup.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llcleanup.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llerror.h"
+#include "llerrorcontrol.h"
+
+void log_subsystem_cleanup(const char* file, int line, const char* function,
+                           const char* classname)
+{
+    LL_INFOS("Cleanup") << LLError::abbreviateFile(file) << "(" << line << "): "
+                        << "calling " << classname << "::cleanupClass() in "
+                        << function << LL_ENDL;
+}
diff --git a/indra/llcommon/llcleanup.h b/indra/llcommon/llcleanup.h
new file mode 100644
index 0000000000000000000000000000000000000000..a319171b5f1891d06969585c9f9a75e02ef7149c
--- /dev/null
+++ b/indra/llcommon/llcleanup.h
@@ -0,0 +1,33 @@
+/**
+ * @file   llcleanup.h
+ * @author Nat Goodspeed
+ * @date   2015-05-20
+ * @brief  Mechanism for cleaning up subsystem resources
+ * 
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Copyright (c) 2015, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLCLEANUP_H)
+#define LL_LLCLEANUP_H
+
+#include <boost/current_function.hpp>
+
+// Instead of directly calling SomeClass::cleanupClass(), use
+// SUBSYSTEM_CLEANUP(SomeClass);
+// This logs the call as well as performing it. That gives us a baseline
+// subsystem shutdown order against which to compare subsequent dynamic
+// shutdown schemes.
+#define SUBSYSTEM_CLEANUP(CLASSNAME)                                    \
+    do {                                                                \
+        log_subsystem_cleanup(__FILE__, __LINE__, BOOST_CURRENT_FUNCTION, #CLASSNAME); \
+        CLASSNAME::cleanupClass();                                      \
+    } while (0)
+// Use ancient do { ... } while (0) macro trick to permit a block of
+// statements with the same syntax as a single statement.
+
+void log_subsystem_cleanup(const char* file, int line, const char* function,
+                           const char* classname);
+
+#endif /* ! defined(LL_LLCLEANUP_H) */
diff --git a/indra/llcommon/llcommon.cpp b/indra/llcommon/llcommon.cpp
index 19642b0982f4680f7ea459580fb28566e86d54f5..439ff4e628e965da33163f1592d9b432eb16f331 100644
--- a/indra/llcommon/llcommon.cpp
+++ b/indra/llcommon/llcommon.cpp
@@ -31,6 +31,7 @@
 #include "llthread.h"
 #include "lltrace.h"
 #include "lltracethreadrecorder.h"
+#include "llcleanup.h"
 
 //static
 BOOL LLCommon::sAprInitialized = FALSE;
@@ -63,11 +64,11 @@ void LLCommon::cleanupClass()
 	sMasterThreadRecorder = NULL;
 	LLTrace::set_master_thread_recorder(NULL);
 	LLThreadSafeRefCount::cleanupThreadSafeRefCount();
-	LLTimer::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLTimer);
 	if (sAprInitialized)
 	{
 		ll_cleanup_apr();
 		sAprInitialized = FALSE;
 	}
-	LLMemory::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLMemory);
 }
diff --git a/indra/llcommon/llcoro_get_id.cpp b/indra/llcommon/llcoro_get_id.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..24ed1fe0c9f3b4e7208126fe0b55d1105b003f49
--- /dev/null
+++ b/indra/llcommon/llcoro_get_id.cpp
@@ -0,0 +1,32 @@
+/**
+ * @file   llcoro_get_id.cpp
+ * @author Nat Goodspeed
+ * @date   2016-09-03
+ * @brief  Implementation for llcoro_get_id.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llcoro_get_id.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llcoros.h"
+
+namespace llcoro
+{
+
+id get_id()
+{
+    // An instance of Current can convert to LLCoros::CoroData*, which can
+    // implicitly convert to void*, which is an llcoro::id.
+    return LLCoros::Current();
+}
+
+} // llcoro
diff --git a/indra/llcommon/llcoro_get_id.h b/indra/llcommon/llcoro_get_id.h
new file mode 100644
index 0000000000000000000000000000000000000000..4c1dca6f191a92a156fc6f0127007133f03b826a
--- /dev/null
+++ b/indra/llcommon/llcoro_get_id.h
@@ -0,0 +1,30 @@
+/**
+ * @file   llcoro_get_id.h
+ * @author Nat Goodspeed
+ * @date   2016-09-03
+ * @brief  Supplement the functionality in llcoro.h.
+ *
+ *         This is broken out as a separate header file to resolve
+ *         circularity: LLCoros isa LLSingleton, yet LLSingleton machinery
+ *         requires llcoro::get_id().
+ *
+ *         Be very suspicious of anyone else #including this header.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLCORO_GET_ID_H)
+#define LL_LLCORO_GET_ID_H
+
+namespace llcoro
+{
+
+/// Get an opaque, distinct token for the running coroutine (or main).
+typedef void* id;
+id get_id();
+
+} // llcoro
+
+#endif /* ! defined(LL_LLCORO_GET_ID_H) */
diff --git a/indra/llcommon/llcoros.cpp b/indra/llcommon/llcoros.cpp
index 8e516d8beb9395429bafb58d6eeb27c7c2a82fa0..3ffce4810a830aa4134510dee2e53d8892fd5279 100644
--- a/indra/llcommon/llcoros.cpp
+++ b/indra/llcommon/llcoros.cpp
@@ -40,32 +40,79 @@
 #include "stringize.h"
 #include "llexception.h"
 
-// do nothing, when we need nothing done
+namespace {
+void no_op() {}
+} // anonymous namespace
+
+// Do nothing, when we need nothing done. This is a static member of LLCoros
+// because CoroData is a private nested class.
 void LLCoros::no_cleanup(CoroData*) {}
 
 // CoroData for the currently-running coroutine. Use a thread_specific_ptr
 // because each thread potentially has its own distinct pool of coroutines.
-// This thread_specific_ptr does NOT own the CoroData object! That's owned by
-// LLCoros::mCoros. It merely identifies it. For this reason we instantiate
-// it with a no-op cleanup function.
-boost::thread_specific_ptr<LLCoros::CoroData>
-LLCoros::sCurrentCoro(LLCoros::no_cleanup);
+LLCoros::Current::Current()
+{
+    // Use a function-static instance so this thread_specific_ptr is
+    // instantiated on demand. Since we happen to know it's consumed by
+    // LLSingleton, this is likely to happen before the runtime has finished
+    // initializing module-static data. For the same reason, we can't package
+    // this pointer in an LLSingleton.
+
+    // This thread_specific_ptr does NOT own the CoroData object! That's owned
+    // by LLCoros::mCoros. It merely identifies it. For this reason we
+    // instantiate it with a no-op cleanup function.
+    static boost::thread_specific_ptr<LLCoros::CoroData> sCurrent(LLCoros::no_cleanup);
+
+    // If this is the first time we're accessing sCurrent for the running
+    // thread, its get() will be NULL. This could be a problem, in that
+    // llcoro::get_id() would return the same (NULL) token value for the "main
+    // coroutine" in every thread, whereas what we really want is a distinct
+    // value for every distinct stack in the process. So if get() is NULL,
+    // give it a heap CoroData: this ensures that llcoro::get_id() will return
+    // distinct values.
+    // This tactic is "leaky": sCurrent explicitly does not destroy any
+    // CoroData to which it points, and we do NOT enter these "main coroutine"
+    // CoroData instances in the LLCoros::mCoros map. They are dummy entries,
+    // and they will leak at process shutdown: one CoroData per thread.
+    if (! sCurrent.get())
+    {
+        // It's tempting to provide a distinct name for each thread's "main
+        // coroutine." But as getName() has always returned the empty string
+        // to mean "not in a coroutine," empty string should suffice here --
+        // and truthfully the additional (thread-safe!) machinery to ensure
+        // uniqueness just doesn't feel worth the trouble.
+        // We use a no-op callable and a minimal stack size because, although
+        // CoroData's constructor in fact initializes its mCoro with a
+        // coroutine with that stack size, no one ever actually enters it by
+        // calling mCoro().
+        sCurrent.reset(new CoroData(0,  // no prev
+                                    "", // not a named coroutine
+                                    no_op,  // no-op callable
+                                    1024)); // stacksize moot
+    }
+
+    mCurrent = &sCurrent;
+}
 
 //static
 LLCoros::CoroData& LLCoros::get_CoroData(const std::string& caller)
 {
-    CoroData* current = sCurrentCoro.get();
-    if (! current)
-    {
-        LL_ERRS("LLCoros") << "Calling " << caller << " from non-coroutine context!" << LL_ENDL;
-    }
+    CoroData* current = Current();
+    // With the dummy CoroData set in LLCoros::Current::Current(), this
+    // pointer should never be NULL.
+    llassert_always(current);
     return *current;
 }
 
 //static
 LLCoros::coro::self& LLCoros::get_self()
 {
-    return *get_CoroData("get_self()").mSelf;
+    CoroData& current = get_CoroData("get_self()");
+    if (! current.mSelf)
+    {
+        LL_ERRS("LLCoros") << "Calling get_self() from non-coroutine context!" << LL_ENDL;
+    }
+    return *current.mSelf;
 }
 
 //static
@@ -80,20 +127,23 @@ bool LLCoros::get_consuming()
     return get_CoroData("get_consuming()").mConsuming;
 }
 
-llcoro::Suspending::Suspending():
-    mSuspended(LLCoros::sCurrentCoro.get())
+llcoro::Suspending::Suspending()
 {
-    // Revert mCurrentCoro to the value it had at the moment we last switched
+    LLCoros::Current current;
+    // Remember currently-running coroutine: we're about to suspend it.
+    mSuspended = current;
+    // Revert Current to the value it had at the moment we last switched
     // into this coroutine.
-    LLCoros::sCurrentCoro.reset(mSuspended->mPrev);
+    current.reset(mSuspended->mPrev);
 }
 
 llcoro::Suspending::~Suspending()
 {
+    LLCoros::Current current;
     // Okay, we're back, update our mPrev
-    mSuspended->mPrev = LLCoros::sCurrentCoro.get();
-    // and reinstate our sCurrentCoro.
-    LLCoros::sCurrentCoro.reset(mSuspended);
+    mSuspended->mPrev = current;
+    // and reinstate our Current.
+    current.reset(mSuspended);
 }
 
 LLCoros::LLCoros():
@@ -213,13 +263,7 @@ bool LLCoros::kill(const std::string& name)
 
 std::string LLCoros::getName() const
 {
-    CoroData* current = sCurrentCoro.get();
-    if (! current)
-    {
-        // not in a coroutine
-        return "";
-    }
-    return current->mName;
+    return Current()->mName;
 }
 
 void LLCoros::setStackSize(S32 stacksize)
@@ -229,8 +273,8 @@ void LLCoros::setStackSize(S32 stacksize)
 }
 
 // Top-level wrapper around caller's coroutine callable. This function accepts
-// the coroutine library's implicit coro::self& parameter and sets sCurrentSelf
-// but does not pass it down to the caller's callable.
+// the coroutine library's implicit coro::self& parameter and saves it, but
+// does not pass it down to the caller's callable.
 void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& callable)
 {
     // capture the 'self' param in CoroData
@@ -254,8 +298,8 @@ void LLCoros::toplevel(coro::self& self, CoroData* data, const callable_t& calla
         CRASH_ON_UNHANDLED_EXCEPTION(STRINGIZE("coroutine " << data->mName));
     }
     // This cleanup isn't perfectly symmetrical with the way we initially set
-    // data->mPrev, but this is our last chance to reset mCurrentCoro.
-    sCurrentCoro.reset(data->mPrev);
+    // data->mPrev, but this is our last chance to reset Current.
+    Current().reset(data->mPrev);
 }
 
 /*****************************************************************************
@@ -278,7 +322,7 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
     mPrev(prev),
     mName(name),
     // Wrap the caller's callable in our toplevel() function so we can manage
-    // sCurrentCoro appropriately at startup and shutdown of each coroutine.
+    // Current appropriately at startup and shutdown of each coroutine.
     mCoro(boost::bind(toplevel, _1, this, callable), stacksize),
     // don't consume events unless specifically directed
     mConsuming(false),
@@ -289,13 +333,13 @@ LLCoros::CoroData::CoroData(CoroData* prev, const std::string& name,
 std::string LLCoros::launch(const std::string& prefix, const callable_t& callable)
 {
     std::string name(generateDistinctName(prefix));
-    // pass the current value of sCurrentCoro as previous context
-    CoroData* newCoro = new CoroData(sCurrentCoro.get(), name,
-                                     callable, mStackSize);
+    Current current;
+    // pass the current value of Current as previous context
+    CoroData* newCoro = new CoroData(current, name, callable, mStackSize);
     // Store it in our pointer map
     mCoros.insert(name, newCoro);
     // also set it as current
-    sCurrentCoro.reset(newCoro);
+    current.reset(newCoro);
     /* Run the coroutine until its first wait, then return here */
     (newCoro->mCoro)(std::nothrow);
     return name;
diff --git a/indra/llcommon/llcoros.h b/indra/llcommon/llcoros.h
index 39316ed0e6eeb1e76558a1d0212d0e8695404511..bbe2d22af4e1b09609ff52ea93dee84002267116 100644
--- a/indra/llcommon/llcoros.h
+++ b/indra/llcommon/llcoros.h
@@ -35,8 +35,10 @@
 #include <boost/ptr_container/ptr_map.hpp>
 #include <boost/function.hpp>
 #include <boost/thread/tss.hpp>
+#include <boost/noncopyable.hpp>
 #include <string>
 #include <stdexcept>
+#include "llcoro_get_id.h"          // for friend declaration
 
 // forward-declare helper class
 namespace llcoro
@@ -83,6 +85,7 @@ class Suspending;
  */
 class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
 {
+    LLSINGLETON(LLCoros);
 public:
     /// Canonical boost::dcoroutines::coroutine signature we use
     typedef boost::dcoroutines::coroutine<void()> coro;
@@ -173,9 +176,8 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     class Future;
 
 private:
-    LLCoros();
-    friend class LLSingleton<LLCoros>;
     friend class llcoro::Suspending;
+    friend llcoro::id llcoro::get_id();
     std::string generateDistinctName(const std::string& prefix) const;
     bool cleanup(const LLSD&);
     struct CoroData;
@@ -222,8 +224,22 @@ class LL_COMMON_API LLCoros: public LLSingleton<LLCoros>
     typedef boost::ptr_map<std::string, CoroData> CoroMap;
     CoroMap mCoros;
 
-    // identify the current coroutine's CoroData
-    static boost::thread_specific_ptr<LLCoros::CoroData> sCurrentCoro;
+    // Identify the current coroutine's CoroData. Use a little helper class so
+    // a caller can either use a temporary instance, or instantiate a named
+    // variable and access it multiple times.
+    class Current
+    {
+    public:
+        Current();
+
+        operator LLCoros::CoroData*() { return get(); }
+        LLCoros::CoroData* operator->() { return get(); }
+        LLCoros::CoroData* get() { return mCurrent->get(); }
+        void reset(LLCoros::CoroData* ptr) { mCurrent->reset(ptr); }
+
+    private:
+        boost::thread_specific_ptr<LLCoros::CoroData>* mCurrent;
+    };
 };
 
 namespace llcoro
@@ -231,7 +247,7 @@ namespace llcoro
 
 /// Instantiate one of these in a block surrounding any leaf point when
 /// control literally switches away from this coroutine.
-class Suspending
+class Suspending: boost::noncopyable
 {
 public:
     Suspending();
diff --git a/indra/llcommon/llerror.cpp b/indra/llcommon/llerror.cpp
index 6a62860c3f1a11da32ed68a878bfae95fac11ee3..229442cec16ad03f8ea893f0b0ff30f472b067b6 100644
--- a/indra/llcommon/llerror.cpp
+++ b/indra/llcommon/llerror.cpp
@@ -238,6 +238,14 @@ namespace {
 namespace
 {
 	std::string className(const std::type_info& type)
+	{
+		return LLError::Log::demangle(type.name());
+	}
+} // anonymous
+
+namespace LLError
+{
+	std::string Log::demangle(const char* mangled)
 	{
 #ifdef __GNUC__
 		// GCC: type_info::name() returns a mangled class name,st demangle
@@ -252,31 +260,34 @@ namespace
 			// but gcc 3.3 libstc++'s implementation of demangling is broken
 			// and fails without.
 			
-		char* name = abi::__cxa_demangle(type.name(),
+		char* name = abi::__cxa_demangle(mangled,
 										abi_name_buf, &abi_name_len, &status);
 			// this call can realloc the abi_name_buf pointer (!)
 
-		return name ? name : type.name();
+		return name ? name : mangled;
 
 #elif LL_WINDOWS
 		// DevStudio: type_info::name() includes the text "class " at the start
 
 		static const std::string class_prefix = "class ";
-
-		std::string name = type.name();
-		std::string::size_type p = name.find(class_prefix);
-		if (p == std::string::npos)
+		std::string name = mangled;
+		if (0 != name.compare(0, class_prefix.length(), class_prefix))
 		{
+			LL_DEBUGS() << "Did not see '" << class_prefix << "' prefix on '"
+					   << name << "'" << LL_ENDL;
 			return name;
 		}
 
-		return name.substr(p + class_prefix.size());
+		return name.substr(class_prefix.length());
 
-#else		
-		return type.name();
+#else
+		return mangled;
 #endif
 	}
+} // LLError
 
+namespace
+{
 	std::string functionName(const std::string& preprocessor_name)
 	{
 #if LL_WINDOWS
@@ -363,9 +374,8 @@ namespace
 
 	class Globals : public LLSingleton<Globals>
 	{
+		LLSINGLETON(Globals);
 	public:
-		Globals();
-
 		std::ostringstream messageStream;
 		bool messageStreamInUse;
 
@@ -438,11 +448,10 @@ namespace LLError
 
 	class Settings : public LLSingleton<Settings>
 	{
+		LLSINGLETON(Settings);
 	public:
-		Settings();
-
 		SettingsConfigPtr getSettingsConfig();
-	
+
 		void reset();
 		SettingsStoragePtr saveAndReset();
 		void restore(SettingsStoragePtr pSettingsStorage);
@@ -450,7 +459,7 @@ namespace LLError
 	private:
 		SettingsConfigPtr mSettingsConfig;
 	};
-	
+
 	SettingsConfig::SettingsConfig()
 		: LLRefCount(),
 		mPrintLocation(false),
@@ -475,8 +484,7 @@ namespace LLError
 		mRecorders.clear();
 	}
 
-	Settings::Settings()
-		: LLSingleton<Settings>(),
+	Settings::Settings():
 		mSettingsConfig(new SettingsConfig())
 	{
 	}
@@ -485,26 +493,31 @@ namespace LLError
 	{
 		return mSettingsConfig;
 	}
-	
+
 	void Settings::reset()
 	{
 		Globals::getInstance()->invalidateCallSites();
 		mSettingsConfig = new SettingsConfig();
 	}
-	
+
 	SettingsStoragePtr Settings::saveAndReset()
 	{
 		SettingsStoragePtr oldSettingsConfig(mSettingsConfig.get());
 		reset();
 		return oldSettingsConfig;
 	}
-	
+
 	void Settings::restore(SettingsStoragePtr pSettingsStorage)
 	{
 		Globals::getInstance()->invalidateCallSites();
 		SettingsConfigPtr newSettingsConfig(dynamic_cast<SettingsConfig *>(pSettingsStorage.get()));
 		mSettingsConfig = newSettingsConfig;
 	}
+
+	bool is_available()
+	{
+		return Settings::instanceExists() && Globals::instanceExists();
+	}
 }
 
 namespace LLError
diff --git a/indra/llcommon/llerror.h b/indra/llcommon/llerror.h
index 7cbe4334b305f046b8daf0bc510be8ac737955b9..ce4d4552df418000bb30c3f998d7555cdcb4264b 100644
--- a/indra/llcommon/llerror.h
+++ b/indra/llcommon/llerror.h
@@ -190,6 +190,7 @@ namespace LLError
 		static std::ostringstream* out();
 		static void flush(std::ostringstream* out, char* message);
 		static void flush(std::ostringstream*, const CallSite&);
+		static std::string demangle(const char* mangled);
 	};
 	
 	struct LL_COMMON_API CallSite
diff --git a/indra/llcommon/llerrorcontrol.h b/indra/llcommon/llerrorcontrol.h
index 56ac52e5de4edfbb8b5a17c8c34abf4bef779823..56e84f71720fb4537f2c985d72d6160b5b2e0989 100644
--- a/indra/llcommon/llerrorcontrol.h
+++ b/indra/llcommon/llerrorcontrol.h
@@ -189,6 +189,11 @@ namespace LLError
 
 	LL_COMMON_API std::string abbreviateFile(const std::string& filePath);
 	LL_COMMON_API int shouldLogCallCount();
+
+	// Check whether Globals exists. This should only be used by LLSingleton
+	// infrastructure to avoid trying to log when our internal LLSingleton is
+	// unavailable -- circularity ensues.
+	LL_COMMON_API bool is_available();
 };
 
 #endif // LL_LLERRORCONTROL_H
diff --git a/indra/llcommon/llevents.h b/indra/llcommon/llevents.h
index a3b9ec02e0d9894ecf06b5e358a21a0a7fc2144f..7cff7dfd4537b99d99c0a83f6753c941375b7000 100644
--- a/indra/llcommon/llevents.h
+++ b/indra/llcommon/llevents.h
@@ -229,7 +229,7 @@ class LLEventPump;
  */
 class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
 {
-    friend class LLSingleton<LLEventPumps>;
+    LLSINGLETON(LLEventPumps);
 public:
     /**
      * Find or create an LLEventPump instance with a specific name. We return
@@ -272,7 +272,6 @@ class LL_COMMON_API LLEventPumps: public LLSingleton<LLEventPumps>
     void unregister(const LLEventPump&);
 
 private:
-    LLEventPumps();
     ~LLEventPumps();
 
 testable:
diff --git a/indra/llcommon/llheteromap.cpp b/indra/llcommon/llheteromap.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..7c19196e0c17607a61c03525eb99093fe6dd6724
--- /dev/null
+++ b/indra/llcommon/llheteromap.cpp
@@ -0,0 +1,32 @@
+/**
+ * @file   llheteromap.cpp
+ * @author Nat Goodspeed
+ * @date   2016-10-12
+ * @brief  Implementation for llheteromap.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llheteromap.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+
+LLHeteroMap::~LLHeteroMap()
+{
+    // For each entry in our map, we must call its deleter, which is the only
+    // record we have of its original type.
+    for (TypeMap::iterator mi(mMap.begin()), me(mMap.end()); mi != me; ++mi)
+    {
+        // mi->second is the std::pair; mi->second.first is the void*;
+        // mi->second.second points to the deleter function
+        (mi->second.second)(mi->second.first);
+        mi->second.first = NULL;
+    }
+}
diff --git a/indra/llcommon/llheteromap.h b/indra/llcommon/llheteromap.h
new file mode 100644
index 0000000000000000000000000000000000000000..9d6f303d08beb261fe4df04db426d5d320397c1c
--- /dev/null
+++ b/indra/llcommon/llheteromap.h
@@ -0,0 +1,95 @@
+/**
+ * @file   llheteromap.h
+ * @author Nat Goodspeed
+ * @date   2016-10-12
+ * @brief  Map capable of storing objects of diverse types, looked up by type.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLHETEROMAP_H)
+#define LL_LLHETEROMAP_H
+
+#include <typeinfo>
+#include <utility>                  // std::pair
+#include <map>
+
+/**
+ * LLHeteroMap addresses an odd requirement. Usually when you want to put
+ * objects of different classes into a runtime collection of any kind, you
+ * derive them all from a common base class and store pointers to that common
+ * base class.
+ *
+ * LLInitParam::BaseBlock uses disturbing raw-pointer arithmetic to find data
+ * members in its subclasses. It seems that no BaseBlock subclass can be
+ * stored in a polymorphic class of any kind: the presence of a vtbl pointer
+ * in the layout silently throws off the reinterpret_cast arithmetic. Bad
+ * Things result. (Many thanks to Nicky D for this analysis!)
+ *
+ * LLHeteroMap collects objects WITHOUT a common base class, retrieves them by
+ * object type and destroys them when the LLHeteroMap is destroyed.
+ */
+class LLHeteroMap
+{
+public:
+    ~LLHeteroMap();
+
+    /// find or create
+    template <class T>
+    T& obtain()
+    {
+        // Look up map entry by typeid(T). We don't simply use mMap[typeid(T)]
+        // because that requires default-constructing T on every lookup. For
+        // some kinds of T, that could be expensive.
+        TypeMap::iterator found = mMap.find(&typeid(T));
+        if (found == mMap.end())
+        {
+            // Didn't find typeid(T). Create an entry. Because we're storing
+            // only a void* in the map, discarding type information, make sure
+            // we capture that type information in our deleter.
+            void* ptr = new T();
+            void (*dlfn)(void*) = &deleter<T>;
+            std::pair<TypeMap::iterator, bool> inserted =
+                mMap.insert(TypeMap::value_type(&typeid(T),
+                    TypeMap::mapped_type(ptr, dlfn)));
+            // Okay, now that we have an entry, claim we found it.
+            found = inserted.first;
+        }
+        // found->second is the std::pair; second.first is the void*
+        // pointer to the object in question. Cast it to correct type and
+        // dereference it.
+        return *(static_cast<T*>(found->second.first));
+    }
+
+private:
+    template <class T>
+    static
+    void deleter(void* p)
+    {
+        delete static_cast<T*>(p);
+    }
+
+    // Comparing two std::type_info* values is tricky, because the standard
+    // does not guarantee that there will be only one type_info instance for a
+    // given type. In other words, &typeid(A) in one part of the program may
+    // not always equal &typeid(A) in some other part. Use special comparator.
+    struct type_info_ptr_comp
+    {
+        bool operator()(const std::type_info* lhs, const std::type_info* rhs)
+        {
+            return lhs->before(*rhs);
+        }
+    };
+
+    // What we actually store is a map from std::type_info (permitting lookup
+    // by object type) to a void* pointer to the object PLUS its deleter.
+    typedef std::map<
+        const std::type_info*, std::pair<void*, void (*)(void*)>,
+        type_info_ptr_comp>
+    TypeMap;
+    TypeMap mMap;
+};
+
+#endif /* ! defined(LL_LLHETEROMAP_H) */
diff --git a/indra/llcommon/llinitdestroyclass.cpp b/indra/llcommon/llinitdestroyclass.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..e6382a79249bf445638ca712a84a5cebeadc2f09
--- /dev/null
+++ b/indra/llcommon/llinitdestroyclass.cpp
@@ -0,0 +1,30 @@
+/**
+ * @file   llinitdestroyclass.cpp
+ * @author Nat Goodspeed
+ * @date   2016-08-30
+ * @brief  Implementation for llinitdestroyclass.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llinitdestroyclass.h"
+// STL headers
+// std headers
+// external library headers
+// other Linden headers
+#include "llerror.h"
+
+void LLCallbackRegistry::fireCallbacks() const
+{
+	for (FuncList::const_iterator fi = mCallbacks.begin(), fe = mCallbacks.end();
+		 fi != fe; ++fi)
+	{
+		LL_INFOS("LLInitDestroyClass") << "calling " << fi->first << "()" << LL_ENDL;
+		fi->second();
+	}
+}
diff --git a/indra/llcommon/llinitdestroyclass.h b/indra/llcommon/llinitdestroyclass.h
new file mode 100644
index 0000000000000000000000000000000000000000..5f979614fe0ee94b4b8036d983a1006ae1d507ee
--- /dev/null
+++ b/indra/llcommon/llinitdestroyclass.h
@@ -0,0 +1,175 @@
+/**
+ * @file   llinitdestroyclass.h
+ * @author Nat Goodspeed
+ * @date   2015-05-27
+ * @brief  LLInitClass / LLDestroyClass mechanism
+ *
+ * The LLInitClass template, extracted from llui.h, ensures that control will
+ * reach a static initClass() method. LLDestroyClass does the same for a
+ * static destroyClass() method.
+ *
+ * The distinguishing characteristics of these templates are:
+ *
+ * - All LLInitClass<T>::initClass() methods are triggered by an explicit call
+ *   to LLInitClassList::instance().fireCallbacks(). Presumably this call
+ *   happens sometime after all static objects in the program have been
+ *   initialized. In other words, each LLInitClass<T>::initClass() method
+ *   should be able to make some assumptions about global program state.
+ *
+ * - Similarly, LLDestroyClass<T>::destroyClass() methods are triggered by
+ *   LLDestroyClassList::instance().fireCallbacks(). Again, presumably this
+ *   happens at a well-defined moment in the program's shutdown sequence.
+ *
+ * - The initClass() calls happen in an unspecified sequence. You may not rely
+ *   on the relative ordering of LLInitClass<T>::initClass() versus another
+ *   LLInitClass<U>::initClass() method. If you need such a guarantee, use
+ *   LLSingleton instead and make the dependency explicit.
+ *
+ * - Similarly, LLDestroyClass<T>::destroyClass() may happen either before or
+ *   after LLDestroyClass<U>::destroyClass(). You cannot rely on that order.
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Copyright (c) 2015, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLINITDESTROYCLASS_H)
+#define LL_LLINITDESTROYCLASS_H
+
+#include "llsingleton.h"
+#include <boost/function.hpp>
+#include <typeinfo>
+#include <vector>
+#include <utility>                  // std::pair
+
+/**
+ * LLCallbackRegistry is an implementation detail base class for
+ * LLInitClassList and LLDestroyClassList. It accumulates the initClass() or
+ * destroyClass() callbacks for registered classes.
+ */
+class LLCallbackRegistry
+{
+public:
+	typedef boost::function<void()> func_t;
+
+	void registerCallback(const std::string& name, const func_t& func)
+	{
+		mCallbacks.push_back(FuncList::value_type(name, func));
+	}
+
+	void fireCallbacks() const;
+
+private:
+	// Arguably this should be a boost::signals2::signal, which is, after all,
+	// a sequence of callables. We manage it by hand so we can log a name for
+	// each registered function we call.
+	typedef std::vector< std::pair<std::string, func_t> > FuncList;
+	FuncList mCallbacks;
+};
+
+/**
+ * LLInitClassList is the LLCallbackRegistry for LLInitClass. It stores the
+ * registered initClass() methods. It must be an LLSingleton because
+ * LLInitClass registers its initClass() method at static construction time
+ * (before main()), requiring LLInitClassList to be fully constructed on
+ * demand regardless of module initialization order.
+ */
+class LLInitClassList : 
+	public LLCallbackRegistry, 
+	public LLSingleton<LLInitClassList>
+{
+	LLSINGLETON_EMPTY_CTOR(LLInitClassList);
+};
+
+/**
+ * LLDestroyClassList is the LLCallbackRegistry for LLDestroyClass. It stores
+ * the registered destroyClass() methods. It must be an LLSingleton because
+ * LLDestroyClass registers its destroyClass() method at static construction
+ * time (before main()), requiring LLDestroyClassList to be fully constructed
+ * on demand regardless of module initialization order.
+ */
+class LLDestroyClassList : 
+	public LLCallbackRegistry, 
+	public LLSingleton<LLDestroyClassList>
+{
+	LLSINGLETON_EMPTY_CTOR(LLDestroyClassList);
+};
+
+/**
+ * LLRegisterWith is an implementation detail for LLInitClass and
+ * LLDestroyClass. It is intended to be used as a static class member whose
+ * constructor registers the specified callback with the LLMumbleClassList
+ * singleton registry specified as the template argument.
+ */
+template<typename T>
+class LLRegisterWith
+{
+public:
+	LLRegisterWith(const std::string& name, const LLCallbackRegistry::func_t& func)
+	{
+		T::instance().registerCallback(name, func);
+	}
+
+	// this avoids a MSVC bug where non-referenced static members are "optimized" away
+	// even if their constructors have side effects
+	S32 reference()
+	{
+		S32 dummy;
+		dummy = 0;
+		return dummy;
+	}
+};
+
+/**
+ * Derive MyClass from LLInitClass<MyClass> (the Curiously Recurring Template
+ * Pattern) to ensure that the static method MyClass::initClass() will be
+ * called (along with all other LLInitClass<T> subclass initClass() methods)
+ * when someone calls LLInitClassList::instance().fireCallbacks(). This gives
+ * the application specific control over the timing of all such
+ * initializations, without having to insert calls for every such class into
+ * generic application code.
+ */
+template<typename T>
+class LLInitClass
+{
+public:
+	LLInitClass() { sRegister.reference(); }
+
+	// When this static member is initialized, the subclass initClass() method
+	// is registered on LLInitClassList. See sRegister definition below.
+	static LLRegisterWith<LLInitClassList> sRegister;
+};
+
+/**
+ * Derive MyClass from LLDestroyClass<MyClass> (the Curiously Recurring
+ * Template Pattern) to ensure that the static method MyClass::destroyClass()
+ * will be called (along with other LLDestroyClass<T> subclass destroyClass()
+ * methods) when someone calls LLDestroyClassList::instance().fireCallbacks().
+ * This gives the application specific control over the timing of all such
+ * cleanup calls, without having to insert calls for every such class into
+ * generic application code.
+ */
+template<typename T>
+class LLDestroyClass
+{
+public:
+	LLDestroyClass() { sRegister.reference(); }
+
+	// When this static member is initialized, the subclass destroyClass()
+	// method is registered on LLInitClassList. See sRegister definition
+	// below.
+	static LLRegisterWith<LLDestroyClassList> sRegister;
+};
+
+// Here's where LLInitClass<T> specifies the subclass initClass() method.
+template <typename T>
+LLRegisterWith<LLInitClassList>
+LLInitClass<T>::sRegister(std::string(typeid(T).name()) + "::initClass",
+						  &T::initClass);
+// Here's where LLDestroyClass<T> specifies the subclass destroyClass() method.
+template <typename T>
+LLRegisterWith<LLDestroyClassList>
+LLDestroyClass<T>::sRegister(std::string(typeid(T).name()) + "::destroyClass",
+							 &T::destroyClass);
+
+#endif /* ! defined(LL_LLINITDESTROYCLASS_H) */
diff --git a/indra/llcommon/llmetricperformancetester.cpp b/indra/llcommon/llmetricperformancetester.cpp
index 1fc821d9a9622c3cb589ff7ec7b85770fea9cbc6..16fc365da1be7ec9d773181bd43611ae6279d90b 100644
--- a/indra/llcommon/llmetricperformancetester.cpp
+++ b/indra/llcommon/llmetricperformancetester.cpp
@@ -40,7 +40,7 @@
 LLMetricPerformanceTesterBasic::name_tester_map_t LLMetricPerformanceTesterBasic::sTesterMap ;
 
 /*static*/ 
-void LLMetricPerformanceTesterBasic::cleanClass() 
+void LLMetricPerformanceTesterBasic::cleanupClass() 
 {
 	for (name_tester_map_t::iterator iter = sTesterMap.begin() ; iter != sTesterMap.end() ; ++iter)
 	{
diff --git a/indra/llcommon/llmetricperformancetester.h b/indra/llcommon/llmetricperformancetester.h
index 1a18cdf36fbf3a55e31f6c7c6cf5bd6a422332ab..e6b46be1cf905f193652bb2458ee8e6e573eb738 100644
--- a/indra/llcommon/llmetricperformancetester.h
+++ b/indra/llcommon/llmetricperformancetester.h
@@ -156,7 +156,7 @@ class LL_COMMON_API LLMetricPerformanceTesterBasic
 	/**
 	 * @brief Delete all testers and reset the tester map
 	 */
-	static void cleanClass() ;
+	static void cleanupClass() ;
 
 private:
 	// Add a tester to the map. Returns false if adding fails.
diff --git a/indra/llcommon/llpounceable.h b/indra/llcommon/llpounceable.h
new file mode 100644
index 0000000000000000000000000000000000000000..0421ce966a7276ece6570a555ab4120d60f1ad86
--- /dev/null
+++ b/indra/llcommon/llpounceable.h
@@ -0,0 +1,216 @@
+/**
+ * @file   llpounceable.h
+ * @author Nat Goodspeed
+ * @date   2015-05-22
+ * @brief  LLPounceable is tangentially related to a future: it's a holder for
+ *         a value that may or may not exist yet. Unlike a future, though,
+ *         LLPounceable freely allows reading the held value. (If the held
+ *         type T does not have a distinguished "empty" value, consider using
+ *         LLPounceable<boost::optional<T>>.)
+ *
+ *         LLPounceable::callWhenReady() is this template's claim to fame. It
+ *         allows its caller to "pounce" on the held value as soon as it
+ *         becomes non-empty. Call callWhenReady() with any C++ callable
+ *         accepting T. If the held value is already non-empty, callWhenReady()
+ *         will immediately call the callable with the held value. If the held
+ *         value is empty, though, callWhenReady() will enqueue the callable
+ *         for later. As soon as LLPounceable is assigned a non-empty held
+ *         value, it will flush the queue of deferred callables.
+ *
+ *         Consider a global LLMessageSystem* gMessageSystem. Message system
+ *         initialization happens at a very specific point during viewer
+ *         initialization. Other subsystems want to register callbacks on the
+ *         LLMessageSystem instance as soon as it's initialized, but their own
+ *         initialization may precede that. If we define gMessageSystem to be
+ *         an LLPounceable<LLMessageSystem*>, a subsystem can use
+ *         callWhenReady() to either register immediately (if gMessageSystem
+ *         is already up and runnning) or register as soon as gMessageSystem
+ *         is set with a new, initialized instance.
+ *
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Copyright (c) 2015, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+#if ! defined(LL_LLPOUNCEABLE_H)
+#define LL_LLPOUNCEABLE_H
+
+#include "llsingleton.h"
+#include <boost/noncopyable.hpp>
+#include <boost/call_traits.hpp>
+#include <boost/type_traits/remove_pointer.hpp>
+#include <boost/utility/value_init.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/signals2/signal.hpp>
+
+// Forward declare the user template, since we want to be able to point to it
+// in some of its implementation classes.
+template <typename T, class TAG>
+class LLPounceable;
+
+template <typename T, typename TAG>
+struct LLPounceableTraits
+{
+    // Our "queue" is a signal object with correct signature.
+    typedef boost::signals2::signal<void (typename boost::call_traits<T>::param_type)> signal_t;
+    // Call callWhenReady() with any callable accepting T.
+    typedef typename signal_t::slot_type func_t;
+    // owner pointer type
+    typedef LLPounceable<T, TAG>* owner_ptr;
+};
+
+// Tag types distinguish the two different implementations of LLPounceable's
+// queue.
+struct LLPounceableQueue {};
+struct LLPounceableStatic {};
+
+// generic LLPounceableQueueImpl deliberately omitted: only the above tags are
+// legal
+template <typename T, class TAG>
+class LLPounceableQueueImpl;
+
+// The implementation selected by LLPounceableStatic uses an LLSingleton
+// because we can't count on a data member queue being initialized at the time
+// we start getting callWhenReady() calls. This is that LLSingleton.
+template <typename T>
+class LLPounceableQueueSingleton:
+    public LLSingleton<LLPounceableQueueSingleton<T> >
+{
+    LLSINGLETON_EMPTY_CTOR(LLPounceableQueueSingleton);
+
+    typedef LLPounceableTraits<T, LLPounceableStatic> traits;
+    typedef typename traits::owner_ptr owner_ptr;
+    typedef typename traits::signal_t signal_t;
+
+    // For a given held type T, every LLPounceable<T, LLPounceableStatic>
+    // instance will call on the SAME LLPounceableQueueSingleton instance --
+    // given how class statics work. We must keep a separate queue for each
+    // LLPounceable instance. Use a hash map for that.
+    typedef boost::unordered_map<owner_ptr, signal_t> map_t;
+
+public:
+    // Disambiguate queues belonging to different LLPounceables.
+    signal_t& get(owner_ptr owner)
+    {
+        // operator[] has find-or-create semantics -- just what we want!
+        return mMap[owner];
+    }
+
+private:
+    map_t mMap;
+};
+
+// LLPounceableQueueImpl that uses the above LLSingleton
+template <typename T>
+class LLPounceableQueueImpl<T, LLPounceableStatic>
+{
+public:
+    typedef LLPounceableTraits<T, LLPounceableStatic> traits;
+    typedef typename traits::owner_ptr owner_ptr;
+    typedef typename traits::signal_t signal_t;
+
+    signal_t& get(owner_ptr owner) const
+    {
+        // this Impl contains nothing; it delegates to the Singleton
+        return LLPounceableQueueSingleton<T>::instance().get(owner);
+    }
+};
+
+// The implementation selected by LLPounceableQueue directly contains the
+// queue of interest, suitable for an LLPounceable we can trust to be fully
+// initialized when it starts getting callWhenReady() calls.
+template <typename T>
+class LLPounceableQueueImpl<T, LLPounceableQueue>
+{
+public:
+    typedef LLPounceableTraits<T, LLPounceableQueue> traits;
+    typedef typename traits::owner_ptr owner_ptr;
+    typedef typename traits::signal_t signal_t;
+
+    signal_t& get(owner_ptr)
+    {
+        return mQueue;
+    }
+
+private:
+    signal_t mQueue;
+};
+
+// LLPounceable<T> is for an LLPounceable instance on the heap or the stack.
+// LLPounceable<T, LLPounceableStatic> is for a static LLPounceable instance.
+template <typename T, class TAG=LLPounceableQueue>
+class LLPounceable: public boost::noncopyable
+{
+private:
+    typedef LLPounceableTraits<T, TAG> traits;
+    typedef typename traits::owner_ptr owner_ptr;
+    typedef typename traits::signal_t signal_t;
+
+public:
+    typedef typename traits::func_t func_t;
+
+    // By default, both the initial value and the distinguished empty value
+    // are a default-constructed T instance. However you can explicitly
+    // specify each.
+    LLPounceable(typename boost::call_traits<T>::value_type init =boost::value_initialized<T>(),
+                 typename boost::call_traits<T>::param_type empty=boost::value_initialized<T>()):
+        mHeld(init),
+        mEmpty(empty)
+    {}
+
+    // make read access to mHeld as cheap and transparent as possible
+    operator T () const { return mHeld; }
+    typename boost::remove_pointer<T>::type operator*() const { return *mHeld; }
+    typename boost::call_traits<T>::value_type operator->() const { return mHeld; }
+    // uncomment 'explicit' as soon as we allow C++11 compilation
+    /*explicit*/ operator bool() const { return bool(mHeld); }
+    bool operator!() const { return ! mHeld; }
+
+    // support both assignment (dumb ptr idiom) and reset() (smart ptr)
+    void operator=(typename boost::call_traits<T>::param_type value)
+    {
+        reset(value);
+    }
+
+    void reset(typename boost::call_traits<T>::param_type value)
+    {
+        mHeld = value;
+        // If this new value is non-empty, flush anything pending in the queue.
+        if (mHeld != mEmpty)
+        {
+            signal_t& signal(get_signal());
+            signal(mHeld);
+            signal.disconnect_all_slots();
+        }
+    }
+
+    // our claim to fame
+    void callWhenReady(const func_t& func)
+    {
+        if (mHeld != mEmpty)
+        {
+            // If the held value is already non-empty, immediately call func()
+            func(mHeld);
+        }
+        else
+        {
+            // Held value still empty, queue func() for later. By default,
+            // connect() enqueues slots in FIFO order.
+            get_signal().connect(func);
+        }
+    }
+
+private:
+    signal_t& get_signal() { return mQueue.get(this); }
+
+    // Store both the current and the empty value.
+    // MAYBE: Might be useful to delegate to LLPounceableTraits the meaning of
+    // testing for "empty." For some types we want operator!(); for others we
+    // want to compare to a distinguished value.
+    typename boost::call_traits<T>::value_type mHeld, mEmpty;
+    // This might either contain the queue (LLPounceableQueue) or delegate to
+    // an LLSingleton (LLPounceableStatic).
+    LLPounceableQueueImpl<T, TAG> mQueue;
+};
+
+#endif /* ! defined(LL_LLPOUNCEABLE_H) */
diff --git a/indra/llcommon/llregistry.h b/indra/llcommon/llregistry.h
index 29950c108dbe104a54f5eb42e41583e25cb8787e..750fe9fdc8a0d3193e99cbcbf1c257d624324f77 100644
--- a/indra/llcommon/llregistry.h
+++ b/indra/llcommon/llregistry.h
@@ -247,7 +247,10 @@ class LLRegistrySingleton
 	:	public LLRegistry<KEY, VALUE, COMPARATOR>,
 		public LLSingleton<DERIVED_TYPE>
 {
-	friend class LLSingleton<DERIVED_TYPE>;
+	// This LLRegistrySingleton doesn't use LLSINGLETON(LLRegistrySingleton)
+	// because the concrete class is actually DERIVED_TYPE, not
+	// LLRegistrySingleton. So each concrete subclass needs
+	// LLSINGLETON(whatever) -- not this intermediate base class.
 public:
 	typedef LLRegistry<KEY, VALUE, COMPARATOR>		registry_t;
 	typedef const KEY&								ref_const_key_t;
@@ -269,7 +272,7 @@ class LLRegistrySingleton
 
 		~ScopedRegistrar()
 		{
-			if (!singleton_t::destroyed())
+			if (singleton_t::instanceExists())
 			{
 				popScope();
 			}
diff --git a/indra/llcommon/llsingleton.cpp b/indra/llcommon/llsingleton.cpp
index 9b49e5237717234ae6ba2179ff053e3a39cf8934..9025e53bb27a2d42d908f957a82242039e1cd170 100644
--- a/indra/llcommon/llsingleton.cpp
+++ b/indra/llcommon/llsingleton.cpp
@@ -25,7 +25,445 @@
  */
 
 #include "linden_common.h"
-
 #include "llsingleton.h"
 
+#include "llerror.h"
+#include "llerrorcontrol.h"         // LLError::is_available()
+#include "lldependencies.h"
+#include "llcoro_get_id.h"
+#include <boost/foreach.hpp>
+#include <boost/unordered_map.hpp>
+#include <algorithm>
+#include <iostream>                 // std::cerr in dire emergency
+#include <sstream>
+#include <stdexcept>
+
+namespace {
+void log(LLError::ELevel level,
+         const char* p1, const char* p2, const char* p3, const char* p4);
+
+void logdebugs(const char* p1="", const char* p2="", const char* p3="", const char* p4="");
+
+bool oktolog();
+} // anonymous namespace
+
+// Our master list of all LLSingletons is itself an LLSingleton. We used to
+// store it in a function-local static, but that could get destroyed before
+// the last of the LLSingletons -- and ~LLSingletonBase() definitely wants to
+// remove itself from the master list. Since the whole point of this master
+// list is to help track inter-LLSingleton dependencies, and since we have
+// this implicit dependency from every LLSingleton to the master list, make it
+// an LLSingleton.
+class LLSingletonBase::MasterList:
+    public LLSingleton<LLSingletonBase::MasterList>
+{
+    LLSINGLETON_EMPTY_CTOR(MasterList);
+
+public:
+    // No need to make this private with accessors; nobody outside this source
+    // file can see it.
+
+    // This is the master list of all instantiated LLSingletons (save the
+    // MasterList itself) in arbitrary order. You MUST call dep_sort() before
+    // traversing this list.
+    LLSingletonBase::list_t mMaster;
+
+    // We need to maintain a stack of LLSingletons currently being
+    // initialized, either in the constructor or in initSingleton(). However,
+    // managing that as a stack depends on having a DISTINCT 'initializing'
+    // stack for every C++ stack in the process! And we have a distinct C++
+    // stack for every running coroutine. It would be interesting and cool to
+    // implement a generic coroutine-local-storage mechanism and use that
+    // here. The trouble is that LLCoros is itself an LLSingleton, so
+    // depending on LLCoros functionality could dig us into infinite
+    // recursion. (Moreover, when we reimplement LLCoros on top of
+    // Boost.Fiber, that library already provides fiber_specific_ptr -- so
+    // it's not worth a great deal of time and energy implementing a generic
+    // equivalent on top of boost::dcoroutine, which is on its way out.)
+    // Instead, use a map of llcoro::id to select the appropriate
+    // coro-specific 'initializing' stack. llcoro::get_id() is carefully
+    // implemented to avoid requiring LLCoros.
+    typedef boost::unordered_map<llcoro::id, LLSingletonBase::list_t> InitializingMap;
+    InitializingMap mInitializing;
+
+    // non-static method, cf. LLSingletonBase::get_initializing()
+    list_t& get_initializing_()
+    {
+        // map::operator[] has find-or-create semantics, exactly what we need
+        // here. It returns a reference to the selected mapped_type instance.
+        return mInitializing[llcoro::get_id()];
+    }
+
+    void cleanup_initializing_()
+    {
+        InitializingMap::iterator found = mInitializing.find(llcoro::get_id());
+        if (found != mInitializing.end())
+        {
+            mInitializing.erase(found);
+        }
+    }
+};
+
+//static
+LLSingletonBase::list_t& LLSingletonBase::get_master()
+{
+    return LLSingletonBase::MasterList::instance().mMaster;
+}
+
+void LLSingletonBase::add_master()
+{
+    // As each new LLSingleton is constructed, add to the master list.
+    get_master().push_back(this);
+}
+
+void LLSingletonBase::remove_master()
+{
+    // When an LLSingleton is destroyed, remove from master list.
+    // add_master() used to capture the iterator to the newly-added list item
+    // so we could directly erase() it from the master list. Unfortunately
+    // that runs afoul of destruction-dependency order problems. So search the
+    // master list, and remove this item IF FOUND. We have few enough
+    // LLSingletons, and they are so rarely destroyed (once per run), that the
+    // cost of a linear search should not be an issue.
+    get_master().remove(this);
+}
+
+//static
+LLSingletonBase::list_t& LLSingletonBase::get_initializing()
+{
+    return LLSingletonBase::MasterList::instance().get_initializing_();
+}
+
+//static
+LLSingletonBase::list_t& LLSingletonBase::get_initializing_from(MasterList* master)
+{
+    return master->get_initializing_();
+}
+
+LLSingletonBase::~LLSingletonBase() {}
+
+void LLSingletonBase::push_initializing(const char* name)
+{
+    // log BEFORE pushing so logging singletons don't cry circularity
+    log_initializing("Pushing", name);
+    get_initializing().push_back(this);
+}
+
+void LLSingletonBase::pop_initializing()
+{
+    list_t& list(get_initializing());
+
+    if (list.empty())
+    {
+        logerrs("Underflow in stack of currently-initializing LLSingletons at ",
+                demangle(typeid(*this).name()).c_str(), "::getInstance()");
+    }
+
+    // Now we know list.back() exists: capture it
+    LLSingletonBase* back(list.back());
+    // and pop it
+    list.pop_back();
+
+    // The viewer launches an open-ended number of coroutines. While we don't
+    // expect most of them to initialize LLSingleton instances, our present
+    // get_initializing() logic could lead to an open-ended number of map
+    // entries. So every time we pop the stack back to empty, delete the entry
+    // entirely.
+    if (list.empty())
+    {
+        MasterList::instance().cleanup_initializing_();
+    }
+
+    // Now validate the newly-popped LLSingleton.
+    if (back != this)
+    {
+        logerrs("Push/pop mismatch in stack of currently-initializing LLSingletons: ",
+                demangle(typeid(*this).name()).c_str(), "::getInstance() trying to pop ",
+                demangle(typeid(*back).name()).c_str());
+    }
+
+    // log AFTER popping so logging singletons don't cry circularity
+    log_initializing("Popping", typeid(*back).name());
+}
+
+//static
+void LLSingletonBase::log_initializing(const char* verb, const char* name)
+{
+    if (oktolog())
+    {
+        LL_DEBUGS("LLSingleton") << verb << ' ' << demangle(name) << ';';
+        list_t& list(get_initializing());
+        for (list_t::const_reverse_iterator ri(list.rbegin()), rend(list.rend());
+             ri != rend; ++ri)
+        {
+            LLSingletonBase* sb(*ri);
+            LL_CONT << ' ' << demangle(typeid(*sb).name());
+        }
+        LL_ENDL;
+    }
+}
+
+void LLSingletonBase::capture_dependency(list_t& initializing, EInitState initState)
+{
+    // Did this getInstance() call come from another LLSingleton, or from
+    // vanilla application code? Note that although this is a nontrivial
+    // method, the vast majority of its calls arrive here with initializing
+    // empty().
+    if (! initializing.empty())
+    {
+        // getInstance() is being called by some other LLSingleton. But -- is
+        // this a circularity? That is, does 'this' already appear in the
+        // initializing stack?
+        // For what it's worth, normally 'initializing' should contain very
+        // few elements.
+        list_t::const_iterator found =
+            std::find(initializing.begin(), initializing.end(), this);
+        if (found != initializing.end())
+        {
+            // Report the circularity. Requiring the coder to dig through the
+            // logic to diagnose exactly how we got here is less than helpful.
+            std::ostringstream out;
+            for ( ; found != initializing.end(); ++found)
+            {
+                // 'found' is an iterator; *found is an LLSingletonBase*; **found
+                // is the actual LLSingletonBase instance.
+                LLSingletonBase* foundp(*found);
+                out << demangle(typeid(*foundp).name()) << " -> ";
+            }
+            // We promise to capture dependencies from both the constructor
+            // and the initSingleton() method, so an LLSingleton's instance
+            // pointer is on the initializing list during both. Now that we've
+            // detected circularity, though, we must distinguish the two. If
+            // the recursive call is from the constructor, we CAN'T honor it:
+            // otherwise we'd be returning a pointer to a partially-
+            // constructed object! But from initSingleton() is okay: that
+            // method exists specifically to support circularity.
+            // Decide which log helper to call based on initState. They have
+            // identical signatures.
+            ((initState == CONSTRUCTING)? logerrs : logwarns)
+                ("LLSingleton circularity: ", out.str().c_str(),
+                 demangle(typeid(*this).name()).c_str(), "");
+        }
+        else
+        {
+            // Here 'this' is NOT already in the 'initializing' stack. Great!
+            // Record the dependency.
+            // initializing.back() is the LLSingletonBase* currently being
+            // initialized. Store 'this' in its mDepends set.
+            LLSingletonBase* current(initializing.back());
+            if (current->mDepends.insert(this).second)
+            {
+                // only log the FIRST time we hit this dependency!
+                logdebugs(demangle(typeid(*current).name()).c_str(),
+                          " depends on ", demangle(typeid(*this).name()).c_str());
+            }
+        }
+    }
+}
+
+//static
+LLSingletonBase::vec_t LLSingletonBase::dep_sort()
+{
+    // While it would theoretically be possible to maintain a static
+    // SingletonDeps through the life of the program, dynamically adding and
+    // removing LLSingletons as they are created and destroyed, in practice
+    // it's less messy to construct it on demand. The overhead of doing so
+    // should happen basically twice: once for cleanupAll(), once for
+    // deleteAll().
+    typedef LLDependencies<LLSingletonBase*> SingletonDeps;
+    SingletonDeps sdeps;
+    list_t& master(get_master());
+    BOOST_FOREACH(LLSingletonBase* sp, master)
+    {
+        // Build the SingletonDeps structure by adding, for each
+        // LLSingletonBase* sp in the master list, sp itself. It has no
+        // associated value type in our SingletonDeps, hence the 0. We don't
+        // record the LLSingletons it must follow; rather, we record the ones
+        // it must precede. Copy its mDepends to a KeyList to express that.
+        sdeps.add(sp, 0,
+                  SingletonDeps::KeyList(),
+                  SingletonDeps::KeyList(sp->mDepends.begin(), sp->mDepends.end()));
+    }
+    vec_t ret;
+    ret.reserve(master.size());
+    // We should be able to effect this with a transform_iterator that
+    // extracts just the first (key) element from each sorted_iterator, then
+    // uses vec_t's range constructor... but frankly this is more
+    // straightforward, as long as we remember the above reserve() call!
+    BOOST_FOREACH(SingletonDeps::sorted_iterator::value_type pair, sdeps.sort())
+    {
+        ret.push_back(pair.first);
+    }
+    // The master list is not itself pushed onto the master list. Add it as
+    // the very last entry -- it is the LLSingleton on which ALL others
+    // depend! -- so our caller will process it.
+    ret.push_back(MasterList::getInstance());
+    return ret;
+}
+
+//static
+void LLSingletonBase::cleanupAll()
+{
+    // It's essential to traverse these in dependency order.
+    BOOST_FOREACH(LLSingletonBase* sp, dep_sort())
+    {
+        // Call cleanupSingleton() only if we haven't already done so for this
+        // instance.
+        if (! sp->mCleaned)
+        {
+            sp->mCleaned = true;
+
+            logdebugs("calling ",
+                      demangle(typeid(*sp).name()).c_str(), "::cleanupSingleton()");
+            try
+            {
+                sp->cleanupSingleton();
+            }
+            catch (const std::exception& e)
+            {
+                logwarns("Exception in ", demangle(typeid(*sp).name()).c_str(),
+                         "::cleanupSingleton(): ", e.what());
+            }
+            catch (...)
+            {
+                logwarns("Unknown exception in ", demangle(typeid(*sp).name()).c_str(),
+                         "::cleanupSingleton()");
+            }
+        }
+    }
+}
+
+//static
+void LLSingletonBase::deleteAll()
+{
+    // It's essential to traverse these in dependency order.
+    BOOST_FOREACH(LLSingletonBase* sp, dep_sort())
+    {
+        // Capture the class name first: in case of exception, don't count on
+        // being able to extract it later.
+        const std::string name = demangle(typeid(*sp).name());
+        try
+        {
+            // Call static method through instance function pointer.
+            if (! sp->mDeleteSingleton)
+            {
+                // This Should Not Happen... but carry on.
+                logwarns(name.c_str(), "::mDeleteSingleton not initialized!");
+            }
+            else
+            {
+                // properly initialized: call it.
+                logdebugs("calling ", name.c_str(), "::deleteSingleton()");
+                // From this point on, DO NOT DEREFERENCE sp!
+                sp->mDeleteSingleton();
+            }
+        }
+        catch (const std::exception& e)
+        {
+            logwarns("Exception in ", name.c_str(), "::deleteSingleton(): ", e.what());
+        }
+        catch (...)
+        {
+            logwarns("Unknown exception in ", name.c_str(), "::deleteSingleton()");
+        }
+    }
+}
+
+/*------------------------ Final cleanup management ------------------------*/
+class LLSingletonBase::MasterRefcount
+{
+public:
+    // store a POD int so it will be statically initialized to 0
+    int refcount;
+};
+static LLSingletonBase::MasterRefcount sMasterRefcount;
+
+LLSingletonBase::ref_ptr_t LLSingletonBase::get_master_refcount()
+{
+    // Calling this method constructs a new ref_ptr_t, which implicitly calls
+    // intrusive_ptr_add_ref(MasterRefcount*).
+    return &sMasterRefcount;
+}
+
+void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount* mrc)
+{
+    // Count outstanding SingletonLifetimeManager instances.
+    ++mrc->refcount;
+}
+
+void intrusive_ptr_release(LLSingletonBase::MasterRefcount* mrc)
+{
+    // Notice when each SingletonLifetimeManager instance is destroyed.
+    if (! --mrc->refcount)
+    {
+        // The last instance was destroyed. Time to kill any remaining
+        // LLSingletons -- but in dependency order.
+        LLSingletonBase::deleteAll();
+    }
+}
+
+/*---------------------------- Logging helpers -----------------------------*/
+namespace {
+bool oktolog()
+{
+    // See comments in log() below.
+    return sMasterRefcount.refcount && LLError::is_available();
+}
+
+void log(LLError::ELevel level,
+         const char* p1, const char* p2, const char* p3, const char* p4)
+{
+    // Check whether we're in the implicit final LLSingletonBase::deleteAll()
+    // call. We've carefully arranged for deleteAll() to be called when the
+    // last SingletonLifetimeManager instance is destroyed -- in other words,
+    // when the last translation unit containing an LLSingleton instance
+    // cleans up static data. That could happen after std::cerr is destroyed!
+    // The is_available() test below ensures that we'll stop logging once
+    // LLError has been cleaned up. If we had a similar portable test for
+    // std::cerr, this would be a good place to use it. As we do not, just
+    // don't log anything during implicit final deleteAll(). Detect that by
+    // the master refcount having gone to zero.
+    if (sMasterRefcount.refcount == 0)
+        return;
+
+    // Check LLError::is_available() because some of LLError's infrastructure
+    // is itself an LLSingleton. If that LLSingleton has not yet been
+    // initialized, trying to log will engage LLSingleton machinery... and
+    // around and around we go.
+    if (LLError::is_available())
+    {
+        LL_VLOGS(level, "LLSingleton") << p1 << p2 << p3 << p4 << LL_ENDL;
+    }
+    else
+    {
+        // Caller may be a test program, or something else whose stderr is
+        // visible to the user.
+        std::cerr << p1 << p2 << p3 << p4 << std::endl;
+    }
+}
+
+void logdebugs(const char* p1, const char* p2, const char* p3, const char* p4)
+{
+    log(LLError::LEVEL_DEBUG, p1, p2, p3, p4);
+}
+} // anonymous namespace        
+
+//static
+void LLSingletonBase::logwarns(const char* p1, const char* p2, const char* p3, const char* p4)
+{
+    log(LLError::LEVEL_WARN, p1, p2, p3, p4);
+}
+
+//static
+void LLSingletonBase::logerrs(const char* p1, const char* p2, const char* p3, const char* p4)
+{
+    log(LLError::LEVEL_ERROR, p1, p2, p3, p4);
+    // The other important side effect of LL_ERRS() is
+    // https://www.youtube.com/watch?v=OMG7paGJqhQ (emphasis on OMG)
+    LLError::crashAndLoop(std::string());
+}
 
+std::string LLSingletonBase::demangle(const char* mangled)
+{
+    return LLError::Log::demangle(mangled);
+}
diff --git a/indra/llcommon/llsingleton.h b/indra/llcommon/llsingleton.h
index 6e6291a1653c97ac014a4913b937747898697542..1b915dfd6e96d927fd520ba58415c52387295049 100644
--- a/indra/llcommon/llsingleton.h
+++ b/indra/llcommon/llsingleton.h
@@ -25,188 +25,495 @@
 #ifndef LLSINGLETON_H
 #define LLSINGLETON_H
 
-#include "llerror.h"	// *TODO: eliminate this
-
-#include <typeinfo>
 #include <boost/noncopyable.hpp>
+#include <boost/unordered_set.hpp>
+#include <boost/intrusive_ptr.hpp>
+#include <list>
+#include <vector>
+#include <typeinfo>
+
+class LLSingletonBase: private boost::noncopyable
+{
+public:
+    class MasterList;
+    class MasterRefcount;
+    typedef boost::intrusive_ptr<MasterRefcount> ref_ptr_t;
+
+private:
+    // All existing LLSingleton instances are tracked in this master list.
+    typedef std::list<LLSingletonBase*> list_t;
+    static list_t& get_master();
+    // This, on the other hand, is a stack whose top indicates the LLSingleton
+    // currently being initialized.
+    static list_t& get_initializing();
+    static list_t& get_initializing_from(MasterList*);
+    // Produce a vector<LLSingletonBase*> of master list, in dependency order.
+    typedef std::vector<LLSingletonBase*> vec_t;
+    static vec_t dep_sort();
+
+    bool mCleaned;                  // cleanupSingleton() has been called
+    // we directly depend on these other LLSingletons
+    typedef boost::unordered_set<LLSingletonBase*> set_t;
+    set_t mDepends;
+
+protected:
+    typedef enum e_init_state
+    {
+        UNINITIALIZED = 0,          // must be default-initialized state
+        CONSTRUCTING,
+        INITIALIZING,
+        INITIALIZED,
+        DELETED
+    } EInitState;
+
+    // Define tag<T> to pass to our template constructor. You can't explicitly
+    // invoke a template constructor with ordinary template syntax:
+    // http://stackoverflow.com/a/3960925/5533635
+    template <typename T>
+    struct tag
+    {
+        typedef T type;
+    };
+
+    // Base-class constructor should only be invoked by the DERIVED_TYPE
+    // constructor, which passes tag<DERIVED_TYPE> for various purposes.
+    template <typename DERIVED_TYPE>
+    LLSingletonBase(tag<DERIVED_TYPE>);
+    virtual ~LLSingletonBase();
+
+    // Every new LLSingleton should be added to/removed from the master list
+    void add_master();
+    void remove_master();
+    // with a little help from our friends.
+    template <class T> friend struct LLSingleton_manage_master;
+
+    // Maintain a stack of the LLSingleton subclass instance currently being
+    // initialized. We use this to notice direct dependencies: we want to know
+    // if A requires B. We deduce a dependency if while initializing A,
+    // control reaches B::getInstance().
+    // We want &A to be at the top of that stack during both A::A() and
+    // A::initSingleton(), since a call to B::getInstance() might occur during
+    // either.
+    // Unfortunately the desired timespan does not correspond neatly with a
+    // single C++ scope, else we'd use RAII to track it. But we do know that
+    // LLSingletonBase's constructor definitely runs just before
+    // LLSingleton's, which runs just before the specific subclass's.
+    void push_initializing(const char*);
+    // LLSingleton is, and must remain, the only caller to initSingleton().
+    // That being the case, we control exactly when it happens -- and we can
+    // pop the stack immediately thereafter.
+    void pop_initializing();
+private:
+    // logging
+    static void log_initializing(const char* verb, const char* name);
+protected:
+    // If a given call to B::getInstance() happens during either A::A() or
+    // A::initSingleton(), record that A directly depends on B.
+    void capture_dependency(list_t& initializing, EInitState);
+
+    // delegate LL_ERRS() logging to llsingleton.cpp
+    static void logerrs(const char* p1, const char* p2="",
+                        const char* p3="", const char* p4="");
+    // delegate LL_WARNS() logging to llsingleton.cpp
+    static void logwarns(const char* p1, const char* p2="",
+                         const char* p3="", const char* p4="");
+    static std::string demangle(const char* mangled);
+
+    // obtain canonical ref_ptr_t
+    static ref_ptr_t get_master_refcount();
+
+    // Default methods in case subclass doesn't declare them.
+    virtual void initSingleton() {}
+    virtual void cleanupSingleton() {}
+
+    // deleteSingleton() isn't -- and shouldn't be -- a virtual method. It's a
+    // class static. However, given only Foo*, deleteAll() does need to be
+    // able to reach Foo::deleteSingleton(). Make LLSingleton (which declares
+    // deleteSingleton()) store a pointer here. Since we know it's a static
+    // class method, a classic-C function pointer will do.
+    void (*mDeleteSingleton)();
+
+public:
+    /**
+     * Call this to call the cleanupSingleton() method for every LLSingleton
+     * constructed since the start of the last cleanupAll() call. (Any
+     * LLSingleton constructed DURING a cleanupAll() call won't be cleaned up
+     * until the next cleanupAll() call.) cleanupSingleton() neither deletes
+     * nor destroys its LLSingleton; therefore it's safe to include logic that
+     * might take significant realtime or even throw an exception.
+     *
+     * The most important property of cleanupAll() is that cleanupSingleton()
+     * methods are called in dependency order, leaf classes last. Thus, given
+     * two LLSingleton subclasses A and B, if A's dependency on B is properly
+     * expressed as a B::getInstance() or B::instance() call during either
+     * A::A() or A::initSingleton(), B will be cleaned up after A.
+     *
+     * If a cleanupSingleton() method throws an exception, the exception is
+     * logged, but cleanupAll() attempts to continue calling the rest of the
+     * cleanupSingleton() methods.
+     */
+    static void cleanupAll();
+    /**
+     * Call this to call the deleteSingleton() method for every LLSingleton
+     * constructed since the start of the last deleteAll() call. (Any
+     * LLSingleton constructed DURING a deleteAll() call won't be cleaned up
+     * until the next deleteAll() call.) deleteSingleton() deletes and
+     * destroys its LLSingleton. Any cleanup logic that might take significant
+     * realtime -- or throw an exception -- must not be placed in your
+     * LLSingleton's destructor, but rather in its cleanupSingleton() method.
+     *
+     * The most important property of deleteAll() is that deleteSingleton()
+     * methods are called in dependency order, leaf classes last. Thus, given
+     * two LLSingleton subclasses A and B, if A's dependency on B is properly
+     * expressed as a B::getInstance() or B::instance() call during either
+     * A::A() or A::initSingleton(), B will be cleaned up after A.
+     *
+     * If a deleteSingleton() method throws an exception, the exception is
+     * logged, but deleteAll() attempts to continue calling the rest of the
+     * deleteSingleton() methods.
+     */
+    static void deleteAll();
+};
+
+// support ref_ptr_t
+void intrusive_ptr_add_ref(LLSingletonBase::MasterRefcount*);
+void intrusive_ptr_release(LLSingletonBase::MasterRefcount*);
 
-// LLSingleton implements the getInstance() method part of the Singleton
-// pattern. It can't make the derived class constructors protected, though, so
-// you have to do that yourself.
-//
-// There are two ways to use LLSingleton. The first way is to inherit from it
-// while using the typename that you'd like to be static as the template
-// parameter, like so:
-//
-//   class Foo: public LLSingleton<Foo>{};
-//
-//   Foo& instance = Foo::instance();
-//
-// The second way is to use the singleton class directly, without inheritance:
-//
-//   typedef LLSingleton<Foo> FooSingleton;
-//
-//   Foo& instance = FooSingleton::instance();
-//
-// In this case, the class being managed as a singleton needs to provide an
-// initSingleton() method since the LLSingleton virtual method won't be
-// available
-//
-// As currently written, it is not thread-safe.
+// Most of the time, we want LLSingleton_manage_master() to forward its
+// methods to real LLSingletonBase methods.
+template <class T>
+struct LLSingleton_manage_master
+{
+    void add(LLSingletonBase* sb) { sb->add_master(); }
+    void remove(LLSingletonBase* sb) { sb->remove_master(); }
+    void push_initializing(LLSingletonBase* sb) { sb->push_initializing(typeid(T).name()); }
+    void pop_initializing (LLSingletonBase* sb) { sb->pop_initializing(); }
+    LLSingletonBase::list_t& get_initializing(T*) { return LLSingletonBase::get_initializing(); }
+};
 
+// But for the specific case of LLSingletonBase::MasterList, don't.
+template <>
+struct LLSingleton_manage_master<LLSingletonBase::MasterList>
+{
+    void add(LLSingletonBase*) {}
+    void remove(LLSingletonBase*) {}
+    void push_initializing(LLSingletonBase*) {}
+    void pop_initializing (LLSingletonBase*) {}
+    LLSingletonBase::list_t& get_initializing(LLSingletonBase::MasterList* instance)
+    {
+        return LLSingletonBase::get_initializing_from(instance);
+    }
+};
+
+// Now we can implement LLSingletonBase's template constructor.
 template <typename DERIVED_TYPE>
-class LLSingleton : private boost::noncopyable
+LLSingletonBase::LLSingletonBase(tag<DERIVED_TYPE>):
+    mCleaned(false),
+    mDeleteSingleton(NULL)
+{
+    // Make this the currently-initializing LLSingleton.
+    LLSingleton_manage_master<DERIVED_TYPE>().push_initializing(this);
+}
+
+/**
+ * LLSingleton implements the getInstance() method part of the Singleton
+ * pattern. It can't make the derived class constructors protected, though, so
+ * you have to do that yourself.
+ *
+ * Derive your class from LLSingleton, passing your subclass name as
+ * LLSingleton's template parameter, like so:
+ *
+ *   class Foo: public LLSingleton<Foo>
+ *   {
+ *       // use this macro at start of every LLSingleton subclass
+ *       LLSINGLETON(Foo);
+ *   public:
+ *       // ...
+ *   };
+ *
+ *   Foo& instance = Foo::instance();
+ *
+ * LLSingleton recognizes a couple special methods in your derived class.
+ *
+ * If you override LLSingleton<T>::initSingleton(), your method will be called
+ * immediately after the instance is constructed. This is useful for breaking
+ * circular dependencies: if you find that your LLSingleton subclass
+ * constructor references other LLSingleton subclass instances in a chain
+ * leading back to yours, move the instance reference from your constructor to
+ * your initSingleton() method.
+ *
+ * If you override LLSingleton<T>::cleanupSingleton(), your method will be
+ * called if someone calls LLSingletonBase::cleanupAll(). The significant part
+ * of this promise is that cleanupAll() will call individual
+ * cleanupSingleton() methods in reverse dependency order.
+ *
+ * That is, consider LLSingleton subclasses C, B and A. A depends on B, which
+ * in turn depends on C. These dependencies are expressed as calls to
+ * B::instance() or B::getInstance(), and C::instance() or C::getInstance().
+ * It shouldn't matter whether these calls appear in A::A() or
+ * A::initSingleton(), likewise B::B() or B::initSingleton().
+ *
+ * We promise that if you later call LLSingletonBase::cleanupAll():
+ * 1. A::cleanupSingleton() will be called before
+ * 2. B::cleanupSingleton(), which will be called before
+ * 3. C::cleanupSingleton().
+ * Put differently, if your LLSingleton subclass constructor or
+ * initSingleton() method explicitly depends on some other LLSingleton
+ * subclass, you may continue to rely on that other subclass in your
+ * cleanupSingleton() method.
+ *
+ * We introduce a special cleanupSingleton() method because cleanupSingleton()
+ * operations can involve nontrivial realtime, or might throw an exception. A
+ * destructor should do neither!
+ *
+ * If your cleanupSingleton() method throws an exception, we log that
+ * exception but proceed with the remaining cleanupSingleton() calls.
+ *
+ * Similarly, if at some point you call LLSingletonBase::deleteAll(), all
+ * remaining LLSingleton instances will be destroyed in dependency order. (Or
+ * call MySubclass::deleteSingleton() to specifically destroy the canonical
+ * MySubclass instance.)
+ *
+ * As currently written, LLSingleton is not thread-safe.
+ */
+template <typename DERIVED_TYPE>
+class LLSingleton : public LLSingletonBase
 {
-	
 private:
-	typedef enum e_init_state
-	{
-		UNINITIALIZED,
-		CONSTRUCTING,
-		INITIALIZING,
-		INITIALIZED,
-		DELETED
-	} EInitState;
-    
     static DERIVED_TYPE* constructSingleton()
     {
         return new DERIVED_TYPE();
     }
-	
-	// stores pointer to singleton instance
-	struct SingletonLifetimeManager
-	{
-		SingletonLifetimeManager()
-		{
-			construct();
-		}
-
-		static void construct()
-		{
-			sData.mInitState = CONSTRUCTING;
-			sData.mInstance = constructSingleton();
-			sData.mInitState = INITIALIZING;
-		}
-
-		~SingletonLifetimeManager()
-		{
-			if (sData.mInitState != DELETED)
-			{
-				deleteSingleton();
-			}
-		}
-	};
-	
+
+    // We know of no way to instruct the compiler that every subclass
+    // constructor MUST be private. However, we can make the LLSINGLETON()
+    // macro both declare a private constructor and provide the required
+    // friend declaration. How can we ensure that every subclass uses
+    // LLSINGLETON()? By making that macro provide a definition for this pure
+    // virtual method. If you get "can't instantiate class due to missing pure
+    // virtual method" for this method, then add LLSINGLETON(yourclass) in the
+    // subclass body.
+    virtual void you_must_use_LLSINGLETON_macro() = 0;
+
+    // stores pointer to singleton instance
+    struct SingletonLifetimeManager
+    {
+        SingletonLifetimeManager():
+            mMasterRefcount(LLSingletonBase::get_master_refcount())
+        {
+            construct();
+        }
+
+        static void construct()
+        {
+            sData.mInitState = CONSTRUCTING;
+            sData.mInstance = constructSingleton();
+            sData.mInitState = INITIALIZING;
+        }
+
+        ~SingletonLifetimeManager()
+        {
+            // The dependencies between LLSingletons, and the arbitrary order
+            // of static-object destruction, mean that we DO NOT WANT this
+            // destructor to delete this LLSingleton. This destructor will run
+            // without regard to any other LLSingleton whose cleanup might
+            // depend on its existence. What we really want is to count the
+            // runtime's attempts to cleanup LLSingleton static data -- and on
+            // the very last one, call LLSingletonBase::deleteAll(). That
+            // method will properly honor cross-LLSingleton dependencies. This
+            // is why we store an intrusive_ptr to a MasterRefcount: our
+            // ref_ptr_t member counts SingletonLifetimeManager instances.
+            // Once the runtime destroys the last of these, THEN we can delete
+            // every remaining LLSingleton.
+        }
+
+        LLSingletonBase::ref_ptr_t mMasterRefcount;
+    };
+
+protected:
+    // Pass DERIVED_TYPE explicitly to LLSingletonBase's constructor because,
+    // until our subclass constructor completes, *this isn't yet a
+    // full-fledged DERIVED_TYPE.
+    LLSingleton(): LLSingletonBase(LLSingletonBase::tag<DERIVED_TYPE>())
+    {
+        // populate base-class function pointer with the static
+        // deleteSingleton() function for this particular specialization
+        mDeleteSingleton = &deleteSingleton;
+
+        // add this new instance to the master list
+        LLSingleton_manage_master<DERIVED_TYPE>().add(this);
+    }
+
 public:
-	virtual ~LLSingleton()
-	{
-		sData.mInstance = NULL;
-		sData.mInitState = DELETED;
-	}
-
-	/**
-	 * @brief Immediately delete the singleton.
-	 *
-	 * A subsequent call to LLProxy::getInstance() will construct a new
-	 * instance of the class.
-	 *
-	 * LLSingletons are normally destroyed after main() has exited and the C++
-	 * runtime is cleaning up statically-constructed objects. Some classes
-	 * derived from LLSingleton have objects that are part of a runtime system
-	 * that is terminated before main() exits. Calling the destructor of those
-	 * objects after the termination of their respective systems can cause
-	 * crashes and other problems during termination of the project. Using this
-	 * method to destroy the singleton early can prevent these crashes.
-	 *
-	 * An example where this is needed is for a LLSingleton that has an APR
-	 * object as a member that makes APR calls on destruction. The APR system is
-	 * shut down explicitly before main() exits. This causes a crash on exit.
-	 * Using this method before the call to apr_terminate() and NOT calling
-	 * getInstance() again will prevent the crash.
-	 */
-	static void deleteSingleton()
-	{
-		delete sData.mInstance;
-		sData.mInstance = NULL;
-		sData.mInitState = DELETED;
-	}
-
-
-	static DERIVED_TYPE* getInstance()
-	{
-		static SingletonLifetimeManager sLifeTimeMgr;
-
-		switch (sData.mInitState)
-		{
-		case UNINITIALIZED:
-			// should never be uninitialized at this point
-			llassert(false);
-			return NULL;
-		case CONSTRUCTING:
-			LL_ERRS() << "Tried to access singleton " << typeid(DERIVED_TYPE).name() << " from singleton constructor!" << LL_ENDL;
-			return NULL;
-		case INITIALIZING:
-			// go ahead and flag ourselves as initialized so we can be reentrant during initialization
-			sData.mInitState = INITIALIZED;	
-			// initialize singleton after constructing it so that it can reference other singletons which in turn depend on it,
-			// thus breaking cyclic dependencies
-			sData.mInstance->initSingleton(); 
-			return sData.mInstance;
-		case INITIALIZED:
-			return sData.mInstance;
-		case DELETED:
-			LL_WARNS() << "Trying to access deleted singleton " << typeid(DERIVED_TYPE).name() << " creating new instance" << LL_ENDL;
-			SingletonLifetimeManager::construct();
-			// same as first time construction
-			sData.mInitState = INITIALIZED;	
-			sData.mInstance->initSingleton(); 
-			return sData.mInstance;
-		}
-
-		return NULL;
-	}
-
-	static DERIVED_TYPE* getIfExists()
-	{
-		return sData.mInstance;
-	}
-
-	// Reference version of getInstance()
-	// Preferred over getInstance() as it disallows checking for NULL
-	static DERIVED_TYPE& instance()
-	{
-		return *getInstance();
-	}
-	
-	// Has this singleton been created uet?
-	// Use this to avoid accessing singletons before the can safely be constructed
-	static bool instanceExists()
-	{
-		return sData.mInitState == INITIALIZED;
-	}
-	
-	// Has this singleton already been deleted?
-	// Use this to avoid accessing singletons from a static object's destructor
-	static bool destroyed()
-	{
-		return sData.mInitState == DELETED;
-	}
+    virtual ~LLSingleton()
+    {
+        // remove this instance from the master list
+        LLSingleton_manage_master<DERIVED_TYPE>().remove(this);
+        sData.mInstance = NULL;
+        sData.mInitState = DELETED;
+    }
 
-private:
+    /**
+     * @brief Immediately delete the singleton.
+     *
+     * A subsequent call to LLProxy::getInstance() will construct a new
+     * instance of the class.
+     *
+     * Without an explicit call to LLSingletonBase::deleteAll(), LLSingletons
+     * are implicitly destroyed after main() has exited and the C++ runtime is
+     * cleaning up statically-constructed objects. Some classes derived from
+     * LLSingleton have objects that are part of a runtime system that is
+     * terminated before main() exits. Calling the destructor of those objects
+     * after the termination of their respective systems can cause crashes and
+     * other problems during termination of the project. Using this method to
+     * destroy the singleton early can prevent these crashes.
+     *
+     * An example where this is needed is for a LLSingleton that has an APR
+     * object as a member that makes APR calls on destruction. The APR system is
+     * shut down explicitly before main() exits. This causes a crash on exit.
+     * Using this method before the call to apr_terminate() and NOT calling
+     * getInstance() again will prevent the crash.
+     */
+    static void deleteSingleton()
+    {
+        delete sData.mInstance;
+        sData.mInstance = NULL;
+        sData.mInitState = DELETED;
+    }
+
+    static DERIVED_TYPE* getInstance()
+    {
+        static SingletonLifetimeManager sLifeTimeMgr;
 
-	virtual void initSingleton() {}
+        switch (sData.mInitState)
+        {
+        case UNINITIALIZED:
+            // should never be uninitialized at this point
+            logerrs("Uninitialized singleton ",
+                    demangle(typeid(DERIVED_TYPE).name()).c_str());
+            return NULL;
 
-	struct SingletonData
-	{
-		// explicitly has a default constructor so that member variables are zero initialized in BSS
-		// and only changed by singleton logic, not constructor running during startup
-		EInitState		mInitState;
-		DERIVED_TYPE*	mInstance;
-	};
-	static SingletonData sData;
+        case CONSTRUCTING:
+            logerrs("Tried to access singleton ",
+                    demangle(typeid(DERIVED_TYPE).name()).c_str(),
+                    " from singleton constructor!");
+            return NULL;
+
+        case INITIALIZING:
+            // go ahead and flag ourselves as initialized so we can be
+            // reentrant during initialization
+            sData.mInitState = INITIALIZED; 
+            // initialize singleton after constructing it so that it can
+            // reference other singletons which in turn depend on it, thus
+            // breaking cyclic dependencies
+            sData.mInstance->initSingleton();
+            // pop this off stack of initializing singletons
+            LLSingleton_manage_master<DERIVED_TYPE>().pop_initializing(sData.mInstance);
+            break;
+
+        case INITIALIZED:
+            break;
+
+        case DELETED:
+            logwarns("Trying to access deleted singleton ",
+                     demangle(typeid(DERIVED_TYPE).name()).c_str(),
+                     " -- creating new instance");
+            SingletonLifetimeManager::construct();
+            // same as first time construction
+            sData.mInitState = INITIALIZED; 
+            sData.mInstance->initSingleton(); 
+            // pop this off stack of initializing singletons
+            LLSingleton_manage_master<DERIVED_TYPE>().pop_initializing(sData.mInstance);
+            break;
+        }
+
+        // By this point, if DERIVED_TYPE was pushed onto the initializing
+        // stack, it has been popped off. So the top of that stack, if any, is
+        // an LLSingleton that directly depends on DERIVED_TYPE. If this call
+        // came from another LLSingleton, rather than from vanilla application
+        // code, record the dependency.
+        sData.mInstance->capture_dependency(
+            LLSingleton_manage_master<DERIVED_TYPE>().get_initializing(sData.mInstance),
+            sData.mInitState);
+        return sData.mInstance;
+    }
+
+    // Reference version of getInstance()
+    // Preferred over getInstance() as it disallows checking for NULL
+    static DERIVED_TYPE& instance()
+    {
+        return *getInstance();
+    }
+
+    // Has this singleton been created yet?
+    // Use this to avoid accessing singletons before they can safely be constructed.
+    static bool instanceExists()
+    {
+        return sData.mInitState == INITIALIZED;
+    }
+
+private:
+    struct SingletonData
+    {
+        // explicitly has a default constructor so that member variables are zero initialized in BSS
+        // and only changed by singleton logic, not constructor running during startup
+        EInitState      mInitState;
+        DERIVED_TYPE*   mInstance;
+    };
+    static SingletonData sData;
 };
 
 template<typename T>
 typename LLSingleton<T>::SingletonData LLSingleton<T>::sData;
 
+/**
+ * Use LLSINGLETON(Foo); at the start of an LLSingleton<Foo> subclass body
+ * when you want to declare an out-of-line constructor:
+ *
+ * @code
+ *   class Foo: public LLSingleton<Foo>
+ *   {
+ *       // use this macro at start of every LLSingleton subclass
+ *       LLSINGLETON(Foo);
+ *   public:
+ *       // ...
+ *   };
+ *   // ...
+ *   [inline]
+ *   Foo::Foo() { ... }
+ * @endcode
+ *
+ * Unfortunately, this mechanism does not permit you to define even a simple
+ * (but nontrivial) constructor within the class body. If it's literally
+ * trivial, use LLSINGLETON_EMPTY_CTOR(); if not, use LLSINGLETON() and define
+ * the constructor outside the class body. If you must define it in a header
+ * file, use 'inline' (unless it's a template class) to avoid duplicate-symbol
+ * errors at link time.
+ */
+#define LLSINGLETON(DERIVED_CLASS)                                      \
+private:                                                                \
+    /* implement LLSingleton pure virtual method whose sole purpose */  \
+    /* is to remind people to use this macro */                         \
+    virtual void you_must_use_LLSINGLETON_macro() {}                    \
+    friend class LLSingleton<DERIVED_CLASS>;                            \
+    DERIVED_CLASS()
+
+/**
+ * Use LLSINGLETON_EMPTY_CTOR(Foo); at the start of an LLSingleton<Foo>
+ * subclass body when the constructor is trivial:
+ *
+ * @code
+ *   class Foo: public LLSingleton<Foo>
+ *   {
+ *       // use this macro at start of every LLSingleton subclass
+ *       LLSINGLETON_EMPTY_CTOR(Foo);
+ *   public:
+ *       // ...
+ *   };
+ * @endcode
+ */
+#define LLSINGLETON_EMPTY_CTOR(DERIVED_CLASS)                           \
+    /* LLSINGLETON() is carefully implemented to permit exactly this */ \
+    LLSINGLETON(DERIVED_CLASS) {}
+
 #endif
diff --git a/indra/llcommon/tests/llheteromap_test.cpp b/indra/llcommon/tests/llheteromap_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..686bffb878b44c8de1da45fb45d80e606cbb1127
--- /dev/null
+++ b/indra/llcommon/tests/llheteromap_test.cpp
@@ -0,0 +1,163 @@
+/**
+ * @file   llheteromap_test.cpp
+ * @author Nat Goodspeed
+ * @date   2016-10-12
+ * @brief  Test for llheteromap.
+ * 
+ * $LicenseInfo:firstyear=2016&license=viewerlgpl$
+ * Copyright (c) 2016, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llheteromap.h"
+// STL headers
+#include <set>
+// std headers
+// external library headers
+
+// (pacify clang)
+std::ostream& operator<<(std::ostream& out, const std::set<std::string>& strset);
+// other Linden headers
+#include "../test/lltut.h"
+
+static std::string clog;
+static std::set<std::string> dlog;
+
+// want to be able to use ensure_equals() on a set<string>
+std::ostream& operator<<(std::ostream& out, const std::set<std::string>& strset)
+{
+    out << '{';
+    const char* delim = "";
+    for (std::set<std::string>::const_iterator si(strset.begin()), se(strset.end());
+         si != se; ++si)
+    {
+        out << delim << '"' << *si << '"';
+        delim = ", ";
+    }
+    out << '}';
+    return out;
+}
+
+// unrelated test classes
+struct Chalk
+{
+    int dummy;
+    std::string name;
+
+    Chalk():
+        dummy(0)
+    {
+        clog.append("a");
+    }
+
+    ~Chalk()
+    {
+        dlog.insert("a");
+    }
+
+private:
+    Chalk(const Chalk&);            // no implementation
+};
+
+struct Cheese
+{
+    std::string name;
+
+    Cheese()
+    {
+        clog.append("e");
+    }
+
+    ~Cheese()
+    {
+        dlog.insert("e");
+    }
+
+private:
+    Cheese(const Cheese&);          // no implementation
+};
+
+struct Chowdah
+{
+    char displace[17];
+    std::string name;
+
+    Chowdah()
+    {
+        displace[0] = '\0';
+        clog.append("o");
+    }
+
+    ~Chowdah()
+    {
+        dlog.insert("o");
+    }
+
+private:
+    Chowdah(const Chowdah&);        // no implementation
+};
+
+/*****************************************************************************
+*   TUT
+*****************************************************************************/
+namespace tut
+{
+    struct llheteromap_data
+    {
+        llheteromap_data()
+        {
+            clog.erase();
+            dlog.clear();
+        }
+    };
+    typedef test_group<llheteromap_data> llheteromap_group;
+    typedef llheteromap_group::object object;
+    llheteromap_group llheteromapgrp("llheteromap");
+
+    template<> template<>
+    void object::test<1>()
+    {
+        set_test_name("create, get, delete");
+
+        {
+            LLHeteroMap map;
+
+            {
+                // create each instance
+                Chalk& chalk = map.obtain<Chalk>();
+                chalk.name = "Chalk";
+
+                Cheese& cheese = map.obtain<Cheese>();
+                cheese.name = "Cheese";
+
+                Chowdah& chowdah = map.obtain<Chowdah>();
+                chowdah.name = "Chowdah";
+            } // refs go out of scope
+
+            {
+                // verify each instance
+                Chalk& chalk = map.obtain<Chalk>();
+                ensure_equals(chalk.name, "Chalk");
+
+                Cheese& cheese = map.obtain<Cheese>();
+                ensure_equals(cheese.name, "Cheese");
+
+                Chowdah& chowdah = map.obtain<Chowdah>();
+                ensure_equals(chowdah.name, "Chowdah");
+            }
+        } // destroy map
+
+        // Chalk, Cheese and Chowdah should have been created in specific order
+        ensure_equals(clog, "aeo");
+
+        // We don't care what order they're destroyed in, as long as each is
+        // appropriately destroyed.
+        std::set<std::string> dtorset;
+        for (const char* cp = "aeo"; *cp; ++cp)
+            dtorset.insert(std::string(1, *cp));
+        ensure_equals(dlog, dtorset);
+    }
+} // namespace tut
diff --git a/indra/llcommon/tests/llpounceable_test.cpp b/indra/llcommon/tests/llpounceable_test.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..2f4915ce11a4eb7f4f76cc032dd12890e370dd19
--- /dev/null
+++ b/indra/llcommon/tests/llpounceable_test.cpp
@@ -0,0 +1,230 @@
+/**
+ * @file   llpounceable_test.cpp
+ * @author Nat Goodspeed
+ * @date   2015-05-22
+ * @brief  Test for llpounceable.
+ * 
+ * $LicenseInfo:firstyear=2015&license=viewerlgpl$
+ * Copyright (c) 2015, Linden Research, Inc.
+ * $/LicenseInfo$
+ */
+
+// Precompiled header
+#include "linden_common.h"
+// associated header
+#include "llpounceable.h"
+// STL headers
+// std headers
+// external library headers
+#include <boost/bind.hpp>
+// other Linden headers
+#include "../test/lltut.h"
+
+/*----------------------------- string testing -----------------------------*/
+void append(std::string* dest, const std::string& src)
+{
+    dest->append(src);
+}
+
+/*-------------------------- Data-struct testing ---------------------------*/
+struct Data
+{
+    Data(const std::string& data):
+        mData(data)
+    {}
+    const std::string mData;
+};
+
+void setter(Data** dest, Data* ptr)
+{
+    *dest = ptr;
+}
+
+static Data* static_check = 0;
+
+// Set up an extern pointer to an LLPounceableStatic so the linker will fill
+// in the forward reference from below, before runtime.
+extern LLPounceable<Data*, LLPounceableStatic> gForward;
+
+struct EnqueueCall
+{
+    EnqueueCall()
+    {
+        // Intentionally use a forward reference to an LLPounceableStatic that
+        // we believe is NOT YET CONSTRUCTED. This models the scenario in
+        // which a constructor in another translation unit runs before
+        // constructors in this one. We very specifically want callWhenReady()
+        // to work even in that case: we need the LLPounceableQueueImpl to be
+        // initialized even if the LLPounceable itself is not.
+        gForward.callWhenReady(boost::bind(setter, &static_check, _1));
+    }
+} nqcall;
+// When this declaration is processed, we should enqueue the
+// setter(&static_check, _1) call for when gForward is set non-NULL. Needless
+// to remark, we want this call not to crash.
+
+// Now declare gForward. Its constructor should not run until after nqcall's.
+LLPounceable<Data*, LLPounceableStatic> gForward;
+
+/*****************************************************************************
+*   TUT
+*****************************************************************************/
+namespace tut
+{
+    struct llpounceable_data
+    {
+    };
+    typedef test_group<llpounceable_data> llpounceable_group;
+    typedef llpounceable_group::object object;
+    llpounceable_group llpounceablegrp("llpounceable");
+
+    template<> template<>
+    void object::test<1>()
+    {
+        set_test_name("LLPounceableStatic out-of-order test");
+        // LLPounceable<T, LLPounceableStatic>::callWhenReady() must work even
+        // before LLPounceable's constructor runs. That's the whole point of
+        // implementing it with an LLSingleton queue. This models (say)
+        // LLPounceableStatic<LLMessageSystem*, LLPounceableStatic>.
+        ensure("static_check should still be null", ! static_check);
+        Data myData("test<1>");
+        gForward = &myData;         // should run setter
+        ensure_equals("static_check should be &myData", static_check, &myData);
+    }
+
+    template<> template<>
+    void object::test<2>()
+    {
+        set_test_name("LLPounceableQueue different queues");
+        // We expect that LLPounceable<T, LLPounceableQueue> should have
+        // different queues because that specialization stores the queue
+        // directly in the LLPounceable instance.
+        Data *aptr = 0, *bptr = 0;
+        LLPounceable<Data*> a, b;
+        a.callWhenReady(boost::bind(setter, &aptr, _1));
+        b.callWhenReady(boost::bind(setter, &bptr, _1));
+        ensure("aptr should be null", ! aptr);
+        ensure("bptr should be null", ! bptr);
+        Data adata("a"), bdata("b");
+        a = &adata;
+        ensure_equals("aptr should be &adata", aptr, &adata);
+        // but we haven't yet set b
+        ensure("bptr should still be null", !bptr);
+        b = &bdata;
+        ensure_equals("bptr should be &bdata", bptr, &bdata);
+    }
+
+    template<> template<>
+    void object::test<3>()
+    {
+        set_test_name("LLPounceableStatic different queues");
+        // LLPounceable<T, LLPounceableStatic> should also have a distinct
+        // queue for each instance, but that engages an additional map lookup
+        // because there's only one LLSingleton for each T.
+        Data *aptr = 0, *bptr = 0;
+        LLPounceable<Data*, LLPounceableStatic> a, b;
+        a.callWhenReady(boost::bind(setter, &aptr, _1));
+        b.callWhenReady(boost::bind(setter, &bptr, _1));
+        ensure("aptr should be null", ! aptr);
+        ensure("bptr should be null", ! bptr);
+        Data adata("a"), bdata("b");
+        a = &adata;
+        ensure_equals("aptr should be &adata", aptr, &adata);
+        // but we haven't yet set b
+        ensure("bptr should still be null", !bptr);
+        b = &bdata;
+        ensure_equals("bptr should be &bdata", bptr, &bdata);
+    }
+
+    template<> template<>
+    void object::test<4>()
+    {
+        set_test_name("LLPounceable<T> looks like T");
+        // We want LLPounceable<T, TAG> to be drop-in replaceable for a plain
+        // T for read constructs. In particular, it should behave like a dumb
+        // pointer -- and with zero abstraction cost for such usage.
+        Data* aptr = 0;
+        Data a("a");
+        // should be able to initialize a pounceable (when its constructor
+        // runs)
+        LLPounceable<Data*> pounceable(&a);
+        // should be able to pass LLPounceable<T> to function accepting T
+        setter(&aptr, pounceable);
+        ensure_equals("aptr should be &a", aptr, &a);
+        // should be able to dereference with *
+        ensure_equals("deref with *", (*pounceable).mData, "a");
+        // should be able to dereference with ->
+        ensure_equals("deref with ->", pounceable->mData, "a");
+        // bool operations
+        ensure("test with operator bool()", pounceable);
+        ensure("test with operator !()", ! (! pounceable));
+    }
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("Multiple callWhenReady() queue items");
+        Data *p1 = 0, *p2 = 0, *p3 = 0;
+        Data a("a");
+        LLPounceable<Data*> pounceable;
+        // queue up a couple setter() calls for later
+        pounceable.callWhenReady(boost::bind(setter, &p1, _1));
+        pounceable.callWhenReady(boost::bind(setter, &p2, _1));
+        // should still be pending
+        ensure("p1 should be null", !p1);
+        ensure("p2 should be null", !p2);
+        ensure("p3 should be null", !p3);
+        pounceable = 0;
+        // assigning a new empty value shouldn't flush the queue
+        ensure("p1 should still be null", !p1);
+        ensure("p2 should still be null", !p2);
+        ensure("p3 should still be null", !p3);
+        // using whichever syntax
+        pounceable.reset(0);
+        // try to make ensure messages distinct... tough to pin down which
+        // ensure() failed if multiple ensure() calls in the same test<n> have
+        // the same message!
+        ensure("p1 should again be null", !p1);
+        ensure("p2 should again be null", !p2);
+        ensure("p3 should again be null", !p3);
+        pounceable.reset(&a);       // should flush queue
+        ensure_equals("p1 should be &a", p1, &a);
+        ensure_equals("p2 should be &a", p2, &a);
+        ensure("p3 still not set", !p3);
+        // immediate call
+        pounceable.callWhenReady(boost::bind(setter, &p3, _1));
+        ensure_equals("p3 should be &a", p3, &a);
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("queue order");
+        std::string data;
+        LLPounceable<std::string*> pounceable;
+        pounceable.callWhenReady(boost::bind(append, _1, "a"));
+        pounceable.callWhenReady(boost::bind(append, _1, "b"));
+        pounceable.callWhenReady(boost::bind(append, _1, "c"));
+        pounceable = &data;
+        ensure_equals("callWhenReady() must preserve chronological order",
+                      data, "abc");
+
+        std::string data2;
+        pounceable = NULL;
+        pounceable.callWhenReady(boost::bind(append, _1, "d"));
+        pounceable.callWhenReady(boost::bind(append, _1, "e"));
+        pounceable.callWhenReady(boost::bind(append, _1, "f"));
+        pounceable = &data2;
+        ensure_equals("LLPounceable must reset queue when fired",
+                      data2, "def");
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("compile-fail test, uncomment to check");
+        // The following declaration should fail: only LLPounceableQueue and
+        // LLPounceableStatic should work as tags.
+//      LLPounceable<Data*, int> pounceable;
+    }
+} // namespace tut
diff --git a/indra/llcommon/tests/llsingleton_test.cpp b/indra/llcommon/tests/llsingleton_test.cpp
index 385289aefef69b16997148840929fe7b94963c3f..56886bc73fd9185932f76c82d0d72232cc5c4e5c 100644
--- a/indra/llcommon/tests/llsingleton_test.cpp
+++ b/indra/llcommon/tests/llsingleton_test.cpp
@@ -30,47 +30,172 @@
 #include "llsingleton.h"
 #include "../test/lltut.h"
 
+
+// Capture execution sequence by appending to log string.
+std::string sLog;
+
+#define DECLARE_CLASS(CLS)                          \
+struct CLS: public LLSingleton<CLS>                 \
+{                                                   \
+    LLSINGLETON(CLS);                               \
+    ~CLS();                                         \
+public:                                             \
+    static enum dep_flag {                          \
+        DEP_NONE, /* no dependency */               \
+        DEP_CTOR, /* dependency in ctor */          \
+        DEP_INIT  /* dependency in initSingleton */ \
+    } sDepFlag;                                     \
+                                                    \
+    void initSingleton();                           \
+    void cleanupSingleton();                        \
+};                                                  \
+                                                    \
+CLS::dep_flag CLS::sDepFlag = DEP_NONE
+
+DECLARE_CLASS(A);
+DECLARE_CLASS(B);
+
+#define DEFINE_MEMBERS(CLS, OTHER)              \
+CLS::CLS()                                      \
+{                                               \
+    sLog.append(#CLS);                          \
+    if (sDepFlag == DEP_CTOR)                   \
+    {                                           \
+        (void)OTHER::instance();                \
+    }                                           \
+}                                               \
+                                                \
+void CLS::initSingleton()                       \
+{                                               \
+    sLog.append("i" #CLS);                      \
+    if (sDepFlag == DEP_INIT)                   \
+    {                                           \
+        (void)OTHER::instance();                \
+    }                                           \
+}                                               \
+                                                \
+void CLS::cleanupSingleton()                    \
+{                                               \
+    sLog.append("x" #CLS);                      \
+}                                               \
+                                                \
+CLS::~CLS()                                     \
+{                                               \
+    sLog.append("~" #CLS);                      \
+}
+
+DEFINE_MEMBERS(A, B)
+DEFINE_MEMBERS(B, A)
+
 namespace tut
 {
-	struct singleton
-	{
-		// We need a class created with the LLSingleton template to test with.
-		class LLSingletonTest: public LLSingleton<LLSingletonTest>
-		{
-
-		};
-	};
-
-	typedef test_group<singleton> singleton_t;
-	typedef singleton_t::object singleton_object_t;
-	tut::singleton_t tut_singleton("LLSingleton");
-
-	template<> template<>
-	void singleton_object_t::test<1>()
-	{
-
-	}
-	template<> template<>
-	void singleton_object_t::test<2>()
-	{
-		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
-		ensure(singleton_test);
-	}
-	template<> template<>
-	void singleton_object_t::test<3>()
-	{
-		//Construct the instance
-		LLSingletonTest::getInstance();
-		ensure(LLSingletonTest::instanceExists());
-
-		//Delete the instance
-		LLSingletonTest::deleteSingleton();
-		ensure(LLSingletonTest::destroyed());
-		ensure(!LLSingletonTest::instanceExists());
-
-		//Construct it again.
-		LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
-		ensure(singleton_test);
-		ensure(LLSingletonTest::instanceExists());
-	}
+    struct singleton
+    {
+        // We need a class created with the LLSingleton template to test with.
+        class LLSingletonTest: public LLSingleton<LLSingletonTest>
+        {
+            LLSINGLETON_EMPTY_CTOR(LLSingletonTest);
+        };
+    };
+
+    typedef test_group<singleton> singleton_t;
+    typedef singleton_t::object singleton_object_t;
+    tut::singleton_t tut_singleton("LLSingleton");
+
+    template<> template<>
+    void singleton_object_t::test<1>()
+    {
+
+    }
+    template<> template<>
+    void singleton_object_t::test<2>()
+    {
+        LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+        ensure(singleton_test);
+    }
+
+    template<> template<>
+    void singleton_object_t::test<3>()
+    {
+        //Construct the instance
+        LLSingletonTest::getInstance();
+        ensure(LLSingletonTest::instanceExists());
+
+        //Delete the instance
+        LLSingletonTest::deleteSingleton();
+        ensure(!LLSingletonTest::instanceExists());
+
+        //Construct it again.
+        LLSingletonTest* singleton_test = LLSingletonTest::getInstance();
+        ensure(singleton_test);
+        ensure(LLSingletonTest::instanceExists());
+    }
+
+#define TESTS(CLS, OTHER, N0, N1, N2, N3)                               \
+    template<> template<>                                               \
+    void singleton_object_t::test<N0>()                                 \
+    {                                                                   \
+        set_test_name("just " #CLS);                                    \
+        CLS::sDepFlag = CLS::DEP_NONE;                                  \
+        OTHER::sDepFlag = OTHER::DEP_NONE;                              \
+        sLog.clear();                                                   \
+                                                                        \
+        (void)CLS::instance();                                          \
+        ensure_equals(sLog, #CLS "i" #CLS);                             \
+        LLSingletonBase::cleanupAll();                                  \
+        ensure_equals(sLog, #CLS "i" #CLS "x" #CLS);                    \
+        LLSingletonBase::deleteAll();                                   \
+        ensure_equals(sLog, #CLS "i" #CLS "x" #CLS "~" #CLS);           \
+    }                                                                   \
+                                                                        \
+    template<> template<>                                               \
+    void singleton_object_t::test<N1>()                                 \
+    {                                                                   \
+        set_test_name(#CLS " ctor depends " #OTHER);                    \
+        CLS::sDepFlag = CLS::DEP_CTOR;                                  \
+        OTHER::sDepFlag = OTHER::DEP_NONE;                              \
+        sLog.clear();                                                   \
+                                                                        \
+        (void)CLS::instance();                                          \
+        ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS);           \
+        LLSingletonBase::cleanupAll();                                  \
+        ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER); \
+        LLSingletonBase::deleteAll();                                   \
+        ensure_equals(sLog, #CLS #OTHER "i" #OTHER "i" #CLS "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+    }                                                                   \
+                                                                        \
+    template<> template<>                                               \
+    void singleton_object_t::test<N2>()                                 \
+    {                                                                   \
+        set_test_name(#CLS " init depends " #OTHER);                    \
+        CLS::sDepFlag = CLS::DEP_INIT;                                  \
+        OTHER::sDepFlag = OTHER::DEP_NONE;                              \
+        sLog.clear();                                                   \
+                                                                        \
+        (void)CLS::instance();                                          \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER);           \
+        LLSingletonBase::cleanupAll();                                  \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \
+        LLSingletonBase::deleteAll();                                   \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+    }                                                                   \
+                                                                        \
+    template<> template<>                                               \
+    void singleton_object_t::test<N3>()                                 \
+    {                                                                   \
+        set_test_name(#CLS " circular init");                           \
+        CLS::sDepFlag = CLS::DEP_INIT;                                  \
+        OTHER::sDepFlag = OTHER::DEP_CTOR;                              \
+        sLog.clear();                                                   \
+                                                                        \
+        (void)CLS::instance();                                          \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER);           \
+        LLSingletonBase::cleanupAll();                                  \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER); \
+        LLSingletonBase::deleteAll();                                   \
+        ensure_equals(sLog, #CLS "i" #CLS #OTHER "i" #OTHER "x" #CLS "x" #OTHER "~" #CLS "~" #OTHER); \
+    }
+
+    TESTS(A, B, 4, 5, 6, 7)
+    TESTS(B, A, 8, 9, 10, 11)
 }
diff --git a/indra/llcorehttp/CMakeLists.txt b/indra/llcorehttp/CMakeLists.txt
index 0bb0348d26b9f9a8112e104ba91fde2f1ea89fad..b03ee6eeda65df2854c50d4c60ca5d4c290d4d62 100644
--- a/indra/llcorehttp/CMakeLists.txt
+++ b/indra/llcorehttp/CMakeLists.txt
@@ -93,6 +93,7 @@ target_link_libraries(
   ${OPENSSL_LIBRARIES}
   ${CRYPTO_LIBRARIES}
   ${BOOST_THREAD_LIBRARY}
+  ${BOOST_SYSTEM_LIBRARY}
   )
 
 # tests
@@ -129,8 +130,8 @@ if (LL_TESTS)
       ${CURL_LIBRARIES}
       ${OPENSSL_LIBRARIES}
       ${CRYPTO_LIBRARIES}
-      ${BOOST_SYSTEM_LIBRARY}
       ${BOOST_THREAD_LIBRARY}
+      ${BOOST_SYSTEM_LIBRARY}
       )
 
   # If http_proxy is in the current environment (e.g. to fetch s3-proxy
@@ -197,8 +198,8 @@ endif (DARWIN)
       ${CURL_LIBRARIES}
       ${OPENSSL_LIBRARIES}
       ${CRYPTO_LIBRARIES}
-      ${BOOST_SYSTEM_LIBRARY}
       ${BOOST_THREAD_LIBRARY}
+      ${BOOST_SYSTEM_LIBRARY}
       )
 
   add_executable(http_texture_load
diff --git a/indra/llcorehttp/tests/llcorehttp_test.cpp b/indra/llcorehttp/tests/llcorehttp_test.cpp
old mode 100644
new mode 100755
index bef762f5ce5b4a526aaade6d4c0be97595cb20dc..a310fc0508e1e3d5ebc8f681233665d6a4978bbf
--- a/indra/llcorehttp/tests/llcorehttp_test.cpp
+++ b/indra/llcorehttp/tests/llcorehttp_test.cpp
@@ -46,6 +46,7 @@
 #include "test_httprequestqueue.hpp"
 
 #include "llproxy.h"
+#include "llcleanup.h"
 
 unsigned long ssl_thread_id_callback(void);
 void ssl_locking_callback(int mode, int type, const char * file, int line);
@@ -101,7 +102,7 @@ void init_curl()
 
 void term_curl()
 {
-	LLProxy::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLProxy);
 	
 	CRYPTO_set_locking_callback(NULL);
 	for (int i(0); i < ssl_mutex_count; ++i)
diff --git a/indra/llcorehttp/tests/test_httprequest.hpp b/indra/llcorehttp/tests/test_httprequest.hpp
index 463e55dd7e7595c6a7f6f11a307135f3f9ded2d7..6cd7960ecd87847b468dbc6e2b5981a2054bbb4c 100644
--- a/indra/llcorehttp/tests/test_httprequest.hpp
+++ b/indra/llcorehttp/tests/test_httprequest.hpp
@@ -729,7 +729,7 @@ void HttpRequestTestObjectType::test<7>()
 #if 0 // defined(WIN32)
 		// Can't do this on any platform anymore, the LL logging system holds
 		// on to memory and produces what looks like memory leaks...
-	
+
 		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());
 		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
 #endif
@@ -1459,21 +1459,21 @@ void HttpRequestTestObjectType::test<14>()
 	// references to it after completion of this method.
 	// Create before memory record as the string copy will bump numbers.
 	TestHandler2 handler(this, "handler");
-    LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor);
-    std::string url_base(get_base_url() + "/sleep/");	// path to a 30-second sleep
-		
+	LLCore::HttpHandler::ptr_t handlerp(&handler, NoOpDeletor);
+	std::string url_base(get_base_url() + "/sleep/");   // path to a 30-second sleep
+
 	// record the total amount of dynamically allocated memory
 	mMemTotal = GetMemTotal();
 	mHandlerCalls = 0;
 
 	HttpRequest * req = NULL;
 	HttpOptions::ptr_t opts;
-	
+
 	try
 	{
-        // Get singletons created
+		// Get singletons created
 		HttpRequest::createService();
-		
+
 		// Start threading early so that thread memory is invariant
 		// over the test.
 		HttpRequest::startThread();
@@ -1482,10 +1482,10 @@ void HttpRequestTestObjectType::test<14>()
 		req = new HttpRequest();
 		ensure("Memory allocated on construction", mMemTotal < GetMemTotal());
 
-        opts = HttpOptions::ptr_t(new HttpOptions);
-		opts->setRetries(0);			// Don't retry
+		opts = HttpOptions::ptr_t(new HttpOptions);
+		opts->setRetries(0);            // Don't retry
 		opts->setTimeout(2);
-		
+
 		// Issue a GET that sleeps
 		mStatus = HttpStatus(HttpStatus::EXT_CURL_EASY, CURLE_OPERATION_TIMEDOUT);
 		HttpHandle handle = req->requestGetByteRange(HttpRequest::DEFAULT_POLICY_ID,
@@ -1494,8 +1494,8 @@ void HttpRequestTestObjectType::test<14>()
 													 0,
 													 0,
 													 opts,
-                                                     HttpHeaders::ptr_t(),
-                                                     handlerp);
+													 HttpHeaders::ptr_t(),
+													 handlerp);
 		ensure("Valid handle returned for ranged request", handle != LLCORE_HTTP_HANDLE_INVALID);
 
 		// Run the notification pump.
@@ -1513,7 +1513,7 @@ void HttpRequestTestObjectType::test<14>()
 		mStatus = HttpStatus();
 		handle = req->requestStopThread(handlerp);
 		ensure("Valid handle returned for second request", handle != LLCORE_HTTP_HANDLE_INVALID);
-	
+
 		// Run the notification pump again
 		count = 0;
 		limit = LOOP_COUNT_LONG;
@@ -1535,30 +1535,29 @@ void HttpRequestTestObjectType::test<14>()
 		ensure("Thread actually stopped running", HttpService::isStopped());
 
 		// release options
-        opts.reset();
-		
+		opts.reset();
+
 		// release the request object
 		delete req;
 		req = NULL;
 
 		// Shut down service
 		HttpRequest::destroyService();
-	
+
 		ensure("Two handler calls on the way out", 2 == mHandlerCalls);
 
-#if defined(WIN32)
-		// Can only do this memory test on Windows.  On other platforms,
-		// the LL logging system holds on to memory and produces what looks
-		// like memory leaks...
-	
-		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());
+#if 0 // defined(WIN32)
+		// Can't do this on any platform anymore, the LL logging system holds
+		// on to memory and produces what looks like memory leaks...
+
+		// printf("Old mem:	 %d, New mem:  %d\n", mMemTotal, GetMemTotal());
 		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
 #endif
 	}
 	catch (...)
 	{
 		stop_thread(req);
-        opts.reset();
+		opts.reset();
 		delete req;
 		HttpRequest::destroyService();
 		throw;
@@ -3065,12 +3064,11 @@ void HttpRequestTestObjectType::test<22>()
 
 		// Shut down service
 		HttpRequest::destroyService();
-	
-#if defined(WIN32)
-		// Can only do this memory test on Windows.  On other platforms,
-		// the LL logging system holds on to memory and produces what looks
-		// like memory leaks...
-	
+
+#if 0 // defined(WIN32)
+		// Can't do this on any platform anymore, the LL logging system holds
+		// on to memory and produces what looks like memory leaks...
+
 		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());
 		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
 #endif
@@ -3195,12 +3193,11 @@ void HttpRequestTestObjectType::test<23>()
 
 		// Shut down service
 		HttpRequest::destroyService();
-	
-#if defined(WIN32)
-		// Can only do this memory test on Windows.  On other platforms,
-		// the LL logging system holds on to memory and produces what looks
-		// like memory leaks...
-	
+
+#if 0 // defined(WIN32)
+		// Can't do this on any platform anymore, the LL logging system holds
+		// on to memory and produces what looks like memory leaks...
+
 		// printf("Old mem:  %d, New mem:  %d\n", mMemTotal, GetMemTotal());
 		ensure("Memory usage back to that at entry", mMemTotal == GetMemTotal());
 #endif
diff --git a/indra/llcrashlogger/llcrashlogger.cpp b/indra/llcrashlogger/llcrashlogger.cpp
index dfb344c908cccc66b42a0f548b3f606c0039b878..dca49be0515587a51f0855f55ff61d670b335a1b 100644
--- a/indra/llcrashlogger/llcrashlogger.cpp
+++ b/indra/llcrashlogger/llcrashlogger.cpp
@@ -45,6 +45,7 @@
 #include "llhttpsdhandler.h"
 #include "httpcommon.h"
 #include "httpresponse.h"
+#include "llcleanup.h"
 
 #include <curl/curl.h>
 #include <openssl/crypto.h>
@@ -623,7 +624,7 @@ void LLCrashLogger::commonCleanup()
 {
     term_curl();
 	LLError::logToFile("");   //close crashreport.log
-	LLProxy::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLProxy);
 }
 
 void LLCrashLogger::init_curl()
diff --git a/indra/llinventory/lleconomy.cpp b/indra/llinventory/lleconomy.cpp
index e10402196fd568e1f1154fe3d8fef45445d55523..2a023d8c24dc4aa4481967f5496cb232d3358047 100644
--- a/indra/llinventory/lleconomy.cpp
+++ b/indra/llinventory/lleconomy.cpp
@@ -31,7 +31,7 @@
 #include "v3math.h"
 
 
-LLGlobalEconomy::LLGlobalEconomy()
+LLBaseEconomy::LLBaseEconomy()
 :	mObjectCount( -1 ),
 	mObjectCapacity( -1 ),
 	mPriceObjectClaim( -1 ),
@@ -45,15 +45,15 @@ LLGlobalEconomy::LLGlobalEconomy()
 	mPriceGroupCreate( -1 )
 { }
 
-LLGlobalEconomy::~LLGlobalEconomy()
+LLBaseEconomy::~LLBaseEconomy()
 { }
 
-void LLGlobalEconomy::addObserver(LLEconomyObserver* observer)
+void LLBaseEconomy::addObserver(LLEconomyObserver* observer)
 {
 	mObservers.push_back(observer);
 }
 
-void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
+void LLBaseEconomy::removeObserver(LLEconomyObserver* observer)
 {
 	std::list<LLEconomyObserver*>::iterator it =
 		std::find(mObservers.begin(), mObservers.end(), observer);
@@ -63,7 +63,7 @@ void LLGlobalEconomy::removeObserver(LLEconomyObserver* observer)
 	}
 }
 
-void LLGlobalEconomy::notifyObservers()
+void LLBaseEconomy::notifyObservers()
 {
 	for (std::list<LLEconomyObserver*>::iterator it = mObservers.begin();
 		it != mObservers.end();
@@ -74,7 +74,7 @@ void LLGlobalEconomy::notifyObservers()
 }
 
 // static
-void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data)
+void LLBaseEconomy::processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data)
 {
 	S32 i;
 	F32 f;
@@ -117,7 +117,7 @@ void LLGlobalEconomy::processEconomyData(LLMessageSystem *msg, LLGlobalEconomy*
 	econ_data->notifyObservers();
 }
 
-S32	LLGlobalEconomy::calculateTeleportCost(F32 distance) const
+S32	LLBaseEconomy::calculateTeleportCost(F32 distance) const
 {
 	S32 min_cost = getTeleportMinPrice();
 	F32 exponent = getTeleportPriceExponent();
@@ -135,13 +135,13 @@ S32	LLGlobalEconomy::calculateTeleportCost(F32 distance) const
 	return cost;
 }
 
-S32	LLGlobalEconomy::calculateLightRent(const LLVector3& object_size) const
+S32	LLBaseEconomy::calculateLightRent(const LLVector3& object_size) const
 {
 	F32 intensity_mod = llmax(object_size.magVec(), 1.f);
 	return (S32)(intensity_mod * getPriceRentLight());
 }
 
-void LLGlobalEconomy::print()
+void LLBaseEconomy::print()
 {
 	LL_INFOS() << "Global Economy Settings: " << LL_ENDL;
 	LL_INFOS() << "Object Capacity: " << mObjectCapacity << LL_ENDL;
@@ -159,8 +159,7 @@ void LLGlobalEconomy::print()
 }
 
 LLRegionEconomy::LLRegionEconomy()
-:	LLGlobalEconomy(),
-	mPriceObjectRent( -1.f ),
+:	mPriceObjectRent( -1.f ),
 	mPriceObjectScaleFactor( -1.f ),
 	mEnergyEfficiency( -1.f ),
 	mBasePriceParcelClaimDefault(-1),
@@ -187,7 +186,7 @@ void LLRegionEconomy::processEconomyData(LLMessageSystem *msg, void** user_data)
 
 	LLRegionEconomy *this_ptr = (LLRegionEconomy*)user_data;
 
-	LLGlobalEconomy::processEconomyData(msg, this_ptr);
+	LLBaseEconomy::processEconomyData(msg, this_ptr);
 
 	msg->getS32Fast(_PREHASH_Info, _PREHASH_PriceParcelClaim, i);
 	this_ptr->setBasePriceParcelClaimDefault(i);
@@ -252,7 +251,7 @@ S32 LLRegionEconomy::getPriceParcelRent() const
 
 void LLRegionEconomy::print()
 {
-	this->LLGlobalEconomy::print();
+	this->LLBaseEconomy::print();
 
 	LL_INFOS() << "Region Economy Settings: " << LL_ENDL;
 	LL_INFOS() << "Land (square meters): " << mAreaTotal << LL_ENDL;
diff --git a/indra/llinventory/lleconomy.h b/indra/llinventory/lleconomy.h
index 47fcf688a26d66e9b61b70f119288d1ceb5c5303..cdfde171c1834371f9af16ecce60999935577252 100644
--- a/indra/llinventory/lleconomy.h
+++ b/indra/llinventory/lleconomy.h
@@ -42,18 +42,11 @@ class LLEconomyObserver
 	virtual void onEconomyDataChange() = 0;
 };
 
-class LLGlobalEconomy
+class LLBaseEconomy
 {
 public:
-	LLGlobalEconomy();
-	virtual ~LLGlobalEconomy();
-
-	// This class defines its singleton internally as a typedef instead of inheriting from
-	// LLSingleton like most others because the LLRegionEconomy sub-class might also
-	// become a singleton and this pattern will more easily disambiguate them.
-	typedef LLSingleton<LLGlobalEconomy> Singleton;
-
-	void initSingleton() { }
+	LLBaseEconomy();
+	virtual ~LLBaseEconomy();
 
 	virtual void print();
 
@@ -61,7 +54,7 @@ class LLGlobalEconomy
 	void	removeObserver(LLEconomyObserver* observer);
 	void	notifyObservers();
 
-	static void processEconomyData(LLMessageSystem *msg, LLGlobalEconomy* econ_data);
+	static void processEconomyData(LLMessageSystem *msg, LLBaseEconomy* econ_data);
 
 	S32		calculateTeleportCost(F32 distance) const;
 	S32		calculateLightRent(const LLVector3& object_size) const;
@@ -108,8 +101,12 @@ class LLGlobalEconomy
 	std::list<LLEconomyObserver*> mObservers;
 };
 
+class LLGlobalEconomy: public LLSingleton<LLGlobalEconomy>, public LLBaseEconomy
+{
+	LLSINGLETON_EMPTY_CTOR(LLGlobalEconomy);
+};
 
-class LLRegionEconomy : public LLGlobalEconomy
+class LLRegionEconomy : public LLBaseEconomy
 {
 public:
 	LLRegionEconomy();
diff --git a/indra/llinventory/llfoldertype.cpp b/indra/llinventory/llfoldertype.cpp
index 86aca77de894f8a4f49a1c3e34d5f6328d900185..b0daf639fad2c054e77f45b21584fa795f1fc585 100644
--- a/indra/llinventory/llfoldertype.cpp
+++ b/indra/llinventory/llfoldertype.cpp
@@ -51,8 +51,7 @@ struct FolderEntry : public LLDictionaryEntry
 class LLFolderDictionary : public LLSingleton<LLFolderDictionary>,
 						   public LLDictionary<LLFolderType::EType, FolderEntry>
 {
-public:
-	LLFolderDictionary();
+	LLSINGLETON(LLFolderDictionary);
 protected:
 	virtual LLFolderType::EType notFound() const
 	{
diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp
index 8807b36117047dd08658ebe9feeaec5ef0fb5993..d1e6807f52138a3fa5fd2ed6a64b5433d6a337b9 100644
--- a/indra/llinventory/llinventorytype.cpp
+++ b/indra/llinventory/llinventorytype.cpp
@@ -63,8 +63,7 @@ struct InventoryEntry : public LLDictionaryEntry
 class LLInventoryDictionary : public LLSingleton<LLInventoryDictionary>,
 							  public LLDictionary<LLInventoryType::EType, InventoryEntry>
 {
-public:
-	LLInventoryDictionary();
+	LLSINGLETON(LLInventoryDictionary);
 };
 
 LLInventoryDictionary::LLInventoryDictionary()
diff --git a/indra/llmessage/llcoproceduremanager.h b/indra/llmessage/llcoproceduremanager.h
index 497367b80cdc5713415a1cbd5f27320fcde950a8..7d0e83180ce1593dc3451b96be834f319e300c2e 100644
--- a/indra/llmessage/llcoproceduremanager.h
+++ b/indra/llmessage/llcoproceduremanager.h
@@ -37,7 +37,8 @@ class LLCoprocedurePool;
 
 class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
 {
-    friend class LLSingleton < LLCoprocedureManager > ;
+    LLSINGLETON(LLCoprocedureManager);
+    virtual ~LLCoprocedureManager();
 
 public:
     typedef boost::function<U32(const std::string &)> SettingQuery_t;
@@ -45,9 +46,6 @@ class LLCoprocedureManager : public LLSingleton < LLCoprocedureManager >
 
     typedef boost::function<void(LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t &, const LLUUID &id)> CoProcedure_t;
 
-    LLCoprocedureManager();
-    virtual ~LLCoprocedureManager();
-
     /// Places the coprocedure on the queue for processing. 
     /// 
     /// @param name Is used for debugging and should identify this coroutine.
diff --git a/indra/llmessage/llexperiencecache.h b/indra/llmessage/llexperiencecache.h
index 1002b33f801865acf6c7665cc65da017ecee7f78..8ee7080d3822ae52b9c288877c845540fccb9fd3 100644
--- a/indra/llmessage/llexperiencecache.h
+++ b/indra/llmessage/llexperiencecache.h
@@ -43,7 +43,7 @@ class LLUUID;
 
 class LLExperienceCache: public LLSingleton < LLExperienceCache >
 {
-    friend class LLSingleton < LLExperienceCache > ;
+    LLSINGLETON(LLExperienceCache);
 
 public:
     typedef boost::function<std::string(const std::string &)> CapabilityQuery_t;
@@ -103,7 +103,6 @@ class LLExperienceCache: public LLSingleton < LLExperienceCache >
     static const int PROPERTY_SUSPENDED;	// 1 << 7
 
 private:
-    LLExperienceCache();
     virtual ~LLExperienceCache();
 
     virtual void initSingleton();
diff --git a/indra/llmessage/llproxy.h b/indra/llmessage/llproxy.h
index bd23dd39defcb644ba2d904fd9c9748cf3d8c7ca..688dff7c8320916b9f2027f91f16d0cd6408867f 100644
--- a/indra/llmessage/llproxy.h
+++ b/indra/llmessage/llproxy.h
@@ -218,14 +218,14 @@ enum LLSocks5AuthType
  */
 class LLProxy: public LLSingleton<LLProxy>
 {
-	LOG_CLASS(LLProxy);
-public:
 	/*###########################################################################################
 	METHODS THAT DO NOT LOCK mProxyMutex!
 	###########################################################################################*/
 	// Constructor, cannot have parameters due to LLSingleton parent class. Call from main thread only.
-	LLProxy();
+	LLSINGLETON(LLProxy);
+	LOG_CLASS(LLProxy);
 
+public:
 	// Static check for enabled status for UDP packets. Call from main thread only.
 	static bool isSOCKSProxyEnabled() { return sUDPProxyEnabled; }
 
@@ -239,9 +239,11 @@ class LLProxy: public LLSingleton<LLProxy>
 	/*###########################################################################################
 	METHODS THAT LOCK mProxyMutex! DO NOT CALL WHILE mProxyMutex IS LOCKED!
 	###########################################################################################*/
+private:
 	// Destructor, closes open connections. Do not call directly, use cleanupClass().
 	~LLProxy();
 
+public:
 	// Delete LLProxy singleton. Allows the apr_socket used in the SOCKS 5 control channel to be
 	// destroyed before the call to apr_terminate. Call from main thread only.
 	static void cleanupClass();
diff --git a/indra/llmessage/message.cpp b/indra/llmessage/message.cpp
index 290b67feb3c46b7eb5470f285557e36d76c4879a..6ef4025ab1823bfa55f8f42a8cd44cb498a97107 100644
--- a/indra/llmessage/message.cpp
+++ b/indra/llmessage/message.cpp
@@ -76,6 +76,7 @@
 #include "v4math.h"
 #include "lltransfertargetvfile.h"
 #include "llcorehttputil.h"
+#include "llpounceable.h"
 
 // Constants
 //const char* MESSAGE_LOG_FILENAME = "message.log";
@@ -1724,7 +1725,9 @@ std::ostream& operator<<(std::ostream& s, LLMessageSystem &msg)
 	return s;
 }
 
-LLMessageSystem	*gMessageSystem = NULL;
+// LLPounceable supports callWhenReady(), to permit clients to queue up (e.g.)
+// callback registrations for when gMessageSystem is first assigned
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 
 // update appropriate ping info
 void	process_complete_ping_check(LLMessageSystem *msgsystem, void** /*user_data*/)
@@ -2641,7 +2644,7 @@ void end_messaging_system(bool print_summary)
 			LL_INFOS("Messaging") << str.str().c_str() << LL_ENDL;
 		}
 
-		delete gMessageSystem;
+		delete static_cast<LLMessageSystem*>(gMessageSystem);
 		gMessageSystem = NULL;
 	}
 }
diff --git a/indra/llmessage/message.h b/indra/llmessage/message.h
index 133db620e68541e6deec77506027384bdc328186..f6c5d9e228d8087ddbb0f985aa18f895d91b2973 100644
--- a/indra/llmessage/message.h
+++ b/indra/llmessage/message.h
@@ -60,6 +60,7 @@
 
 #include "llstoredmessage.h"
 #include "boost/function.hpp"
+#include "llpounceable.h"
 
 const U32 MESSAGE_MAX_STRINGS_LENGTH = 64;
 const U32 MESSAGE_NUMBER_OF_HASH_BUCKETS = 8192;
@@ -68,10 +69,10 @@ const S32 MESSAGE_MAX_PER_FRAME = 400;
 
 class LLMessageStringTable : public LLSingleton<LLMessageStringTable>
 {
-public:
-	LLMessageStringTable();
+	LLSINGLETON(LLMessageStringTable);
 	~LLMessageStringTable();
 
+public:
 	char *getString(const char *str);
 
 	U32	 mUsed;
@@ -832,7 +833,7 @@ class LLMessageSystem : public LLMessageSenderInterface
 
 
 // external hook into messaging system
-extern LLMessageSystem	*gMessageSystem;
+extern LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 
 // Must specific overall system version, which is used to determine
 // if a patch is available in the message template checksum verification.
diff --git a/indra/llmessage/tests/llhttpclient_test.cpp b/indra/llmessage/tests/llhttpclient_test.cpp
index a32bfa59ce8d046bf443c85d1e49cbd519e3a0d3..9356a14f1f89fd24a5ee6bc0047bf763c4744002 100644
--- a/indra/llmessage/tests/llhttpclient_test.cpp
+++ b/indra/llmessage/tests/llhttpclient_test.cpp
@@ -42,6 +42,7 @@
 
 #include "lliosocket.h"
 #include "stringize.h"
+#include "llcleanup.h"
 
 namespace tut
 {
@@ -66,7 +67,7 @@ namespace tut
 		~HTTPClientTestData()
 		{
 			delete mClientPump;
-			LLProxy::cleanupClass();
+			SUBSYSTEM_CLEANUP(LLProxy);
 			apr_pool_destroy(mPool);
 		}
 
diff --git a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
index 3b04530c1ac9e5bd98e596a4e9360c144a9f6d09..e20f61b73f8fddadfff14eaf397907ec8bc162e0 100644
--- a/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
+++ b/indra/llmessage/tests/lltemplatemessagedispatcher_test.cpp
@@ -31,11 +31,12 @@
 #include "llhost.h"
 #include "message.h"
 #include "llsd.h"
+#include "llpounceable.h"
 
 #include "llhost.cpp" // Needed for copy operator
 #include "net.cpp" // Needed by LLHost.
 
-LLMessageSystem * gMessageSystem = NULL;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 
 // sensor test doubles
 bool gClearRecvWasCalled = false;
diff --git a/indra/llmessage/tests/lltrustedmessageservice_test.cpp b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
index 55748ad27e36d2c4fc0c34fea63bea8bd6995f09..41f982a7e22668c70f5312e74967e64dddd1d210 100644
--- a/indra/llmessage/tests/lltrustedmessageservice_test.cpp
+++ b/indra/llmessage/tests/lltrustedmessageservice_test.cpp
@@ -33,8 +33,9 @@
 #include "message.h"
 #include "llmessageconfig.h"
 #include "llhttpnode_stub.cpp"
+#include "llpounceable.h"
 
-LLMessageSystem* gMessageSystem = NULL;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 
 LLMessageConfig::SenderTrust
 LLMessageConfig::getSenderTrustedness(const std::string& msg_name)
diff --git a/indra/llmessage/tests/networkio.h b/indra/llmessage/tests/networkio.h
index 5eb739393febf14f076be528964880636872fe5c..598652434233e5f1b2e4a90bec4df809cbd54fd5 100644
--- a/indra/llmessage/tests/networkio.h
+++ b/indra/llmessage/tests/networkio.h
@@ -44,7 +44,7 @@
 // init time. Use the lazy, on-demand initialization we get from LLSingleton.
 class NetworkIO: public LLSingleton<NetworkIO>
 {
-public:
+    LLSINGLETON(NetworkIO);
     NetworkIO():
         mServicePump(NULL),
         mDone(false)
@@ -69,6 +69,7 @@ class NetworkIO: public LLSingleton<NetworkIO>
                                                        boost::bind(&NetworkIO::done, this, _1));
     }
 
+public:
     bool pump(F32 timeout=10)
     {
         // Reset the done flag so we don't pop out prematurely
diff --git a/indra/llui/llclipboard.h b/indra/llui/llclipboard.h
index 58d80e26876419977f48b4f216dbb780a5a76609..a668ac1ac6cfe9a30963d58340127117d23be931 100644
--- a/indra/llui/llclipboard.h
+++ b/indra/llui/llclipboard.h
@@ -48,10 +48,10 @@
 
 class LLClipboard : public LLSingleton<LLClipboard>
 {
-public:
-	LLClipboard();
+	LLSINGLETON(LLClipboard);
 	~LLClipboard();
 	
+public:
 	// Clears the clipboard
 	void reset();
 	// Returns the state of the clipboard so client can know if it has been modified (comparing with tracked state)
diff --git a/indra/llui/llcommandmanager.h b/indra/llui/llcommandmanager.h
index f2f2145953c3f35820dbb6f2f6146fc69c39922a..8cec5e2b244e6d3e1b1dbdb32f3f711392675b5c 100644
--- a/indra/llui/llcommandmanager.h
+++ b/indra/llui/llcommandmanager.h
@@ -173,6 +173,9 @@ class LLCommand
 class LLCommandManager
 :	public LLSingleton<LLCommandManager>
 {
+	LLSINGLETON(LLCommandManager);
+	~LLCommandManager();
+
 public:
 	struct Params : public LLInitParam::Block<Params>
 	{
@@ -184,9 +187,6 @@ class LLCommandManager
 		}
 	};
 
-	LLCommandManager();
-	~LLCommandManager();
-
 	U32 commandCount() const;
 	LLCommand * getCommand(U32 commandIndex);
 	LLCommand * getCommand(const LLCommandId& commandId);
diff --git a/indra/llui/llcontainerview.h b/indra/llui/llcontainerview.h
index ac92b19977512043dc5e15ea2e0877f654742ea1..99267d978aa49f7c5283f846441bd15e81a7044c 100644
--- a/indra/llui/llcontainerview.h
+++ b/indra/llui/llcontainerview.h
@@ -35,7 +35,9 @@
 class LLScrollContainer;
 
 struct ContainerViewRegistry : public LLChildRegistry<ContainerViewRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(ContainerViewRegistry);
+};
 
 class LLContainerView : public LLView
 {
diff --git a/indra/llui/llfunctorregistry.h b/indra/llui/llfunctorregistry.h
index f5364f48636d12c81e7e9fe46e6052a5fcc2ffa5..e43974bc52fa9d44324538d05de1fadbb17a1340 100644
--- a/indra/llui/llfunctorregistry.h
+++ b/indra/llui/llfunctorregistry.h
@@ -53,14 +53,8 @@
 template <typename FUNCTOR_TYPE>
 class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 {
-	friend class LLSingleton<LLFunctorRegistry>;
+	LLSINGLETON(LLFunctorRegistry);
 	LOG_CLASS(LLFunctorRegistry);
-private:
-	LLFunctorRegistry() : LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing")
-	{
-		mMap[LOGFUNCTOR] = log_functor;
-		mMap[DONOTHING] = do_nothing;
-	}
 
 public:
 	typedef FUNCTOR_TYPE ResponseFunctor;
@@ -124,6 +118,14 @@ class LLFunctorRegistry : public LLSingleton<LLFunctorRegistry<FUNCTOR_TYPE> >
 	FunctorMap mMap;
 };
 
+template <typename FUNCTOR_TYPE>
+LLFunctorRegistry<FUNCTOR_TYPE>::LLFunctorRegistry() :
+	LOGFUNCTOR("LogFunctor"), DONOTHING("DoNothing")
+{
+	mMap[LOGFUNCTOR] = log_functor;
+	mMap[DONOTHING] = do_nothing;
+}
+
 template <typename FUNCTOR_TYPE>
 class LLFunctorRegistration
 {
diff --git a/indra/llui/lllayoutstack.h b/indra/llui/lllayoutstack.h
index a245ebe1b9cce788732535aa26a5c8e8ba9aaee3..f772dbc6b49940921d246c99080753f49f773291 100644
--- a/indra/llui/lllayoutstack.h
+++ b/indra/llui/lllayoutstack.h
@@ -40,7 +40,9 @@ class LLLayoutStack : public LLView, public LLInstanceTracker<LLLayoutStack>
 public:
 
 	struct LayoutStackRegistry : public LLChildRegistry<LayoutStackRegistry>
-	{};
+	{
+		LLSINGLETON_EMPTY_CTOR(LayoutStackRegistry);
+	};
 
 	struct Params : public LLInitParam::Block<Params, LLView::Params>
 	{
diff --git a/indra/llui/llmenugl.h b/indra/llui/llmenugl.h
index 628dedb906ed4c2b871c24f7e32fca22079664ec..c7f7f6848cd7fa186e7564a365f6616af817026d 100644
--- a/indra/llui/llmenugl.h
+++ b/indra/llui/llmenugl.h
@@ -347,7 +347,9 @@ class LLMenuItemCheckGL
 
 // child widget registry
 struct MenuRegistry : public LLChildRegistry<MenuRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(MenuRegistry);
+};
 
 
 class LLMenuGL 
diff --git a/indra/llui/llnotifications.h b/indra/llui/llnotifications.h
index 354add0b82a0e022bc8d64f8bb53d49c463bf48e..024332ee65c66fd624aa439ebdd4b68e6bd38c81 100644
--- a/indra/llui/llnotifications.h
+++ b/indra/llui/llnotifications.h
@@ -884,9 +884,9 @@ class LLNotifications :
 	public LLSingleton<LLNotifications>, 
 	public LLNotificationChannelBase
 {
+	LLSINGLETON(LLNotifications);
 	LOG_CLASS(LLNotifications);
 
-	friend class LLSingleton<LLNotifications>;
 public:
 
     // Needed to clear up RefCounted things prior to actual destruction
@@ -966,8 +966,6 @@ class LLNotifications :
 	bool isVisibleByRules(LLNotificationPtr pNotification);
 	
 private:
-	// we're a singleton, so we don't have a public constructor
-	LLNotifications();
 	/*virtual*/ void initSingleton();
 	
 	void loadPersistentNotifications();
diff --git a/indra/llui/llpanel.h b/indra/llui/llpanel.h
index c2185f24ded66e8c4b303eb0931bb86866980393..b8f47ef6badd427fdf00b03df3821278c99b0420 100644
--- a/indra/llui/llpanel.h
+++ b/indra/llui/llpanel.h
@@ -268,8 +268,9 @@ typedef boost::function<LLPanel* (void)> LLPanelClassCreatorFunc;
 class LLRegisterPanelClass
 :	public LLSingleton< LLRegisterPanelClass >
 {
+	LLSINGLETON_EMPTY_CTOR(LLRegisterPanelClass);
 public:
-	// reigister with either the provided builder, or the generic templated builder
+	// register with either the provided builder, or the generic templated builder
 	void addPanelClass(const std::string& tag,LLPanelClassCreatorFunc func)
 	{
 		mPanelClassesNames[tag] = func;
diff --git a/indra/llui/llresmgr.h b/indra/llui/llresmgr.h
index a652dcd2c06cf08bed409c7010a6d339ede7dc98..b19d8d40b89f48912284950d1c8bbe849304cbd7 100644
--- a/indra/llui/llresmgr.h
+++ b/indra/llui/llresmgr.h
@@ -42,9 +42,9 @@ enum LLLOCALE_ID
 
 class LLResMgr : public LLSingleton<LLResMgr>
 {
-public:
-	LLResMgr();
+	LLSINGLETON(LLResMgr);
 
+public:
 	void				setLocale( LLLOCALE_ID locale_id );
 	LLLOCALE_ID			getLocale() const						{ return mLocale; }
 
diff --git a/indra/llui/llscrollcontainer.h b/indra/llui/llscrollcontainer.h
index f64cf43a8ed48ce2c8863979535bdf4e3e5fd4b8..c4c4d0a136b7ba052bbccc951c7f49644a42a3ac 100644
--- a/indra/llui/llscrollcontainer.h
+++ b/indra/llui/llscrollcontainer.h
@@ -48,7 +48,9 @@ class LLUICtrlFactory;
  *****************************************************************************/
 
 struct ScrollContainerRegistry : public LLChildRegistry<ScrollContainerRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(ScrollContainerRegistry);
+};
 
 class LLScrollContainer : public LLUICtrl
 {
diff --git a/indra/llui/llspellcheck.h b/indra/llui/llspellcheck.h
index 4ab80195ead318f7f586563474d0f9fb5706d10d..acac589e433dd8d33c452641c1638bb751199559 100644
--- a/indra/llui/llspellcheck.h
+++ b/indra/llui/llspellcheck.h
@@ -29,16 +29,15 @@
 
 #include "llsingleton.h"
 #include "llui.h"
+#include "llinitdestroyclass.h"
 #include <boost/signals2.hpp>
 
 class Hunspell;
 
 class LLSpellChecker : public LLSingleton<LLSpellChecker>, public LLInitClass<LLSpellChecker>
 {
-	friend class LLSingleton<LLSpellChecker>;
+	LLSINGLETON(LLSpellChecker);
 	friend class LLInitClass<LLSpellChecker>;
-protected:
-	LLSpellChecker();
 	~LLSpellChecker();
 
 public:
diff --git a/indra/llui/llstatview.h b/indra/llui/llstatview.h
index bc78d3b5fdca9379bd0e8e1a01e0bea68fcafe1a..af4db7d7ea0a56f50ef8e64bf97e19637e477be4 100644
--- a/indra/llui/llstatview.h
+++ b/indra/llui/llstatview.h
@@ -35,7 +35,9 @@ class LLStatBar;
 
 // widget registrars
 struct StatViewRegistry : public LLChildRegistry<StatViewRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(StatViewRegistry);
+};
 
 class LLStatView : public LLContainerView
 {
diff --git a/indra/llui/lltextparser.h b/indra/llui/lltextparser.h
index 400aeeb8be78dd22d330a34f4b0a37dcf00fe890..3d71e40452d84342a708e0dd1db41553110432e5 100644
--- a/indra/llui/lltextparser.h
+++ b/indra/llui/lltextparser.h
@@ -37,14 +37,14 @@ class LLColor4;
 
 class LLTextParser : public LLSingleton<LLTextParser>
 {
+	LLSINGLETON(LLTextParser);
+
 public:
 	typedef enum e_condition_type { CONTAINS, MATCHES, STARTS_WITH, ENDS_WITH } EConditionType;
 	typedef enum e_highlight_type { PART, ALL } EHighlightType;
 	typedef enum e_highlight_position { WHOLE, START, MIDDLE, END } EHighlightPosition;
 	typedef enum e_dialog_action { ACTION_NONE, ACTION_CLOSE, ACTION_ADD, ACTION_COPY, ACTION_UPDATE } EDialogAction;
 
-	LLTextParser();
-
 	LLSD parsePartialLineHighlights(const std::string &text,const LLColor4 &color, EHighlightPosition part=WHOLE, S32 index=0);
 	bool parseFullLineHighlights(const std::string &text, LLColor4 *color);
 
diff --git a/indra/llui/lltooltip.h b/indra/llui/lltooltip.h
index fad127fc4cd440d980115bd66333c0ca2616d21b..0b1fbe536748946108178440b823c9421846c394 100644
--- a/indra/llui/lltooltip.h
+++ b/indra/llui/lltooltip.h
@@ -129,9 +129,10 @@ class LLInspector : public LLToolTip
 
 class LLToolTipMgr : public LLSingleton<LLToolTipMgr>
 {
+	LLSINGLETON(LLToolTipMgr);
 	LOG_CLASS(LLToolTipMgr);
+
 public:
-	LLToolTipMgr();
 	void show(const LLToolTip::Params& params);
 	void show(const std::string& message);
 
diff --git a/indra/llui/llui.cpp b/indra/llui/llui.cpp
index f790d8e005bf992a01e8d8b4e9836edc70988521..770f13c1c398d710266752010afaad60132eb150 100644
--- a/indra/llui/llui.cpp
+++ b/indra/llui/llui.cpp
@@ -60,6 +60,7 @@
 #include "llflyoutbutton.h"
 #include "llsearcheditor.h"
 #include "lltoolbar.h"
+#include "llcleanup.h"
 
 // for XUIParse
 #include "llquaternion.h"
@@ -208,7 +209,7 @@ void LLUI::initClass(const settings_map_t& settings,
 
 void LLUI::cleanupClass()
 {
-	LLRender2D::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLRender2D);
 }
 
 void LLUI::setPopupFuncs(const add_popup_t& add_popup, const remove_popup_t& remove_popup,  const clear_popups_t& clear_popups)
diff --git a/indra/llui/llui.h b/indra/llui/llui.h
index c727f75c4fa6a953f8abdc244ef05225f4c764e7..d7151dbee9939fd0ecf9af5d65e5646394e00833 100644
--- a/indra/llui/llui.h
+++ b/indra/llui/llui.h
@@ -344,95 +344,6 @@ class LLUI
 
 // Moved LLLocalClipRect to lllocalcliprect.h
 
-class LLCallbackRegistry
-{
-public:
-	typedef boost::signals2::signal<void()> callback_signal_t;
-	
-	void registerCallback(const callback_signal_t::slot_type& slot)
-	{
-		mCallbacks.connect(slot);
-	}
-
-	void fireCallbacks()
-	{
-		mCallbacks();
-	}
-
-private:
-	callback_signal_t mCallbacks;
-};
-
-class LLInitClassList : 
-	public LLCallbackRegistry, 
-	public LLSingleton<LLInitClassList>
-{
-	friend class LLSingleton<LLInitClassList>;
-private:
-	LLInitClassList() {}
-};
-
-class LLDestroyClassList : 
-	public LLCallbackRegistry, 
-	public LLSingleton<LLDestroyClassList>
-{
-	friend class LLSingleton<LLDestroyClassList>;
-private:
-	LLDestroyClassList() {}
-};
-
-template<typename T>
-class LLRegisterWith
-{
-public:
-	LLRegisterWith(boost::function<void ()> func)
-	{
-		T::instance().registerCallback(func);
-	}
-
-	// this avoids a MSVC bug where non-referenced static members are "optimized" away
-	// even if their constructors have side effects
-	S32 reference()
-	{
-		S32 dummy;
-		dummy = 0;
-		return dummy;
-	}
-};
-
-template<typename T>
-class LLInitClass
-{
-public:
-	LLInitClass() { sRegister.reference(); }
-
-	static LLRegisterWith<LLInitClassList> sRegister;
-private:
-
-	static void initClass()
-	{
-		LL_ERRS() << "No static initClass() method defined for " << typeid(T).name() << LL_ENDL;
-	}
-};
-
-template<typename T>
-class LLDestroyClass
-{
-public:
-	LLDestroyClass() { sRegister.reference(); }
-
-	static LLRegisterWith<LLDestroyClassList> sRegister;
-private:
-
-	static void destroyClass()
-	{
-		LL_ERRS() << "No static destroyClass() method defined for " << typeid(T).name() << LL_ENDL;
-	}
-};
-
-template <typename T> LLRegisterWith<LLInitClassList> LLInitClass<T>::sRegister(&T::initClass);
-template <typename T> LLRegisterWith<LLDestroyClassList> LLDestroyClass<T>::sRegister(&T::destroyClass);
-
 // useful parameter blocks
 struct TimeIntervalParam : public LLInitParam::ChoiceBlock<TimeIntervalParam>
 {
diff --git a/indra/llui/lluicolortable.h b/indra/llui/lluicolortable.h
index 6a7a681d57a005775764cda908c343023439ea82..44472070cc4f4249d1dc1c7daebc21bcd4089f4f 100644
--- a/indra/llui/lluicolortable.h
+++ b/indra/llui/lluicolortable.h
@@ -38,7 +38,8 @@ class LLUIColor;
 
 class LLUIColorTable : public LLSingleton<LLUIColorTable>
 {
-LOG_CLASS(LLUIColorTable);
+	LLSINGLETON_EMPTY_CTOR(LLUIColorTable);
+	LOG_CLASS(LLUIColorTable);
 
 	// consider using sorted vector, can be much faster
 	typedef std::map<std::string, LLUIColor>  string_color_map_t;
diff --git a/indra/llui/lluictrl.h b/indra/llui/lluictrl.h
index 99553ee0d26c701fb042895c54c15d6a7d987498..550bee5c709e7989e0506a3fa1ee3814faba1435 100644
--- a/indra/llui/lluictrl.h
+++ b/indra/llui/lluictrl.h
@@ -258,18 +258,25 @@ class LLUICtrl
 
 	class LLTextInputFilter : public LLQueryFilter, public LLSingleton<LLTextInputFilter>
 	{
+		LLSINGLETON_EMPTY_CTOR(LLTextInputFilter);
 		/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const 
 		{
 			return filterResult_t(view->isCtrl() && static_cast<const LLUICtrl *>(view)->acceptsTextInput(), TRUE);
 		}
 	};
-	
+
 	template <typename F, typename DERIVED> class CallbackRegistry : public LLRegistrySingleton<std::string, F, DERIVED >
 	{};	
 
-	class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>{};
+	class CommitCallbackRegistry : public CallbackRegistry<commit_callback_t, CommitCallbackRegistry>
+	{
+		LLSINGLETON_EMPTY_CTOR(CommitCallbackRegistry);
+	};
 	// the enable callback registry is also used for visiblity callbacks
-	class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>{};
+	class EnableCallbackRegistry : public CallbackRegistry<enable_callback_t, EnableCallbackRegistry>
+	{
+		LLSINGLETON_EMPTY_CTOR(EnableCallbackRegistry);
+	};
 		
 protected:
 
diff --git a/indra/llui/lluictrlfactory.h b/indra/llui/lluictrlfactory.h
index 3ce39c947f7e87f90fcc69f98f6aec82864b8dbf..03d946f1b7729e6cc9808ba78529e5abc06b0877 100644
--- a/indra/llui/lluictrlfactory.h
+++ b/indra/llui/lluictrlfactory.h
@@ -33,6 +33,8 @@
 #include "llxuiparser.h"
 #include "llstl.h"
 #include "lldir.h"
+#include "llsingleton.h"
+#include "llheteromap.h"
 
 class LLView;
 
@@ -57,22 +59,24 @@ class LLChildRegistry : public LLRegistrySingleton<std::string, LLWidgetCreatorF
 
 class LLDefaultChildRegistry : public LLChildRegistry<LLDefaultChildRegistry>
 {
-protected:
-	LLDefaultChildRegistry(){}
-	friend class LLSingleton<LLDefaultChildRegistry>;
+	LLSINGLETON_EMPTY_CTOR(LLDefaultChildRegistry);
 };
 
 // lookup widget name by type
 class LLWidgetNameRegistry 
 :	public LLRegistrySingleton<const std::type_info*, std::string, LLWidgetNameRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(LLWidgetNameRegistry);
+};
 
 // lookup function for generating empty param block by widget type
 // this is used for schema generation
 //typedef const LLInitParam::BaseBlock& (*empty_param_block_func_t)();
 //class LLDefaultParamBlockRegistry
 //:	public LLRegistrySingleton<const std::type_info*, empty_param_block_func_t, LLDefaultParamBlockRegistry>
-//{};
+//{
+//	LLSINGLETON(LLDefaultParamBlockRegistry);
+//};
 
 extern LLTrace::BlockTimerStatHandle FTM_WIDGET_SETUP;
 extern LLTrace::BlockTimerStatHandle FTM_WIDGET_CONSTRUCTION;
@@ -85,31 +89,15 @@ extern template class LLUICtrlFactory* LLSingleton<class LLUICtrlFactory>::getIn
 
 class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 {
-private:
-	friend class LLSingleton<LLUICtrlFactory>;
-	LLUICtrlFactory();
+	LLSINGLETON(LLUICtrlFactory);
 	~LLUICtrlFactory();
 
 	// only partial specialization allowed in inner classes, so use extra dummy parameter
 	template <typename PARAM_BLOCK, int DUMMY>
-	class ParamDefaults : public LLSingleton<ParamDefaults<PARAM_BLOCK, DUMMY> > 
+	class ParamDefaults
 	{
 	public:
-		ParamDefaults()
-		{
-			// look up template file for this param block...
-			const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
-			if (param_block_tag)
-			{	// ...and if it exists, back fill values using the most specific template first
-				PARAM_BLOCK params;
-				LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params);
-				mPrototype.fillFrom(params);
-			}
-			// recursively fill from base class param block
-			((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY>::instance().get());
-
-		}
-
+		ParamDefaults();
 		const PARAM_BLOCK& get() { return mPrototype; }
 
 	private:
@@ -118,9 +106,10 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 
 	// base case for recursion, there are NO base classes of LLInitParam::BaseBlock
 	template<int DUMMY>
-	class ParamDefaults<LLInitParam::BaseBlock, DUMMY> : public LLSingleton<ParamDefaults<LLInitParam::BaseBlock, DUMMY> >
+	class ParamDefaults<LLInitParam::BaseBlock, DUMMY>
 	{
 	public:
+		ParamDefaults();
 		const LLInitParam::BaseBlock& get() { return mBaseBlock; }
 	private:
 		LLInitParam::BaseBlock mBaseBlock;
@@ -132,7 +121,7 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	template<typename T>
 	static const typename T::Params& getDefaultParams()
 	{
-		return ParamDefaults<typename T::Params, 0>::instance().get();
+		return instance().mParamDefaultsMap.obtain< ParamDefaults<typename T::Params, 0> >().get();
 	}
 
 	// Does what you want for LLFloaters and LLPanels
@@ -147,7 +136,8 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 	template<typename T>
 	static T* create(typename T::Params& params, LLView* parent = NULL)
 	{
-		params.fillFrom(ParamDefaults<typename T::Params, 0>::instance().get());
+		params.fillFrom(instance().mParamDefaultsMap.obtain<
+						ParamDefaults<typename T::Params, 0> >().get());
 
 		T* widget = createWidgetImpl<T>(params, parent);
 		if (widget)
@@ -295,8 +285,40 @@ class LLUICtrlFactory : public LLSingleton<LLUICtrlFactory>
 
 	class LLPanel*		mDummyPanel;
 	std::vector<std::string>	mFileNames;
+
+	// store ParamDefaults specializations
+	// Each ParamDefaults specialization used to be an LLSingleton in its own
+	// right. But the 2016 changes to the LLSingleton mechanism, making
+	// LLSingleton instances polymorphic, are incompatible with current
+	// LLInitParam::BaseBlock functionality. (Thanks NickyD for spotting
+	// that!) Moreover, instances of the private nested ParamDefaults template
+	// aren't global resources -- which is what LLSingleton is designed for.
+	// This is simply a cache looked up by type. Its lifespan is tied to
+	// LLUICtrlFactory. Use LLHeteroMap for this cache.
+	LLHeteroMap mParamDefaultsMap;
 };
 
+template <typename PARAM_BLOCK, int DUMMY>
+LLUICtrlFactory::ParamDefaults<PARAM_BLOCK, DUMMY>::ParamDefaults()
+{
+	// look up template file for this param block...
+	const std::string* param_block_tag = LLWidgetNameRegistry::instance().getValue(&typeid(PARAM_BLOCK));
+	if (param_block_tag)
+	{	// ...and if it exists, back fill values using the most specific template first
+		PARAM_BLOCK params;
+		LLUICtrlFactory::loadWidgetTemplate(*param_block_tag, params);
+		mPrototype.fillFrom(params);
+	}
+	// recursively fill from base class param block
+	((typename PARAM_BLOCK::base_block_t&)mPrototype).fillFrom(
+		LLUICtrlFactory::instance().mParamDefaultsMap.obtain<
+		ParamDefaults<typename PARAM_BLOCK::base_block_t, DUMMY> >().get());
+
+}
+
+template <int DUMMY>
+LLUICtrlFactory::ParamDefaults<LLInitParam::BaseBlock, DUMMY>::ParamDefaults() {}
+
 // this is here to make gcc happy with reference to LLUICtrlFactory
 template<typename DERIVED>
 template<typename T> 
diff --git a/indra/llui/llurlregistry.h b/indra/llui/llurlregistry.h
index 24c3a2b513c3826fa11ffbd07976146f1f0e77c4..efafe543abc65278835b292d6195bdecc561221f 100644
--- a/indra/llui/llurlregistry.h
+++ b/indra/llui/llurlregistry.h
@@ -62,9 +62,9 @@ void LLUrlRegistryNullCallback(const std::string &url,
 ///
 class LLUrlRegistry : public LLSingleton<LLUrlRegistry>
 {
-public:
+	LLSINGLETON(LLUrlRegistry);
 	~LLUrlRegistry();
-
+public:
 	/// add a new Url handler to the registry (will be freed on destruction)
 	/// optionally force it to the front of the list, making it take
 	/// priority over other regular expression matches for URLs
@@ -89,9 +89,6 @@ class LLUrlRegistry : public LLSingleton<LLUrlRegistry>
 	bool isUrl(const LLWString &text);
 
 private:
-	LLUrlRegistry();
-	friend class LLSingleton<LLUrlRegistry>;
-
 	std::vector<LLUrlEntryBase *> mUrlEntry;
 	LLUrlEntryBase*	mUrlEntryTrusted;
 	LLUrlEntryBase*	mUrlEntryIcon;
diff --git a/indra/llui/llview.cpp b/indra/llui/llview.cpp
index 9604e5ce10e38d435b46b00f895a03d0abd0bdbe..89ad8138d89749cdbee477ef540f98edf7f1ec57 100644
--- a/indra/llui/llview.cpp
+++ b/indra/llui/llview.cpp
@@ -1912,6 +1912,7 @@ class CompareByTabOrder
 
 class SortByTabOrder : public LLQuerySorter, public LLSingleton<SortByTabOrder>
 {
+	LLSINGLETON_EMPTY_CTOR(SortByTabOrder);
 	/*virtual*/ void sort(LLView * parent, LLView::child_list_t &children) const 
 	{
 		children.sort(CompareByTabOrder(parent->getTabOrder(), parent->getDefaultTabGroup()));
@@ -1935,6 +1936,7 @@ const LLViewQuery & LLView::getTabOrderQuery()
 // This class is only used internally by getFocusRootsQuery below. 
 class LLFocusRootsFilter : public LLQueryFilter, public LLSingleton<LLFocusRootsFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLFocusRootsFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const 
 	{
 		return filterResult_t(view->isCtrl() && view->isFocusRoot(), !view->isFocusRoot());
diff --git a/indra/llui/llviewereventrecorder.h b/indra/llui/llviewereventrecorder.h
index 375efcc3de870ab83ca2c8590fa651dafdebc18d..d1059d55deb75bdfecbc46b83cc44711e66ad013 100644
--- a/indra/llui/llviewereventrecorder.h
+++ b/indra/llui/llviewereventrecorder.h
@@ -44,13 +44,10 @@
 
 class LLViewerEventRecorder : public LLSingleton<LLViewerEventRecorder>
 {
-
- public:
-
-  LLViewerEventRecorder(); // TODO Protect constructor better if we can (not happy in private section) - could add a factory... - we are singleton
+  LLSINGLETON(LLViewerEventRecorder);
   ~LLViewerEventRecorder();
 
-
+ public:
   void updateMouseEventInfo(S32 local_x,S32 local_y, S32 global_x, S32 global_y,  std::string mName);
   void setMouseLocalCoords(S32 x,S32 y);
   void setMouseGlobalCoords(S32 x,S32 y);
diff --git a/indra/llui/llviewquery.h b/indra/llui/llviewquery.h
index 9044c4ff29c16d7d016e4f9853ff834ca67d9b9b..21bb1be26f8d5c86a17e19c569446d79ecbebf8d 100644
--- a/indra/llui/llviewquery.h
+++ b/indra/llui/llviewquery.h
@@ -54,31 +54,37 @@ class LLQuerySorter
 
 class LLLeavesFilter : public LLQueryFilter, public LLSingleton<LLLeavesFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLLeavesFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
 class LLRootsFilter : public LLQueryFilter, public LLSingleton<LLRootsFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLRootsFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
 class LLVisibleFilter : public LLQueryFilter, public LLSingleton<LLVisibleFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLVisibleFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
 class LLEnabledFilter : public LLQueryFilter, public LLSingleton<LLEnabledFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLEnabledFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
 class LLTabStopFilter : public LLQueryFilter, public LLSingleton<LLTabStopFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLTabStopFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
 class LLCtrlFilter : public LLQueryFilter, public LLSingleton<LLCtrlFilter>
 {
+	LLSINGLETON_EMPTY_CTOR(LLCtrlFilter);
 	/*virtual*/ filterResult_t operator() (const LLView* const view, const viewList_t & children) const;
 };
 
diff --git a/indra/llui/llxuiparser.h b/indra/llui/llxuiparser.h
index bb11a23938df0c17616da614eb492b6797b57002..eb0eac8194def07f180a18aa5d758ecd3b49ce21 100644
--- a/indra/llui/llxuiparser.h
+++ b/indra/llui/llxuiparser.h
@@ -41,7 +41,9 @@ class LLView;
 // lookup widget type by name
 class LLWidgetTypeRegistry
 :	public LLRegistrySingleton<std::string, const std::type_info*, LLWidgetTypeRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(LLWidgetTypeRegistry);
+};
 
 
 // global static instance for registering all widget types
@@ -51,7 +53,9 @@ typedef LLRegistry<std::string, LLWidgetCreatorFunc> widget_registry_t;
 
 class LLChildRegistryRegistry
 : public LLRegistrySingleton<const std::type_info*, widget_registry_t, LLChildRegistryRegistry>
-{};
+{
+	LLSINGLETON_EMPTY_CTOR(LLChildRegistryRegistry);
+};
 
 class LLXSDWriter : public LLInitParam::Parser
 {
diff --git a/indra/llui/tests/llurlentry_stub.cpp b/indra/llui/tests/llurlentry_stub.cpp
old mode 100644
new mode 100755
index f01178c374c6fac0c30026c6c9100979e5d7842c..338be1808dd84d174d0293c15a93e8c740f9f944
--- a/indra/llui/tests/llurlentry_stub.cpp
+++ b/indra/llui/tests/llurlentry_stub.cpp
@@ -31,6 +31,7 @@
 #include "llcachename.h"
 #include "lluuid.h"
 #include "message.h"
+#include "llpounceable.h"
 
 #include <string>
 
@@ -165,7 +166,7 @@ LLFontGL* LLFontGL::getFontDefault()
 char const* const _PREHASH_AgentData = (char *)"AgentData";
 char const* const _PREHASH_AgentID = (char *)"AgentID";
 
-LLMessageSystem* gMessageSystem = NULL;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 
 //
 // Stub implementation for LLMessageSystem
diff --git a/indra/media_plugins/cef/windows_volume_catcher.cpp b/indra/media_plugins/cef/windows_volume_catcher.cpp
index 0cfb810906b578e4ae3466b32ca0a8c808dd9132..c9ea3ed5979af835b4a556e4a7ecac5fbd677d29 100644
--- a/indra/media_plugins/cef/windows_volume_catcher.cpp
+++ b/indra/media_plugins/cef/windows_volume_catcher.cpp
@@ -31,17 +31,16 @@
 #include "llsingleton.h"
 class VolumeCatcherImpl : public LLSingleton<VolumeCatcherImpl>
 {
-friend LLSingleton<VolumeCatcherImpl>;
+	LLSINGLETON(VolumeCatcherImpl);
+	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
+	~VolumeCatcherImpl();
+
 public:
 
 	void setVolume(F32 volume);
 	void setPan(F32 pan);
 	
 private:
-	// This is a singleton class -- both callers and the component implementation should use getInstance() to find the instance.
-	VolumeCatcherImpl();
-	~VolumeCatcherImpl();
-
 	typedef void (WINAPI *set_volume_func_t)(F32);
 	typedef void (WINAPI *set_mute_func_t)(bool);
 
diff --git a/indra/newview/llaccountingcostmanager.h b/indra/newview/llaccountingcostmanager.h
index f251ceffd47694742ea1cc671713a5b40ad61349..55e1d19f05f45a298f070bdc01c7108efe01d5bc 100644
--- a/indra/newview/llaccountingcostmanager.h
+++ b/indra/newview/llaccountingcostmanager.h
@@ -58,9 +58,9 @@ class LLAccountingCostObserver
 //===============================================================================
 class LLAccountingCostManager : public LLSingleton<LLAccountingCostManager>
 {
+	LLSINGLETON(LLAccountingCostManager);
+
 public:
-	//Ctor
-	LLAccountingCostManager();
 	//Store an object that will be eventually fetched
 	void addObject( const LLUUID& objectID );
 	//Request quotas for object list
diff --git a/indra/newview/llagentpicksinfo.h b/indra/newview/llagentpicksinfo.h
index abf7027ed22cadd79cc0a5c0ca4526415a796c5a..f981e08ff7715c6b7d60e602a9a2873d6b7db27f 100644
--- a/indra/newview/llagentpicksinfo.h
+++ b/indra/newview/llagentpicksinfo.h
@@ -36,14 +36,12 @@ struct LLAvatarPicks;
  */
 class LLAgentPicksInfo : public LLSingleton<LLAgentPicksInfo>
 {
+	LLSINGLETON(LLAgentPicksInfo);
+	virtual ~LLAgentPicksInfo();
+
 	class LLAgentPicksObserver;
 
 public:
-
-	LLAgentPicksInfo();
-	
-	virtual ~LLAgentPicksInfo();
-
 	/**
 	 * Requests number of picks from server. 
 	 * 
diff --git a/indra/newview/llagentwearables.h b/indra/newview/llagentwearables.h
index b27698fd8f7110187ca3fa2b614f2357d7c27a5e..27102629104216d6e612d21cc484914c0b68fe83 100644
--- a/indra/newview/llagentwearables.h
+++ b/indra/newview/llagentwearables.h
@@ -38,6 +38,7 @@
 #include "llviewerinventory.h"
 #include "llavatarappearancedefines.h"
 #include "llwearabledata.h"
+#include "llinitdestroyclass.h"
 
 class LLInventoryItem;
 class LLVOAvatarSelf;
diff --git a/indra/newview/llappearancemgr.cpp b/indra/newview/llappearancemgr.cpp
index 92e3cd02791ae4c793660910a78acb56213a24e4..2d84251da0809dbff29cdb9b5cf7d2759434b9db 100644
--- a/indra/newview/llappearancemgr.cpp
+++ b/indra/newview/llappearancemgr.cpp
@@ -3942,7 +3942,6 @@ LLAppearanceMgr::LLAppearanceMgr():
 	mAttachmentInvLinkEnabled(false),
 	mOutfitIsDirty(false),
 	mOutfitLocked(false),
-	mInFlightCounter(0),
 	mInFlightTimer(),
 	mIsInUpdateAppearanceFromCOF(false),
     mOutstandingAppearanceBakeRequest(false),
diff --git a/indra/newview/llappearancemgr.h b/indra/newview/llappearancemgr.h
index f0d3f80f5966870f47eca8247221b7aa160c70e1..5948dd870c1235a4483a798bb134229951e2f950 100644
--- a/indra/newview/llappearancemgr.h
+++ b/indra/newview/llappearancemgr.h
@@ -42,9 +42,10 @@ class LLOutfitUnLockTimer;
 
 class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 {
+	LLSINGLETON(LLAppearanceMgr);
+	~LLAppearanceMgr();
 	LOG_CLASS(LLAppearanceMgr);
 
-	friend class LLSingleton<LLAppearanceMgr>;
 	friend class LLOutfitUnLockTimer;
 	
 public:
@@ -241,10 +242,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
     static void debugAppearanceUpdateCOF(const LLSD& content);
 
 	std::string		mAppearanceServiceURL;
-	
-protected:
-	LLAppearanceMgr();
-	~LLAppearanceMgr();
 
 private:
 
@@ -272,7 +269,6 @@ class LLAppearanceMgr: public LLSingleton<LLAppearanceMgr>
 	 * to avoid unsynchronized outfit state or performing duplicate operations.
 	 */
 	bool mOutfitLocked;
-	S32  mInFlightCounter;
 	LLTimer mInFlightTimer;
 	static bool mActive;
 
diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp
index 9db03a74381a9fbd58a485b3cc42ba162f0c1dea..dac1da6ad1d11ad33323595dc72d2929903211cf 100644
--- a/indra/newview/llappviewer.cpp
+++ b/indra/newview/llappviewer.cpp
@@ -233,6 +233,7 @@
 #include "llsecapi.h"
 #include "llmachineid.h"
 #include "llmainlooprepeater.h"
+#include "llcleanup.h"
 
 #include "llcoproceduremanager.h"
 #include "llviewereventrecorder.h"
@@ -387,6 +388,7 @@ const char* const VIEWER_WINDOW_CLASSNAME = "Second Life";
  */
 class LLDeferredTaskList: public LLSingleton<LLDeferredTaskList>
 {
+	LLSINGLETON_EMPTY_CTOR(LLDeferredTaskList);
 	LOG_CLASS(LLDeferredTaskList);
 
 	friend class LLAppViewer;
@@ -737,7 +739,7 @@ LLAppViewer::LLAppViewer()
 LLAppViewer::~LLAppViewer()
 {
 	delete mSettingsLocationList;
-	LLViewerEventRecorder::instance().~LLViewerEventRecorder();
+	LLViewerEventRecorder::deleteSingleton();
 
 	LLLoginInstance::instance().setUpdaterService(0);
 	
@@ -1743,7 +1745,7 @@ bool LLAppViewer::cleanup()
 	gTransferManager.cleanup();
 #endif
 
-	LLLocalBitmapMgr::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLLocalBitmapMgr);
 
 	// Note: this is where gWorldMap used to be deleted.
 
@@ -1852,11 +1854,11 @@ bool LLAppViewer::cleanup()
 	
 	LLViewerObject::cleanupVOClasses();
 
-	LLAvatarAppearance::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLAvatarAppearance);
 	
-	LLAvatarAppearance::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLAvatarAppearance);
 	
-	LLPostProcess::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLPostProcess);
 
 	LLTracker::cleanupInstance();
 	
@@ -1882,12 +1884,12 @@ bool LLAppViewer::cleanup()
 
  	//end_messaging_system();
 
-	LLFollowCamMgr::cleanupClass();
-	//LLVolumeMgr::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLFollowCamMgr);
+	//SUBSYSTEM_CLEANUP(LLVolumeMgr);
 	LLPrimitive::cleanupVolumeManager();
-	LLWorldMapView::cleanupClass();
-	LLFolderViewItem::cleanupClass();
-	LLUI::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLWorldMapView);
+	SUBSYSTEM_CLEANUP(LLFolderViewItem);
+	SUBSYSTEM_CLEANUP(LLUI);
 	
 	//
 	// Shut down the VFS's AFTER the decode manager cleans up (since it cleans up vfiles).
@@ -1896,7 +1898,7 @@ bool LLAppViewer::cleanup()
 
 	//
 	LL_INFOS() << "Cleaning up VFS" << LL_ENDL;
-	LLVFile::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLVFile);
 
 	LL_INFOS() << "Saving Data" << LL_ENDL;
 	
@@ -1999,9 +2001,9 @@ bool LLAppViewer::cleanup()
 	// Non-LLCurl libcurl library
 	mAppCoreHttp.cleanup();
 
-	LLFilePickerThread::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLFilePickerThread);
 
-	//MUST happen AFTER LLCurl::cleanupClass
+	//MUST happen AFTER SUBSYSTEM_CLEANUP(LLCurl)
 	delete sTextureCache;
     sTextureCache = NULL;
 	delete sTextureFetch;
@@ -2025,22 +2027,22 @@ bool LLAppViewer::cleanup()
 			gDirUtilp->getExpandedFilename(LL_PATH_LOGS, report_name));
 	}	
 
-	LLMetricPerformanceTesterBasic::cleanClass() ;
+	SUBSYSTEM_CLEANUP(LLMetricPerformanceTesterBasic) ;
 
 	LL_INFOS() << "Cleaning up Media and Textures" << LL_ENDL;
 
 	//Note:
-	//LLViewerMedia::cleanupClass() has to be put before gTextureList.shutdown()
+	//SUBSYSTEM_CLEANUP(LLViewerMedia) has to be put before gTextureList.shutdown()
 	//because some new image might be generated during cleaning up media. --bao
-	LLViewerMedia::cleanupClass();
-	LLViewerParcelMedia::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLViewerMedia);
+	SUBSYSTEM_CLEANUP(LLViewerParcelMedia);
 	gTextureList.shutdown(); // shutdown again in case a callback added something
 	LLUIImageList::getInstance()->cleanUp();
 	
 	// This should eventually be done in LLAppViewer
-	LLImage::cleanupClass();
-	LLVFSThread::cleanupClass();
-	LLLFSThread::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLImage);
+	SUBSYSTEM_CLEANUP(LLVFSThread);
+	SUBSYSTEM_CLEANUP(LLLFSThread);
 
 #ifndef LL_RELEASE_FOR_DOWNLOAD
 	LL_INFOS() << "Auditing VFS" << LL_ENDL;
@@ -2083,10 +2085,10 @@ bool LLAppViewer::cleanup()
 		LL_INFOS() << "File launched." << LL_ENDL;
 	}
 	LL_INFOS() << "Cleaning up LLProxy." << LL_ENDL;
-	LLProxy::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLProxy);
     LLCore::LLHttp::cleanup();
 
-	LLWearableType::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLWearableType);
 
 	LLMainLoopRepeater::instance().stop();
 
@@ -2098,10 +2100,34 @@ bool LLAppViewer::cleanup()
 	LLError::LLCallStacks::cleanup();
 
 	removeMarkerFiles();
-	
-    LL_INFOS() << "Goodbye!" << LL_ENDL;
 
-    removeDumpDir();
+	// It's not at first obvious where, in this long sequence, generic cleanup
+	// calls OUGHT to go. So let's say this: as we migrate cleanup from
+	// explicit hand-placed calls into the generic mechanism, eventually
+	// all cleanup will get subsumed into the generic calls. So the calls you
+	// still see above are calls that MUST happen before the generic cleanup
+	// kicks in.
+    
+	// This calls every remaining LLSingleton's cleanupSingleton() method.
+	// This method should perform any cleanup that might take significant
+	// realtime, or might throw an exception.
+	LLSingletonBase::cleanupAll();
+
+	// This calls every remaining LLSingleton's deleteSingleton() method.
+	// No class destructor should perform any cleanup that might take
+	// significant realtime, or throw an exception.
+	// LLSingleton machinery includes a last-gasp implicit deleteAll() call,
+	// so this explicit call shouldn't strictly be necessary. However, by the
+	// time the runtime engages that implicit call, it may already have
+	// destroyed things like std::cerr -- so the implicit deleteAll() refrains
+	// from logging anything. Since both cleanupAll() and deleteAll() call
+	// their respective cleanup methods in computed dependency order, it's
+	// probably useful to be able to log that order.
+	LLSingletonBase::deleteAll();
+
+	LL_INFOS() << "Goodbye!" << LL_ENDL;
+
+	removeDumpDir();
 
 	// return 0;
 	return true;
@@ -5496,9 +5522,12 @@ void LLAppViewer::disconnectViewer()
 	}
 
 	saveNameCache();
-    LLExperienceCache *expCache = LLExperienceCache::getIfExists();
-    if (expCache)
-        expCache->cleanup();
+	if (LLExperienceCache::instanceExists())
+	{
+		// TODO: LLExperienceCache::cleanup() logic should be moved to
+		// cleanupSingleton().
+		LLExperienceCache::instance().cleanup();
+	}
 
 	// close inventory interface, close all windows
 	LLFloaterInventory::cleanup();
diff --git a/indra/newview/llattachmentsmgr.h b/indra/newview/llattachmentsmgr.h
index bb7d35edbcb740fab527b167831093b0f2a9acb5..a4ef762e8b1b07a02efb185426c766b31739cfd1 100644
--- a/indra/newview/llattachmentsmgr.h
+++ b/indra/newview/llattachmentsmgr.h
@@ -62,6 +62,9 @@ class LLViewerInventoryItem;
 //--------------------------------------------------------------------------------
 class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
 {
+    LLSINGLETON(LLAttachmentsMgr);
+	virtual ~LLAttachmentsMgr();
+
 public:
     // Stores info for attachments that will be requested during idle.
 	struct AttachmentsInfo
@@ -72,9 +75,6 @@ class LLAttachmentsMgr: public LLSingleton<LLAttachmentsMgr>
 	};
 	typedef std::deque<AttachmentsInfo> attachments_vec_t;
 
-	LLAttachmentsMgr();
-	virtual ~LLAttachmentsMgr();
-
 	void addAttachmentRequest(const LLUUID& item_id,
                               const U8 attachment_pt,
                               const BOOL add);
diff --git a/indra/newview/llautoreplace.h b/indra/newview/llautoreplace.h
index 9eecc2d9814911608793d5195a72a7e202e1cdaf..23cc3136468575a3ce1dce365cc4cb525c94c28e 100644
--- a/indra/newview/llautoreplace.h
+++ b/indra/newview/llautoreplace.h
@@ -191,6 +191,7 @@ class LLAutoReplaceSettings
  */
 class LLAutoReplace : public LLSingleton<LLAutoReplace>
 {
+    LLSINGLETON(LLAutoReplace);
 public:
     /// Callback that provides the hook for use in text entry methods
     void autoreplaceCallback(S32& replacement_start, S32& replacement_length, LLWString& replacement_string, S32& cursor_pos, const LLWString& input_text);
@@ -202,8 +203,6 @@ class LLAutoReplace : public LLSingleton<LLAutoReplace>
     void setSettings(const LLAutoReplaceSettings& settings);
 
 private:
-    friend class LLSingleton<LLAutoReplace>;
-    LLAutoReplace();
     /*virtual*/ void initSingleton();
 
     LLAutoReplaceSettings mSettings; ///< configuration information
diff --git a/indra/newview/llavataractions.cpp b/indra/newview/llavataractions.cpp
index 7b8c630837264c7baccad48150f8616043140c00..36e95c07f4d3ae2edd2d14b85395987b287e02c2 100644
--- a/indra/newview/llavataractions.cpp
+++ b/indra/newview/llavataractions.cpp
@@ -689,6 +689,8 @@ namespace action_give_inventory
 
 	struct LLShareInfo : public LLSingleton<LLShareInfo>
 	{
+		LLSINGLETON_EMPTY_CTOR(LLShareInfo);
+	public:
 		std::vector<LLAvatarName> mAvatarNames;
 		uuid_vec_t mAvatarUuids;
 	};
diff --git a/indra/newview/llavatariconctrl.h b/indra/newview/llavatariconctrl.h
index 5b5720f4ac8fd74887b723c5feefe9d36e940ae8..a1dacd1a270a201a13038786c9c71c489f221604 100644
--- a/indra/newview/llavatariconctrl.h
+++ b/indra/newview/llavatariconctrl.h
@@ -37,6 +37,8 @@ class LLAvatarName;
 
 class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache>
 {
+	LLSINGLETON(LLAvatarIconIDCache);
+
 public:
 	struct LLAvatarIconIDCacheItem
 	{
@@ -46,10 +48,6 @@ class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache>
 		bool expired();
 	};
 
-	LLAvatarIconIDCache()
-	:	mFilename("avatar_icons_cache.txt")
-	{}
-
 	void				load	();
 	void				save	();
 
@@ -64,6 +62,11 @@ class LLAvatarIconIDCache: public LLSingleton<LLAvatarIconIDCache>
 	std::map<LLUUID,LLAvatarIconIDCacheItem> mCache;//we cache only LLUID and time
 };
 
+inline
+LLAvatarIconIDCache::LLAvatarIconIDCache()
+	:	mFilename("avatar_icons_cache.txt")
+{}
+
 namespace LLAvatarIconCtrlEnums
 {
 	enum ESymbolPos
diff --git a/indra/newview/llavatarpropertiesprocessor.h b/indra/newview/llavatarpropertiesprocessor.h
index 1dcd2c9b907b674a1f80d1f442914d408bba0e9c..d5c5c75c6914d7a8942a5da13470af7a5ea0c0a8 100644
--- a/indra/newview/llavatarpropertiesprocessor.h
+++ b/indra/newview/llavatarpropertiesprocessor.h
@@ -187,13 +187,12 @@ class LLAvatarPropertiesObserver
 class LLAvatarPropertiesProcessor
 	: public LLSingleton<LLAvatarPropertiesProcessor>
 {
-public:
-	
-	LLAvatarPropertiesProcessor();
+	LLSINGLETON(LLAvatarPropertiesProcessor);
 	virtual ~LLAvatarPropertiesProcessor();
 
+public:
 	void addObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
-	
+
 	void removeObserver(const LLUUID& avatar_id, LLAvatarPropertiesObserver* observer);
 
 	// Request various types of avatar data.  Duplicate requests will be
diff --git a/indra/newview/llavatarrenderinfoaccountant.h b/indra/newview/llavatarrenderinfoaccountant.h
index 870ef4f394ac44870ad4b09472bad2e883422084..6b5fa7bc35d21c7b95ebabc06e66c9dd893f0beb 100644
--- a/indra/newview/llavatarrenderinfoaccountant.h
+++ b/indra/newview/llavatarrenderinfoaccountant.h
@@ -38,13 +38,13 @@ class LLViewerRegion;
 // that is sent to or fetched from regions.
 class LLAvatarRenderInfoAccountant : public LLSingleton<LLAvatarRenderInfoAccountant>
 {
+	LLSINGLETON(LLAvatarRenderInfoAccountant);
+	~LLAvatarRenderInfoAccountant();
+
   private:
 	LOG_CLASS(LLAvatarRenderInfoAccountant);
 
   public:
-	LLAvatarRenderInfoAccountant();
-	~LLAvatarRenderInfoAccountant();
-
 	void sendRenderInfoToRegion(LLViewerRegion * regionp);
 	void getRenderInfoFromRegion(LLViewerRegion * regionp);
 
diff --git a/indra/newview/llavatarrendernotifier.h b/indra/newview/llavatarrendernotifier.h
index a169baef40f4ad6c64e769af59984c2d6468b1d1..de65bd2e139b4a7a9aee7b84f68bfd767121defd 100644
--- a/indra/newview/llavatarrendernotifier.h
+++ b/indra/newview/llavatarrendernotifier.h
@@ -67,9 +67,9 @@ typedef std::list<LLHUDComplexity> hud_complexity_list_t;
 // reported that user's agent is too 'heavy' for their settings
 class LLAvatarRenderNotifier : public LLSingleton<LLAvatarRenderNotifier>
 {
-public:
-	LLAvatarRenderNotifier();
+	LLSINGLETON(LLAvatarRenderNotifier);
 
+public:
     void displayNotification(bool show_over_limit);
 	bool isNotificationVisible();
 
diff --git a/indra/newview/llchannelmanager.h b/indra/newview/llchannelmanager.h
index a5de8a53271dc434fa5cae04ad7ee59d1ce47705..8b9d0dda8b6ca2158b3e90bdec497039bc397fe6 100644
--- a/indra/newview/llchannelmanager.h
+++ b/indra/newview/llchannelmanager.h
@@ -43,6 +43,9 @@ namespace LLNotificationsUI
  */
 class LLChannelManager : public LLSingleton<LLChannelManager>
 {
+	LLSINGLETON(LLChannelManager);
+	virtual ~LLChannelManager();
+
 public:
 
 
@@ -65,9 +68,6 @@ class LLChannelManager : public LLSingleton<LLChannelManager>
 		}
 	};
 
-	LLChannelManager();	
-	virtual ~LLChannelManager();
-
 	// On LoginCompleted - show StartUp toast
 	void onLoginCompleted();
 	// removes a channel intended for the startup toast and allows other channels to show their toasts
diff --git a/indra/newview/llchicletbar.cpp b/indra/newview/llchicletbar.cpp
index 254e3f61a81a8763829cda1ca716c64d2e36a8a9..c4f959bfa9c03f27d59ef26ec23b92dfab65d520 100644
--- a/indra/newview/llchicletbar.cpp
+++ b/indra/newview/llchicletbar.cpp
@@ -38,7 +38,7 @@ namespace
 	const std::string& PANEL_CHICLET_NAME	= "chiclet_list_panel";
 }
 
-LLChicletBar::LLChicletBar(const LLSD&)
+LLChicletBar::LLChicletBar()
 :	mChicletPanel(NULL),
 	mToolbarStack(NULL)
 {
diff --git a/indra/newview/llchicletbar.h b/indra/newview/llchicletbar.h
index 956c82cb77026036fbd0cc486d46fc51a8833828..6c521dc1d504f176b0f3cfc367ed10ece092af14 100644
--- a/indra/newview/llchicletbar.h
+++ b/indra/newview/llchicletbar.h
@@ -38,8 +38,9 @@ class LLChicletBar
 	: public LLSingleton<LLChicletBar>
 	, public LLPanel
 {
+	LLSINGLETON(LLChicletBar);
 	LOG_CLASS(LLChicletBar);
-	friend class LLSingleton<LLChicletBar>;
+
 public:
 
 	BOOL postBuild();
@@ -82,8 +83,6 @@ class LLChicletBar
 	void fitWithTopInfoBar();
 
 protected:
-	LLChicletBar(const LLSD& key = LLSD());
-
 	LLChicletPanel* 	mChicletPanel;
 	LLLayoutStack*		mToolbarStack;
 };
diff --git a/indra/newview/llconversationlog.h b/indra/newview/llconversationlog.h
index 62f08144b9e94d763072393e49f637cca5a1092d..035cbcb9451e7eb41be8747176b15ece750f84eb 100644
--- a/indra/newview/llconversationlog.h
+++ b/indra/newview/llconversationlog.h
@@ -109,7 +109,7 @@ class LLConversation
 
 class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObserver
 {
-	friend class LLSingleton<LLConversationLog>;
+	LLSINGLETON(LLConversationLog);
 public:
 
 	void removeConversation(const LLConversation& conversation);
@@ -157,7 +157,6 @@ class LLConversationLog : public LLSingleton<LLConversationLog>, LLIMSessionObse
 
 private:
 
-	LLConversationLog();
 	virtual ~LLConversationLog()
 	{
 		if (mAvatarNameCacheConnection.connected())
diff --git a/indra/newview/lldaycyclemanager.h b/indra/newview/lldaycyclemanager.h
index 3d2144960da160d3429ec6b039f7db70f554911a..04db9d5dacedeaa6675f69fafbb19a590dc1ae02 100644
--- a/indra/newview/lldaycyclemanager.h
+++ b/indra/newview/lldaycyclemanager.h
@@ -40,6 +40,7 @@
  */
 class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
 {
+	LLSINGLETON_EMPTY_CTOR(LLDayCycleManager);
 	LOG_CLASS(LLDayCycleManager);
 
 public:
@@ -66,7 +67,6 @@ class LLDayCycleManager : public LLSingleton<LLDayCycleManager>
 	boost::signals2::connection setModifyCallback(const modify_signal_t::slot_type& cb);
 
 private:
-	friend class LLSingleton<LLDayCycleManager>;
 	/*virtual*/ void initSingleton();
 
 	void loadAllPresets();
diff --git a/indra/newview/lldeferredsounds.h b/indra/newview/lldeferredsounds.h
index bf1eb629570b8be297fc82325821094e8d05444b..33f02b35215b2e219df508369e62b561b9569fb6 100644
--- a/indra/newview/lldeferredsounds.h
+++ b/indra/newview/lldeferredsounds.h
@@ -33,7 +33,7 @@ struct SoundData;
 
 class LLDeferredSounds : public LLSingleton<LLDeferredSounds>
 {
-private:
+	LLSINGLETON_EMPTY_CTOR(LLDeferredSounds);
 	std::vector<SoundData> soundVector;
 public:
 	//Add sounds to be played once progress bar is hidden (such as after teleport or loading screen)
diff --git a/indra/newview/lldonotdisturbnotificationstorage.cpp b/indra/newview/lldonotdisturbnotificationstorage.cpp
index 7836e2cb94e578251a6804a544db9cc2a2d51d09..7d2712eec708f611338e0bae252facb0a078f8a8 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.cpp
+++ b/indra/newview/lldonotdisturbnotificationstorage.cpp
@@ -69,8 +69,7 @@ BOOL LLDoNotDisturbNotificationStorageTimer::tick()
 }
 
 LLDoNotDisturbNotificationStorage::LLDoNotDisturbNotificationStorage()
-	: LLSingleton<LLDoNotDisturbNotificationStorage>()
-	, LLNotificationStorage("")
+	: LLNotificationStorage("")
     , mDirty(false)
 {
     nameToPayloadParameterMap[toastName] = "SESSION_ID";
diff --git a/indra/newview/lldonotdisturbnotificationstorage.h b/indra/newview/lldonotdisturbnotificationstorage.h
index 6e68b0d1be1013bec70431a7f010bda5e33ddb53..e6cb7835e311b4277df3daf26c2363c3e8d29b62 100644
--- a/indra/newview/lldonotdisturbnotificationstorage.h
+++ b/indra/newview/lldonotdisturbnotificationstorage.h
@@ -47,14 +47,14 @@ class LLDoNotDisturbNotificationStorageTimer : public LLEventTimer
 
 class LLDoNotDisturbNotificationStorage : public LLSingleton<LLDoNotDisturbNotificationStorage>, public LLNotificationStorage
 {
+	LLSINGLETON(LLDoNotDisturbNotificationStorage);
+	~LLDoNotDisturbNotificationStorage();
+
 	LOG_CLASS(LLDoNotDisturbNotificationStorage);
 public:
     static const char * toastName;
     static const char * offerName;
 
-	LLDoNotDisturbNotificationStorage();
-	~LLDoNotDisturbNotificationStorage();
-
 	void initialize();
     bool getDirty();
     void resetDirty();
diff --git a/indra/newview/llenvmanager.h b/indra/newview/llenvmanager.h
index c7877303fc1a507ed2b234b781d950b5706edade..6a0a267f4e355b0d78945f2469c8dc423eca9ae3 100644
--- a/indra/newview/llenvmanager.h
+++ b/indra/newview/llenvmanager.h
@@ -162,14 +162,13 @@ class LLEnvPrefs
  */
 class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 {
+	LLSINGLETON(LLEnvManagerNew);
 	LOG_CLASS(LLEnvManagerNew);
 public:
 	typedef boost::signals2::signal<void()> prefs_change_signal_t;
 	typedef boost::signals2::signal<void()> region_settings_change_signal_t;
 	typedef boost::signals2::signal<void(bool)> region_settings_applied_signal_t;
 
-	LLEnvManagerNew();
-
 	// getters to access user env. preferences
 	bool getUseRegionSettings() const;
 	bool getUseDayCycle() const;
@@ -231,7 +230,6 @@ class LLEnvManagerNew : public LLSingleton<LLEnvManagerNew>
 	void onRegionSettingsApplyResponse(bool ok);
 
 private:
-	friend class LLSingleton<LLEnvManagerNew>;
 	/*virtual*/ void initSingleton();
 
 	void loadUserPrefs();
diff --git a/indra/newview/llestateinfomodel.h b/indra/newview/llestateinfomodel.h
index fcfbd1ce7db2c9c0abd88ae6c33353948ac52141..e7a6a2a725c9f1d04407e4aaf52a3ef914132d30 100644
--- a/indra/newview/llestateinfomodel.h
+++ b/indra/newview/llestateinfomodel.h
@@ -38,6 +38,7 @@ class LLMessageSystem;
  */
 class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 {
+	LLSINGLETON(LLEstateInfoModel);
 	LOG_CLASS(LLEstateInfoModel);
 
 public:
@@ -73,11 +74,8 @@ class LLEstateInfoModel : public LLSingleton<LLEstateInfoModel>
 protected:
 	typedef std::vector<std::string> strings_t;
 
-	friend class LLSingleton<LLEstateInfoModel>;
 	friend class LLDispatchEstateUpdateInfo;
 
-	LLEstateInfoModel();
-
 	/// refresh model with data from the incoming server message
 	void update(const strings_t& strings);
 
diff --git a/indra/newview/llexperiencelog.h b/indra/newview/llexperiencelog.h
index ac227db336c5ac761b76da771feda8ce57af7a83..09e0cd8821bd6fd3ae96a52f17f052c16b726300 100644
--- a/indra/newview/llexperiencelog.h
+++ b/indra/newview/llexperiencelog.h
@@ -33,6 +33,7 @@
 
 class LLExperienceLog : public LLSingleton<LLExperienceLog>
 {
+	LLSINGLETON(LLExperienceLog);
 public:
 	typedef boost::signals2::signal<void(LLSD&)> 
 		callback_signal_t;
@@ -62,7 +63,6 @@ class LLExperienceLog : public LLSingleton<LLExperienceLog>
 	void setEventsToSave(LLSD new_events){mEventsToSave = new_events; }
 	bool isNotExpired(std::string& date);
 protected:
-	LLExperienceLog();
 	void handleExperienceMessage(LLSD& message);
 
 
@@ -81,7 +81,6 @@ class LLExperienceLog : public LLSingleton<LLExperienceLog>
 	bool mNotifyNewEvent;
 
 	friend class LLExperienceLogDispatchHandler;
-	friend class LLSingleton<LLExperienceLog>;
 };
 
 
diff --git a/indra/newview/llfacebookconnect.h b/indra/newview/llfacebookconnect.h
index 2a2cdb54991d432344412720500b5f2a9bb1b353..7fd4070f54dfeb872b98ffc0b2e322fe3d9e44f7 100644
--- a/indra/newview/llfacebookconnect.h
+++ b/indra/newview/llfacebookconnect.h
@@ -43,6 +43,8 @@ class LLEventPump;
  */
 class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
 {
+	LLSINGLETON(LLFacebookConnect);
+	~LLFacebookConnect() {};
 	LOG_CLASS(LLFacebookConnect);
 public:
     enum EConnectionState
@@ -86,10 +88,7 @@ class LLFacebookConnect : public LLSingleton<LLFacebookConnect>
     void openFacebookWeb(std::string url);
 
 private:
-	friend class LLSingleton<LLFacebookConnect>;
 
-	LLFacebookConnect();
-	~LLFacebookConnect() {};
  	std::string getFacebookConnectURL(const std::string& route = "", bool include_read_from_master = false);
 
     EConnectionState mConnectionState;
diff --git a/indra/newview/llfavoritesbar.h b/indra/newview/llfavoritesbar.h
index 2115f77cf3138bf470843576f58beeeeaeb9c4fe..cac32c7f2a6dfce51212e59a0e7e6cf08b28d753 100644
--- a/indra/newview/llfavoritesbar.h
+++ b/indra/newview/llfavoritesbar.h
@@ -34,6 +34,7 @@
 #include "llinventoryobserver.h"
 #include "llinventorymodel.h"
 #include "llviewerinventory.h"
+#include "llinitdestroyclass.h"
 
 class LLMenuItemCallGL;
 class LLToggleableMenu;
@@ -173,6 +174,7 @@ class LLFavoritesBarCtrl : public LLUICtrl, public LLInventoryObserver
 class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
 	, public LLDestroyClass<LLFavoritesOrderStorage>
 {
+	LLSINGLETON(LLFavoritesOrderStorage);
 	LOG_CLASS(LLFavoritesOrderStorage);
 public:
 	/**
@@ -221,10 +223,6 @@ class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
 	std::map<LLUUID,std::string> mFavoriteNames;
 
 private:
-	friend class LLSingleton<LLFavoritesOrderStorage>;
-	LLFavoritesOrderStorage() : mIsDirty(false), mUpdateRequired(false){ load(); }
-	~LLFavoritesOrderStorage() {}
-    
 	/**
 	 * Removes sort indexes for items which are not in Favorites bar for now.
 	 */
@@ -274,4 +272,10 @@ class LLFavoritesOrderStorage : public LLSingleton<LLFavoritesOrderStorage>
 	};
 
 };
+
+inline
+LLFavoritesOrderStorage::LLFavoritesOrderStorage() :
+	mIsDirty(false), mUpdateRequired(false)
+{ load(); }
+
 #endif // LL_LLFAVORITESBARCTRL_H
diff --git a/indra/newview/llfeaturemanager.h b/indra/newview/llfeaturemanager.h
index c3d87cea0bf8a7c0f3f42261ccbfc3b99200e895..54bd07329a9541fd8ea5176610724c99fb31ea44 100644
--- a/indra/newview/llfeaturemanager.h
+++ b/indra/newview/llfeaturemanager.h
@@ -97,20 +97,10 @@ class LLFeatureList
 
 class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManager>
 {
-public:
-	LLFeatureManager()
-	:	LLFeatureList("default"),
-
-		mInited(FALSE),
-		mTableVersion(0),
-		mSafe(FALSE),
-		mGPUClass(GPU_CLASS_UNKNOWN),
-		mExpectedGLVersion(0.f),
-		mGPUSupported(FALSE)		
-	{
-	}
+	LLSINGLETON(LLFeatureManager);
 	~LLFeatureManager() {cleanupFeatureTables();}
 
+public:
 	// initialize this by loading feature table and gpu table
 	void init();
 
@@ -181,5 +171,17 @@ class LLFeatureManager : public LLFeatureList, public LLSingleton<LLFeatureManag
 	BOOL		mGPUSupported;
 };
 
+inline
+LLFeatureManager::LLFeatureManager()
+:	LLFeatureList("default"),
+
+	mInited(FALSE),
+	mTableVersion(0),
+	mSafe(FALSE),
+	mGPUClass(GPU_CLASS_UNKNOWN),
+	mExpectedGLVersion(0.f),
+	mGPUSupported(FALSE)
+{
+}
 
 #endif // LL_LLFEATUREMANAGER_H
diff --git a/indra/newview/llflickrconnect.h b/indra/newview/llflickrconnect.h
index 0155804da0f95e766822374b5e416435de6a9728..43cadca708957bcc170c502ef55e760435222e7c 100644
--- a/indra/newview/llflickrconnect.h
+++ b/indra/newview/llflickrconnect.h
@@ -43,6 +43,8 @@ class LLEventPump;
  */
 class LLFlickrConnect : public LLSingleton<LLFlickrConnect>
 {
+	LLSINGLETON(LLFlickrConnect);
+	~LLFlickrConnect() {};
 	LOG_CLASS(LLFlickrConnect);
 public:
     enum EConnectionState
@@ -80,10 +82,7 @@ class LLFlickrConnect : public LLSingleton<LLFlickrConnect>
     void openFlickrWeb(std::string url);
 
 private:
-	friend class LLSingleton<LLFlickrConnect>;
 
-	LLFlickrConnect();
-	~LLFlickrConnect() {};
  	std::string getFlickrConnectURL(const std::string& route = "", bool include_read_from_master = false);
 
     EConnectionState mConnectionState;
diff --git a/indra/newview/llfloaterbvhpreview.cpp b/indra/newview/llfloaterbvhpreview.cpp
index e5df417ca9f89d5d8174c6e61d9be7fd3c4f33a4..602d2dce73fe26aa64a9fe725ccdf028e1345ed0 100644
--- a/indra/newview/llfloaterbvhpreview.cpp
+++ b/indra/newview/llfloaterbvhpreview.cpp
@@ -992,7 +992,7 @@ void LLFloaterBvhPreview::onBtnOK(void* userdata)
 			{
 				std::string name = floaterp->getChild<LLUICtrl>("name_form")->getValue().asString();
 				std::string desc = floaterp->getChild<LLUICtrl>("description_form")->getValue().asString();
-				S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+				S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 
                 LLResourceUploadInfo::ptr_t assetUpdloadInfo(new LLResourceUploadInfo(
                     floaterp->mTransactionID, LLAssetType::AT_ANIMATION,
diff --git a/indra/newview/llfloaterimcontainer.cpp b/indra/newview/llfloaterimcontainer.cpp
index 15b67b905d036b596a7006f7f466d1932ff8c34f..7039e48e74a328b8f466092fab12e84b6941f4c1 100644
--- a/indra/newview/llfloaterimcontainer.cpp
+++ b/indra/newview/llfloaterimcontainer.cpp
@@ -101,7 +101,7 @@ LLFloaterIMContainer::~LLFloaterIMContainer()
 	gSavedPerAccountSettings.setBOOL("ConversationsMessagePaneCollapsed", mMessagesPane->isCollapsed());
 	gSavedPerAccountSettings.setBOOL("ConversationsParticipantListCollapsed", !isParticipantListExpanded());
 
-	if (!LLSingleton<LLIMMgr>::destroyed())
+	if (LLIMMgr::instanceExists())
 	{
 		LLIMMgr::getInstance()->removeSessionObserver(this);
 	}
diff --git a/indra/newview/llfloaternamedesc.cpp b/indra/newview/llfloaternamedesc.cpp
index 4a5732aecfed578cf0ab0f6d72a16d2f38274b99..c9a689281ea9bc1d2c56264fdd1070f6fa606886 100644
--- a/indra/newview/llfloaternamedesc.cpp
+++ b/indra/newview/llfloaternamedesc.cpp
@@ -123,7 +123,7 @@ BOOL LLFloaterNameDesc::postBuild()
 	// Cancel button
 	getChild<LLUICtrl>("cancel_btn")->setCommitCallback(boost::bind(&LLFloaterNameDesc::onBtnCancel, this));
 
-	getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload() ));
+	getChild<LLUICtrl>("ok_btn")->setLabelArg("[AMOUNT]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload() ));
 	
 	setDefaultBtn("ok_btn");
 	
@@ -162,7 +162,7 @@ void LLFloaterNameDesc::onBtnOK( )
 	getChildView("ok_btn")->setEnabled(FALSE); // don't allow inadvertent extra uploads
 	
 	LLAssetStorage::LLStoreAssetCallback callback = NULL;
-	S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
+	S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
 
     if (can_afford_transaction(expected_upload_cost))
     {
diff --git a/indra/newview/llfriendcard.h b/indra/newview/llfriendcard.h
index ae3800e17badd84b298351641c0280a708419142..2fb912a93048b87340a4b6e4e8d32e0a230f14f6 100644
--- a/indra/newview/llfriendcard.h
+++ b/indra/newview/llfriendcard.h
@@ -37,9 +37,10 @@ class LLFriendCardsManager
 	: public LLSingleton<LLFriendCardsManager>
 	, public LLFriendObserver
 {
+	LLSINGLETON(LLFriendCardsManager);
+	~LLFriendCardsManager();
 	LOG_CLASS(LLFriendCardsManager);
 
-	friend class LLSingleton<LLFriendCardsManager>;
 	friend class CreateFriendCardCallback;
 
 public:
@@ -97,8 +98,6 @@ class LLFriendCardsManager
 private:
 	typedef boost::function<void()> callback_t;
 
-	LLFriendCardsManager();
-	~LLFriendCardsManager();
 
 
 	/**
diff --git a/indra/newview/llgesturemgr.h b/indra/newview/llgesturemgr.h
index 26a5924ec307f4c499ad792586267f890e8b1fe4..402bdf6039952df5e1391eaddaf190df64b74514 100644
--- a/indra/newview/llgesturemgr.h
+++ b/indra/newview/llgesturemgr.h
@@ -51,6 +51,8 @@ class LLGestureManagerObserver
 
 class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchItemsObserver
 {
+	LLSINGLETON(LLGestureMgr);
+	~LLGestureMgr();
 public:
 
 	typedef boost::function<void (LLMultiGesture* loaded_gesture)> gesture_loaded_callback_t;
@@ -58,8 +60,6 @@ class LLGestureMgr : public LLSingleton<LLGestureMgr>, public LLInventoryFetchIt
 	typedef std::map<LLUUID, LLMultiGesture*> item_map_t;
 	typedef std::map<LLUUID, gesture_loaded_callback_t> callback_map_t;
 
-	LLGestureMgr();
-	~LLGestureMgr();
 
 	void init();
 
diff --git a/indra/newview/llgroupmgr.h b/indra/newview/llgroupmgr.h
index e5ce76803582042cf1915ec41a9db05c303bf25d..940ef6eea13af48a80782c117585e3aed2235b8c 100644
--- a/indra/newview/llgroupmgr.h
+++ b/indra/newview/llgroupmgr.h
@@ -348,6 +348,8 @@ struct LLRoleActionSet
 
 class LLGroupMgr : public LLSingleton<LLGroupMgr>
 {
+	LLSINGLETON(LLGroupMgr);
+	~LLGroupMgr();
 	LOG_CLASS(LLGroupMgr);
 	
 public:
@@ -369,8 +371,6 @@ class LLGroupMgr : public LLSingleton<LLGroupMgr>
 
 
 public:
-	LLGroupMgr();
-	~LLGroupMgr();
 
 	void addObserver(LLGroupMgrObserver* observer);
 	void addObserver(const LLUUID& group_id, LLParticularGroupObserver* observer);
diff --git a/indra/newview/llhints.h b/indra/newview/llhints.h
index ebffe561b9513d1d8fbe92c3640129d10d74e00b..dd6195a9ce37e782287df50b334dd7e61a5f8be4 100644
--- a/indra/newview/llhints.h
+++ b/indra/newview/llhints.h
@@ -29,6 +29,7 @@
 
 #include "llpanel.h"
 #include "llnotifications.h"
+#include "llinitdestroyclass.h"
 
 
 class LLHints :  public LLInitClass<LLHints>
diff --git a/indra/newview/llhudmanager.h b/indra/newview/llhudmanager.h
index 9c5d49decd0aff979431310167fdacb95fcc520e..7782739690dca1e83e31da5120262d70e4870c19 100644
--- a/indra/newview/llhudmanager.h
+++ b/indra/newview/llhudmanager.h
@@ -36,10 +36,10 @@ class LLMessageSystem;
 
 class LLHUDManager : public LLSingleton<LLHUDManager>
 {
-public:
-	LLHUDManager();
+	LLSINGLETON(LLHUDManager);
 	~LLHUDManager();
 
+public:
 	LLHUDEffect *createViewerEffect(const U8 type, BOOL send_to_sim = TRUE, BOOL originated_here = TRUE);
 
 	void updateEffects();
diff --git a/indra/newview/llimagefiltersmanager.h b/indra/newview/llimagefiltersmanager.h
index 4751933065bfa9c8fa9635d3a5f550e10238da0d..f1ed3cf1c395cdbac8a695ba45942fcdcf34e886 100644
--- a/indra/newview/llimagefiltersmanager.h
+++ b/indra/newview/llimagefiltersmanager.h
@@ -34,6 +34,8 @@
 
 class LLImageFiltersManager : public LLSingleton<LLImageFiltersManager>
 {
+	LLSINGLETON(LLImageFiltersManager);
+	~LLImageFiltersManager();
 	LOG_CLASS(LLImageFiltersManager);
 public:
     const std::vector<std::string> getFiltersList() const;
@@ -43,10 +45,7 @@ class LLImageFiltersManager : public LLSingleton<LLImageFiltersManager>
 	void loadAllFilters();
 	void loadFiltersFromDir(const std::string& dir);
     
-    friend class LLSingleton<LLImageFiltersManager>;
 	/*virtual*/ void initSingleton();
-	LLImageFiltersManager();
-	~LLImageFiltersManager();
     
 	// List of filters : first is the user friendly localized name, second is the xml file name
     std::map<std::string,std::string> mFiltersList;
diff --git a/indra/newview/llimview.h b/indra/newview/llimview.h
index 41a8813acb2b4ac2cb933c673eca32735f017c52..da40ac83931f38e3258516b4412e8732ac562052 100644
--- a/indra/newview/llimview.h
+++ b/indra/newview/llimview.h
@@ -33,6 +33,7 @@
 
 #include "lllogchat.h"
 #include "llvoicechannel.h"
+#include "llinitdestroyclass.h"
 
 #include "llcoros.h"
 #include "lleventcoro.h"
@@ -61,6 +62,7 @@ class LLSessionTimeoutTimer : public LLEventTimer
  */
 class LLIMModel :  public LLSingleton<LLIMModel>
 {
+	LLSINGLETON(LLIMModel);
 public:
 
 	struct LLIMSession : public boost::signals2::trackable
@@ -151,7 +153,6 @@ class LLIMModel :  public LLSingleton<LLIMModel>
 	};
 	
 
-	LLIMModel();
 
 	/** Session id to session object */
 	std::map<LLUUID, LLIMSession*> mId2SessionMap;
@@ -312,6 +313,7 @@ class LLIMSessionObserver
 
 class LLIMMgr : public LLSingleton<LLIMMgr>
 {
+	LLSINGLETON(LLIMMgr);
 	friend class LLIMModel;
 
 public:
@@ -322,8 +324,6 @@ class LLIMMgr : public LLSingleton<LLIMMgr>
 		INVITATION_TYPE_IMMEDIATE = 2
 	};
 
-	LLIMMgr();
-	virtual ~LLIMMgr() {};
 
 	// Add a message to a session. The session can keyed to sesion id
 	// or agent id.
diff --git a/indra/newview/llinventoryicon.cpp b/indra/newview/llinventoryicon.cpp
index 013a5a7629afe0e0631d9440d8d76713c662162c..495180f087a50097dfb5ba052085baf71a1e5938 100644
--- a/indra/newview/llinventoryicon.cpp
+++ b/indra/newview/llinventoryicon.cpp
@@ -46,8 +46,7 @@ struct IconEntry : public LLDictionaryEntry
 class LLIconDictionary : public LLSingleton<LLIconDictionary>,
 						 public LLDictionary<LLInventoryType::EIconName, IconEntry>
 {
-public:
-	LLIconDictionary();
+	LLSINGLETON(LLIconDictionary);
 };
 
 typedef LLPointer<LLUIImage> LLUIImagePtr;
diff --git a/indra/newview/llinventorymodelbackgroundfetch.h b/indra/newview/llinventorymodelbackgroundfetch.h
index 19fbfc2ed3b3e40b2f285f38b31c57d484200d20..00d2908c1b52775af1b626e734cd949f5de37458 100644
--- a/indra/newview/llinventorymodelbackgroundfetch.h
+++ b/indra/newview/llinventorymodelbackgroundfetch.h
@@ -43,9 +43,9 @@
 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 class LLInventoryModelBackgroundFetch : public LLSingleton<LLInventoryModelBackgroundFetch>
 {
-public:
-	LLInventoryModelBackgroundFetch();
+	LLSINGLETON(LLInventoryModelBackgroundFetch);
 	~LLInventoryModelBackgroundFetch();
+public:
 
 	// Start and stop background breadth-first fetching of inventory contents.
 	// This gets triggered when performing a filter-search.
diff --git a/indra/newview/lllocationhistory.h b/indra/newview/lllocationhistory.h
index 9fef42c5df11996246dd882ba1c4718f11533cb5..1cecbabd3b5302f1850af6e0eb1dfee636e3ea3c 100644
--- a/indra/newview/lllocationhistory.h
+++ b/indra/newview/lllocationhistory.h
@@ -103,6 +103,7 @@ class LLLocationHistoryItem {
 
 class LLLocationHistory: public LLSingleton<LLLocationHistory>
 {
+	LLSINGLETON(LLLocationHistory);
 	LOG_CLASS(LLLocationHistory);
 
 public:
@@ -117,7 +118,6 @@ class LLLocationHistory: public LLSingleton<LLLocationHistory>
 	typedef boost::function<void(EChangeType event)>			history_changed_callback_t;
 	typedef boost::signals2::signal<void(EChangeType event)>	history_changed_signal_t;
 	
-	LLLocationHistory();
 	
 	void					addItem(const LLLocationHistoryItem& item);
 	bool					touchItem(const LLLocationHistoryItem& item);
diff --git a/indra/newview/lllogchat.cpp b/indra/newview/lllogchat.cpp
index 485d4677b1ca7ee702490b1e9d255d213771e97a..b9194c6c67b6f9404f7f808b7372cf5edd301138 100644
--- a/indra/newview/lllogchat.cpp
+++ b/indra/newview/lllogchat.cpp
@@ -132,15 +132,9 @@ void append_to_last_message(std::list<LLSD>& messages, const std::string& line)
 
 class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 {
-public:
-	LLLogChatTimeScanner()
-	{
-		// Note, date/time facets will be destroyed by string streams
-		mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT)));
-		mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT)));
-		mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT)));
-	}
+	LLSINGLETON(LLLogChatTimeScanner);
 
+public:
 	date getTodayPacificDate()
 	{
 		typedef	boost::date_time::local_adjustor<ptime, -8, no_dst> pst;
@@ -205,6 +199,15 @@ class LLLogChatTimeScanner: public LLSingleton<LLLogChatTimeScanner>
 	std::stringstream mTimeStream;
 };
 
+inline
+LLLogChatTimeScanner::LLLogChatTimeScanner()
+{
+	// Note, date/time facets will be destroyed by string streams
+	mDateStream.imbue(std::locale(mDateStream.getloc(), new date_input_facet(DATE_FORMAT)));
+	mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_facet(TIME_FORMAT)));
+	mTimeStream.imbue(std::locale(mTimeStream.getloc(), new time_input_facet(DATE_FORMAT)));
+}
+
 LLLogChat::save_history_signal_t * LLLogChat::sSaveHistorySignal = NULL;
 
 std::map<LLUUID,LLLoadHistoryThread *> LLLogChat::sLoadHistoryThreads;
diff --git a/indra/newview/lllogininstance.h b/indra/newview/lllogininstance.h
index c6773bbf6807ad635273ea4cf8620b7a14384d0b..282ddc1cea2d824f073b92f0701325009b73794a 100644
--- a/indra/newview/lllogininstance.h
+++ b/indra/newview/lllogininstance.h
@@ -40,12 +40,12 @@ class LLUpdaterService;
 // negotiate user authentication attempts.
 class LLLoginInstance : public LLSingleton<LLLoginInstance>
 {
+	LLSINGLETON(LLLoginInstance);
+	~LLLoginInstance();
+
 public:
 	class Disposable;
 
-	LLLoginInstance();
-	~LLLoginInstance();
-
 	void connect(LLPointer<LLCredential> credentials); // Connect to the current grid choice.
 	void connect(const std::string& uri, LLPointer<LLCredential> credentials);	// Connect to the given uri.
 	void reconnect(); // reconnect using the current credentials.
diff --git a/indra/newview/llmainlooprepeater.h b/indra/newview/llmainlooprepeater.h
index f84c0ca94c2d1b4c812533d655e689a357c275a8..2ec3a74e4ae3bc4a446182cc444c5d654cd044d6 100644
--- a/indra/newview/llmainlooprepeater.h
+++ b/indra/newview/llmainlooprepeater.h
@@ -43,9 +43,8 @@
 class LLMainLoopRepeater:
 	public LLSingleton<LLMainLoopRepeater>
 {
+	LLSINGLETON(LLMainLoopRepeater);
 public:
-	LLMainLoopRepeater(void);
-	
 	// Start the repeater service.
 	void start(void);
 	
diff --git a/indra/newview/llmarketplacefunctions.h b/indra/newview/llmarketplacefunctions.h
index 9d795c6ced836e1c1287382168d739efeb82b0a6..ec312baca395b65116c27286cfe73c53ec7f3229 100644
--- a/indra/newview/llmarketplacefunctions.h
+++ b/indra/newview/llmarketplacefunctions.h
@@ -86,11 +86,10 @@ namespace MarketplaceFetchCodes
 class LLMarketplaceInventoryImporter
 	: public LLSingleton<LLMarketplaceInventoryImporter>
 {
+	LLSINGLETON(LLMarketplaceInventoryImporter);
 public:
 	static void update();
-	
-	LLMarketplaceInventoryImporter();
-	
+
 	typedef boost::signals2::signal<void (bool)> status_changed_signal_t;
 	typedef boost::signals2::signal<void (U32, const LLSD&)> status_report_signal_t;
 
@@ -181,10 +180,11 @@ class LLSLMDeleteListingsResponder;
 class LLMarketplaceData
     : public LLSingleton<LLMarketplaceData>
 {
-    friend class LLSingleton < LLMarketplaceData > ;
+    LLSINGLETON(LLMarketplaceData);
+    virtual ~LLMarketplaceData();
 
 public:
-	friend class LLSLMGetMerchantResponder;
+    friend class LLSLMGetMerchantResponder;
     friend class LLSLMGetListingsResponder;
     friend class LLSLMCreateListingsResponder;
     friend class LLSLMGetListingResponder;
@@ -242,9 +242,6 @@ class LLMarketplaceData
     void decrementValidationWaiting(const LLUUID& folder_id, S32 count = 1);
 
 private:
-    LLMarketplaceData();
-    virtual ~LLMarketplaceData();
-
     // Modify Marketplace data set  : each method returns true if the function succeeds, false if error
     // Used internally only by SLM Responders when data are received from the SLM Server
     bool addListing(const LLUUID& folder_id, S32 listing_id, const LLUUID& version_id, bool is_listed, const std::string& edit_url, S32 count);
diff --git a/indra/newview/llmaterialmgr.h b/indra/newview/llmaterialmgr.h
index 36dd0904b6dad1791a554048c06b3121a42aa8ef..60b58d17de7156d0234e6a5a39e4fd33e7e0ee7b 100644
--- a/indra/newview/llmaterialmgr.h
+++ b/indra/newview/llmaterialmgr.h
@@ -38,9 +38,7 @@ class LLViewerRegion;
 
 class LLMaterialMgr : public LLSingleton<LLMaterialMgr>
 {
-	friend class LLSingleton<LLMaterialMgr>;
-protected:
-	LLMaterialMgr();
+	LLSINGLETON(LLMaterialMgr);
 	virtual ~LLMaterialMgr();
 
 public:
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
index 8879cfd7fbf8ed593b4ba58df20737bbdf3766c0..63d97f6ac2da08e6103d6567b1bfb2158946e0f0 100644
--- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.cpp
@@ -41,8 +41,7 @@
 #include "llpathfindingnavmeshstatus.h"
 #include "llviewerregion.h"
 
-LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() 
-	: LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>(),
+LLMenuOptionPathfindingRebakeNavmesh::LLMenuOptionPathfindingRebakeNavmesh() :
 	mIsInitialized(false),
 	mCanRebakeRegion(false),
 	mRebakeNavMeshMode(kRebakeNavMesh_Default),
diff --git a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h
index 7b1d2873bad0933e54a0823ddbd7da84f11b6f48..649a387dd3c70db09d278e574021d8833a8bc90c 100644
--- a/indra/newview/llmenuoptionpathfindingrebakenavmesh.h
+++ b/indra/newview/llmenuoptionpathfindingrebakenavmesh.h
@@ -37,6 +37,8 @@ class LLPathfindingNavMeshStatus;
 
 class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPathfindingRebakeNavmesh>
 {
+	LLSINGLETON(LLMenuOptionPathfindingRebakeNavmesh);
+	virtual ~LLMenuOptionPathfindingRebakeNavmesh();
 	LOG_CLASS(LLMenuOptionPathfindingRebakeNavmesh);
 
 public:
@@ -49,8 +51,6 @@ class LLMenuOptionPathfindingRebakeNavmesh : public LLSingleton<LLMenuOptionPath
 		kRebakeNavMesh_Default = kRebakeNavMesh_NotAvailable
 	} ERebakeNavMeshMode;
 
-	LLMenuOptionPathfindingRebakeNavmesh();
-	virtual ~LLMenuOptionPathfindingRebakeNavmesh();
 
 	void               initialize();
 	void               quit();
diff --git a/indra/newview/llmutelist.cpp b/indra/newview/llmutelist.cpp
index 84cf7d03133b4eb7a964cac040bcfcee85f5fcbc..0f70c9d13f9c83dea08e925d31f4049b55686668 100644
--- a/indra/newview/llmutelist.cpp
+++ b/indra/newview/llmutelist.cpp
@@ -47,6 +47,7 @@
 #include "pipeline.h"
 
 #include <boost/tokenizer.hpp>
+#include <boost/bind.hpp>
 
 #include "lldispatcher.h"
 #include "llxfermanager.h"
@@ -147,22 +148,6 @@ std::string LLMute::getDisplayType() const
 	}
 }
 
-
-/* static */
-LLMuteList* LLMuteList::getInstance()
-{
-	// Register callbacks at the first time that we find that the message system has been created.
-	static BOOL registered = FALSE;
-	if( !registered && gMessageSystem != NULL)
-	{
-		registered = TRUE;
-		// Register our various callbacks
-		gMessageSystem->setHandlerFuncFast(_PREHASH_MuteListUpdate, processMuteListUpdate);
-		gMessageSystem->setHandlerFuncFast(_PREHASH_UseCachedMuteList, processUseCachedMuteList);
-	}
-	return LLSingleton<LLMuteList>::getInstance(); // Call the "base" implementation.
-}
-
 //-----------------------------------------------------------------------------
 // LLMuteList()
 //-----------------------------------------------------------------------------
@@ -170,6 +155,18 @@ LLMuteList::LLMuteList() :
 	mIsLoaded(FALSE)
 {
 	gGenericDispatcher.addHandler("emptymutelist", &sDispatchEmptyMuteList);
+
+	// Register our callbacks. We may be constructed before gMessageSystem, so
+	// use callWhenReady() to register them as soon as gMessageSystem becomes
+	// available.
+	// When using bind(), must be explicit about default arguments such as
+	// that last NULL.
+	gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1,
+											 _PREHASH_MuteListUpdate, processMuteListUpdate,
+											 static_cast<void**>(NULL)));
+	gMessageSystem.callWhenReady(boost::bind(&LLMessageSystem::setHandlerFuncFast, _1,
+											 _PREHASH_UseCachedMuteList, processUseCachedMuteList,
+											 static_cast<void**>(NULL)));
 }
 
 //-----------------------------------------------------------------------------
diff --git a/indra/newview/llmutelist.h b/indra/newview/llmutelist.h
index 4e7b6ee880fbf8ad0ecb4e264f53ba0a8d0cef39..4ceddc97fd81f3d00d7fe58215a8b5817d181af7 100644
--- a/indra/newview/llmutelist.h
+++ b/indra/newview/llmutelist.h
@@ -71,6 +71,8 @@ class LLMute
 
 class LLMuteList : public LLSingleton<LLMuteList>
 {
+	LLSINGLETON(LLMuteList);
+	~LLMuteList();
 public:
 	// reasons for auto-unmuting a resident
 	enum EAutoReason 
@@ -81,13 +83,6 @@ class LLMuteList : public LLSingleton<LLMuteList>
 		AR_COUNT			// enum count
 	};
 
-	LLMuteList();
-	~LLMuteList();
-
-	// Implemented locally so that we can perform some delayed initialization. 
-	// Callers should be careful to call this one and not LLSingleton<LLMuteList>::getInstance()
-	// which would circumvent that mechanism. -MG
-	static LLMuteList* getInstance();
 
 	void addObserver(LLMuteListObserver* observer);
 	void removeObserver(LLMuteListObserver* observer);
diff --git a/indra/newview/llnavigationbar.h b/indra/newview/llnavigationbar.h
old mode 100644
new mode 100755
index 29dbaedf7af9c2f63b0add0d058db42614a4a169..a44c6dd6997e315dd6722579861276ac8b3d8896
--- a/indra/newview/llnavigationbar.h
+++ b/indra/newview/llnavigationbar.h
@@ -30,6 +30,7 @@
 #include "llpanel.h"
 #include "llbutton.h"
 #include "lllayoutstack.h"
+#include "llinitdestroyclass.h"
 
 class LLLocationInputCtrl;
 class LLMenuGL;
@@ -84,12 +85,12 @@ class LLPullButton: public LLButton
 class LLNavigationBar
 	:	public LLPanel, public LLSingleton<LLNavigationBar>, private LLDestroyClass<LLNavigationBar>
 {
+	LLSINGLETON(LLNavigationBar);
+	virtual ~LLNavigationBar();
 	LOG_CLASS(LLNavigationBar);
 	friend class LLDestroyClass<LLNavigationBar>;
-	
+
 public:
-	LLNavigationBar();
-	virtual ~LLNavigationBar();
 	
 	/*virtual*/ void	draw();
 	/*virtual*/ BOOL handleRightMouseDown(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/llnotificationmanager.h b/indra/newview/llnotificationmanager.h
index f37c6b833c0b406827d1427ca03c09488089a919..52c79cc68970d172a37dd3a9abe6c3e9f8625396 100644
--- a/indra/newview/llnotificationmanager.h
+++ b/indra/newview/llnotificationmanager.h
@@ -46,11 +46,11 @@ class LLToast;
  */
 class LLNotificationManager : public LLSingleton<LLNotificationManager>
 {
-	typedef std::pair<std::string, LLEventHandler*> eventhandlers;
-public:	
-	LLNotificationManager();	
+	LLSINGLETON(LLNotificationManager);
 	virtual ~LLNotificationManager();
+	typedef std::pair<std::string, LLEventHandler*> eventhandlers;
 
+public:
 	//TODO: make private
 	// this method initialize handlers' map for different types of notifications
 	void init(void);
diff --git a/indra/newview/llnotificationstorage.cpp b/indra/newview/llnotificationstorage.cpp
index 3418b33d377897bbe88faca093017a802c6d5082..35fdfa88bb52d39ca7d313949cc16d4d01f5d764 100644
--- a/indra/newview/llnotificationstorage.cpp
+++ b/indra/newview/llnotificationstorage.cpp
@@ -45,9 +45,10 @@ typedef boost::function<LLNotificationResponderInterface * (const LLSD& pParams)
 
 class LLResponderRegistry : public LLRegistrySingleton<std::string, responder_constructor_t, LLResponderRegistry>
 {
-    public:
-        template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
-        LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
+    LLSINGLETON_EMPTY_CTOR(LLResponderRegistry);
+public:
+    template<typename RESPONDER_TYPE> static LLNotificationResponderInterface * create(const LLSD& pParams);
+    LLNotificationResponderInterface * createResponder(const std::string& pNotificationName, const LLSD& pParams);
 };
 
 template<typename RESPONDER_TYPE> LLNotificationResponderInterface * LLResponderRegistry::create(const LLSD& pParams)
diff --git a/indra/newview/lloutfitgallery.cpp b/indra/newview/lloutfitgallery.cpp
index bc1e2c5d59590d137f232f4cb9a0d78576281462..8887a61857f460eb774c68b94cb785d0ffa7577f 100644
--- a/indra/newview/lloutfitgallery.cpp
+++ b/indra/newview/lloutfitgallery.cpp
@@ -1126,7 +1126,7 @@ void LLOutfitGallery::uploadPhoto(LLUUID outfit_id)
                 return;
             }
 
-            S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
+            S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload(); // kinda hack - assumes that unsubclassed LLFloaterNameDesc is only used for uploading chargeable assets, which it is right now (it's only used unsubclassed for the sound upload dialog, and THAT should be a subclass).
             void *nruserdata = NULL;
             nruserdata = (void *)&outfit_id;
 
diff --git a/indra/newview/lloutfitobserver.h b/indra/newview/lloutfitobserver.h
index 87d4b0c998d060d870aa9dfbfa704b985892f508..77041db68d094c475df3615fac856a6024f0f475 100644
--- a/indra/newview/lloutfitobserver.h
+++ b/indra/newview/lloutfitobserver.h
@@ -36,10 +36,10 @@
  */
 class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitObserver>
 {
-public:
+	LLSINGLETON(LLOutfitObserver);
 	virtual ~LLOutfitObserver();
 
-	friend class LLSingleton<LLOutfitObserver>;
+public:
 
 	virtual void changed(U32 mask);
 
@@ -58,7 +58,6 @@ class LLOutfitObserver: public LLInventoryObserver, public LLSingleton<LLOutfitO
 	void addOutfitLockChangedCallback(const signal_t::slot_type& cb) { mOutfitLockChanged.connect(cb); }
 
 protected:
-	LLOutfitObserver();
 
 	/** Get a version of an inventory category specified by its UUID */
 	static S32 getCategoryVersion(const LLUUID& cat_id);
diff --git a/indra/newview/llpaneleditwearable.cpp b/indra/newview/llpaneleditwearable.cpp
index b7e1b2d3a432e8441f665bc60c9657dfdfc8c516..f2d43a103772fd81506033d369b972e79ae80e21 100644
--- a/indra/newview/llpaneleditwearable.cpp
+++ b/indra/newview/llpaneleditwearable.cpp
@@ -117,8 +117,7 @@ class LLEditWearableDictionary : public LLSingleton<LLEditWearableDictionary>
         //--------------------------------------------------------------------
         // Constructors and Destructors
         //--------------------------------------------------------------------
-public:
-        LLEditWearableDictionary();
+        LLSINGLETON(LLEditWearableDictionary);
         virtual ~LLEditWearableDictionary();
         
         //--------------------------------------------------------------------
diff --git a/indra/newview/llpanelmaininventory.cpp b/indra/newview/llpanelmaininventory.cpp
index eb40616a9c4a32b473b563731b829db5b2e18ba1..211cb32c0119e67e44b5611a8fac4cec6ed4398e 100644
--- a/indra/newview/llpanelmaininventory.cpp
+++ b/indra/newview/llpanelmaininventory.cpp
@@ -1309,7 +1309,7 @@ void LLPanelMainInventory::setUploadCostIfNeeded()
 		LLMenuItemBranchGL* upload_menu = menu->findChild<LLMenuItemBranchGL>("upload");
 		if(upload_menu)
 		{
-			S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+			S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 			std::string cost_str;
 
 			// getPriceUpload() returns -1 if no data available yet.
diff --git a/indra/newview/llpanelsnapshotinventory.cpp b/indra/newview/llpanelsnapshotinventory.cpp
index b2952834fb76f8d7a9fcd757c6a028f870eea6dc..21ac7604ff52cb7ce516a8c2f9cdb2a18ce36aac 100644
--- a/indra/newview/llpanelsnapshotinventory.cpp
+++ b/indra/newview/llpanelsnapshotinventory.cpp
@@ -135,7 +135,7 @@ BOOL LLPanelSnapshotInventory::postBuild()
 // virtual
 void LLPanelSnapshotInventory::onOpen(const LLSD& key)
 {
-	getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()));
+	getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload()));
 	LLPanelSnapshot::onOpen(key);
 }
 
@@ -155,7 +155,7 @@ void LLPanelSnapshotInventory::onResolutionCommit(LLUICtrl* ctrl)
 
 void LLPanelSnapshotInventoryBase::onSend()
 {
-    S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+    S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
     if (can_afford_transaction(expected_upload_cost))
     {
         if (mSnapshotFloater)
@@ -191,7 +191,7 @@ BOOL LLPanelOutfitSnapshotInventory::postBuild()
 // virtual
 void LLPanelOutfitSnapshotInventory::onOpen(const LLSD& key)
 {
-    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::Singleton::getInstance()->getPriceUpload()));
+    getChild<LLUICtrl>("hint_lbl")->setTextArg("[UPLOAD_COST]", llformat("%d", LLGlobalEconomy::getInstance()->getPriceUpload()));
     LLPanelSnapshot::onOpen(key);
 }
 
diff --git a/indra/newview/llpanelsnapshotoptions.cpp b/indra/newview/llpanelsnapshotoptions.cpp
index 269f16c5e42cbd148dc57848cde529c71d5d5748..95c14e4226c9eef40b6093a70fd1895bbca43669 100644
--- a/indra/newview/llpanelsnapshotoptions.cpp
+++ b/indra/newview/llpanelsnapshotoptions.cpp
@@ -77,12 +77,12 @@ LLPanelSnapshotOptions::LLPanelSnapshotOptions()
 	mCommitCallbackRegistrar.add("Snapshot.SendToFacebook",		boost::bind(&LLPanelSnapshotOptions::onSendToFacebook, this));
 	mCommitCallbackRegistrar.add("Snapshot.SendToTwitter",		boost::bind(&LLPanelSnapshotOptions::onSendToTwitter, this));
 	mCommitCallbackRegistrar.add("Snapshot.SendToFlickr",		boost::bind(&LLPanelSnapshotOptions::onSendToFlickr, this));
-	LLGlobalEconomy::Singleton::getInstance()->addObserver(this);
+	LLGlobalEconomy::getInstance()->addObserver(this);
 }
 
 LLPanelSnapshotOptions::~LLPanelSnapshotOptions()
 {
-	LLGlobalEconomy::Singleton::getInstance()->removeObserver(this);
+	LLGlobalEconomy::getInstance()->removeObserver(this);
 }
 
 // virtual
@@ -100,7 +100,7 @@ void LLPanelSnapshotOptions::onOpen(const LLSD& key)
 
 void LLPanelSnapshotOptions::updateUploadCost()
 {
-	S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 	getChild<LLUICtrl>("save_to_inventory_btn")->setLabelArg("[AMOUNT]", llformat("%d", upload_cost));
 }
 
diff --git a/indra/newview/llpanelteleporthistory.cpp b/indra/newview/llpanelteleporthistory.cpp
index 3de9dc2f8058defc0b7559078c4ac8aace2e2970..fe0608d5441594e958547554213017c52425502d 100644
--- a/indra/newview/llpanelteleporthistory.cpp
+++ b/indra/newview/llpanelteleporthistory.cpp
@@ -104,7 +104,9 @@ class LLTeleportHistoryFlatItem : public LLPanel
 ////////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////////
 
-class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlatItemStorage> {
+class LLTeleportHistoryFlatItemStorage: public LLSingleton<LLTeleportHistoryFlatItemStorage>
+{
+	LLSINGLETON_EMPTY_CTOR(LLTeleportHistoryFlatItemStorage);
 protected:
 	typedef std::vector< LLHandle<LLTeleportHistoryFlatItem> > flat_item_list_t;
 
diff --git a/indra/newview/llpaneltopinfobar.h b/indra/newview/llpaneltopinfobar.h
index f37bd9c048823990ffab34a7c02823ff958d5ca9..78dd99702906f95f2f32bc6aa0045d838ceb6dbb 100644
--- a/indra/newview/llpaneltopinfobar.h
+++ b/indra/newview/llpaneltopinfobar.h
@@ -28,6 +28,7 @@
 #define LLPANELTOPINFOBAR_H_
 
 #include "llpanel.h"
+#include "llinitdestroyclass.h"
 
 class LLButton;
 class LLTextBox;
@@ -36,6 +37,8 @@ class LLParcelChangeObserver;
 
 class LLPanelTopInfoBar : public LLPanel, public LLSingleton<LLPanelTopInfoBar>, private LLDestroyClass<LLPanelTopInfoBar>
 {
+	LLSINGLETON(LLPanelTopInfoBar);
+	~LLPanelTopInfoBar();
 	LOG_CLASS(LLPanelTopInfoBar);
 
 	friend class LLDestroyClass<LLPanelTopInfoBar>;
@@ -43,9 +46,6 @@ class LLPanelTopInfoBar : public LLPanel, public LLSingleton<LLPanelTopInfoBar>,
 public:
 	typedef boost::signals2::signal<void ()> resize_signal_t;
 
-	LLPanelTopInfoBar();
-	~LLPanelTopInfoBar();
-
 	/*virtual*/ BOOL postBuild();
 	/*virtual*/ void draw();
 
diff --git a/indra/newview/llpathfindingmanager.cpp b/indra/newview/llpathfindingmanager.cpp
index 711a869e823d478ac8a7946f7c94e2d0e98e3b67..cb4c07a417bb3d9ab012f8d9a54f9f7975431443 100644
--- a/indra/newview/llpathfindingmanager.cpp
+++ b/indra/newview/llpathfindingmanager.cpp
@@ -144,8 +144,7 @@ typedef boost::shared_ptr<LinksetsResponder> LinksetsResponderPtr;
 // LLPathfindingManager
 //---------------------------------------------------------------------------
 
-LLPathfindingManager::LLPathfindingManager()
-	: LLSingleton<LLPathfindingManager>(),
+LLPathfindingManager::LLPathfindingManager():
 	mNavMeshMap(),
 	mAgentStateSignal()
 {
diff --git a/indra/newview/llpathfindingmanager.h b/indra/newview/llpathfindingmanager.h
index e8fad590ba7c9e8cb0a04fe7d87d82be37a3e970..a44cd892da61c4d45028bb4680fa76c27f2e3bc6 100644
--- a/indra/newview/llpathfindingmanager.h
+++ b/indra/newview/llpathfindingmanager.h
@@ -48,6 +48,9 @@ class LinksetsResponder;
 
 class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 {
+	LLSINGLETON(LLPathfindingManager);
+	virtual ~LLPathfindingManager();
+
 	friend class LLNavMeshSimStateChangeNode;
 	friend class NavMeshStatusResponder;
 	friend class LLAgentStateChangeNode;
@@ -60,9 +63,6 @@ class LLPathfindingManager : public LLSingleton<LLPathfindingManager>
 		kRequestError
 	} ERequestStatus;
 
-	LLPathfindingManager();
-	virtual ~LLPathfindingManager();
-
 	void initSystem();
 	void quitSystem();
 
diff --git a/indra/newview/llpathfindingpathtool.cpp b/indra/newview/llpathfindingpathtool.cpp
index 006755e20b1c48952c202a5f83e7f8270ba5efb3..318732510117efed78fa0bdbf3376db23c1de13d 100644
--- a/indra/newview/llpathfindingpathtool.cpp
+++ b/indra/newview/llpathfindingpathtool.cpp
@@ -46,7 +46,6 @@
 
 LLPathfindingPathTool::LLPathfindingPathTool()
 	: LLTool(PATH_TOOL_NAME),
-	LLSingleton<LLPathfindingPathTool>(),
 	mFinalPathData(),
 	mTempPathData(),
 	mPathResult(LLPathingLib::LLPL_NO_PATH),
diff --git a/indra/newview/llpathfindingpathtool.h b/indra/newview/llpathfindingpathtool.h
index 97284265f19b0d4327de284b82b0dee170fbe41c..88cb3a15f89e1e2131d4f613b1ebd746712a9616 100644
--- a/indra/newview/llpathfindingpathtool.h
+++ b/indra/newview/llpathfindingpathtool.h
@@ -36,6 +36,9 @@
 
 class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPathTool>
 {
+	LLSINGLETON(LLPathfindingPathTool);
+	virtual ~LLPathfindingPathTool();
+
 public:
 	typedef enum
 	{
@@ -59,9 +62,6 @@ class LLPathfindingPathTool : public LLTool, public LLSingleton<LLPathfindingPat
 		kCharacterTypeD
 	} ECharacterType;
 
-	LLPathfindingPathTool();
-	virtual ~LLPathfindingPathTool();
-
 	typedef boost::function<void (void)>         path_event_callback_t;
 	typedef boost::signals2::signal<void (void)> path_event_signal_t;
 	typedef boost::signals2::connection          path_event_slot_t;
diff --git a/indra/newview/llpersistentnotificationstorage.cpp b/indra/newview/llpersistentnotificationstorage.cpp
index 9c0222d0bcef0eee343455e4dac879cc81043ad8..264382ae8280be64506e877e961f2d57073d1ea3 100644
--- a/indra/newview/llpersistentnotificationstorage.cpp
+++ b/indra/newview/llpersistentnotificationstorage.cpp
@@ -36,9 +36,8 @@
 #include "llscriptfloater.h"
 #include "llviewermessage.h"
 #include "llviewernetwork.h"
-LLPersistentNotificationStorage::LLPersistentNotificationStorage()
-	: LLSingleton<LLPersistentNotificationStorage>()
-	, LLNotificationStorage("")
+LLPersistentNotificationStorage::LLPersistentNotificationStorage():
+	  LLNotificationStorage("")
 	, mLoaded(false)
 {
 }
diff --git a/indra/newview/llpersistentnotificationstorage.h b/indra/newview/llpersistentnotificationstorage.h
index bf0306380e7bd1f3c9658222451d4ea5fa48659d..40c9923c7412036cc0b26cf1cb5ab860e0cb4acc 100644
--- a/indra/newview/llpersistentnotificationstorage.h
+++ b/indra/newview/llpersistentnotificationstorage.h
@@ -45,10 +45,10 @@ class LLSD;
 
 class LLPersistentNotificationStorage : public LLSingleton<LLPersistentNotificationStorage>, public LLNotificationStorage
 {
+	LLSINGLETON(LLPersistentNotificationStorage);
+	~LLPersistentNotificationStorage();
 	LOG_CLASS(LLPersistentNotificationStorage);
 public:
-	LLPersistentNotificationStorage();
-	~LLPersistentNotificationStorage();
 
 	void saveNotifications();
 	void loadNotifications();
diff --git a/indra/newview/llpresetsmanager.h b/indra/newview/llpresetsmanager.h
index 21f9885f2786c9d4ec95c0db2462a62488982e50..0014e32267ffd026a9c698e29a3dd20d8b2fb7e6 100644
--- a/indra/newview/llpresetsmanager.h
+++ b/indra/newview/llpresetsmanager.h
@@ -46,6 +46,9 @@ enum EDefaultOptions
 
 class LLPresetsManager : public LLSingleton<LLPresetsManager>
 {
+	LLSINGLETON(LLPresetsManager);
+	~LLPresetsManager();
+
 public:
 
 	typedef std::list<std::string> preset_name_list_t;
@@ -67,9 +70,6 @@ class LLPresetsManager : public LLSingleton<LLPresetsManager>
 
 	preset_name_list_t mPresetNames;
 
-	LLPresetsManager();
-	~LLPresetsManager();
-
 	preset_list_signal_t mPresetListChangeSignal;
 
   private:
diff --git a/indra/newview/llproductinforequest.h b/indra/newview/llproductinforequest.h
index 75dbf220d17cdf140bba4aea684e9b3a101293a7..d1036374e8008302ff83f8b8d68ee12f4d7eaade 100644
--- a/indra/newview/llproductinforequest.h
+++ b/indra/newview/llproductinforequest.h
@@ -41,12 +41,11 @@
  */
 class LLProductInfoRequestManager : public LLSingleton<LLProductInfoRequestManager>
 {
+	LLSINGLETON(LLProductInfoRequestManager);
 public:
-	LLProductInfoRequestManager();
 	std::string getDescriptionForSku(const std::string& sku);
 
 private:
-	friend class LLSingleton<LLProductInfoRequestManager>;	
 	/* virtual */ void initSingleton();
 
     void getLandDescriptionsCoro(std::string url);
diff --git a/indra/newview/llrecentpeople.h b/indra/newview/llrecentpeople.h
index d0d637686749fe2490ea5ef5525c56b07f4eb9d8..c7aaf604f5dd554ce64d4d60f47f2cf5c80cbf70 100644
--- a/indra/newview/llrecentpeople.h
+++ b/indra/newview/llrecentpeople.h
@@ -50,6 +50,7 @@ class LLDate;
  */
 class LLRecentPeople: public LLSingleton<LLRecentPeople>, public LLOldEvents::LLSimpleListener
 {
+	LLSINGLETON_EMPTY_CTOR(LLRecentPeople);
 	LOG_CLASS(LLRecentPeople);
 public:
 	typedef boost::signals2::signal<void ()> signal_t;
diff --git a/indra/newview/llregioninfomodel.h b/indra/newview/llregioninfomodel.h
index d22a0de4635bfd14abd5e7f862aeb86073fd26aa..ea9640efda99e81461f2df77fa5c3fee7df53b4e 100644
--- a/indra/newview/llregioninfomodel.h
+++ b/indra/newview/llregioninfomodel.h
@@ -36,6 +36,7 @@ class LLMessageSystem;
  */
 class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel>
 {
+	LLSINGLETON(LLRegionInfoModel);
 	LOG_CLASS(LLRegionInfoModel);
 
 public:
@@ -73,10 +74,8 @@ class LLRegionInfoModel : public LLSingleton<LLRegionInfoModel>
 	std::string	mSimType;
 
 protected:
-	friend class LLSingleton<LLRegionInfoModel>;
 	friend class LLViewerRegion;
 
-	LLRegionInfoModel();
 
 	/**
 	 * Refresh model with data from the incoming server message.
diff --git a/indra/newview/llremoteparcelrequest.h b/indra/newview/llremoteparcelrequest.h
index cb5af50c5f083e737a7f5aab4a693b18fa466794..5b0d1891378fbbbb4975e6010e13c691952972ff 100644
--- a/indra/newview/llremoteparcelrequest.h
+++ b/indra/newview/llremoteparcelrequest.h
@@ -74,9 +74,10 @@ class LLRemoteParcelInfoObserver
 
 class LLRemoteParcelInfoProcessor : public LLSingleton<LLRemoteParcelInfoProcessor>
 {
-public:
+	LLSINGLETON_EMPTY_CTOR(LLRemoteParcelInfoProcessor);
 	virtual ~LLRemoteParcelInfoProcessor() {}
 
+public:
 	void addObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
 	void removeObserver(const LLUUID& parcel_id, LLRemoteParcelInfoObserver* observer);
 
diff --git a/indra/newview/llrootview.h b/indra/newview/llrootview.h
index 5223a314f39b392b3c74cdd5d29a6eaec6d42011..2ac958e7b831781ed54a730f70d9c92969c0f688 100644
--- a/indra/newview/llrootview.h
+++ b/indra/newview/llrootview.h
@@ -32,7 +32,9 @@
 #include "lltooltip.h"
 
 class LLRootViewRegistry : public LLChildRegistry<LLRootViewRegistry>
-{};
+{
+	LLSINGLETON(LLRootViewRegistry);
+};
 
 class LLRootView : public LLView
 {
diff --git a/indra/newview/llscenemonitor.h b/indra/newview/llscenemonitor.h
index 2b6ea57b96016a88663da97aa9865d0e399ee141..7cd531bd34667c510e492f3d396ba63226e792b1 100644
--- a/indra/newview/llscenemonitor.h
+++ b/indra/newview/llscenemonitor.h
@@ -39,10 +39,10 @@ class LLViewerTexture;
 
 class LLSceneMonitor : public LLSingleton<LLSceneMonitor>
 {
+	LLSINGLETON(LLSceneMonitor);
+	~LLSceneMonitor();
 	LOG_CLASS(LLSceneMonitor);
 public:
-	LLSceneMonitor();
-	~LLSceneMonitor();
 
 	void freezeAvatar(LLCharacter* avatarp);
 	void setDebugViewerVisible(bool visible);
diff --git a/indra/newview/llscriptfloater.h b/indra/newview/llscriptfloater.h
index 70451194b38bbde051a7f5c3a7b1a9193db1d5d8..c0b84abdcb1f9eb6123a6b2524828f92914dddd7 100644
--- a/indra/newview/llscriptfloater.h
+++ b/indra/newview/llscriptfloater.h
@@ -41,6 +41,7 @@ class LLScriptFloaterManager : public LLSingleton<LLScriptFloaterManager>
 	// *TODO
 	// LLScriptFloaterManager and LLScriptFloater will need some refactoring after we 
 	// know how script notifications should look like.
+	LLSINGLETON_EMPTY_CTOR(LLScriptFloaterManager);
 public:
 
 	typedef enum e_object_type
diff --git a/indra/newview/llsearchhistory.h b/indra/newview/llsearchhistory.h
index 3309a8fcac0d2a0447e4dd88220fe932fc3b461a..5aab5e6765ce4df17da7fdbb7911dfe289f89c3c 100644
--- a/indra/newview/llsearchhistory.h
+++ b/indra/newview/llsearchhistory.h
@@ -28,6 +28,7 @@
 #define LL_LLSEARCHHISTORY_H
 
 #include "llsingleton.h"
+#include "llinitdestroyclass.h"
 #include "llui.h"
 
 /**
@@ -36,6 +37,7 @@
  */
 class LLSearchHistory : public LLSingleton<LLSearchHistory>, private LLDestroyClass<LLSearchHistory>
 {
+	LLSINGLETON(LLSearchHistory);
 	friend class LLDestroyClass<LLSearchHistory>;
 public:
 
@@ -71,7 +73,6 @@ class LLSearchHistory : public LLSingleton<LLSearchHistory>, private LLDestroyCl
 	 */
 	void addEntry(const std::string& search_text);
 
-	LLSearchHistory();
 
 	/**
 	 * Class for storing data about single search request.
diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h
index bc50e443f80035b09cd354f691d871e9f0ccc2a1..c167ecd2360f65d75fe67bf0beabfa7bc385cc21 100644
--- a/indra/newview/llselectmgr.h
+++ b/indra/newview/llselectmgr.h
@@ -388,6 +388,9 @@ struct LLSelectGetFirstTest;
 
 class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 {
+	LLSINGLETON(LLSelectMgr);
+	~LLSelectMgr();
+
 public:
 	static BOOL					sRectSelectInclusive;	// do we need to surround an object to pick it?
 	static BOOL					sRenderHiddenSelections;	// do we show selection silhouettes that are occluded?
@@ -413,9 +416,6 @@ class LLSelectMgr : public LLEditMenuHandler, public LLSingleton<LLSelectMgr>
 	LLCachedControl<bool>					mDebugSelectMgr;
 
 public:
-	LLSelectMgr();
-	~LLSelectMgr();
-
 	static void cleanupGlobals();
 
 	// LLEditMenuHandler interface
diff --git a/indra/newview/llsnapshotlivepreview.cpp b/indra/newview/llsnapshotlivepreview.cpp
index 0b5c4eb9ae459aa15f4a72532e06b9f5c01442bd..58e48480c1ea9c252b8af93af8d92570efad0b15 100644
--- a/indra/newview/llsnapshotlivepreview.cpp
+++ b/indra/newview/llsnapshotlivepreview.cpp
@@ -1036,7 +1036,7 @@ void LLSnapshotLivePreview::saveTexture(BOOL outfit_snapshot, std::string name)
 		LLAgentUI::buildLocationString(pos_string, LLAgentUI::LOCATION_FORMAT_FULL);
 		std::string who_took_it;
 		LLAgentUI::buildFullname(who_took_it);
-		S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+		S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
         std::string res_name = outfit_snapshot ? name : "Snapshot : " + pos_string;
         std::string res_desc = outfit_snapshot ? "" : "Taken by " + who_took_it + " at " + pos_string;
         LLFolderType::EType folder_type = outfit_snapshot ? LLFolderType::FT_NONE : LLFolderType::FT_SNAPSHOT_CATEGORY;
diff --git a/indra/newview/llspeakers.h b/indra/newview/llspeakers.h
index 5cff70f37767cdf42aace17853c62923a548f2b0..617bae39844c3a3880031ab703ed7f87ea3ba8cf 100644
--- a/indra/newview/llspeakers.h
+++ b/indra/newview/llspeakers.h
@@ -341,20 +341,18 @@ class LLIMSpeakerMgr : public LLSpeakerMgr
 
 class LLActiveSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLActiveSpeakerMgr>
 {
+	LLSINGLETON(LLActiveSpeakerMgr);
 	LOG_CLASS(LLActiveSpeakerMgr);
 
-public:
-	LLActiveSpeakerMgr();
 protected:
 	virtual void updateSpeakerList();
 };
 
 class LLLocalSpeakerMgr : public LLSpeakerMgr, public LLSingleton<LLLocalSpeakerMgr>
 {
-	LOG_CLASS(LLLocalSpeakerMgr);
-public:
-	LLLocalSpeakerMgr();
+	LLSINGLETON(LLLocalSpeakerMgr);
 	~LLLocalSpeakerMgr ();
+	LOG_CLASS(LLLocalSpeakerMgr);
 protected:
 	virtual void updateSpeakerList();
 };
diff --git a/indra/newview/llspeakingindicatormanager.cpp b/indra/newview/llspeakingindicatormanager.cpp
index 78fe7863c8090226f197d9267ea4649e48a01e4f..5ca1d4b4a57d597c558f4594052f70ed31acacb3 100644
--- a/indra/newview/llspeakingindicatormanager.cpp
+++ b/indra/newview/llspeakingindicatormanager.cpp
@@ -48,6 +48,8 @@
  */
 class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, LLVoiceClientParticipantObserver
 {
+	LLSINGLETON(SpeakingIndicatorManager);
+	~SpeakingIndicatorManager();
 	LOG_CLASS(SpeakingIndicatorManager);
 public:
 
@@ -91,10 +93,6 @@ class SpeakingIndicatorManager : public LLSingleton<SpeakingIndicatorManager>, L
 	typedef speaking_indicators_mmap_t::const_iterator indicator_const_iterator;
 	typedef std::pair<indicator_const_iterator, indicator_const_iterator> indicator_range_t;
 
-	friend class LLSingleton<SpeakingIndicatorManager>;
-	SpeakingIndicatorManager();
-	~SpeakingIndicatorManager();
-
 	/**
 	 * Callback to determine when voice channel is changed.
 	 *
diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp
index 4e81d78455ef6ddd400b6c1db32d82e617985eaf..1bc20ccf12bcd13f77d098385205e4bf177c9421 100644
--- a/indra/newview/llstartup.cpp
+++ b/indra/newview/llstartup.cpp
@@ -193,6 +193,7 @@
 #include "llstartuplistener.h"
 #include "lltoolbarview.h"
 #include "llexperiencelog.h"
+#include "llcleanup.h"
 
 #if LL_WINDOWS
 #include "lldxhardware.h"
@@ -2808,7 +2809,7 @@ void LLStartUp::initExperiences()
 
 void LLStartUp::cleanupNameCache()
 {
-	LLAvatarNameCache::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLAvatarNameCache);
 
 	delete gCacheName;
 	gCacheName = NULL;
diff --git a/indra/newview/llstylemap.h b/indra/newview/llstylemap.h
index 8aa0af535c38f9aa062db679b52a6cb7da2d9c33..96b392059372bf38463a5b32c875fff1f0a678e5 100644
--- a/indra/newview/llstylemap.h
+++ b/indra/newview/llstylemap.h
@@ -39,6 +39,7 @@ typedef std::map<LLUUID, LLStyle::Params> style_map_t;
 
 class LLStyleMap : public LLSingleton<LLStyleMap>
 {
+	LLSINGLETON_EMPTY_CTOR(LLStyleMap);
 public:
 	// Just like the [] accessor but it will add the entry in if it doesn't exist.
 	const LLStyle::Params &lookupAgent(const LLUUID &source); 
diff --git a/indra/newview/llsyntaxid.h b/indra/newview/llsyntaxid.h
index 0afa6dc04ba2868e21f7600351991fea1a0c83ae..1360b3e042efc43b716d67d5341179ef00714e55 100644
--- a/indra/newview/llsyntaxid.h
+++ b/indra/newview/llsyntaxid.h
@@ -38,9 +38,9 @@ class fetchKeywordsFileResponder;
 
 class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
 {
-	friend class LLSingleton<LLSyntaxIdLSL>;
+	LLSINGLETON(LLSyntaxIdLSL);
 	friend class fetchKeywordsFileResponder;
-	
+
 private:
     std::set<std::string> mInflightFetches;
 	typedef boost::signals2::signal<void()> syntax_id_changed_signal_t;
@@ -67,7 +67,6 @@ class LLSyntaxIdLSL : public LLSingleton<LLSyntaxIdLSL>
 	LLSD			mKeywordsXml;
 	
 public:
-	LLSyntaxIdLSL();
 	void initialize();
 	bool keywordFetchInProgress();
 	LLSD getKeywordsXML() const { return mKeywordsXml; };
diff --git a/indra/newview/llsyswellwindow.h b/indra/newview/llsyswellwindow.h
index d02293e6fffa2fe595b9e75ef05a5ca0a5536e29..b96a2573a1f934f51054878676c6ed5bfe228092 100644
--- a/indra/newview/llsyswellwindow.h
+++ b/indra/newview/llsyswellwindow.h
@@ -32,6 +32,7 @@
 #include "llscreenchannel.h"
 #include "llsyswellitem.h"
 #include "lltransientdockablefloater.h"
+#include "llinitdestroyclass.h"
 
 class LLAvatarName;
 class LLChiclet;
diff --git a/indra/newview/llteleporthistory.h b/indra/newview/llteleporthistory.h
index e9c29c39bf3e945d91a57f4260d8ad705919f56d..db0ccdda59cec04280062ed2f148131c152df4c6 100644
--- a/indra/newview/llteleporthistory.h
+++ b/indra/newview/llteleporthistory.h
@@ -73,6 +73,8 @@ class LLTeleportHistoryItem
  */
 class LLTeleportHistory: public LLSingleton<LLTeleportHistory>
 {
+	LLSINGLETON(LLTeleportHistory);
+	~LLTeleportHistory();
 	LOG_CLASS(LLTeleportHistory);
 
 public:
@@ -81,9 +83,6 @@ class LLTeleportHistory: public LLSingleton<LLTeleportHistory>
 	typedef boost::function<void()>				history_callback_t;
 	typedef boost::signals2::signal<void()>		history_signal_t;
 	
-	LLTeleportHistory();
-	~LLTeleportHistory();
-
 	/**
 	 * Go back in the history.
 	 */
diff --git a/indra/newview/llteleporthistorystorage.h b/indra/newview/llteleporthistorystorage.h
index cf4c85a9910106a91c9f69be4cfe62dea049cb0a..946ac0af1aaed473bb4fd6e1adce22ae1a985708 100644
--- a/indra/newview/llteleporthistorystorage.h
+++ b/indra/newview/llteleporthistorystorage.h
@@ -68,6 +68,8 @@ class LLTeleportHistoryPersistentItem
  */
 class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 {
+	LLSINGLETON(LLTeleportHistoryStorage);
+	~LLTeleportHistoryStorage();
 	LOG_CLASS(LLTeleportHistoryStorage);
 
 public:
@@ -78,9 +80,6 @@ class LLTeleportHistoryStorage: public LLSingleton<LLTeleportHistoryStorage>
 	typedef boost::function<void(S32 removed_index)>		history_callback_t;
 	typedef boost::signals2::signal<void(S32 removed_index)>	history_signal_t;
 
-	LLTeleportHistoryStorage();
-	~LLTeleportHistoryStorage();
-
 	/**
 	 * @return history items.
 	 */
diff --git a/indra/newview/lltextureatlasmanager.h b/indra/newview/lltextureatlasmanager.h
index b643056198d9a2278969a8461e25c7f50848ab7a..1b8df708c6299abfb79bdb42e6da5bb76f693fa7 100644
--- a/indra/newview/lltextureatlasmanager.h
+++ b/indra/newview/lltextureatlasmanager.h
@@ -85,12 +85,11 @@ class LLTextureAtlasSlot : public LLRefCount
 
 class LLTextureAtlasManager : public LLSingleton<LLTextureAtlasManager>
 {
-private:
+	LLSINGLETON(LLTextureAtlasManager);
+	~LLTextureAtlasManager();
 	typedef std::list<LLPointer<LLTextureAtlas> > ll_texture_atlas_list_t ;
 
 public:
-	LLTextureAtlasManager();
-	~LLTextureAtlasManager();
 
 	LLPointer<LLTextureAtlasSlot> reserveAtlasSlot(S32 sub_texture_size, S8 ncomponents, 
 		LLSpatialGroup* groupp, LLViewerTexture* imagep) ;
diff --git a/indra/newview/lltoolbrush.h b/indra/newview/lltoolbrush.h
index 2ec6911de91e4520a1b461f6e3347d8009decf3d..c108d8325681b0f54317f5d5899f05444bcb5ae7 100644
--- a/indra/newview/lltoolbrush.h
+++ b/indra/newview/lltoolbrush.h
@@ -43,10 +43,10 @@ class LLViewerRegion;
 
 class LLToolBrushLand : public LLTool, public LLEditMenuHandler, public LLSingleton<LLToolBrushLand>
 {
+	LLSINGLETON(LLToolBrushLand);
 	typedef std::set<LLViewerRegion*> region_list_t;
 
 public:
-	LLToolBrushLand();
 	
 	// x,y in window coords, 0,0 = left,bot
 	virtual BOOL handleMouseDown( S32 x, S32 y, MASK mask );
diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp
index 2b4fa757f671e96c3dbf183400f2650c6361b9ca..d9adec82b48a32b8bb42591139463ff4cb18bea4 100644
--- a/indra/newview/lltoolcomp.cpp
+++ b/indra/newview/lltoolcomp.cpp
@@ -683,7 +683,7 @@ LLToolCompGun::LLToolCompGun()
 	: LLToolComposite(std::string("Mouselook"))
 {
 	mGun = new LLToolGun(this);
-	mGrab = new LLToolGrab(this);
+	mGrab = new LLToolGrabBase(this);
 	mNull = sNullTool;
 
 	setCurrentTool(mGun);
diff --git a/indra/newview/lltoolcomp.h b/indra/newview/lltoolcomp.h
index e75d3c22e28fb116af78f1106518b8601a57468f..86506f725ef4a93fa3563955759efa453589bd6c 100644
--- a/indra/newview/lltoolcomp.h
+++ b/indra/newview/lltoolcomp.h
@@ -103,9 +103,9 @@ class LLToolComposite : public LLTool
 
 class LLToolCompInspect : public LLToolComposite, public LLSingleton<LLToolCompInspect>
 {
-public:
-	LLToolCompInspect();
+	LLSINGLETON(LLToolCompInspect);
 	virtual ~LLToolCompInspect();
+public:
 
 	// Overridden from LLToolComposite
     virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
@@ -128,9 +128,9 @@ class LLToolCompInspect : public LLToolComposite, public LLSingleton<LLToolCompI
 
 class LLToolCompTranslate : public LLToolComposite, public LLSingleton<LLToolCompTranslate>
 {
-public:
-	LLToolCompTranslate();
+	LLSINGLETON(LLToolCompTranslate);
 	virtual ~LLToolCompTranslate();
+public:
 
 	// Overridden from LLToolComposite
 	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
@@ -149,9 +149,9 @@ class LLToolCompTranslate : public LLToolComposite, public LLSingleton<LLToolCom
 
 class LLToolCompScale : public LLToolComposite, public LLSingleton<LLToolCompScale>
 {
-public:
-	LLToolCompScale();
+	LLSINGLETON(LLToolCompScale);
 	virtual ~LLToolCompScale();
+public:
 
 	// Overridden from LLToolComposite
     virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
@@ -171,9 +171,9 @@ class LLToolCompScale : public LLToolComposite, public LLSingleton<LLToolCompSca
 
 class LLToolCompRotate : public LLToolComposite, public LLSingleton<LLToolCompRotate>
 {
-public:
-	LLToolCompRotate();
+	LLSINGLETON(LLToolCompRotate);
 	virtual ~LLToolCompRotate();
+public:
 
 	// Overridden from LLToolComposite
     virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
@@ -194,9 +194,9 @@ class LLToolCompRotate : public LLToolComposite, public LLSingleton<LLToolCompRo
 
 class LLToolCompCreate : public LLToolComposite, public LLSingleton<LLToolCompCreate>
 {
-public:
-	LLToolCompCreate();
+	LLSINGLETON(LLToolCompCreate);
 	virtual ~LLToolCompCreate();
+public:
 
 	// Overridden from LLToolComposite
     virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
@@ -214,14 +214,14 @@ class LLToolCompCreate : public LLToolComposite, public LLSingleton<LLToolCompCr
 // LLToolCompGun
 
 class LLToolGun;
-class LLToolGrab;
+class LLToolGrabBase;
 class LLToolSelect;
 
 class LLToolCompGun : public LLToolComposite, public LLSingleton<LLToolCompGun>
 {
-public:
-	LLToolCompGun();
+	LLSINGLETON(LLToolCompGun);
 	virtual ~LLToolCompGun();
+public:
 
 	// Overridden from LLToolComposite
     virtual BOOL			handleHover(S32 x, S32 y, MASK mask);
@@ -237,7 +237,7 @@ class LLToolCompGun : public LLToolComposite, public LLSingleton<LLToolCompGun>
 
 protected:
 	LLToolGun*			mGun;
-	LLToolGrab*			mGrab;
+	LLToolGrabBase*		mGrab;
 	LLTool*				mNull;
 };
 
diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h
index 63be1ef09b2b94beb88421c02d152139540f7b6b..766046785b6cd13ac7e0ddc0d45a4528faeb6f7a 100644
--- a/indra/newview/lltooldraganddrop.h
+++ b/indra/newview/lltooldraganddrop.h
@@ -43,11 +43,10 @@ class LLPickInfo;
 
 class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 {
+	LLSINGLETON(LLToolDragAndDrop);
 public:
 	typedef boost::signals2::signal<void ()> enddrag_signal_t;
 
-	LLToolDragAndDrop();
-
 	// overridden from LLTool
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
@@ -281,8 +280,8 @@ class LLToolDragAndDrop : public LLTool, public LLSingleton<LLToolDragAndDrop>
 	class LLDragAndDropDictionary : public LLSingleton<LLDragAndDropDictionary>,
 									public LLDictionary<EDragAndDropType, DragAndDropEntry>
 	{
+		LLSINGLETON(LLDragAndDropDictionary);
 	public:
-		LLDragAndDropDictionary();
 		dragOrDrop3dImpl get(EDragAndDropType dad_type, EDropTarget drop_target);
 	};
 };
diff --git a/indra/newview/lltoolface.h b/indra/newview/lltoolface.h
index 7eb13b0fbcf2c4edf6a9969e7a20eb12ade009c2..e4b8ae12b87d4a62e95e727feee1527acc97b149 100644
--- a/indra/newview/lltoolface.h
+++ b/indra/newview/lltoolface.h
@@ -35,9 +35,9 @@ class LLPickInfo;
 class LLToolFace
 :	public LLTool, public LLSingleton<LLToolFace>
 {
-public:
-	LLToolFace();
+	LLSINGLETON(LLToolFace);
 	virtual ~LLToolFace();
+public:
 
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleDoubleClick(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolfocus.h b/indra/newview/lltoolfocus.h
index d23eb2cce63196a4b92a6a877df0539912f4298b..cfc235b6c2a411fba999d95e0de805f7fb13b532 100644
--- a/indra/newview/lltoolfocus.h
+++ b/indra/newview/lltoolfocus.h
@@ -34,9 +34,9 @@ class LLPickInfo;
 class LLToolCamera
 :	public LLTool, public LLSingleton<LLToolCamera>
 {
-public:
-	LLToolCamera();
+	LLSINGLETON(LLToolCamera);
 	virtual ~LLToolCamera();
+public:
 
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolgrab.cpp b/indra/newview/lltoolgrab.cpp
index c0ca4d7a9a4737fa316e3622e3f5cbf577f124b6..ed32e584a5aa86691a594e6ad3418f0795dc773b 100644
--- a/indra/newview/lltoolgrab.cpp
+++ b/indra/newview/lltoolgrab.cpp
@@ -69,7 +69,7 @@ extern BOOL gDebugClicks;
 //
 // Methods
 //
-LLToolGrab::LLToolGrab( LLToolComposite* composite )
+LLToolGrabBase::LLToolGrabBase( LLToolComposite* composite )
 :	LLTool( std::string("Grab"), composite ),
 	mMode( GRAB_INACTIVE ),
 	mVerticalDragging( FALSE ),
@@ -88,12 +88,12 @@ LLToolGrab::LLToolGrab( LLToolComposite* composite )
 	mHideBuildHighlight(FALSE)
 { }
 
-LLToolGrab::~LLToolGrab()
+LLToolGrabBase::~LLToolGrabBase()
 { }
 
 
 // virtual
-void LLToolGrab::handleSelect()
+void LLToolGrabBase::handleSelect()
 {
 	if(gFloaterTools)
 	{
@@ -106,7 +106,7 @@ void LLToolGrab::handleSelect()
 	gGrabBtnSpin = FALSE;
 }
 
-void LLToolGrab::handleDeselect()
+void LLToolGrabBase::handleDeselect()
 {
 	if( hasMouseCapture() )
 	{
@@ -123,7 +123,7 @@ void LLToolGrab::handleDeselect()
 
 }
 
-BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask)
+BOOL LLToolGrabBase::handleDoubleClick(S32 x, S32 y, MASK mask)
 {
 	if (gDebugClicks)
 	{
@@ -133,7 +133,7 @@ BOOL LLToolGrab::handleDoubleClick(S32 x, S32 y, MASK mask)
 	return FALSE;
 }
 
-BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
+BOOL LLToolGrabBase::handleMouseDown(S32 x, S32 y, MASK mask)
 {
 	if (gDebugClicks)
 	{
@@ -152,7 +152,7 @@ BOOL LLToolGrab::handleMouseDown(S32 x, S32 y, MASK mask)
 	return TRUE;
 }
 
-void LLToolGrab::pickCallback(const LLPickInfo& pick_info)
+void LLToolGrabBase::pickCallback(const LLPickInfo& pick_info)
 {
 	LLToolGrab::getInstance()->mGrabPick = pick_info;
 	LLViewerObject	*objectp = pick_info.getObject();
@@ -182,7 +182,7 @@ void LLToolGrab::pickCallback(const LLPickInfo& pick_info)
 	}
 }
 
-BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
+BOOL LLToolGrabBase::handleObjectHit(const LLPickInfo& info)
 {
 	mGrabPick = info;
 	LLViewerObject* objectp = mGrabPick.getObject();
@@ -315,7 +315,7 @@ BOOL LLToolGrab::handleObjectHit(const LLPickInfo& info)
 }
 
 
-void LLToolGrab::startSpin()
+void LLToolGrabBase::startSpin()
 {
 	LLViewerObject* objectp = mGrabPick.getObject();
 	if (!objectp)
@@ -339,7 +339,7 @@ void LLToolGrab::startSpin()
 }
 
 
-void LLToolGrab::stopSpin()
+void LLToolGrabBase::stopSpin()
 {
 	mSpinGrabbing = FALSE;
 
@@ -373,7 +373,7 @@ void LLToolGrab::stopSpin()
 }
 
 
-void LLToolGrab::startGrab()
+void LLToolGrabBase::startGrab()
 {
 	// Compute grab_offset in the OBJECT's root's coordinate frame
 	// (sometimes root == object)
@@ -422,7 +422,7 @@ void LLToolGrab::startGrab()
 }
 
 
-BOOL LLToolGrab::handleHover(S32 x, S32 y, MASK mask)
+BOOL LLToolGrabBase::handleHover(S32 x, S32 y, MASK mask)
 {
 	if (!gViewerWindow->getLeftMouseDown())
 	{
@@ -466,7 +466,7 @@ const F32 GRAB_SENSITIVITY_Y = 0.0075f;
 
 		
 // Dragging.
-void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
+void LLToolGrabBase::handleHoverActive(S32 x, S32 y, MASK mask)
 {
 	LLViewerObject* objectp = mGrabPick.getObject();
 	if (!objectp || !hasMouseCapture() ) return;
@@ -724,7 +724,7 @@ void LLToolGrab::handleHoverActive(S32 x, S32 y, MASK mask)
 }
  
 
-void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
+void LLToolGrabBase::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
 {
 	LLViewerObject* objectp = mGrabPick.getObject();
 	if (!objectp || !hasMouseCapture() ) return;
@@ -881,7 +881,7 @@ void LLToolGrab::handleHoverNonPhysical(S32 x, S32 y, MASK mask)
  
 
 // Not dragging.  Just showing affordances
-void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
+void LLToolGrabBase::handleHoverInactive(S32 x, S32 y, MASK mask)
 {
 	// JC - TODO - change cursor based on gGrabBtnVertical, gGrabBtnSpin
 	LL_DEBUGS("UserInput") << "hover handled by LLToolGrab (inactive-not over editable object)" << LL_ENDL;		
@@ -889,7 +889,7 @@ void LLToolGrab::handleHoverInactive(S32 x, S32 y, MASK mask)
 }
 
 // User is trying to do something that's not allowed.
-void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask)
+void LLToolGrabBase::handleHoverFailed(S32 x, S32 y, MASK mask)
 {
 	if( GRAB_NOOBJECT == mMode )
 	{
@@ -930,7 +930,7 @@ void LLToolGrab::handleHoverFailed(S32 x, S32 y, MASK mask)
 
 
 
-BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask)
+BOOL LLToolGrabBase::handleMouseUp(S32 x, S32 y, MASK mask)
 {
 	// call the base class to propogate info to sim
 	LLTool::handleMouseUp(x, y, mask);
@@ -961,7 +961,7 @@ BOOL LLToolGrab::handleMouseUp(S32 x, S32 y, MASK mask)
 	return TRUE;
 } 
 
-void LLToolGrab::stopEditing()
+void LLToolGrabBase::stopEditing()
 {
 	if( hasMouseCapture() )
 	{
@@ -969,7 +969,7 @@ void LLToolGrab::stopEditing()
 	}
 }
 
-void LLToolGrab::onMouseCaptureLost()
+void LLToolGrabBase::onMouseCaptureLost()
 {
 	LLViewerObject* objectp = mGrabPick.getObject();
 	if (!objectp)
@@ -1026,7 +1026,7 @@ void LLToolGrab::onMouseCaptureLost()
 }
 
 
-void LLToolGrab::stopGrab()
+void LLToolGrabBase::stopGrab()
 {
 	LLViewerObject* objectp = mGrabPick.getObject();
 	if (!objectp)
@@ -1067,29 +1067,29 @@ void LLToolGrab::stopGrab()
 }
 
 
-void LLToolGrab::draw()
+void LLToolGrabBase::draw()
 { }
 
-void LLToolGrab::render()
+void LLToolGrabBase::render()
 { }
 
-BOOL LLToolGrab::isEditing()
+BOOL LLToolGrabBase::isEditing()
 {
 	return (mGrabPick.getObject().notNull());
 }
 
-LLViewerObject* LLToolGrab::getEditingObject()
+LLViewerObject* LLToolGrabBase::getEditingObject()
 {
 	return mGrabPick.getObject();
 }
 
 
-LLVector3d LLToolGrab::getEditingPointGlobal()
+LLVector3d LLToolGrabBase::getEditingPointGlobal()
 {
 	return getGrabPointGlobal();
 }
 
-LLVector3d LLToolGrab::getGrabPointGlobal()
+LLVector3d LLToolGrabBase::getGrabPointGlobal()
 {
 	switch(mMode)
 	{
diff --git a/indra/newview/lltoolgrab.h b/indra/newview/lltoolgrab.h
index 5d24c8813e4dcfef52c968aacf2ab91e909a1d13..02ed5c26d752c9ffb3eeddaf0cf73ca7002a8f1f 100644
--- a/indra/newview/lltoolgrab.h
+++ b/indra/newview/lltoolgrab.h
@@ -45,12 +45,17 @@ void send_ObjectGrab_message(LLViewerObject* object, const LLPickInfo & pick, co
 void send_ObjectDeGrab_message(LLViewerObject* object, const LLPickInfo & pick);
 
 
-
-class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab>
+/**
+ * LLToolGrabBase contains most of the semantics of LLToolGrab. It's just that
+ * LLToolGrab is an LLSingleton, but we also explicitly instantiate
+ * LLToolGrabBase as part of LLToolCompGun. You can't just make an extra
+ * instance of an LLSingleton!
+ */
+class LLToolGrabBase : public LLTool
 {
 public:
-	LLToolGrab( LLToolComposite* composite = NULL );
-	~LLToolGrab();
+	LLToolGrabBase(LLToolComposite* composite=NULL);
+	~LLToolGrabBase();
 
 	/*virtual*/ BOOL	handleHover(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
@@ -140,10 +145,14 @@ class LLToolGrab : public LLTool, public LLSingleton<LLToolGrab>
 	BOOL			mClickedInMouselook;
 };
 
+/// This is the LLSingleton instance of LLToolGrab.
+class LLToolGrab : public LLToolGrabBase, public LLSingleton<LLToolGrab>
+{
+	LLSINGLETON_EMPTY_CTOR(LLToolGrab);
+};
+
 extern BOOL gGrabBtnVertical;
 extern BOOL gGrabBtnSpin;
 extern LLTool* gGrabTransientTool;
 
 #endif  // LL_TOOLGRAB_H
-
-
diff --git a/indra/newview/lltoolindividual.h b/indra/newview/lltoolindividual.h
index 961a6a4d93d4c49f27f717acca790363dd8012c0..e7c2060fba01909da6a84bc444dc7f03d9e256bf 100644
--- a/indra/newview/lltoolindividual.h
+++ b/indra/newview/lltoolindividual.h
@@ -39,9 +39,9 @@ class LLPickInfo;
 
 class LLToolIndividual : public LLTool, public LLSingleton<LLToolIndividual>
 {
-public:
-	LLToolIndividual();
+	LLSINGLETON(LLToolIndividual);
 	virtual ~LLToolIndividual();
+public:
 
 	virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL handleDoubleClick(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolmgr.h b/indra/newview/lltoolmgr.h
index e5b45750d900f6fb2eebe1faea562f736f0748ea..28465d5d2cd1e83de8cbe1829bfd840822413fe9 100644
--- a/indra/newview/lltoolmgr.h
+++ b/indra/newview/lltoolmgr.h
@@ -42,9 +42,9 @@ const MASK MASK_COPY			= MASK_SHIFT;
 
 class LLToolMgr : public LLSingleton<LLToolMgr>
 {
-public:
-	LLToolMgr();
+	LLSINGLETON(LLToolMgr);
 	~LLToolMgr();
+public:
 
 	// Must be called after gSavedSettings set up.
 	void			initTools();
diff --git a/indra/newview/lltoolobjpicker.h b/indra/newview/lltoolobjpicker.h
index 0c37be1f92471fbb87d0203b1b57d923b06b62e7..5ad9b67e217859e85709603b33b0ea29b775e53b 100644
--- a/indra/newview/lltoolobjpicker.h
+++ b/indra/newview/lltoolobjpicker.h
@@ -35,8 +35,8 @@ class LLPickInfo;
 
 class LLToolObjPicker : public LLTool, public LLSingleton<LLToolObjPicker>
 {
+	LLSINGLETON(LLToolObjPicker);
 public:
-	LLToolObjPicker();
 
 	virtual BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL		handleMouseUp(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolpie.h b/indra/newview/lltoolpie.h
index 6391e675c551a7c7ffbf846097adbea8034a8352..95d155a474a4ea1005df415b3784524794bfb906 100644
--- a/indra/newview/lltoolpie.h
+++ b/indra/newview/lltoolpie.h
@@ -37,9 +37,9 @@ class LLObjectSelection;
 
 class LLToolPie : public LLTool, public LLSingleton<LLToolPie>
 {
+	LLSINGLETON(LLToolPie);
 	LOG_CLASS(LLToolPie);
 public:
-	LLToolPie( );
 
 	// Virtual functions inherited from LLMouseHandler
 	virtual BOOL		handleAnyMouseClick(S32 x, S32 y, MASK mask, EClickType clicktype, BOOL down);
diff --git a/indra/newview/lltoolpipette.h b/indra/newview/lltoolpipette.h
index 8a83bf31af641534257bcc459aeb94940d2d2608..7575d8ad18454b60ad66451af839338b4efdc6d0 100644
--- a/indra/newview/lltoolpipette.h
+++ b/indra/newview/lltoolpipette.h
@@ -43,10 +43,10 @@ class LLPickInfo;
 class LLToolPipette
 :	public LLTool, public LLSingleton<LLToolPipette>
 {
-public:
-	LLToolPipette();
+	LLSINGLETON(LLToolPipette);
 	virtual ~LLToolPipette();
 
+public:
 	virtual BOOL	handleMouseDown(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleMouseUp(S32 x, S32 y, MASK mask);
 	virtual BOOL	handleHover(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltoolselectland.h b/indra/newview/lltoolselectland.h
index b368a4b1533e8f69d2ad2afd797724f9615c3950..b5ba72f16d5d0073e3bcb6127cf12c136b1352c4 100644
--- a/indra/newview/lltoolselectland.h
+++ b/indra/newview/lltoolselectland.h
@@ -35,10 +35,10 @@ class LLParcelSelection;
 class LLToolSelectLand
 :	public LLTool, public LLSingleton<LLToolSelectLand>
 {
-public:
-	LLToolSelectLand( );
+	LLSINGLETON(LLToolSelectLand);
 	virtual ~LLToolSelectLand();
 
+public:
 	/*virtual*/ BOOL		handleMouseDown(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL		handleDoubleClick(S32 x, S32 y, MASK mask);
 	/*virtual*/ BOOL		handleMouseUp(S32 x, S32 y, MASK mask);
diff --git a/indra/newview/lltransientfloatermgr.h b/indra/newview/lltransientfloatermgr.h
index b4611c8c87bb4d2954938fba16110e08d9c72a06..d126543f1535b9cec4128121c1ff500d954c428e 100644
--- a/indra/newview/lltransientfloatermgr.h
+++ b/indra/newview/lltransientfloatermgr.h
@@ -38,9 +38,7 @@ class LLTransientFloater;
  */
 class LLTransientFloaterMgr: public LLSingleton<LLTransientFloaterMgr>
 {
-protected:
-	LLTransientFloaterMgr();
-	friend class LLSingleton<LLTransientFloaterMgr>;
+	LLSINGLETON(LLTransientFloaterMgr);
 
 public:
 	enum ETransientGroup
diff --git a/indra/newview/lltwitterconnect.h b/indra/newview/lltwitterconnect.h
index be481a17c10b9f4e27f97dea1cd8c79145f2150f..e77048cc35112390873121dd5dd4e2797ff8e674 100644
--- a/indra/newview/lltwitterconnect.h
+++ b/indra/newview/lltwitterconnect.h
@@ -43,6 +43,7 @@ class LLEventPump;
  */
 class LLTwitterConnect : public LLSingleton<LLTwitterConnect>
 {
+	LLSINGLETON(LLTwitterConnect);
 	LOG_CLASS(LLTwitterConnect);
 public:
     enum EConnectionState
@@ -81,10 +82,7 @@ class LLTwitterConnect : public LLSingleton<LLTwitterConnect>
     void openTwitterWeb(std::string url);
 
 private:
-	friend class LLSingleton<LLTwitterConnect>;
 
-	LLTwitterConnect();
-	~LLTwitterConnect() {};
  	std::string getTwitterConnectURL(const std::string& route = "", bool include_read_from_master = false);
 
     EConnectionState mConnectionState;
diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp
index 08ba5a5f252cebade2b4399a5fda49e2a0f332c5..ad0c1734f9fd132b12eb91f39e5434d5cefdf06f 100644
--- a/indra/newview/llviewerassettype.cpp
+++ b/indra/newview/llviewerassettype.cpp
@@ -48,8 +48,7 @@ struct ViewerAssetEntry : public LLDictionaryEntry
 class LLViewerAssetDictionary : public LLSingleton<LLViewerAssetDictionary>,
 						  public LLDictionary<LLViewerAssetType::EType, ViewerAssetEntry>
 {
-public:
-	LLViewerAssetDictionary();
+	LLSINGLETON(LLViewerAssetDictionary);
 };
 
 LLViewerAssetDictionary::LLViewerAssetDictionary()
diff --git a/indra/newview/llviewerassetupload.cpp b/indra/newview/llviewerassetupload.cpp
index 94f1b09fa9d1e83d0a2380502705ccdff0af5173..4271b20ad6e7b56b08167f51351a41b99f2e616f 100644
--- a/indra/newview/llviewerassetupload.cpp
+++ b/indra/newview/llviewerassetupload.cpp
@@ -174,7 +174,7 @@ S32 LLResourceUploadInfo::getEconomyUploadCost()
         getAssetType() == LLAssetType::AT_ANIMATION ||
         getAssetType() == LLAssetType::AT_MESH)
     {
-        return LLGlobalEconomy::Singleton::instance().getPriceUpload();
+        return LLGlobalEconomy::instance().getPriceUpload();
     }
 
     return 0;
diff --git a/indra/newview/llvieweraudio.h b/indra/newview/llvieweraudio.h
index 8c302c65492456033c91401557c2474472321be9..16f9b63113d88699a0ffb8d74fe459decc9e8366 100644
--- a/indra/newview/llvieweraudio.h
+++ b/indra/newview/llvieweraudio.h
@@ -43,6 +43,9 @@ void audio_update_wind(bool force_update = true);
 
 class LLViewerAudio : public LLSingleton<LLViewerAudio>
 {
+	LLSINGLETON(LLViewerAudio);
+	virtual ~LLViewerAudio();
+
 public:
 
 	enum EFadeState
@@ -52,9 +55,6 @@ class LLViewerAudio : public LLSingleton<LLViewerAudio>
 		FADE_OUT,
 	};
 
-	LLViewerAudio();
-	virtual ~LLViewerAudio();
-	
 	void startInternetStreamWithAutoFade(std::string streamURI);
 	void stopInternetStreamWithAutoFade();
 	
diff --git a/indra/newview/llviewercamera.h b/indra/newview/llviewercamera.h
index 7b2887d725b5458979a437725676bc5b6d824890..f8c973690a08aff2a3d26111348da4a931beb3ba 100644
--- a/indra/newview/llviewercamera.h
+++ b/indra/newview/llviewercamera.h
@@ -54,6 +54,7 @@ extern template class LLViewerCamera* LLSingleton<class LLViewerCamera>::getInst
 LL_ALIGN_PREFIX(16)
 class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
 {
+	LLSINGLETON(LLViewerCamera);
 public:
 	void* operator new(size_t size)
 	{
@@ -82,8 +83,6 @@ class LLViewerCamera : public LLCamera, public LLSingleton<LLViewerCamera>
 
 	static eCameraID sCurCameraID;
 
-	LLViewerCamera();
-
 	void updateCameraLocation(const LLVector3 &center,
 								const LLVector3 &up_direction,
 								const LLVector3 &point_of_interest);
diff --git a/indra/newview/llviewerfoldertype.cpp b/indra/newview/llviewerfoldertype.cpp
index b8ff2cc9b4fee36e2bff7a9d220b6c76a62ff606..9cb2e0336a337a0786b1bd1892e4cf05c63faef7 100644
--- a/indra/newview/llviewerfoldertype.cpp
+++ b/indra/newview/llviewerfoldertype.cpp
@@ -103,8 +103,7 @@ struct ViewerFolderEntry : public LLDictionaryEntry
 class LLViewerFolderDictionary : public LLSingleton<LLViewerFolderDictionary>,
 								 public LLDictionary<LLFolderType::EType, ViewerFolderEntry>
 {
-public:
-	LLViewerFolderDictionary();
+	LLSINGLETON(LLViewerFolderDictionary);
 protected:
 	bool initEnsemblesFromFile(); // Reads in ensemble information from foldertypes.xml
 };
diff --git a/indra/newview/llviewerhelp.h b/indra/newview/llviewerhelp.h
index a983012e2ee4ca9025b8a39c0d6896a33f6a2bfc..da50e07a4362a092c2241e26929dbf6be5f52a87 100644
--- a/indra/newview/llviewerhelp.h
+++ b/indra/newview/llviewerhelp.h
@@ -39,7 +39,7 @@ class LLUICtrl;
 
 class LLViewerHelp : public LLHelp, public LLSingleton<LLViewerHelp>
 {
-	friend class LLSingleton<LLViewerHelp>;
+	LLSINGLETON_EMPTY_CTOR(LLViewerHelp);
 
  public:
 	/// display the specified help topic in the help viewer
diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp
index 434641aa257c998a4b541adbfcc2bec303c8c05e..87d8f753b84a8b8e63e2c7477362d366322dd7e7 100644
--- a/indra/newview/llviewerinventory.cpp
+++ b/indra/newview/llviewerinventory.cpp
@@ -94,107 +94,10 @@ void doInventoryCb(LLPointer<LLInventoryCallback> cb, LLUUID id)
 ///----------------------------------------------------------------------------
 class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInventoryItemsDictionary>
 {
+	LLSINGLETON(LLLocalizedInventoryItemsDictionary);
 public:
 	std::map<std::string, std::string> mInventoryItemsDict;
 
-	LLLocalizedInventoryItemsDictionary()
-	{
-		mInventoryItemsDict["New Shape"]		= LLTrans::getString("New Shape");
-		mInventoryItemsDict["New Skin"]			= LLTrans::getString("New Skin");
-		mInventoryItemsDict["New Hair"]			= LLTrans::getString("New Hair");
-		mInventoryItemsDict["New Eyes"]			= LLTrans::getString("New Eyes");
-		mInventoryItemsDict["New Shirt"]		= LLTrans::getString("New Shirt");
-		mInventoryItemsDict["New Pants"]		= LLTrans::getString("New Pants");
-		mInventoryItemsDict["New Shoes"]		= LLTrans::getString("New Shoes");
-		mInventoryItemsDict["New Socks"]		= LLTrans::getString("New Socks");
-		mInventoryItemsDict["New Jacket"]		= LLTrans::getString("New Jacket");
-		mInventoryItemsDict["New Gloves"]		= LLTrans::getString("New Gloves");
-		mInventoryItemsDict["New Undershirt"]	= LLTrans::getString("New Undershirt");
-		mInventoryItemsDict["New Underpants"]	= LLTrans::getString("New Underpants");
-		mInventoryItemsDict["New Skirt"]		= LLTrans::getString("New Skirt");
-		mInventoryItemsDict["New Alpha"]		= LLTrans::getString("New Alpha");
-		mInventoryItemsDict["New Tattoo"]		= LLTrans::getString("New Tattoo");
-		mInventoryItemsDict["New Physics"]		= LLTrans::getString("New Physics");
-		mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
-
-		mInventoryItemsDict["New Gesture"]		= LLTrans::getString("New Gesture");
-		mInventoryItemsDict["New Script"]		= LLTrans::getString("New Script");
-		mInventoryItemsDict["New Folder"]		= LLTrans::getString("New Folder");
-		mInventoryItemsDict["New Note"]			= LLTrans::getString("New Note");
-		mInventoryItemsDict["Contents"]			= LLTrans::getString("Contents");
-
-		mInventoryItemsDict["Gesture"]			= LLTrans::getString("Gesture");
-		mInventoryItemsDict["Male Gestures"]	= LLTrans::getString("Male Gestures");
-		mInventoryItemsDict["Female Gestures"]	= LLTrans::getString("Female Gestures");
-		mInventoryItemsDict["Other Gestures"]	= LLTrans::getString("Other Gestures");
-		mInventoryItemsDict["Speech Gestures"]	= LLTrans::getString("Speech Gestures");
-		mInventoryItemsDict["Common Gestures"]	= LLTrans::getString("Common Gestures");
-
-		//predefined gestures
-
-		//male
-		mInventoryItemsDict["Male - Excuse me"]			= LLTrans::getString("Male - Excuse me");
-		mInventoryItemsDict["Male  - Get lost"]			= LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319
-		mInventoryItemsDict["Male - Blow kiss"]			= LLTrans::getString("Male - Blow kiss");
-		mInventoryItemsDict["Male - Boo"]				= LLTrans::getString("Male - Boo");
-		mInventoryItemsDict["Male - Bored"]				= LLTrans::getString("Male - Bored");
-		mInventoryItemsDict["Male - Hey"]				= LLTrans::getString("Male - Hey");
-		mInventoryItemsDict["Male - Laugh"]				= LLTrans::getString("Male - Laugh");
-		mInventoryItemsDict["Male - Repulsed"]			= LLTrans::getString("Male - Repulsed");
-		mInventoryItemsDict["Male - Shrug"]				= LLTrans::getString("Male - Shrug");
-		mInventoryItemsDict["Male - Stick tougue out"]	= LLTrans::getString("Male - Stick tougue out");
-		mInventoryItemsDict["Male - Wow"]				= LLTrans::getString("Male - Wow");
-
-		//female
-		mInventoryItemsDict["Female - Chuckle"]			= LLTrans::getString("Female - Chuckle");
-		mInventoryItemsDict["Female - Cry"]				= LLTrans::getString("Female - Cry");
-		mInventoryItemsDict["Female - Embarrassed"]		= LLTrans::getString("Female - Embarrassed");
-		mInventoryItemsDict["Female - Excuse me"]		= LLTrans::getString("Female - Excuse me");
-		mInventoryItemsDict["Female  - Get lost"]		= LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319
-		mInventoryItemsDict["Female - Blow kiss"]		= LLTrans::getString("Female - Blow kiss");
-		mInventoryItemsDict["Female - Boo"]				= LLTrans::getString("Female - Boo");
-		mInventoryItemsDict["Female - Bored"]			= LLTrans::getString("Female - Bored");
-		mInventoryItemsDict["Female - Hey"]				= LLTrans::getString("Female - Hey");
-		mInventoryItemsDict["Female - Hey baby"]		= LLTrans::getString("Female - Hey baby");
-		mInventoryItemsDict["Female - Laugh"]			= LLTrans::getString("Female - Laugh");
-		mInventoryItemsDict["Female - Looking good"]	= LLTrans::getString("Female - Looking good");
-		mInventoryItemsDict["Female - Over here"]		= LLTrans::getString("Female - Over here");
-		mInventoryItemsDict["Female - Please"]			= LLTrans::getString("Female - Please");
-		mInventoryItemsDict["Female - Repulsed"]		= LLTrans::getString("Female - Repulsed");
-		mInventoryItemsDict["Female - Shrug"]			= LLTrans::getString("Female - Shrug");
-		mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out");
-		mInventoryItemsDict["Female - Wow"]				= LLTrans::getString("Female - Wow");
-
-		//common
-		mInventoryItemsDict["/bow"]						= LLTrans::getString("/bow");
-		mInventoryItemsDict["/clap"]					= LLTrans::getString("/clap");
-		mInventoryItemsDict["/count"]					= LLTrans::getString("/count");
-		mInventoryItemsDict["/extinguish"]				= LLTrans::getString("/extinguish");
-		mInventoryItemsDict["/kmb"]						= LLTrans::getString("/kmb");
-		mInventoryItemsDict["/muscle"]					= LLTrans::getString("/muscle");
-		mInventoryItemsDict["/no"]						= LLTrans::getString("/no");
-		mInventoryItemsDict["/no!"]						= LLTrans::getString("/no!");
-		mInventoryItemsDict["/paper"]					= LLTrans::getString("/paper");
-		mInventoryItemsDict["/pointme"]					= LLTrans::getString("/pointme");
-		mInventoryItemsDict["/pointyou"]				= LLTrans::getString("/pointyou");
-		mInventoryItemsDict["/rock"]					= LLTrans::getString("/rock");
-		mInventoryItemsDict["/scissor"]					= LLTrans::getString("/scissor");
-		mInventoryItemsDict["/smoke"]					= LLTrans::getString("/smoke");
-		mInventoryItemsDict["/stretch"]					= LLTrans::getString("/stretch");
-		mInventoryItemsDict["/whistle"]					= LLTrans::getString("/whistle");
-		mInventoryItemsDict["/yes"]						= LLTrans::getString("/yes");
-		mInventoryItemsDict["/yes!"]					= LLTrans::getString("/yes!");
-		mInventoryItemsDict["afk"]						= LLTrans::getString("afk");
-		mInventoryItemsDict["dance1"]					= LLTrans::getString("dance1");
-		mInventoryItemsDict["dance2"]					= LLTrans::getString("dance2");
-		mInventoryItemsDict["dance3"]					= LLTrans::getString("dance3");
-		mInventoryItemsDict["dance4"]					= LLTrans::getString("dance4");
-		mInventoryItemsDict["dance5"]					= LLTrans::getString("dance5");
-		mInventoryItemsDict["dance6"]					= LLTrans::getString("dance6");
-		mInventoryItemsDict["dance7"]					= LLTrans::getString("dance7");
-		mInventoryItemsDict["dance8"]					= LLTrans::getString("dance8");
-	}
-
 	/**
 	 * Finds passed name in dictionary and replaces it with found localized value.
 	 *
@@ -217,6 +120,103 @@ class LLLocalizedInventoryItemsDictionary : public LLSingleton<LLLocalizedInvent
 	}
 };
 
+LLLocalizedInventoryItemsDictionary::LLLocalizedInventoryItemsDictionary()
+{
+	mInventoryItemsDict["New Shape"]		= LLTrans::getString("New Shape");
+	mInventoryItemsDict["New Skin"]			= LLTrans::getString("New Skin");
+	mInventoryItemsDict["New Hair"]			= LLTrans::getString("New Hair");
+	mInventoryItemsDict["New Eyes"]			= LLTrans::getString("New Eyes");
+	mInventoryItemsDict["New Shirt"]		= LLTrans::getString("New Shirt");
+	mInventoryItemsDict["New Pants"]		= LLTrans::getString("New Pants");
+	mInventoryItemsDict["New Shoes"]		= LLTrans::getString("New Shoes");
+	mInventoryItemsDict["New Socks"]		= LLTrans::getString("New Socks");
+	mInventoryItemsDict["New Jacket"]		= LLTrans::getString("New Jacket");
+	mInventoryItemsDict["New Gloves"]		= LLTrans::getString("New Gloves");
+	mInventoryItemsDict["New Undershirt"]	= LLTrans::getString("New Undershirt");
+	mInventoryItemsDict["New Underpants"]	= LLTrans::getString("New Underpants");
+	mInventoryItemsDict["New Skirt"]		= LLTrans::getString("New Skirt");
+	mInventoryItemsDict["New Alpha"]		= LLTrans::getString("New Alpha");
+	mInventoryItemsDict["New Tattoo"]		= LLTrans::getString("New Tattoo");
+	mInventoryItemsDict["New Physics"]		= LLTrans::getString("New Physics");
+	mInventoryItemsDict["Invalid Wearable"] = LLTrans::getString("Invalid Wearable");
+
+	mInventoryItemsDict["New Gesture"]		= LLTrans::getString("New Gesture");
+	mInventoryItemsDict["New Script"]		= LLTrans::getString("New Script");
+	mInventoryItemsDict["New Folder"]		= LLTrans::getString("New Folder");
+	mInventoryItemsDict["New Note"]			= LLTrans::getString("New Note");
+	mInventoryItemsDict["Contents"]			= LLTrans::getString("Contents");
+
+	mInventoryItemsDict["Gesture"]			= LLTrans::getString("Gesture");
+	mInventoryItemsDict["Male Gestures"]	= LLTrans::getString("Male Gestures");
+	mInventoryItemsDict["Female Gestures"]	= LLTrans::getString("Female Gestures");
+	mInventoryItemsDict["Other Gestures"]	= LLTrans::getString("Other Gestures");
+	mInventoryItemsDict["Speech Gestures"]	= LLTrans::getString("Speech Gestures");
+	mInventoryItemsDict["Common Gestures"]	= LLTrans::getString("Common Gestures");
+
+	//predefined gestures
+
+	//male
+	mInventoryItemsDict["Male - Excuse me"]			= LLTrans::getString("Male - Excuse me");
+	mInventoryItemsDict["Male  - Get lost"]			= LLTrans::getString("Male - Get lost"); // double space after Male. EXT-8319
+	mInventoryItemsDict["Male - Blow kiss"]			= LLTrans::getString("Male - Blow kiss");
+	mInventoryItemsDict["Male - Boo"]				= LLTrans::getString("Male - Boo");
+	mInventoryItemsDict["Male - Bored"]				= LLTrans::getString("Male - Bored");
+	mInventoryItemsDict["Male - Hey"]				= LLTrans::getString("Male - Hey");
+	mInventoryItemsDict["Male - Laugh"]				= LLTrans::getString("Male - Laugh");
+	mInventoryItemsDict["Male - Repulsed"]			= LLTrans::getString("Male - Repulsed");
+	mInventoryItemsDict["Male - Shrug"]				= LLTrans::getString("Male - Shrug");
+	mInventoryItemsDict["Male - Stick tougue out"]	= LLTrans::getString("Male - Stick tougue out");
+	mInventoryItemsDict["Male - Wow"]				= LLTrans::getString("Male - Wow");
+
+	//female
+	mInventoryItemsDict["Female - Chuckle"]			= LLTrans::getString("Female - Chuckle");
+	mInventoryItemsDict["Female - Cry"]				= LLTrans::getString("Female - Cry");
+	mInventoryItemsDict["Female - Embarrassed"]		= LLTrans::getString("Female - Embarrassed");
+	mInventoryItemsDict["Female - Excuse me"]		= LLTrans::getString("Female - Excuse me");
+	mInventoryItemsDict["Female  - Get lost"]		= LLTrans::getString("Female - Get lost"); // double space after Female. EXT-8319
+	mInventoryItemsDict["Female - Blow kiss"]		= LLTrans::getString("Female - Blow kiss");
+	mInventoryItemsDict["Female - Boo"]				= LLTrans::getString("Female - Boo");
+	mInventoryItemsDict["Female - Bored"]			= LLTrans::getString("Female - Bored");
+	mInventoryItemsDict["Female - Hey"]				= LLTrans::getString("Female - Hey");
+	mInventoryItemsDict["Female - Hey baby"]		= LLTrans::getString("Female - Hey baby");
+	mInventoryItemsDict["Female - Laugh"]			= LLTrans::getString("Female - Laugh");
+	mInventoryItemsDict["Female - Looking good"]	= LLTrans::getString("Female - Looking good");
+	mInventoryItemsDict["Female - Over here"]		= LLTrans::getString("Female - Over here");
+	mInventoryItemsDict["Female - Please"]			= LLTrans::getString("Female - Please");
+	mInventoryItemsDict["Female - Repulsed"]		= LLTrans::getString("Female - Repulsed");
+	mInventoryItemsDict["Female - Shrug"]			= LLTrans::getString("Female - Shrug");
+	mInventoryItemsDict["Female - Stick tougue out"]= LLTrans::getString("Female - Stick tougue out");
+	mInventoryItemsDict["Female - Wow"]				= LLTrans::getString("Female - Wow");
+
+	//common
+	mInventoryItemsDict["/bow"]						= LLTrans::getString("/bow");
+	mInventoryItemsDict["/clap"]					= LLTrans::getString("/clap");
+	mInventoryItemsDict["/count"]					= LLTrans::getString("/count");
+	mInventoryItemsDict["/extinguish"]				= LLTrans::getString("/extinguish");
+	mInventoryItemsDict["/kmb"]						= LLTrans::getString("/kmb");
+	mInventoryItemsDict["/muscle"]					= LLTrans::getString("/muscle");
+	mInventoryItemsDict["/no"]						= LLTrans::getString("/no");
+	mInventoryItemsDict["/no!"]						= LLTrans::getString("/no!");
+	mInventoryItemsDict["/paper"]					= LLTrans::getString("/paper");
+	mInventoryItemsDict["/pointme"]					= LLTrans::getString("/pointme");
+	mInventoryItemsDict["/pointyou"]				= LLTrans::getString("/pointyou");
+	mInventoryItemsDict["/rock"]					= LLTrans::getString("/rock");
+	mInventoryItemsDict["/scissor"]					= LLTrans::getString("/scissor");
+	mInventoryItemsDict["/smoke"]					= LLTrans::getString("/smoke");
+	mInventoryItemsDict["/stretch"]					= LLTrans::getString("/stretch");
+	mInventoryItemsDict["/whistle"]					= LLTrans::getString("/whistle");
+	mInventoryItemsDict["/yes"]						= LLTrans::getString("/yes");
+	mInventoryItemsDict["/yes!"]					= LLTrans::getString("/yes!");
+	mInventoryItemsDict["afk"]						= LLTrans::getString("afk");
+	mInventoryItemsDict["dance1"]					= LLTrans::getString("dance1");
+	mInventoryItemsDict["dance2"]					= LLTrans::getString("dance2");
+	mInventoryItemsDict["dance3"]					= LLTrans::getString("dance3");
+	mInventoryItemsDict["dance4"]					= LLTrans::getString("dance4");
+	mInventoryItemsDict["dance5"]					= LLTrans::getString("dance5");
+	mInventoryItemsDict["dance6"]					= LLTrans::getString("dance6");
+	mInventoryItemsDict["dance7"]					= LLTrans::getString("dance7");
+	mInventoryItemsDict["dance8"]					= LLTrans::getString("dance8");
+}
 
 ///----------------------------------------------------------------------------
 /// Local function declarations, constants, enums, and typedefs
diff --git a/indra/newview/llviewerinventory.h b/indra/newview/llviewerinventory.h
index 5194679a0cdca7722b9510ccd7091bb7f916eb7f..074d51b8b3661bba68920ad485de44b94fabb947 100644
--- a/indra/newview/llviewerinventory.h
+++ b/indra/newview/llviewerinventory.h
@@ -30,7 +30,7 @@
 #include "llinventory.h"
 #include "llframetimer.h"
 #include "llwearable.h"
-#include "llui.h" //for LLDestroyClass
+#include "llinitdestroyclass.h" //for LLDestroyClass
 
 #include <boost/signals2.hpp>	// boost::signals2::trackable
 
diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h
index 80c758a5af77991df14926a8b41651540259d171..016b435ee84648a54f4f04bf7d9baef7fe9cc847 100644
--- a/indra/newview/llviewerjoystick.h
+++ b/indra/newview/llviewerjoystick.h
@@ -45,10 +45,10 @@ typedef enum e_joystick_driver_state
 
 class LLViewerJoystick : public LLSingleton<LLViewerJoystick>
 {
-public:
-	LLViewerJoystick();
+	LLSINGLETON(LLViewerJoystick);
 	virtual ~LLViewerJoystick();
-	
+
+public:
 	void init(bool autoenable);
 	void terminate();
 
diff --git a/indra/newview/llviewerkeyboard.cpp b/indra/newview/llviewerkeyboard.cpp
index 2186ed3c5297d508e58c800aa262d3a5ed132f23..fd4315a319d25f2a9ed6aceb93856c0cb6903374 100644
--- a/indra/newview/llviewerkeyboard.cpp
+++ b/indra/newview/llviewerkeyboard.cpp
@@ -57,6 +57,7 @@ const F32 ORBIT_NUDGE_RATE = 0.05f;  // fraction of normal speed
 struct LLKeyboardActionRegistry 
 :	public LLRegistrySingleton<std::string, boost::function<void (EKeystate keystate)>, LLKeyboardActionRegistry>
 {
+	LLSINGLETON_EMPTY_CTOR(LLKeyboardActionRegistry);
 };
 
 LLViewerKeyboard gViewerKeyboard;
diff --git a/indra/newview/llviewermediafocus.h b/indra/newview/llviewermediafocus.h
index 0b2a64868ea0c40710b1c288884c5b1cc959f96e..368c671f84b96cb553b86c4184d1c84efae91660 100644
--- a/indra/newview/llviewermediafocus.h
+++ b/indra/newview/llviewermediafocus.h
@@ -41,10 +41,10 @@ class LLViewerMediaFocus :
 	public LLFocusableElement, 
 	public LLSingleton<LLViewerMediaFocus>
 {
-public:
-	LLViewerMediaFocus();
+	LLSINGLETON(LLViewerMediaFocus);
 	~LLViewerMediaFocus();
-	
+
+public:
 	// Set/clear the face that has media focus (takes keyboard input and has the full set of controls)
 	void setFocusFace(LLPointer<LLViewerObject> objectp, S32 face, viewer_media_t media_impl, LLVector3 pick_normal = LLVector3::zero);
 	void clearFocus();
diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp
index 39059fc01eab0e768bef2fa9fdc85de5d2bbada4..ac494b6eba709ede2947bc8d0904bbcbbc8a0d23 100644
--- a/indra/newview/llviewermenu.cpp
+++ b/indra/newview/llviewermenu.cpp
@@ -133,6 +133,7 @@
 #include "llpathfindingmanager.h"
 #include "llstartup.h"
 #include "boost/unordered_map.hpp"
+#include "llcleanup.h"
 
 using namespace LLAvatarAppearanceDefines;
 
@@ -8484,7 +8485,7 @@ class LLWorldPostProcess : public view_listener_t
 
 void handle_flush_name_caches()
 {
-	LLAvatarNameCache::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLAvatarNameCache);
 	if (gCacheName) gCacheName->clear();
 }
 
@@ -8528,7 +8529,7 @@ class LLToggleUIHints : public view_listener_t
 
 void LLUploadCostCalculator::calculateCost()
 {
-	S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 
 	// getPriceUpload() returns -1 if no data available yet.
 	if(upload_cost >= 0)
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index 08d024e45c5cdf517914bcf33d0f659af6f6ea33..d46bb0199bf051945a0b7775f85b75a8cffaefa2 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -84,7 +84,7 @@ class LLFileEnableUpload : public view_listener_t
 	bool handleEvent(const LLSD& userdata)
 	{
         return true;
-// 		bool new_value = gStatusBar && LLGlobalEconomy::Singleton::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::Singleton::getInstance()->getPriceUpload());
+// 		bool new_value = gStatusBar && LLGlobalEconomy::getInstance() && (gStatusBar->getBalance() >= LLGlobalEconomy::getInstance()->getPriceUpload());
 // 		return new_value;
 	}
 };
@@ -429,7 +429,7 @@ class LLFileUploadBulk : public view_listener_t
 		if (picker.getMultipleOpenFiles())
 		{
             std::string filename = picker.getFirstFile();
-            S32 expected_upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+            S32 expected_upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 
             while (!filename.empty())
             {
diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp
index 15ecfe5dca7581ec40c45f7a314dcc09698515b5..d81cb804e4c1946ac4a7d70e20780d6b2d5af2f1 100644
--- a/indra/newview/llviewermessage.cpp
+++ b/indra/newview/llviewermessage.cpp
@@ -6284,9 +6284,9 @@ void process_frozen_message(LLMessageSystem *msgsystem, void **user_data)
 // do some extra stuff once we get our economy data
 void process_economy_data(LLMessageSystem *msg, void** /*user_data*/)
 {
-	LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::Singleton::getInstance());
+	LLGlobalEconomy::processEconomyData(msg, LLGlobalEconomy::getInstance());
 
-	S32 upload_cost = LLGlobalEconomy::Singleton::getInstance()->getPriceUpload();
+	S32 upload_cost = LLGlobalEconomy::getInstance()->getPriceUpload();
 
 	LL_INFOS_ONCE("Messaging") << "EconomyData message arrived; upload cost is L$" << upload_cost << LL_ENDL;
 
diff --git a/indra/newview/llviewermessage.h b/indra/newview/llviewermessage.h
index d8f5c71f8d3bfff2a6b7c30e43832d939a81215d..b0eaa37541db4af72b8eb4c7ccda1bf30e0de7a3 100644
--- a/indra/newview/llviewermessage.h
+++ b/indra/newview/llviewermessage.h
@@ -210,6 +210,7 @@ void set_dad_inbox_object(const LLUUID& object_id);
 
 class LLViewerMessage : public  LLSingleton<LLViewerMessage>
 {
+	LLSINGLETON_EMPTY_CTOR(LLViewerMessage);
 public:
 	typedef boost::function<void()> teleport_started_callback_t;
 	typedef boost::signals2::signal<void()> teleport_started_signal_t;
diff --git a/indra/newview/llviewernetwork.cpp b/indra/newview/llviewernetwork.cpp
index 25258862226aa35249e49b79c6736e76ecad7a58..6937d064f982bfa5ce88a0e5b7ed5dd6bd639c8d 100644
--- a/indra/newview/llviewernetwork.cpp
+++ b/indra/newview/llviewernetwork.cpp
@@ -95,13 +95,6 @@ LLGridManager::LLGridManager()
 }
 
 
-LLGridManager::LLGridManager(const std::string& grid_file)
-{
-	// initialize with an explicity grid file for testing.
-	LL_DEBUGS("GridManager")<<LL_ENDL;
-	initialize(grid_file);
-}
-
 //
 // LLGridManager - class for managing the list of known grids, and the current
 // selection
diff --git a/indra/newview/llviewernetwork.h b/indra/newview/llviewernetwork.h
index 228303d8e2d0a3b3d23cdef2c1582cbd451aaa8d..b8ff494b8b0d27e79d997dc8d47cea4020d14062 100644
--- a/indra/newview/llviewernetwork.h
+++ b/indra/newview/llviewernetwork.h
@@ -58,16 +58,15 @@ class LLInvalidGridName
  **/
 class LLGridManager : public LLSingleton<LLGridManager>
 {
+	/// Instantiate the grid manager, load default grids, selects the default grid
+	LLSINGLETON(LLGridManager);
+	~LLGridManager();
+
   public:
 	/* ================================================================
 	 * @name Initialization and Configuration
 	 * @{
 	 */
-	/// Instantiate the grid manager, load default grids, selects the default grid
-	LLGridManager(const std::string& grid_file);
-	LLGridManager();
-	~LLGridManager();
-	
 	/// add grids from an external grids file
 	void initialize(const std::string& grid_file);
 	
diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp
index 7964bf18481865439928cfc59b8f3b4b98c16862..61dd71ab753af8b7ca12415fa896e16e2056044b 100644
--- a/indra/newview/llviewerobject.cpp
+++ b/indra/newview/llviewerobject.cpp
@@ -102,6 +102,7 @@
 #include "llmediaentry.h"
 #include "llfloaterperms.h"
 #include "llvocache.h"
+#include "llcleanup.h"
 
 //#define DEBUG_UPDATE_TYPE
 
@@ -530,11 +531,11 @@ void LLViewerObject::initVOClasses()
 
 void LLViewerObject::cleanupVOClasses()
 {
-	LLVOGrass::cleanupClass();
-	LLVOWater::cleanupClass();
-	LLVOTree::cleanupClass();
-	LLVOAvatar::cleanupClass();
-	LLVOVolume::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLVOGrass);
+	SUBSYSTEM_CLEANUP(LLVOWater);
+	SUBSYSTEM_CLEANUP(LLVOTree);
+	SUBSYSTEM_CLEANUP(LLVOAvatar);
+	SUBSYSTEM_CLEANUP(LLVOVolume);
 
 	sObjectDataMap.clear();
 }
diff --git a/indra/newview/llviewerparcelmgr.h b/indra/newview/llviewerparcelmgr.h
index bb6bbf33083127c29b7e04d8cf7d1c65b7d70ae5..29219843c9ef20b3ea5161a9d28dcd65b37882d4 100644
--- a/indra/newview/llviewerparcelmgr.h
+++ b/indra/newview/llviewerparcelmgr.h
@@ -75,6 +75,8 @@ class LLParcelObserver
 
 class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 {
+	LLSINGLETON(LLViewerParcelMgr);
+	~LLViewerParcelMgr();
 
 public:
 	typedef boost::function<void (const LLVector3d&, const bool& local)> teleport_finished_callback_t;
@@ -82,9 +84,6 @@ class LLViewerParcelMgr : public LLSingleton<LLViewerParcelMgr>
 	typedef boost::function<void()> teleport_failed_callback_t;
 	typedef boost::signals2::signal<void()> teleport_failed_signal_t;
 
-	LLViewerParcelMgr();
-	~LLViewerParcelMgr();
-
 	static void cleanupGlobals();
 
 	BOOL	selectionEmpty() const;
diff --git a/indra/newview/llviewerpartsim.h b/indra/newview/llviewerpartsim.h
index 40e8e1d45df1322a758fa8682c9858ffce0972b9..ab1cd715ab225552ce52b213f0f0028a13dcf021 100644
--- a/indra/newview/llviewerpartsim.h
+++ b/indra/newview/llviewerpartsim.h
@@ -135,9 +135,8 @@ class LLViewerPartGroup
 
 class LLViewerPartSim : public LLSingleton<LLViewerPartSim>
 {
+	LLSINGLETON(LLViewerPartSim);
 public:
-	LLViewerPartSim();
-	virtual ~LLViewerPartSim(){}
 	void destroyClass();
 
 	typedef std::vector<LLViewerPartGroup *> group_list_t;
diff --git a/indra/newview/llviewerstats.h b/indra/newview/llviewerstats.h
index 7843652589f7621b60fa7db3696dcbb3d3ecbabe..97a060d95e401102b79c8281e891a065b47201c1 100644
--- a/indra/newview/llviewerstats.h
+++ b/indra/newview/llviewerstats.h
@@ -246,13 +246,11 @@ extern LLTrace::EventStatHandle<LLUnit<F32, LLUnits::Percent> > OBJECT_CACHE_HIT
 
 class LLViewerStats : public LLSingleton<LLViewerStats>
 {
-public:
-	void resetStats();
+	LLSINGLETON(LLViewerStats);
+	~LLViewerStats();
 
 public:
-
-	LLViewerStats();
-	~LLViewerStats();
+	void resetStats();
 
 	void updateFrameStats(const F64Seconds time_diff);
 	
diff --git a/indra/newview/llviewerstatsrecorder.h b/indra/newview/llviewerstatsrecorder.h
index d1744f4910d66eaac242ca3af0d3033988260b4f..c974bea49de5f38cdb55016809c719ab72dd1446 100644
--- a/indra/newview/llviewerstatsrecorder.h
+++ b/indra/newview/llviewerstatsrecorder.h
@@ -44,11 +44,11 @@ class LLViewerObject;
 
 class LLViewerStatsRecorder : public LLSingleton<LLViewerStatsRecorder>
 {
- public:
-	LOG_CLASS(LLViewerStatsRecorder);	 
-	LLViewerStatsRecorder();
+	LLSINGLETON(LLViewerStatsRecorder);
+	LOG_CLASS(LLViewerStatsRecorder);
 	~LLViewerStatsRecorder();
 
+ public:
 	void objectUpdateFailure(U32 local_id, const EObjectUpdateType update_type, S32 msg_size)
 	{
 #if LL_RECORD_VIEWER_STATS
diff --git a/indra/newview/llviewertexturelist.h b/indra/newview/llviewertexturelist.h
index ba7677083852f6d39aa555199fe42699996d5d06..070544063ac5854b3ae9ef8e4fb82c2438625e0a 100644
--- a/indra/newview/llviewertexturelist.h
+++ b/indra/newview/llviewertexturelist.h
@@ -237,6 +237,7 @@ class LLViewerTextureList
 
 class LLUIImageList : public LLImageProviderInterface, public LLSingleton<LLUIImageList>
 {
+	LLSINGLETON_EMPTY_CTOR(LLUIImageList);
 public:
 	// LLImageProviderInterface
 	/*virtual*/ LLPointer<LLUIImage> getUIImageByID(const LLUUID& id, S32 priority);
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 9e68bb78e0900f3bee15c7b2ba474857134a121a..cce988c2febddb39a1403e11d7f883462d36c30b 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -208,6 +208,7 @@
 #include "llwindowlistener.h"
 #include "llviewerwindowlistener.h"
 #include "llpaneltopinfobar.h"
+#include "llcleanup.h"
 
 #if LL_WINDOWS
 #include <tchar.h> // For Unicode conversion methods
@@ -292,13 +293,8 @@ class RecordToChatConsoleRecorder : public LLError::Recorder
 
 class RecordToChatConsole : public LLSingleton<RecordToChatConsole>
 {
+	LLSINGLETON(RecordToChatConsole);
 public:
-	RecordToChatConsole()
-		: LLSingleton<RecordToChatConsole>(),
-		mRecorder(new RecordToChatConsoleRecorder())
-	{
-	}
-
 	void startRecorder() { LLError::addRecorder(mRecorder); }
 	void stopRecorder() { LLError::removeRecorder(mRecorder); }
 
@@ -306,6 +302,11 @@ class RecordToChatConsole : public LLSingleton<RecordToChatConsole>
 	LLError::RecorderPtr mRecorder;
 };
 
+RecordToChatConsole::RecordToChatConsole():
+	mRecorder(new RecordToChatConsoleRecorder())
+{
+}
+
 ////////////////////////////////////////////////////////////////////////////
 //
 // LLDebugText
@@ -2176,10 +2177,7 @@ void LLViewerWindow::shutdownViews()
 
 	// destroy the nav bar, not currently part of gViewerWindow
 	// *TODO: Make LLNavigationBar part of gViewerWindow
-	if (LLNavigationBar::instanceExists())
-	{
-		delete LLNavigationBar::getInstance();
-	}
+	LLNavigationBar::deleteSingleton();
 	LL_INFOS() << "LLNavigationBar destroyed." << LL_ENDL ;
 	
 	// destroy menus after instantiating navbar above, as it needs
@@ -2215,7 +2213,7 @@ void LLViewerWindow::shutdownGL()
 	// Shutdown GL cleanly.  Order is very important here.
 	//--------------------------------------------------------
 	LLFontGL::destroyDefaultFonts();
-	LLFontManager::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLFontManager);
 	stop_glerror();
 
 	gSky.cleanup();
@@ -2238,7 +2236,7 @@ void LLViewerWindow::shutdownGL()
 	LLWorldMapView::cleanupTextures();
 
 	LLViewerTextureManager::cleanup() ;
-	LLImageGL::cleanupClass() ;
+	SUBSYSTEM_CLEANUP(LLImageGL) ;
 
 	LL_INFOS() << "All textures and llimagegl images are destroyed!" << LL_ENDL ;
 
@@ -2251,7 +2249,7 @@ void LLViewerWindow::shutdownGL()
 
 	gGL.shutdown();
 
-	LLVertexBuffer::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLVertexBuffer);
 
 	LL_INFOS() << "LLVertexBuffer cleaned." << LL_ENDL ;
 }
diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h
index 082f5f0b1d684ebf8bddf7c070b529ca4594031a..7aabde1b2da66d2ac36360dcaaf7db9080098efd 100644
--- a/indra/newview/llvocache.h
+++ b/indra/newview/llvocache.h
@@ -223,6 +223,9 @@ class LLVOCachePartition : public LLViewerOctreePartition, public LLTrace::MemTr
 //
 class LLVOCache : public LLSingleton<LLVOCache>
 {
+	LLSINGLETON(LLVOCache);
+	~LLVOCache() ;
+
 private:
 	struct HeaderEntryInfo
 	{
@@ -253,13 +256,8 @@ class LLVOCache : public LLSingleton<LLVOCache>
 	};
 	typedef std::set<HeaderEntryInfo*, header_entry_less> header_entry_queue_t;
 	typedef std::map<U64, HeaderEntryInfo*> handle_entry_map_t;
-private:
-    friend class LLSingleton<LLVOCache>;
-	LLVOCache() ;
 
 public:
-	~LLVOCache() ;
-
 	void initCache(ELLPath location, U32 size, U32 cache_version) ;
 	void removeCache(ELLPath location, bool started = false) ;
 
diff --git a/indra/newview/llvoicechannel.h b/indra/newview/llvoicechannel.h
index ef15b2c79ee2d5c184d7cf6e59df2802168e3ad7..309c3eebddfea599b9decd08d3dc362fe096457b 100644
--- a/indra/newview/llvoicechannel.h
+++ b/indra/newview/llvoicechannel.h
@@ -167,8 +167,8 @@ class LLVoiceChannelGroup : public LLVoiceChannel
 
 class LLVoiceChannelProximal : public LLVoiceChannel, public LLSingleton<LLVoiceChannelProximal>
 {
+	LLSINGLETON(LLVoiceChannelProximal);
 public:
-	LLVoiceChannelProximal();
 
 	/*virtual*/ void onChange(EStatusType status, const std::string &channelURI, bool proximal);
 	/*virtual*/ void handleStatusChange(EStatusType status);
diff --git a/indra/newview/llvoiceclient.h b/indra/newview/llvoiceclient.h
index b05bcb23b705c8601327d32072647f87488b3abf..32637dcf42e796b0d6dac12261da23cab44efdf3 100644
--- a/indra/newview/llvoiceclient.h
+++ b/indra/newview/llvoiceclient.h
@@ -299,11 +299,11 @@ class LLVoiceEffectInterface
 
 class LLVoiceClient: public LLSingleton<LLVoiceClient>
 {
+	LLSINGLETON(LLVoiceClient);
 	LOG_CLASS(LLVoiceClient);
-public:
-	LLVoiceClient();	
 	~LLVoiceClient();
 
+public:
 	typedef boost::signals2::signal<void(void)> micro_changed_signal_t;
 	micro_changed_signal_t mMicroChangedSignal;
 
@@ -485,6 +485,8 @@ class LLVoiceClient: public LLSingleton<LLVoiceClient>
  **/
 class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
 {
+	LLSINGLETON(LLSpeakerVolumeStorage);
+	~LLSpeakerVolumeStorage();
 	LOG_CLASS(LLSpeakerVolumeStorage);
 public:
 
@@ -513,10 +515,6 @@ class LLSpeakerVolumeStorage : public LLSingleton<LLSpeakerVolumeStorage>
 	void removeSpeakerVolume(const LLUUID& speaker_id);
 
 private:
-	friend class LLSingleton<LLSpeakerVolumeStorage>;
-	LLSpeakerVolumeStorage();
-	~LLSpeakerVolumeStorage();
-
 	const static std::string SETTINGS_FILE_NAME;
 
 	void load();
diff --git a/indra/newview/llvoicevivox.h b/indra/newview/llvoicevivox.h
index f32c7c975f668a037d19e1ec2a56a16cb001e7fc..81e924e4382c06b91919a7a4dad94a30815ff832 100644
--- a/indra/newview/llvoicevivox.h
+++ b/indra/newview/llvoicevivox.h
@@ -56,12 +56,11 @@ class LLVivoxVoiceClient :	public LLSingleton<LLVivoxVoiceClient>,
 							virtual public LLVoiceModuleInterface,
 							virtual public LLVoiceEffectInterface
 {
+	LLSINGLETON(LLVivoxVoiceClient);
 	LOG_CLASS(LLVivoxVoiceClient);
-public:
-	LLVivoxVoiceClient();	
 	virtual ~LLVivoxVoiceClient();
-	
-	
+
+public:
 	/// @name LLVoiceModuleInterface virtual implementations
 	///  @see LLVoiceModuleInterface
 	//@{
@@ -1027,10 +1026,10 @@ class LLVivoxProtocolParser : public LLIOPipe
 
 class LLVivoxSecurity :	public LLSingleton<LLVivoxSecurity>
 {
-  public:
-	LLVivoxSecurity();	
-	virtual ~LLVivoxSecurity();
+    LLSINGLETON(LLVivoxSecurity);
+    virtual ~LLVivoxSecurity();
 
+  public:
     std::string     connectorHandle() { return mConnectorHandle; };
     std::string     accountHandle()    { return mAccountHandle;    };
 
diff --git a/indra/newview/llwatchdog.h b/indra/newview/llwatchdog.h
index fee3ec6f2001c05d9127864480daa23ee3d6b1a4..9a6624258e90f43c43a114fa1250d579b45ec990 100644
--- a/indra/newview/llwatchdog.h
+++ b/indra/newview/llwatchdog.h
@@ -75,10 +75,10 @@ class LLWatchdogTimeout : public LLWatchdogEntry
 class LLWatchdogTimerThread; // Defined in the cpp
 class LLWatchdog : public LLSingleton<LLWatchdog>
 {
-public:
-	LLWatchdog();
+	LLSINGLETON(LLWatchdog);
 	~LLWatchdog();
 
+public:
 	// Add an entry to the watchdog.
 	void add(LLWatchdogEntry* e);
 	void remove(LLWatchdogEntry* e);
diff --git a/indra/newview/llwaterparammanager.h b/indra/newview/llwaterparammanager.h
index dc7d41be2ac57b0cff6712da49a30d4bb71d1126..3f169e439a607d52110112e5c2f19326f5a2e795 100644
--- a/indra/newview/llwaterparammanager.h
+++ b/indra/newview/llwaterparammanager.h
@@ -214,6 +214,8 @@ struct WaterExpFloatControl
 /// WindLight parameter manager class - what controls all the wind light shaders
 class LLWaterParamManager : public LLSingleton<LLWaterParamManager>
 {
+	LLSINGLETON(LLWaterParamManager);
+	~LLWaterParamManager();
 	LOG_CLASS(LLWaterParamManager);
 public:
 	typedef std::list<std::string> preset_name_list_t;
@@ -317,11 +319,7 @@ class LLWaterParamManager : public LLSingleton<LLWaterParamManager>
 	F32 mDensitySliderValue;
 
 private:
-	friend class LLSingleton<LLWaterParamManager>;
 	/*virtual*/ void initSingleton();
-	LLWaterParamManager();
-	~LLWaterParamManager();
-
 	void loadAllPresets();
 	void loadPresetsFromDir(const std::string& dir);
 	bool loadPreset(const std::string& path);
diff --git a/indra/newview/llwearableitemslist.h b/indra/newview/llwearableitemslist.h
index 63e3e9dbc9757d125960394ab91f86a01ffc1127..f3182ed163b4669b4e44f644e601d8f38358dbce 100644
--- a/indra/newview/llwearableitemslist.h
+++ b/indra/newview/llwearableitemslist.h
@@ -411,8 +411,8 @@ class LLWearableItemsList : public LLInventoryItemsList
 	 */
 	class ContextMenu : public LLListContextMenu, public LLSingleton<ContextMenu>
 	{
+		LLSINGLETON(ContextMenu);
 	public:
-		ContextMenu();
 		/*virtual*/ void show(LLView* spawning_view, const uuid_vec_t& uuids, S32 x, S32 y);
 
 	protected:
diff --git a/indra/newview/llwearablelist.h b/indra/newview/llwearablelist.h
index d6f0fd09a6d5c0376c78ad8ff2327e3c06c9e747..782f7751e59f19f8702a0ea81f52a7df4510d3ea 100644
--- a/indra/newview/llwearablelist.h
+++ b/indra/newview/llwearablelist.h
@@ -41,9 +41,9 @@
 */
 class LLWearableList : public LLSingleton<LLWearableList>
 {
-public:
-	LLWearableList()	{}
+	LLSINGLETON_EMPTY_CTOR(LLWearableList);
 	~LLWearableList();
+public:
 	void cleanup() ;
 
 	S32					getLength() const { return mList.size(); }
diff --git a/indra/newview/llwindebug.h b/indra/newview/llwindebug.h
index a3cbf6dc036cde80da35f5c19d5c20dffbec2f89..90882cf04a099baf97a8afb396f73f5ac90c5f9a 100644
--- a/indra/newview/llwindebug.h
+++ b/indra/newview/llwindebug.h
@@ -34,6 +34,7 @@
 class LLWinDebug:
 	public LLSingleton<LLWinDebug>
 {
+	LLSINGLETON_EMPTY_CTOR(LLWinDebug);
 public:
 	static void init();
 	static void generateMinidump(struct _EXCEPTION_POINTERS *pExceptionInfo = NULL);
diff --git a/indra/newview/llwlparammanager.h b/indra/newview/llwlparammanager.h
index e13aed98edfc507d5bec39592e9fdc8493cc67a1..a10102edf786fdb9102acecfb8efedb51b90ec50 100644
--- a/indra/newview/llwlparammanager.h
+++ b/indra/newview/llwlparammanager.h
@@ -213,6 +213,8 @@ struct LLWLParamKey : LLEnvKey
 /// WindLight parameter manager class - what controls all the wind light shaders
 class LLWLParamManager : public LLSingleton<LLWLParamManager>
 {
+	LLSINGLETON(LLWLParamManager);
+	~LLWLParamManager();
 	LOG_CLASS(LLWLParamManager);
 
 public:
@@ -375,11 +377,7 @@ class LLWLParamManager : public LLSingleton<LLWLParamManager>
 	static std::string getSysDir();
 	static std::string getUserDir();
 
-	friend class LLSingleton<LLWLParamManager>;
 	/*virtual*/ void initSingleton();
-	LLWLParamManager();
-	~LLWLParamManager();
-
 	// list of all the parameters, listed by name
 	std::map<LLWLParamKey, LLWLParamSet> mParamList;
 
diff --git a/indra/newview/llworld.h b/indra/newview/llworld.h
index b2d84180648ddfadc41c3ce0185f9354153451d8..c9ac241d5aae22473d0a302974d57ca00cb0aeab 100644
--- a/indra/newview/llworld.h
+++ b/indra/newview/llworld.h
@@ -61,8 +61,8 @@ class LLVOAvatar;
 
 class LLWorld : public LLSingleton<LLWorld>
 {
+	LLSINGLETON(LLWorld);
 public:
-	LLWorld();
 	void destroyClass();
 
 	LLViewerRegion*	addRegion(const U64 &region_handle, const LLHost &host);
diff --git a/indra/newview/llworldmap.h b/indra/newview/llworldmap.h
index 1a168e4b4d4f76ee6d25499d00d45491e2c5085a..5e5caa6a74358e8b762fe2d40a7ff82e71bb52bf 100644
--- a/indra/newview/llworldmap.h
+++ b/indra/newview/llworldmap.h
@@ -193,10 +193,10 @@ const S32 MAP_BLOCK_RES = (MAP_MAX_SIZE / MAP_BLOCK_SIZE);
 
 class LLWorldMap : public LLSingleton<LLWorldMap>
 {
-public:
-	LLWorldMap();
+	LLSINGLETON(LLWorldMap);
 	~LLWorldMap();
 
+public:
 	// Clear all: list of region info, tiles, blocks and items
 	void reset();
 
diff --git a/indra/newview/llworldmapmessage.h b/indra/newview/llworldmapmessage.h
index ac1ea1607c793d6370d3f3e95cd4f414c9889a26..65276df06820835dcd2157d2a2aa76a63bd16b78 100644
--- a/indra/newview/llworldmapmessage.h
+++ b/indra/newview/llworldmapmessage.h
@@ -34,13 +34,13 @@ class LLMessageSystem;
 
 class LLWorldMapMessage : public LLSingleton<LLWorldMapMessage>
 {
+	LLSINGLETON(LLWorldMapMessage);
+	~LLWorldMapMessage();
+
 public:
 	typedef boost::function<void(U64 region_handle, const std::string& url, const LLUUID& snapshot_id, bool teleport)>
 		url_callback_t;
 
-	LLWorldMapMessage();
-	~LLWorldMapMessage();
-
 	// Process incoming answers to map stuff requests
 	static void processMapBlockReply(LLMessageSystem*, void**);
 	static void processMapItemReply(LLMessageSystem*, void**);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index 70989bacff4528302a9973590d40f51b62545665..7c019dc3ea657edc099fc2109bccc41181b3802a 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -114,6 +114,7 @@
 #include "llpathfindingpathtool.h"
 #include "llscenemonitor.h"
 #include "llprogressview.h"
+#include "llcleanup.h"
 
 #ifdef _DEBUG
 // Debug indices is disabled for now for debug performance - djs 4/24/02
@@ -7385,7 +7386,7 @@ void LLPipeline::doResetVertexBuffers(bool forced)
 	}
 	LLVOPartGroup::destroyGL();
 
-	LLVertexBuffer::cleanupClass();
+	SUBSYSTEM_CLEANUP(LLVertexBuffer);
 	
 	//delete all name pool caches
 	LLGLNamePool::cleanupPools();
diff --git a/indra/newview/tests/llremoteparcelrequest_test.cpp b/indra/newview/tests/llremoteparcelrequest_test.cpp
index ea5014a59c2fa4c07319766567296d7204514a41..4f7f87b6b01ef39afd15e9453904ffdcf6f08080 100644
--- a/indra/newview/tests/llremoteparcelrequest_test.cpp
+++ b/indra/newview/tests/llremoteparcelrequest_test.cpp
@@ -34,6 +34,7 @@
 #include "../llagent.h"
 #include "message.h"
 #include "llurlentry.h"
+#include "llpounceable.h"
 
 namespace {
 	const LLUUID TEST_PARCEL_ID("11111111-1111-1111-1111-111111111111");
@@ -62,7 +63,7 @@ void LLMessageSystem::addUUID(char const *,LLUUID const &) { }
 void LLMessageSystem::addUUIDFast(char const *,LLUUID const &) { }
 void LLMessageSystem::nextBlockFast(char const *) { }
 void LLMessageSystem::newMessage(char const *) { }
-LLMessageSystem * gMessageSystem;
+LLPounceable<LLMessageSystem*, LLPounceableStatic> gMessageSystem;
 char const* const _PREHASH_AgentID = 0;   // never dereferenced during this test
 char const* const _PREHASH_AgentData = 0; // never dereferenced during this test
 LLAgent gAgent;
diff --git a/indra/test/message_tut.cpp b/indra/test/message_tut.cpp
index 8718360f0cb309caf0ad93f477348a4a1433f74b..76063e6db120b8d1a333fd2f30c7d643c9d76372 100644
--- a/indra/test/message_tut.cpp
+++ b/indra/test/message_tut.cpp
@@ -103,7 +103,7 @@ namespace tut
 		~LLMessageSystemTestData()
 		{
 			// not end_messaging_system()
-			delete gMessageSystem;
+			delete static_cast<LLMessageSystem*>(gMessageSystem);
 			gMessageSystem = NULL;
 
 			// rm contents of temp dir