mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noël Rouvignac
18.26.2016 5b498b0ef16a5ffdfa7ebb5ae1bf90b5299db49e
Removed InitialLdapContext import from ReplicationCliMain. Used ConnectionWrapper instead

Renamed all *ctx* to *conn*.
Changed all mentions of "context" by "connection".
5 files modified
1080 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/admin/ads/util/ConnectionWrapper.java 3 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/admin/ads/util/PreferredConnection.java 11 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/ImportLDIFPanel.java 2 ●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java 3 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java 1061 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/admin/ads/util/ConnectionWrapper.java
@@ -100,8 +100,7 @@
    }
    catch (URISyntaxException e)
    {
      // FIXME JNR
      throw new NamingException(e.getLocalizedMessage());
      throw new NamingException(e.getLocalizedMessage() + ". LDAP URL was: \"" + ldapUrl + "\"");
    }
  }
opendj-server-legacy/src/main/java/org/opends/admin/ads/util/PreferredConnection.java
@@ -96,11 +96,12 @@
  /**
   * Commodity method that returns a PreferredConnection object with the
   * information on a given InitialLdapContext.
   * @param ctx the connection we retrieve the information from.
   * @param conn the connection we retrieve the information from.
   * @return a preferred connection object.
   */
  public static PreferredConnection getPreferredConnection(InitialLdapContext ctx)
  public static PreferredConnection getPreferredConnection(ConnectionWrapper conn)
  {
    InitialLdapContext ctx = conn.getLdapContext();
    String ldapUrl = ConnectionUtils.getLdapUrl(ctx);
    PreferredConnection.Type type;
    if (ConnectionUtils.isStartTLS(ctx))
@@ -121,11 +122,11 @@
  /**
   * Commodity method that generates a list of preferred connection (of just
   * one) with the information on a given InitialLdapContext.
   * @param ctx the connection we retrieve the information from.
   * @param conn the connection we retrieve the information from.
   * @return a list containing the preferred connection object.
   */
  public static Set<PreferredConnection> getPreferredConnections(InitialLdapContext ctx)
  public static Set<PreferredConnection> getPreferredConnections(ConnectionWrapper conn)
  {
    return Collections.singleton(getPreferredConnection(ctx));
    return Collections.singleton(getPreferredConnection(conn));
  }
}
opendj-server-legacy/src/main/java/org/opends/guitools/controlpanel/ui/ImportLDIFPanel.java
@@ -822,7 +822,7 @@
      {
        LocalizableMessage msg = INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, conn.getHostPort());
        getProgressDialog().appendProgressHtml(Utilities.applyFont(msg + "<br>", ColorAndFontConstants.progressFont));
        repl.initializeAllSuffix(baseDN.toString(), conn.getLdapContext(), true);
        repl.initializeAllSuffix(baseDN.toString(), conn, true);
      }
    }
opendj-server-legacy/src/main/java/org/opends/quicksetup/installer/Installer.java
@@ -24,7 +24,6 @@
import static org.opends.admin.ads.ServerDescriptor.*;
import static org.opends.admin.ads.ServerDescriptor.ServerProperty.*;
import static org.opends.admin.ads.util.ConnectionUtils.*;
import static org.opends.admin.ads.util.PreferredConnection.*;
import static org.opends.admin.ads.util.PreferredConnection.Type.*;
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.quicksetup.Step.*;
@@ -3964,7 +3963,7 @@
    }
    lastLoadedCache = new TopologyCache(adsContext, trustManager, getConnectTimeout());
    // We cannot use getPreferredConnections since the user data has not been updated yet.
    lastLoadedCache.setPreferredConnections(Collections.singleton(getPreferredConnection(adsContext.getDirContext())));
    lastLoadedCache.setPreferredConnections(PreferredConnection.getPreferredConnections(adsContext.getConnection()));
    lastLoadedCache.reloadTopology();
    Set<SuffixDescriptor> suffixes = lastLoadedCache.getSuffixes();
    Set<SuffixDescriptor> moreSuffixes = null;
opendj-server-legacy/src/main/java/org/opends/server/tools/dsreplication/ReplicationCliMain.java
@@ -65,12 +65,10 @@
import javax.naming.NameNotFoundException;
import javax.naming.NamingEnumeration;
import javax.naming.NamingException;
import javax.naming.NoPermissionException;
import javax.naming.directory.BasicAttributes;
import javax.naming.directory.DirContext;
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLException;
@@ -198,7 +196,7 @@
  private boolean forceNonInteractive;
  /** Always use SSL with the administration connector. */
  private final Type connectiontype = LDAPS;
  private final Type connectionType = LDAPS;
  /**
   * The enumeration containing the different options we display when we ask
@@ -275,20 +273,20 @@
     * @param interactive if user has to input information
     * @return whether we should stop
     */
    boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source, InitialLdapContext dest,
    boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source, ConnectionWrapper dest,
        boolean interactive);
    /**
     * Confirm with the user whether the current task should continue.
     *
     * @param uData servers address and authentication parameters
     * @param ctxSource LDAP Context for the destination server
     * @param ctxDestination LDAP Context for the source server
     * @param connSource connection to the source server
     * @param connDestination connection to the destination server
     * @param defaultValue default yes or no
     * @return whether the current task should be interrupted
     */
    boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource,
        InitialLdapContext ctxDestination, final boolean defaultValue);
    boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource,
        ConnectionWrapper connDestination, final boolean defaultValue);
  }
  /** The argument parser to be used. */
@@ -1053,56 +1051,7 @@
    return returnCode;
  }
  /**
   * Returns an InitialLdapContext using the provided parameters. We try to
   * guarantee that the connection is able to read the configuration.
   *
   * @param hostPort
   *          the host name and port to connect.
   * @param useSSL
   *          whether to use SSL or not.
   * @param useStartTLS
   *          whether to use StartTLS or not.
   * @param bindDn
   *          the bind dn to be used.
   * @param pwd
   *          the password.
   * @param connectTimeout
   *          the timeout in milliseconds to connect to the server.
   * @param trustManager
   *          the trust manager.
   * @return an InitialLdapContext connected.
   * @throws NamingException
   *           if there was an error establishing the connection.
   */
  private static InitialLdapContext createAdministrativeContext(HostPort hostPort,
      boolean useSSL, boolean useStartTLS, String bindDn, String pwd,
      int connectTimeout, ApplicationTrustManager trustManager)
      throws NamingException
  {
    InitialLdapContext ctx;
    String ldapUrl = getLDAPUrl(hostPort, useSSL);
    if (useSSL)
    {
      ctx = createLdapsContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null);
    }
    else if (useStartTLS)
    {
      ctx = createStartTLSContext(ldapUrl, bindDn, pwd, connectTimeout, null, trustManager, null);
    }
    else
    {
      ctx = createLdapContext(ldapUrl, bindDn, pwd, connectTimeout, null);
    }
    if (!connectedAsAdministrativeUser(ctx))
    {
      throw new NoPermissionException(ERR_NOT_ADMINISTRATIVE_USER.get().toString());
    }
    return ctx;
  }
  private ConnectionWrapper createConnectionInteracting(LDAPConnectionConsoleInteraction ci)
      throws ClientException
  private ConnectionWrapper createConnectionInteracting(LDAPConnectionConsoleInteraction ci) throws ClientException
  {
    return createConnectionInteracting(ci, isInteractive() && ci.isTrustStoreInMemory());
  }
@@ -1121,16 +1070,13 @@
  }
  /**
   * Creates an Initial LDAP Context interacting with the user if the
   * application is interactive.
   * Creates a connection interacting with the user if the application is interactive.
   *
   * @param ci
   *          the LDAPConnectionConsoleInteraction object that is assumed to
   *          have been already run.
   *          the LDAPConnectionConsoleInteraction object that is assumed to have been already run.
   * @param promptForCertificate
   *          whether we should prompt for the certificate or not.
   * @return the initial LDAP context or <CODE>null</CODE> if the user did not
   *         accept to trust the certificates.
   * @return the connection or {@code null} if the user did not accept to trust the certificates.
   * @throws ClientException
   *           if there was an error establishing the connection.
   */
@@ -1277,11 +1223,10 @@
    return new ClientException(ReturnCode.CLIENT_SIDE_CONNECT_ERROR, ERR_FAILED_TO_CONNECT.get(hostName, portNumber));
  }
  private ReplicationCliReturnCode purgeHistoricalRemotely(
      PurgeHistoricalUserData uData)
  private ReplicationCliReturnCode purgeHistoricalRemotely(PurgeHistoricalUserData uData)
  {
    InitialLdapContext ctx = createAdministrativeContext(uData);
    if (ctx == null)
    ConnectionWrapper conn = createAdministrativeConnection(uData);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -1289,7 +1234,7 @@
    try
    {
      List<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForPurgeHistorical(baseDNs, ctx, false);
      checkSuffixesForPurgeHistorical(baseDNs, conn, false);
      if (baseDNs.isEmpty())
      {
        return HISTORICAL_CANNOT_BE_PURGED_ON_BASEDN;
@@ -1302,7 +1247,7 @@
      try
      {
        return purgeHistoricalRemoteTask(ctx, uData);
        return purgeHistoricalRemoteTask(conn, uData);
      }
      catch (ReplicationCliException rce)
      {
@@ -1314,7 +1259,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -1331,8 +1276,8 @@
        resetChangeNumberOperations = new OperationBetweenSourceAndDestinationServers()
    {
      @Override
      public boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source,
          InitialLdapContext dest, boolean interactive)
      public boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source,
          ConnectionWrapper dest, boolean interactive)
      {
        TopologyCacheFilter filter = new TopologyCacheFilter();
        filter.setSearchMonitoringInformation(false);
@@ -1351,8 +1296,8 @@
      }
      @Override
      public boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource,
          InitialLdapContext ctxDestination, boolean defaultValue)
      public boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource,
          ConnectionWrapper connDestination, boolean defaultValue)
      {
        return !askConfirmation(INFO_RESET_CHANGE_NUMBER_CONFIRM_RESET.get(uData.getDestinationHostPort()),
            defaultValue);
@@ -1364,10 +1309,9 @@
  private ReplicationCliReturnCode resetChangeNumber(SourceDestinationServerUserData uData)
  {
    InitialLdapContext ctxSource = createAdministrativeContext(uData, uData.getSource());
    InitialLdapContext ctxDest = createAdministrativeContext(uData, uData.getDestination());
    if (!getCommonSuffixes(ctxSource, ctxDest, SuffixRelationType.NOT_FULLY_REPLICATED).isEmpty())
    ConnectionWrapper connSource = createAdministrativeConnection(uData, uData.getSource());
    ConnectionWrapper connDest = createAdministrativeConnection(uData, uData.getDestination());
    if (!getCommonSuffixes(connSource, connDest, SuffixRelationType.NOT_FULLY_REPLICATED).isEmpty())
    {
      errPrintln(ERROR_RESET_CHANGE_NUMBER_SERVERS_BASEDNS_DIFFER.get(uData.getSourceHostPort(),
          uData.getDestinationHostPort()));
@@ -1386,7 +1330,7 @@
      }
      else
      {
        newStartCN = getNewestChangeNumber(ctxSource);
        newStartCN = getNewestChangeNumber(connSource);
        if (newStartCN.isEmpty())
        {
          return ERROR_UNKNOWN_CHANGE_NUMBER;
@@ -1401,8 +1345,8 @@
              "replicationCSN",
              "targetDN"
          });
      NamingEnumeration<SearchResult> listeners = ctxSource.search(new LdapName("cn=changelog"),
          "(changeNumber=" + newStartCN + ")", ctls);
      NamingEnumeration<SearchResult> listeners = connSource.getLdapContext().search(
          new LdapName("cn=changelog"), "(changeNumber=" + newStartCN + ")", ctls);
      if (!listeners.hasMore())
      {
        errPrintln(ERROR_RESET_CHANGE_NUMBER_UNKNOWN_NUMBER.get(newStartCN, uData.getSourceHostPort()));
@@ -1419,7 +1363,7 @@
      DN targetBaseDN = DN.rootDN();
      try
      {
        for (String adn : getCommonSuffixes(ctxSource, ctxDest, SuffixRelationType.REPLICATED))
        for (String adn : getCommonSuffixes(connSource, connDest, SuffixRelationType.REPLICATED))
        {
          DN dn = DN.valueOf(adn);
          if (DN.valueOf(targetDN).isSubordinateOrEqualTo(dn) && dn.isSubordinateOrEqualTo(targetBaseDN))
@@ -1444,10 +1388,10 @@
      taskAttrs.put("ds-task-reset-change-number-to", newStartCN);
      taskAttrs.put("ds-task-reset-change-number-csn", newStartCSN);
      taskAttrs.put("ds-task-reset-change-number-base-dn", targetBaseDN.toString());
      String taskDN = createServerTask(ctxDest,
      String taskDN = createServerTask(connDest,
          "ds-task-reset-change-number", "org.opends.server.tasks.ResetChangeNumberTask", "dsreplication-reset-cn",
          taskAttrs);
      waitUntilResetChangeNumberTaskEnds(ctxDest, taskDN);
      waitUntilResetChangeNumberTaskEnds(connDest, taskDN);
      return SUCCESSFUL;
    }
    catch (ReplicationCliException | NamingException | NullPointerException e)
@@ -1457,14 +1401,14 @@
    }
  }
  private String getNewestChangeNumber(InitialLdapContext source)
  private String getNewestChangeNumber(ConnectionWrapper conn)
  {
    try
    {
      SearchControls ctls = new SearchControls();
      ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
      ctls.setReturningAttributes(new String[] {"lastChangeNumber"});
      NamingEnumeration<SearchResult> results = source.search(new LdapName(""), "objectclass=*", ctls);
      NamingEnumeration<SearchResult> results = conn.getLdapContext().search(new LdapName(""), "objectclass=*", ctls);
      if (results.hasMore()) {
        return getFirstValue(results.next(), "lastChangeNumber");
      }
@@ -1477,7 +1421,7 @@
    return "";
  }
  private void waitUntilResetChangeNumberTaskEnds(InitialLdapContext server, String taskDN)
  private void waitUntilResetChangeNumberTaskEnds(ConnectionWrapper conn, String taskDN)
      throws ReplicationCliException
  {
    String lastLogMsg = null;
@@ -1486,7 +1430,7 @@
      sleepCatchInterrupt(500);
      try
      {
        SearchResult sr = getLastSearchResult(server, taskDN, "ds-task-log-message", "ds-task-state" );
        SearchResult sr = getLastSearchResult(conn, taskDN, "ds-task-log-message", "ds-task-state");
        String logMsg = getFirstValue(sr, "ds-task-log-message");
        if (logMsg != null && !logMsg.equals(lastLogMsg))
        {
@@ -1498,8 +1442,7 @@
        if (helper.isDone(state) || helper.isStoppedByError(state))
        {
          LocalizableMessage errorMsg = ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server);
          LocalizableMessage errorMsg = ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, conn.getHostPort());
          if (helper.isCompletedWithErrors(state))
          {
            logger.warn(LocalizableMessage.raw("Completed with error: " + errorMsg));
@@ -1530,48 +1473,23 @@
    }
  }
  private InitialLdapContext createAdministrativeContext(MonoServerReplicationUserData uData)
  {
    final String bindDn = getAdministratorDN(uData.getAdminUid());
    return createAdministrativeContext(uData, bindDn);
  }
  private ConnectionWrapper createAdministrativeConnection(MonoServerReplicationUserData uData)
  {
    final String bindDn = getAdministratorDN(uData.getAdminUid());
    return createAdministrativeConnection(uData, bindDn);
    return createAdministrativeConnection(uData, getAdministratorDN(uData.getAdminUid()));
  }
  private ConnectionWrapper createAdministrativeConnection(MonoServerReplicationUserData uData, final String bindDn)
  {
    try
    {
      return new ConnectionWrapper(uData.getHostPort(), connectiontype, bindDn, uData.getAdminPwd(),
          getConnectTimeout(), getTrustManager(sourceServerCI));
      return new ConnectionWrapper(uData.getHostPort(), connectionType,
          bindDn, uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI));
    }
    catch (NamingException e)
    {
      errPrintln();
      errPrintln(getMessageForException(e, uData.getHostPort().toString()));
      logger.error(LocalizableMessage.raw("Error when creating connection for:" + uData.getHostPort()));
    }
    return null;
  }
  private InitialLdapContext createAdministrativeContext(MonoServerReplicationUserData uData, final String bindDn)
  {
    try
    {
      boolean useStartTLS = START_TLS.equals(connectiontype);
      boolean useSSL = LDAPS.equals(connectiontype);
      return createAdministrativeContext(uData.getHostPort(), useSSL, useStartTLS,
          bindDn, uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI));
    }
    catch (NamingException ne)
    {
      errPrintln();
      errPrintln(getMessageForException(ne, uData.getHostPort().toString()));
      logger.error(LocalizableMessage.raw("Complete error stack:"), ne);
      logger.error(LocalizableMessage.raw("Error when creating connection for:" + uData.getHostPort()), e);
      return null;
    }
  }
@@ -1609,15 +1527,14 @@
  }
  /**
   * Launches the purge historical operation using the
   * provided connection.
   * @param ctx the connection to the server.
   * @throws ReplicationCliException if there is an error performing the
   * operation.
   * Launches the purge historical operation using the provided connection.
   *
   * @param conn
   *          the connection to the server.
   * @throws ReplicationCliException
   *           if there is an error performing the operation.
   */
  private ReplicationCliReturnCode purgeHistoricalRemoteTask(
      InitialLdapContext ctx,
      PurgeHistoricalUserData uData)
  private ReplicationCliReturnCode purgeHistoricalRemoteTask(ConnectionWrapper conn, PurgeHistoricalUserData uData)
  throws ReplicationCliException
  {
    printPurgeProgressMessage(uData);
@@ -1633,7 +1550,7 @@
      taskID = PurgeHistoricalUserData.getTaskID(attrs);
      try
      {
        DirContext dirCtx = ctx.createSubcontext(dn, attrs);
        DirContext dirCtx = conn.getLdapContext().createSubcontext(dn, attrs);
        taskCreated = true;
        logger.info(LocalizableMessage.raw("created task entry: "+attrs));
        dirCtx.close();
@@ -1656,7 +1573,7 @@
      sleepCatchInterrupt(500);
      try
      {
        SearchResult sr = getFirstSearchResult(ctx, dn,
        SearchResult sr = getFirstSearchResult(conn, dn,
            "ds-task-log-message",
            "ds-task-state",
            "ds-task-purge-conflicts-historical-purged-values-count",
@@ -1675,7 +1592,7 @@
        if (helper.isDone(state) || helper.isStoppedByError(state))
        {
          isOver = true;
          LocalizableMessage errorMsg = getPurgeErrorMsg(lastLogMsg, state, ctx);
          LocalizableMessage errorMsg = getPurgeErrorMsg(lastLogMsg, state, conn);
          if (helper.isCompletedWithErrors(state))
          {
@@ -1710,14 +1627,14 @@
    return returnCode;
  }
  private SearchResult getFirstSearchResult(InitialLdapContext ctx, String dn, String... returnedAttributes)
  private SearchResult getFirstSearchResult(ConnectionWrapper conn, String dn, String... returnedAttributes)
      throws NamingException
  {
    SearchControls searchControls = new SearchControls();
    searchControls.setCountLimit(1);
    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
    searchControls.setReturningAttributes(returnedAttributes);
    NamingEnumeration<SearchResult> res = ctx.search(dn, "objectclass=*", searchControls);
    NamingEnumeration<SearchResult> res = conn.getLdapContext().search(dn, "objectclass=*", searchControls);
    try
    {
      SearchResult sr = null;
@@ -1730,14 +1647,14 @@
    }
  }
  private LocalizableMessage getPurgeErrorMsg(String lastLogMsg, String state, InitialLdapContext ctx)
  private LocalizableMessage getPurgeErrorMsg(String lastLogMsg, String state, ConnectionWrapper conn)
  {
    HostPort server = getHostPort(ctx);
    HostPort hostPort = conn.getHostPort();
    if (lastLogMsg != null)
    {
      return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server);
      return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, hostPort);
    }
    return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, server);
    return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, hostPort);
  }
  /**
@@ -1745,14 +1662,13 @@
   * for the server.
   * @param suffixes the suffixes provided by the user.  This Collection is
   * updated with the base DNs that the user provided interactively.
   * @param ctx connection to the server.
   * @param conn connection to the server.
   * @param interactive whether to ask the user to provide interactively
   * base DNs if none of the provided base DNs can be purged.
   */
  private void checkSuffixesForPurgeHistorical(Collection<String> suffixes,
      InitialLdapContext ctx, boolean interactive)
  private void checkSuffixesForPurgeHistorical(Collection<String> suffixes, ConnectionWrapper conn, boolean interactive)
  {
    checkSuffixesForPurgeHistorical(suffixes, getReplicas(ctx), interactive);
    checkSuffixesForPurgeHistorical(suffixes, getReplicas(conn), interactive);
  }
  /**
@@ -1934,18 +1850,18 @@
        initializeReplicationOperations = new OperationBetweenSourceAndDestinationServers()
    {
      @Override
      public boolean continueAfterUserInput(Collection<String> baseDNs, InitialLdapContext source,
          InitialLdapContext dest, boolean interactive)
      public boolean continueAfterUserInput(Collection<String> baseDNs, ConnectionWrapper source,
          ConnectionWrapper dest, boolean interactive)
      {
        checkSuffixesForInitializeReplication(baseDNs, source, dest, interactive);
        return baseDNs.isEmpty();
      }
      @Override
      public boolean confirmOperation(SourceDestinationServerUserData uData, InitialLdapContext ctxSource,
          InitialLdapContext ctxDestination, boolean defaultValue)
      public boolean confirmOperation(SourceDestinationServerUserData uData, ConnectionWrapper connSource,
          ConnectionWrapper connDestination, boolean defaultValue)
      {
        return !askConfirmation(getInitializeReplicationPrompt(uData, ctxSource, ctxDestination), defaultValue);
        return !askConfirmation(getInitializeReplicationPrompt(uData, connSource, connDestination), defaultValue);
      }
    };
    return promptIfRequired(uData, initializeReplicationOperations) ? initializeReplication(uData) : USER_CANCELLED;
@@ -1984,7 +1900,7 @@
      List<String> suffixes = argParser.getBaseDNs();
      if (uData.isOnline())
      {
        checkSuffixesForPurgeHistorical(suffixes, connWrapper.getLdapContext(), true);
        checkSuffixesForPurgeHistorical(suffixes, connWrapper, true);
      }
      else
      {
@@ -1998,7 +1914,7 @@
      if (uData.isOnline())
      {
        List<? extends TaskEntry> taskEntries = getAvailableTaskEntries(connWrapper.getLdapContext());
        List<? extends TaskEntry> taskEntries = getAvailableTaskEntries(connWrapper);
        TaskScheduleInteraction interaction =
            new TaskScheduleInteraction(uData.getTaskSchedule(), argParser.taskArgs, this,
@@ -2091,13 +2007,12 @@
    }
  }
  private List<? extends TaskEntry> getAvailableTaskEntries(
      InitialLdapContext ctx)
  private List<? extends TaskEntry> getAvailableTaskEntries(ConnectionWrapper conn)
  {
    List<TaskEntry> taskEntries = new ArrayList<>();
    List<Exception> exceptions = new ArrayList<>();
    ConfigFromDirContext cfg = new ConfigFromDirContext();
    cfg.updateTaskInformation(ctx, exceptions, taskEntries);
    cfg.updateTaskInformation(conn.getLdapContext(), exceptions, taskEntries);
    for (Exception ode : exceptions)
    {
      logger.warn(LocalizableMessage.raw("Error retrieving task entries: "+ode, ode));
@@ -2159,9 +2074,9 @@
     */
    sourceServerCI.initializeGlobalArguments(host1, port1, adminUid, bindDn1, pwd,
        pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile));
    ConnectionWrapper ctx1 = null;
    ConnectionWrapper conn1 = null;
    while (ctx1 == null && !cancelled)
    while (conn1 == null && !cancelled)
    {
      try
      {
@@ -2183,8 +2098,8 @@
        bindDn1 = sourceServerCI.getBindDN();
        pwd1 = sourceServerCI.getBindPassword();
        ctx1 = createConnectionInteracting(sourceServerCI);
        if (ctx1 == null)
        conn1 = createConnectionInteracting(sourceServerCI);
        if (conn1 == null)
        {
          cancelled = true;
        }
@@ -2215,14 +2130,14 @@
    boolean secureReplication1 = argParser.server1.secureReplicationArg.isPresent();
    boolean configureReplicationServer1 = argParser.server1.configureReplicationServer();
    boolean configureReplicationDomain1 = argParser.server1.configureReplicationDomain();
    if (ctx1 != null)
    if (conn1 != null)
    {
      int repPort1 = getReplicationPort(ctx1);
      int repPort1 = getReplicationPort(conn1);
      boolean replicationServer1Configured = repPort1 > 0;
      if (replicationServer1Configured && !configureReplicationServer1)
      {
        final LocalizableMessage msg =
            INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(ctx1.getHostPort(), repPort1);
            INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(conn1.getHostPort(), repPort1);
        if (!askConfirmation(msg, false))
        {
          cancelled = true;
@@ -2330,13 +2245,13 @@
      // eventually admin authentication data.
      if (!cancelled)
      {
        AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx1);
        AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn1);
        cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, true);
        ctx1 = aux.get();
        conn1 = aux.get();
      }
      if (!cancelled)
      {
        administratorDefined |= hasAdministrator(ctx1);
        administratorDefined |= hasAdministrator(conn1);
        if (uData.getAdminPwd() != null)
        {
          adminPwd = uData.getAdminPwd();
@@ -2400,9 +2315,9 @@
          pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile));
      destinationServerCI.setUseAdminOrBindDn(true);
    }
    ConnectionWrapper ctx2 = null;
    while (ctx2 == null && !cancelled)
    ConnectionWrapper conn2 = null;
    while (conn2 == null && !cancelled)
    {
      try
      {
@@ -2436,8 +2351,8 @@
        if (!error)
        {
          ctx2 = createConnectionInteracting(destinationServerCI, true);
          if (ctx2 == null)
          conn2 = createConnectionInteracting(destinationServerCI, true);
          if (conn2 == null)
          {
            cancelled = true;
          }
@@ -2483,14 +2398,14 @@
    boolean secureReplication2 = argParser.server2.secureReplicationArg.isPresent();
    boolean configureReplicationServer2 = argParser.server2.configureReplicationServer();
    boolean configureReplicationDomain2 = argParser.server2.configureReplicationDomain();
    if (ctx2 != null)
    if (conn2 != null)
    {
      int repPort2 = getReplicationPort(ctx2);
      int repPort2 = getReplicationPort(conn2);
      boolean replicationServer2Configured = repPort2 > 0;
      if (replicationServer2Configured && !configureReplicationServer2)
      {
        final LocalizableMessage prompt =
            INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(ctx2.getHostPort(), repPort2);
            INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.get(conn2.getHostPort(), repPort2);
        if (!askConfirmation(prompt, false))
        {
          cancelled = true;
@@ -2607,13 +2522,13 @@
      // to load the ADS to ask the user to accept the certificates.
      if (!cancelled)
      {
        AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx2);
        AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn2);
        cancelled = !loadADSAndAcceptCertificates(destinationServerCI, aux, uData, false);
        ctx2 = aux.get();
        conn2 = aux.get();
      }
      if (!cancelled)
      {
        administratorDefined |= hasAdministrator(ctx2);
        administratorDefined |= hasAdministrator(conn2);
      }
    }
    uData.getServer2().setReplicationPort(replicationPort2);
@@ -2700,13 +2615,13 @@
    if (!cancelled)
    {
      List<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true, uData);
      checkSuffixesForEnableReplication(suffixes, conn1, conn2, true, uData);
      cancelled = suffixes.isEmpty();
      uData.setBaseDNs(suffixes);
    }
    close(ctx1, ctx2);
    close(conn1, conn2);
    uData.setReplicateSchema(!argParser.noSchemaReplication());
    return !cancelled;
@@ -2738,9 +2653,9 @@
    int port = argParser.getPortToDisable();
    /* Try to connect to the server. */
    ConnectionWrapper ctx = null;
    ConnectionWrapper conn = null;
    while (ctx == null && !cancelled)
    while (conn == null && !cancelled)
    {
      try
      {
@@ -2752,8 +2667,8 @@
        adminUid = sourceServerCI.getProvidedAdminUID();
        adminPwd = sourceServerCI.getBindPassword();
        ctx = createConnectionInteracting(sourceServerCI);
        if (ctx == null)
        conn = createConnectionInteracting(sourceServerCI);
        if (conn == null)
        {
          cancelled = true;
        }
@@ -2781,16 +2696,16 @@
      uData.setBindDn(bindDn);
      uData.setAdminPwd(adminPwd);
    }
    if (ctx != null && adminUid != null)
    if (conn != null && adminUid != null)
    {
      // If the server contains an ADS, try to load it and only load it: if
      // there are issues with the ADS they will be encountered in the
      // disableReplication(DisableReplicationUserData) method.  Here we have
      // to load the ADS to ask the user to accept the certificates and
      // eventually admin authentication data.
      AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx);
      AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn);
      cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, false);
      ctx = aux.get();
      conn = aux.get();
    }
    boolean disableAll = argParser.disableAllArg.isPresent();
@@ -2812,7 +2727,7 @@
        cancelled = true;
      }
    }
    int repPort = getReplicationPort(ctx);
    int repPort = getReplicationPort(conn);
    if (!disableAll
        && (argParser.advancedArg.isPresent() || disableReplicationServer)
        && repPort > 0)
@@ -2833,7 +2748,7 @@
    if (disableReplicationServer && repPort < 0)
    {
      disableReplicationServer = false;
      final LocalizableMessage msg = INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get(ctx.getHostPort());
      final LocalizableMessage msg = INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get(conn.getHostPort());
      try
      {
        cancelled = askConfirmation(msg, false, logger);
@@ -2853,19 +2768,20 @@
    if (!cancelled && !disableAll)
    {
      List<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForDisableReplication(suffixes, ctx.getLdapContext(), true, !disableReplicationServer);
      checkSuffixesForDisableReplication(suffixes, conn, true, !disableReplicationServer);
      cancelled = suffixes.isEmpty() && !disableReplicationServer;
      uData.setBaseDNs(suffixes);
      if (!uData.disableReplicationServer() && repPort > 0 &&
          disableAllBaseDns(ctx.getLdapContext(), uData) && !argParser.advancedArg.isPresent())
      if (!uData.disableReplicationServer() && repPort > 0
          && disableAllBaseDns(conn, uData)
          && !argParser.advancedArg.isPresent())
      {
        try
        {
          uData.setDisableReplicationServer(askConfirmation(
              INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER.get(
                  ctx.getHostPort(), repPort), true,
                  conn.getHostPort(), repPort), true,
              logger));
        }
        catch (ClientException ce)
@@ -2917,7 +2833,7 @@
      }
    }
    close(ctx);
    close(conn);
    return !cancelled;
  }
@@ -2941,7 +2857,7 @@
      }
      List<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForInitializeReplication(suffixes, conn.getLdapContext(), true);
      checkSuffixesForInitializeReplication(suffixes, conn, true);
      if (suffixes.isEmpty())
      {
        return false;
@@ -2993,23 +2909,17 @@
   */
  private boolean promptIfRequiredForPreOrPost(MonoServerReplicationUserData uData)
  {
    ConnectionWrapper ctx = null;
    try
    try (ConnectionWrapper conn = getConnection(uData))
    {
      ctx = getConnection(uData);
      if (ctx == null)
      if (conn == null)
      {
        return false;
      }
      List<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForInitializeReplication(suffixes, ctx.getLdapContext(), true);
      checkSuffixesForInitializeReplication(suffixes, conn, true);
      uData.setBaseDNs(suffixes);
      return !suffixes.isEmpty();
    }
    finally
    {
      close(ctx);
    }
  }
  private ConnectionWrapper getConnection(MonoServerReplicationUserData uData)
@@ -3063,17 +2973,16 @@
   * @param uData the object to be updated.
   * @return <CODE>true</CODE> if the object was successfully updated and
   * <CODE>false</CODE> if the user cancelled the operation.
   * @throws ReplicationCliException if a critical error occurs reading the
   * ADS.
   * @throws ReplicationCliException if a critical error occurs reading the ADS.
   */
  private boolean promptIfRequired(StatusReplicationUserData uData)
  throws ReplicationCliException
  {
    ConnectionWrapper ctx = null;
    ConnectionWrapper conn = null;
    try
    {
      ctx = getConnection(uData);
      if (ctx == null)
      conn = getConnection(uData);
      if (conn == null)
      {
        return false;
      }
@@ -3083,9 +2992,9 @@
      // statusReplication(StatusReplicationUserData) method. Here we have
      // to load the ADS to ask the user to accept the certificates and
      // eventually admin authentication data.
      AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(ctx);
      AtomicReference<ConnectionWrapper> aux = new AtomicReference<>(conn);
      boolean cancelled = !loadADSAndAcceptCertificates(sourceServerCI, aux, uData, false);
      ctx = aux.get();
      conn = aux.get();
      if (cancelled)
      {
        return false;
@@ -3099,7 +3008,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -3136,10 +3045,10 @@
     */
    sourceServerCI.initializeGlobalArguments(hostSource, portSource, adminUid, null, adminPwd,
        pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile));
    /* Try to connect to the source server. */
    ConnectionWrapper ctxSource = null;
    while (ctxSource == null && !cancelled)
    // Try to connect to the source server
    ConnectionWrapper connSource = null;
    while (connSource == null && !cancelled)
    {
      try
      {
@@ -3150,8 +3059,8 @@
        adminUid = sourceServerCI.getAdministratorUID();
        adminPwd = sourceServerCI.getBindPassword();
        ctxSource = createConnectionInteracting(sourceServerCI);
        if (ctxSource == null)
        connSource = createConnectionInteracting(sourceServerCI);
        if (connSource == null)
        {
          cancelled = true;
        }
@@ -3197,11 +3106,11 @@
        argParser.getSecureArgsList());
    destinationServerCI.initializeGlobalArguments(hostDestination, portDestination, adminUid, null, adminPwd,
        pwdFile == null ? null : new LinkedHashMap<String, String>(pwdFile));
    /* Try to connect to the destination server. */
    ConnectionWrapper ctxDestination = null;
    /* Try to connect to the destination server. */
    ConnectionWrapper connDestination = null;
    destinationServerCI.resetHeadingDisplayed();
    while (ctxDestination == null && !cancelled)
    while (connDestination == null && !cancelled)
    {
      try
      {
@@ -3223,8 +3132,8 @@
        if (!error)
        {
          ctxDestination = createConnectionInteracting(destinationServerCI, true);
          if (ctxDestination == null)
          connDestination = createConnectionInteracting(destinationServerCI, true);
          if (connDestination == null)
          {
            cancelled = true;
          }
@@ -3252,28 +3161,26 @@
      uData.setPortDestination(portDestination);
      List<String> suffixes = argParser.getBaseDNs();
      cancelled = serversOperations.continueAfterUserInput(
          suffixes, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), true);
      cancelled = serversOperations.continueAfterUserInput(suffixes, connSource, connDestination, true);
      uData.setBaseDNs(suffixes);
      if (!cancelled)
      {
        println();
        cancelled = serversOperations.confirmOperation(
            uData, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), true);
        cancelled = serversOperations.confirmOperation(uData, connSource, connDestination, true);
        println();
      }
    }
    close(ctxSource, ctxDestination);
    close(connSource, connDestination);
    return !cancelled;
  }
  private LocalizableMessage getInitializeReplicationPrompt(SourceDestinationServerUserData uData,
      InitialLdapContext ctxSource, InitialLdapContext ctxDestination)
      ConnectionWrapper connSource, ConnectionWrapper connDestination)
  {
    HostPort hostPortSource = getHostPort(ctxSource);
    HostPort hostPortDestination = getHostPort(ctxDestination);
    HostPort hostPortSource = connSource.getHostPort();
    HostPort hostPortDestination = connDestination.getHostPort();
    if (initializeADS(uData.getBaseDNs()))
    {
      final String adminSuffixDN = ADSContext.getAdministrationSuffixDN();
@@ -3332,28 +3239,28 @@
        getValueOrDefault(args.hostNameArg), getValueOrDefault(args.portArg)));
    String pwd = args.getBindPassword();
    if (pwd == null)
    if (pwd == null || canConnectWithCredentials(server, adminDN, adminPwd))
    {
      server.setBindDn(adminDN);
      server.setPwd(adminPwd);
    }
    else
    {
      // Best-effort: try to use admin, if it does not work, use bind DN.
      try
      {
        InitialLdapContext ctx = createAdministrativeContext(server.getHostPort(),
            LDAPS.equals(connectiontype), START_TLS.equals(connectiontype), adminDN, adminPwd,
            getConnectTimeout(), getTrustManager(sourceServerCI));
        server.setBindDn(adminDN);
        server.setPwd(adminPwd);
        ctx.close();
      }
      catch (Throwable t)
      {
        server.setBindDn(getValueOrDefault(args.bindDnArg));
        server.setPwd(pwd);
      }
      server.setBindDn(getValueOrDefault(args.bindDnArg));
      server.setPwd(pwd);
    }
  }
  private boolean canConnectWithCredentials(EnableReplicationServerData server, String adminDN, String adminPwd)
  {
    try (ConnectionWrapper validCredentials = new ConnectionWrapper(
        server.getHostPort(), connectionType, adminDN, adminPwd, getConnectTimeout(), getTrustManager(sourceServerCI)))
    {
      return true;
    }
    catch (Throwable t)
    {
      return false;
    }
  }
@@ -3446,15 +3353,15 @@
  }
  /**
   * Tells whether the server to which the LdapContext is connected has a
   * replication port or not.
   * @param connWrapper the InitialLdapContext to be used.
   * @return <CODE>true</CODE> if the replication port for the server could
   * be found and <CODE>false</CODE> otherwise.
   * Tells whether the server for which a connection is provided has a replication port or not.
   *
   * @param conn
   *          the connection to be used.
   * @return {@code true} if the server replication port could be found, {@code false} otherwise.
   */
  private boolean hasReplicationPort(ConnectionWrapper connWrapper)
  private boolean hasReplicationPort(ConnectionWrapper conn)
  {
    return getReplicationPort(connWrapper) != -1;
    return getReplicationPort(conn) != -1;
  }
  /**
@@ -3466,7 +3373,6 @@
   */
  private int getReplicationPort(ConnectionWrapper connWrapper)
  {
    int replicationPort = -1;
    try
    {
      RootCfgClient root = connWrapper.getRootConfiguration();
@@ -3478,26 +3384,26 @@
      {
        ReplicationServerCfgClient replicationServer =
          sync.getReplicationServer();
        replicationPort = replicationServer.getReplicationPort();
        return replicationServer.getReplicationPort();
      }
    }
    catch (Throwable t)
    {
      logger.warn(LocalizableMessage.raw("Unexpected error retrieving the replication port: " + t, t));
    }
    return replicationPort;
    return -1;
  }
  /**
   * Loads the ADS with the provided context.  If there are certificates to
   * Loads the ADS with the provided connection.  If there are certificates to
   * be accepted we prompt them to the user.  If there are errors loading the
   * servers we display them to the user and we ask for confirmation.  If the
   * provided ctx is not using Global Administrator credentials, we prompt the
   * provided connection is not using Global Administrator credentials, we prompt the
   * user to provide them and update the provide ReplicationUserData
   * accordingly.
   *
   * @param ci the LDAP connection to the server
   * @param connWrapper the Ldap context to be used in an array: note the context
   * @param connWrapper the connection to be used in an array: note the connection
   * may be modified with the new credentials provided by the user.
   * @param uData the ReplicationUserData to be updated.
   * @param isFirstOrSourceServer whether this is the first server in the
@@ -3515,24 +3421,9 @@
  {
    boolean cancelled = false;
    boolean triedWithUserProvidedAdmin = false;
    final ConnectionWrapper connWrapper1 = connWrapper.get();
    final InitialLdapContext ctx1 = connWrapper1.getLdapContext();
    HostPort hostPort = connWrapper1.getHostPort();
    boolean isSSL = isSSL(ctx1);
    boolean isStartTLS = isStartTLS(ctx1);
    Type connectionType;
    if (isSSL)
    {
      connectionType = LDAPS;
    }
    else if (isStartTLS)
    {
      connectionType = START_TLS;
    }
    else
    {
      connectionType = LDAP;
    }
    final ConnectionWrapper conn1 = connWrapper.get();
    HostPort hostPort = conn1.getHostPort();
    Type connectionType = getConnectionType(conn1);
    if (getTrustManager(ci) == null)
    {
      // This is required when the user did  connect to the server using SSL or
@@ -3542,7 +3433,7 @@
    }
    try
    {
      ADSContext adsContext = new ADSContext(connWrapper1);
      ADSContext adsContext = new ADSContext(conn1);
      if (adsContext.hasAdminData())
      {
        boolean reloadTopology = true;
@@ -3556,7 +3447,7 @@
              getTrustManager(ci), getConnectTimeout());
          cache.getFilter().setSearchMonitoringInformation(false);
          cache.getFilter().setSearchBaseDNInformation(false);
          cache.setPreferredConnections(getPreferredConnections(ctx1));
          cache.setPreferredConnections(getPreferredConnections(conn1));
          cache.reloadTopology();
          reloadTopology = false;
@@ -3609,8 +3500,7 @@
                    if (!errorDisplayed)
                    {
                      println();
                      println(
                          INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get());
                      println(INFO_NOT_GLOBAL_ADMINISTRATOR_PROVIDED.get());
                      errorDisplayed = true;
                    }
                    adminUid = askForAdministratorUID(
@@ -3619,7 +3509,7 @@
                    adminPwd = askForAdministratorPwd(logger);
                    println();
                  }
                  close(ctx1);
                close(conn1);
                  try
                  {
                    final ConnectionWrapper connWrapper2 = new ConnectionWrapper(
@@ -3630,7 +3520,7 @@
                    cache = new TopologyCache(adsContext, getTrustManager(ci), getConnectTimeout());
                    cache.getFilter().setSearchMonitoringInformation(false);
                    cache.getFilter().setSearchBaseDNInformation(false);
                    cache.setPreferredConnections(getPreferredConnections(connWrapper2.getLdapContext()));
                    cache.setPreferredConnections(getPreferredConnections(connWrapper2));
                    connected = true;
                  }
                  catch (Throwable t)
@@ -3706,18 +3596,35 @@
    return !cancelled;
  }
  private Type getConnectionType(final ConnectionWrapper conn)
  {
    if (isSSL(conn.getLdapContext()))
    {
      return LDAPS;
    }
    else if (isStartTLS(conn.getLdapContext()))
    {
      return START_TLS;
    }
    else
    {
      return LDAP;
    }
  }
  /**
   * Tells whether there is a Global Administrator defined in the server
   * to which the InitialLdapContext is connected.
   * @param connWrapper the InitialLdapContext.
   * @return <CODE>true</CODE> if we could find an administrator and
   * <CODE>false</CODE> otherwise.
   * Tells whether there is a Global Administrator defined in the server for which the connection is
   * provided.
   *
   * @param conn
   *          the connection.
   * @return {@code true} if we could find an administrator and {@code false} otherwise.
   */
  private boolean hasAdministrator(ConnectionWrapper connWrapper)
  private boolean hasAdministrator(ConnectionWrapper conn)
  {
    try
    {
      ADSContext adsContext = new ADSContext(connWrapper);
      ADSContext adsContext = new ADSContext(conn);
      if (adsContext.hasAdminData())
      {
        Set<?> administrators = adsContext.readAdministratorRegistry();
@@ -3734,20 +3641,18 @@
  /**
   * Tells whether there is a Global Administrator corresponding to the provided
   * ReplicationUserData defined in the server to which the InitialLdapContext
   * is connected.
   * @param connWrapper the InitialLdapContext.
   * ReplicationUserData defined in the server for which the connection is provided.
   * @param conn the connection
   * @param uData the user data
   * @return <CODE>true</CODE> if we could find an administrator and
   * <CODE>false</CODE> otherwise.
   */
  private boolean hasAdministrator(ConnectionWrapper connWrapper,
      ReplicationUserData uData)
  private boolean hasAdministrator(ConnectionWrapper conn, ReplicationUserData uData)
  {
    String adminUid = uData.getAdminUid();
    try
    {
      ADSContext adsContext = new ADSContext(connWrapper);
      ADSContext adsContext = new ADSContext(conn);
      Set<Map<AdministratorProperty, Object>> administrators =
        adsContext.readAdministratorRegistry();
      for (Map<AdministratorProperty, Object> admin : administrators)
@@ -3769,7 +3674,7 @@
    return false;
  }
  /** Helper type for the {@link #getCommonSuffixes(InitialLdapContext, InitialLdapContext, SuffixRelationType)}. */
  /** Helper type for {@link #getCommonSuffixes(ConnectionWrapper, ConnectionWrapper, SuffixRelationType)}. */
  private enum SuffixRelationType
  {
    NOT_REPLICATED, FULLY_REPLICATED, REPLICATED, NOT_FULLY_REPLICATED, ALL
@@ -3781,23 +3686,23 @@
   * replicated this list contains only the suffixes that are replicated
   * between the servers or the list of suffixes that are not replicated
   * between the servers).
   * @param ctx1 the connection to the first server.
   * @param ctx2 the connection to the second server.
   * @param conn1 the connection to the first server.
   * @param conn2 the connection to the second server.
   * @param type whether to return a list with the suffixes that are
   * replicated, fully replicated (replicas have exactly the same list of
   * replication servers), not replicated or all the common suffixes.
   * @return a Collection containing a list of suffixes that are replicated
   * (or those that can be replicated) in two servers.
   */
  private List<String> getCommonSuffixes(InitialLdapContext ctx1, InitialLdapContext ctx2, SuffixRelationType type)
  private List<String> getCommonSuffixes(ConnectionWrapper conn1, ConnectionWrapper conn2, SuffixRelationType type)
  {
    LinkedList<String> suffixes = new LinkedList<>();
    try
    {
      TopologyCacheFilter filter = new TopologyCacheFilter();
      filter.setSearchMonitoringInformation(false);
      ServerDescriptor server1 = ServerDescriptor.createStandalone(ctx1, filter);
      ServerDescriptor server2 = ServerDescriptor.createStandalone(ctx2, filter);
      ServerDescriptor server1 = ServerDescriptor.createStandalone(conn1.getLdapContext(), filter);
      ServerDescriptor server2 = ServerDescriptor.createStandalone(conn2.getLdapContext(), filter);
      for (ReplicaDescriptor rep1 : server1.getReplicas())
      {
@@ -3904,17 +3809,17 @@
  /**
   * Returns a Collection containing a list of replicas in a server.
   * @param ctx the connection to the server.
   * @param conn the connection to the server.
   * @return a Collection containing a list of replicas in a server.
   */
  private Collection<ReplicaDescriptor> getReplicas(InitialLdapContext ctx)
  private Collection<ReplicaDescriptor> getReplicas(ConnectionWrapper conn)
  {
    LinkedList<ReplicaDescriptor> suffixes = new LinkedList<>();
    TopologyCacheFilter filter = new TopologyCacheFilter();
    filter.setSearchMonitoringInformation(false);
    try
    {
      ServerDescriptor server = ServerDescriptor.createStandalone(ctx, filter);
      ServerDescriptor server = ServerDescriptor.createStandalone(conn.getLdapContext(), filter);
      suffixes.addAll(server.getReplicas());
    }
    catch (Throwable t)
@@ -3936,16 +3841,16 @@
   */
  private ReplicationCliReturnCode enableReplication(EnableReplicationUserData uData)
  {
    ConnectionWrapper ctx1 = null;
    ConnectionWrapper ctx2 = null;
    ConnectionWrapper conn1 = null;
    ConnectionWrapper conn2 = null;
    try
    {
      println();
      print(formatter.getFormattedWithPoints(INFO_REPLICATION_CONNECTING.get()));
      List<LocalizableMessage> errorMessages = new LinkedList<>();
      ctx1 = createAdministrativeConnection(uData.getServer1(), errorMessages);
      ctx2 = createAdministrativeConnection(uData.getServer2(), errorMessages);
      conn1 = createAdministrativeConnection(uData.getServer1(), errorMessages);
      conn2 = createAdministrativeConnection(uData.getServer2(), errorMessages);
      if (!errorMessages.isEmpty())
      {
@@ -3959,7 +3864,7 @@
      if (!argParser.isInteractive())
      {
        checksForNonInteractiveMode(uData, ctx1, ctx2, errorMessages);
        checksForNonInteractiveMode(uData, conn1, conn2, errorMessages);
        if (!errorMessages.isEmpty())
        {
          errPrintLn(errorMessages);
@@ -3968,7 +3873,7 @@
      }
      List<String> suffixes = uData.getBaseDNs();
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false, uData);
      checkSuffixesForEnableReplication(suffixes, conn1, conn2, false, uData);
      if (suffixes.isEmpty())
      {
        // The error messages are already displayed in the method
@@ -3984,14 +3889,14 @@
      if (!isInteractive())
      {
        checkReplicationServerAlreadyConfigured(ctx1, uData.getServer1());
        checkReplicationServerAlreadyConfigured(ctx2, uData.getServer2());
        checkReplicationServerAlreadyConfigured(conn1, uData.getServer1());
        checkReplicationServerAlreadyConfigured(conn2, uData.getServer2());
      }
      try
      {
        updateConfiguration(ctx1, ctx2, uData);
        printSuccessfullyEnabled(ctx1, ctx2);
        updateConfiguration(conn1, conn2, uData);
        printSuccessfullyEnabled(conn1, conn2);
        return SUCCESSFUL;
      }
      catch (ReplicationCliException rce)
@@ -4004,7 +3909,7 @@
    }
    finally
    {
      close(ctx1, ctx2);
      close(conn1, conn2);
    }
  }
@@ -4104,7 +4009,7 @@
  {
    try
    {
      return new ConnectionWrapper(server.getHostPort(), connectiontype, server.getBindDn(), server.getPwd(),
      return new ConnectionWrapper(server.getHostPort(), connectionType, server.getBindDn(), server.getPwd(),
          getConnectTimeout(), getTrustManager(sourceServerCI));
    }
    catch (NamingException e)
@@ -4130,8 +4035,8 @@
        ? getAdministratorDN(uData.getAdminUid())
        : uData.getBindDn();
    ConnectionWrapper connWrapper = createAdministrativeConnection(uData, bindDn);
    if (connWrapper == null)
    ConnectionWrapper conn = createAdministrativeConnection(uData, bindDn);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -4143,8 +4048,7 @@
      println();
      List<String> suffixes = uData.getBaseDNs();
      checkSuffixesForDisableReplication(
          suffixes, connWrapper.getLdapContext(), false, !uData.disableReplicationServer());
      checkSuffixesForDisableReplication(suffixes, conn, false, !uData.disableReplicationServer());
      if (suffixes.isEmpty() && !uData.disableReplicationServer() && !uData.disableAll())
      {
        return REPLICATION_CANNOT_BE_DISABLED_ON_BASEDN;
@@ -4153,7 +4057,7 @@
      if (!isInteractive())
      {
        boolean hasReplicationPort = hasReplicationPort(connWrapper);
        boolean hasReplicationPort = hasReplicationPort(conn);
        if (uData.disableAll() && hasReplicationPort)
        {
          uData.setDisableReplicationServer(true);
@@ -4162,7 +4066,7 @@
        {
          uData.setDisableReplicationServer(false);
          println(
              INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get(connWrapper.getHostPort()));
              INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get(conn.getHostPort()));
          println();
        }
      }
@@ -4173,18 +4077,18 @@
      }
      if (!isInteractive() && !uData.disableReplicationServer() && !uData.disableAll()
          && disableAllBaseDns(connWrapper.getLdapContext(), uData) && hasReplicationPort(connWrapper))
          && disableAllBaseDns(conn, uData) && hasReplicationPort(conn))
      {
        // Inform the user that the replication server will not be disabled.
        // Inform also of the user of the disableReplicationServerArg
        println(INFO_REPLICATION_DISABLE_ALL_SUFFIXES_KEEP_REPLICATION_SERVER.get(
            connWrapper.getHostPort(),
            conn.getHostPort(),
            argParser.disableReplicationServerArg.getLongIdentifier(),
            argParser.disableAllArg.getLongIdentifier()));
      }
      try
      {
        updateConfiguration(connWrapper, uData);
        updateConfiguration(conn, uData);
        return SUCCESSFUL;
      }
      catch (ReplicationCliException rce)
@@ -4197,7 +4101,7 @@
    }
    finally
    {
      close(connWrapper);
      close(conn);
    }
  }
@@ -4209,11 +4113,10 @@
   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
   * successful and an error code otherwise.
   */
  private ReplicationCliReturnCode statusReplication(
      StatusReplicationUserData uData)
  private ReplicationCliReturnCode statusReplication(StatusReplicationUserData uData)
  {
    final ConnectionWrapper ctx = createAdministrativeConnection(uData);
    if (ctx == null)
    final ConnectionWrapper conn = createAdministrativeConnection(uData);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -4222,7 +4125,7 @@
    {
      try
      {
        displayStatus(ctx, uData);
        displayStatus(conn, uData);
        return SUCCESSFUL;
      }
      catch (ReplicationCliException rce)
@@ -4235,7 +4138,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -4250,17 +4153,17 @@
   */
  private ReplicationCliReturnCode initializeReplication(SourceDestinationServerUserData uData)
  {
    InitialLdapContext ctxSource = createAdministrativeContext(uData, uData.getSource());
    InitialLdapContext ctxDestination = createAdministrativeContext(uData, uData.getDestination());
    ConnectionWrapper connSource = createAdministrativeConnection(uData, uData.getSource());
    ConnectionWrapper connDestination = createAdministrativeConnection(uData, uData.getDestination());
    try
    {
      if (ctxSource == null || ctxDestination == null)
      if (connSource == null || connDestination == null)
      {
        return ERROR_CONNECTING;
      }
      List<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForInitializeReplication(baseDNs, ctxSource, ctxDestination, false);
      checkSuffixesForInitializeReplication(baseDNs, connSource, connDestination, false);
      if (baseDNs.isEmpty())
      {
        return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
@@ -4277,9 +4180,10 @@
        try
        {
          println();
          print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, getHostPort(ctxSource))));
          print(formatter.getFormattedProgress(
              INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, connSource.getHostPort())));
          println();
          initializeSuffix(baseDN, ctxSource, ctxDestination, true);
          initializeSuffix(baseDN, connSource, connDestination, true);
          returnValue = SUCCESSFUL;
        }
        catch (ReplicationCliException rce)
@@ -4294,18 +4198,16 @@
    }
    finally
    {
      close(ctxDestination, ctxSource);
      close(connDestination, connSource);
    }
  }
  private InitialLdapContext createAdministrativeContext(SourceDestinationServerUserData uData, HostPort server)
  private ConnectionWrapper createAdministrativeConnection(SourceDestinationServerUserData uData, HostPort server)
  {
    try
    {
      return createAdministrativeContext(
          server, LDAPS.equals(connectiontype), START_TLS.equals(connectiontype),
          getAdministratorDN(uData.getAdminUid()), uData.getAdminPwd(),
          getConnectTimeout(), getTrustManager(sourceServerCI));
      return new ConnectionWrapper(server, connectionType, getAdministratorDN(uData.getAdminUid()),
          uData.getAdminPwd(), getConnectTimeout(), getTrustManager(sourceServerCI));
    }
    catch (NamingException ne)
    {
@@ -4328,8 +4230,8 @@
  private ReplicationCliReturnCode initializeAllReplication(
      InitializeAllReplicationUserData uData)
  {
    final InitialLdapContext ctx = createAdministrativeContext(uData);
    if (ctx == null)
    final ConnectionWrapper conn = createAdministrativeConnection(uData);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -4337,7 +4239,7 @@
    try
    {
      List<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
      checkSuffixesForInitializeReplication(baseDNs, conn, false);
      if (baseDNs.isEmpty())
      {
        return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
@@ -4354,9 +4256,9 @@
        try
        {
          println();
          print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, getHostPort(ctx))));
          print(formatter.getFormattedProgress(INFO_PROGRESS_INITIALIZING_SUFFIX.get(baseDN, conn.getHostPort())));
          println();
          initializeAllSuffix(baseDN, ctx, true);
          initializeAllSuffix(baseDN, conn, true);
          returnValue = SUCCESSFUL;
        }
        catch (ReplicationCliException rce)
@@ -4371,7 +4273,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -4385,11 +4287,10 @@
   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
   * successful and an error code otherwise.
   */
  private ReplicationCliReturnCode preExternalInitialization(
      PreExternalInitializationUserData uData)
  private ReplicationCliReturnCode preExternalInitialization(PreExternalInitializationUserData uData)
  {
    InitialLdapContext ctx = createAdministrativeContext(uData);
    if (ctx == null)
    ConnectionWrapper conn = createAdministrativeConnection(uData);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -4397,7 +4298,7 @@
    try
    {
      List<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
      checkSuffixesForInitializeReplication(baseDNs, conn, false);
      if (baseDNs.isEmpty())
      {
        return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
@@ -4415,7 +4316,7 @@
        {
          println();
          print(formatter.getFormattedWithPoints(INFO_PROGRESS_PRE_EXTERNAL_INITIALIZATION.get(baseDN)));
          preExternalInitialization(baseDN, ctx);
          preExternalInitialization(baseDN, conn);
          print(formatter.getFormattedDone());
          println();
        }
@@ -4434,7 +4335,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -4448,11 +4349,10 @@
   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
   * successful and an error code otherwise.
   */
  private ReplicationCliReturnCode postExternalInitialization(
      PostExternalInitializationUserData uData)
  private ReplicationCliReturnCode postExternalInitialization(PostExternalInitializationUserData uData)
  {
    InitialLdapContext ctx = createAdministrativeContext(uData);
    if (ctx == null)
    ConnectionWrapper conn = createAdministrativeConnection(uData);
    if (conn == null)
    {
      return ERROR_CONNECTING;
    }
@@ -4460,7 +4360,7 @@
    try
    {
      List<String> baseDNs = uData.getBaseDNs();
      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
      checkSuffixesForInitializeReplication(baseDNs, conn, false);
      if (baseDNs.isEmpty())
      {
        return REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
@@ -4478,7 +4378,7 @@
        {
          println();
          print(formatter.getFormattedWithPoints(INFO_PROGRESS_POST_EXTERNAL_INITIALIZATION.get(baseDN)));
          postExternalInitialization(baseDN, ctx);
          postExternalInitialization(baseDN, conn);
          println(formatter.getFormattedDone());
          println();
        }
@@ -4497,7 +4397,7 @@
    }
    finally
    {
      close(ctx);
      close(conn);
    }
  }
@@ -4507,8 +4407,8 @@
   * @param suffixes the suffixes provided by the user.  This Collection is
   * updated by removing the base DNs that cannot be enabled and with the
   * base DNs that the user provided interactively.
   * @param ctx1 connection to the first server.
   * @param ctx2 connection to the second server.
   * @param conn1 connection to the first server.
   * @param conn2 connection to the second server.
   * @param interactive whether to ask the user to provide interactively
   * base DNs if none of the provided base DNs can be enabled.
   * @param uData the user data.  This object will not be updated by this method
@@ -4516,7 +4416,7 @@
   * replication domains must be configured or not.
   */
  private void checkSuffixesForEnableReplication(Collection<String> suffixes,
      ConnectionWrapper ctx1, ConnectionWrapper ctx2,
      ConnectionWrapper conn1, ConnectionWrapper conn2,
      boolean interactive, EnableReplicationUserData uData)
  {
    EnableReplicationServerData server1 = uData.getServer1();
@@ -4526,24 +4426,22 @@
    if (server1.configureReplicationDomain() &&
        server2.configureReplicationDomain())
    {
      availableSuffixes.addAll(getCommonSuffixes(ctx1.getLdapContext(), ctx2.getLdapContext(),
            SuffixRelationType.NOT_FULLY_REPLICATED));
      alreadyReplicatedSuffixes.addAll(getCommonSuffixes(ctx1.getLdapContext(), ctx2.getLdapContext(),
            SuffixRelationType.FULLY_REPLICATED));
      availableSuffixes.addAll(getCommonSuffixes(conn1, conn2, SuffixRelationType.NOT_FULLY_REPLICATED));
      alreadyReplicatedSuffixes.addAll(getCommonSuffixes(conn1, conn2, SuffixRelationType.FULLY_REPLICATED));
    }
    else if (server1.configureReplicationDomain())
    {
      updateAvailableAndReplicatedSuffixesForOneDomain(ctx1, ctx2,
      updateAvailableAndReplicatedSuffixesForOneDomain(conn1, conn2,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
    else if (server2.configureReplicationDomain())
    {
      updateAvailableAndReplicatedSuffixesForOneDomain(ctx2, ctx1,
      updateAvailableAndReplicatedSuffixesForOneDomain(conn2, conn1,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
    else
    {
      updateAvailableAndReplicatedSuffixesForNoDomain(ctx1, ctx2,
      updateAvailableAndReplicatedSuffixesForNoDomain(conn1, conn2,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
@@ -4629,13 +4527,13 @@
   * @param suffixes the suffixes provided by the user.  This Collection is
   * updated by removing the base DNs that cannot be disabled and with the
   * base DNs that the user provided interactively.
   * @param ctx connection to the server.
   * @param conn connection to the server.
   * @param interactive whether to ask the user to provide interactively
   * base DNs if none of the provided base DNs can be disabled.
   * @param displayErrors whether to display errors or not.
   */
  private void checkSuffixesForDisableReplication(Collection<String> suffixes,
      InitialLdapContext ctx, boolean interactive, boolean displayErrors)
      ConnectionWrapper conn, boolean interactive, boolean displayErrors)
  {
    // whether the user must provide base DNs or not
    // (if it is <CODE>false</CODE> the user will be proposed the suffixes only once)
@@ -4644,7 +4542,7 @@
    TreeSet<String> availableSuffixes = new TreeSet<>();
    TreeSet<String> notReplicatedSuffixes = new TreeSet<>();
    Collection<ReplicaDescriptor> replicas = getReplicas(ctx);
    Collection<ReplicaDescriptor> replicas = getReplicas(conn);
    for (ReplicaDescriptor rep : replicas)
    {
      String dn = rep.getSuffix().getDN();
@@ -4781,17 +4679,17 @@
   * @param suffixes the suffixes provided by the user.  This Collection is
   * updated by removing the base DNs that cannot be initialized and with the
   * base DNs that the user provided interactively.
   * @param ctx connection to the server.
   * @param conn connection to the server.
   * @param interactive whether to ask the user to provide interactively
   * base DNs if none of the provided base DNs can be initialized.
   */
  private void checkSuffixesForInitializeReplication(
      Collection<String> suffixes, InitialLdapContext ctx, boolean interactive)
      Collection<String> suffixes, ConnectionWrapper conn, boolean interactive)
  {
    TreeSet<String> availableSuffixes = new TreeSet<>();
    TreeSet<String> notReplicatedSuffixes = new TreeSet<>();
    Collection<ReplicaDescriptor> replicas = getReplicas(ctx);
    Collection<ReplicaDescriptor> replicas = getReplicas(conn);
    for (ReplicaDescriptor rep : replicas)
    {
      String dn = rep.getSuffix().getDN();
@@ -4960,17 +4858,16 @@
   * @param suffixes the suffixes provided by the user.  This Collection is
   * updated by removing the base DNs that cannot be enabled and with the
   * base DNs that the user provided interactively.
   * @param ctxSource connection to the source server.
   * @param ctxDestination connection to the destination server.
   * @param connSource connection to the source server.
   * @param connDestination connection to the destination server.
   * @param interactive whether to ask the user to provide interactively
   * base DNs if none of the provided base DNs can be initialized.
   */
  private void checkSuffixesForInitializeReplication(
      Collection<String> suffixes, InitialLdapContext ctxSource,
      InitialLdapContext ctxDestination, boolean interactive)
  private void checkSuffixesForInitializeReplication(Collection<String> suffixes, ConnectionWrapper connSource,
      ConnectionWrapper connDestination, boolean interactive)
  {
    TreeSet<String> availableSuffixes = new TreeSet<>(
        getCommonSuffixes(ctxSource, ctxDestination, SuffixRelationType.REPLICATED));
        getCommonSuffixes(connSource, connDestination, SuffixRelationType.REPLICATED));
    if (availableSuffixes.isEmpty())
    {
      errPrintln();
@@ -5007,13 +4904,13 @@
  /**
   * Updates the configuration in the two servers (and in other servers if
   * they are referenced) to enable replication.
   * @param ctx1 the connection to the first server.
   * @param ctx2 the connection to the second server.
   * @param conn1 the connection to the first server.
   * @param conn2 the connection to the second server.
   * @param uData the EnableReplicationUserData object containing the required
   * parameters to update the configuration.
   * @throws ReplicationCliException if there is an error.
   */
  private void updateConfiguration(ConnectionWrapper ctx1, ConnectionWrapper ctx2, EnableReplicationUserData uData)
  private void updateConfiguration(ConnectionWrapper conn1, ConnectionWrapper conn2, EnableReplicationUserData uData)
      throws ReplicationCliException
  {
    final Set<String> twoReplServers = new LinkedHashSet<>();
@@ -5027,11 +4924,11 @@
    filter.addBaseDNToSearch(ADSContext.getAdministrationSuffixDN());
    filter.addBaseDNToSearch(Constants.SCHEMA_DN);
    addBaseDNs(filter, uData.getBaseDNs());
    ServerDescriptor serverDesc1 = createStandalone(ctx1, filter);
    ServerDescriptor serverDesc2 = createStandalone(ctx2, filter);
    ServerDescriptor serverDesc1 = createStandalone(conn1, filter);
    ServerDescriptor serverDesc2 = createStandalone(conn2, filter);
    ADSContext adsCtx1 = new ADSContext(ctx1);
    ADSContext adsCtx2 = new ADSContext(ctx2);
    ADSContext adsCtx1 = new ADSContext(conn1);
    ADSContext adsCtx2 = new ADSContext(conn2);
    if (!argParser.isInteractive())
    {
@@ -5041,8 +4938,8 @@
      try
      {
        final Set<PreferredConnection> cnx = new LinkedHashSet<>();
        cnx.addAll(getPreferredConnections(ctx1.getLdapContext()));
        cnx.addAll(getPreferredConnections(ctx2.getLdapContext()));
        cnx.addAll(getPreferredConnections(conn1));
        cnx.addAll(getPreferredConnections(conn2));
        TopologyCache cache1 = createTopologyCache(adsCtx1, cnx, uData);
        if (cache1 != null)
        {
@@ -5115,8 +5012,8 @@
    // These are used to identify which server we use to initialize
    // the contents of the other server (if any).
    ConnectionWrapper ctxSource = null;
    ConnectionWrapper ctxDestination = null;
    ConnectionWrapper connSource = null;
    ConnectionWrapper connDestination = null;
    ADSContext adsCtxSource = null;
    boolean adsAlreadyReplicated = false;
@@ -5144,8 +5041,8 @@
            registerServer(adsCtx1, serverDesc1.getAdsProperties());
          }
          ctxSource = ctx1;
          ctxDestination = ctx2;
          connSource = conn1;
          connDestination = conn2;
          adsCtxSource = adsCtx1;
        }
        else if (registry1.size() <= 1)
@@ -5163,8 +5060,8 @@
            registerServer(adsCtx2, serverDesc2.getAdsProperties());
          }
          ctxSource = ctx2;
          ctxDestination = ctx1;
          connSource = conn2;
          connDestination = conn1;
          adsCtxSource = adsCtx2;
        }
        else if (!areEqual(registry1, registry2))
@@ -5173,7 +5070,7 @@
          println();
          boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2);
          ctxSource = isFirstSource ? ctx1 : ctx2;
          connSource = isFirstSource ? conn1 : conn2;
          adsMergeDone = true;
        }
        else
@@ -5194,7 +5091,7 @@
              println();
              boolean isFirstSource = mergeRegistries(adsCtx1, adsCtx2);
              ctxSource = isFirstSource ? ctx1 : ctx2;
              connSource = isFirstSource ? conn1 : conn2;
              adsMergeDone = true;
            }
            else if (isADS1Replicated || !isADS2Replicated)
@@ -5213,8 +5110,8 @@
                registerServer(adsCtx1, serverDesc1.getAdsProperties());
              }
              ctxSource = ctx1;
              ctxDestination = ctx2;
              connSource = conn1;
              connDestination = conn2;
              adsCtxSource = adsCtx1;
            }
            else if (isADS2Replicated)
@@ -5231,8 +5128,8 @@
                registerServer(adsCtx2, serverDesc2.getAdsProperties());
              }
              ctxSource = ctx2;
              ctxDestination = ctx1;
              connSource = conn2;
              connDestination = conn1;
              adsCtxSource = adsCtx2;
            }
          }
@@ -5253,8 +5150,8 @@
          registerServer(adsCtx2, serverDesc2.getAdsProperties());
        }
        ctxSource = ctx2;
        ctxDestination = ctx1;
        connSource = conn2;
        connDestination = conn1;
        adsCtxSource = adsCtx2;
      }
      else if (adsCtx1.hasAdminData() && !adsCtx2.hasAdminData())
@@ -5272,14 +5169,14 @@
          registerServer(adsCtx1, serverDesc1.getAdsProperties());
        }
        ctxSource = ctx1;
        ctxDestination = ctx2;
        connSource = conn1;
        connDestination = conn2;
        adsCtxSource = adsCtx1;
      }
      else
      {
        adsCtx1.createAdminData(null);
        if (!hasAdministrator(ctx1, uData))
        if (!hasAdministrator(conn1, uData))
        {
          // This could occur if the user created an administrator without
          // registering any server.
@@ -5290,8 +5187,8 @@
        serverDesc2.updateAdsPropertiesWithServerProperties();
        adsCtx1.registerServer(serverDesc2.getAdsProperties());
        ctxSource = ctx1;
        ctxDestination = ctx2;
        connSource = conn1;
        connDestination = conn2;
        adsCtxSource = adsCtx1;
      }
    }
@@ -5305,13 +5202,13 @@
    {
      try
      {
        ServerDescriptor.seedAdsTrustStore(ctxDestination.getLdapContext(), adsCtxSource.getTrustedCertificates());
        ServerDescriptor.seedAdsTrustStore(connDestination.getLdapContext(), adsCtxSource.getTrustedCertificates());
      }
      catch (Throwable t)
      {
        logger.error(LocalizableMessage.raw("Error seeding truststores: "+t, t));
        throw new ReplicationCliException(
            ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(ctxDestination.getHostPort(),
            ERR_REPLICATION_ENABLE_SEEDING_TRUSTSTORE.get(connDestination.getHostPort(),
            adsCtxSource.getHostPort(), toString(t)),
            ERROR_SEEDING_TRUSTORE, t);
      }
@@ -5341,8 +5238,8 @@
    try
    {
      Set<PreferredConnection> cnx = new LinkedHashSet<>();
      cnx.addAll(getPreferredConnections(ctx1.getLdapContext()));
      cnx.addAll(getPreferredConnections(ctx2.getLdapContext()));
      cnx.addAll(getPreferredConnections(conn1));
      cnx.addAll(getPreferredConnections(conn2));
      cache1 = createTopologyCache(adsCtx1, cnx, uData);
      if (cache1 != null)
      {
@@ -5367,8 +5264,8 @@
          ERROR_READING_TOPOLOGY_CACHE, tce);
    }
    addToSets(serverDesc1, uData.getServer1(), ctx1, twoReplServers, usedReplicationServerIds);
    addToSets(serverDesc2, uData.getServer2(), ctx2, twoReplServers, usedReplicationServerIds);
    addToSets(serverDesc1, uData.getServer1(), conn1, twoReplServers, usedReplicationServerIds);
    addToSets(serverDesc2, uData.getServer2(), conn2, twoReplServers, usedReplicationServerIds);
    for (String baseDN : uData.getBaseDNs())
    {
@@ -5403,10 +5300,10 @@
    }
    Set<String> alreadyConfiguredReplicationServers = new HashSet<>();
    configureServer(ctx1, serverDesc1, uData.getServer1(), argParser.server1.replicationPortArg,
    configureServer(conn1, serverDesc1, uData.getServer1(), argParser.server1.replicationPortArg,
        usedReplicationServerIds, allRepServers, alreadyConfiguredReplicationServers,
        WARN_FIRST_REPLICATION_SERVER_ALREADY_CONFIGURED);
    configureServer(ctx2, serverDesc2, uData.getServer2(), argParser.server2.replicationPortArg,
    configureServer(conn2, serverDesc2, uData.getServer2(), argParser.server2.replicationPortArg,
        usedReplicationServerIds, allRepServers, alreadyConfiguredReplicationServers,
        WARN_SECOND_REPLICATION_SERVER_ALREADY_CONFIGURED);
@@ -5416,10 +5313,10 @@
      Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN);
      Set<String> alreadyConfiguredServers = new HashSet<>();
      configureToReplicateBaseDN(uData.getServer1(), ctx1, serverDesc1, cache1, baseDN,
      configureToReplicateBaseDN(uData.getServer1(), conn1, serverDesc1, cache1, baseDN,
          usedIds, alreadyConfiguredServers, repServers, allRepServers, alreadyConfiguredReplicationServers);
      configureToReplicateBaseDN(uData.getServer2(), ctx2, serverDesc2, cache2, baseDN,
      configureToReplicateBaseDN(uData.getServer2(), conn2, serverDesc2, cache2, baseDN,
          usedIds, alreadyConfiguredServers, repServers, allRepServers, alreadyConfiguredReplicationServers);
    }
@@ -5429,11 +5326,11 @@
    if (adsMergeDone)
    {
      PointAdder pointAdder = new PointAdder(this);
      print(INFO_ENABLE_REPLICATION_INITIALIZING_ADS_ALL.get(ctxSource.getHostPort()));
      print(INFO_ENABLE_REPLICATION_INITIALIZING_ADS_ALL.get(connSource.getHostPort()));
      pointAdder.start();
      try
      {
        initializeAllSuffix(ADSContext.getAdministrationSuffixDN(), ctxSource.getLdapContext(), false);
        initializeAllSuffix(ADSContext.getAdministrationSuffixDN(), connSource, false);
      }
      finally
      {
@@ -5443,13 +5340,13 @@
      print(formatter.getFormattedDone());
      println();
    }
    else if (ctxSource != null && ctxDestination != null)
    else if (connSource != null && connDestination != null)
    {
      print(formatter.getFormattedWithPoints(
          INFO_ENABLE_REPLICATION_INITIALIZING_ADS.get(ctxDestination.getHostPort(), ctxSource.getHostPort())));
INFO_ENABLE_REPLICATION_INITIALIZING_ADS.get(
          connDestination.getHostPort(), connSource.getHostPort())));
      initializeSuffix(
          ADSContext.getAdministrationSuffixDN(), ctxSource.getLdapContext(), ctxDestination.getLdapContext(), false);
      initializeSuffix(ADSContext.getAdministrationSuffixDN(), connSource, connDestination, false);
      print(formatter.getFormattedDone());
      println();
    }
@@ -5459,23 +5356,23 @@
    {
      if (argParser.useSecondServerAsSchemaSource())
      {
        ctxSource = ctx2;
        ctxDestination = ctx1;
        connSource = conn2;
        connDestination = conn1;
      }
      else
      {
        ctxSource = ctx1;
        ctxDestination = ctx2;
        connSource = conn1;
        connDestination = conn2;
      }
      if (adsMergeDone)
      {
        PointAdder pointAdder = new PointAdder(this);
        println(INFO_ENABLE_REPLICATION_INITIALIZING_SCHEMA.get(
            ctxDestination.getHostPort(), ctxSource.getHostPort()));
connDestination.getHostPort(), connSource.getHostPort()));
        pointAdder.start();
        try
        {
          initializeAllSuffix(Constants.SCHEMA_DN, ctxSource.getLdapContext(), false);
          initializeAllSuffix(Constants.SCHEMA_DN, connSource, false);
        }
        finally
        {
@@ -5486,8 +5383,9 @@
      else
      {
        print(formatter.getFormattedWithPoints(INFO_ENABLE_REPLICATION_INITIALIZING_SCHEMA.get(
            ctxDestination.getHostPort(), ctxSource.getHostPort())));
        initializeSuffix(Constants.SCHEMA_DN, ctxSource.getLdapContext(), ctxDestination.getLdapContext(), false);
connDestination
            .getHostPort(), connSource.getHostPort())));
        initializeSuffix(Constants.SCHEMA_DN, connSource, connDestination, false);
      }
      print(formatter.getFormattedDone());
      println();
@@ -5508,7 +5406,7 @@
    }
  }
  private void configureToReplicateBaseDN(EnableReplicationServerData server, ConnectionWrapper ctx,
  private void configureToReplicateBaseDN(EnableReplicationServerData server, ConnectionWrapper conn,
      ServerDescriptor serverDesc, TopologyCache cache, String baseDN, Set<Integer> usedIds,
      Set<String> alreadyConfiguredServers, Set<String> repServers, final Set<String> allRepServers,
      Set<String> alreadyConfiguredReplicationServers) throws ReplicationCliException
@@ -5518,12 +5416,12 @@
    {
      try
      {
        configureToReplicateBaseDN(ctx, baseDN, repServers, usedIds);
        configureToReplicateBaseDN(conn, baseDN, repServers, usedIds);
      }
      catch (Exception ode)
      catch (Exception e)
      {
        LocalizableMessage msg = getMessageForEnableException(ctx.getHostPort(), baseDN);
        throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
        LocalizableMessage msg = getMessageForEnableException(conn.getHostPort(), baseDN);
        throw new ReplicationCliException(msg, ERROR_ENABLING_REPLICATION_ON_BASEDN, e);
      }
    }
    alreadyConfiguredServers.add(serverDesc.getId());
@@ -5535,7 +5433,7 @@
    }
  }
  private void configureServer(ConnectionWrapper ctx, ServerDescriptor serverDesc,
  private void configureServer(ConnectionWrapper conn, ServerDescriptor serverDesc,
      EnableReplicationServerData enableServer, IntegerArgument replicationPortArg,
      Set<Integer> usedReplicationServerIds, Set<String> allRepServers,
      Set<String> alreadyConfiguredReplicationServers, Arg2<Number, Number> replicationServerAlreadyConfiguredMsg)
@@ -5545,23 +5443,23 @@
    {
      try
      {
        configureAsReplicationServer(ctx, enableServer.getReplicationPort(), enableServer.isSecureReplication(),
        configureAsReplicationServer(conn, enableServer.getReplicationPort(), enableServer.isSecureReplication(),
            allRepServers, usedReplicationServerIds);
      }
      catch (Exception ode)
      {
        throw errorConfiguringReplicationServer(ctx, ode);
        throw errorConfiguringReplicationServer(conn, ode);
      }
    }
    else if (serverDesc.isReplicationServer())
    {
      try
      {
        updateReplicationServer(ctx, allRepServers);
        updateReplicationServer(conn, allRepServers);
      }
      catch (Exception ode)
      {
        throw errorConfiguringReplicationServer(ctx, ode);
        throw errorConfiguringReplicationServer(conn, ode);
      }
      if (replicationPortArg.isPresent() && enableServer.getReplicationPort() != serverDesc.getReplicationServerPort())
      {
@@ -5611,15 +5509,19 @@
  }
  /**
   * Updates the configuration in the server (and in other servers if
   * they are referenced) to disable replication.
   * @param ctx the connection to the server.
   * @param uData the DisableReplicationUserData object containing the required
   * parameters to update the configuration.
   * @throws ReplicationCliException if there is an error.
   * Updates the configuration in the server (and in other servers if they are referenced) to
   * disable replication.
   *
   * @param conn
   *          the connection to the server.
   * @param uData
   *          the DisableReplicationUserData object containing the required parameters to update the
   *          configuration.
   * @throws ReplicationCliException
   *           if there is an error.
   */
  private void updateConfiguration(ConnectionWrapper ctx,
      DisableReplicationUserData uData) throws ReplicationCliException
  private void updateConfiguration(ConnectionWrapper conn, DisableReplicationUserData uData)
      throws ReplicationCliException
  {
    TopologyCacheFilter filter = new TopologyCacheFilter();
    filter.setSearchMonitoringInformation(false);
@@ -5628,9 +5530,9 @@
      filter.addBaseDNToSearch(ADSContext.getAdministrationSuffixDN());
      addBaseDNs(filter, uData.getBaseDNs());
    }
    ServerDescriptor server = createStandalone(ctx, filter);
    ServerDescriptor server = createStandalone(conn, filter);
    ADSContext adsCtx = new ADSContext(ctx);
    ADSContext adsCtx = new ADSContext(conn);
    TopologyCache cache = null;
    // Only try to update remote server if the user provided a Global
@@ -5641,7 +5543,7 @@
      if (adsCtx.hasAdminData() && tryToUpdateRemote)
      {
        cache = new TopologyCache(adsCtx, getTrustManager(sourceServerCI), getConnectTimeout());
        cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext()));
        cache.setPreferredConnections(getPreferredConnections(conn));
        cache.getFilter().setSearchMonitoringInformation(false);
        if (!uData.disableAll())
        {
@@ -5809,9 +5711,9 @@
    boolean forceDisableADS = false;
    boolean schemaReplicated = false;
    boolean adsReplicated = false;
    boolean disableAllBaseDns = disableAllBaseDns(ctx.getLdapContext(), uData);
    boolean disableAllBaseDns = disableAllBaseDns(conn, uData);
    Collection<ReplicaDescriptor> replicas = getReplicas(ctx.getLdapContext());
    Collection<ReplicaDescriptor> replicas = getReplicas(conn);
    for (ReplicaDescriptor rep : replicas)
    {
      String dn = rep.getSuffix().getDN();
@@ -5905,11 +5807,11 @@
    {
      try
      {
        deleteReplicationDomain(ctx, baseDN);
        deleteReplicationDomain(conn, baseDN);
      }
      catch (OpenDsException ode)
      {
        LocalizableMessage msg = getMessageForDisableException(ctx.getHostPort(), baseDN);
        LocalizableMessage msg = getMessageForDisableException(conn.getHostPort(), baseDN);
        throw new ReplicationCliException(msg, ERROR_DISABLING_REPLICATION_ON_BASEDN, ode);
      }
    }
@@ -5945,19 +5847,19 @@
          }
        }
      }
      String bindDn = getBindDN(ctx.getLdapContext());
      String pwd = getBindPassword(ctx.getLdapContext());
      String bindDn = getBindDN(conn.getLdapContext());
      String pwd = getBindPassword(conn.getLdapContext());
      for (ServerDescriptor s : serversToUpdate)
      {
        removeReferencesInServer(s, replicationServerHostPort, bindDn, pwd,
            baseDNsToUpdate, disableReplicationServer,
            getPreferredConnections(ctx.getLdapContext()));
            getPreferredConnections(conn));
      }
      if (disableReplicationServer)
      {
        // Disable replication server
        disableReplicationServer(ctx);
        disableReplicationServer(conn);
        replicationServerDisabled = true;
        // Wait to be sure that changes are taken into account and reset the
        // contents of the ADS.
@@ -5967,7 +5869,7 @@
    if (disableReplicationServer && !replicationServerDisabled)
    {
      // This can happen if we could not retrieve the TopologyCache
      disableReplicationServer(ctx);
      disableReplicationServer(conn);
      replicationServerDisabled = true;
    }
@@ -6022,24 +5924,27 @@
  }
  /**
   * Displays the replication status of the different base DNs in the servers
   * registered in the ADS.
   * @param ctx the connection to the server.
   * @param uData the StatusReplicationUserData object containing the required
   * parameters to update the configuration.
   * @throws ReplicationCliException if there is an error.
   * Displays the replication status of the different base DNs in the servers registered in the ADS.
   *
   * @param conn
   *          the connection to the server.
   * @param uData
   *          the StatusReplicationUserData object containing the required parameters to update the
   *          configuration.
   * @throws ReplicationCliException
   *           if there is an error.
   */
  private void displayStatus(ConnectionWrapper ctx,
  private void displayStatus(ConnectionWrapper conn,
      StatusReplicationUserData uData) throws ReplicationCliException
  {
    ADSContext adsCtx = new ADSContext(ctx);
    ADSContext adsCtx = new ADSContext(conn);
    boolean somethingDisplayed = false;
    TopologyCache cache;
    try
    {
      cache = new TopologyCache(adsCtx, getTrustManager(sourceServerCI), getConnectTimeout());
      cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext()));
      cache.setPreferredConnections(getPreferredConnections(conn));
      addBaseDNs(cache.getFilter(), uData.getBaseDNs());
      cache.reloadTopology();
    }
@@ -6120,7 +6025,7 @@
      }
      if (!rServers.isEmpty())
      {
        displayStatus(rServers, uData.isScriptFriendly(), getPreferredConnections(ctx.getLdapContext()));
        displayStatus(rServers, uData.isScriptFriendly(), getPreferredConnections(conn));
        somethingDisplayed = true;
      }
    }
@@ -6134,8 +6039,7 @@
        boolean inserted = false;
        for (int i=0; i<orderedReplicaLists.size() && !inserted; i++)
        {
          String dn2 =
            orderedReplicaLists.get(i).iterator().next().getSuffix().getDN();
          String dn2 = orderedReplicaLists.get(i).iterator().next().getSuffix().getDN();
          if (dn1.compareTo(dn2) < 0)
          {
            orderedReplicaLists.add(i, replicas);
@@ -6150,8 +6054,7 @@
      Set<ReplicaDescriptor> replicasWithNoReplicationServer = new HashSet<>();
      Set<ServerDescriptor> serversWithNoReplica = new HashSet<>();
      displayStatus(orderedReplicaLists, uData.isScriptFriendly(),
            getPreferredConnections(ctx.getLdapContext()),
            cache.getServers(),
            getPreferredConnections(conn), cache.getServers(),
            replicasWithNoReplicationServer, serversWithNoReplica);
      somethingDisplayed = true;
@@ -6805,20 +6708,23 @@
  }
  /**
   * Updates the configuration of the replication server with the list of
   * replication servers provided.
   * @param ctx the context connected to the server that we want to update.
   * @param replicationServers the list of replication servers to which the
   * replication server will communicate with.
   * @throws OpenDsException if there is an error updating the configuration.
   * Updates the configuration of the replication server with the list of replication servers
   * provided.
   *
   * @param conn
   *          the connection to the server that we want to update.
   * @param replicationServers
   *          the list of replication servers to which the replication server will communicate with.
   * @throws OpenDsException
   *           if there is an error updating the configuration.
   */
  private void updateReplicationServer(ConnectionWrapper ctx,
  private void updateReplicationServer(ConnectionWrapper conn,
      Set<String> replicationServers) throws Exception
  {
    print(formatter.getFormattedWithPoints(
        INFO_REPLICATION_ENABLE_UPDATING_REPLICATION_SERVER.get(ctx.getHostPort())));
        INFO_REPLICATION_ENABLE_UPDATING_REPLICATION_SERVER.get(conn.getHostPort())));
    RootCfgClient root = ctx.getRootConfiguration();
    RootCfgClient root = conn.getRootConfiguration();
    ReplicationSynchronizationProviderCfgClient sync =
      (ReplicationSynchronizationProviderCfgClient)
@@ -6868,18 +6774,22 @@
  }
  /**
   * Configures a replication domain for a given base DN in the server to which
   * the provided InitialLdapContext is connected.
   * @param ctx the context connected to the server that we want to configure.
   * @param baseDN the base DN of the replication domain to configure.
   * @param replicationServers the list of replication servers to which the
   * replication domain will communicate with.
   * @param usedReplicationDomainIds the set of replication domain IDs that
   * are already in use.  The set will be updated with the replication ID
   * that will be used by the newly configured replication server.
   * @throws OpenDsException if there is an error updating the configuration.
   * Configures a replication domain for a given base DN in the server for which the connection is
   * provided.
   *
   * @param conn
   *          the connection to the server that we want to configure.
   * @param baseDN
   *          the base DN of the replication domain to configure.
   * @param replicationServers
   *          the list of replication servers to which the replication domain will communicate with.
   * @param usedReplicationDomainIds
   *          the set of replication domain IDs that are already in use. The set will be updated
   *          with the replication ID that will be used by the newly configured replication server.
   * @throws OpenDsException
   *           if there is an error updating the configuration.
   */
  private void configureToReplicateBaseDN(ConnectionWrapper ctx,
  private void configureToReplicateBaseDN(ConnectionWrapper conn,
      String baseDN,
      Set<String> replicationServers,
      Set<Integer> usedReplicationDomainIds) throws Exception
@@ -6894,15 +6804,15 @@
        && areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN()))
    {
      print(formatter.getFormattedWithPoints(
          INFO_REPLICATION_ENABLE_CONFIGURING_ADS.get(ctx.getHostPort())));
          INFO_REPLICATION_ENABLE_CONFIGURING_ADS.get(conn.getHostPort())));
    }
    else
    {
      print(formatter.getFormattedWithPoints(
          INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN.get(baseDN, ctx.getHostPort())));
          INFO_REPLICATION_ENABLE_CONFIGURING_BASEDN.get(baseDN, conn.getHostPort())));
    }
    RootCfgClient root = ctx.getRootConfiguration();
    RootCfgClient root = conn.getRootConfiguration();
    ReplicationSynchronizationProviderCfgClient sync =
      (ReplicationSynchronizationProviderCfgClient)
      root.getSynchronizationProvider("Multimaster Synchronization");
@@ -7026,7 +6936,7 @@
    for (ServerDescriptor s : allServers)
    {
      logger.info(LocalizableMessage.raw("Configuring server "+server.getHostPort(true)));
      try (ConnectionWrapper conn = getDirContextForServer(cache, s))
      try (ConnectionWrapper conn = getConnection(cache, s))
      {
        if (serversToConfigureDomain.contains(s))
        {
@@ -7071,8 +6981,8 @@
    return adminProperties;
  }
  private void initializeSuffix(String baseDN, InitialLdapContext ctxSource,
      InitialLdapContext ctxDestination, boolean displayProgress)
  private void initializeSuffix(String baseDN, ConnectionWrapper connSource, ConnectionWrapper connDestination,
      boolean displayProgress)
  throws ReplicationCliException
  {
    int replicationId = -1;
@@ -7081,7 +6991,7 @@
      TopologyCacheFilter filter = new TopologyCacheFilter();
      filter.setSearchMonitoringInformation(false);
      filter.addBaseDNToSearch(baseDN);
      ServerDescriptor source = ServerDescriptor.createStandalone(ctxSource, filter);
      ServerDescriptor source = ServerDescriptor.createStandalone(connSource.getLdapContext(), filter);
      for (ReplicaDescriptor replica : source.getReplicas())
      {
        if (areDnsEqual(replica.getSuffix().getDN(), baseDN))
@@ -7093,14 +7003,14 @@
    }
    catch (NamingException ne)
    {
      LocalizableMessage msg = getMessageForException(ne, getHostPort(ctxSource).toString());
      LocalizableMessage msg = getMessageForException(ne, connSource.getHostPort().toString());
      throw new ReplicationCliException(msg, ERROR_READING_CONFIGURATION, ne);
    }
    if (replicationId == -1)
    {
      throw new ReplicationCliException(
          ERR_INITIALIZING_REPLICATIONID_NOT_FOUND.get(getHostPort(ctxSource), baseDN),
          ERR_INITIALIZING_REPLICATIONID_NOT_FOUND.get(connSource.getHostPort(), baseDN),
          REPLICATIONID_NOT_FOUND, null);
    }
@@ -7125,7 +7035,8 @@
    {
      try
      {
        installer.initializeSuffix(ctxDestination, replicationId, baseDN, displayProgress, getHostPort(ctxSource));
        installer.initializeSuffix(
            connDestination.getLdapContext(), replicationId, baseDN, displayProgress, connSource.getHostPort());
        initDone = true;
      }
      catch (PeerNotFoundException pnfe)
@@ -7151,13 +7062,13 @@
  /**
   * Initializes all the replicas in the topology with the contents of a
   * given replica.
   * @param ctx the connection to the server where the source replica of the
   * @param conn the connection to the server where the source replica of the
   * initialization is.
   * @param baseDN the dn of the suffix.
   * @param displayProgress whether we want to display progress or not.
   * @throws ReplicationCliException if an unexpected error occurs.
   */
  public void initializeAllSuffix(String baseDN, InitialLdapContext ctx, boolean displayProgress)
  public void initializeAllSuffix(String baseDN, ConnectionWrapper conn, boolean displayProgress)
      throws ReplicationCliException
  {
    if (argParser == null)
@@ -7177,8 +7088,8 @@
    {
      try
      {
        initializeAllSuffixTry(baseDN, ctx, displayProgress);
        postPreExternalInitialization(baseDN, ctx, false);
        initializeAllSuffixTry(baseDN, conn, displayProgress);
        postPreExternalInitialization(baseDN, conn, false);
        initDone = true;
      }
      catch (PeerNotFoundException pnfe)
@@ -7205,39 +7116,38 @@
   * Launches the pre external initialization operation using the provided
   * connection on a given base DN.
   * @param baseDN the base DN that we want to reset.
   * @param ctx the connection to the server.
   * @param conn the connection to the server.
   * @throws ReplicationCliException if there is an error performing the
   * operation.
   */
  private void preExternalInitialization(String baseDN, InitialLdapContext ctx) throws ReplicationCliException
  private void preExternalInitialization(String baseDN, ConnectionWrapper conn) throws ReplicationCliException
  {
    postPreExternalInitialization(baseDN, ctx, true);
    postPreExternalInitialization(baseDN, conn, true);
  }
  /**
   * Launches the post external initialization operation using the provided
   * connection on a given base DN required for replication to work.
   * @param baseDN the base DN that we want to reset.
   * @param ctx the connection to the server.
   * @param conn the connection to the server.
   * @throws ReplicationCliException if there is an error performing the
   * operation.
   */
  private void postExternalInitialization(String baseDN, InitialLdapContext ctx) throws ReplicationCliException
  private void postExternalInitialization(String baseDN, ConnectionWrapper conn) throws ReplicationCliException
  {
    postPreExternalInitialization(baseDN, ctx, false);
    postPreExternalInitialization(baseDN, conn, false);
  }
  /**
   * Launches the pre or post external initialization operation using the
   * provided connection on a given base DN.
   * @param baseDN the base DN that we want to reset.
   * @param ctx the connection to the server.
   * @param conn the connection to the server.
   * @param isPre whether this is the pre operation or the post operation.
   * @throws ReplicationCliException if there is an error performing the
   * operation.
   * @throws ReplicationCliException if there is an error performing the operation
   */
  private void postPreExternalInitialization(String baseDN,
      InitialLdapContext ctx, boolean isPre) throws ReplicationCliException
      ConnectionWrapper conn, boolean isPre) throws ReplicationCliException
  {
    boolean isOver = false;
    String dn = null;
@@ -7249,8 +7159,11 @@
    attrMap.put("ds-task-reset-generation-id-domain-base-dn", baseDN);
    try {
      dn = createServerTask(ctx, "ds-task-reset-generation-id", "org.opends.server.tasks.SetGenerationIdTask",
          "dsreplication-reset-generation-id", attrMap);
      dn = createServerTask(conn,
          "ds-task-reset-generation-id",
          "org.opends.server.tasks.SetGenerationIdTask",
          "dsreplication-reset-generation-id",
          attrMap);
    }
    catch (NamingException ne)
    {
@@ -7269,7 +7182,7 @@
      sleepCatchInterrupt(500);
      try
      {
        SearchResult sr = getLastSearchResult(ctx, dn, "ds-task-log-message", "ds-task-state");
        SearchResult sr = getLastSearchResult(conn, dn, "ds-task-log-message", "ds-task-state");
        String logMsg = getFirstValue(sr, "ds-task-log-message");
        if (logMsg != null && !logMsg.equals(lastLogMsg))
        {
@@ -7282,7 +7195,7 @@
        if (helper.isDone(state) || helper.isStoppedByError(state))
        {
          isOver = true;
          LocalizableMessage errorMsg = getPrePostErrorMsg(lastLogMsg, state, ctx);
          LocalizableMessage errorMsg = getPrePostErrorMsg(lastLogMsg, state, conn);
          if (helper.isCompletedWithErrors(state))
          {
@@ -7312,14 +7225,14 @@
    }
  }
  private LocalizableMessage getPrePostErrorMsg(String lastLogMsg, String state, InitialLdapContext ctx)
  private LocalizableMessage getPrePostErrorMsg(String lastLogMsg, String state, ConnectionWrapper conn)
  {
    HostPort server = getHostPort(ctx);
    HostPort hostPort = conn.getHostPort();
    if (lastLogMsg != null)
    {
      return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, server);
      return ERR_UNEXPECTED_DURING_TASK_WITH_LOG.get(lastLogMsg, state, hostPort);
    }
    return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, server);
    return ERR_UNEXPECTED_DURING_TASK_NO_LOG.get(state, hostPort);
  }
  private void sleepCatchInterrupt(long millis)
@@ -7336,7 +7249,7 @@
  /**
   * Initializes all the replicas in the topology with the contents of a
   * given replica.  This method will try to create the task only once.
   * @param ctx the connection to the server where the source replica of the
   * @param conn the connection to the server where the source replica of the
   * initialization is.
   * @param baseDN the dn of the suffix.
   * @param displayProgress whether we want to display progress or not.
@@ -7344,25 +7257,27 @@
   * @throws PeerNotFoundException if the replication mechanism cannot find
   * a peer.
   */
  public void initializeAllSuffixTry(String baseDN, InitialLdapContext ctx,
      boolean displayProgress)
  throws ClientException, PeerNotFoundException
  public void initializeAllSuffixTry(String baseDN, ConnectionWrapper conn, boolean displayProgress)
      throws ClientException, PeerNotFoundException
  {
    boolean isOver = false;
    String dn = null;
    HostPort serverDisplay = getHostPort(ctx);
    HostPort hostPort = conn.getHostPort();
    Map<String, String> attrsMap = new TreeMap<>();
    attrsMap.put("ds-task-initialize-domain-dn", baseDN);
    attrsMap.put("ds-task-initialize-replica-server-id", "all");
    try
    {
      dn = createServerTask(ctx, "ds-task-initialize-remote-replica", "org.opends.server.tasks.InitializeTargetTask",
          "dsreplication-initialize", attrsMap);
      dn = createServerTask(conn,
          "ds-task-initialize-remote-replica",
          "org.opends.server.tasks.InitializeTargetTask",
          "dsreplication-initialize",
          attrsMap);
    }
    catch (NamingException ne)
    {
      throw new ClientException(ReturnCode.APPLICATION_ERROR,
              getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(serverDisplay), ne), ne);
              getThrowableMsg(INFO_ERROR_LAUNCHING_INITIALIZATION.get(hostPort), ne), ne);
    }
    LocalizableMessage lastDisplayedMsg = null;
@@ -7375,7 +7290,7 @@
      sleepCatchInterrupt(500);
      try
      {
        SearchResult sr = getLastSearchResult(ctx, dn, "ds-task-unprocessed-entry-count",
        SearchResult sr = getLastSearchResult(conn, dn, "ds-task-unprocessed-entry-count",
            "ds-task-processed-entry-count", "ds-task-log-message", "ds-task-state" );
        // Get the number of entries that have been handled and a percentage...
@@ -7435,7 +7350,7 @@
            println();
          }
          LocalizableMessage errorMsg = getInitializeAllErrorMsg(serverDisplay, lastLogMsg, state);
          LocalizableMessage errorMsg = getInitializeAllErrorMsg(hostPort, lastLogMsg, state);
          if (helper.isCompletedWithErrors(state))
          {
            logger.warn(LocalizableMessage.raw("Processed errorMsg: "+errorMsg));
@@ -7491,19 +7406,18 @@
      {
        throw new ClientException(
            ReturnCode.APPLICATION_ERROR,
                getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get(
                    serverDisplay), ne), ne);
                getThrowableMsg(INFO_ERROR_POOLING_INITIALIZATION.get(hostPort), ne), ne);
      }
    }
  }
  private SearchResult getLastSearchResult(InitialLdapContext ctx, String dn, String... returnedAttributes)
  private SearchResult getLastSearchResult(ConnectionWrapper conn, String dn, String... returnedAttributes)
      throws NamingException
  {
    SearchControls searchControls = new SearchControls();
    searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
    searchControls.setReturningAttributes(returnedAttributes);
    NamingEnumeration<SearchResult> res = ctx.search(dn, "objectclass=*", searchControls);
    NamingEnumeration<SearchResult> res = conn.getLdapContext().search(dn, "objectclass=*", searchControls);
    try
    {
      SearchResult sr = null;
@@ -7519,7 +7433,7 @@
    }
  }
  private String createServerTask(InitialLdapContext ctx, String taskObjectclass,
  private String createServerTask(ConnectionWrapper conn, String taskObjectclass,
      String taskJavaClass, String taskID, Map<String, String> taskAttrs) throws NamingException
  {
    int i = 1;
@@ -7538,7 +7452,7 @@
      dn = "ds-task-id=" + id + ",cn=Scheduled Tasks,cn=Tasks";
      try
      {
        DirContext dirCtx = ctx.createSubcontext(dn, attrs);
        DirContext dirCtx = conn.getLdapContext().createSubcontext(dn, attrs);
        logger.info(LocalizableMessage.raw("created task entry: " + attrs));
        dirCtx.close();
        return dn;
@@ -7639,15 +7553,13 @@
    filter.setSearchBaseDNInformation(false);
    ServerLoader loader = new ServerLoader(server.getAdsProperties(), bindDn,
        pwd, getTrustManager(sourceServerCI), getConnectTimeout(), cnx, filter);
    ConnectionWrapper ctx = null;
    String lastBaseDN = null;
    HostPort hostPort = null;
    try
    try (ConnectionWrapper conn = loader.createConnectionWrapper())
    {
      ctx = loader.createConnectionWrapper();
      hostPort = ctx.getHostPort();
      RootCfgClient root = ctx.getRootConfiguration();
      hostPort = conn.getHostPort();
      RootCfgClient root = conn.getRootConfiguration();
      ReplicationSynchronizationProviderCfgClient sync = null;
      try
      {
@@ -7748,10 +7660,6 @@
        throw new ReplicationCliException(msg, ERROR_CONNECTING, ode);
      }
    }
    finally
    {
      close(ctx);
    }
  }
  /**
@@ -8179,15 +8087,14 @@
   * @return <CODE>true</CODE> if we want to disable all the replicated suffixes
   * and <CODE>false</CODE> otherwise.
   */
  private boolean disableAllBaseDns(InitialLdapContext ctx,
      DisableReplicationUserData uData)
  private boolean disableAllBaseDns(ConnectionWrapper conn, DisableReplicationUserData uData)
  {
    if (uData.disableAll())
    {
      return true;
    }
    Collection<ReplicaDescriptor> replicas = getReplicas(ctx);
    Collection<ReplicaDescriptor> replicas = getReplicas(conn);
    Set<String> replicatedSuffixes = new HashSet<>();
    for (ReplicaDescriptor rep : replicas)
    {
@@ -9085,13 +8992,13 @@
  }
  private void updateAvailableAndReplicatedSuffixesForOneDomain(
      ConnectionWrapper ctxDomain, ConnectionWrapper ctxOther,
      ConnectionWrapper connDomain, ConnectionWrapper connOther,
      Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes)
  {
    Collection<ReplicaDescriptor> replicas = getReplicas(ctxDomain.getLdapContext());
    int replicationPort = getReplicationPort(ctxOther);
    Collection<ReplicaDescriptor> replicas = getReplicas(connDomain);
    int replicationPort = getReplicationPort(connOther);
    boolean isReplicationServerConfigured = replicationPort != -1;
    String replicationServer = getReplicationServer(ctxOther.getHostPort().getHost(), replicationPort);
    String replicationServer = getReplicationServer(connOther.getHostPort().getHost(), replicationPort);
    for (ReplicaDescriptor replica : replicas)
    {
      if (!isReplicationServerConfigured)
@@ -9123,19 +9030,19 @@
  }
  private void updateAvailableAndReplicatedSuffixesForNoDomain(
      ConnectionWrapper ctx1, ConnectionWrapper ctx2,
      ConnectionWrapper conn1, ConnectionWrapper conn2,
      Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes)
  {
    int replicationPort1 = getReplicationPort(ctx1);
    int replicationPort1 = getReplicationPort(conn1);
    boolean isReplicationServer1Configured = replicationPort1 != -1;
    String replicationServer1 = getReplicationServer(ctx1.getHostPort().getHost(), replicationPort1);
    String replicationServer1 = getReplicationServer(conn1.getHostPort().getHost(), replicationPort1);
    int replicationPort2 = getReplicationPort(ctx2);
    int replicationPort2 = getReplicationPort(conn2);
    boolean isReplicationServer2Configured = replicationPort2 != -1;
    String replicationServer2 = getReplicationServer(ctx2.getHostPort().getHost(), replicationPort2);
    String replicationServer2 = getReplicationServer(conn2.getHostPort().getHost(), replicationPort2);
    TopologyCache cache1 = isReplicationServer1Configured ? createTopologyCache(ctx1) : null;
    TopologyCache cache2 = isReplicationServer2Configured ? createTopologyCache(ctx2) : null;
    TopologyCache cache1 = isReplicationServer1Configured ? createTopologyCache(conn1) : null;
    TopologyCache cache2 = isReplicationServer2Configured ? createTopologyCache(conn2) : null;
    if (cache1 != null && cache2 != null)
    {
      updateAvailableAndReplicatedSuffixesForNoDomainOneSense(cache1, cache2,
@@ -9155,16 +9062,16 @@
    }
  }
  private TopologyCache createTopologyCache(ConnectionWrapper ctx)
  private TopologyCache createTopologyCache(ConnectionWrapper conn)
  {
    try
    {
      ADSContext adsContext = new ADSContext(ctx);
      ADSContext adsContext = new ADSContext(conn);
      if (adsContext.hasAdminData())
      {
        TopologyCache cache = new TopologyCache(adsContext, getTrustManager(sourceServerCI), getConnectTimeout());
        cache.getFilter().setSearchMonitoringInformation(false);
        cache.setPreferredConnections(getPreferredConnections(ctx.getLdapContext()));
        cache.setPreferredConnections(getPreferredConnections(conn));
        cache.reloadTopology();
        return cache;
      }
@@ -9172,7 +9079,7 @@
    catch (Throwable t)
    {
      logger.warn(LocalizableMessage.raw("Error loading topology cache in "
          + getLdapUrl(ctx.getLdapContext()) + ": " + t, t));
          + getLdapUrl(conn.getLdapContext()) + ": " + t, t));
    }
    return null;
  }
@@ -9193,8 +9100,7 @@
  }
  private void updateAvailableAndReplicatedSuffixesForNoDomainOneSense(
      TopologyCache cache1, TopologyCache cache2, String replicationServer1,
      String replicationServer2,
      TopologyCache cache1, TopologyCache cache2, String replicationServer1, String replicationServer2,
      Set<String> availableSuffixes, Set<String> alreadyReplicatedSuffixes)
  {
    for (SuffixDescriptor suffix : cache1.getSuffixes())
@@ -9349,8 +9255,8 @@
    PointAdder pointAdder = new PointAdder(this);
    try
    {
      Set<PreferredConnection> cnx = new LinkedHashSet<>(getPreferredConnections(adsCtx1.getDirContext()));
      cnx.addAll(getPreferredConnections(adsCtx2.getDirContext()));
      Set<PreferredConnection> cnx = new LinkedHashSet<>(getPreferredConnections(adsCtx1.getConnection()));
      cnx.addAll(getPreferredConnections(adsCtx2.getConnection()));
      TopologyCache cache1 = createTopologyCache(adsCtx1, cnx);
      TopologyCache cache2 = createTopologyCache(adsCtx2, cnx);
@@ -9491,7 +9397,7 @@
          {
            logger.info(LocalizableMessage.raw("Seeding to replication server on "+
                server.getHostPort(true)+" with certificates of "+ adsCtxSource.getHostPort()));
            try (ConnectionWrapper conn = getDirContextForServer(cacheDestination, server))
            try (ConnectionWrapper conn = getConnection(cacheDestination, server))
            {
              ServerDescriptor.seedAdsTrustStore(conn.getLdapContext(), adsCtxSource.getTrustedCertificates());
            }
@@ -9616,8 +9522,7 @@
    }
  }
  private ConnectionWrapper getDirContextForServer(TopologyCache cache, ServerDescriptor server)
      throws NamingException
  private ConnectionWrapper getConnection(TopologyCache cache, ServerDescriptor server) throws NamingException
  {
    String dn = getBindDN(cache.getAdsContext().getDirContext());
    String pwd = getBindPassword(cache.getAdsContext().getDirContext());