public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState)
        {
            string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint;

            instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{host}", host);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{tenant}", tenant);

            instanceDiscoveryEndpoint = HttpHelper.CheckForExtraQueryParameter(instanceDiscoveryEndpoint);

            ClientMetrics clientMetrics = new ClientMetrics();

            try
            {
                IHttpWebRequest request = NetworkPlugin.HttpWebRequestFactory.Create(instanceDiscoveryEndpoint);
                request.Method = "GET";
                HttpHelper.AddCorrelationIdHeadersToRequest(request, callState);
                AdalIdHelper.AddAsHeaders(request);

                clientMetrics.BeginClientMetricsRecord(request, callState);

                using (var response = await request.GetResponseSyncOrAsync(callState))
                {
                    HttpHelper.VerifyCorrelationIdHeaderInReponse(response, callState);
                    InstanceDiscoveryResponse discoveryResponse = HttpHelper.DeserializeResponse <InstanceDiscoveryResponse>(response);
                    clientMetrics.SetLastError(null);
                    if (discoveryResponse.TenantDiscoveryEndpoint == null)
                    {
                        throw new AdalException(AdalError.AuthorityNotInValidList);
                    }
                }
            }
            catch (WebException ex)
            {
                TokenResponse tokenResponse = OAuth2Response.ReadErrorResponse(ex.Response);
                clientMetrics.SetLastError(tokenResponse.ErrorCodes);

                if (tokenResponse.Error == "invalid_instance")
                {
                    throw new AdalServiceException(AdalError.AuthorityNotInValidList, ex);
                }
                else
                {
                    throw new AdalServiceException(
                              AdalError.AuthorityValidationFailed,
                              string.Format(CultureInfo.InvariantCulture, "{0}. {1}: {2}", AdalErrorMessage.AuthorityValidationFailed, tokenResponse.Error, tokenResponse.ErrorDescription),
                              tokenResponse.ErrorCodes,
                              ex);
                }
            }
            finally
            {
                clientMetrics.EndClientMetricsRecord(ClientMetricsEndpointType.InstanceDiscovery, callState);
            }
        }
        // No return value. Modifies InstanceCache directly.
        private static async Task DiscoverAsync(Uri authority, bool validateAuthority, CallState callState)
        {
            string instanceDiscoveryEndpoint = string.Format(
                CultureInfo.InvariantCulture,
                "https://{0}/common/discovery/instance?api-version=1.1&authorization_endpoint={1}",
                WhitelistedAuthorities.Contains(authority.Host) ? authority.Host : DefaultTrustedAuthority,
                FormatAuthorizeEndpoint(authority.Host, GetTenant(authority)));
            var client = new AdalHttpClient(instanceDiscoveryEndpoint, callState);
            InstanceDiscoveryResponse discoveryResponse = null;

            try
            {
                discoveryResponse = await client.GetResponseAsync <InstanceDiscoveryResponse>().ConfigureAwait(false);

                if (validateAuthority && discoveryResponse.TenantDiscoveryEndpoint == null)
                {
                    // hard stop here
                    throw new AdalException(AdalError.AuthorityNotInValidList);
                }
            }
            catch (AdalServiceException ex)
            {
                // The pre-existing implementation (https://github.com/AzureAD/azure-activedirectory-library-for-dotnet/pull/796/files#diff-e4febd8f40f03e71bcae0f990f9690eaL99)
                // has been coded in this way: it catches the AdalServiceException and then translate it into 2 validation-relevant exceptions.
                // So the following implementation absorbs these specific exceptions when the validateAuthority flag is false.
                // All other unexpected exceptions will still bubble up, as always.
                if (validateAuthority)
                {
                    // hard stop here
                    throw new AdalException(
                              (ex.ErrorCode == "invalid_instance")
                            ? AdalError.AuthorityNotInValidList
                            : AdalError.AuthorityValidationFailed, ex);
                }
            }

            foreach (var entry in discoveryResponse?.Metadata ?? Enumerable.Empty <InstanceDiscoveryMetadataEntry>())
            {
                foreach (var aliasedAuthority in entry?.Aliases ?? Enumerable.Empty <string>())
                {
                    InstanceCache.TryAdd(aliasedAuthority, entry);
                }
            }

            AddMetadataEntry(authority.Host);
        }
        public async Task VerifyAnotherHostByInstanceDiscoveryAsync(string host, string tenant, CallState callState)
        {
            string instanceDiscoveryEndpoint = this.InstanceDiscoveryEndpoint;

            instanceDiscoveryEndpoint += ("?api-version=1.0&authorization_endpoint=" + AuthorizeEndpointTemplate);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{host}", host);
            instanceDiscoveryEndpoint  = instanceDiscoveryEndpoint.Replace("{tenant}", tenant);

            try
            {
                var client = new AdalHttpClient(instanceDiscoveryEndpoint, callState);
                InstanceDiscoveryResponse discoveryResponse = await client.GetResponseAsync <InstanceDiscoveryResponse>().ConfigureAwait(false);

                if (discoveryResponse.TenantDiscoveryEndpoint == null)
                {
                    throw new AdalException(AdalError.AuthorityNotInValidList);
                }
            }
            catch (AdalServiceException ex)
            {
                throw new AdalException((ex.ErrorCode == "invalid_instance") ? AdalError.AuthorityNotInValidList : AdalError.AuthorityValidationFailed, ex);
            }
        }