@Override
      public AuthorizationIdentity getAuthorizationIdentity() throws RealmUnavailableException {

        if (groups.length() > 0) {
          String[] temp = groups.split(COMMA);
          Set<String> groups = new HashSet<>(temp.length);

          for (String current : temp) {
            String cleaned = current.trim();
            if (cleaned.length() > 0) {
              SECURITY_LOGGER.tracef("Adding group '%s' for identity '%s'.", cleaned, name);
              groups.add(cleaned);
            }
          }

          Map<String, Set<String>> groupsAttributeMap = new HashMap<String, Set<String>>();
          groupsAttributeMap.put("GROUPS", Collections.unmodifiableSet(groups));

          return AuthorizationIdentity.basicIdentity(
              new MapAttributes(Collections.unmodifiableMap(groupsAttributeMap)));
        } else {
          SECURITY_LOGGER.tracef("No groups found for identity '%s' in properties file.", name);
          return AuthorizationIdentity.EMPTY;
        }
      }
    @Override
    public LdapEntry[] groupSearch(DirContext dirContext, LdapEntry entry)
        throws IOException, NamingException {
      Set<LdapEntry> foundEntries = new HashSet<LdapEntry>();
      // Load the list of group.
      Attributes groups =
          dirContext.getAttributes(entry.getDistinguishedName(), new String[] {groupAttribute});
      Attribute groupRef = groups.get(groupAttribute);
      if (groupRef != null && groupRef.size() > 0) {
        NamingEnumeration<String> groupRefValues = (NamingEnumeration<String>) groupRef.getAll();
        while (groupRefValues.hasMore()) {
          String distingushedName = groupRefValues.next();
          SECURITY_LOGGER.tracef("Group found with distinguishedName=%s", distingushedName);
          String simpleName = null;
          if (groupNameAttribute != null) {
            // Load the Name
            Attributes groupNameAttrs =
                dirContext.getAttributes(distingushedName, new String[] {groupNameAttribute});
            Attribute groupNameAttr = groupNameAttrs.get(groupNameAttribute);
            simpleName = (String) groupNameAttr.get();
            SECURITY_LOGGER.tracef(
                "simpleName %s loaded for group with distinguishedName=%s",
                simpleName, distingushedName);
          } else {
            SECURITY_LOGGER.trace("No groupNameAttribute to load simpleName");
          }
          foundEntries.add(new LdapEntry(simpleName, distingushedName));
        }
      } else {
        SECURITY_LOGGER.tracef("No groups found for %s", entry);
      }

      return foundEntries.toArray(new LdapEntry[foundEntries.size()]);
    }
    private LdapEntry convertToLdapEntry(SearchResult searchResult, Attributes attributes)
        throws NamingException {
      String simpleName = null;
      String distinguishedName = null;

      if (groupNameAttribute != null) {
        SECURITY_LOGGER.tracef("Getting groupNameAttribute=%s", groupNameAttribute);
        Attribute groupNameAttr = attributes.get(groupNameAttribute);
        if (groupNameAttr != null) {
          simpleName = (String) groupNameAttr.get();
        }
      }

      if (groupDnAttribute != null) {
        if ("dn".equals(groupDnAttribute)) {
          SECURITY_LOGGER.trace("Obtaining dn using getNameInNamespace()");
          distinguishedName = searchResult.getNameInNamespace();
        } else {
          SECURITY_LOGGER.tracef("Getting groupDnAttribute=%s", groupDnAttribute);
          Attribute groupDnAttr = attributes.get(groupDnAttribute);
          if (groupDnAttr != null) {
            distinguishedName = (String) groupDnAttr.get();
          }
        }
      }

      return new LdapEntry(simpleName, distinguishedName);
    }
    @Override
    public LdapEntry[] groupSearch(DirContext dirContext, LdapEntry entry)
        throws IOException, NamingException {
      SearchControls searchControls =
          createSearchControl(recursive, attributeArray); // TODO - Can we create this in
      // advance?
      Set<LdapEntry> foundEntries = new HashSet<LdapEntry>();
      Object[] searchParameter = getSearchParameter(entry);
      boolean trace = SECURITY_LOGGER.isTraceEnabled();
      if (trace) {
        SECURITY_LOGGER.tracef(
            "Performing search baseDn=%s, filterString=%s, searchParameter=%s",
            baseDn, filterString, Arrays.toString(searchParameter));
      }
      NamingEnumeration<SearchResult> searchResults =
          dirContext.search(baseDn, filterString, searchParameter, searchControls);
      if (trace && searchResults.hasMore() == false) {
        SECURITY_LOGGER.trace("No search results found.");
      }
      while (searchResults.hasMore()) {
        SearchResult current = searchResults.next();
        Attributes attributes = current.getAttributes();
        if (attributes != null) {
          LdapEntry newEntry = convertToLdapEntry(current, attributes);
          SECURITY_LOGGER.tracef("Adding %s", newEntry);
          foundEntries.add(newEntry);
        } else {
          SECURITY_LOGGER.tracef("No attributes found for %s", current);
        }
      }

      return foundEntries.toArray(new LdapEntry[foundEntries.size()]);
    }
    private PrincipalToGroupSearcher(final String groupAttribute, final String groupNameAttribute) {
      this.groupAttribute = groupAttribute;
      this.groupNameAttribute = groupNameAttribute;

      if (SECURITY_LOGGER.isTraceEnabled()) {
        SECURITY_LOGGER.tracef("PrincipalToGroupSearcher groupAttribute=%s", groupAttribute);
        SECURITY_LOGGER.tracef(
            "PrincipalToGroupSearcher groupNameAttribute=%s", groupNameAttribute);
      }
    }
    private GroupToPrincipalSearcher(
        final String baseDn,
        final String groupDnAttribute,
        final String groupNameAttribute,
        final String principalAttribute,
        final boolean recursive,
        final GroupName searchBy) {
      this.baseDn = baseDn;
      this.groupDnAttribute = groupDnAttribute;
      this.groupNameAttribute = groupNameAttribute;
      this.attributeArray = createArray(groupDnAttribute, groupNameAttribute);
      this.filterString = String.format("(%s={0})", principalAttribute);
      this.recursive = recursive;
      this.searchBy = searchBy;

      if (SECURITY_LOGGER.isTraceEnabled()) {
        SECURITY_LOGGER.tracef("GroupToPrincipalSearcher baseDn=%s", baseDn);
        SECURITY_LOGGER.tracef("GroupToPrincipalSearcher groupDnAttribute=%s", groupDnAttribute);
        SECURITY_LOGGER.tracef(
            "GroupToPrincipalSearcher groupNameAttribute=%s", groupNameAttribute);
        SECURITY_LOGGER.tracef(
            "GroupToPrincipalSearcher attributeArray=%s", Arrays.toString(attributeArray));
        SECURITY_LOGGER.tracef("GroupToPrincipalSearcher filterString=%s", filterString);
        SECURITY_LOGGER.tracef("GroupToPrincipalSearcher recursive=%b", recursive);
        SECURITY_LOGGER.tracef("GroupToPrincipalSearcher searchBy=%s", searchBy);
      }
    }
 private static SearchControls createSearchControl(
     final boolean recursive, final String[] attributes) {
   if (SECURITY_LOGGER.isTraceEnabled()) {
     SECURITY_LOGGER.tracef(
         "createSearchControl recursive=%b,  attributes=%s",
         recursive, Arrays.toString(attributes));
   }
   // 2 - Search to identify the DN of the user connecting
   SearchControls searchControls = new SearchControls();
   if (recursive) {
     searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
   } else {
     searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
   }
   searchControls.setReturningAttributes(attributes);
   searchControls.setTimeLimit(searchTimeLimit);
   return searchControls;
 }
  private Set<RealmGroup> loadGroups(final Properties properties, final RealmUser user) {
    Set<RealmGroup> response;
    String groupString = properties.getProperty(user.getName(), "").trim();
    if (groupString.length() > 0) {
      String[] groups = groupString.split(COMMA);
      response = new HashSet<RealmGroup>(groups.length);
      for (String current : groups) {
        String cleaned = current.trim();
        if (cleaned.length() > 0) {
          RealmGroup newGroup = new RealmGroup(realmName, cleaned);
          SECURITY_LOGGER.tracef("Adding group '%s' for user '%s'.", newGroup, user);
          response.add(newGroup);
        }
      }
    } else {
      SECURITY_LOGGER.tracef("No groups found for user '%s' in properties file.", user);
      response = Collections.emptySet();
    }

    return response;
  }