/// <summary>
        /// Initializes a new <c>VssOAuthTokenRequest</c> instance with the specified grant and client credential.
        /// Additional parameters specified by the token parameters will be provided in the token request.
        /// </summary>
        /// <param name="grant">The authorization grant to use for the token request</param>
        /// <param name="clientCredential">The client credential to use for the token request</param>
        /// <param name="tokenParameters">An optional set of additional parameters for the token request</param>
        public VssOAuthTokenRequest(
            VssOAuthGrant grant,
            VssOAuthClientCredential clientCredential,
            VssOAuthTokenParameters tokenParameters)
        {
            ArgumentUtility.CheckForNull(grant, nameof(grant));

            m_grant            = grant;
            m_clientCredential = clientCredential;
            m_tokenParameters  = tokenParameters;
        }
 /// <summary>
 /// Initializes a new <c>VssOAuthTokenProvider</c> instance for the specified credential.
 /// </summary>
 /// <param name="credential">The <c>VssOAuthCredential</c> instance which owns the token provider</param>
 /// <param name="serverUrl">The resource server which issued the authentication challenge</param>
 /// <param name="authorizationUrl">The authorization server token endpoint</param>
 /// <param name="grant">The authorization grant to use for token requests</param>
 /// <param name="clientCrential">The client credentials to use for token requests</param>
 /// <param name="tokenParameters">Additional parameters to include with token requests </param>
 protected VssOAuthTokenProvider(
     IssuedTokenCredential credential,
     Uri serverUrl,
     Uri authorizationUrl,
     VssOAuthGrant grant,
     VssOAuthClientCredential clientCrential,
     VssOAuthTokenParameters tokenParameters)
     : base(credential, serverUrl, authorizationUrl)
 {
     m_grant            = grant;
     m_tokenParameters  = tokenParameters;
     m_clientCredential = clientCrential;
 }
        /// <summary>
        /// Performs a token exchange using the specified authorization grant and client credentials.
        /// </summary>
        /// <param name="grant">The authorization grant for the token request</param>
        /// <param name="credential">The credentials to present to the secure token service as proof of identity</param>
        /// <param name="tokenParameters">An collection of additional parameters to provide for the token request</param>
        /// <param name="cancellationToken">A token for signalling cancellation</param>
        /// <returns>A <c>Task&lt;VssOAuthTokenResponse&gt;</c> which may be used to track progress of the token request</returns>
        public async Task <VssOAuthTokenResponse> GetTokenAsync(
            VssOAuthGrant grant,
            VssOAuthClientCredential credential,
            VssOAuthTokenParameters tokenParameters = null,
            CancellationToken cancellationToken     = default(CancellationToken))
        {
            VssTraceActivity traceActivity = VssTraceActivity.Current;

            using (HttpClient client = new HttpClient(CreateMessageHandler(this.AuthorizationUrl)))
            {
                var requestMessage = new HttpRequestMessage(HttpMethod.Post, this.AuthorizationUrl);
                requestMessage.Content = CreateRequestContent(grant, credential, tokenParameters);
                requestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));

                if (VssClientHttpRequestSettings.Default.UseHttp11)
                {
                    requestMessage.Version = HttpVersion.Version11;
                }

                foreach (var headerVal in VssClientHttpRequestSettings.Default.UserAgent)
                {
                    if (!requestMessage.Headers.UserAgent.Contains(headerVal))
                    {
                        requestMessage.Headers.UserAgent.Add(headerVal);
                    }
                }

                using (var response = await client.SendAsync(requestMessage, cancellationToken: cancellationToken).ConfigureAwait(false))
                {
                    string correlationId = "Unknown";
                    if (response.Headers.TryGetValues("x-ms-request-id", out IEnumerable <string> requestIds))
                    {
                        correlationId = string.Join(",", requestIds);
                    }
                    VssHttpEventSource.Log.AADCorrelationID(correlationId);

                    if (IsValidTokenResponse(response))
                    {
                        return(await response.Content.ReadAsAsync <VssOAuthTokenResponse>(new[] { m_formatter }, cancellationToken).ConfigureAwait(false));
                    }
                    else
                    {
                        var responseContent = await response.Content.ReadAsStringAsync().ConfigureAwait(false);

                        throw new VssServiceResponseException(response.StatusCode, responseContent, null);
                    }
                }
            }
        }
        /// <summary>
        /// Initializes a new <c>VssOAuthCredential</c> instance with the specified authorization grant and client
        /// credentials.
        /// </summary>
        /// <param name="authorizationUrl">The location of the token endpoint for the target authorization server</param>
        /// <param name="grant">The grant to provide for the token exchange</param>
        /// <param name="clientCredential">The client credentials to provide for the token exchange</param>
        /// <param name="tokenParameters">An optional set of token parameters which, if present, are sent in the request body of the token request</param>
        /// <param name="accessToken">An optional access token which, if present, is used prior to requesting new tokens</param>
        public VssOAuthCredential(
            Uri authorizationUrl,
            VssOAuthGrant grant,
            VssOAuthClientCredential clientCredential,
            VssOAuthTokenParameters tokenParameters = null,
            VssOAuthAccessToken accessToken         = null)
            : base(accessToken)
        {
            ArgumentUtility.CheckForNull(authorizationUrl, nameof(authorizationUrl));
            ArgumentUtility.CheckForNull(grant, nameof(grant));

            m_authorizationUrl = authorizationUrl;
            m_grant            = grant;
            m_tokenParameters  = tokenParameters;
            m_clientCredential = clientCredential;
        }