/// <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>
		/// <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)) {
					// TODO: refreshToken should be set appropriately based on authorization server policy.
					responseMessage = this.PrepareAccessTokenResponse(requestMessage);
				} else {
					responseMessage = new AccessTokenFailedResponse() {
						Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest,
					};
				}
			} 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>
		/// <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);
		}
		/// <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)) {
					IAccessTokenRequestInternal accessRequestInternal = requestMessage;
					accessRequestInternal.AccessTokenCreationParameters = this.AuthorizationServerServices.GetAccessTokenParameters(requestMessage);
					ErrorUtilities.VerifyHost(accessRequestInternal.AccessTokenCreationParameters != null, "IAuthorizationServer.GetAccessTokenParameters must not return null.");

					var successResponseMessage = this.PrepareAccessTokenResponse(requestMessage, accessRequestInternal.AccessTokenCreationParameters.IncludeRefreshToken);
					successResponseMessage.Lifetime = accessRequestInternal.AccessTokenCreationParameters.AccessTokenLifetime;

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

					responseMessage = successResponseMessage;
				} else {
					responseMessage = new AccessTokenFailedResponse() { Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest, };
				}
			} catch (TokenEndpointProtocolException ex) {
				responseMessage = new AccessTokenFailedResponse() { Error = ex.Error, ErrorDescription = ex.Description, ErrorUri = ex.MoreInformation };
			} catch (ProtocolException) {
				responseMessage = new AccessTokenFailedResponse() {
					Error = Protocol.AccessTokenRequestErrorCodes.InvalidRequest,
				};
			}

			return this.Channel.PrepareResponse(responseMessage);
		}