auto import from //depot/cupcake/@135843
diff --git a/tools/axl/singletonmixin.py b/tools/axl/singletonmixin.py
new file mode 100644
index 0000000..7935d6d
--- /dev/null
+++ b/tools/axl/singletonmixin.py
@@ -0,0 +1,220 @@
+"""
+A Python Singleton mixin class that makes use of some of the ideas
+found at http://c2.com/cgi/wiki?PythonSingleton. Just inherit
+from it and you have a singleton. No code is required in
+subclasses to create singleton behavior -- inheritance from 
+Singleton is all that is needed.
+
+Assume S is a class that inherits from Singleton. Useful behaviors
+are:
+
+1) Getting the singleton:
+
+    S.getInstance() 
+    
+returns the instance of S. If none exists, it is created. 
+
+2) The usual idiom to construct an instance by calling the class, i.e.
+
+    S()
+    
+is disabled for the sake of clarity. If it were allowed, a programmer
+who didn't happen  notice the inheritance from Singleton might think he
+was creating a new instance. So it is felt that it is better to
+make that clearer by requiring the call of a class method that is defined in
+Singleton. An attempt to instantiate via S() will restult in an SingletonException
+being raised.
+
+3) If S.__init__(.) requires parameters, include them in the
+first call to S.getInstance(.). If subsequent calls have parameters,
+a SingletonException is raised.
+
+4) As an implementation detail, classes that inherit 
+from Singleton may not have their own __new__
+methods. To make sure this requirement is followed, 
+an exception is raised if a Singleton subclass includ
+es __new__. This happens at subclass instantiation
+time (by means of the MetaSingleton metaclass.
+
+By Gary Robinson, grobinson@transpose.com. No rights reserved -- 
+placed in the public domain -- which is only reasonable considering
+how much it owes to other people's version which are in the
+public domain. The idea of using a metaclass came from 
+a  comment on Gary's blog (see 
+http://www.garyrobinson.net/2004/03/python_singleto.html#comments). 
+Not guaranteed to be fit for any particular purpose. 
+"""
+
+class SingletonException(Exception):
+    pass
+
+class MetaSingleton(type):
+    def __new__(metaclass, strName, tupBases, dict):
+        if '__new__' in dict:
+            raise SingletonException, 'Can not override __new__ in a Singleton'
+        return super(MetaSingleton,metaclass).__new__(metaclass, strName, tupBases, dict)
+        
+    def __call__(cls, *lstArgs, **dictArgs):
+        raise SingletonException, 'Singletons may only be instantiated through getInstance()'
+        
+class Singleton(object):
+    __metaclass__ = MetaSingleton
+    
+    def getInstance(cls, *lstArgs):
+        """
+        Call this to instantiate an instance or retrieve the existing instance.
+        If the singleton requires args to be instantiated, include them the first
+        time you call getInstance.        
+        """
+        if cls._isInstantiated():
+            if len(lstArgs) != 0:
+                raise SingletonException, 'If no supplied args, singleton must already be instantiated, or __init__ must require no args'
+        else:
+            if len(lstArgs) != cls._getConstructionArgCountNotCountingSelf():
+                raise SingletonException, 'If the singleton requires __init__ args, supply them on first instantiation'
+            instance = cls.__new__(cls)
+            instance.__init__(*lstArgs)
+            cls.cInstance = instance
+        return cls.cInstance
+    getInstance = classmethod(getInstance)
+    
+    def _isInstantiated(cls):
+        return hasattr(cls, 'cInstance')
+    _isInstantiated = classmethod(_isInstantiated)
+
+    def _getConstructionArgCountNotCountingSelf(cls):
+        return cls.__init__.im_func.func_code.co_argcount - 1
+    _getConstructionArgCountNotCountingSelf = classmethod(_getConstructionArgCountNotCountingSelf)
+
+    def _forgetClassInstanceReferenceForTesting(cls):
+        """
+        This is designed for convenience in testing -- sometimes you 
+        want to get rid of a singleton during test code to see what
+        happens when you call getInstance() under a new situation.
+        
+        To really delete the object, all external references to it
+        also need to be deleted.
+        """
+        try:
+            delattr(cls,'cInstance')
+        except AttributeError:
+            # run up the chain of base classes until we find the one that has the instance
+            # and then delete it there
+            for baseClass in cls.__bases__: 
+                if issubclass(baseClass, Singleton):
+                    baseClass._forgetClassInstanceReferenceForTesting()
+    _forgetClassInstanceReferenceForTesting = classmethod(_forgetClassInstanceReferenceForTesting)
+
+
+if __name__ == '__main__':
+    import unittest
+    
+    class PublicInterfaceTest(unittest.TestCase):
+        def testReturnsSameObject(self):
+            """
+            Demonstrates normal use -- just call getInstance and it returns a singleton instance
+            """
+        
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+                    
+            a1 = A.getInstance()
+            a2 = A.getInstance()
+            self.assertEquals(id(a1), id(a2))
+            
+        def testInstantiateWithMultiArgConstructor(self):
+            """
+            If the singleton needs args to construct, include them in the first
+            call to get instances.
+            """
+                    
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            b1 = B.getInstance('arg1 value', 'arg2 value')
+            b2 = B.getInstance()
+            self.assertEquals(b1.arg1, 'arg1 value')
+            self.assertEquals(b1.arg2, 'arg2 value')
+            self.assertEquals(id(b1), id(b2))
+            
+            
+        def testTryToInstantiateWithoutNeededArgs(self):
+            
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            self.assertRaises(SingletonException, B.getInstance)
+            
+        def testTryToInstantiateWithoutGetInstance(self):
+            """
+            Demonstrates that singletons can ONLY be instantiated through
+            getInstance, as long as they call Singleton.__init__ during construction.
+            
+            If this check is not required, you don't need to call Singleton.__init__().
+            """
+
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+                    
+            self.assertRaises(SingletonException, A)
+            
+        def testDontAllowNew(self):
+        
+            def instantiatedAnIllegalClass():
+                class A(Singleton): 
+                    def __init__(self):
+                        super(A, self).__init__()
+                        
+                    def __new__(metaclass, strName, tupBases, dict):
+                        return super(MetaSingleton,metaclass).__new__(metaclass, strName, tupBases, dict)
+                                        
+            self.assertRaises(SingletonException, instantiatedAnIllegalClass)
+        
+        
+        def testDontAllowArgsAfterConstruction(self):
+            class B(Singleton): 
+                    
+                def __init__(self, arg1, arg2):
+                    super(B, self).__init__()
+                    self.arg1 = arg1
+                    self.arg2 = arg2
+
+            b1 = B.getInstance('arg1 value', 'arg2 value')
+            self.assertRaises(SingletonException, B, 'arg1 value', 'arg2 value')
+            
+        def test_forgetClassInstanceReferenceForTesting(self):
+            class A(Singleton): 
+                def __init__(self):
+                    super(A, self).__init__()
+            class B(A): 
+                def __init__(self):
+                    super(B, self).__init__()
+                    
+            # check that changing the class after forgetting the instance produces
+            # an instance of the new class
+            a = A.getInstance()
+            assert a.__class__.__name__ == 'A'
+            A._forgetClassInstanceReferenceForTesting()
+            b = B.getInstance()
+            assert b.__class__.__name__ == 'B'
+            
+            # check that invoking the 'forget' on a subclass still deletes the instance
+            B._forgetClassInstanceReferenceForTesting()
+            a = A.getInstance()
+            B._forgetClassInstanceReferenceForTesting()
+            b = B.getInstance()
+            assert b.__class__.__name__ == 'B'
+
+    unittest.main()
+
+