From bbdcd1d918a2f27fccb2e6a3fe4d854b901dffd8 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Mon, 06 Jul 2009 13:52:09 +0000
Subject: [PATCH] Fix for issue 4092 (dsreplication should allow to configure servers with no replication server and servers with only a replication server)

---
 opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java    |   96 ++
 opends/src/server/org/opends/server/tools/ToolConstants.java                              |   10 
 opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java |  129 +++
 opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java   |   46 +
 opends/src/messages/messages/admin_tool.properties                                        |  133 +++
 opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java           | 1882 +++++++++++++++++++++++++++++++++++++++++++----
 opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java                          |   10 
 7 files changed, 2,094 insertions(+), 212 deletions(-)

diff --git a/opends/src/messages/messages/admin_tool.properties b/opends/src/messages/messages/admin_tool.properties
index 91dadeb..a16959a 100644
--- a/opends/src/messages/messages/admin_tool.properties
+++ b/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
diff --git a/opends/src/server/org/opends/server/tools/ToolConstants.java b/opends/src/server/org/opends/server/tools/ToolConstants.java
index c4d7014..ed5f1fc 100644
--- a/opends/src/server/org/opends/server/tools/ToolConstants.java
+++ b/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;
 }
 
diff --git a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java b/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
index 3254f08..42e5497 100644
--- a/opends/src/server/org/opends/server/tools/dsconfig/DSConfig.java
+++ b/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();
diff --git a/opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java b/opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java
index d918cfe..08d5afb 100644
--- a/opends/src/server/org/opends/server/tools/dsreplication/DisableReplicationUserData.java
+++ b/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;
+  }
 }
diff --git a/opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java b/opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java
index 230013e..905d229 100644
--- a/opends/src/server/org/opends/server/tools/dsreplication/EnableReplicationUserData.java
+++ b/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;
+  }
 }
diff --git a/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java b/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java
index ce30d54..2b6257d 100644
--- a/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliArgumentParser.java
+++ b/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++)
diff --git a/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java b/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java
index 0e82973..77067cf 100644
--- a/opends/src/server/org/opends/server/tools/dsreplication/ReplicationCliMain.java
+++ b/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());
+  }
 }

--
Gitblit v1.10.0