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

jvergara
06.52.2009 bbdcd1d918a2f27fccb2e6a3fe4d854b901dffd8
Fix for issue 4092 (dsreplication should allow to configure servers with no replication server and servers with only a replication server)

The new arguments for the enable subcommand are:
--noReplicationServer1
Specifies not to have a replication port and changelog on the first server.
The first server will only contain replicated data but no changelog with
the modifications made to the replicated data. At least two servers with a
changelog are required in the replication topology to avoid a single point
of failure
--onlyReplicationServer1
Specifies to only have a changelog (with a replication port) on the first
server. The first server will not contain replicated data but only a
changelog with the modifications made in the data contained in other
servers
--noReplicationServer2
Specifies not to have a replication port and changelog on the second
server. The second server will only contain replicated data but no
changelog with the modifications made to the replicated data. At least two
servers with a changelog are required in the replication topology to avoid
a single point of failure
--onlyReplicationServer2
Specifies to only have a changelog (with a replication port) on the second
server. The second server will not contain replicated data but only a
changelog with the modifications made in the data contained in other
servers


The two new arguments for the disable subcommand are:

--disableReplicationServerArg
Disable the replication server. The replication port and changelog will be
disabled on the specified server
--disableAll
Disable all the replication configuration in the specified server. The
contents of the server will no longer be replicated and the replication
server (changelog and replication port) will be disabled if it is
configured

There is a new configuration argument:
--advanced
Use this option to have access to advanced settings when running this
command-line in interactive mode


Note that the --disableAll is not required but it can be considered a handy option to remove all replication information in a given server (including the contents in cn=admin data). It can be useful when the user wants to start over a replication configuration as it guarantees a clean starting point.

The current behavior (when no new arguments are specified) has been kept intact. This means that the user will not have to choose to configure the replication server or the domains unless the advanced option is specified.

The exception to this happens in the case where the user decides to disable all the suffixes (but the new --disableAll option is not specified). In this case the replication server will not be automatically disabled. However if the command is run in non-interactive mode, the user will be informed of this and if run in interactive mode, the user will be proposed to disable it.

The status subcommand has also been modified to display the cases where there are replication servers that are no domains and vice-versa.
7 files modified
2306 ■■■■■ changed files
opends/src/messages/messages/admin_tool.properties 133 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/ToolConstants.java 10 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java 10 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java 46 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java 96 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java 129 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java 1882 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/admin_tool.properties
@@ -413,10 +413,20 @@
 communication through the replication port of the first server is encrypted \
 or not.  This option will only be taken into account the first time \
 replication is configured on the first server.
INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER1=Specifies not to \
 have a replication port and changelog on the first server.  The first server \
 will only contain replicated data but no changelog with the modifications \
 made to the replicated data.  At least two servers with a changelog are \
 required in the replication topology to avoid a single point of failure
INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER1=Specifies to \
 only have a changelog (with a replication port) on the first server.  The \
 first server will not contain replicated data but only a changelog with the \
 modifications made in the data contained in other servers
INFO_DESCRIPTION_ENABLE_REPLICATION_HOST2=Fully qualified directory server \
 host name or IP address of the second server whose contents will be replicated
INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2=Directory server administration port \
 number of the second server whose contents will be replicated
INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2=Directory server \
 administration port number of the second server whose contents will be \
 replicated
INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN2=DN to use to \
 bind to the second server whose contents will be replicated.  If not \
 specified the global administrator will be used to bind
@@ -444,6 +454,16 @@
 communication through the replication port of the second server is encrypted \
 or not.  This option will only be taken into account the first time \
 replication is configured on the second server
INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER2=Specifies not to \
 have a replication port and changelog on the second server.  The second \
 server will only contain replicated data but no changelog with the \
 modifications made to the replicated data.  At least two servers with a \
 changelog are required in the replication topology to avoid a single point of \
 failure
INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER2=Specifies to \
 only have a changelog (with a replication port) on the second server.  The \
 second server will not contain replicated data but only a changelog with the \
 modifications made in the data contained in other servers
INFO_DESCRIPTION_ENABLE_REPLICATION_STARTTLS2=Use StartTLS to secure \
 communication with the second server
INFO_DESCRIPTION_REPLICATION_BASEDNS=Base DN of \
@@ -485,6 +505,12 @@
 user does not want to remove references in the other replicated servers.  The \
 password provided for the Global Administrator will be used when specifying \
 this option
INFO_DESCRIPTION_DISABLE_REPLICATION_SERVER=Disable the replication server.  \
 The replication port and changelog will be disabled on the specified server
INFO_DESCRIPTION_DISABLE_ALL=Disable all the replication configuration in the \
 specified server.  The contents of the server will no longer be replicated \
 and the replication server (changelog and replication port) will be disabled \
 if it is configured
INFO_DESCRIPTION_SUBCMD_INITIALIZE_REPLICATION=Initialize the contents of the \
 data under the specified Base DN on the destination server with the contents \
 on the source server.  This operation is required after enabling replication \
@@ -567,6 +593,11 @@
INFO_REPLICATION_ENABLE_PORT1_PROMPT=Administration port of the first server
INFO_REPLICATION_ENABLE_PROTOCOL1=How do you want to connect to the first \
 server?
INFO_REPLICATION_ENABLE_REPLICATION_SERVER1_PROMPT=A replication server \
 contains a changelog with the replication changes and requires a replication \
 port to be configured.%nDo you want the first server to contain a changelog?
INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN1_PROMPT=Will this server contain \
 the data that is going to be replicated?
INFO_REPLICATION_ENABLE_REPLICATIONPORT1_PROMPT=Replication port for the first \
 server (the port must be free)
INFO_REPLICATION_ENABLE_SECURE1_PROMPT=Do you want replication to use encrypted \
@@ -579,6 +610,11 @@
INFO_REPLICATION_ENABLE_PORT2_PROMPT=Administration port of the second server
INFO_REPLICATION_ENABLE_PROTOCOL2=How do you want to connect to the second \
 server?
INFO_REPLICATION_ENABLE_REPLICATION_SERVER2_PROMPT=A replication server \
 contains a changelog with the replication changes and requires a replication \
 port to be configured.%nDo you want the second server to contain a changelog?
INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN2_PROMPT=Will this server contain \
 the data that is going to be replicated?
INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT=Replication port for the \
 second server (the port must be free)
INFO_REPLICATION_ENABLE_SECURE2_PROMPT=Do you want replication to use encrypted \
@@ -591,6 +627,11 @@
 server administration connection parameters for the destination server
SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION=There are no base DN's \
 available to enable replication between the two servers.
SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION_NO_DOMAIN=There are no \
 base DN's available to enable replication between the two servers.  You must \
 specify at least one server that will contain the replicated data, before \
 configuring servers that will only contain the replication changelog \
 (replication servers).
INFO_ALREADY_REPLICATED_SUFFIXES=The following base DN's are already replicated \
 between the two servers:%n%s
INFO_ALREADY_NOT_REPLICATED_SUFFIXES=The following base DN's are not \
@@ -618,7 +659,7 @@
 base DN's replicated in the server.
MILD_ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND=The following base DN's could \
 not be found on the server:%n%s
 MILD_ERR_REPLICATION_INITIALIZE_LOCAL_SUFFIXES_NOT_FOUND=The following base \
MILD_ERR_REPLICATION_INITIALIZE_LOCAL_SUFFIXES_NOT_FOUND=The following base \
 DN's could not be found on the server:%n%s
MILD_ERR_NO_SUFFIXES_SELECTED_TO_DISABLE=You must choose at least one \
 base DN to be disabled.
@@ -634,6 +675,38 @@
 the base DN's that have been initialized using the import-ldif command or the \
 binary copy.
INFO_REPLICATION_DISABLE_SUFFIX_PROMPT=Disable replication on base DN %s?
INFO_REPLICATION_DISABLE_ALL_SUFFIXES_KEEP_REPLICATION_SERVER=You have chosen \
 to disable replication on all the replicated servers of '%s'.  If you want \
 also the replication server (changelog and replication port) to be disabled \
 you must also specify the '--%s' or '--%s' argument.
INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER=You have \
 chosen to disable replication on all the replicated servers of '%s'.  Do you \
 want to disable also the the replication server (with replication port '%d') \
 configured on the server?
INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER=You have \
 chosen to disable all the base DNs on the server '%s'.  Do you want to \
 disable also the replication port '%d'?
INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE=You have decided to disable the \
 replication server (replication changelog).  After disabling the replication \
 server only one replication server will be configured for the following \
 suffixes:%n%s%nTo avoid a single point of failure at least two replication \
 servers must be configured.
INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE_PROMPT=You have decided to \
 disable the replication server (replication changelog).  After disabling the \
 replication server only one replication server will be configured for the \
 following suffixes:%n%s%nTo avoid a single point of failure at least two \
 replication servers must be configured.%nDo you want to continue?
INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE=You have decided to disable the \
 replication server (replication changelog).  At least one replicaton server \
 is required in a replication topology and this is the last replication server \
 for the following suffixes:%n%s%nReplication will be disabled for these \
 servers.
INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE_PROMPT=You have decided to disable \
 the replication server (replication changelog).  At least one replicaton \
 server is required in a replication topology and this is the last replication \
 server for the following suffixes:%n%s%nReplication will be disabled for \
 these servers.%nDo you want to continue?
INFO_REPLICATION_DISABLE_ADS_CONTENTS=Removing registration information
INFO_REPLICATION_INITIALIZE_ALL_SUFFIX_PROMPT=Initialize base DN %s?
INFO_REPLICATION_PRE_EXTERNAL_INITIALIZATION_SUFFIX_PROMPT=Are you going to \
 initialize with import-ldif or binary copy base DN %s?
@@ -660,10 +733,22 @@
INFO_REPLICATION_CONFIRM_DISABLE_GENERIC=Disabling replication will make the \
 data under the selected base DN's not to be synchronized with other servers \
 any more.  Do you want to continue?
INFO_REPLICATION_CONFIRM_DISABLE_LAST_SUFFIXES=Disabling replication will make \
 the data under the selected base DN's not to be synchronized with other \
 servers any more.  The replication port on the server will also be disabled.  \
 Do you want to continue?
INFO_REPLICATION_PROMPT_DISABLE_ALL=You can choose to disable all the \
 replication on the server.  If you choose 'yes' the changelog and the \
 replication port (if defined) will be disabled; if this server contains \
 replicated data, the data will not be replicated with other servers any \
 more; all the registration information will be deleted.%nDo you want to \
 disable all the replication configuration?
INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE=There is no \
 replication server configured in '%s'.  Do you want to continue?
INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE=There is no \
 replication server configured in '%s'.
INFO_REPLICATION_CONFIRM_DISABLE_ALL=Disabling all replication will make \
 the data under the base DN's not to be synchronized with other \
 servers any more.  The replication server (changelog and replicatin port) on \
 the server will also be disabled.  Do you want to disable all replication?
INFO_REPLICATION_PROMPT_DISABLE_REPLICATION_SERVER=Do you want to disable the \
 replication server (changelog and replicatin port '%d') on the server?
INFO_REPLICATION_CONFIRM_INITIALIZE_ADS=You chose to initialize the contents \
 of base DN %s on server %s with the contents in server %s.  This base DN is \
 used by the replication mechanism and by some administrative tools and it is \
@@ -685,6 +770,12 @@
 replication tool will to try to update the configuration of all the servers \
 in a best-effort mode.  However it cannot guarantee that the servers that are \
 generating errors will be updated.
INFO_REPLICATION_SERVER_CONFIGURED_WARNING=You asked not to configure a \
 replication server in '%s' but the server already has a replication server \
 configured (with replication port '%d').
INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT=You asked not to configure a \
 replication server in '%s' but the server already has a replication server \
 configured (with replication port '%d').  Do you want to continue?
INFO_REPLICATION_CONNECTING=Establishing connections
INFO_REPLICATION_ENABLE_UPDATING_ADS_CONTENTS=Checking Registration information
INFO_REPLICATION_ENABLE_UPDATING_REPLICATION_SERVER=Updating remote references \
@@ -751,6 +842,32 @@
missing change:
INFO_REPLICATION_STATUS_LABEL_REPLICATION_PORT=Replication Port:
INFO_REPLICATION_STATUS_LABEL_SECURE=Security:
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LEGEND=[5] Server not \
 configured as a replication server (no replication changelog).
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LEGEND=[6] Server does not \
 contain replicated data for the suffix.
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_SHORT=-- [5]
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_SHORT=-- [6]
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LONG=Server not configured as \
 a replication server (no changelog)
INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LONG=Server does not contain \
 replicated data for the suffix
INFO_REPLICATION_STATUS_INDEPENDENT_REPLICATION_SERVERS=The following servers \
 have a replication server (with changelog and a replication port) but are not \
 linked to any server containing replicated data.
INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_CONFIRM=Only one replication \
 server will be defined for the following base DNs:%n%s%nIt is recommended to \
 have at least two replication servers (two changelogs) to avoid a single \
 point of failure in the replication topology.%nDo you want to continue?
INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_WARNING=Only one replication \
 server will be defined for the following base DNs:%n%s%nIt is recommended to \
 have at least two replication servers (two changelogs) to avoid a single \
 point of failure in the replication topology.
SEVERE_ERR_REPLICATION_NO_REPLICATION_SERVER=No replication server is defined \
 for the following base DNs:%n%s%nAt least one replication server (a \
 changelog) is required in the replication topology.  It is recommended to \
 have at least two replication servers (two changelogs) to avoid a single \
 point of failure in the replication topology.
INFO_REPLICATION_STATUS_SECURITY_ENABLED=Enabled
INFO_REPLICATION_STATUS_SECURITY_DISABLED=Disabled
INFO_REPLICATION_CRITICAL_ERROR_DETAILS=Details: %s
@@ -812,6 +929,8 @@
INFO_REPLICATION_DESCRIPTION_EQUIVALENT_COMMAND_FILE_PATH=The full path to \
 the file where the equivalent non-interactive commands will be written when \
 this command is run in interactive mode
INFO_REPLICATION_DESCRIPTION_ADVANCED=Use this option to have access to \
 advanced settings when running this command-line in interactive mode
MILD_ERR_REPLICATION_ERROR_WRITING_EQUIVALENT_COMMAND_LINE=An error \
 occurred while attempting to write equivalent non-interactive command line to \
 file %s.  Error details:  %s
opends/src/server/org/opends/server/tools/ToolConstants.java
@@ -735,5 +735,15 @@
   */
  public static final String OPTION_LONG_EQUIVALENT_COMMAND_FILE_PATH =
    "commandFilePath";
  /**
   * The value for the long option advanced.
   */
  public static final String OPTION_DSCFG_LONG_ADVANCED = "advanced";
  /**
   * The value for the short option advanced.
   */
  public static final Character OPTION_DSCFG_SHORT_ADVANCED = null;
}
opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
@@ -286,16 +286,6 @@
  public static final String GENERIC_TYPE = "generic";
  /**
   * The value for the long option advanced.
   */
  private static final String OPTION_DSCFG_LONG_ADVANCED = "advanced";
  /**
   * The value for the short option advanced.
   */
  private static final Character OPTION_DSCFG_SHORT_ADVANCED = null;
  /**
   * The tracer object for the debug logger.
   */
  private static final DebugTracer TRACER = getTracer();
opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java
@@ -41,6 +41,8 @@
  private boolean useSSL;
  private String bindDn;
  private String bindPwd;
  private boolean disableReplicationServer;
  private boolean disableAll;
  /**
   * Returns the host name of the server.
@@ -158,4 +160,48 @@
  {
    this.bindPwd = bindPwd;
  }
  /**
   * Tells whether the user wants to disable all the replication from the
   * server.
   * @return <CODE>true</CODE> if the user wants to disable all replication
   * from the server and <CODE>false</CODE> otherwise.
   */
  public boolean disableAll()
  {
    return disableAll;
  }
  /**
   * Sets whether the user wants to disable all the replication from the
   * server.
   * @param disableAll whether the user wants to disable all the replication
   * from the server.
   */
  public void setDisableAll(boolean disableAll)
  {
    this.disableAll = disableAll;
  }
  /**
   * Tells whether the user asked to disable the replication server in the
   * server.
   * @return <CODE>true</CODE> if the user wants to disable replication server
   * in the server and <CODE>false</CODE> otherwise.
   */
  public boolean disableReplicationServer()
  {
    return disableReplicationServer;
  }
  /**
   * Sets whether the user asked to disable the replication server in the
   * server.
   * @param disableReplicationServer whether the user asked to disable the
   * replication server in the server.
   */
  public void setDisableReplicationServer(boolean disableReplicationServer)
  {
    this.disableReplicationServer = disableReplicationServer;
  }
}
opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java
@@ -48,6 +48,10 @@
  private int replicationPort2;
  private boolean secureReplication2;
  private boolean replicateSchema = true;
  private boolean configureReplicationServer1 = true;
  private boolean configureReplicationServer2 = true;
  private boolean configureReplicationDomain1 = true;
  private boolean configureReplicationDomain2 = true;
  /**
   * Returns the host name of the first server.
@@ -300,4 +304,96 @@
  {
    this.secureReplication2 = secureReplication2;
  }
  /**
   * Returns whether the user asked to configure the replication server on the
   * first server or not.
   * @return whether the user asked to configure the replication server on the
   * first server or not.
   */
  public boolean configureReplicationServer1()
  {
    return configureReplicationServer1;
  }
  /**
   * Sets whether the replication server on the first server must be configured
   * or not.
   * @param configureReplicationServer1 whether the replication server on the
   * first server must be configured or not.
   */
  public void setConfigureReplicationServer1(
      boolean configureReplicationServer1)
  {
    this.configureReplicationServer1 = configureReplicationServer1;
  }
  /**
   * Returns whether the user asked to configure the replication server on the
   * second server or not.
   * @return whether the user asked to configure the replication server on the
   * second server or not.
   */
  public boolean configureReplicationServer2()
  {
    return configureReplicationServer2;
  }
  /**
   * Sets whether the replication server on the second server must be configured
   * or not.
   * @param configureReplicationServer2 whether the replication server on the
   * second server must be configured or not.
   */
  public void setConfigureReplicationServer2(
      boolean configureReplicationServer2)
  {
    this.configureReplicationServer2 = configureReplicationServer2;
  }
  /**
   * Returns whether the user asked to configure the replication domain on the
   * first server or not.
   * @return whether the user asked to configure the replication domain on the
   * first server or not.
   */
  public boolean configureReplicationDomain1()
  {
    return configureReplicationDomain1;
  }
  /**
   * Sets whether the replication domain on the first server must be configured
   * or not.
   * @param configureReplicationDomain1 whether the replication domain on the
   * first server must be configured or not.
   */
  public void setConfigureReplicationDomain1(
      boolean configureReplicationDomain1)
  {
    this.configureReplicationDomain1 = configureReplicationDomain1;
  }
  /**
   * Returns whether the user asked to configure the replication domain on the
   * second server or not.
   * @return whether the user asked to configure the replication domain on the
   * second server or not.
   */
  public boolean configureReplicationDomain2()
  {
    return configureReplicationDomain2;
  }
  /**
   * Sets whether the replication domain on the second server must be configured
   * or not.
   * @param configureReplicationDomain2 whether the replication domain on the
   * second server must be configured or not.
   */
  public void setConfigureReplicationDomain2(
      boolean configureReplicationDomain2)
  {
    this.configureReplicationDomain2 = configureReplicationDomain2;
  }
}
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java
@@ -34,6 +34,7 @@
import java.io.File;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedList;
import org.opends.messages.Message;
@@ -45,6 +46,7 @@
import org.opends.server.admin.client.cli.SecureConnectionCliParser;
import org.opends.server.util.args.Argument;
import org.opends.server.util.args.ArgumentException;
import org.opends.server.util.args.ArgumentGroup;
import org.opends.server.util.args.BooleanArgument;
import org.opends.server.util.args.FileBasedArgument;
import org.opends.server.util.args.IntegerArgument;
@@ -107,6 +109,16 @@
  IntegerArgument replicationPort1Arg = null;
  /**
   * The 'noReplicationServer' argument for the first server.
   */
  BooleanArgument noReplicationServer1Arg = null;
  /**
   * The 'onlyReplicationServer' argument for the first server.
   */
  BooleanArgument onlyReplicationServer1Arg = null;
  /**
   * The 'secureReplication' argument for the first server.
   */
  BooleanArgument secureReplication1Arg = null;
@@ -142,6 +154,16 @@
  IntegerArgument replicationPort2Arg = null;
  /**
   * The 'noReplicationServer' argument for the second server.
   */
  BooleanArgument noReplicationServer2Arg = null;
  /**
   * The 'onlyReplicationServer' argument for the second server.
   */
  BooleanArgument onlyReplicationServer2Arg = null;
  /**
   * The 'secureReplication' argument for the second server.
   */
  private BooleanArgument secureReplication2Arg = null;
@@ -162,6 +184,18 @@
  private BooleanArgument useSecondServerAsSchemaSourceArg;
  /**
   * The 'disableAll' argument to disable all the replication configuration of
   * server.
   */
  BooleanArgument disableAllArg;
  /**
   * The 'disableReplicationServer' argument to disable the replication
   * server.
   */
  BooleanArgument disableReplicationServerArg;
  /**
   * The 'hostName' argument for the source server.
   */
  private StringArgument hostNameSourceArg = null;
@@ -225,6 +259,12 @@
  StringArgument equivalentCommandFileArgument;
  /**
   * The argument that the user must set to have advanced options in interactive
   * mode.
   */
  BooleanArgument advancedArg;
  /**
   * The text of the enable replication subcommand.
   */
  public static final String ENABLE_REPLICATION_SUBCMD_NAME = "enable";
@@ -365,10 +405,21 @@
      }
    }
    if (noPromptArg.isPresent() && advancedArg.isPresent())
    {
      Message message = ERR_TOOL_CONFLICTING_ARGS.get(
          noPromptArg.getLongIdentifier(),
          advancedArg.getLongIdentifier());
      errors.add(message);
    }
    if (!isInteractive())
    {
      // Check that we have the required data
      if (!baseDNsArg.isPresent() && !isStatusReplicationSubcommand())
      if (!baseDNsArg.isPresent() &&
          !isStatusReplicationSubcommand() &&
          !disableAllArg.isPresent() &&
          !disableReplicationServerArg.isPresent())
      {
        errors.add(ERR_REPLICATION_NO_BASE_DN_PROVIDED.get());
      }
@@ -503,6 +554,12 @@
        INFO_REPLICATION_DESCRIPTION_EQUIVALENT_COMMAND_FILE_PATH.get());
    defaultArgs.add(index++, equivalentCommandFileArgument);
    advancedArg = new BooleanArgument(OPTION_DSCFG_LONG_ADVANCED,
        OPTION_DSCFG_SHORT_ADVANCED,
        OPTION_DSCFG_LONG_ADVANCED,
        INFO_REPLICATION_DESCRIPTION_ADVANCED.get());
    defaultArgs.add(index++, advancedArg);
    for (int i=0; i<index; i++)
    {
      Argument arg = defaultArgs.get(i);
@@ -522,7 +579,38 @@
    defaultArgs.add(this.noPropertiesFileArgument);
    setNoPropertiesFileArgument(this.noPropertiesFileArgument);
    initializeGlobalArguments(defaultArgs);
    initializeGlobalArguments(defaultArgs, null);
  }
  /**
   * Initialize the global options with the provided set of arguments.
   * @param args the arguments to use to initialize the global options.
   * @param argGroup to which args will be added
   * @throws ArgumentException if there is a conflict with the provided
   * arguments.
   */
  protected void initializeGlobalArguments(
          Collection<Argument> args,
          ArgumentGroup argGroup)
  throws ArgumentException
  {
    for (Argument arg : args)
    {
      if (arg == advancedArg)
      {
        ArgumentGroup toolOptionsGroup = new ArgumentGroup(
            INFO_DESCRIPTION_CONFIG_OPTIONS_ARGS.get(), 2);
        addGlobalArgument(advancedArg, toolOptionsGroup);
      }
      else
      {
        addGlobalArgument(arg, argGroup);
      }
    }
    // Set the propertiesFile argument
    setFilePropertiesArgument(propertiesFileArg);
  }
  /**
@@ -567,6 +655,14 @@
        "secureReplication1",
        INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION1.get());
    noReplicationServer1Arg = new BooleanArgument(
        "noreplicationserver1", null, "noReplicationServer1",
        INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER1.get());
    onlyReplicationServer1Arg = new BooleanArgument(
        "onlyreplicationserver1", null, "onlyReplicationServer1",
        INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER1.get());
    hostName2Arg = new StringArgument("host2", 'O',
        "host2", false, false, true, INFO_HOST_PLACEHOLDER.get(),
        getDefaultHostValue(),
@@ -600,6 +696,14 @@
        "secureReplication2",
        INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION2.get());
    noReplicationServer2Arg = new BooleanArgument(
        "noreplicationserver2", null, "noReplicationServer2",
        INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER2.get());
    onlyReplicationServer2Arg = new BooleanArgument(
        "onlyreplicationserver2", null, "onlyReplicationServer2",
        INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER2.get());
    skipPortCheckArg = new BooleanArgument(
        "skipportcheck", 'S', "skipPortCheck",
        INFO_DESCRIPTION_ENABLE_REPLICATION_SKIPPORT.get());
@@ -620,8 +724,10 @@
    Argument[] argsToAdd = {
        hostName1Arg, port1Arg, bindDn1Arg, bindPassword1Arg,
        bindPasswordFile1Arg, replicationPort1Arg, secureReplication1Arg,
        noReplicationServer1Arg, onlyReplicationServer1Arg,
        hostName2Arg, port2Arg, bindDn2Arg, bindPassword2Arg,
        bindPasswordFile2Arg, replicationPort2Arg, secureReplication2Arg,
        noReplicationServer2Arg, onlyReplicationServer2Arg,
        skipPortCheckArg, noSchemaReplicationArg,
        useSecondServerAsSchemaSourceArg
    };
@@ -649,8 +755,17 @@
        OPTION_LONG_BINDDN, false, false, true, INFO_BINDDN_PLACEHOLDER.get(),
        "cn=Directory Manager", OPTION_LONG_BINDDN,
        INFO_DESCRIPTION_DISABLE_REPLICATION_BINDDN.get());
    disableReplicationServerArg = new BooleanArgument(
        "disablereplicationserverarg", null, "disableReplicationServerArg",
        INFO_DESCRIPTION_DISABLE_REPLICATION_SERVER.get());
    disableAllArg = new BooleanArgument(
        "disableall", null, "disableAll",
        INFO_DESCRIPTION_DISABLE_ALL.get());
    Argument[] argsToAdd = { secureArgsList.hostNameArg,
        secureArgsList.portArg, secureArgsList.bindDnArg };
        secureArgsList.portArg, secureArgsList.bindDnArg,
        disableReplicationServerArg, disableAllArg};
    for (int i=0; i<argsToAdd.length; i++)
    {
      disableReplicationSubCmd.addArgument(argsToAdd[i]);
@@ -1775,6 +1890,10 @@
    {
        {bindPassword1Arg, bindPasswordFile1Arg},
        {bindPassword2Arg, bindPasswordFile2Arg},
        {replicationPort1Arg, noReplicationServer1Arg},
        {noReplicationServer1Arg, onlyReplicationServer1Arg},
        {replicationPort2Arg, noReplicationServer1Arg},
        {noReplicationServer2Arg, onlyReplicationServer2Arg},
        {noSchemaReplicationArg, useSecondServerAsSchemaSourceArg}
    };
@@ -1816,7 +1935,9 @@
  {
    Argument[][] conflictingPairs =
    {
        {secureArgsList.adminUidArg, secureArgsList.bindDnArg}
        {secureArgsList.adminUidArg, secureArgsList.bindDnArg},
        {disableAllArg, disableReplicationServerArg},
        {disableAllArg, baseDNsArg}
    };
    for (int i=0; i< conflictingPairs.length; i++)
opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java
@@ -45,6 +45,7 @@
import java.net.InetAddress;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
@@ -53,6 +54,7 @@
import java.util.LinkedList;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;
@@ -68,12 +70,10 @@
import javax.naming.directory.SearchControls;
import javax.naming.directory.SearchResult;
import javax.naming.ldap.InitialLdapContext;
import javax.naming.ldap.LdapName;
import javax.net.ssl.TrustManager;
import org.opends.admin.ads.ADSContext;
import org.opends.admin.ads.ADSContextException;
import org.opends.admin.ads.ADSContextHelper;
import org.opends.admin.ads.ReplicaDescriptor;
import org.opends.admin.ads.ServerDescriptor;
import org.opends.admin.ads.SuffixDescriptor;
@@ -82,7 +82,6 @@
import org.opends.admin.ads.TopologyCacheFilter;
import org.opends.admin.ads.ADSContext.ADSPropertySyntax;
import org.opends.admin.ads.ADSContext.AdministratorProperty;
import org.opends.admin.ads.ADSContext.ServerProperty;
import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.admin.ads.util.PreferredConnection;
@@ -907,10 +906,56 @@
    }
    int replicationPort1 = -1;
    boolean secureReplication1 = argParser.isSecureReplication1();
    boolean configureReplicationServer1 =
      !argParser.noReplicationServer1Arg.isPresent();
    boolean configureReplicationDomain1 =
      !argParser.onlyReplicationServer1Arg.isPresent();
    if (ctx1 != null)
    {
      int repPort1 = getReplicationPort(ctx1);
      boolean replicationServer1Configured = repPort1 > 0;
      if (replicationServer1Configured && !configureReplicationServer1)
      {
        try
        {
          if (!askConfirmation(
              INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.
              get(ConnectionUtils.getHostPort(ctx1), repPort1), false, LOG))
          {
            cancelled = true;
          }
        }
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
      // Try to get the replication port for server 1 only if it is required.
      if (!hasReplicationPort(ctx1))
      if (!replicationServer1Configured && configureReplicationServer1 &&
          !cancelled)
      {
        if (argParser.advancedArg.isPresent() &&
            configureReplicationDomain1)
        {
          // Only ask if the replication domain will be configured (if not
          // the replication server MUST be configured).
          try
          {
            configureReplicationServer1 = askConfirmation(
                INFO_REPLICATION_ENABLE_REPLICATION_SERVER1_PROMPT.get(),
                true, LOG);
          }
          catch (CLIException ce)
          {
            println(ce.getMessageObject());
            cancelled = true;
          }
        }
      }
      if (!cancelled &&
          !replicationServer1Configured && configureReplicationServer1)
      {
        boolean tryWithDefault = argParser.getReplicationPort1() != -1;
        while (replicationPort1 == -1)
@@ -968,6 +1013,24 @@
          println();
        }
      }
      if (!cancelled &&
          configureReplicationDomain1 &&
          configureReplicationServer1 &&
          argParser.advancedArg.isPresent())
      {
        // Only necessary to ask if the replication server will be configured
        try
        {
          configureReplicationDomain1 = askConfirmation(
              INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN1_PROMPT.get(),
              true, LOG);
        }
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
      // 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
      // enableReplication(EnableReplicationUserData) method.  Here we have
@@ -987,6 +1050,8 @@
    }
    uData.setReplicationPort1(replicationPort1);
    uData.setSecureReplication1(secureReplication1);
    uData.setConfigureReplicationServer1(configureReplicationServer1);
    uData.setConfigureReplicationDomain1(configureReplicationDomain1);
    firstServerCommandBuilder = new CommandBuilder(null);
    if (mustPrintCommandBuilder())
    {
@@ -1115,75 +1180,140 @@
    int replicationPort2 = -1;
    boolean secureReplication2 = argParser.isSecureReplication2();
    boolean configureReplicationServer2 =
      !argParser.noReplicationServer2Arg.isPresent();
    boolean configureReplicationDomain2 =
      !argParser.onlyReplicationServer2Arg.isPresent();
    if (ctx2 != null)
    {
      if (!hasReplicationPort(ctx2))
      int repPort2 = getReplicationPort(ctx2);
      boolean replicationServer2Configured = repPort2 > 0;
      if (replicationServer2Configured && !configureReplicationServer2)
      {
        boolean tryWithDefault = argParser.getReplicationPort2() != -1;
        while (replicationPort2 == -1)
        try
        {
          if (tryWithDefault)
          if (!askConfirmation(
              INFO_REPLICATION_SERVER_CONFIGURED_WARNING_PROMPT.
              get(ConnectionUtils.getHostPort(ctx2), repPort2), false, LOG))
          {
            replicationPort2 = argParser.getReplicationPort2();
            tryWithDefault = false;
          }
          else
          {
            replicationPort2 = askPort(
                INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT.get(),
                argParser.getDefaultReplicationPort2());
            println();
          }
          if (!argParser.skipReplicationPortCheck() && isLocalHost(host2))
          {
            if (!SetupUtils.canUseAsPort(replicationPort2))
            {
              println();
              println(getCannotBindToPortError(replicationPort2));
              println();
              replicationPort2 = -1;
            }
          }
          else
          {
            // This is something that we must do in any case... this test is
            // already included when we call SetupUtils.canUseAsPort
            if (replicationPort2 == port2)
            {
              println();
              println(
                  ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get(
                      host2, String.valueOf(replicationPort2)));
              replicationPort2 = -1;
            }
          }
          if (host1.equalsIgnoreCase(host2))
          {
            if ((replicationPort1 > 0) &&
                (replicationPort1 == replicationPort2))
            {
              println();
              println(ERR_REPLICATION_SAME_REPLICATION_PORT.get(
                      String.valueOf(replicationPort2), host1));
              println();
              replicationPort2 = -1;
            }
            cancelled = true;
          }
        }
        if (!secureReplication2)
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
      // Try to get the replication port for server 2 only if it is required.
      if (!replicationServer2Configured && configureReplicationServer2 &&
          !cancelled)
      {
        // Only ask if the replication domain will be configured (if not the
        // replication server MUST be configured).
        if (argParser.advancedArg.isPresent() &&
            configureReplicationDomain2)
        {
          try
          {
            secureReplication2 =
              askConfirmation(INFO_REPLICATION_ENABLE_SECURE2_PROMPT.get(
                  String.valueOf(replicationPort2)), false, LOG);
            configureReplicationServer2 = askConfirmation(
                INFO_REPLICATION_ENABLE_REPLICATION_SERVER2_PROMPT.get(),
                true, LOG);
          }
          catch (CLIException ce)
          {
            println(ce.getMessageObject());
            cancelled = true;
          }
          println();
        }
        if (!cancelled &&
            !replicationServer2Configured && configureReplicationServer2)
        {
          boolean tryWithDefault = argParser.getReplicationPort2() != -1;
          while (replicationPort2 == -1)
          {
            if (tryWithDefault)
            {
              replicationPort2 = argParser.getReplicationPort2();
              tryWithDefault = false;
            }
            else
            {
              replicationPort2 = askPort(
                  INFO_REPLICATION_ENABLE_REPLICATIONPORT2_PROMPT.get(),
                  argParser.getDefaultReplicationPort2());
              println();
            }
            if (!argParser.skipReplicationPortCheck() && isLocalHost(host2))
            {
              if (!SetupUtils.canUseAsPort(replicationPort2))
              {
                println();
                println(getCannotBindToPortError(replicationPort2));
                println();
                replicationPort2 = -1;
              }
            }
            else
            {
              // This is something that we must do in any case... this test is
              // already included when we call SetupUtils.canUseAsPort
              if (replicationPort2 == port2)
              {
                println();
                println(
                    ERR_REPLICATION_PORT_AND_REPLICATION_PORT_EQUAL.get(
                        host2, String.valueOf(replicationPort2)));
                replicationPort2 = -1;
              }
            }
            if (host1.equalsIgnoreCase(host2))
            {
              if ((replicationPort1 > 0) &&
                  (replicationPort1 == replicationPort2))
              {
                println();
                println(ERR_REPLICATION_SAME_REPLICATION_PORT.get(
                    String.valueOf(replicationPort2), host1));
                println();
                replicationPort2 = -1;
              }
            }
          }
          if (!secureReplication2)
          {
            try
            {
              secureReplication2 =
                askConfirmation(INFO_REPLICATION_ENABLE_SECURE2_PROMPT.get(
                    String.valueOf(replicationPort2)), false, LOG);
            }
            catch (CLIException ce)
            {
              println(ce.getMessageObject());
              cancelled = true;
            }
            println();
          }
        }
      }
      if (!cancelled &&
          configureReplicationDomain2 &&
          configureReplicationServer2 &&
          argParser.advancedArg.isPresent())
      {
        // Only necessary to ask if the replication server will be configured
        try
        {
          configureReplicationDomain2 = askConfirmation(
              INFO_REPLICATION_ENABLE_REPLICATION_DOMAIN2_PROMPT.get(),
              true, LOG);
        }
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
      // If the server contains an ADS. Try to load it and only load it: if
@@ -1200,6 +1330,8 @@
    }
    uData.setReplicationPort2(replicationPort2);
    uData.setSecureReplication2(secureReplication2);
    uData.setConfigureReplicationServer2(configureReplicationServer2);
    uData.setConfigureReplicationDomain2(configureReplicationDomain2);
    // If the adminUid and adminPwd are not set in the EnableReplicationUserData
    // object, that means that there are no administrators and that they
@@ -1265,7 +1397,7 @@
    if (!cancelled)
    {
      LinkedList<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true);
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, true, uData);
      cancelled = suffixes.isEmpty();
      uData.setBaseDNs(suffixes);
@@ -1385,18 +1517,99 @@
      ctx = aux[0];
    }
    if (!cancelled)
    boolean disableAll = argParser.disableAllArg.isPresent();
    boolean disableReplicationServer =
      argParser.disableReplicationServerArg.isPresent();
    if (disableAll ||
        (argParser.advancedArg.isPresent() &&
        argParser.getBaseDNs().isEmpty() &&
        !disableReplicationServer))
    {
      try
      {
        disableAll = askConfirmation(INFO_REPLICATION_PROMPT_DISABLE_ALL.get(),
          disableAll, LOG);
      }
      catch (CLIException ce)
      {
        println(ce.getMessageObject());
        cancelled = true;
      }
    }
    int repPort = getReplicationPort(ctx);
    if (!disableAll &&
        (argParser.advancedArg.isPresent() ||
        disableReplicationServer))
    {
      if (repPort > 0)
      {
        try
        {
          disableReplicationServer = askConfirmation(
              INFO_REPLICATION_PROMPT_DISABLE_REPLICATION_SERVER.get(repPort),
              disableReplicationServer,
              LOG);
        }
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
    }
    if (disableReplicationServer && repPort < 0)
    {
      disableReplicationServer = false;
      try
      {
        cancelled = askConfirmation(
            INFO_REPLICATION_PROMPT_NO_REPLICATION_SERVER_TO_DISABLE.get(
                ConnectionUtils.getHostPort(ctx)),
                false,
                LOG);
      }
      catch (CLIException ce)
      {
        println(ce.getMessageObject());
        cancelled = true;
      }
    }
    if (repPort > 0 && disableAll)
    {
      disableReplicationServer = true;
    }
    uData.setDisableAll(disableAll);
    uData.setDisableReplicationServer(disableReplicationServer);
    if (!cancelled && !disableAll)
    {
      LinkedList<String> suffixes = argParser.getBaseDNs();
      checkSuffixesForDisableReplication(suffixes, ctx, true);
      cancelled = suffixes.isEmpty();
      checkSuffixesForDisableReplication(suffixes, ctx, true,
          !disableReplicationServer, !disableReplicationServer);
      cancelled = suffixes.isEmpty() && !disableReplicationServer;
      uData.setBaseDNs(suffixes);
      if (!uData.disableReplicationServer() && repPort > 0 &&
          disableAllBaseDns(ctx, uData) && !argParser.advancedArg.isPresent())
      {
        try
        {
          uData.setDisableReplicationServer(askConfirmation(
         INFO_REPLICATION_DISABLE_ALL_SUFFIXES_DISABLE_REPLICATION_SERVER.get(
             ConnectionUtils.getHostPort(ctx), repPort), true, LOG));
        }
        catch (CLIException ce)
        {
          println(ce.getMessageObject());
          cancelled = true;
        }
      }
    }
    if (!cancelled)
    {
      // Ask for confirmation to disable.
      // Ask for confirmation to disable if not already done.
      boolean disableADS = false;
      boolean disableSchema = false;
      for (String dn : uData.getBaseDNs())
@@ -1445,16 +1658,22 @@
        println();
        try
        {
          if (disableAllBaseDns(ctx, uData))
          if (uData.disableAll())
          {
            cancelled = !askConfirmation(
                INFO_REPLICATION_CONFIRM_DISABLE_LAST_SUFFIXES.get(), true,
                LOG);
            // Another confirmation is redundant: we already asked the user...
          }
          else
          {
            cancelled = !askConfirmation(
                INFO_REPLICATION_CONFIRM_DISABLE_GENERIC.get(), true, LOG);
            if (!uData.getBaseDNs().isEmpty())
            {
               cancelled = !askConfirmation(
                INFO_REPLICATION_CONFIRM_DISABLE_GENERIC.get(), true,
                LOG);
            }
            else
            {
              // Another confirmation for the replication server is redundant.
            }
          }
        }
        catch (CLIException ce)
@@ -2312,6 +2531,14 @@
    uData.setReplicationPort2(replicationPort2);
    uData.setSecureReplication2(argParser.isSecureReplication2());
    uData.setReplicateSchema(!argParser.noSchemaReplication());
    uData.setConfigureReplicationDomain1(
        !argParser.onlyReplicationServer1Arg.isPresent());
    uData.setConfigureReplicationDomain2(
        !argParser.onlyReplicationServer2Arg.isPresent());
    uData.setConfigureReplicationServer1(
        !argParser.noReplicationServer1Arg.isPresent());
    uData.setConfigureReplicationServer2(
        !argParser.noReplicationServer2Arg.isPresent());
  }
  /**
@@ -2371,6 +2598,10 @@
    int port = getValue(argParser.getPortToDisable(),
        argParser.getDefaultPortToDisable());
    uData.setPort(port);
    uData.setDisableAll(argParser.disableAllArg.isPresent());
    uData.setDisableReplicationServer(
        argParser.disableReplicationServerArg.isPresent());
  }
  /**
@@ -2659,7 +2890,7 @@
                    println();
                    println(
                        ERR_ERROR_CONNECTING_TO_SERVER_PROMPT_AGAIN.get(
                        host+":"+port, t.getMessage()));
                          getServerRepresentation(host, port), t.getMessage()));
                    LOG.log(Level.WARNING, "Complete error stack:", t);
                    println();
                  }
@@ -3022,7 +3253,7 @@
    }
    catch (NamingException ne)
    {
      String hostPort = host1+":"+port1;
      String hostPort = getServerRepresentation(host1, port1);
      errorMessages.add(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3035,7 +3266,7 @@
    }
    catch (NamingException ne)
    {
      String hostPort = host2+":"+port2;
      String hostPort = getServerRepresentation(host2, port2);
      errorMessages.add(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3114,7 +3345,7 @@
    if (errorMessages.isEmpty())
    {
      LinkedList<String> suffixes = uData.getBaseDNs();
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false);
      checkSuffixesForEnableReplication(suffixes, ctx1, ctx2, false, uData);
      if (!suffixes.isEmpty())
      {
        uData.setBaseDNs(suffixes);
@@ -3134,6 +3365,27 @@
                t);
          }
        }
        if (!isInteractive())
        {
          int repPort1 = getReplicationPort(ctx1);
          int repPort2 = getReplicationPort(ctx2);
          if (!uData.configureReplicationServer1() && repPort1 > 0)
          {
            println(INFO_REPLICATION_SERVER_CONFIGURED_WARNING.get(
                ConnectionUtils.getHostPort(ctx1), repPort1));
            println();
          }
          if (!uData.configureReplicationServer2() && repPort2 > 0)
          {
            println(INFO_REPLICATION_SERVER_CONFIGURED_WARNING.get(
                ConnectionUtils.getHostPort(ctx2), repPort2));
            println();
          }
        }
        try
        {
          updateConfiguration(ctx1, ctx2, uData);
@@ -3232,7 +3484,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostName()+":"+uData.getPort();
      String hostPort =
        getServerRepresentation(uData.getHostName(), uData.getPort());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3244,10 +3497,31 @@
      printProgress(formatter.getFormattedDone());
      printlnProgress();
      LinkedList<String> suffixes = uData.getBaseDNs();
      checkSuffixesForDisableReplication(suffixes, ctx, false);
      if (!suffixes.isEmpty())
      checkSuffixesForDisableReplication(suffixes, ctx, false,
          !uData.disableReplicationServer(), !uData.disableReplicationServer());
      if (!suffixes.isEmpty() || uData.disableReplicationServer() ||
          uData.disableAll())
      {
        uData.setBaseDNs(suffixes);
        if (!isInteractive())
        {
          boolean hasReplicationPort = hasReplicationPort(ctx);
          if (uData.disableAll() && hasReplicationPort)
          {
            uData.setDisableReplicationServer(true);
          }
          else if (uData.disableReplicationServer() && !hasReplicationPort &&
              !uData.disableAll())
          {
            uData.setDisableReplicationServer(false);
            println(
                INFO_REPLICATION_WARNING_NO_REPLICATION_SERVER_TO_DISABLE.get(
                    ConnectionUtils.getHostPort(ctx)));
            println();
          }
        }
        if (mustPrintCommandBuilder())
        {
          try
@@ -3263,6 +3537,18 @@
                t);
          }
        }
        if (!isInteractive() && !uData.disableReplicationServer() &&
            !uData.disableAll() && disableAllBaseDns(ctx, uData))
        {
          // 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(
               ConnectionUtils.getHostPort(ctx),
               argParser.disableReplicationServerArg.getLongIdentifier(),
               argParser.disableAllArg.getLongIdentifier()));
        }
        try
        {
          updateConfiguration(ctx, uData);
@@ -3321,7 +3607,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostName()+":"+uData.getPort();
      String hostPort =
        getServerRepresentation(uData.getHostName(), uData.getPort());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3386,7 +3673,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostNameSource()+":"+uData.getPortSource();
      String hostPort = getServerRepresentation(uData.getHostNameSource(),
          uData.getPortSource());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3402,8 +3690,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostNameDestination()+":"+
      uData.getPortDestination();
      String hostPort = getServerRepresentation(uData.getHostNameDestination(),
      uData.getPortDestination());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3510,7 +3798,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostName()+":"+uData.getPort();
      String hostPort =
        getServerRepresentation(uData.getHostName(), uData.getPort());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3606,7 +3895,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostName()+":"+uData.getPort();
      String hostPort =
        getServerRepresentation(uData.getHostName(), uData.getPort());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3721,7 +4011,8 @@
    }
    catch (NamingException ne)
    {
      String hostPort = uData.getHostName()+":"+uData.getPort();
      String hostPort =
        getServerRepresentation(uData.getHostName(), uData.getPort());
      println();
      println(getMessageForException(ne, hostPort));
      LOG.log(Level.SEVERE, "Complete error stack:", ne);
@@ -3808,23 +4099,69 @@
   * @param ctx2 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
   * but it is assumed that it contains information about whether the
   * replication domains must be configured or not.
   */
  private void checkSuffixesForEnableReplication(Collection<String> suffixes,
      InitialLdapContext ctx1, InitialLdapContext ctx2,
      boolean interactive)
      boolean interactive, EnableReplicationUserData uData)
  {
    TreeSet<String> availableSuffixes =
      new TreeSet<String>(getCommonSuffixes(ctx1, ctx2,
          SuffixRelationType.NOT_FULLY_REPLICATED));
    TreeSet<String> alreadyReplicatedSuffixes =
      new TreeSet<String>(getCommonSuffixes(ctx1, ctx2,
          SuffixRelationType.FULLY_REPLICATED));
    TreeSet<String> availableSuffixes;
    TreeSet<String> alreadyReplicatedSuffixes;
    if (uData.configureReplicationDomain1() &&
        uData.configureReplicationDomain2())
    {
      availableSuffixes =
        new TreeSet<String>(getCommonSuffixes(ctx1, ctx2,
            SuffixRelationType.NOT_FULLY_REPLICATED));
      alreadyReplicatedSuffixes =
        new TreeSet<String>(getCommonSuffixes(ctx1, ctx2,
            SuffixRelationType.FULLY_REPLICATED));
    }
    else if (uData.configureReplicationDomain1())
    {
      availableSuffixes = new TreeSet<String>();
      alreadyReplicatedSuffixes = new TreeSet<String>();
      updateAvailableAndReplicatedSuffixesForOneDomain(ctx1, ctx2,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
    else if (uData.configureReplicationDomain2())
    {
      availableSuffixes = new TreeSet<String>();
      alreadyReplicatedSuffixes = new TreeSet<String>();
      updateAvailableAndReplicatedSuffixesForOneDomain(ctx2, ctx1,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
    else
    {
      availableSuffixes = new TreeSet<String>();
      alreadyReplicatedSuffixes = new TreeSet<String>();
      updateAvailableAndReplicatedSuffixesForNoDomain(ctx1, ctx2,
          availableSuffixes, alreadyReplicatedSuffixes);
    }
    if (availableSuffixes.size() == 0)
    {
      println();
      println(
      if (!uData.configureReplicationDomain1() &&
          !uData.configureReplicationDomain1() &&
          alreadyReplicatedSuffixes.isEmpty())
      {
        // Use a clarifying message: there is no replicated base DN.
        println(
            ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION_NO_DOMAIN.get());
      }
      else
      {
        println(
          ERR_NO_SUFFIXES_AVAILABLE_TO_ENABLE_REPLICATION.get());
      }
      LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs();
      TreeSet<String> userProvidedReplicatedSuffixes = new TreeSet<String>();
@@ -3973,9 +4310,14 @@
   * @param ctx 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.
   * @param areSuffixRequired whether the user must provide base DNs or not
   * (if it is <CODE>false</CODE> the user will be proposed the suffixes
   * only once).
   */
  private void checkSuffixesForDisableReplication(Collection<String> suffixes,
      InitialLdapContext ctx, boolean interactive)
      InitialLdapContext ctx, boolean interactive, boolean displayErrors,
      boolean areSuffixRequired)
  {
    TreeSet<String> availableSuffixes = new TreeSet<String>();
    TreeSet<String> notReplicatedSuffixes = new TreeSet<String>();
@@ -3995,8 +4337,11 @@
    }
    if (availableSuffixes.size() == 0)
    {
      println();
      println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get());
      if (displayErrors)
      {
        println();
        println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get());
      }
      LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs();
      TreeSet<String> userProvidedNotReplicatedSuffixes =
        new TreeSet<String>();
@@ -4010,7 +4355,7 @@
          }
        }
      }
      if (userProvidedNotReplicatedSuffixes.size() > 0)
      if (userProvidedNotReplicatedSuffixes.size() > 0 && displayErrors)
      {
        println();
        println(INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get(
@@ -4059,14 +4404,14 @@
      }
      suffixes.removeAll(notFound);
      suffixes.removeAll(alreadyNotReplicated);
      if (notFound.size() > 0)
      if (notFound.size() > 0 && displayErrors)
      {
        println();
        println(ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND.get(
                Utils.getStringFromCollection(notFound,
                    Constants.LINE_SEPARATOR)));
      }
      if (alreadyNotReplicated.size() > 0)
      if (alreadyNotReplicated.size() > 0 && displayErrors)
      {
        println();
        println(INFO_ALREADY_NOT_REPLICATED_SUFFIXES.get(
@@ -4092,14 +4437,20 @@
          {
            // In interactive mode we do not propose to manage the
            // administration suffix.
            println();
            println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get());
            if (displayErrors)
            {
              println();
              println(ERR_NO_SUFFIXES_AVAILABLE_TO_DISABLE_REPLICATION.get());
            }
            break;
          }
          else
          {
            println();
            println(ERR_NO_SUFFIXES_SELECTED_TO_DISABLE.get());
            if (areSuffixRequired)
            {
              println();
              println(ERR_NO_SUFFIXES_SELECTED_TO_DISABLE.get());
            }
            for (String dn : availableSuffixes)
            {
              if (!Utils.areDnsEqual(dn,
@@ -4110,7 +4461,8 @@
                try
                {
                  if (askConfirmation(
                      INFO_REPLICATION_DISABLE_SUFFIX_PROMPT.get(dn), true,LOG))
                      INFO_REPLICATION_DISABLE_SUFFIX_PROMPT.get(dn), true,
                      LOG))
                  {
                    suffixes.add(dn);
                  }
@@ -4129,6 +4481,10 @@
            suffixes.clear();
            break;
          }
          if (!areSuffixRequired)
          {
            break;
          }
        }
      }
    }
@@ -4577,6 +4933,57 @@
                    Constants.LINE_SEPARATOR).toString()));
      }
    }
    // Check whether there is more than one replication server in the
    // topology.
    Set<String> baseDNsWithOneReplicationServer = new TreeSet<String>();
    Set<String> baseDNsWithNoReplicationServer = new TreeSet<String>();
    updateBaseDnsWithNotEnoughReplicationServer(adsCtx1, adsCtx2, uData,
       baseDNsWithNoReplicationServer, baseDNsWithOneReplicationServer);
    if (!baseDNsWithNoReplicationServer.isEmpty())
    {
      Message errorMsg =
        ERR_REPLICATION_NO_REPLICATION_SERVER.get(
            Utils.getStringFromCollection(baseDNsWithNoReplicationServer,
                Constants.LINE_SEPARATOR));
      throw new ReplicationCliException(
          errorMsg,
          ReplicationCliReturnCode.ERROR_USER_DATA, null);
    }
    else if (!baseDNsWithOneReplicationServer.isEmpty())
    {
      if (isInteractive())
      {
        Message confirmMsg =
          INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_CONFIRM.get(
              Utils.getStringFromCollection(baseDNsWithOneReplicationServer,
                  Constants.LINE_SEPARATOR));
        try
        {
          if (!confirmAction(confirmMsg, false))
          {
            throw new ReplicationCliException(
                ERR_REPLICATION_USER_CANCELLED.get(),
                ReplicationCliReturnCode.USER_CANCELLED, null);
          }
        }
        catch (Throwable t)
        {
          throw new ReplicationCliException(
              ERR_REPLICATION_USER_CANCELLED.get(),
              ReplicationCliReturnCode.USER_CANCELLED, t);
        }
      }
      else
      {
        Message warningMsg =
          INFO_REPLICATION_ONLY_ONE_REPLICATION_SERVER_WARNING.get(
              Utils.getStringFromCollection(baseDNsWithOneReplicationServer,
                  Constants.LINE_SEPARATOR));
        println(warningMsg);
        println();
      }
    }
    // These are used to identify which server we use to initialize
    // the contents of the other server (if any).
@@ -4828,20 +5235,20 @@
      twoReplServers.add(server1.getReplicationServerHostPort());
      usedReplicationServerIds.add(server1.getReplicationServerId());
    }
    else
    else if (uData.configureReplicationServer1())
    {
      twoReplServers.add(
          ConnectionUtils.getHostName(ctx1)+":"+uData.getReplicationPort1());
      twoReplServers.add(getReplicationServer(
          ConnectionUtils.getHostName(ctx1), uData.getReplicationPort1()));
    }
    if (server2.isReplicationServer())
    {
      twoReplServers.add(server2.getReplicationServerHostPort());
      usedReplicationServerIds.add(server2.getReplicationServerId());
    }
    else
    else if (uData.configureReplicationServer2())
    {
      twoReplServers.add(
          ConnectionUtils.getHostName(ctx2)+":"+uData.getReplicationPort2());
      twoReplServers.add(getReplicationServer(
          ConnectionUtils.getHostName(ctx2), uData.getReplicationPort2()));
    }
    for (String baseDN : uData.getBaseDNs())
@@ -4879,7 +5286,7 @@
    }
    Set<String> alreadyConfiguredReplicationServers = new HashSet<String>();
    if (!server1.isReplicationServer())
    if (!server1.isReplicationServer() && uData.configureReplicationServer1())
    {
      try
      {
@@ -4895,7 +5302,7 @@
            ERROR_CONFIGURING_REPLICATIONSERVER, ode);
      }
    }
    else
    else if (server1.isReplicationServer())
    {
      try
      {
@@ -4923,7 +5330,7 @@
      }
    }
    alreadyConfiguredReplicationServers.add(server1.getId());
    if (!server2.isReplicationServer())
    if (!server2.isReplicationServer() && uData.configureReplicationServer2())
    {
      try
      {
@@ -4939,7 +5346,7 @@
            ERROR_CONFIGURING_REPLICATIONSERVER, ode);
      }
    }
    else
    else if (server2.isReplicationServer())
    {
      try
      {
@@ -4974,28 +5381,37 @@
      Set<Integer> usedIds = hmUsedReplicationDomainIds.get(baseDN);
      Set<String> alreadyConfiguredServers = new HashSet<String>();
      try
      if (uData.configureReplicationDomain1() ||
          Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN()))
      {
        configureToReplicateBaseDN(ctx1, baseDN, repServers, usedIds);
      }
      catch (OpenDsException ode)
      {
        Message msg = getMessageForEnableException(ode,
            ConnectionUtils.getHostPort(ctx1), baseDN);
        throw new ReplicationCliException(msg,
            ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
        try
        {
          configureToReplicateBaseDN(ctx1, baseDN, repServers, usedIds);
        }
        catch (OpenDsException ode)
        {
          Message msg = getMessageForEnableException(ode,
              ConnectionUtils.getHostPort(ctx1), baseDN);
          throw new ReplicationCliException(msg,
              ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
        }
      }
      alreadyConfiguredServers.add(server1.getId());
      try
      if (uData.configureReplicationDomain2() ||
          Utils.areDnsEqual(baseDN, ADSContext.getAdministrationSuffixDN()))
      {
        configureToReplicateBaseDN(ctx2, baseDN, repServers, usedIds);
      }
      catch (OpenDsException ode)
      {
        Message msg = getMessageForEnableException(ode,
            ConnectionUtils.getHostPort(ctx2), baseDN);
        throw new ReplicationCliException(msg,
            ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
        try
        {
          configureToReplicateBaseDN(ctx2, baseDN, repServers, usedIds);
        }
        catch (OpenDsException ode)
        {
          Message msg = getMessageForEnableException(ode,
              ConnectionUtils.getHostPort(ctx2), baseDN);
          throw new ReplicationCliException(msg,
              ERROR_ENABLING_REPLICATION_ON_BASEDN, ode);
        }
      }
      alreadyConfiguredServers.add(server2.getId());
@@ -5031,7 +5447,7 @@
    }
    // If we must initialize the schema do so.
    if (mustInitializeSchema(server1, server2))
    if (mustInitializeSchema(server1, server2, uData))
    {
      if (argParser.useSecondServerAsSchemaSource())
      {
@@ -5133,6 +5549,196 @@
      }
    }
    boolean disableReplicationServer = false;
    if (server.isReplicationServer() &&
        (uData.disableReplicationServer() || uData.disableAll()))
    {
      disableReplicationServer = true;
    }
    if ((cache != null) && disableReplicationServer)
    {
      String replicationServer = server.getReplicationServerHostPort();
      // Figure out if this is the last replication server for a given
      // topology (containing a different replica) or there will be only
      // another replication server left (single point of failure).
      Set<SuffixDescriptor> lastRepServer =
        new TreeSet<SuffixDescriptor>(new SuffixComparator());
      Set<SuffixDescriptor> beforeLastRepServer =
        new TreeSet<SuffixDescriptor>(new SuffixComparator());
      for (SuffixDescriptor suffix : cache.getSuffixes())
      {
        if (Utils.areDnsEqual(suffix.getDN(),
            ADSContext.getAdministrationSuffixDN()) ||
            Utils.areDnsEqual(suffix.getDN(), Constants.SCHEMA_DN))
        {
          // Do not display these suffixes.
          continue;
        }
        Set<String> repServers = suffix.getReplicationServers();
        if (repServers.size() <= 2)
        {
          boolean found = false;
          for (String repServer : repServers)
          {
            if (repServer.equalsIgnoreCase(replicationServer))
            {
              found = true;
              break;
            }
          }
          if (found)
          {
            if (repServers.size() == 2)
            {
              beforeLastRepServer.add(suffix);
            }
            else
            {
              lastRepServer.add(suffix);
            }
          }
        }
      }
      // Inform the user
      if (beforeLastRepServer.size() > 0)
      {
        LinkedHashSet<String> baseDNs = new LinkedHashSet<String>();
        for (SuffixDescriptor suffix : beforeLastRepServer)
        {
          if (!Utils.areDnsEqual(suffix.getDN(),
              ADSContext.getAdministrationSuffixDN()) &&
              !Utils.areDnsEqual(suffix.getDN(), Constants.SCHEMA_DN))
          {
            // Do not display these suffixes.
            baseDNs.add(suffix.getDN());
          }
        }
        if (!baseDNs.isEmpty())
        {
          String arg =
            Utils.getStringFromCollection(baseDNs, Constants.LINE_SEPARATOR);
          if (!isInteractive())
          {
            println(INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE.get(arg));
          }
          else
          {
            try
            {
              if (!askConfirmation(
                  INFO_DISABLE_REPLICATION_ONE_POINT_OF_FAILURE_PROMPT.get(arg),
                      false, LOG))
              {
                throw new ReplicationCliException(
                    ERR_REPLICATION_USER_CANCELLED.get(),
                    ReplicationCliReturnCode.USER_CANCELLED, null);
              }
            }
            catch (CLIException ce)
            {
              println(ce.getMessageObject());
              throw new ReplicationCliException(
                  ERR_REPLICATION_USER_CANCELLED.get(),
                  ReplicationCliReturnCode.USER_CANCELLED, null);
            }
          }
        }
      }
      if (lastRepServer.size() > 0)
      {
        // Check that there are other replicas and that this message, really
        // makes sense to be displayed.
        LinkedHashSet<String> suffixArg = new LinkedHashSet<String>();
        for (SuffixDescriptor suffix : lastRepServer)
        {
          boolean baseDNSpecified = false;
          for (String baseDN : uData.getBaseDNs())
          {
            if (Utils.areDnsEqual(baseDN,
                ADSContext.getAdministrationSuffixDN()) ||
                Utils.areDnsEqual(baseDN, Constants.SCHEMA_DN))
            {
              // Do not display these suffixes.
              continue;
            }
            if (Utils.areDnsEqual(baseDN, suffix.getDN()))
            {
              baseDNSpecified = true;
              break;
            }
          }
          if (!baseDNSpecified)
          {
            Set<ServerDescriptor> servers =
              new TreeSet<ServerDescriptor>(new ServerComparator());
            for (ReplicaDescriptor replica : suffix.getReplicas())
            {
              servers.add(replica.getServer());
            }
            suffixArg.add(getSuffixDisplay(suffix.getDN(), servers));
          }
          else
          {
            // Check that there are other replicas.
            if (suffix.getReplicas().size() > 1)
            {
              // If there is just one replica, it is the one in this server.
              Set<ServerDescriptor> servers =
                new TreeSet<ServerDescriptor>(new ServerComparator());
              for (ReplicaDescriptor replica : suffix.getReplicas())
              {
                if (!areSameServer(replica.getServer(), server))
                {
                  servers.add(replica.getServer());
                }
              }
              if (!servers.isEmpty())
              {
                suffixArg.add(getSuffixDisplay(suffix.getDN(), servers));
              }
            }
          }
        }
        if (!suffixArg.isEmpty())
        {
          String arg =
            Utils.getStringFromCollection(suffixArg, Constants.LINE_SEPARATOR);
          if (!isInteractive())
          {
            println(INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE.get(arg));
          }
          else
          {
            try
            {
              if (!askConfirmation(
                  INFO_DISABLE_REPLICATION_DISABLE_IN_REMOTE_PROMPT.get(arg),
                      false, LOG))
              {
                throw new ReplicationCliException(
                    ERR_REPLICATION_USER_CANCELLED.get(),
                    ReplicationCliReturnCode.USER_CANCELLED, null);
              }
            }
            catch (CLIException ce)
            {
              println(ce.getMessageObject());
              throw new ReplicationCliException(
                  ERR_REPLICATION_USER_CANCELLED.get(),
                  ReplicationCliReturnCode.USER_CANCELLED, null);
            }
          }
        }
      }
    }
    /**
     * Try to figure out if we must explicitly disable replication on
     * cn=admin data and cn=schema.
@@ -5160,18 +5766,13 @@
      }
    }
    boolean recreateServerKey = false ;
    Object keyId = null ;
    Object certValue = null ;
    if (disableAllBaseDns)
    if (disableAllBaseDns &&
        (disableReplicationServer || !server.isReplicationServer()))
    {
      // Unregister the server from the ADS
      // Unregister the server from the ADS if no other server has dependencies
      // with it (no replicated base DNs and no replication server).
      server.updateAdsPropertiesWithServerProperties();
      recreateServerKey = true ;
      keyId = server.getAdsProperties().
          get(ADSContext.ServerProperty.INSTANCE_KEY_ID);
      certValue = server.getAdsProperties().
          get(ADSContext.ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE);
      try
      {
        adsCtx.unregisterServer(server.getAdsProperties());
@@ -5183,7 +5784,6 @@
        catch (Throwable t)
        {
        }
        recreateServerKey = true ;
      }
      catch (ADSContextException adce)
      {
@@ -5196,10 +5796,29 @@
      }
    }
    if (disableAllBaseDns)
    Set<String> suffixesToDisable = new HashSet<String>();
    if (uData.disableAll())
    {
      forceDisableSchema = schemaReplicated;
      forceDisableADS = adsReplicated;
      suffixesToDisable.clear();
      for (ReplicaDescriptor replica : server.getReplicas())
      {
        if (replica.isReplicated())
        {
          suffixesToDisable.add(replica.getSuffix().getDN());
        }
      }
    }
    else
    {
      suffixesToDisable.addAll(uData.getBaseDNs());
      if (disableAllBaseDns &&
          (disableReplicationServer || !server.isReplicationServer()))
      {
        forceDisableSchema = schemaReplicated;
        forceDisableADS = adsReplicated;
      }
      for (String dn : uData.getBaseDNs())
      {
        if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(), dn))
@@ -5213,18 +5832,24 @@
          forceDisableSchema = false;
        }
      }
    }
    Set<String> suffixesToDisable = new HashSet<String>(uData.getBaseDNs());
    if (forceDisableSchema)
    {
      suffixesToDisable.add(Constants.SCHEMA_DN);
    }
    if (forceDisableADS)
    {
      suffixesToDisable.add(ADSContext.getAdministrationSuffixDN());
      if (forceDisableSchema)
      {
        suffixesToDisable.add(Constants.SCHEMA_DN);
      }
      if (forceDisableADS)
      {
        suffixesToDisable.add(ADSContext.getAdministrationSuffixDN());
      }
    }
    String replicationServerHostPort = server.getReplicationServerHostPort();
    String replicationServerHostPort = null;
    if (server.isReplicationServer())
    {
      replicationServerHostPort = server.getReplicationServerHostPort();
    }
    boolean replicationServerDisabled = false;
    for (String baseDN : suffixesToDisable)
    {
      try
@@ -5244,7 +5869,8 @@
    {
      Set<ServerDescriptor> serversToUpdate =
        new LinkedHashSet<ServerDescriptor>();
      for (String baseDN : suffixesToDisable)
      Set<String> baseDNsToUpdate = new HashSet<String>(suffixesToDisable);
      for (String baseDN : baseDNsToUpdate)
      {
        SuffixDescriptor suffix = getSuffix(baseDN, cache, server);
        if (suffix != null)
@@ -5255,18 +5881,45 @@
          }
        }
      }
      if (disableReplicationServer)
      {
        // Find references in all servers.
        Set<SuffixDescriptor> suffixes = cache.getSuffixes();
        for (SuffixDescriptor suffix : suffixes)
        {
          boolean found = false;
          for (String repServer : suffix.getReplicationServers())
          {
            found = repServer.equalsIgnoreCase(replicationServerHostPort);
            if (found)
            {
              break;
            }
          }
          if (found)
          {
            baseDNsToUpdate.add(suffix.getDN());
            for (ReplicaDescriptor replica : suffix.getReplicas())
            {
              serversToUpdate.add(replica.getServer());
            }
          }
        }
      }
      String bindDn = ConnectionUtils.getBindDN(ctx);
      String pwd = ConnectionUtils.getBindPassword(ctx);
      for (ServerDescriptor s : serversToUpdate)
      {
        removeReferencesInServer(s, replicationServerHostPort, bindDn, pwd,
            suffixesToDisable, disableAllBaseDns, getPreferredConnections(ctx));
            baseDNsToUpdate, disableReplicationServer,
            getPreferredConnections(ctx));
      }
      if (disableAllBaseDns)
      if (disableReplicationServer)
      {
        // Disable replication server
        disableReplicationServer(ctx);
        replicationServerDisabled = true;
        // Wait to be sure that changes are taken into account and reset the
        // contents of the ADS.
        try
@@ -5276,6 +5929,9 @@
        catch (Throwable t)
        {
        }
      }
      else if (disableReplicationServer)
      {
        for (ServerDescriptor s: serversToUpdate)
        {
          try
@@ -5284,7 +5940,7 @@
          }
          catch (ADSContextException adce)
          {
            LOG.log(Level.INFO, "Error unregistering server: "+
            LOG.log(Level.WARNING, "Error unregistering server: "+
                s.getAdsProperties(), adce);
            println();
            println(
@@ -5294,24 +5950,43 @@
        }
      }
    }
    if (recreateServerKey)
    if (disableReplicationServer && !replicationServerDisabled)
    {
      Map<ServerProperty, Object> serverProperties =
        new HashMap<ServerProperty, Object>();
      serverProperties.put(ServerProperty.INSTANCE_KEY_ID, keyId);
      serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE,
          certValue);
      LdapName ldapName = null ;
      ADSContextHelper helper = new ADSContextHelper();
      // This can happen if we could not retrieve the TopologyCache
      disableReplicationServer(ctx);
      replicationServerDisabled = true;
    }
    if (uData.disableAll())
    {
      try
      {
        helper.registerInstanceKeyCertificate(
            adsCtx.getDirContext(),serverProperties,ldapName);
        // Delete all contents from ADSContext.
        printProgress(formatter.getFormattedWithPoints(
            INFO_REPLICATION_DISABLE_ADS_CONTENTS.get()));
        adsCtx.removeAdminData();
        String adminBackendName = null;
        for (ReplicaDescriptor replica : server.getReplicas())
        {
          if (Utils.areDnsEqual(ADSContext.getAdministrationSuffixDN(),
              replica.getSuffix().getDN()))
          {
            adminBackendName = replica.getBackendName();
            break;
          }
        }
        adsCtx.createAdminData(adminBackendName);
        printProgress(formatter.getFormattedDone());
      }
      catch (ADSContextException e)
      catch (ADSContextException adce)
      {
        LOG.log(Level.SEVERE, "Error resetting contents of cn=admin data: "+
            adce, adce);
        println();
        println(
            ERR_REPLICATION_UPDATING_ADS.get(adce.getMessage()));
        println();
      }
    }
  }
@@ -5383,13 +6058,15 @@
      new LinkedList<Set<ReplicaDescriptor>>();
    boolean oneReplicated = false;
    boolean displayAll = userBaseDNs.isEmpty();
    for (SuffixDescriptor suffix : cache.getSuffixes())
    {
      String dn = suffix.getDN();
      // If no base DNs where specified display all the base DNs but the schema
      // and cn=admin data.
      boolean found = userBaseDNs.isEmpty() &&
      boolean found = displayAll &&
      !Utils.areDnsEqual(dn, ADSContext.getAdministrationSuffixDN()) &&
      !Utils.areDnsEqual(dn, Constants.SCHEMA_DN) &&
      !Utils.areDnsEqual(dn, Constants.REPLICATION_CHANGES_DN);
@@ -5440,18 +6117,40 @@
      }
    }
    if (replicaLists.isEmpty())
    if (!oneReplicated)
    {
      printProgress(INFO_REPLICATION_STATUS_NO_BASEDNS.get());
      printlnProgress();
      if (displayAll)
      {
        // Maybe there are some replication server configured...
        SortedSet<ServerDescriptor> rServers =
          new TreeSet<ServerDescriptor>(new ReplicationServerComparator());
        for (ServerDescriptor server : cache.getServers())
        {
          if (server.isReplicationServer())
          {
            rServers.add(server);
          }
        }
        if (!rServers.isEmpty())
        {
          displayStatus(rServers, uData.isScriptFriendly(),
              getPreferredConnections(ctx));
        }
      }
      else
      {
        printProgress(INFO_REPLICATION_STATUS_NO_BASEDNS.get());
        printlnProgress();
      }
    }
    else
    if (!replicaLists.isEmpty())
    {
      LinkedList<Set<ReplicaDescriptor>> orderedReplicaLists =
        new LinkedList<Set<ReplicaDescriptor>>();
      for (Set<ReplicaDescriptor> replicas1 : replicaLists)
      for (Set<ReplicaDescriptor> replicas : replicaLists)
      {
        String dn1 = replicas1.iterator().next().getSuffix().getDN();
        String dn1 = replicas.iterator().next().getSuffix().getDN();
        boolean inserted = false;
        for (int i=0; i<orderedReplicaLists.size() && !inserted; i++)
        {
@@ -5459,25 +6158,42 @@
            orderedReplicaLists.get(i).iterator().next().getSuffix().getDN();
          if (dn1.compareTo(dn2) < 0)
          {
            orderedReplicaLists.add(i, replicas1);
            orderedReplicaLists.add(i, replicas);
            inserted = true;
          }
        }
        if (!inserted)
        {
          orderedReplicaLists.add(replicas1);
          orderedReplicaLists.add(replicas);
        }
      }
      Set<ReplicaDescriptor> replicasWithNoReplicationServer =
        new HashSet<ReplicaDescriptor>();
      Set<ServerDescriptor> serversWithNoReplica =
        new HashSet<ServerDescriptor>();
      for (Set<ReplicaDescriptor> replicas : orderedReplicaLists)
      {
        printlnProgress();
        displayStatus(replicas, uData.isScriptFriendly(),
            getPreferredConnections(ctx));
            getPreferredConnections(ctx), cache.getServers(),
            replicasWithNoReplicationServer, serversWithNoReplica);
      }
      if (oneReplicated && !uData.isScriptFriendly())
      {
        printlnProgress();
        printProgress(INFO_REPLICATION_STATUS_REPLICATED_LEGEND.get());
        if (!replicasWithNoReplicationServer.isEmpty())
        {
          printlnProgress();
          printProgress(
              INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LEGEND.get());
        }
        if (!replicasWithNoReplicationServer.isEmpty())
        {
          printlnProgress();
          printProgress(
              INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LEGEND.get());
        }
        printlnProgress();
      }
    }
@@ -5487,18 +6203,30 @@
   * Displays the replication status of the replicas provided.  The code assumes
   * that all the replicas have the same baseDN and that if they are replicated
   * all the replicas are replicated with each other.
   * Note: the code assumes that all the objects come from the same read of the
   * topology cache.  So comparisons in terms of pointers can be made.
   * @param replicas the list of replicas that we are trying to display.
   * @param cnx the preferred connections used to connect to the server.
   * @param scriptFriendly wheter to display it on script-friendly mode or not.
   * @param servers all the servers configured in the topology.
   * @param replicasWithNoReplicationServer the set of replicas that will be
   * updated with all the replicas that have no replication server.
   * @param serversWithNoReplica the set of servers that will be updated with
   * all the servers that act as replication server in the topology but have
   * no replica.
   */
  private void displayStatus(Set<ReplicaDescriptor> replicas,
      boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx)
      boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx,
      Set<ServerDescriptor> servers,
      Set<ReplicaDescriptor> replicasWithNoReplicationServer,
      Set<ServerDescriptor> serversWithNoReplica)
  {
    boolean isReplicated = false;
    Set<ReplicaDescriptor> orderedReplicas =
      new LinkedHashSet<ReplicaDescriptor>();
    Set<String> hostPorts = new TreeSet<String>();
    Set<ServerDescriptor> notAddedReplicationServers =
      new TreeSet<ServerDescriptor>(new ReplicationServerComparator());
    for (ReplicaDescriptor replica : replicas)
    {
      if (replica.isReplicated())
@@ -5517,6 +6245,41 @@
        }
      }
    }
    for (ServerDescriptor server : servers)
    {
      if (server.isReplicationServer())
      {
        boolean isDomain = false;
        boolean isRepServer = false;
        String replicationServer = server.getReplicationServerHostPort();
        for (ReplicaDescriptor replica : replicas)
        {
          if (!isRepServer)
          {
            Set<String> repServers = replica.getReplicationServers();
            for (String repServer : repServers)
            {
              if (replicationServer.equalsIgnoreCase(repServer))
              {
                isRepServer = true;
              }
            }
          }
          if (replica.getServer() == server)
          {
            isDomain = true;
          }
          if (isDomain && isRepServer)
          {
            break;
          }
        }
        if (!isDomain && isRepServer)
        {
          notAddedReplicationServers.add(server);
        }
      }
    }
    final int SERVERPORT = 0;
    final int NUMBER_ENTRIES = 1;
    final int MISSING_CHANGES = 2;
@@ -5566,9 +6329,67 @@
        };
      }
    }
    Message[][] values = new Message[orderedReplicas.size()][headers.length];
    Message[][] values = new Message[
     notAddedReplicationServers.size() +orderedReplicas.size()][headers.length];
    int i = 0;
    for (ServerDescriptor server : notAddedReplicationServers)
    {
      serversWithNoReplica.add(server);
      Message v;
      for (int j=0; j<headers.length; j++)
      {
        switch (j)
        {
        case SERVERPORT:
          v = Message.raw(getHostPort(server, cnx));
          break;
        case NUMBER_ENTRIES:
          if (scriptFriendly)
          {
            v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_LONG.get();
          }
          else
          {
            v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_DOMAIN_SHORT.get();
          }
          break;
        case MISSING_CHANGES:
          v = INFO_NOT_APPLICABLE_LABEL.get();
          break;
        case AGE_OF_OLDEST_MISSING_CHANGE:
          v = INFO_NOT_APPLICABLE_LABEL.get();
          break;
        case REPLICATION_PORT:
          int replicationPort = server.getReplicationServerPort();
          if (replicationPort >= 0)
          {
            v = Message.raw(String.valueOf(replicationPort));
          }
          else
          {
            v = INFO_NOT_AVAILABLE_SHORT_LABEL.get();
          }
          break;
        case SECURE:
          if (server.isReplicationSecure())
          {
            v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get();
          }
          else
          {
            v = INFO_REPLICATION_STATUS_SECURITY_DISABLED.get();
          }
          break;
        default:
          throw new IllegalStateException("Unknown index: "+j);
        }
        values[i][j] = v;
      }
      i++;
    }
    for (ReplicaDescriptor replica : orderedReplicas)
    {
      Message v;
@@ -5615,7 +6436,19 @@
          break;
        case REPLICATION_PORT:
          int replicationPort = replica.getServer().getReplicationServerPort();
          if (replicationPort >= 0)
          if (!replica.getServer().isReplicationServer())
          {
            if (scriptFriendly)
            {
              v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_LONG.get();
            }
            else
            {
              v = INFO_REPLICATION_STATUS_NOT_A_REPLICATION_SERVER_SHORT.get();
            }
            replicasWithNoReplicationServer.add(replica);
          }
          else if (replicationPort >= 0)
          {
            v = Message.raw(String.valueOf(replicationPort));
          }
@@ -5625,7 +6458,11 @@
          }
          break;
        case SECURE:
          if (replica.getServer().isReplicationSecure())
          if (!replica.getServer().isReplicationServer())
          {
            v = INFO_NOT_APPLICABLE_LABEL.get();
          }
          else if (replica.getServer().isReplicationSecure())
          {
            v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get();
          }
@@ -5713,6 +6550,131 @@
  }
  /**
   * Displays the replication status of the replication servers provided.  The
   * code assumes that all the servers have a replication server and that there
   * are associated with no replication domain.
   * @param servers the servers
   * @param cnx the preferred connections used to connect to the server.
   * @param scriptFriendly wheter to display it on script-friendly mode or not.
   */
  private void displayStatus(Set<ServerDescriptor> servers,
      boolean scriptFriendly, LinkedHashSet<PreferredConnection> cnx)
  {
    final int SERVERPORT = 0;
    final int REPLICATION_PORT = 1;
    final int SECURE = 2;
    Message[] headers;
    if (scriptFriendly)
    {
      headers = new Message[] {
          INFO_REPLICATION_STATUS_LABEL_SERVERPORT.get(),
          INFO_REPLICATION_STATUS_LABEL_REPLICATION_PORT.get(),
          INFO_REPLICATION_STATUS_LABEL_SECURE.get()
      };
    }
    else
    {
      headers = new Message[] {
            INFO_REPLICATION_STATUS_HEADER_SERVERPORT.get(),
            INFO_REPLICATION_STATUS_HEADER_REPLICATION_PORT.get(),
            INFO_REPLICATION_STATUS_HEADER_SECURE.get()
      };
    }
    Message[][] values = new Message[servers.size()][headers.length];
    int i = 0;
    for (ServerDescriptor server : servers)
    {
      Message v;
      for (int j=0; j<headers.length; j++)
      {
        switch (j)
        {
        case SERVERPORT:
          v = Message.raw(getHostPort(server, cnx));
          break;
        case REPLICATION_PORT:
          int replicationPort = server.getReplicationServerPort();
          if (replicationPort >= 0)
          {
            v = Message.raw(String.valueOf(replicationPort));
          }
          else
          {
            v = INFO_NOT_AVAILABLE_SHORT_LABEL.get();
          }
          break;
        case SECURE:
          if (server.isReplicationSecure())
          {
            v = INFO_REPLICATION_STATUS_SECURITY_ENABLED.get();
          }
          else
          {
            v = INFO_REPLICATION_STATUS_SECURITY_DISABLED.get();
          }
          break;
        default:
          throw new IllegalStateException("Unknown index: "+j);
        }
        values[i][j] = v;
      }
      i++;
    }
    if (scriptFriendly)
    {
      printProgress(
          INFO_REPLICATION_STATUS_INDEPENDENT_REPLICATION_SERVERS.get());
      printlnProgress();
      for (i=0; i<values.length; i++)
      {
        printProgress(Message.raw("-"));
        printlnProgress();
        for (int j=0; j<values[i].length; j++)
        {
          printProgress(Message.raw(headers[j]+" "+values[i][j]));
          printlnProgress();
        }
      }
    }
    else
    {
      Message msg =
        INFO_REPLICATION_STATUS_INDEPENDENT_REPLICATION_SERVERS.get();
      printProgressMessageNoWrap(msg);
      printlnProgress();
      int length = msg.length();
      StringBuffer buf = new StringBuffer();
      for (i=0; i<length; i++)
      {
        buf.append("=");
      }
      printProgressMessageNoWrap(Message.raw(buf.toString()));
      printlnProgress();
      TableBuilder table = new TableBuilder();
      for (i=0; i< headers.length; i++)
      {
        table.appendHeading(headers[i]);
      }
      for (i=0; i<values.length; i++)
      {
        table.startRow();
        for (int j=0; j<headers.length; j++)
        {
          table.appendCell(values[i][j]);
        }
      }
      TextTablePrinter printer = new TextTablePrinter(getOutputStream());
      printer.setColumnSeparator(ToolConstants.LIST_TABLE_SEPARATOR);
      table.print(printer);
    }
  }
  /**
   * Retrieves all the replication servers for a given baseDN.  The
   * ServerDescriptor is used to identify the server where the suffix is
   * defined and it cannot be null.  The TopologyCache is used to retrieve
@@ -6914,6 +7876,7 @@
    InitialLdapContext ctx = null;
    String lastBaseDN = null;
    String hostPort = null;
    try
    {
      ctx = loader.createContext();
@@ -7329,7 +8292,8 @@
    MessageBuilder mb = new MessageBuilder();
    mb.append(rce.getMessageObject());
    File logFile = QuickSetupLog.getLogFile();
    if (logFile != null)
    if ((logFile != null) &&
        (rce.getErrorCode() != ReplicationCliReturnCode.USER_CANCELLED))
    {
      mb.append(Constants.LINE_SEPARATOR);
      mb.append(INFO_GENERAL_SEE_FOR_DETAILS.get(logFile.getPath()));
@@ -7390,7 +8354,7 @@
  }
  private boolean mustInitializeSchema(ServerDescriptor server1,
      ServerDescriptor server2)
      ServerDescriptor server2, EnableReplicationUserData uData)
  {
    boolean mustInitializeSchema = false;
    if (!argParser.noSchemaReplication())
@@ -7406,6 +8370,12 @@
        mustInitializeSchema = true;
      }
    }
    if (mustInitializeSchema)
    {
      // Check that both will contain replication data
      mustInitializeSchema = uData.configureReplicationDomain1() &&
      uData.configureReplicationDomain2();
    }
    return mustInitializeSchema;
  }
@@ -7773,6 +8743,11 @@
  private boolean disableAllBaseDns(InitialLdapContext ctx,
      DisableReplicationUserData uData)
  {
    if (uData.disableAll())
    {
      return true;
    }
    boolean returnValue = true;
    Collection<ReplicaDescriptor> replicas = getReplicas(ctx);
    Set<String> replicatedSuffixes = new HashSet<String>();
@@ -7793,12 +8768,16 @@
        boolean found = false;
        for (String dn2 : uData.getBaseDNs())
        {
          found = Utils.areDnsEqual(dn1, dn2);
          break;
          if (Utils.areDnsEqual(dn1, dn2))
          {
            found = true;
            break;
          }
        }
        if (!found)
        {
          returnValue = false;
          break;
        }
      }
    }
@@ -8126,6 +9105,32 @@
          break;
        }
      }
      // This is required when both the bindDN and the admin UID are provided
      // in the command-line.
      boolean forceAddBindDN1 = false;
      boolean forceAddBindPwdFile1 = false;
      if (useAdminUID)
      {
        String bindDN1 = uData.getBindDn1();
        String adminUID = uData.getAdminUid();
        if (bindDN1 != null && adminUID != null)
        {
          if (!Utils.areDnsEqual(ADSContext.getAdministratorDN(adminUID),
              bindDN1))
          {
            forceAddBindDN1 = true;
            for (Argument arg : firstServerCommandBuilder.getArguments())
            {
              if (arg.getLongIdentifier().equals(OPTION_LONG_BINDPWD_FILE))
              {
                forceAddBindPwdFile1 = true;
                break;
              }
            }
          }
        }
      }
      for (Argument arg : firstServerCommandBuilder.getArguments())
      {
        if (arg.getLongIdentifier().equals(OPTION_LONG_HOST))
@@ -8145,6 +9150,38 @@
              INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT1.get());
          port.addValue(String.valueOf(uData.getPort1()));
          commandBuilder.addArgument(port);
          if (forceAddBindDN1)
          {
            StringArgument bindDN = new StringArgument("bindDN1",
                OPTION_SHORT_BINDDN,
                "bindDN1", false, false, true, INFO_BINDDN_PLACEHOLDER.get(),
                "cn=Directory Manager", null,
                INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN1.get());
            bindDN.addValue(uData.getBindDn1());
            commandBuilder.addArgument(bindDN);
            if (forceAddBindPwdFile1)
            {
              FileBasedArgument bindPasswordFileArg = new FileBasedArgument(
                  "bindPasswordFile1",
                  null, "bindPasswordFile1", false, false,
                  INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null,
                  INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE1.get());
              bindPasswordFileArg.getNameToValueMap().put("{password file}",
                  "{password file}");
              commandBuilder.addArgument(bindPasswordFileArg);
            }
            else
            {
              StringArgument bindPasswordArg = new StringArgument(
                  "bindPassword1",
                  null, "bindPassword1", false, false, true,
                  INFO_BINDPWD_PLACEHOLDER.get(), null, null,
                  INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD1.get());
              bindPasswordArg.addValue(arg.getValue());
              commandBuilder.addObfuscatedArgument(bindPasswordArg);
            }
          }
        }
        else if (arg.getLongIdentifier().equals(OPTION_LONG_BINDDN))
        {
@@ -8242,6 +9279,32 @@
          break;
        }
      }
//    This is required when both the bindDN and the admin UID are provided
      // in the command-line.
      boolean forceAddBindDN2 = false;
      boolean forceAddBindPwdFile2 = false;
      if (useAdminUID)
      {
        String bindDN2 = uData.getBindDn2();
        String adminUID = uData.getAdminUid();
        if (bindDN2 != null && adminUID != null)
        {
          if (!Utils.areDnsEqual(ADSContext.getAdministratorDN(adminUID),
              bindDN2))
          {
            forceAddBindDN2 = true;
            for (Argument arg : interactionBuilder.getArguments())
            {
              if (arg.getLongIdentifier().equals(OPTION_LONG_BINDPWD_FILE))
              {
                forceAddBindPwdFile2 = true;
                break;
              }
            }
          }
        }
      }
      ArrayList<Argument> argsToAnalyze = new ArrayList<Argument>();
      for (Argument arg : interactionBuilder.getArguments())
      {
@@ -8261,6 +9324,38 @@
              INFO_DESCRIPTION_ENABLE_REPLICATION_SERVER_PORT2.get());
          port.addValue(String.valueOf(uData.getPort2()));
          commandBuilder.addArgument(port);
          if (forceAddBindDN2)
          {
            StringArgument bindDN = new StringArgument("bindDN2",
                OPTION_SHORT_BINDDN,
                "bindDN2", false, false, true, INFO_BINDDN_PLACEHOLDER.get(),
                "cn=Directory Manager", null,
                INFO_DESCRIPTION_ENABLE_REPLICATION_BINDDN2.get());
            bindDN.addValue(uData.getBindDn2());
            commandBuilder.addArgument(bindDN);
            if (forceAddBindPwdFile2)
            {
              FileBasedArgument bindPasswordFileArg = new FileBasedArgument(
                  "bindPasswordFile2",
                  null, "bindPasswordFile2", false, false,
                  INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null,
                  INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORDFILE2.get());
              bindPasswordFileArg.getNameToValueMap().put("{password file}",
                  "{password file}");
              commandBuilder.addArgument(bindPasswordFileArg);
            }
            else
            {
              StringArgument bindPasswordArg = new StringArgument(
                  "bindPassword2",
                  null, "bindPassword2", false, false, true,
                  INFO_BINDPWD_PLACEHOLDER.get(), null, null,
                  INFO_DESCRIPTION_ENABLE_REPLICATION_BINDPASSWORD2.get());
              bindPasswordArg.addValue(arg.getValue());
              commandBuilder.addObfuscatedArgument(bindPasswordArg);
            }
          }
        }
        else if (arg.getLongIdentifier().equals(OPTION_LONG_BINDDN))
        {
@@ -8385,7 +9480,28 @@
      }
    }
    if (uData.getReplicationPort1() > 0)
    if (uData.configureReplicationServer1() &&
        !uData.configureReplicationDomain1())
    {
      commandBuilder.addArgument(new BooleanArgument(
          argParser.onlyReplicationServer1Arg.getName(),
          argParser.onlyReplicationServer1Arg.getShortIdentifier(),
          argParser.onlyReplicationServer1Arg.getLongIdentifier(),
          INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER1.get()));
    }
    if (!uData.configureReplicationServer1() &&
        uData.configureReplicationDomain1())
    {
      commandBuilder.addArgument(new BooleanArgument(
          argParser.noReplicationServer1Arg.getName(),
          argParser.noReplicationServer1Arg.getShortIdentifier(),
          argParser.noReplicationServer1Arg.getLongIdentifier(),
          INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER1.get()));
    }
    if (uData.configureReplicationServer1() &&
        uData.getReplicationPort1() > 0)
    {
      IntegerArgument replicationPort1 = new IntegerArgument(
          "replicationPort1", 'r',
@@ -8401,7 +9517,29 @@
          "secureReplication1",
          INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION1.get()));
    }
    if (uData.getReplicationPort2() > 0)
    if (uData.configureReplicationServer2() &&
        !uData.configureReplicationDomain2())
    {
      commandBuilder.addArgument(new BooleanArgument(
          argParser.onlyReplicationServer2Arg.getName(),
          argParser.onlyReplicationServer2Arg.getShortIdentifier(),
          argParser.onlyReplicationServer2Arg.getLongIdentifier(),
          INFO_DESCRIPTION_ENABLE_REPLICATION_ONLY_REPLICATION_SERVER2.get()));
    }
    if (!uData.configureReplicationServer2() &&
        uData.configureReplicationDomain2())
    {
      commandBuilder.addArgument(new BooleanArgument(
          argParser.noReplicationServer2Arg.getName(),
          argParser.noReplicationServer2Arg.getShortIdentifier(),
          argParser.noReplicationServer2Arg.getLongIdentifier(),
          INFO_DESCRIPTION_ENABLE_REPLICATION_NO_REPLICATION_SERVER2.get()));
    }
    if (uData.configureReplicationServer2() &&
        uData.getReplicationPort2() > 0)
    {
      IntegerArgument replicationPort2 = new IntegerArgument(
          "replicationPort2", 'r',
@@ -8417,6 +9555,8 @@
          "secureReplication2",
          INFO_DESCRIPTION_ENABLE_SECURE_REPLICATION2.get()));
    }
    if (!uData.replicateSchema())
    {
      commandBuilder.addArgument(new BooleanArgument(
@@ -8534,4 +9674,364 @@
      }
    }
  }
  private void updateAvailableAndReplicatedSuffixesForOneDomain(
      InitialLdapContext ctxDomain, InitialLdapContext ctxOther,
      Collection<String> availableSuffixes,
      Collection<String> alreadyReplicatedSuffixes)
  {
    Collection<ReplicaDescriptor> replicas = getReplicas(ctxDomain);
    int replicationPort = getReplicationPort(ctxOther);
    boolean isReplicationServerConfigured = replicationPort != -1;
    String replicationServer = getReplicationServer(
      ConnectionUtils.getHostName(ctxOther), replicationPort);
    for (ReplicaDescriptor replica : replicas)
    {
      if (!isReplicationServerConfigured)
      {
        if (replica.isReplicated())
        {
          alreadyReplicatedSuffixes.add(replica.getSuffix().getDN());
        }
        availableSuffixes.add(replica.getSuffix().getDN());
      }
      if (!isReplicationServerConfigured)
      {
        availableSuffixes.add(replica.getSuffix().getDN());
      }
      else
      {
        if (!replica.isReplicated())
        {
          availableSuffixes.add(replica.getSuffix().getDN());
        }
        else
        {
          // Check if the replica is already configured with the replication
          // server.
          boolean alreadyReplicated = false;
          Set<String> rServers = replica.getReplicationServers();
          for (String rServer : rServers)
          {
            if (replicationServer.equalsIgnoreCase(rServer))
            {
              alreadyReplicated = true;
            }
          }
          if (alreadyReplicated)
          {
            alreadyReplicatedSuffixes.add(replica.getSuffix().getDN());
          }
          else
          {
            availableSuffixes.add(replica.getSuffix().getDN());
          }
        }
      }
    }
  }
  private void updateAvailableAndReplicatedSuffixesForNoDomain(
      InitialLdapContext ctx1, InitialLdapContext ctx2,
      Collection<String> availableSuffixes,
      Collection<String> alreadyReplicatedSuffixes)
  {
    int replicationPort1 = getReplicationPort(ctx1);
    boolean isReplicationServer1Configured = replicationPort1 != -1;
    String replicationServer1 = getReplicationServer(
      ConnectionUtils.getHostName(ctx1), replicationPort1);
    int replicationPort2 = getReplicationPort(ctx2);
    boolean isReplicationServer2Configured = replicationPort2 != -1;
    String replicationServer2 = getReplicationServer(
      ConnectionUtils.getHostName(ctx2), replicationPort2);
    TopologyCache cache1 = null;
    TopologyCache cache2 = null;
    if (isReplicationServer1Configured)
    {
      try
      {
        ADSContext adsContext = new ADSContext(ctx1);
        if (adsContext.hasAdminData())
        {
          cache1 = new TopologyCache(adsContext, getTrustManager());
        }
      }
      catch (Throwable t)
      {
        LOG.log(Level.WARNING, "Error loading topology cache in "+
            ConnectionUtils.getLdapUrl(ctx1)+": "+t, t);
      }
    }
    if (isReplicationServer2Configured)
    {
      try
      {
        ADSContext adsContext = new ADSContext(ctx2);
        if (adsContext.hasAdminData())
        {
          cache2 = new TopologyCache(adsContext, getTrustManager());
        }
      }
      catch (Throwable t)
      {
        LOG.log(Level.WARNING, "Error loading topology cache in "+
            ConnectionUtils.getLdapUrl(ctx2)+": "+t, t);
      }
    }
    if (cache1 != null && cache2 != null)
    {
      // Check common suffixes
      Set<String> dns1 = new HashSet<String>();
      Set<String> dns2 = new HashSet<String>();
      Set<SuffixDescriptor> suffixes = cache1.getSuffixes();
      for (SuffixDescriptor suffix : suffixes)
      {
        for (String rServer : suffix.getReplicationServers())
        {
          if (rServer.equalsIgnoreCase(replicationServer1))
          {
            dns1.add(suffix.getDN());
          }
        }
      }
      suffixes = cache2.getSuffixes();
      for (SuffixDescriptor suffix : suffixes)
      {
        for (String rServer : suffix.getReplicationServers())
        {
          if (rServer.equalsIgnoreCase(replicationServer2))
          {
            dns2.add(suffix.getDN());
          }
        }
      }
      availableSuffixes.addAll(dns1);
      availableSuffixes.removeAll(dns2);
      alreadyReplicatedSuffixes.addAll(dns1);
      alreadyReplicatedSuffixes.retainAll(dns2);
    }
    else if (cache1 != null)
    {
      Set<SuffixDescriptor> suffixes = cache1.getSuffixes();
      for (SuffixDescriptor suffix : suffixes)
      {
        for (String rServer : suffix.getReplicationServers())
        {
          if (rServer.equalsIgnoreCase(replicationServer1))
          {
            availableSuffixes.add(suffix.getDN());
          }
        }
      }
    }
    else if (cache2 != null)
    {
      Set<SuffixDescriptor> suffixes = cache2.getSuffixes();
      for (SuffixDescriptor suffix : suffixes)
      {
        for (String rServer : suffix.getReplicationServers())
        {
          if (rServer.equalsIgnoreCase(replicationServer2))
          {
            availableSuffixes.add(suffix.getDN());
          }
        }
      }
    }
  }
  private void updateBaseDnsWithNotEnoughReplicationServer(ADSContext adsCtx1,
      ADSContext adsCtx2, EnableReplicationUserData uData,
      Set<String> baseDNsWithNoReplicationServer,
      Set<String> baseDNsWithOneReplicationServer)
  {
    if (uData.configureReplicationServer1() &&
        uData.configureReplicationServer2())
    {
      return;
    }
    Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
    try
    {
      if (adsCtx1.hasAdminData())
      {
        TopologyCache cache = new TopologyCache(adsCtx1,
            getTrustManager());
        cache.getFilter().setSearchMonitoringInformation(false);
        for (String dn : uData.getBaseDNs())
        {
          cache.getFilter().addBaseDNToSearch(dn);
        }
        cache.reloadTopology();
        suffixes.addAll(cache.getSuffixes());
      }
    }
    catch (Throwable t)
    {
      LOG.log(Level.WARNING, "Error loading topology cache from "+
          ConnectionUtils.getHostPort(adsCtx1.getDirContext())+": "+t, t);
    }
    try
    {
      if (adsCtx2.hasAdminData())
      {
        TopologyCache cache = new TopologyCache(adsCtx2,
            getTrustManager());
        cache.getFilter().setSearchMonitoringInformation(false);
        cache.reloadTopology();
        for (String dn : uData.getBaseDNs())
        {
          cache.getFilter().addBaseDNToSearch(dn);
        }
        suffixes.addAll(cache.getSuffixes());
      }
    }
    catch (Throwable t)
    {
      LOG.log(Level.WARNING, "Error loading topology cache from "+
          ConnectionUtils.getHostPort(adsCtx2.getDirContext())+": "+t, t);
    }
    int repPort1 = getReplicationPort(adsCtx1.getDirContext());
    String repServer1 =  getReplicationServer(uData.getHostName1(), repPort1);
    int repPort2 = getReplicationPort(adsCtx2.getDirContext());
    String repServer2 =  getReplicationServer(uData.getHostName2(), repPort2);
    for (String baseDN : uData.getBaseDNs())
    {
      int nReplicationServers = 0;
      for (SuffixDescriptor suffix : suffixes)
      {
        if (Utils.areDnsEqual(suffix.getDN(), baseDN))
        {
          Set<String> replicationServers = suffix.getReplicationServers();
          nReplicationServers += replicationServers.size();
          for (String repServer : replicationServers)
          {
            if (uData.configureReplicationServer1() &&
                repServer.equalsIgnoreCase(repServer1))
            {
              nReplicationServers --;
            }
            if (uData.configureReplicationServer2() &&
                repServer.equalsIgnoreCase(repServer2))
            {
              nReplicationServers --;
            }
          }
        }
      }
      if (uData.configureReplicationServer1())
      {
        nReplicationServers ++;
      }
      if (uData.configureReplicationServer2())
      {
        nReplicationServers ++;
      }
      if (nReplicationServers == 1)
      {
        baseDNsWithOneReplicationServer.add(baseDN);
      }
      else if (nReplicationServers == 0)
      {
        baseDNsWithNoReplicationServer.add(baseDN);
      }
    }
  }
  private String getReplicationServer(String hostName, int replicationPort)
  {
    return hostName.toLowerCase() + ":" + replicationPort;
  }
  private String getServerRepresentation(String hostName, int port)
  {
    return hostName.toLowerCase() + ":" + port;
  }
  private String getSuffixDisplay(String baseDN, Set<ServerDescriptor> servers)
  {
    StringBuilder sb = new StringBuilder();
    sb.append(baseDN);
    for (ServerDescriptor server : servers)
    {
      sb.append(Constants.LINE_SEPARATOR+"    ");
      sb.append(server.getHostPort(true));
    }
    return sb.toString();
  }
  private boolean areSameServer(ServerDescriptor server1,
      ServerDescriptor server2)
  {
    return server1.getId().equals(server2.getId());
  }
}
/**
 * Class used to compare replication servers.
 *
 */
class ReplicationServerComparator implements Comparator<ServerDescriptor>
{
  /**
   * {@inheritDoc}
   */
  public int compare(ServerDescriptor s1, ServerDescriptor s2)
  {
    int compare = s1.getHostName().compareTo(s2.getHostName());
    if (compare == 0)
    {
      if (s1.getReplicationServerPort() > s2.getReplicationServerPort())
      {
        compare = 1;
      }
      else if (s1.getReplicationServerPort() < s2.getReplicationServerPort())
      {
        compare = -1;
      }
    }
    return compare;
  }
}
/**
 * Class used to compare suffixes.
 *
 */
class SuffixComparator implements Comparator<SuffixDescriptor>
{
  /**
   * {@inheritDoc}
   */
  public int compare(SuffixDescriptor s1, SuffixDescriptor s2)
  {
    return s1.getId().compareTo(s2.getId());
  }
}
/**
 * Class used to compare servers.
 *
 */
class ServerComparator implements Comparator<ServerDescriptor>
{
  /**
   * {@inheritDoc}
   */
  public int compare(ServerDescriptor s1, ServerDescriptor s2)
  {
    return s1.getId().compareTo(s2.getId());
  }
}