diff --git a/indra/llcommon/llinstancetracker.cpp b/indra/llcommon/llinstancetracker.cpp
index f57620451117ab40509dae0ef013d8eaf41c6f68..5dc3ea5d7bc751bfe0cefbfa25419eb50470e937 100644
--- a/indra/llcommon/llinstancetracker.cpp
+++ b/indra/llcommon/llinstancetracker.cpp
@@ -35,14 +35,15 @@
 //static 
 void * & LLInstanceTrackerBase::getInstances(std::type_info const & info)
 {
-	static std::map<std::string, void *> instances;
+	typedef std::map<std::string, void *> InstancesMap;
+	static InstancesMap instances;
 
-	std::string k = info.name();
-	if(instances.find(k) == instances.end())
-	{
-		instances[k] = NULL;
-	}
-
-	return instances[k];
+	// std::map::insert() is just what we want here. You attempt to insert a
+	// (key, value) pair. If the specified key doesn't yet exist, it inserts
+	// the pair and returns a std::pair of (iterator, true). If the specified
+	// key DOES exist, insert() simply returns (iterator, false). One lookup
+	// handles both cases.
+	return instances.insert(InstancesMap::value_type(info.name(),
+													 InstancesMap::mapped_type()))
+		.first->second;
 }
-
diff --git a/indra/llcommon/llinstancetracker.h b/indra/llcommon/llinstancetracker.h
index afb714c71c5882ed742c5b6aa7b8aca1da3da80c..5a3990a8df58d8dcf4f40069af59f31cefc80452 100644
--- a/indra/llcommon/llinstancetracker.h
+++ b/indra/llcommon/llinstancetracker.h
@@ -29,6 +29,7 @@
 #define LL_LLINSTANCETRACKER_H
 
 #include <map>
+#include <typeinfo>
 
 #include "string_table.h"
 #include <boost/utility.hpp>
@@ -37,10 +38,40 @@
 #include <boost/iterator/transform_iterator.hpp>
 #include <boost/iterator/indirect_iterator.hpp>
 
+/**
+ * Base class manages "class-static" data that must actually have singleton
+ * semantics: one instance per process, rather than one instance per module as
+ * sometimes happens with data simply declared static.
+ */
 class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 {
-	protected:
-		static void * & getInstances(std::type_info const & info);
+protected:
+	/// Get a process-unique void* pointer slot for the specified type_info
+	static void * & getInstances(std::type_info const & info);
+
+	/// Find or create a STATICDATA instance for the specified TRACKED class.
+	/// STATICDATA must be default-constructible.
+	template<typename STATICDATA, class TRACKED>
+	static STATICDATA& getStatic()
+	{
+		void *& instances = getInstances(typeid(TRACKED));
+		if (! instances)
+		{
+			instances = new STATICDATA;
+		}
+		return *static_cast<STATICDATA*>(instances);
+	}
+
+    /// It's not essential to derive your STATICDATA (for use with
+    /// getStatic()) from StaticBase; it's just that both known
+    /// implementations do.
+    struct StaticBase
+    {
+        StaticBase():
+            sIterationNestDepth(0)
+        {}
+        S32 sIterationNestDepth;
+    };
 };
 
 /// This mix-in class adds support for tracking all instances of the specified class parameter T
@@ -50,8 +81,15 @@ class LL_COMMON_API LLInstanceTrackerBase : public boost::noncopyable
 template<typename T, typename KEY = T*>
 class LLInstanceTracker : public LLInstanceTrackerBase
 {
-	typedef typename std::map<KEY, T*> InstanceMap;
 	typedef LLInstanceTracker<T, KEY> MyT;
+	typedef typename std::map<KEY, T*> InstanceMap;
+	struct StaticData: public StaticBase
+	{
+		InstanceMap sMap;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceMap& getMap_() { return getStatic().sMap; }
+
 public:
 	class instance_iter : public boost::iterator_facade<instance_iter, T, boost::forward_traversal_tag>
 	{
@@ -61,12 +99,12 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		instance_iter(const typename InstanceMap::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
@@ -95,18 +133,18 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		key_iter(typename InstanceMap::iterator it)
 			:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		key_iter(const key_iter& other)
 			:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~key_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 
@@ -159,8 +197,8 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 	virtual ~LLInstanceTracker() 
 	{ 
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
-		remove_(); 		
+		llassert_always(getStatic().sIterationNestDepth == 0);
+		remove_();		
 	}
 	virtual void setKey(KEY key) { remove_(); add_(key); }
 	virtual const KEY& getKey() const { return mInstanceKey; }
@@ -176,31 +214,24 @@ class LLInstanceTracker : public LLInstanceTrackerBase
 		getMap_().erase(mInstanceKey);
 	}
 
-    static InstanceMap& getMap_()
-    {
-		void * & instances = getInstances(typeid(MyT));
-        if (! instances)
-        {
-            instances = new InstanceMap;
-        }
-        return * static_cast<InstanceMap*>(instances);
-    }
-
 private:
-
 	KEY mInstanceKey;
-	static S32 sIterationNestDepth;
 };
 
-template <typename T, typename KEY> S32 LLInstanceTracker<T, KEY>::sIterationNestDepth = 0;
-
 /// explicit specialization for default case where KEY is T*
 /// use a simple std::set<T*>
 template<typename T>
 class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 {
-	typedef typename std::set<T*> InstanceSet;
 	typedef LLInstanceTracker<T, T*> MyT;
+	typedef typename std::set<T*> InstanceSet;
+	struct StaticData: public StaticBase
+	{
+		InstanceSet sSet;
+	};
+	static StaticData& getStatic() { return LLInstanceTrackerBase::getStatic<StaticData, MyT>(); }
+	static InstanceSet& getSet_() { return getStatic().sSet; }
+
 public:
 
 	/// for completeness of analogy with the generic implementation
@@ -213,18 +244,18 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 		instance_iter(const typename InstanceSet::iterator& it)
 		:	mIterator(it)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		instance_iter(const instance_iter& other)
 		:	mIterator(other.mIterator)
 		{
-			++sIterationNestDepth;
+			++getStatic().sIterationNestDepth;
 		}
 
 		~instance_iter()
 		{
-			--sIterationNestDepth;
+			--getStatic().sIterationNestDepth;
 		}
 
 	private:
@@ -250,13 +281,13 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 protected:
 	LLInstanceTracker()
 	{
-		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.  This assert will probably be turned on early in the next development cycle.
+		// it's safe but unpredictable to create instances of this type while all instances are being iterated over.  I hate unpredictable.	 This assert will probably be turned on early in the next development cycle.
 		getSet_().insert(static_cast<T*>(this));
 	}
 	virtual ~LLInstanceTracker()
 	{
 		// it's unsafe to delete instances of this type while all instances are being iterated over.
-		llassert(sIterationNestDepth == 0);
+		llassert_always(getStatic().sIterationNestDepth == 0);
 		getSet_().erase(static_cast<T*>(this));
 	}
 
@@ -264,20 +295,6 @@ class LLInstanceTracker<T, T*> : public LLInstanceTrackerBase
 	{
 		getSet_().insert(static_cast<T*>(this));
 	}
-
-	static InstanceSet& getSet_()
-	{
-		void * & instances = getInstances(typeid(MyT));
-		if (! instances)
-		{
-			instances = new InstanceSet;
-		}
-		return * static_cast<InstanceSet *>(instances);
-	}
-
-	static S32 sIterationNestDepth;
 };
 
-template <typename T> S32 LLInstanceTracker<T, T*>::sIterationNestDepth = 0;
-
 #endif
diff --git a/indra/llcommon/tests/llinstancetracker_test.cpp b/indra/llcommon/tests/llinstancetracker_test.cpp
index 80b35bbdc38981ba3f4eb4670c35157d95031aed..b34d1c5fd34c266e14b8abc1595f8795408dc63f 100644
--- a/indra/llcommon/tests/llinstancetracker_test.cpp
+++ b/indra/llcommon/tests/llinstancetracker_test.cpp
@@ -40,6 +40,7 @@
 #include <boost/scoped_ptr.hpp>
 // other Linden headers
 #include "../test/lltut.h"
+#include "wrapllerrs.h"
 
 struct Keyed: public LLInstanceTracker<Keyed, std::string>
 {
@@ -165,4 +166,67 @@ namespace tut
 
         ensure_equals("unreported instance", instances.size(), 0);
     }
+
+    template<> template<>
+    void object::test<5>()
+    {
+        set_test_name("delete Keyed with outstanding instance_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::instance_iter i(Keyed::beginInstances());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<6>()
+    {
+        set_test_name("delete Keyed with outstanding key_iter");
+        std::string what;
+        Keyed* keyed = new Keyed("one");
+        {
+            WrapLL_ERRS wrapper;
+            Keyed::key_iter i(Keyed::beginKeys());
+            try
+            {
+                delete keyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
+
+    template<> template<>
+    void object::test<7>()
+    {
+        set_test_name("delete Unkeyed with outstanding instance_iter");
+        std::string what;
+        Unkeyed* unkeyed = new Unkeyed;
+        {
+            WrapLL_ERRS wrapper;
+            Unkeyed::instance_iter i(Unkeyed::beginInstances());
+            try
+            {
+                delete unkeyed;
+            }
+            catch (const WrapLL_ERRS::FatalException& e)
+            {
+                what = e.what();
+            }
+        }
+        ensure(! what.empty());
+    }
 } // namespace tut