/// <summary>
        /// Generates the OpenID Providers that are capable of asserting ownership
        /// of a particular XRI claimed identifier.
        /// </summary>
        /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
        /// <param name="userSuppliedIdentifier">The i-name supplied by the user.</param>
        /// <returns>A sequence of the providers that can assert ownership of the given identifier.</returns>
        private static IEnumerable <IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable <XrdElement> xrds, XriIdentifier userSuppliedIdentifier)
        {
            // Cannot use code contracts because this method uses yield return.
            ////Contract.Requires<ArgumentNullException>(xrds != null);
            ////Contract.Ensures(Contract.Result<IEnumerable<IdentifierDiscoveryResult>>() != null);
            ErrorUtilities.VerifyArgumentNotNull(xrds, "xrds");

            foreach (var service in xrds.FindClaimedIdentifierServices())
            {
                foreach (var uri in service.UriElements)
                {
                    // spec section 7.3.2.3 on Claimed Id -> CanonicalID substitution
                    if (service.Xrd.CanonicalID == null)
                    {
                        break; // skip on to next service
                    }
                    ErrorUtilities.VerifyProtocol(service.Xrd.IsCanonicalIdVerified, XrdsStrings.CIDVerificationFailed, userSuppliedIdentifier);

                    // In the case of XRI names, the ClaimedId is actually the CanonicalID.
                    var claimedIdentifier = new XriIdentifier(service.Xrd.CanonicalID);
                    var providerEndpoint  = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris);
                    yield return(IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority));
                }
            }
        }
 /// <summary>
 /// Generates OpenID Providers that can authenticate using directed identity.
 /// </summary>
 /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
 /// <param name="opIdentifier">The OP Identifier entered (and resolved) by the user.  Essentially the user-supplied identifier.</param>
 /// <returns>A sequence of the providers that can offer directed identity services.</returns>
 private static IEnumerable <IdentifierDiscoveryResult> GenerateOPIdentifierServiceEndpoints(this IEnumerable <XrdElement> xrds, Identifier opIdentifier)
 {
     return(from service in xrds.FindOPIdentifierServices()
            from uri in service.UriElements
            let protocol = Protocol.FindBestVersion(p => p.OPIdentifierServiceTypeURI, service.TypeElementUris)
                           let providerDescription = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
                                                     select IdentifierDiscoveryResult.CreateForProviderIdentifier(opIdentifier, providerDescription, service.Priority, uri.Priority));
 }
 /// <summary>
 /// Generates the OpenID Providers that are capable of asserting ownership
 /// of a particular URI claimed identifier.
 /// </summary>
 /// <param name="xrds">The XrdsDocument instance to use in this process.</param>
 /// <param name="claimedIdentifier">The claimed identifier.</param>
 /// <param name="userSuppliedIdentifier">The user supplied identifier.</param>
 /// <returns>
 /// A sequence of the providers that can assert ownership of the given identifier.
 /// </returns>
 private static IEnumerable <IdentifierDiscoveryResult> GenerateClaimedIdentifierServiceEndpoints(this IEnumerable <XrdElement> xrds, UriIdentifier claimedIdentifier, UriIdentifier userSuppliedIdentifier)
 {
     return(from service in xrds.FindClaimedIdentifierServices()
            from uri in service.UriElements
            where uri.Uri != null
            let providerEndpoint = new ProviderEndpointDescription(uri.Uri, service.TypeElementUris)
                                   select IdentifierDiscoveryResult.CreateForClaimedIdentifier(claimedIdentifier, userSuppliedIdentifier, service.ProviderLocalIdentifier, providerEndpoint, service.Priority, uri.Priority));
 }
 /// <summary>
 /// Gets the priority rating for a given type of endpoint, allowing a
 /// priority sorting of endpoints.
 /// </summary>
 /// <param name="endpoint">The endpoint to prioritize.</param>
 /// <returns>An arbitary integer, which may be used for sorting against other returned values from this method.</returns>
 private static double GetEndpointPrecedenceOrderByServiceType(IdentifierDiscoveryResult endpoint)
 {
     // The numbers returned from this method only need to compare against other numbers
     // from this method, which makes them arbitrary but relational to only others here.
     if (endpoint.Capabilities.Contains(Protocol.V20.OPIdentifierServiceTypeURI))
     {
         return 0;
     }
     if (endpoint.Capabilities.Contains(Protocol.V20.ClaimedIdentifierServiceTypeURI))
     {
         return 1;
     }
     if (endpoint.Capabilities.Contains(Protocol.V11.ClaimedIdentifierServiceTypeURI))
     {
         return 2;
     }
     if (endpoint.Capabilities.Contains(Protocol.V10.ClaimedIdentifierServiceTypeURI))
     {
         return 3;
     }
     return 10;
 }