docs: protected AuthenticationBuilder authenticateInternal(final AuthenticationTransaction transaction) throws AuthenticationException {
          val credentials = transaction.getCredentials();
          LOGGER.debug("Authentication credentials provided for this transaction are [{}]", credentials);
  
          if (credentials.isEmpty()) {
              LOGGER.error("Resolved authentication handlers for this transaction are empty");
              throw new AuthenticationException("Resolved credentials for this transaction are empty");
          }
  
          val builder = new DefaultAuthenticationBuilder(NullPrincipal.getInstance());
          credentials.forEach(cred -> builder.addCredential(new BasicCredentialMetaData(cred)));
          
          val handlerSet = this.authenticationEventExecutionPlan.getAuthenticationHandlersForTransaction(transaction);
          LOGGER.debug("Candidate resolved authentication handlers for this transaction are [{}]", handlerSet);
  
          if (handlerSet.isEmpty()) {
              LOGGER.error("Resolved authentication handlers for this transaction are empty");
              throw new AuthenticationException(builder.getFailures(), builder.getSuccesses());
          }
  
          try {
              val it = credentials.iterator();
              AuthenticationCredentialsThreadLocalBinder.clearInProgressAuthentication();
              while (it.hasNext()) {
                  val credential = it.next();
                  LOGGER.debug("Attempting to authenticate credential [{}]", credential);
  
                  val itHandlers = handlerSet.iterator();
                  var proceedWithNextHandler = true;
                  while (proceedWithNextHandler && itHandlers.hasNext()) {
                      val handler = itHandlers.next();
                      if (handler.supports(credential)) {
                          try {
                              val resolver = getPrincipalResolverLinkedToHandlerIfAny(handler, transaction);
                              LOGGER.debug("Attempting authentication of [{}] using [{}]", credential.getId(), handler.getName());
                              authenticateAndResolvePrincipal(builder, credential, resolver, handler);
  
                              val authnResult = builder.build();
                              AuthenticationCredentialsThreadLocalBinder.bindInProgress(authnResult);
                              val failures = evaluateAuthenticationPolicies(authnResult, transaction, handlerSet);
                              proceedWithNextHandler = !failures.getKey();
                          } catch (final Exception e) {
                              LOGGER.error("Authentication has failed. Credentials may be incorrect or CAS cannot "
                                  + "find authentication handler that supports [{}] of type [{}]. Examine the configuration to "
                                  + "ensure a method of authentication is defined and analyze CAS logs at DEBUG level to trace "
                                  + "the authentication event.", credential, credential.getClass().getSimpleName());
  
                              handleAuthenticationException(e, handler.getName(), builder);
                              proceedWithNextHandler = true;
                          }
                      } else {
                          LOGGER.debug("Authentication handler [{}] does not support the credential type [{}]. Trying next...", handler.getName(), credential);
                      }
                  }
              }
              evaluateFinalAuthentication(builder, transaction, handlerSet);
              return builder;
          } finally {
              AuthenticationCredentialsThreadLocalBinder.clearInProgressAuthentication();
          }
      }