public function build(): JWS
    {
        if (null === $this->payload) {
            throw new \RuntimeException('The payload is not set.');
        }
        if (0 === \count($this->signatures)) {
            throw new \RuntimeException('At least one signature must be set.');
        }

        $encodedPayload = false === $this->isPayloadEncoded ? $this->payload : Base64Url::encode($this->payload);
        $jws = JWS::create($this->payload, $encodedPayload, $this->isPayloadDetached);
        foreach ($this->signatures as $signature) {
            /** @var SignatureAlgorithm $signatureAlgorithm */
            $signatureAlgorithm = $signature['signature_algorithm'];
            /** @var JWK $signatureKey */
            $signatureKey = $signature['signature_key'];
            /** @var array $protectedHeader */
            $protectedHeader = $signature['protected_header'];
            /** @var array $header */
            $header = $signature['header'];
            $encodedProtectedHeader = empty($protectedHeader) ? null : Base64Url::encode($this->jsonConverter->encode($protectedHeader));
            $input = \sprintf('%s.%s', $encodedProtectedHeader, $encodedPayload);
            $s = $signatureAlgorithm->sign($signatureKey, $input);
            $jws = $jws->addSignature($s, $protectedHeader, $encodedProtectedHeader, $header);
        }

        return $jws;
    }