docs: @SuppressWarnings("unchecked")
      protected boolean bindingLogin(String username, Object password) throws LoginException,
              NamingException {
          final String cacheToken = Credential.MD5.digest(username + ":" + password.toString());
          if (_cacheDuration > 0) { // only worry about caching if there is a cacheDuration set.
              CachedUserInfo cached = USERINFOCACHE.get(cacheToken);
              if (cached != null) {
                  if (System.currentTimeMillis() < cached.expires) {
                      LOG.debug("Cache Hit for " + username + ".");
                      userInfoCacheHits++;
                      JAASUserInfo jaasUserInfo = new JAASUserInfo(cached.userInfo);
                      try {
                          jaasUserInfo.fetchRoles();
                      } catch(Exception ex) {
                          if(_debug) {
                              LOG.debug("Failed to fetch roles",ex);
                          }
                          throw new LoginException("Error obtaining user info.");
                      }
                      setCurrentUser(jaasUserInfo);
                      setAuthenticated(true);
                      return true;
                  } else {
                      LOG.info("Cache Eviction for " + username + ".");
                      USERINFOCACHE.remove(cacheToken);
                  }
              } else {
                  LOG.debug("Cache Miss for " + username + ".");
              }
          }
  
          SearchResult searchResult = findUser(username);
  
          String userDn = searchResult.getNameInNamespace();
  
          LOG.info("Attempting authentication: " + userDn);
          DirContext dirContext = createBindUserDirContext(userDn, password);
          setDemographicAttributes(searchResult.getAttributes());
  
          // use _rootContext to find roles, if configured to doso
          if ( _forceBindingLoginUseRootContextForRoles ) {
              dirContext = _rootContext;
              LOG.debug("Using _rootContext for role lookup.");
          }
          List roles = getUserRolesByDn(dirContext, userDn, username);
  
          UserInfo userInfo = new UserInfo(username, new Password(password.toString()), roles);
          if (_cacheDuration > 0) {
              USERINFOCACHE.put(cacheToken,
                  new CachedUserInfo(userInfo,
                      System.currentTimeMillis() + _cacheDuration));
              LOG.debug("Adding " + username + " set to expire: " + System.currentTimeMillis() + _cacheDuration);
          }
          JAASUserInfo jaasUserInfo = new JAASUserInfo(userInfo);
          try {
              jaasUserInfo.fetchRoles();
          } catch(Exception ex) {
              if(_debug) {
                  LOG.debug("Failed to fetch roles",ex);
              }
              throw new LoginException("Error obtaining user info.");
          }
          setCurrentUser(jaasUserInfo);
          setAuthenticated(true);
          return true;
      }