public Integer retrieveListCount(String attribute, String searchFilter) {
        final int pageSize = LDAP_PAGE_SIZE.getValue();
        LdapContext ctx = null;
        LdapContext ctx2 = null;
        Integer count = 0;
        try {
            ctx = getContext(baseDN);

            // Set up request controls, if appropriate.
            List<Control> baseTmpRequestControls = new ArrayList<>();
            if (pageSize > 0) {
                // Server side paging.
                baseTmpRequestControls.add(new PagedResultsControl(pageSize, Control.NONCRITICAL));
            }
            Control[] baseRequestControls = baseTmpRequestControls.toArray(new Control[0]);
            ctx.setRequestControls(baseRequestControls);

            SearchControls searchControls = new SearchControls();
            // See if recursive searching is enabled. Otherwise, only search one level.
            if (isSubTreeSearch()) {
                searchControls.setSearchScope(SearchControls.SUBTREE_SCOPE);
            }
            else {
                searchControls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
            }
            searchControls.setReturningAttributes(new String[] { attribute });
            byte[] cookie;
            // Run through all pages of results (one page is also possible  ;)  )
            do {
                cookie = null;
                NamingEnumeration<SearchResult> answer = ctx.search("", searchFilter, searchControls);

                // Examine all of the results on this page
                while (answer.hasMoreElements()) {
                    answer.next();
                    count++;
                }
                // Examine the paged results control response
                Control[] controls = ctx.getResponseControls();
                if (controls != null) {
                    for (Control control : controls) {
                        if (control instanceof PagedResultsResponseControl) {
                            PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
                            cookie = prrc.getCookie();
                        }
                    }
                }
                // Close the enumeration.
                answer.close();
                // Re-activate paged results; affects nothing if no paging support
                List<Control> tmpRequestControls = new ArrayList<>();
                if (pageSize > 0) {
                    // Server side paging.
                    tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
                }
                Control[] requestControls = tmpRequestControls.toArray(new Control[0]);
                ctx.setRequestControls(requestControls);
            } while (cookie != null);

            // Add groups found in alternate DN
            if (alternateBaseDN != null) {
                ctx2 = getContext(alternateBaseDN);
                ctx2.setRequestControls(baseRequestControls);

                // Run through all pages of results (one page is also possible  ;)  )
                do {
                    cookie = null;
                    NamingEnumeration<SearchResult> answer = ctx2.search("", searchFilter, searchControls);

                    // Examine all of the results on this page
                    while (answer.hasMoreElements()) {
                        answer.next();
                        count++;
                    }
                    // Examine the paged results control response
                    Control[] controls = ctx2.getResponseControls();
                    if (controls != null) {
                        for (Control control : controls) {
                            if (control instanceof PagedResultsResponseControl) {
                                PagedResultsResponseControl prrc = (PagedResultsResponseControl) control;
                                cookie = prrc.getCookie();
                            }
                        }
                    }
                    // Close the enumeration.
                    answer.close();
                    // Re-activate paged results; affects nothing if no paging support
                    List<Control> tmpRequestControls = new ArrayList<>();
                    if (pageSize > 0) {
                        // Server side paging.
                        tmpRequestControls.add(new PagedResultsControl(pageSize, cookie, Control.CRITICAL));
                    }
                    Control[] requestControls = tmpRequestControls.toArray(new Control[0]);
                    ctx2.setRequestControls(requestControls);
                } while (cookie != null);
            }
        }
        catch (Exception e) {
            Log.error("An exception occurred while trying to retrieve a list count for attribute: {}", attribute, e);
        }
        finally {
            try {
                if (ctx != null) {
                    ctx.setRequestControls(null);
                    ctx.close();
                }
                if (ctx2 != null) {
                    ctx2.setRequestControls(null);
                    ctx2.close();
                }
            }
            catch (Exception e) {
                Log.debug("An exception occurred while trying to close contexts after retrieving a list count for attribute: {}", attribute, e);
            }
        }
        return count;
    }
Generic routine for retrieving the number of available results from the LDAP server that
match the passed search filter.  This routine also accounts for paging settings and
alternate DNs.

The passed in filter string needs to be pre-prepared!  In other words, nothing will be changed
in the string before it is used as a string.

@param attribute LDAP attribute to be pulled from each result and used in the query.
    Typically pulled from this manager.
@param searchFilter Filter to use to perform the search.  Typically pulled from this manager.
@return The number of entries that match the filter.
xmppserver/src/main/java/org/jivesoftware/openfire/ldap/LdapManager.java