/// <summary>
        /// Approves an authorization request.
        /// </summary>
        /// <param name="authorizationRequest">The authorization request to approve.</param>
        /// <param name="userDataAndNonce">The username of the account that approved the request (or whose data will be accessed by the client).</param>
        /// <param name="nonce">The nonce data.</param>
        /// <param name="successAccessTokenResponse">The end user authorization success access token response.</param>
        /// <param name="scopes">The scope of access the client should be granted.  If <c>null</c>, all scopes in the original request will be granted.</param>
        /// <param name="callback">The Client callback URL to use when formulating the redirect to send the user agent back to the Client.</param>
        /// <returns>The authorization response message to send to the Client.</returns>
        public EndUserAuthorizationSuccessResponseBase PrepareApproveAuthorizationRequest(EndUserAuthorizationRequest authorizationRequest,
                                                                                          string userDataAndNonce, string nonce, out EndUserAuthorizationSuccessAccessTokenResponse successAccessTokenResponse, IEnumerable <string> scopes = null, Uri callback = null)
        {
            Contract.Ensures(Contract.Result <EndUserAuthorizationSuccessResponseBase>() != null);

            if (callback == null)
            {
                callback = this.GetCallback(authorizationRequest);
            }

            var client = this.AuthorizationServerServices.GetClientOrThrow(authorizationRequest.ClientIdentifier);
            EndUserAuthorizationSuccessResponseBase        response;
            EndUserAuthorizationSuccessAccessTokenResponse implicitGrantResponse = null;

            switch (authorizationRequest.ResponseType)
            {
            case EndUserAuthorizationResponseType.AccessToken:
                IAccessTokenRequestInternal accessRequestInternal = (EndUserAuthorizationImplicitRequest)authorizationRequest;
                var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(accessRequestInternal, nonce);
                ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null.");

                accessRequestInternal.AccessTokenResult = accessTokenResult;

                implicitGrantResponse          = new EndUserAuthorizationSuccessAccessTokenResponse(callback, authorizationRequest);
                implicitGrantResponse.Lifetime = accessTokenResult.AccessToken.Lifetime;
                accessTokenResult.AccessToken.ApplyAuthorization(implicitGrantResponse.Scope, userDataAndNonce, implicitGrantResponse.Lifetime);

                IAccessTokenCarryingRequest tokenCarryingResponse = implicitGrantResponse;
                tokenCarryingResponse.AuthorizationDescription = accessTokenResult.AccessToken;

                response = implicitGrantResponse;
                break;

            case EndUserAuthorizationResponseType.AuthorizationCode:
                var authCodeResponse = new EndUserAuthorizationSuccessAuthCodeResponseAS(callback, authorizationRequest);
                IAuthorizationCodeCarryingRequest codeCarryingResponse = authCodeResponse;
                codeCarryingResponse.AuthorizationDescription = new AuthorizationCode(
                    authorizationRequest.ClientIdentifier,
                    authorizationRequest.Callback,
                    authCodeResponse.Scope,
                    userDataAndNonce);
                response = authCodeResponse;
                break;

            default:
                throw ErrorUtilities.ThrowInternal("Unexpected response type.");
            }

            response.AuthorizingUsername = userDataAndNonce;

            // Customize the approved scope if the authorization server has decided to do so.
            if (scopes != null)
            {
                response.Scope.ResetContents(scopes);
            }

            successAccessTokenResponse = implicitGrantResponse;
            return(response);
        }
        /// <summary>
        /// Handles an incoming request to the authorization server's token endpoint.
        /// </summary>
        /// <param name="request">The HTTP request.</param>
        /// <returns>The HTTP response to send to the client.</returns>
        public OutgoingWebResponse HandleTokenRequest(HttpRequestBase request = null)
        {
            if (request == null)
            {
                request = this.Channel.GetRequestFromContext();
            }

            AccessTokenRequestBase requestMessage;
            IProtocolMessage       responseMessage;

            try {
                if (this.Channel.TryReadFromRequest(request, out requestMessage))
                {
                    var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(requestMessage);
                    ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null.");

                    IAccessTokenRequestInternal accessRequestInternal = requestMessage;
                    accessRequestInternal.AccessTokenResult = accessTokenResult;

                    var successResponseMessage = this.PrepareAccessTokenResponse(requestMessage, accessTokenResult.AllowRefreshToken);
                    successResponseMessage.Lifetime = accessTokenResult.AccessToken.Lifetime;

                    var authCarryingRequest = requestMessage as IAuthorizationCarryingRequest;
                    if (authCarryingRequest != null)
                    {
                        accessTokenResult.AccessToken.ApplyAuthorization(authCarryingRequest.AuthorizationDescription);
                        IAccessTokenIssuingResponse accessTokenIssuingResponse = successResponseMessage;
                        accessTokenIssuingResponse.AuthorizationDescription = accessTokenResult.AccessToken;
                    }

                    responseMessage = successResponseMessage;
                }
                else
                {
                    responseMessage = new AccessTokenFailedResponse()
                    {
                        Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest
                    };
                }
            } catch (TokenEndpointProtocolException ex) {
                responseMessage = ex.GetResponse();
            } catch (ProtocolException) {
                responseMessage = new AccessTokenFailedResponse()
                {
                    Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest
                };
            }

            return(this.Channel.PrepareResponse(responseMessage));
        }
        /// <summary>
        /// Handles an incoming request to the authorization server's token endpoint.
        /// </summary>
        /// <param name="request">The HTTP request.</param>
        /// <param name="cancellationToken">The cancellation token.</param>
        /// <returns>
        /// The HTTP response to send to the client.
        /// </returns>
        public async Task <HttpResponseMessage> HandleTokenRequestAsync(HttpRequestMessage request, CancellationToken cancellationToken = default(CancellationToken))
        {
            Requires.NotNull(request, "request");

            IProtocolMessage responseMessage;

            try {
                AccessTokenRequestBase requestMessage = await this.Channel.TryReadFromRequestAsync <AccessTokenRequestBase>(request, cancellationToken);

                if (requestMessage != null)
                {
                    var accessTokenResult = this.AuthorizationServerServices.CreateAccessToken(requestMessage);
                    ErrorUtilities.VerifyHost(accessTokenResult != null, "IAuthorizationServerHost.CreateAccessToken must not return null.");

                    IAccessTokenRequestInternal accessRequestInternal = requestMessage;
                    accessRequestInternal.AccessTokenResult = accessTokenResult;

                    var successResponseMessage = this.PrepareAccessTokenResponse(requestMessage, accessTokenResult.AllowRefreshToken);
                    successResponseMessage.Lifetime = accessTokenResult.AccessToken.Lifetime;

                    var authCarryingRequest = requestMessage as IAuthorizationCarryingRequest;
                    if (authCarryingRequest != null)
                    {
                        accessTokenResult.AccessToken.ApplyAuthorization(authCarryingRequest.AuthorizationDescription);
                        IAccessTokenIssuingResponse accessTokenIssuingResponse = successResponseMessage;
                        accessTokenIssuingResponse.AuthorizationDescription = accessTokenResult.AccessToken;
                    }

                    responseMessage = successResponseMessage;
                }
                else
                {
                    responseMessage = new AccessTokenFailedResponse()
                    {
                        Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest
                    };
                }
            } catch (TokenEndpointProtocolException ex) {
                responseMessage = ex.GetResponse();
            } catch (ProtocolException) {
                responseMessage = new AccessTokenFailedResponse()
                {
                    Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest
                };
            }

            return(await this.Channel.PrepareResponseAsync(responseMessage, cancellationToken));
        }