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))
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