public async Task <string> ValidateCredentialAsync(CancellationToken cancellationToken)
        {
            var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl);
            var tokenResponse   = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken);

            // return the underlying authentication error
            return(tokenResponse.Error);
        }
        /// <summary>
        /// Issues a token request to the configured secure token service. On success, the access token issued by the
        /// token service is returned to the caller
        /// </summary>
        /// <param name="failedToken">If applicable, the previous token which is now considered invalid</param>
        /// <param name="cancellationToken">A token used for signalling cancellation</param>
        /// <returns>A <c>Task&lgt;IssuedToken&gt;</c> for tracking the progress of the token request</returns>
        protected override async Task <IssuedToken> OnGetTokenAsync(
            IssuedToken failedToken,
            CancellationToken cancellationToken)
        {
            if (this.SignInUrl == null ||
                this.Grant == null ||
                this.ClientCredential == null)
            {
                return(null);
            }

            IssuedToken issuedToken   = null;
            var         traceActivity = VssTraceActivity.Current;

            try
            {
                var tokenHttpClient = new VssOAuthTokenHttpClient(this.SignInUrl);
                var tokenResponse   = await tokenHttpClient.GetTokenAsync(this.Grant, this.ClientCredential, this.TokenParameters, cancellationToken).ConfigureAwait(false);

                if (!String.IsNullOrEmpty(tokenResponse.AccessToken))
                {
                    // Construct a new access token based on the response, including the expiration time so we know
                    // when to refresh the token.
                    issuedToken = CreateIssuedToken(tokenResponse);

                    if (!String.IsNullOrEmpty(tokenResponse.RefreshToken))
                    {
                        // TODO: How should this flow be handled? Refresh Token is a credential change which is not
                        //       the same thing as access token storage
                    }
                }
                else if (!String.IsNullOrEmpty(tokenResponse.Error))
                {
                    // Raise a new exception describing the underlying authentication error
                    throw new VssOAuthTokenRequestException(tokenResponse.ErrorDescription)
                          {
                              Error = tokenResponse.Error,
                          };
                }
                else
                {
                    // If the error property isn't set, but we didn't get an access token, then it's not
                    // clear what the issue is. In this case just trace the response and fall through with
                    // a null access token return value.
                    var sb         = new StringBuilder();
                    var serializer = JsonSerializer.Create(s_traceSettings.Value);
                    using (var sr = new StringWriter(sb))
                    {
                        serializer.Serialize(sr, tokenResponse);
                    }

                    VssHttpEventSource.Log.AuthenticationError(traceActivity, this, sb.ToString());
                }
            }
            catch (VssServiceResponseException ex)
            {
                VssHttpEventSource.Log.AuthenticationError(traceActivity, this, ex);
            }

            return(issuedToken);
        }