docs: protected JwtClaims buildJwtClaims(final HttpServletRequest request,
                                         final AccessToken accessTokenId,
                                         final long timeoutInSeconds,
                                         final OidcRegisteredService service,
                                         final UserProfile profile,
                                         final J2EContext context,
                                         final OAuth20ResponseTypes responseType) {
          val authentication = accessTokenId.getAuthentication();
          val principal = authentication.getPrincipal();
          val oidc = getConfigurationContext().getCasProperties().getAuthn().getOidc();
  
          val claims = new JwtClaims();
  
          val jwtId = getJwtId(accessTokenId.getTicketGrantingTicket());
          claims.setJwtId(jwtId);
  
          claims.setIssuer(oidc.getIssuer());
          claims.setAudience(accessTokenId.getClientId());
  
          val expirationDate = NumericDate.now();
          expirationDate.addSeconds(timeoutInSeconds);
          claims.setExpirationTime(expirationDate);
          claims.setIssuedAtToNow();
          claims.setNotBeforeMinutesInThePast(oidc.getSkew());
          claims.setSubject(principal.getId());
  
          val mfa = getConfigurationContext().getCasProperties().getAuthn().getMfa();
          val attributes = authentication.getAttributes();
  
          if (attributes.containsKey(mfa.getAuthenticationContextAttribute())) {
              val val = CollectionUtils.toCollection(attributes.get(mfa.getAuthenticationContextAttribute()));
              claims.setStringClaim(OidcConstants.ACR, val.iterator().next().toString());
          }
          if (attributes.containsKey(AuthenticationHandler.SUCCESSFUL_AUTHENTICATION_HANDLERS)) {
              val val = CollectionUtils.toCollection(attributes.get(AuthenticationHandler.SUCCESSFUL_AUTHENTICATION_HANDLERS));
              claims.setStringListClaim(OidcConstants.AMR, val.toArray(ArrayUtils.EMPTY_STRING_ARRAY));
          }
  
          claims.setStringClaim(OAuth20Constants.CLIENT_ID, service.getClientId());
          if (attributes.containsKey(OAuth20Constants.STATE)) {
              claims.setClaim(OAuth20Constants.STATE, attributes.get(OAuth20Constants.STATE).get(0));
          }
          if (attributes.containsKey(OAuth20Constants.NONCE)) {
              claims.setClaim(OAuth20Constants.NONCE, attributes.get(OAuth20Constants.NONCE).get(0));
          }
          claims.setClaim(OidcConstants.CLAIM_AT_HASH, generateAccessTokenHash(accessTokenId, service));
  
          LOGGER.trace("Comparing principal attributes [{}] with supported claims [{}]", principal.getAttributes(), oidc.getClaims());
  
          principal.getAttributes().entrySet().stream()
              .filter(entry -> {
                  if (oidc.getClaims().contains(entry.getKey())) {
                      LOGGER.trace("Found supported claim [{}]", entry.getKey());
                      return true;
                  }
                  LOGGER.warn("Claim [{}] is not defined as a supported claim in CAS configuration. Skipping...", entry.getKey());
                  return false;
              })
              .forEach(entry -> claims.setClaim(entry.getKey(), entry.getValue()));
  
          if (!claims.hasClaim(OidcConstants.CLAIM_PREFERRED_USERNAME)) {
              claims.setClaim(OidcConstants.CLAIM_PREFERRED_USERNAME, profile.getId());
          }
  
          return claims;
      }