text: #!/usr/bin/env python
  """
  Twisted Related Utility Code
  ----------------------------
  """
  
  from collections import defaultdict
  
  from twisted.internet.defer import Deferred
  
  class ObservableDict(dict):
      """Subclass of dict which can return deferreds which fire when a key's
      value changes."""
  
      def __init__(self, *args, **kwargs):
          self._listeners = defaultdict(lambda: [])
          super(ObservableDict, self).__init__(*args, **kwargs)
  
      def deferred_getitem(self, key, immediate=False):
          """Like dict[], but returns a deferred.
  
  	Setting 'immediate=True' causes the callback to fire immediately. This
  	could result in a KeyError.
  
          Setting 'immediate=False' (the default) causes the callback to fire
          when the value stored at the key changes. If the key is not in the
          dict, the deferred will not fire until the key is added to the dict,
          hence KeyError cannot be raised.
          """
          deferred = Deferred()
          deferred.addCallback(lambda r: self[key])
          if immediate:
              deferred.callback(None)
          else:
              self._add_listener(key, deferred)
          return deferred
  
      def deferred_get(self, key, default=None, immediate=False):
          """Like dict.get() but returns a deferred.
  
  	Setting 'immediate=True' causes the callback to fire immediately; the
          default value will be returned if the key is not in the dict.
  
          Setting 'immediate=False' (the default) causes the callback to fire
          when the value stored at the key changes. If the key is not in the
          dict, the deferred will not fire until the key is added to the dict,
          hence the default value will never be returned.
          """
          deferred = Deferred()
          deferred.addCallback(lambda r: super(ObservableDict, self).get(key, default))
          if immediate:
              deferred.callback(None)
          else:
              self._add_listener(key, deferred)
          return deferred
  
      def _add_listener(self, key, deferred):
          """Adds listener d to the list of listeners for key."""
          self._listeners[key].append(deferred)
  
      def __setitem__(self, key, val):
          """Like dict.__setitem__ but also notifies listeners of the change."""
          super(ObservableDict, self).__setitem__(key, val)
          # notify listeners and reset list for key
          listeners = self._listeners[key]
          del self._listeners[key]
          for listener in listeners:
              listener.callback(val)
  
  