public async Task <IntrospectionResult> PostIntrospection(IntrospectionParameter introspectionParameter, AuthenticationHeaderValue authenticationHeaderValue, string issuerName)
        {
            if (introspectionParameter == null)
            {
                throw new ArgumentNullException(nameof(introspectionParameter));
            }

            var processId = Guid.NewGuid().ToString();

            try
            {
                _eventPublisher.Publish(new IntrospectionRequestReceived(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(introspectionParameter, authenticationHeaderValue), authenticationHeaderValue, 0));
                _introspectionParameterValidator.Validate(introspectionParameter);
                var result = await _postIntrospectionAction.Execute(introspectionParameter, authenticationHeaderValue, issuerName);

                _eventPublisher.Publish(new IntrospectionResultReturned(Guid.NewGuid().ToString(), processId, _payloadSerializer.GetPayload(result), 1));
                return(result);
            }
            catch (IdentityServerException ex)
            {
                _eventPublisher.Publish(new OAuthErrorReceived(Guid.NewGuid().ToString(), processId, ex.Code, ex.Message, 1));
                throw;
            }
        }
        public async Task <IntrospectionResult> Execute(
            IntrospectionParameter introspectionParameter,
            AuthenticationHeaderValue authenticationHeaderValue, string issuerName)
        {
            // 1. Validate the parameters
            if (introspectionParameter == null)
            {
                throw new ArgumentNullException(nameof(introspectionParameter));
            }

            if (string.IsNullOrWhiteSpace(introspectionParameter.Token))
            {
                throw new ArgumentNullException(nameof(introspectionParameter.Token));
            }

            _introspectionParameterValidator.Validate(introspectionParameter);

            // 2. Authenticate the client
            var instruction = CreateAuthenticateInstruction(introspectionParameter, authenticationHeaderValue);
            var authResult  = await _authenticateClient.AuthenticateAsync(instruction, issuerName);

            if (authResult.Client == null)
            {
                throw new IdentityServerException(ErrorCodes.InvalidClient, authResult.ErrorMessage);
            }

            // 3. Retrieve the token type hint
            var tokenTypeHint = Constants.StandardTokenTypeHintNames.AccessToken;

            if (Constants.AllStandardTokenTypeHintNames.Contains(introspectionParameter.TokenTypeHint))
            {
                tokenTypeHint = introspectionParameter.TokenTypeHint;
            }

            // 4. Trying to fetch the information about the access_token  || refresh_token
            GrantedToken grantedToken = null;

            if (tokenTypeHint == Constants.StandardTokenTypeHintNames.AccessToken)
            {
                grantedToken = await _tokenStore.GetAccessToken(introspectionParameter.Token);

                if (grantedToken == null)
                {
                    grantedToken = await _tokenStore.GetRefreshToken(introspectionParameter.Token);
                }
            }
            else
            {
                grantedToken = await _tokenStore.GetRefreshToken(introspectionParameter.Token);

                if (grantedToken == null)
                {
                    grantedToken = await _tokenStore.GetAccessToken(introspectionParameter.Token);
                }
            }

            // 5. Throw an exception if there's no granted token
            if (grantedToken == null)
            {
                throw new IdentityServerException(
                          ErrorCodes.InvalidToken,
                          ErrorDescriptions.TheTokenIsNotValid);
            }

            // 6. Fill-in parameters
            //// TODO : Specifiy the other parameters : NBF & JTI
            var result = new IntrospectionResult
            {
                Scope      = grantedToken.Scope,
                ClientId   = grantedToken.ClientId,
                Expiration = grantedToken.ExpiresIn,
                TokenType  = grantedToken.TokenType
            };

            // 7. Fill-in the other parameters
            if (grantedToken.IdTokenPayLoad != null)
            {
                var audiences    = string.Empty;
                var audiencesArr = grantedToken.IdTokenPayLoad.GetArrayClaim(StandardClaimNames.Audiences);
                var issuedAt     = grantedToken.IdTokenPayLoad.Iat;
                var issuer       = grantedToken.IdTokenPayLoad.Issuer;
                var subject      = grantedToken.IdTokenPayLoad.GetClaimValue(Jwt.Constants.StandardResourceOwnerClaimNames.Subject);
                var userName     = grantedToken.IdTokenPayLoad.GetClaimValue(Jwt.Constants.StandardResourceOwnerClaimNames.Name);
                if (audiencesArr.Any())
                {
                    audiences = string.Join(" ", audiencesArr);
                }

                result.Audience = audiences;
                result.IssuedAt = issuedAt;
                result.Issuer   = issuer;
                result.Subject  = subject;
                result.UserName = userName;
            }

            // 8. Based on the expiration date disable OR enable the introspection result
            var expirationDateTime = grantedToken.CreateDateTime.AddSeconds(grantedToken.ExpiresIn);
            var tokenIsExpired     = DateTime.UtcNow > expirationDateTime;

            if (tokenIsExpired)
            {
                result.Active = false;
            }
            else
            {
                result.Active = true;
            }

            return(result);
        }