public static function createFromString(string $token) : SignedJwt
    {
        $segments = explode('.', $token);

        if (count($segments) !== 3) {
            throw new InvalidArgumentException('Token did not contain 3 segments');
        }

        list($encodedHeader, $encodedPayload, $encodedSignature) = $segments;
        $decodedHeader = \json_decode(self::base64UrlDecode($encodedHeader), true, 512, JSON_BIGINT_AS_STRING);
        $decodedPayload = \json_decode(self::base64UrlDecode($encodedPayload), true, 512, JSON_BIGINT_AS_STRING);
        $signature = self::base64UrlDecode($encodedSignature);

        if ($decodedHeader === null) {
            throw new InvalidArgumentException('Invalid header');
        }

        if ($decodedPayload === null) {
            throw new InvalidArgumentException('Invalid payload');
        }

        if (!isset($decodedHeader['alg'])) {
            throw new InvalidArgumentException('No algorithm set in header');
        }

        $header = new JwtHeader($decodedHeader['alg'], $decodedHeader);
        $payload = new JwtPayload();

        if (is_array($decodedPayload)) {
            foreach ($decodedPayload as $name => $value) {
                $payload->add($name, $value);
            }
        }

        return new self($header, $payload, $signature);
    }