docs: @FFDCIgnore({ Exception.class })
      public ProviderAuthenticationResult createResultWithJose4J(String responseState,
              Map<String, String> tokens,
              ConvergedClientConfig clientConfig,
              OidcClientRequest oidcClientRequest) {
          //oidcClientRequest.setTokenType(OidcClientRequest.TYPE_); // decided by the caller
          // This is for ID Token only at the writing time
          ProviderAuthenticationResult oidcResult = null;
          String tokenStr = getIdToken(tokens, clientConfig);
          String accessToken = tokens.get(Constants.ACCESS_TOKEN);
          String refreshToken = tokens.get(Constants.REFRESH_TOKEN);
          String clientId = clientConfig.getClientId();
          try {
              if (tokenStr == null) {
                  // This is for ID Token only
                  Tr.error(tc, "OIDC_CLIENT_IDTOKEN_REQUEST_FAILURE", new Object[] { clientId, clientConfig.getTokenEndpointUrl() });
                  return new ProviderAuthenticationResult(AuthResult.SEND_401, HttpServletResponse.SC_UNAUTHORIZED);
              }
  
              JwtContext jwtContext = parseJwtWithoutValidation(tokenStr);
              JwtClaims jwtClaims = parseJwtWithValidation(clientConfig, tokenStr, jwtContext, oidcClientRequest);
              if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                  Tr.debug(tc, "post jwtClaims: " + jwtClaims + " firstPass jwtClaims=" + jwtContext.getJwtClaims());
              }
              OidcTokenImplBase idToken = new OidcTokenImplBase(jwtClaims, accessToken, refreshToken, clientId, oidcClientRequest.getTokenTypeNoSpace());
  
              if (idToken.getSubject() == null) {
                  return new ProviderAuthenticationResult(AuthResult.SEND_401, HttpServletResponse.SC_UNAUTHORIZED);
              }
              AttributeToSubject attributeToSubject = new AttributeToSubject(clientConfig, idToken);
              if (attributeToSubject.checkUserNameForNull()) {
                  return new ProviderAuthenticationResult(AuthResult.SEND_401, HttpServletResponse.SC_UNAUTHORIZED);
              }
  
              boolean isImplicit = Constants.IMPLICIT.equals(clientConfig.getGrantType());
              // verify nonce when nonce is enabled
              // this id for ID Token only
              if (clientConfig.isNonceEnabled() || isImplicit) {
                  String nonceInIDToken = idToken.getNonce();
                  boolean bNonceVerified = OidcUtil.verifyNonce(oidcClientRequest, nonceInIDToken, clientConfig, responseState);
                  if (!bNonceVerified) {
                      // Error handling
                      Tr.error(tc, "OIDC_CLIENT_REQUEST_NONCE_FAILED", new Object[] { clientId, nonceInIDToken });
                      return new ProviderAuthenticationResult(AuthResult.SEND_401, HttpServletResponse.SC_UNAUTHORIZED);
                  }
              }
  
              // if social login flow, put tokens and anything else social might want
              // into PAR props here and return it. Social will build the subject.
              if (clientConfig.isSocial()) {
                  if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) {
                      Tr.debug(tc, "social login flow, storing id token in result");
                  }
                  Hashtable<String, Object> props = new Hashtable<String, Object>();
                  props.put(Constants.ID_TOKEN, tokenStr);
                  props.put(Constants.ACCESS_TOKEN, accessToken);
                  if (idToken != null) {
                      props.put(Constants.ID_TOKEN_OBJECT, idToken);
                  }
                  oidcResult = new ProviderAuthenticationResult(AuthResult.SUCCESS, HttpServletResponse.SC_OK, null, null, props, null);
                  return oidcResult;
              }
  
              Hashtable<String, Object> customProperties = new Hashtable<String, Object>();
              if (clientConfig.isIncludeCustomCacheKeyInSubject() || clientConfig.isDisableLtpaCookie()) {
                  long storingTime = new Date().getTime();
                  String customCacheKey = oidcClientRequest.getAndSetCustomCacheKeyValue(); //username + tokenStr.toString().hashCode();
                  customProperties.put(ClientConstants.CREDENTIAL_STORING_TIME_MILLISECONDS, Long.valueOf(storingTime));
                  customProperties.put(AttributeNameConstants.WSCREDENTIAL_CACHE_KEY, customCacheKey);
                  customProperties.put(AuthenticationConstants.INTERNAL_ASSERTION_KEY, Boolean.TRUE); // TODO checking?
              }
              Subject subject = null;
              if (clientConfig.isIncludeIdTokenInSubject()) {
                  subject = new Subject();
                  subject.getPrivateCredentials().add(idToken); // add the external IDToken
                  customProperties.putAll(tokens); // add ALL tokens to props.
              } else {
                  if (refreshToken != null) {
                      customProperties.put(Constants.REFRESH_TOKEN, refreshToken);
                  }
                  if (accessToken != null) {
                      customProperties.put(Constants.ACCESS_TOKEN, accessToken);
                  }
              }
              if (idToken != null) {
                  customProperties.put(Constants.ID_TOKEN_OBJECT, idToken); // pass back to authenticator
              }
  
              //addJWTTokenToSubject(customProperties, idToken, clientConfig);
  
              //doIdAssertion(customProperties, payload, clientConfig);
              oidcResult = attributeToSubject.doMapping(customProperties, subject);
              //oidcResult = new ProviderAuthenticationResult(AuthResult.SUCCESS, HttpServletResponse.SC_OK, username, subject, customProperties, null);
  
          } catch (Exception e) {
              Tr.error(tc, "OIDC_CLIENT_IDTOKEN_VERIFY_ERR", new Object[] { e.getLocalizedMessage(), clientId });
              oidcResult = new ProviderAuthenticationResult(AuthResult.SEND_401, HttpServletResponse.SC_UNAUTHORIZED);
          }
  
          return oidcResult;
      }