:type obj dict|None
    :type ignore_non_existing bool

def deserialize(self, obj=None, ignore_non_existing=False):
    """
    :type obj dict|None
    :type ignore_non_existing bool
    """
    if not isinstance(obj, dict):
      if ignore_non_existing:
        return

      raise TypeError("Wrong data '{}' passed for '{}' deserialization".format(obj, self.__class__.__name__))

    definitions = {k: v for k, v in self.__class__.__dict__.items() if k[:1] != "_"}
    def_property_keys = set(definitions.keys())
    property_keys = set(obj.keys())

    existing_keys = def_property_keys & property_keys
    non_defined_keys = property_keys - def_property_keys
    non_existing_keys = def_property_keys - property_keys

    if not ignore_non_existing and non_defined_keys:
      raise TypeError(self.__class__.__name__ + " doesn't contain properties: {}".format(", ".join(non_defined_keys)))

    for k in existing_keys:
      v = obj[k]
      attr_type = definitions[k]

      try:
        if isinstance(attr_type, list) and self._isclass(attr_type[0], BaseView):
          if isinstance(v, list):
            obj_list = [attr_type[0](serialized_obj=v_item, ignore_non_existing=ignore_non_existing) for v_item in v]
          else:
            obj_list = [attr_type[0](serialized_obj=v, ignore_non_existing=ignore_non_existing)]

          self.__setattr__(k, obj_list)
        elif self._isclass(attr_type, BaseView):
          self.__setattr__(k, attr_type(v))
        else:
          self.__setattr__(k, v)
      except IndexError:
        self.__setattr__(k, v)  # check test_empty_view_deserialization test suite for test-case

    for k in non_existing_keys:
      attr_type = definitions[k]

      if attr_type is None:
        self.__setattr__(k, None)
      elif isinstance(attr_type, (list, set, tuple, dict)) and len(attr_type) == 0:
        self.__setattr__(k, attr_type.__class__())
      elif isinstance(attr_type, (list, set, tuple)) and self._isclass(attr_type[0], BaseView):
        self.__setattr__(k, attr_type.__class__())
      else:
        self.__setattr__(k, attr_type.__class__(attr_type))

    return self