public static function deserialize($template)
    {
        $xml = simplexml_load_string($template);
        $result = new TokenRestrictionTemplate();

        // Validation
        if ($xml->getName() !== 'TokenRestrictionTemplate') {
            throw new \RuntimeException("This is not a TokenRestrictionTemplate, it is a '{$xml->getName()}'");
        }
        if (!isset($xml->Issuer)) {
            throw new \RuntimeException("The TokenRestrictionTemplate must contains an 'Issuer' element");
        }
        if (!isset($xml->Audience)) {
            throw new \RuntimeException("The TokenRestrictionTemplate must contains an 'Audience' element");
        }
        if (!isset($xml->PrimaryVerificationKey) &&
            !isset($xml->OpenIdConnectDiscoveryDocument)) {
            throw new \RuntimeException('Both PrimaryVerificationKey and OpenIdConnectDiscoveryDocument are undefined');
        }

        // decoding
        if (isset($xml->AlternateVerificationKeys)) {
            $result->setAlternateVerificationKeys(
                self::deserializeAlternateVerificationKeys($xml->AlternateVerificationKeys)
            );
        }

        $result->setAudience((string) $xml->Audience);
        $result->setIssuer((string) $xml->Issuer);

        if (isset($xml->PrimaryVerificationKey)) {
            $result->setPrimaryVerificationKey(self::deserializeTokenVerificationKey($xml->PrimaryVerificationKey));
        }

        if (isset($xml->RequiredClaims)) {
            $result->setRequiredClaims(self::deserializeRequiredClaims($xml->RequiredClaims));
        }

        if (isset($xml->TokenType)) {
            $result->setTokenType((string) $xml->TokenType);
        }

        if (isset($xml->OpenIdConnectDiscoveryDocument)) {
            $result->setOpenIdConnectDiscoveryDocument(
                self::deserializeOpenIdConnectDiscoveryDocument($xml->OpenIdConnectDiscoveryDocument)
            );
        }

        return $result;
    }