public virtual TokenResponse CreateTokenResponseFromAuthorizationCode(TokenHandle handle, ITokenHandleManager handleManager)
        {
            var resourceOwner = Principal.Create(
                "OAuth2",
                handle.ResourceOwner.ToClaims().ToArray());

            var validatedRequest = new ValidatedRequest
            {
                Client = handle.Client,
                Application = handle.Application,
                Scopes = handle.Scopes
            };

            var response = CreateTokenResponse(validatedRequest, resourceOwner);

            if (handle.CreateRefreshToken)
            {
                var refreshTokenHandle = TokenHandle.CreateRefreshTokenHandle(
                    resourceOwner.GetSubject(),
                    handle.Client,
                    handle.Application,
                    resourceOwner.Claims,
                    handle.Scopes,
                    handle.RefreshTokenExpiration);

                handleManager.Add(refreshTokenHandle);
                response.RefreshToken = refreshTokenHandle.HandleId;
            }
                
            handleManager.Delete(handle.HandleId);

            return response;
        }
        public Models.TokenHandle Get(string handleIdentifier)
        {
            DateTime expiration;
            if (_expired)
            {
                expiration = DateTime.UtcNow.Subtract(TimeSpan.FromHours(1));
            }
            else
            {
                expiration = DateTime.UtcNow.Add(TimeSpan.FromHours(1));
            }

            if (handleIdentifier == _id)
            {
                var handle = new TokenHandle
                {
                    Client = new Client
                    {
                        ClientId = _clientId
                    },

                    RedirectUri = _redirectUri,
                    Expiration = expiration
                };

                return handle;
            }

            return null;
        }
        public virtual TokenResponse CreateTokenResponse(TokenHandle handle, ITokenHandleManager handleManager)
        {
            if (handle.Type == TokenHandleType.AuthorizationCode)
            {
                return CreateTokenResponseFromAuthorizationCode(handle, handleManager);
            }
            if (handle.Type == TokenHandleType.RefreshTokenIdentifier)
            {
                return CreateTokenResponseFromRefreshToken(handle, handleManager);
            }

            throw new ArgumentException("handle.Type");
        }
        public Models.TokenHandle Get(string handleIdentifier)
        {
            var handle = new TokenHandle
            {
                Client = new Client
                {
                    ClientId = _clientId
                },

                RedirectUri = _redirectUri
            };
            
            return handle;
        }
        public virtual TokenResponse CreateTokenResponseFromRefreshToken(TokenHandle handle, ITokenHandleManager handleManager)
        {
            var resourceOwner = Principal.Create(
                "OAuth2",
                handle.ResourceOwner.ToClaims().ToArray());

            var validatedRequest = new ValidatedRequest
            {
                Client = handle.Client,
                Application = handle.Application,
                Scopes = handle.Scopes,
            };

            var response = CreateTokenResponse(validatedRequest, resourceOwner);
            response.RefreshToken = handle.HandleId;
            
            return response;
        }
        public virtual TokenResponse CreateTokenResponseFromRefreshToken(TokenHandle handle, ITokenHandleManager handleManager)
        {
            var resourceOwner = Principal.Create(
                "OAuth2",
                handle.ResourceOwner.ToClaims().ToArray());

            if (DateTime.UtcNow > handle.Expiration)
            {
                throw new InvalidOperationException("Refresh token has expired.");
            }

            var validatedRequest = new ValidatedRequest
            {
                Client = handle.Client,
                Application = handle.Application,
                Scopes = handle.Scopes,
            };

            var response = CreateTokenResponse(validatedRequest, resourceOwner);
            response.RefreshToken = handle.HandleId;
            
            return response;
        }