docs: private NamingEnumeration<SearchResult> search(String name, String filterExpr, Object[] filterArgs,
                                                     SearchControls cons, Control requestControls[]) throws WIMException {
          final String METHODNAME = "search(String, String, Object[], SearchControls)";
  
          if (iPageSize == 0) {
              TimedDirContext ctx = iContextManager.getDirContext();
              NamingEnumeration<SearchResult> neu = null;
              try {
                  try {
                      if (filterArgs == null) {
                          neu = ctx.search(new LdapName(name), filterExpr, cons);
                      } else {
                          neu = ctx.search(new LdapName(name), filterExpr, filterArgs, cons);
                      }
                  } catch (NamingException e) {
                      if (!ContextManager.isConnectionException(e)) {
                          throw e;
                      }
                      ctx = iContextManager.reCreateDirContext(ctx, e.toString());
                      if (filterArgs == null) {
                          neu = ctx.search(new LdapName(name), filterExpr, cons);
                      } else {
                          neu = ctx.search(new LdapName(name), filterExpr, filterArgs, cons);
                      }
                  }
              } catch (NameNotFoundException e) {
                  String msg = Tr.formatMessage(tc, WIMMessageKey.LDAP_ENTRY_NOT_FOUND, WIMMessageHelper.generateMsgParms(name, e.toString(true)));
                  throw new EntityNotFoundException(WIMMessageKey.LDAP_ENTRY_NOT_FOUND, msg, e);
              } catch (NamingException e) {
                  String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                  throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
              } finally {
                  iContextManager.releaseDirContext(ctx);
              }
  
              return neu;
          } else {
              TimedDirContext ctx = iContextManager.getDirContext();
              try {
                  if (requestControls != null) {
                      ctx.setRequestControls(new Control[] { requestControls[0], new PagedResultsControl(iPageSize, false) });
                  } else {
                      ctx.setRequestControls(new Control[] { new PagedResultsControl(iPageSize, false) });
                  }
  
                  byte[] cookie = null;
                  int pageCount = 1;
                  int count = 0;
                  CachedNamingEnumeration allNeu = new CachedNamingEnumeration();
                  int retries = 0; // The number of retries
                  boolean tryAgain; // Whether to retry the search
  
                  do {
                      tryAgain = false;
  
                      NamingEnumeration<SearchResult> neu = null;
                      try {
                          if (tc.isDebugEnabled()) {
                              Tr.debug(tc, METHODNAME + " Search page: " + pageCount + ", Retries: " + retries);
                          }
                          if (filterArgs == null) {
                              neu = ctx.search(new LdapName(name), filterExpr, cons);
                          } else {
                              neu = ctx.search(new LdapName(name), filterExpr, filterArgs, cons);
                          }
  
                          /*
                           * Save the results.
                           */
                          if (neu != null) {
                              pageCount++;
                              if (tc.isDebugEnabled()) {
                                  Tr.debug(tc, METHODNAME + " Received search results, looping through elements. May include referral chasing.");
                              }
  
                              while (neu.hasMoreElements()) {
                                  allNeu.add(neu.nextElement());
                                  count++;
                              }
  
                              if (tc.isDebugEnabled()) {
                                  Tr.debug(tc, METHODNAME + " Received search results, looped through elements. Num of elements retrieved: " + count);
                              }
  
                              /*
                               * Get the cookie if there are more results to process.
                               */
                              Control[] resCtrls = ctx.getResponseControls();
                              if (resCtrls != null && resCtrls.length > 0) {
                                  PagedResultsResponseControl resCtrl = (PagedResultsResponseControl) resCtrls[0];
                                  cookie = resCtrl.getCookie();
                                  if (cookie != null && cookie.length > 0) {
                                      ctx.setRequestControls(new Control[] { new PagedResultsControl(iPageSize, cookie, false) });
                                  }
                              }
                          }
  
                      } catch (NamingException e) {
  
                          if (ContextManager.isConnectionException(e) && retries == 0) {
  
                              /*
                               * Some LDAP servers do not allow the paged searches to span new connections, so
                               * we need to start the paged search from the beginning. Clear the cookie and
                               * the results collected so far and start at page 1. We also need to be aware that
                               * the new connection could be to another (fail-over) server that has no context
                               * for the current paged search's cookie.
                               */
                              tryAgain = true;
                              retries++;
                              pageCount = 1;
                              cookie = null;
                              allNeu = new CachedNamingEnumeration();
                              count = 0;
  
                              /*
                               * Recreate the connection.
                               */
                              ctx = iContextManager.reCreateDirContext(ctx, e.toString());
                              if (requestControls != null) {
                                  ctx.setRequestControls(new Control[] { requestControls[0], new PagedResultsControl(iPageSize, false) });
                              } else {
                                  ctx.setRequestControls(new Control[] { new PagedResultsControl(iPageSize, false) });
                              }
  
                          } else {
                              throw e;
                          }
                      }
  
                  } while (tryAgain || (cookie != null && cookie.length > 0 && count < cons.getCountLimit()));
                  return allNeu;
              } catch (NamingException e) {
                  String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                  throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
              } catch (IOException e) {
                  String msg = Tr.formatMessage(tc, WIMMessageKey.GENERIC, WIMMessageHelper.generateMsgParms(e.toString()));
                  throw new WIMSystemException(WIMMessageKey.GENERIC, msg, e);
              } finally {
                  try {
                      ctx.setRequestControls(null);
                  } catch (NamingException e) {
                      if (tc.isDebugEnabled())
                          Tr.debug(tc, METHODNAME + e.toString(true));
                  }
                  iContextManager.releaseDirContext(ctx);
              }
          }
      }