public static function serialize($tokenRestriction)
    {
        if (!$tokenRestriction->getPrimaryVerificationKey() &&
            ($tokenRestriction->getOpenIdConnectDiscoveryDocument() == null ||
             !$tokenRestriction->getOpenIdConnectDiscoveryDocument()->getOpenIdDiscoveryUri())) {
            throw new \RuntimeException('Both PrimaryVerificationKey and OpenIdConnectDiscoveryDocument are null');
        }

        if (!$tokenRestriction->getAudience()) {
            throw new \RuntimeException('TokenRestrictionTemplate Serialize: Audience is required');
        }

        if (!$tokenRestriction->getIssuer()) {
            throw new \RuntimeException('TokenRestrictionTemplate Serialize: Issuer is required');
        }

        $writer = new \XMLWriter();

        $writer->openMemory();
        $writer->startElementNS(null, 'TokenRestrictionTemplate', Resources::TRT_XML_NAMESPACE);
        $writer->writeAttributeNS('xmlns', 'i', null, Resources::XSI_XML_NAMESPACE);

        if ($tokenRestriction->getAlternateVerificationKeys()) {
            self::serializeAlternateVerificationKeys($writer, $tokenRestriction->getAlternateVerificationKeys());
        }

        $writer->writeElement('Audience', $tokenRestriction->getAudience());
        $writer->writeElement('Issuer', $tokenRestriction->getIssuer());

        if ($tokenRestriction->getPrimaryVerificationKey()) {
            $writer->startElement('PrimaryVerificationKey');
            self::serializeTokenVerificationKey($writer, $tokenRestriction->getPrimaryVerificationKey());
            $writer->endElement();
        }

        if ($tokenRestriction->getRequiredClaims()) {
            self::serializeRequiredClaims($writer, $tokenRestriction->getRequiredClaims());
        }

        if ($tokenRestriction->getTokenType()) {
            $writer->writeElement('TokenType', $tokenRestriction->getTokenType());
        }

        if ($tokenRestriction->getOpenIdConnectDiscoveryDocument()) {
            self::serializeOpenIdConnectDiscoveryDocument(
                $writer, $tokenRestriction->getOpenIdConnectDiscoveryDocument()
            );
        }

        $writer->endElement();

        return $writer->outputMemory();
    }