public async Task <Option <GrantedToken> > Execute(
            AuthorizationCodeGrantTypeParameter authorizationCodeGrantTypeParameter,
            AuthenticationHeaderValue?authenticationHeaderValue,
            X509Certificate2?certificate,
            string issuerName,
            CancellationToken cancellationToken)
        {
            var option = await ValidateParameter(
                authorizationCodeGrantTypeParameter,
                authenticationHeaderValue,
                certificate,
                issuerName,
                cancellationToken)
                         .ConfigureAwait(false);

            if (option is Option <ValidationResult> .Error e)
            {
                return(e.Details);
            }

            var result = ((Option <ValidationResult> .Result)option).Item;

            // 1. Invalidate the authorization code by removing it !
            await _authorizationCodeStore.Remove(result.AuthCode.Code, cancellationToken).ConfigureAwait(false);

            var grantedToken = await _tokenStore.GetValidGrantedToken(
                _jwksStore,
                result.AuthCode.Scopes,
                result.AuthCode.ClientId,
                cancellationToken,
                idTokenJwsPayload : result.AuthCode.IdTokenPayload,
                userInfoJwsPayload : result.AuthCode.UserInfoPayLoad)
                               .ConfigureAwait(false);

            if (grantedToken == null)
            {
                grantedToken = await result.Client.GenerateToken(
                    _jwksStore,
                    result.AuthCode.Scopes.Split(' '),
                    issuerName,
                    result.AuthCode.UserInfoPayLoad,
                    result.AuthCode.IdTokenPayload,
                    cancellationToken,
                    result.AuthCode.IdTokenPayload?.Claims.Where(
                        c => result.Client.UserClaimsToIncludeInAuthToken.Any(r => r.IsMatch(c.Type)))
                    .ToArray()
                    ?? Array.Empty <Claim>())
                               .ConfigureAwait(false);

                await _eventPublisher.Publish(
                    new TokenGranted(
                        Id.Create(),
                        grantedToken.UserInfoPayLoad?.Sub,
                        result.AuthCode.ClientId,
                        result.AuthCode.Scopes,
                        GrantTypes.AuthorizationCode,
                        DateTimeOffset.UtcNow))
                .ConfigureAwait(false);

                // Fill-in the id-token
                if (grantedToken.IdTokenPayLoad != null)
                {
                    grantedToken = grantedToken with
                    {
                        IdTokenPayLoad =
                            JwtGenerator.UpdatePayloadDate(
                                grantedToken.IdTokenPayLoad,
                                result.Client.TokenLifetime),
                        IdToken = await result !.Client.GenerateIdToken(
                            grantedToken.IdTokenPayLoad,
                            _jwksStore,
                            cancellationToken)
                                  .ConfigureAwait(false)
                    };
                }

                await _tokenStore.AddToken(grantedToken !, cancellationToken).ConfigureAwait(false);
            }

            return(grantedToken !);
        }