docs: @FFDCIgnore({ InterruptedException.class, NamingException.class })
      public TimedDirContext getDirContext() throws WIMSystemException {
          final String METHODNAME = "getDirContext";
          TimedDirContext ctx = null;
          long currentTimeSeconds = roundToSeconds(System.currentTimeMillis());
  
          if (iContextPoolEnabled) {
              do {
                  //Get the lock for the current domain
                  synchronized (iLock) {
                      if (iContexts == null) {
                          try {
                              createContextPool(iInitPoolSize, null);
                          } catch (NamingException e) {
                              String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                              throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
                          }
                      }
  
                      if (iContexts.size() > 0) {
                          ctx = iContexts.remove(iContexts.size() - 1);
                      } else if (iLiveContexts < iMaxPoolSize || iMaxPoolSize == 0) {
                          //Will create later outside of the synchronized code.
                          iLiveContexts++;
                      } else {
                          try {
                              iLock.wait(iPoolWaitTime);
                          } catch (InterruptedException e) {
                              // This is ok...if exception occurs, then continue...
                          }
                          continue;
                      }
                  }
  
                  TimedDirContext oldCtx = null;
                  if (ctx != null) {
                      /*
                       * Has the context from the pool expired?
                       *
                       * If iPoolTimeOut > 0, check if the DirContex expires or not. If iPoolTimeOut = 0,
                       * the DirContext will be used forever until it is staled.
                       */
                      if (iPoolTimeOut > 0 && (currentTimeSeconds - ctx.getPoolTimestamp()) > iPoolTimeOut) {
                          if (tc.isDebugEnabled()) {
                              Tr.debug(tc, METHODNAME + " ContextPool: context is time out. currentTime=" + currentTimeSeconds + ", createTime="
                                           + ctx.getPoolTimestamp() + ", iPoolTimeOut=" + iPoolTimeOut);
                          }
                          oldCtx = ctx;
                          ctx = null;
                      }
                  } else {
                      if (tc.isDebugEnabled()) {
                          Tr.debug(tc, METHODNAME + " ContextPool: no free context, create a new one...");
                      }
                  }
  
                  if (ctx == null) {
                      try {
                          ctx = createDirContext(getEnvironment(URLTYPE_SEQUENCE, getActiveURL()));
                      } catch (NamingException e) {
                          iLiveContexts--;
                          String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                          throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
                      }
                  } else {
                      // Check
                      if (iReturnToPrimary && (currentTimeSeconds - iLastQueryTime) > iQueryInterval) {
                          try {
                              String currentURL = getProviderURL(ctx);
                              String primaryURL = getPrimaryURL();
                              if (!primaryURL.equalsIgnoreCase(currentURL)) {
                                  // Test if primaryURL is available
                                  Hashtable<String, Object> env = getEnvironment(URLTYPE_SINGLE, primaryURL);
                                  boolean primaryOK = false;
                                  try {
                                      if (tc.isDebugEnabled()) {
                                          Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "'...");
                                      }
                                      TimedDirContext testCtx = createDirContext(env);
                                      if (tc.isDebugEnabled()) {
                                          Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "': success");
                                      }
  
                                      // Log the URL being used.
                                      if (tc.isDebugEnabled())
                                          Tr.debug(tc, WIMMessageKey.CURRENT_LDAP_SERVER, WIMMessageHelper.generateMsgParms(getActiveURL()));
  
                                      primaryOK = true;
                                      TimedDirContext tempCtx = ctx;
                                      try {
                                          tempCtx.close();
                                      } catch (NamingException e) {
                                          if (tc.isDebugEnabled())
                                              Tr.debug(tc, METHODNAME + " Can not close LDAP connection: " + e.toString(true));
                                      }
                                      ctx = testCtx;
                                  } catch (NamingException e) {
                                      if (tc.isInfoEnabled())
                                          Tr.info(tc, WIMMessageKey.CANNOT_CONNECT_LDAP_SERVER, WIMMessageHelper.generateMsgParms(primaryURL));
  
                                      if (tc.isDebugEnabled()) {
                                          Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "': fail");
                                      }
                                  }
  
                                  // Refresh context pool if another thread has not already done so
                                  if (primaryOK) {
                                      synchronized (iLock) {
                                          if (!getActiveURL().equalsIgnoreCase(primaryURL)) {
                                              createContextPool(iLiveContexts - 1, primaryURL);
                                              ctx.setCreateTimestamp(iPoolCreateTimestampSeconds);
                                          }
                                      }
                                  }
                              }
                              iLastQueryTime = currentTimeSeconds;
                          } catch (NamingException e) {
                              String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                              throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
                          }
                      }
                  }
                  if (oldCtx != null) {
                      try {
                          oldCtx.close();
                      } catch (NamingException e) {
                          if (tc.isDebugEnabled())
                              Tr.debug(tc, METHODNAME + " Can not close LDAP connection: " + e.toString(true));
                      }
                  }
              } while (ctx == null);
  
              if (tc.isDebugEnabled()) {
                  Tr.debug(tc, METHODNAME + " ContextPool: total=" + iLiveContexts + ", poolSize=" + iContexts.size() + ", currentTime=" + currentTimeSeconds + ", createTime="
                               + ctx.getPoolTimestamp());
              }
          } else {
              try {
                  // Test if primaryURL is available
                  if (iReturnToPrimary && (currentTimeSeconds - iLastQueryTime) > iQueryInterval) {
                      String primaryURL = getPrimaryURL();
                      if (!primaryURL.equalsIgnoreCase(getActiveURL())) {
                          Hashtable<String, Object> env = getEnvironment(URLTYPE_SINGLE, primaryURL);
                          try {
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "'...");
                              ctx = createDirContext(env);
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "': success");
  
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, WIMMessageKey.CURRENT_LDAP_SERVER, WIMMessageHelper.generateMsgParms(getActiveURL()));
                          } catch (NamingException e) {
                              if (tc.isInfoEnabled())
                                  Tr.info(tc, WIMMessageKey.CANNOT_CONNECT_LDAP_SERVER, WIMMessageHelper.generateMsgParms(primaryURL));
                              if (tc.isDebugEnabled())
                                  Tr.debug(tc, METHODNAME + " Ping primary server '" + primaryURL + "': fail");
                          }
                      }
                      iLastQueryTime = currentTimeSeconds;
                  }
  
                  // create the connection
                  if (ctx == null) {
                      ctx = createDirContext(getEnvironment(URLTYPE_SEQUENCE, getActiveURL()));
  
                      if (tc.isDebugEnabled())
                          Tr.debug(tc, WIMMessageKey.CURRENT_LDAP_SERVER, WIMMessageHelper.generateMsgParms(getActiveURL()));
                  }
              } catch (NamingException e) {
                  String msg = Tr.formatMessage(tc, WIMMessageKey.NAMING_EXCEPTION, WIMMessageHelper.generateMsgParms(e.toString(true)));
                  throw new WIMSystemException(WIMMessageKey.NAMING_EXCEPTION, msg, e);
              }
          }
          return ctx;
      }