docs: def mapped_jsontree_class(mapping):
      """Return a class which is a jsontree, but with a supplied attribute name
      mapping. The mapping argument can be a mapping object
      (dict, jsontree, etc.) or it can be a callable which takes a single
      argument (the attribute name), and returns a new name.
      
      This is useful in situations where you have a jsontree with keys that are
      not valid python attribute names, to simplify communication with a client
      library, or allow for configurable names.
      
      For example:
      
      >>> numjt = mapped_jsontree_class(dict(one='1', two='2', three='3'))
      >>> number = numjt()
      >>> number.one = 'something'
      >>> number
      defaultdict(<class 'jsontree.mapped_jsontree'>, {'1': 'something'})
      
      This is very useful for abstracting field names that may change between
      a development sandbox and production environment. Both FogBugz and Jira
      bug trackers have custom fields with dynamically generated values. These
      field names can be abstracted out into a configruation mapping, and the
      jsontree code can be standardized.
      
      This can also be iseful for JavaScript API's (PHPCake) which insist on
      having spaces in some key names. A function can be supplied which maps
      all '_'s in the attribute name to spaces:
      
      >>> spacify = lambda name: name.replace('_', ' ')
      >>> spacemapped = mapped_jsontree_class(spacify)
      >>> sm = spacemapped()
      >>> sm.hello_there = 5
      >>> sm.hello_there
      5
      >>> sm.keys()
      ['hello there']
      
          
      This will also work with non-string keys for translating from libraries
      that use object keys in python over to string versions of the keys in JSON
      
      >>> numjt = mapped_jsontree_class(dict(one=1, two=2))
      >>> number = numjt()
      >>> number.one = 'something'
      >>> number
      defaultdict(<class 'jsontree.mapped_jsontree'>, {1: 'something'})
      >>> numjt_as_text = mapped_jsontree_class(dict(one='1', two='2'))
      >>> dumped_number = dumps(number)
      >>> loaded_number = loads(dumped_number, jsontreecls=numjt_as_text)
      >>> loaded_number.one
      'something'
      >>> loaded_number
      defaultdict(<class 'jsontree.mapped_jsontree'>, {'1': 'something'})
      
      """
      mapper = mapping
      if not callable(mapping):
          if not isinstance(mapping, collections.Mapping):
              raise TypeError("Argument mapping is not collable or an instance "
                                "of collections.Mapping")
          mapper = lambda name: mapping.get(name, name)
      class mapped_jsontree(collections.defaultdict):
          def __init__(self, *args, **kwdargs):
              super(mapped_jsontree, self).__init__(mapped_jsontree, *args, **kwdargs)
          def __getattribute__(self, name):
              mapped_name = mapper(name)
              if not isinstance(mapped_name, basestring):
                  return self[mapped_name]
              try:
                  return object.__getattribute__(self, mapped_name)
              except AttributeError:
                  return self[mapped_name]
          def __setattr__(self, name, value):
              mapped_name = mapper(name)
              self[mapped_name] = value
              return value
      return mapped_jsontree