def unpack(self, token):
        """
        Unpack a received signed or signed and encrypted Json Web Token

        :param token: The Json Web Token
        :return: If decryption and signature verification work the payload
            will be returned as a Message instance if possible.
        """
        if not token:
            raise KeyError

        _jwe_header = _jws_header = None

        # Check if it's an encrypted JWT
        darg = {}
        if self.allowed_enc_encs:
            darg['enc'] = self.allowed_enc_encs
        if self.allowed_enc_algs:
            darg['alg'] = self.allowed_enc_algs
        try:
            _decryptor = jwe_factory(token, **darg)
        except (KeyError, HeaderError):
            _decryptor = None

        if _decryptor:
            # Yes, try to decode
            _info = self._decrypt(_decryptor, token)
            _jwe_header = _decryptor.jwt.headers
            # Try to find out if the information encrypted was a signed JWT
            try:
                _content_type = _decryptor.jwt.headers['cty']
            except KeyError:
                _content_type = ''
        else:
            _content_type = 'jwt'
            _info = token

        # If I have reason to believe the information I have is a signed JWT
        if _content_type.lower() == 'jwt':
            # Check that is a signed JWT
            if self.allowed_sign_algs:
                _verifier = jws_factory(_info, alg=self.allowed_sign_algs)
            else:
                _verifier = jws_factory(_info)

            if _verifier:
                _info = self._verify(_verifier, _info)
            else:
                raise Exception()
            _jws_header = _verifier.jwt.headers
        else:
            # So, not a signed JWT
            try:
                # A JSON document ?
                _info = json.loads(_info)
            except JSONDecodeError:  # Oh, no ! Not JSON
                return _info
            except TypeError:
                try:
                    _info = as_unicode(_info)
                    _info = json.loads(_info)
                except JSONDecodeError:  # Oh, no ! Not JSON
                    return _info

        # If I know what message class the info should be mapped into
        if self.msg_cls:
            _msg_cls = self.msg_cls
        else:
            try:
                # try to find a issuer specific message class
                _msg_cls = self.iss2msg_cls[_info['iss']]
            except KeyError:
                _msg_cls = None

        if _msg_cls:
            vp_args = {'skew': self.skew}
            if self.iss:
                vp_args['aud'] = self.iss
            _info = self.verify_profile(_msg_cls, _info, **vp_args)
            _info.jwe_header = _jwe_header
            _info.jws_header = _jws_header
            return _info
        else:
            return _info
Unpack a received signed or signed and encrypted Json Web Token

        :param token: The Json Web Token
        :return: If decryption and signature verification work the payload
            will be returned as a Message instance if possible.