docs: def deserialize(cls, value, trusted=False, strict=False,
                      assert_valid=False, **kwargs):
          """Deserialize nested HasUID instance from flat pointer dictionary
  
          **Parameters**
  
          * **value** - Flat pointer dictionary produced by :code:`serialize`
            with UID/HasUID key/value pairs. It also includes a
            :code:`__root__` key to specify the root HasUID instance.
          * **trusted** - If True (and if the input dictionaries have
            :code:`'__class__'` keyword and this class is in the registry), the
            new **HasProperties** class will come from the dictionary.
            If False (the default), only the **HasProperties** class this
            method is called on will be constructed.
          * **strict** - Requires :code:`'__class__'`, if present on the input
            dictionary, to match the deserialized instance's class. Also
            disallows unused properties in the input dictionary. Default
            is False.
          * **assert_valid** - Require deserialized instance to be valid.
            Default is False.
          * You may also specify an alternative **root** - This allows a different
            HasUID root instance to be specified. It overrides :code:`__root__`
            in the input dictionary.
          * Any other keyword arguments will be passed through to the Property
            deserializers.
  
          .. note::
  
              HasUID instances are constructed with no input arguments
              (ie :code:`cls()` is called). This means deserialization will
              fail if the init method has been overridden to require
              input parameters.
          """
          registry = kwargs.pop('registry', None)
          if registry is None:
              if not isinstance(value, dict):
                  raise ValueError('HasUID must deserialize from dictionary')
              registry = value.copy()
              uid = kwargs.get('root', registry.get('__root__'))
          else:
              uid = value
          if uid in cls._INSTANCES and uid not in registry:
              return cls._INSTANCES[uid]
          if uid in cls._INSTANCES:
              raise ValueError('UID already used: {}'.format(uid))
          if uid not in registry:
              raise ValueError('Invalid UID: {}'.format(uid))
          value = registry[uid]
          if not isinstance(value, HasUID):
              try:
                  input_class = value.get('__class__')
              except AttributeError:
                  input_class = None
              new_cls = cls._deserialize_class(input_class, trusted, strict)
              new_inst = new_cls()
              registry.update({uid: new_inst})
              super(HasUID, cls).deserialize(
                  value=value,
                  trusted=trusted,
                  strict=strict,
                  registry=registry,
                  _instance=new_inst,
                  **kwargs
              )
          cls._INSTANCES[uid] = registry[uid]
          return registry[uid]