docs: def _add_value(self, skey, vtyp, key, val, _deser, null_allowed):
          """
          Main method for adding a value to the instance. Does all the
          checking on type of value and if among allowed values.
          
          :param skey: string version of the key 
          :param vtyp: Type of value
          :param key: original representation of the key
          :param val: The value to add
          :param _deser: A deserializer for this value type
          :param null_allowed: Whether null is an allowed value for this key
          """
  
          if isinstance(val, list):
              if (len(val) == 0 or val[0] is None) and null_allowed is False:
                  return
  
          if isinstance(vtyp, tuple):
              vtyp = vtyp[0]
  
          if isinstance(vtyp, list):
              vtype = vtyp[0]
              if isinstance(val, vtype):
                  if issubclass(vtype, Message):
                      self._dict[skey] = [val]
                  elif _deser:
                      try:
                          self._dict[skey] = _deser(val, sformat="urlencoded")
                      except Exception as exc:
                          raise DecodeError(ERRTXT % (key, exc))
                  else:
                      setattr(self, skey, [val])
              elif isinstance(val, list):
                  if _deser:
                      try:
                          val = _deser(val, sformat="dict")
                      except Exception as exc:
                          raise DecodeError(ERRTXT % (key, exc))
  
                  if issubclass(vtype, Message):
                      try:
                          _val = []
                          for v in val:
                              _val.append(vtype(**dict([(str(x), y) for x, y
                                                        in v.items()])))
                          val = _val
                      except Exception as exc:
                          raise DecodeError(ERRTXT % (key, exc))
                  else:
                      for v in val:
                          if not isinstance(v, vtype):
                              raise DecodeError(
                                  ERRTXT % (key, "type != %s (%s)" % (
                                      vtype, type(v))))
  
                  self._dict[skey] = val
              elif isinstance(val, dict):
                  try:
                      val = _deser(val, sformat="dict")
                  except Exception as exc:
                      raise DecodeError(ERRTXT % (key, exc))
                  else:
                      self._dict[skey] = val
              else:
                  raise DecodeError(ERRTXT % (key, "type != %s" % vtype))
          else:
              if val is None:
                  self._dict[skey] = None
              elif isinstance(val, bool):
                  if vtyp is bool:
                      self._dict[skey] = val
                  else:
                      raise ValueError(
                          '"{}", wrong type of value for "{}"'.format(val, skey))
              elif isinstance(val, vtyp):  # Not necessary to do anything
                  self._dict[skey] = val
              else:
                  if _deser:
                      try:
                          val = _deser(val, sformat="dict")
                      except Exception as exc:
                          raise DecodeError(ERRTXT % (key, exc))
                      else:
                          # if isinstance(val, str):
                          #     self._dict[skey] = val
                          # elif isinstance(val, list):
                          #     if len(val) == 1:
                          #         self._dict[skey] = val[0]
                          #     elif not len(val):
                          #         pass
                          #     else:
                          #         raise TooManyValues(key)
                          # else:
                          self._dict[skey] = val
                  elif vtyp is int:
                      try:
                          self._dict[skey] = int(val)
                      except (ValueError, TypeError):
                          raise ValueError(
                              '"{}", wrong type of value for "{}"'.format(val,
                                                                          skey))
                  elif vtyp is bool:
                      raise ValueError(
                          '"{}", wrong type of value for "{}"'.format(val, skey))
                  elif vtyp != type(val):
                      if vtyp == Message:
                          if type(val) == dict or isinstance(val, str):
                              self._dict[skey] = val
                          else:
                              raise ValueError(
                                  '"{}", wrong type of value for "{}"'.format(
                                      val, skey))
                      else:
                          raise ValueError(
                              '"{}", wrong type of value for "{}"'.format(val,
                                                                          skey))