docs: protected boolean authenticate(final String webUserName, final Object webCredential) throws LoginException {
          try {
              if (isEmptyOrNull(webUserName) || isEmptyOrNull(webCredential) || (webCredential instanceof char[] && ((char[]) webCredential).length == 0)) {
                  LOG.info("empty username or password not allowed");
                  setAuthenticated(false);
                  return isAuthenticated();
              }
  
              loginAttempts++;
  
              if(_reportStatistics)
              {
                  DecimalFormat percentHit = new DecimalFormat("#.##");
                  LOG.info("Login attempts: " + loginAttempts + ", Hits: " + userInfoCacheHits +
                          ", Ratio: " + percentHit.format((double)userInfoCacheHits / loginAttempts * 100f) + "%.");
              }
  
              if (_forceBindingLogin) {
                  return bindingLogin(webUserName, webCredential);
              }
  
              // This sets read and the credential
              UserInfo userInfo = getUserInfo(webUserName);
  
              if (userInfo == null) {
                  setAuthenticated(false);
                  return false;
              }
  
              JAASUserInfo jaasUserInfo = new JAASUserInfo(userInfo);
              jaasUserInfo.fetchRoles(); //must run this otherwise will throw NPE later
              setCurrentUser(jaasUserInfo);
  
              if (webCredential instanceof String) {
                  return credentialLogin(Credential.getCredential((String) webCredential));
              }
  
              return credentialLogin(webCredential);
          } catch (UnsupportedCallbackException e) {
              throw new LoginException("Error obtaining callback information.");
          } catch (IOException e) {
              if (_debug) {
                  e.printStackTrace();
              }
              throw new LoginException("IO Error performing login.");
          } catch (LoginException e) {
              throw e;
          } catch (Exception e) {
              if (_debug) {
                  e.printStackTrace();
              }
              throw new LoginException("Error obtaining user info.");
          }
      }