@Override
 public Set<String> retrieveUserGroups(LdapUserContext userContext) throws LdapException {
   Set<String> groups = new HashSet<String>();
   try {
     Filter groupClassFilter;
     if (groupObjectClass != null && !groupObjectClass.isEmpty()) {
       groupClassFilter = Filter.createEqualityFilter("objectClass", groupObjectClass);
     } else {
       groupClassFilter = Filter.createPresenceFilter("objectClass");
     }
     Filter filter =
         Filter.createANDFilter(
             groupClassFilter,
             Filter.createEqualityFilter(groupMemberAttribute, userContext.getDn()));
     LOGGER.debug(filter.toString());
     SearchResult searchResult =
         ldapConnectionPool.search(
             StringUtils.join(groupBase, ','), SearchScope.SUB, filter, "cn");
     for (SearchResultEntry entry : searchResult.getSearchEntries()) {
       groups.add(entry.getAttributeValue("cn"));
     }
     return groups;
   } catch (com.unboundid.ldap.sdk.LDAPException e) {
     throw new LdapException(e);
   }
 }
 @Override
 public Map<String, String> getAttributeValues(LdapUserContext userContext, String... attributes)
     throws LdapException {
   Map<String, String> result = new HashMap<String, String>();
   List<String> retainedAttr = new ArrayList<String>();
   Map<String, String> knownAttributes =
       ((DefaultLdapUserContext) userContext).getKnownAttributes();
   for (String attr : attributes) {
     if (knownAttributes.get(attr.toLowerCase()) == null) {
       retainedAttr.add(attr.toLowerCase());
     }
   }
   if (!retainedAttr.isEmpty()) {
     LOGGER.debug("Will connect to LDAP to retrieve attributes {}", retainedAttr);
     try {
       SearchResultEntry entry =
           ldapConnectionPool.getEntry(
               userContext.getDn(), retainedAttr.toArray(new String[retainedAttr.size()]));
       for (String attr : retainedAttr) {
         knownAttributes.put(attr, entry.getAttributeValue(attr));
       }
     } catch (com.unboundid.ldap.sdk.LDAPException e) {
       throw new LdapException(e);
     }
   }
   for (String attr : attributes) {
     result.put(attr.toLowerCase(), knownAttributes.get(attr.toLowerCase()));
   }
   return result;
 }
 @Override
 public LdapUserContext findUser(String identityAttributeValue) throws LdapException {
   try {
     Filter userClassFilter;
     if (userObjectClass != null && !userObjectClass.isEmpty()) {
       userClassFilter = Filter.createEqualityFilter("objectClass", userObjectClass);
     } else {
       userClassFilter = Filter.createPresenceFilter("objectClass");
     }
     Filter filter =
         Filter.createANDFilter(
             userClassFilter,
             Filter.createEqualityFilter(userIdentityAttribute, identityAttributeValue));
     LOGGER.debug(filter.toString());
     String[] attributesToRetrieve;
     if (userAdditionalAttributes != null) {
       attributesToRetrieve = userAdditionalAttributes;
       if (!ArrayUtils.contains(attributesToRetrieve, "cn")
           || !ArrayUtils.contains(attributesToRetrieve, "CN")) {
         ArrayUtils.add(attributesToRetrieve, "cn");
       }
     } else {
       attributesToRetrieve = new String[] {"cn"};
     }
     SearchResult searchResult =
         ldapConnectionPool.search(
             StringUtils.join(userBase, ','), SearchScope.SUB, filter, attributesToRetrieve);
     if (searchResult.getEntryCount() != 1) {
       throw new UnknownAccountException();
     }
     SearchResultEntry searchResultEntry = searchResult.getSearchEntries().get(0);
     String dn = searchResultEntry.getDN();
     DefaultLdapUserContext ldapUserContext = internalCreateUser(dn);
     ldapUserContext.getKnownAttributes().put("cn", searchResultEntry.getAttributeValue("cn"));
     return ldapUserContext;
   } catch (com.unboundid.ldap.sdk.LDAPException e) {
     throw new LdapException(e);
   }
 }