From a61b71ab9d53011751d73156a1521395873514a9 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Thu, 15 Nov 2007 20:53:25 +0000
Subject: [PATCH] CLI part for Issue 2424 (Impact of generation ID on binary copy).

---
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java           |   14 
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PreExternalInitializationUserData.java  |   61 ++
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/MonoServerReplicationUserData.java      |  117 ++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java   |   83 ---
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PostExternalInitializationUserData.java |   39 +
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java                 |  827 ++++++++++++++++++++++++++++++
 opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java       |  291 +++++++++++
 opendj-sdk/opends/src/messages/messages/admin_tool.properties                                             |   72 ++
 8 files changed, 1,395 insertions(+), 109 deletions(-)

diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java
index 5c1e1f8..e9bff0b 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/InitializeAllReplicationUserData.java
@@ -29,90 +29,11 @@
 
 /**
  * This class is used to store the information provided by the user to
- * iniitalize a complete replication topology.  It is required because when we
+ * initialize a complete replication topology.  It is required because when we
  * are in interactive mode the ReplicationCliArgumentParser is not enough.
  *
  */
-class InitializeAllReplicationUserData extends ReplicationUserData
+class InitializeAllReplicationUserData extends MonoServerReplicationUserData
 {
-  private String hostName;
-  private int port;
-  private boolean useStartTLS;
-  private boolean useSSL;
-
-  /**
-   * Returns the host name of the server.
-   * @return the host name of the server.
-   */
-  String getHostName()
-  {
-    return hostName;
-  }
-
-  /**
-   * Sets the host name of the server.
-   * @param hostName the host name of the server.
-   */
-  void setHostName(String hostName)
-  {
-    this.hostName = hostName;
-  }
-
-  /**
-   * Returns the port of the server.
-   * @return the port of the server.
-   */
-  int getPort()
-  {
-    return port;
-  }
-
-  /**
-   * Sets the port of the server.
-   * @param port the port of the server.
-   */
-  void setPort(int port)
-  {
-    this.port = port;
-  }
-  /**
-   * Returns <CODE>true</CODE> if we must use SSL to connect to the server and
-   * <CODE>false</CODE> otherwise.
-   * @return <CODE>true</CODE> if we must use SSL to connect to the server and
-   * <CODE>false</CODE> otherwise.
-   */
-  boolean useSSL()
-  {
-    return useSSL;
-  }
-
-  /**
-   * Sets whether we must use SSL to connect to the server or not.
-   * @param useSSL whether we must use SSL to connect to the server or not.
-   */
-  void setUseSSL(boolean useSSL)
-  {
-    this.useSSL = useSSL;
-  }
-
-  /**
-   * Returns <CODE>true</CODE> if we must use StartTLS to connect to the server
-   * and <CODE>false</CODE> otherwise.
-   * @return <CODE>true</CODE> if we must use StartTLS to connect to the server
-   * and <CODE>false</CODE> otherwise.
-   */
-  boolean useStartTLS()
-  {
-    return useStartTLS;
-  }
-
-  /**
-   * Sets whether we must use StartTLS to connect to the server or not.
-   * @param useStartTLS whether we must use SSL to connect to the server or not.
-   */
-  void setUseStartTLS(boolean useStartTLS)
-  {
-    this.useStartTLS = useStartTLS;
-  }
 }
 
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/MonoServerReplicationUserData.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/MonoServerReplicationUserData.java
new file mode 100644
index 0000000..9d87abb
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/MonoServerReplicationUserData.java
@@ -0,0 +1,117 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.replicationcli;
+
+/**
+ * This is an abstract class used for code refactorization.
+ *
+ */
+abstract class MonoServerReplicationUserData extends ReplicationUserData
+{
+  private String hostName;
+  private int port;
+  private boolean useStartTLS;
+  private boolean useSSL;
+
+  /**
+   * Returns the host name of the server.
+   * @return the host name of the server.
+   */
+  String getHostName()
+  {
+    return hostName;
+  }
+
+  /**
+   * Sets the host name of the server.
+   * @param hostName the host name of the server.
+   */
+  void setHostName(String hostName)
+  {
+    this.hostName = hostName;
+  }
+
+  /**
+   * Returns the port of the server.
+   * @return the port of the server.
+   */
+  int getPort()
+  {
+    return port;
+  }
+
+  /**
+   * Sets the port of the server.
+   * @param port the port of the server.
+   */
+  void setPort(int port)
+  {
+    this.port = port;
+  }
+  /**
+   * Returns <CODE>true</CODE> if we must use SSL to connect to the server and
+   * <CODE>false</CODE> otherwise.
+   * @return <CODE>true</CODE> if we must use SSL to connect to the server and
+   * <CODE>false</CODE> otherwise.
+   */
+  boolean useSSL()
+  {
+    return useSSL;
+  }
+
+  /**
+   * Sets whether we must use SSL to connect to the server or not.
+   * @param useSSL whether we must use SSL to connect to the server or not.
+   */
+  void setUseSSL(boolean useSSL)
+  {
+    this.useSSL = useSSL;
+  }
+
+  /**
+   * Returns <CODE>true</CODE> if we must use StartTLS to connect to the server
+   * and <CODE>false</CODE> otherwise.
+   * @return <CODE>true</CODE> if we must use StartTLS to connect to the server
+   * and <CODE>false</CODE> otherwise.
+   */
+  boolean useStartTLS()
+  {
+    return useStartTLS;
+  }
+
+  /**
+   * Sets whether we must use StartTLS to connect to the server or not.
+   * @param useStartTLS whether we must use SSL to connect to the server or not.
+   */
+  void setUseStartTLS(boolean useStartTLS)
+  {
+    this.useStartTLS = useStartTLS;
+  }
+}
+
+
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PostExternalInitializationUserData.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PostExternalInitializationUserData.java
new file mode 100644
index 0000000..bb5ef78
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PostExternalInitializationUserData.java
@@ -0,0 +1,39 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.replicationcli;
+
+/**
+ * This class is used to store the information provided by the user to
+ * perform the operations required after doing an initialization using
+ * import-ldif of the binary copy.  It is required because when we
+ * are in interactive mode the ReplicationCliArgumentParser is not enough.
+ *
+ */
+class PostExternalInitializationUserData extends MonoServerReplicationUserData
+{
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PreExternalInitializationUserData.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PreExternalInitializationUserData.java
new file mode 100644
index 0000000..f71b72f
--- /dev/null
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/PreExternalInitializationUserData.java
@@ -0,0 +1,61 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License, Version 1.0 only
+ * (the "License").  You may not use this file except in compliance
+ * with the License.
+ *
+ * You can obtain a copy of the license at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE
+ * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at
+ * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+ * add the following below this CDDL HEADER, with the fields enclosed
+ * by brackets "[]" replaced with your own identifying information:
+ *      Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ *
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.guitools.replicationcli;
+
+/**
+ * This class is used to store the information provided by the user to
+ * perform the operations required before doing an initialization using
+ * import-ldif of the binary copy.  It is required because when we
+ * are in interactive mode the ReplicationCliArgumentParser is not enough.
+ *
+ */
+class PreExternalInitializationUserData extends MonoServerReplicationUserData
+{
+  private boolean onlyLocal;
+
+  /**
+   * Whether the operation must be applied only on the local server or not.
+   * @return <CODE>true</CODE> if the operation must be applied only on the
+   * local server and <CODE>false</CODE> otherwise.
+   */
+  public boolean isOnlyLocal()
+  {
+    return onlyLocal;
+  }
+
+  /**
+   * Sets whether the operation must be applied only on the local server or not.
+   * @param onlyLocal whether the operation must be applied only on the local
+   * server or not.
+   */
+  public void setOnlyLocal(boolean onlyLocal)
+  {
+    this.onlyLocal = onlyLocal;
+  }
+
+}
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java
index 67382d1..3598135 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliArgumentParser.java
@@ -62,6 +62,8 @@
   private SubCommand disableReplicationSubCmd;
   private SubCommand initializeReplicationSubCmd;
   private SubCommand initializeAllReplicationSubCmd;
+  private SubCommand postExternalInitializationSubCmd;
+  private SubCommand preExternalInitializationSubCmd;
   private SubCommand statusReplicationSubCmd;
 
   private BooleanArgument noPromptArg;
@@ -219,6 +221,12 @@
   private StringArgument baseDNsArg = null;
 
   /**
+   * The argument that specifies if the external initialization will be
+   * performed only on this server.
+   */
+  private BooleanArgument externalInitializationOnlyInLocalArg;
+
+  /**
    * The 'quiet' argument.
    */
   private BooleanArgument quietArg;
@@ -250,6 +258,18 @@
     "initialize-all";
 
   /**
+   * The text of the pre external initialization subcommand.
+   */
+  public static final String PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME =
+    "pre-external-initialization";
+
+  /**
+   * The text of the initialize all replication subcommand.
+   */
+  public static final String POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME =
+    "post-external-initialization";
+
+  /**
    * The text of the status replication subcommand.
    */
   public static final String STATUS_REPLICATION_SUBCMD_NAME = "status";
@@ -288,6 +308,8 @@
     createDisableReplicationSubCommand();
     createInitializeReplicationSubCommand();
     createInitializeAllReplicationSubCommand();
+    createPreExternalInitializationSubCommand();
+    createPostExternalInitializationSubCommand();
     createStatusReplicationSubCommand();
   }
 
@@ -695,6 +717,65 @@
   }
 
   /**
+   * Creates the subcommand that the user must launch before doing an external
+   * initialization of the topology ( and all the specific
+   * options for the subcommand.  Note: this method assumes that
+   * initializeGlobalArguments has already been called and that hostNameArg,
+   * portArg, startTLSArg and useSSLArg have been created.
+   */
+  private void createPreExternalInitializationSubCommand()
+  throws ArgumentException
+  {
+    preExternalInitializationSubCmd = new SubCommand(this,
+        PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME,
+        INFO_DESCRIPTION_SUBCMD_PRE_EXTERNAL_INITIALIZATION.get(
+            POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME));
+    secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue());
+    externalInitializationOnlyInLocalArg = new BooleanArgument(
+        "only-local",
+        'l',
+        "only-local",
+        INFO_DESCRIPTION_EXTERNAL_INITIALIZATION_LOCAL.get());
+    externalInitializationOnlyInLocalArg.setPropertyName(
+        externalInitializationOnlyInLocalArg.getLongIdentifier());
+    Argument[] argsToAdd = { secureArgsList.hostNameArg,
+        secureArgsList.portArg, secureArgsList.useSSLArg,
+        secureArgsList.useStartTLSArg,
+        externalInitializationOnlyInLocalArg};
+
+    for (int i=0; i<argsToAdd.length; i++)
+    {
+      preExternalInitializationSubCmd.addArgument(argsToAdd[i]);
+    }
+  }
+
+  /**
+   * Creates the subcommand that the user must launch after doing an external
+   * initialization of the topology ( and all the specific
+   * options for the subcommand.  Note: this method assumes that
+   * initializeGlobalArguments has already been called and that hostNameArg,
+   * portArg, startTLSArg and useSSLArg have been created.
+   */
+  private void createPostExternalInitializationSubCommand()
+  throws ArgumentException
+  {
+    postExternalInitializationSubCmd = new SubCommand(this,
+        POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME,
+        INFO_DESCRIPTION_SUBCMD_POST_EXTERNAL_INITIALIZATION.get(
+            PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME));
+    secureArgsList.hostNameArg.setDefaultValue(getDefaultHostValue());
+    externalInitializationOnlyInLocalArg.setPropertyName(
+        externalInitializationOnlyInLocalArg.getLongIdentifier());
+    Argument[] argsToAdd = { secureArgsList.hostNameArg,
+        secureArgsList.portArg, secureArgsList.useSSLArg,
+        secureArgsList.useStartTLSArg};
+    for (int i=0; i<argsToAdd.length; i++)
+    {
+      postExternalInitializationSubCmd.addArgument(argsToAdd[i]);
+    }
+  }
+
+  /**
    * Creates the status replication subcommand and all the specific options
    * for the subcommand.  Note: this method assumes that
    * initializeGlobalArguments has already been called and that hostNameArg,
@@ -1012,6 +1093,56 @@
   }
 
   /**
+   * Indicate if the SSL mode is required for the server in the pre external
+   * initialization subcommand.
+   *
+   * @return <CODE>true</CODE> if SSL mode is required for the server in the
+   * pre external initialization subcommand and <CODE>false</CODE> otherwise.
+   */
+  public boolean useSSLToPreExternalInitialization()
+  {
+    return secureArgsList.useSSLArg.isPresent();
+  }
+
+  /**
+   * Indicate if the SSL mode is required for the server in the pre external
+   * initialization subcommand.
+   *
+   * @return <CODE>true</CODE> if StartTLS mode is required for the server in
+   * the pre external initialization subcommand and <CODE>false</CODE>
+   * otherwise.
+   */
+  public boolean useStartTLSToPreExternalInitialization()
+  {
+    return secureArgsList.useStartTLSArg.isPresent();
+  }
+
+  /**
+   * Indicate if the SSL mode is required for the server in the post external
+   * initialization subcommand.
+   *
+   * @return <CODE>true</CODE> if SSL mode is required for the server in the
+   * post external initialization subcommand and <CODE>false</CODE> otherwise.
+   */
+  public boolean useSSLToPostExternalInitialization()
+  {
+    return secureArgsList.useSSLArg.isPresent();
+  }
+
+  /**
+   * Indicate if the SSL mode is required for the server in the post external
+   * initialization subcommand.
+   *
+   * @return <CODE>true</CODE> if StartTLS mode is required for the server in
+   * the post external initialization subcommand and <CODE>false</CODE>
+   * otherwise.
+   */
+  public boolean useStartTLSToPostExternalInitialization()
+  {
+    return secureArgsList.useStartTLSArg.isPresent();
+  }
+
+  /**
    * Indicate if the SSL mode is required for the server in the status
    * replication subcommand.
    *
@@ -1371,6 +1502,50 @@
   }
 
   /**
+   * Returns the host name explicitly provided in the pre external
+   * initialization subcommand.
+   * @return the host name explicitly provided in the pre external
+   * initialization subcommand.
+   */
+  public String getHostNameToPreExternalInitialization()
+  {
+    return getValue(secureArgsList.hostNameArg);
+  }
+
+  /**
+   * Returns the host name default value in the pre external initialization
+   * subcommand.
+   * @return the host name default value in the pre external initialization
+   * subcommand.
+   */
+  public String getDefaultHostNameToPreExternalInitialization()
+  {
+    return getDefaultValue(secureArgsList.hostNameArg);
+  }
+
+  /**
+   * Returns the host name explicitly provided in the post external
+   * initialization subcommand.
+   * @return the host name explicitly provided in the post external
+   * initialization subcommand.
+   */
+  public String getHostNameToPostExternalInitialization()
+  {
+    return getValue(secureArgsList.hostNameArg);
+  }
+
+  /**
+   * Returns the host name default value in the post external initialization
+   * subcommand.
+   * @return the host name default value in the post external initialization
+   * subcommand.
+   */
+  public String getDefaultHostNameToPostExternalInitialization()
+  {
+    return getDefaultValue(secureArgsList.hostNameArg);
+  }
+
+  /**
    * Returns the source host name explicitly provided in the initialize
    * replication subcommand.
    * @return the source host name explicitly provided in the initialize
@@ -1503,6 +1678,50 @@
   }
 
   /**
+   * Returns the server port explicitly provided in the pre external
+   * initialization subcommand.
+   * @return the server port explicitly provided in the pre external
+   * initialization subcommand.  Returns -1 if no port was explicitly provided.
+   */
+  public int getPortToPreExternalInitialization()
+  {
+    return getValue(secureArgsList.portArg);
+  }
+
+  /**
+   * Returns the server port default value in the pre external initialization
+   * subcommand.
+   * @return the server port default value in the pre external initialization
+   * subcommand.
+   */
+  public int getDefaultPortToPreExternalInitialization()
+  {
+    return getDefaultValue(secureArgsList.portArg);
+  }
+
+  /**
+   * Returns the server port explicitly provided in the post external
+   * initialization subcommand.
+   * @return the server port explicitly provided in the post external
+   * initialization subcommand.  Returns -1 if no port was explicitly provided.
+   */
+  public int getPortToPostExternalInitialization()
+  {
+    return getValue(secureArgsList.portArg);
+  }
+
+  /**
+   * Returns the server port default value in the post external initialization
+   * subcommand.
+   * @return the server port default value in the post external initialization
+   * subcommand.
+   */
+  public int getDefaultPortToPostExternalInitialization()
+  {
+    return getDefaultValue(secureArgsList.portArg);
+  }
+
+  /**
    * Returns the server port explicitly provided in the status replication
    * subcommand.
    * @return the server port explicitly provided in the status replication
@@ -1634,6 +1853,14 @@
     {
       validateInitializeAllReplicationOptions(buf);
     }
+    else if (isPreExternalInitializationSubcommand())
+    {
+      validatePreExternalInitializationOptions(buf);
+    }
+    else if (isPostExternalInitializationSubcommand())
+    {
+      validatePostExternalInitializationOptions(buf);
+    }
 
     else
     {
@@ -1688,6 +1915,28 @@
   }
 
   /**
+   * Returns whether the user provided subcommand is the pre external
+   * initialization or not.
+   * @return <CODE>true</CODE> if the user provided subcommand is the
+   * pre external initialization and <CODE>false</CODE> otherwise.
+   */
+  public boolean isPreExternalInitializationSubcommand()
+  {
+    return isSubcommand(PRE_EXTERNAL_INITIALIZATION_SUBCMD_NAME);
+  }
+
+  /**
+   * Returns whether the user provided subcommand is the post external
+   * initialization or not.
+   * @return <CODE>true</CODE> if the user provided subcommand is the
+   * post external initialization and <CODE>false</CODE> otherwise.
+   */
+  public boolean isPostExternalInitializationSubcommand()
+  {
+    return isSubcommand(POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME);
+  }
+
+  /**
    * Returns whether the user provided subcommand is the initialize replication
    * or not.
    * @return <CODE>true</CODE> if the user provided subcommand is the
@@ -1699,6 +1948,18 @@
   }
 
   /**
+   * Tells whether the user specified to apply the pre (or post) external
+   * initialization operations only on the local server.
+   * @return <CODE>true</CODE> if the user specified to apply the pre (or post)
+   * external initialization operations only on the local server and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean isExternalInitializationOnlyInLocal()
+  {
+    return externalInitializationOnlyInLocalArg.isPresent();
+  }
+
+  /**
    * Returns whether the command-line subcommand has the name provided
    * or not.
    * @param name the name of the subcommand.
@@ -1823,6 +2084,36 @@
   }
 
   /**
+   * Checks the pre external initialization subcommand options and updates the
+   * provided MessageBuilder with the errors that were encountered with the
+   * subcommand options.
+   *
+   * This method assumes that the method parseArguments for the parser has
+   * already been called.
+   * @param buf the MessageBuilder object where we add the error messages
+   * describing the errors encountered.
+   */
+  private void validatePreExternalInitializationOptions(MessageBuilder buf)
+  {
+    validateInitializeAllReplicationOptions(buf);
+  }
+
+  /**
+   * Checks the post external initialization subcommand options and updates the
+   * provided MessageBuilder with the errors that were encountered with the
+   * subcommand options.
+   *
+   * This method assumes that the method parseArguments for the parser has
+   * already been called.
+   * @param buf the MessageBuilder object where we add the error messages
+   * describing the errors encountered.
+   */
+  private void validatePostExternalInitializationOptions(MessageBuilder buf)
+  {
+    validateInitializeAllReplicationOptions(buf);
+  }
+
+  /**
    * Checks the status replication subcommand options and updates the provided
    * MessageBuilder with the errors that were encountered with the subcommand
    * options.
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
index 6ec6fc1..8d537f3 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliMain.java
@@ -327,7 +327,9 @@
         ci = new LDAPConnectionConsoleInteraction(this,
             argParser.getSecureArgsList());
         ci.setDisplayLdapIfSecureParameters(
-            !argParser.isInitializeAllReplicationSubcommand());
+            !argParser.isInitializeAllReplicationSubcommand() &&
+            !argParser.isPreExternalInitializationSubcommand() ||
+            !argParser.isPostExternalInitializationSubcommand());
       }
       if (returnValue == SUCCESSFUL_NOP)
       {
@@ -347,6 +349,14 @@
         {
           returnValue = initializeAllReplication();
         }
+        else if (argParser.isPreExternalInitializationSubcommand())
+        {
+          returnValue = preExternalInitialization();
+        }
+        else if (argParser.isPostExternalInitializationSubcommand())
+        {
+          returnValue = postExternalInitialization();
+        }
         else if (argParser.isStatusReplicationSubcommand())
         {
           returnValue = statusReplication();
@@ -468,6 +478,66 @@
   }
 
   /**
+   * Based on the data provided in the command-line execute the pre external
+   * initialization operation.
+   * @return the error code if the operation failed and SUCCESSFUL if it was
+   * successful.
+   */
+  private ReplicationCliReturnCode preExternalInitialization()
+  {
+    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
+    PreExternalInitializationUserData uData =
+      new PreExternalInitializationUserData();
+    if (argParser.isInteractive())
+    {
+      if (promptIfRequired(uData))
+      {
+        returnValue = preExternalInitialization(uData);
+      }
+      else
+      {
+        returnValue = USER_CANCELLED;
+      }
+    }
+    else
+    {
+      initializeWithArgParser(uData);
+      returnValue = preExternalInitialization(uData);
+    }
+    return returnValue;
+  }
+
+  /**
+   * Based on the data provided in the command-line execute the post external
+   * initialization operation.
+   * @return the error code if the operation failed and SUCCESSFUL if it was
+   * successful.
+   */
+  private ReplicationCliReturnCode postExternalInitialization()
+  {
+    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
+    PostExternalInitializationUserData uData =
+      new PostExternalInitializationUserData();
+    if (argParser.isInteractive())
+    {
+      if (promptIfRequired(uData))
+      {
+        returnValue = postExternalInitialization(uData);
+      }
+      else
+      {
+        returnValue = USER_CANCELLED;
+      }
+    }
+    else
+    {
+      initializeWithArgParser(uData);
+      returnValue = postExternalInitialization(uData);
+    }
+    return returnValue;
+  }
+
+  /**
    * Based on the data provided in the command-line it displays replication
    * status.
    * @return the error code if the operation failed and SUCCESSFUL if it was
@@ -1232,7 +1302,7 @@
     if (!cancelled)
     {
       LinkedList<String> suffixes = argParser.getBaseDNs();
-      checkSuffixesForInitializeAllReplication(suffixes, ctx, true);
+      checkSuffixesForInitializeReplication(suffixes, ctx, true);
       cancelled = suffixes.isEmpty();
 
       uData.setBaseDNs(suffixes);
@@ -1283,6 +1353,210 @@
   }
 
   /**
+   * Updates the contents of the provided PreExternalInitializationUserData
+   * object with the information provided in the command-line.  If some
+   * information is missing, ask the user to provide valid data.
+   * We assume that if this method is called we are in interactive mode.
+   * @param uData the object to be updated.
+   * @return <CODE>true</CODE> if the object was successfully updated and
+   * <CODE>false</CODE> if the user cancelled the operation.
+   */
+  private boolean promptIfRequired(PreExternalInitializationUserData uData)
+  {
+    boolean cancelled = false;
+
+    String adminPwd = argParser.getBindPasswordAdmin();
+    String adminUid = argParser.getAdministratorUID();
+
+    String host = argParser.getHostNameToInitializeAll();
+    int port = argParser.getPortToInitializeAll();
+    boolean useSSL = argParser.useSSLToInitializeAll();
+    boolean useStartTLS = argParser.useStartTLSToInitializeAll();
+
+    /*
+     * Try to connect to the server.
+     */
+    InitialLdapContext ctx = null;
+
+    while ((ctx == null) && !cancelled)
+    {
+      try
+      {
+        ci.run();
+        useSSL = ci.useSSL();
+        useStartTLS = ci.useStartTLS();
+        host = ci.getHostName();
+        port = ci.getPortNumber();
+        adminUid = ci.getAdministratorUID();
+        adminPwd = ci.getBindPassword();
+
+        ctx = createInitialLdapContextInteracting(ci);
+
+        if (ctx == null)
+        {
+          cancelled = true;
+        }
+      }
+      catch (ClientException ce)
+      {
+        LOG.log(Level.WARNING, "Client exception "+ce);
+        println();
+        println(ce.getMessageObject());
+        println();
+        resetConnectionArguments();
+      }
+      catch (ArgumentException ae)
+      {
+        LOG.log(Level.WARNING, "Argument exception "+ae);
+        println();
+        println(ae.getMessageObject());
+        println();
+        cancelled = true;
+      }
+    }
+    if (!cancelled)
+    {
+      boolean onlyLocal = false;
+      if (!argParser.isExternalInitializationOnlyInLocal())
+      {
+        println();
+        onlyLocal = askConfirmation(
+            INFO_REPLICATION_PRE_EXTERNAL_INITIALIZATION_LOCAL_PROMPT.get(
+                ConnectionUtils.getHostPort(ctx)), false, LOG);
+      }
+      else
+      {
+        onlyLocal = true;
+      }
+      uData.setOnlyLocal(onlyLocal);
+
+      uData.setHostName(host);
+      uData.setPort(port);
+      uData.setUseSSL(useSSL);
+      uData.setUseStartTLS(useStartTLS);
+      uData.setAdminUid(adminUid);
+      uData.setAdminPwd(adminPwd);
+    }
+
+    if (!cancelled)
+    {
+      LinkedList<String> suffixes = argParser.getBaseDNs();
+      checkSuffixesForInitializeReplication(suffixes, ctx, true);
+      cancelled = suffixes.isEmpty();
+
+      uData.setBaseDNs(suffixes);
+    }
+
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (Throwable t)
+      {
+      }
+    }
+
+    return !cancelled;
+  }
+
+  /**
+   * Updates the contents of the provided PostExternalInitializationUserData
+   * object with the information provided in the command-line.  If some
+   * information is missing, ask the user to provide valid data.
+   * We assume that if this method is called we are in interactive mode.
+   * @param uData the object to be updated.
+   * @return <CODE>true</CODE> if the object was successfully updated and
+   * <CODE>false</CODE> if the user cancelled the operation.
+   */
+  private boolean promptIfRequired(PostExternalInitializationUserData uData)
+  {
+    boolean cancelled = false;
+
+    String adminPwd = argParser.getBindPasswordAdmin();
+    String adminUid = argParser.getAdministratorUID();
+
+    String host = argParser.getHostNameToInitializeAll();
+    int port = argParser.getPortToInitializeAll();
+    boolean useSSL = argParser.useSSLToInitializeAll();
+    boolean useStartTLS = argParser.useStartTLSToInitializeAll();
+
+    /*
+     * Try to connect to the server.
+     */
+    InitialLdapContext ctx = null;
+
+    while ((ctx == null) && !cancelled)
+    {
+      try
+      {
+        ci.run();
+        useSSL = ci.useSSL();
+        useStartTLS = ci.useStartTLS();
+        host = ci.getHostName();
+        port = ci.getPortNumber();
+        adminUid = ci.getAdministratorUID();
+        adminPwd = ci.getBindPassword();
+
+        ctx = createInitialLdapContextInteracting(ci);
+
+        if (ctx == null)
+        {
+          cancelled = true;
+        }
+      }
+      catch (ClientException ce)
+      {
+        LOG.log(Level.WARNING, "Client exception "+ce);
+        println();
+        println(ce.getMessageObject());
+        println();
+        resetConnectionArguments();
+      }
+      catch (ArgumentException ae)
+      {
+        LOG.log(Level.WARNING, "Argument exception "+ae);
+        println();
+        println(ae.getMessageObject());
+        println();
+        cancelled = true;
+      }
+    }
+    if (!cancelled)
+    {
+      uData.setHostName(host);
+      uData.setPort(port);
+      uData.setUseSSL(useSSL);
+      uData.setUseStartTLS(useStartTLS);
+      uData.setAdminUid(adminUid);
+      uData.setAdminPwd(adminPwd);
+    }
+
+    if (!cancelled)
+    {
+      LinkedList<String> suffixes = argParser.getBaseDNs();
+      checkSuffixesForInitializeReplication(suffixes, ctx, true);
+      cancelled = suffixes.isEmpty();
+
+      uData.setBaseDNs(suffixes);
+    }
+
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (Throwable t)
+      {
+      }
+    }
+
+    return !cancelled;
+  }
+
+  /**
    * Updates the contents of the provided StatusReplicationUserData object
    * with the information provided in the command-line.  If some information
    * is missing, ask the user to provide valid data.
@@ -1827,7 +2101,8 @@
    * Initializes the contents of the provided initialize all replication user
    * data object with what was provided in the command-line without prompting to
    * the user.
-   * @param uData the disable replication user data object to be initialized.
+   * @param uData the initialize all replication user data object to be
+   * initialized.
    */
   private void initializeWithArgParser(InitializeAllReplicationUserData uData)
   {
@@ -1848,6 +2123,59 @@
     uData.setUseStartTLS(argParser.useStartTLSToInitializeAll());
   }
 
+  /**
+   * Initializes the contents of the provided pre external replication user
+   * data object with what was provided in the command-line without prompting to
+   * the user.
+   * @param uData the pre external replication user data object to be
+   * initialized.
+   */
+  private void initializeWithArgParser(PreExternalInitializationUserData uData)
+  {
+    uData.setBaseDNs(new LinkedList<String>(argParser.getBaseDNs()));
+    String adminUid = getValue(argParser.getAdministratorUID(),
+        argParser.getDefaultAdministratorUID());
+    uData.setAdminUid(adminUid);
+    String adminPwd = argParser.getBindPasswordAdmin();
+    uData.setAdminPwd(adminPwd);
+
+    String hostName = getValue(argParser.getHostNameToInitializeAll(),
+        argParser.getDefaultHostNameToInitializeAll());
+    uData.setHostName(hostName);
+    int port = getValue(argParser.getPortToInitializeAll(),
+        argParser.getDefaultPortToInitializeAll());
+    uData.setPort(port);
+    uData.setUseSSL(argParser.useSSLToInitializeAll());
+    uData.setUseStartTLS(argParser.useStartTLSToInitializeAll());
+    uData.setOnlyLocal(argParser.isExternalInitializationOnlyInLocal());
+  }
+
+  /**
+   * Initializes the contents of the provided post external replication user
+   * data object with what was provided in the command-line without prompting to
+   * the user.
+   * @param uData the pre external replication user data object to be
+   * initialized.
+   */
+  private void initializeWithArgParser(PostExternalInitializationUserData uData)
+  {
+    uData.setBaseDNs(new LinkedList<String>(argParser.getBaseDNs()));
+    String adminUid = getValue(argParser.getAdministratorUID(),
+        argParser.getDefaultAdministratorUID());
+    uData.setAdminUid(adminUid);
+    String adminPwd = argParser.getBindPasswordAdmin();
+    uData.setAdminPwd(adminPwd);
+
+    String hostName = getValue(argParser.getHostNameToInitializeAll(),
+        argParser.getDefaultHostNameToInitializeAll());
+    uData.setHostName(hostName);
+    int port = getValue(argParser.getPortToInitializeAll(),
+        argParser.getDefaultPortToInitializeAll());
+    uData.setPort(port);
+    uData.setUseSSL(argParser.useSSLToInitializeAll());
+    uData.setUseStartTLS(argParser.useStartTLSToInitializeAll());
+  }
+
 
   /**
    * Initializes the contents of the provided status replication user data
@@ -2333,8 +2661,8 @@
    * user for information if something is missing.
    * @param uData the EnableReplicationUserData object.
    * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
-   * successful.
-   * and the replication could be enabled and an error code otherwise.
+   * successful and the replication could be enabled and an error code
+   * otherwise.
    */
   private ReplicationCliReturnCode enableReplication(
       EnableReplicationUserData uData)
@@ -2529,8 +2857,7 @@
    * to the user for information if something is missing.
    * @param uData the DisableReplicationUserData object.
    * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
-   * successful.
-   * and the replication could be enabled and an error code otherwise.
+   * successful and an error code otherwise.
    */
   private ReplicationCliReturnCode disableReplication(
       DisableReplicationUserData uData)
@@ -2607,8 +2934,7 @@
    * to the user for information if something is missing.
    * @param uData the StatusReplicationUserData object.
    * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
-   * successful.
-   * and the replication could be enabled and an error code otherwise.
+   * successful and an error code otherwise.
    */
   private ReplicationCliReturnCode statusReplication(
       StatusReplicationUserData uData)
@@ -2671,8 +2997,7 @@
    * missing.
    * @param uData the InitializeReplicationUserData object.
    * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
-   * successful.
-   * and the replication could be enabled and an error code otherwise.
+   * successful and an error code otherwise.
    */
   private ReplicationCliReturnCode initializeReplication(
       InitializeReplicationUserData uData)
@@ -2781,8 +3106,7 @@
    * missing.
    * @param uData the InitializeAllReplicationUserData object.
    * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
-   * successful.
-   * and the replication could be enabled and an error code otherwise.
+   * successful and an error code otherwise.
    */
   private ReplicationCliReturnCode initializeAllReplication(
       InitializeAllReplicationUserData uData)
@@ -2806,7 +3130,7 @@
     if (ctx != null)
     {
       LinkedList<String> baseDNs = uData.getBaseDNs();
-      checkSuffixesForInitializeAllReplication(baseDNs, ctx, false);
+      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
       if (!baseDNs.isEmpty())
       {
         for (String baseDN : baseDNs)
@@ -2854,6 +3178,189 @@
     return returnValue;
   }
 
+  /**
+   * Performs the operation that must be made before initializing the topology
+   * using the import-ldif command or the binary copy.  The operation uses
+   * the parameters in the provided InitializeAllReplicationUserData.
+   * This method does not prompt to the user for information if something is
+   * missing.
+   * @param uData the PreExternalInitializationUserData object.
+   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
+   * successful and an error code otherwise.
+   */
+  private ReplicationCliReturnCode preExternalInitialization(
+      PreExternalInitializationUserData uData)
+  {
+    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
+    InitialLdapContext ctx = null;
+    try
+    {
+      ctx = createAdministrativeContext(uData.getHostName(), uData.getPort(),
+          uData.useSSL(), uData.useStartTLS(),
+          ADSContext.getAdministratorDN(uData.getAdminUid()),
+          uData.getAdminPwd(), getTrustManager());
+    }
+    catch (NamingException ne)
+    {
+      String hostPort = uData.getHostName()+":"+uData.getPort();
+      println();
+      println(getMessageForException(ne, hostPort));
+      LOG.log(Level.SEVERE, "Complete error stack:", ne);
+    }
+    if (ctx != null)
+    {
+      LinkedList<String> baseDNs = uData.getBaseDNs();
+      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
+      if (!baseDNs.isEmpty())
+      {
+        for (String baseDN : baseDNs)
+        {
+          try
+          {
+            printlnProgress();
+            Message msg = formatter.getFormattedWithPoints(
+                INFO_PROGRESS_PRE_EXTERNAL_INITIALIZATION.get(baseDN));
+            printProgress(msg);
+            preExternalInitialization(baseDN, ctx, uData.isOnlyLocal(), false);
+            printProgress(formatter.getFormattedDone());
+            printlnProgress();
+          }
+          catch (ReplicationCliException rce)
+          {
+            println();
+            println(getCriticalExceptionMessage(rce));
+            returnValue = rce.getErrorCode();
+            LOG.log(Level.SEVERE, "Complete error stack:", rce);
+          }
+        }
+        if (uData.isOnlyLocal())
+        {
+          printlnProgress();
+          printProgress(
+              INFO_PROGRESS_PRE_INITIALIZATION_LOCAL_FINISHED_PROCEDURE.get(
+                  ConnectionUtils.getHostPort(ctx),
+                  ReplicationCliArgumentParser.
+                  POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME));
+          printlnProgress();
+        }
+        else
+        {
+          printlnProgress();
+          printProgress(
+            INFO_PROGRESS_PRE_INITIALIZATION_FINISHED_PROCEDURE.get(
+                ReplicationCliArgumentParser.
+                POST_EXTERNAL_INITIALIZATION_SUBCMD_NAME));
+          printlnProgress();
+        }
+      }
+      else
+      {
+        returnValue = REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
+      }
+    }
+    else
+    {
+      returnValue = ERROR_CONNECTING;
+    }
+
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (Throwable t)
+      {
+      }
+    }
+
+    return returnValue;
+  }
+
+  /**
+   * Performs the operation that must be made after initializing the topology
+   * using the import-ldif command or the binary copy.  The operation uses
+   * the parameters in the provided InitializeAllReplicationUserData.
+   * This method does not prompt to the user for information if something is
+   * missing.
+   * @param uData the PostExternalInitializationUserData object.
+   * @return ReplicationCliReturnCode.SUCCESSFUL if the operation was
+   * successful and an error code otherwise.
+   */
+  private ReplicationCliReturnCode postExternalInitialization(
+      PostExternalInitializationUserData uData)
+  {
+    ReplicationCliReturnCode returnValue = SUCCESSFUL_NOP;
+    InitialLdapContext ctx = null;
+    try
+    {
+      ctx = createAdministrativeContext(uData.getHostName(), uData.getPort(),
+          uData.useSSL(), uData.useStartTLS(),
+          ADSContext.getAdministratorDN(uData.getAdminUid()),
+          uData.getAdminPwd(), getTrustManager());
+    }
+    catch (NamingException ne)
+    {
+      String hostPort = uData.getHostName()+":"+uData.getPort();
+      println();
+      println(getMessageForException(ne, hostPort));
+      LOG.log(Level.SEVERE, "Complete error stack:", ne);
+    }
+    if (ctx != null)
+    {
+      LinkedList<String> baseDNs = uData.getBaseDNs();
+      checkSuffixesForInitializeReplication(baseDNs, ctx, false);
+      if (!baseDNs.isEmpty())
+      {
+        for (String baseDN : baseDNs)
+        {
+          try
+          {
+            printlnProgress();
+            Message msg = formatter.getFormattedWithPoints(
+                INFO_PROGRESS_POST_EXTERNAL_INITIALIZATION.get(baseDN));
+            printProgress(msg);
+            postExternalInitialization(baseDN, ctx, false);
+            printProgress(formatter.getFormattedDone());
+            printlnProgress();
+          }
+          catch (ReplicationCliException rce)
+          {
+            println();
+            println(getCriticalExceptionMessage(rce));
+            returnValue = rce.getErrorCode();
+            LOG.log(Level.SEVERE, "Complete error stack:", rce);
+          }
+        }
+        printlnProgress();
+        printProgress(
+            INFO_PROGRESS_POST_INITIALIZATION_FINISHED_PROCEDURE.get());
+        printlnProgress();
+      }
+      else
+      {
+        returnValue = REPLICATION_CANNOT_BE_INITIALIZED_ON_BASEDN;
+      }
+    }
+    else
+    {
+      returnValue = ERROR_CONNECTING;
+    }
+
+    if (ctx != null)
+    {
+      try
+      {
+        ctx.close();
+      }
+      catch (Throwable t)
+      {
+      }
+    }
+
+    return returnValue;
+  }
+
 
   /**
    * Checks that replication can actually be enabled in the provided baseDNs
@@ -3172,7 +3679,7 @@
    * @param interactive whether to ask the user to provide interactively
    * base DNs if none of the provided base DNs can be initialized.
    */
-  private void checkSuffixesForInitializeAllReplication(
+  private void checkSuffixesForInitializeReplication(
       Collection<String> suffixes, InitialLdapContext ctx, boolean interactive)
   {
     TreeSet<String> availableSuffixes = new TreeSet<String>();
@@ -3194,7 +3701,15 @@
     if (availableSuffixes.size() == 0)
     {
       println();
-      println(ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION.get());
+      if (argParser.isInitializeAllReplicationSubcommand())
+      {
+        println(ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION.get());
+      }
+      else
+      {
+        println(
+            ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_LOCAL_REPLICATION.get());
+      }
       LinkedList<String> userProvidedSuffixes = argParser.getBaseDNs();
       TreeSet<String> userProvidedNotReplicatedSuffixes =
         new TreeSet<String>();
@@ -3260,7 +3775,7 @@
       if (notFound.size() > 0)
       {
         println();
-        println(ERR_REPLICATION_INITIALIZE_ALL_SUFFIXES_NOT_FOUND.get(
+        println(ERR_REPLICATION_INITIALIZE_LOCAL_SUFFIXES_NOT_FOUND.get(
                 Utils.getStringFromCollection(notFound,
                     Constants.LINE_SEPARATOR)));
       }
@@ -3290,14 +3805,35 @@
             // In interactive mode we do not propose to manage the
             // administration suffix.
             println();
-            println(
+            if (argParser.isInitializeAllReplicationSubcommand())
+            {
+              println(
                 ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION.get());
+            }
+            else
+            {
+              println(
+               ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_LOCAL_REPLICATION.get());
+            }
             break;
           }
           else
           {
             println();
-            println(ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE_ALL.get());
+            if (argParser.isInitializeAllReplicationSubcommand())
+            {
+              println(ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE_ALL.get());
+            }
+            else if (argParser.isPreExternalInitializationSubcommand())
+            {
+              println(
+                 ERR_NO_SUFFIXES_SELECTED_TO_PRE_EXTERNAL_INITIALIZATION.get());
+            }
+            else if (argParser.isPostExternalInitializationSubcommand())
+            {
+              println(
+                ERR_NO_SUFFIXES_SELECTED_TO_POST_EXTERNAL_INITIALIZATION.get());
+            }
             for (String dn : availableSuffixes)
             {
               if (!Utils.areDnsEqual(dn,
@@ -3305,9 +3841,26 @@
                   !Utils.areDnsEqual(dn, Constants.SCHEMA_DN) &&
                   !Utils.areDnsEqual(dn, Constants.REPLICATION_CHANGES_DN))
               {
-                if (askConfirmation(
-                    INFO_REPLICATION_INITIALIZE_ALL_SUFFIX_PROMPT.get(dn),
-                    true, LOG))
+                boolean addSuffix;
+                if (argParser.isPreExternalInitializationSubcommand())
+                {
+                  addSuffix = askConfirmation(
+                    INFO_REPLICATION_PRE_EXTERNAL_INITIALIZATION_SUFFIX_PROMPT.
+                    get(dn), true, LOG);
+                }
+                else if (argParser.isPostExternalInitializationSubcommand())
+                {
+                  addSuffix = askConfirmation(
+                    INFO_REPLICATION_POST_EXTERNAL_INITIALIZATION_SUFFIX_PROMPT.
+                    get(dn), true, LOG);
+                }
+                else
+                {
+                  addSuffix = askConfirmation(
+                      INFO_REPLICATION_INITIALIZE_ALL_SUFFIX_PROMPT.get(dn),
+                      true, LOG);
+                }
+                if (addSuffix)
                 {
                   suffixes.add(dn);
                 }
@@ -5043,6 +5596,211 @@
   }
 
   /**
+   * Launches the pre external initialization operation using the provided
+   * connection on a given base DN.
+   * @param baseDN the base DN that we want to reset.
+   * @param ctx the connection to the server.
+   * @param onlyLocal whether the resetting internal operations must only apply
+   * to the server to which we are connected.
+   * @param displayProgress whether to display operation progress or not.
+   * @throws ReplicationCliException if there is an error performing the
+   * operation.
+   */
+  private void preExternalInitialization(String baseDN, InitialLdapContext ctx,
+      boolean onlyLocal, boolean displayProgress) throws ReplicationCliException
+  {
+    postPreExternalInitialization(baseDN, ctx, onlyLocal, displayProgress,
+        true);
+  }
+
+  /**
+   * Launches the post external initialization operation using the provided
+   * connection on a given base DN required for replication to work.
+   * @param baseDN the base DN that we want to reset.
+   * @param ctx the connection to the server.
+   * @param displayProgress whether to display operation progress or not.
+   * @throws ReplicationCliException if there is an error performing the
+   * operation.
+   */
+  private void postExternalInitialization(String baseDN, InitialLdapContext ctx,
+      boolean displayProgress) throws ReplicationCliException
+  {
+    postPreExternalInitialization(baseDN, ctx, false, displayProgress, false);
+  }
+
+  /**
+   * Launches the pre or post external initialization operation using the
+   * provided connection on a given base DN.
+   * @param baseDN the base DN that we want to reset.
+   * @param ctx the connection to the server.
+   * @param onlyLocal whether the resetting internal operations must only apply
+   * to the server to which we are connected.
+   * @param displayProgress whether to display operation progress or not.
+   * @param isPre whether this is the pre operation or the post operation.
+   * @throws ReplicationCliException if there is an error performing the
+   * operation.
+   */
+  private void postPreExternalInitialization(String baseDN,
+      InitialLdapContext ctx, boolean onlyLocal, boolean displayProgress,
+      boolean isPre) throws ReplicationCliException
+  {
+    boolean taskCreated = false;
+    int i = 1;
+    boolean isOver = false;
+    String dn = null;
+    BasicAttributes attrs = new BasicAttributes();
+    Attribute oc = new BasicAttribute("objectclass");
+    oc.add("top");
+    oc.add("ds-task");
+    oc.add("ds-task-reset-generation-id");
+    attrs.put(oc);
+    attrs.put("ds-task-class-name",
+        "org.opends.server.tasks.SetGenerationIdTask");
+    if (isPre)
+    {
+      if (!onlyLocal)
+      {
+        attrs.put("ds-task-reset-generation-id-new-value", "-1");
+      }
+      else
+      {
+        try
+        {
+          attrs.put("ds-task-reset-generation-id-new-value",
+            String.valueOf(getReplicationDomainId(ctx, baseDN)));
+        }
+        catch (NamingException ne)
+        {
+          LOG.log(Level.SEVERE, "Error get replication domain id for base DN "+
+              baseDN+" on server "+ConnectionUtils.getHostPort(ctx), ne);
+
+          throw new ReplicationCliException(getThrowableMsg(
+              ERR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION.get(), ne),
+              ERROR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION, ne);
+        }
+      }
+    }
+    attrs.put("ds-task-reset-generation-id-domain-base-dn", baseDN);
+    while (!taskCreated)
+    {
+      String id = "dsreplication-reset-generation-id-"+i;
+      dn = "ds-task-id="+id+",cn=Scheduled Tasks,cn=Tasks";
+      attrs.put("ds-task-id", id);
+      try
+      {
+        DirContext dirCtx = ctx.createSubcontext(dn, attrs);
+        taskCreated = true;
+        LOG.log(Level.INFO, "created task entry: "+attrs);
+        dirCtx.close();
+      }
+      catch (NameAlreadyBoundException x)
+      {
+      }
+      catch (NamingException ne)
+      {
+        LOG.log(Level.SEVERE, "Error creating task "+attrs, ne);
+        Message msg = isPre ?
+        ERR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION.get():
+          ERR_LAUNCHING_POST_EXTERNAL_INITIALIZATION.get();
+        ReplicationCliReturnCode code = isPre?
+            ERROR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION:
+              ERROR_LAUNCHING_POST_EXTERNAL_INITIALIZATION;
+        throw new ReplicationCliException(
+            getThrowableMsg(msg, ne), code, ne);
+      }
+      i++;
+    }
+    // Wait until it is over
+    SearchControls searchControls = new SearchControls();
+    searchControls.setCountLimit(1);
+    searchControls.setSearchScope(
+        SearchControls. OBJECT_SCOPE);
+    String filter = "objectclass=*";
+    searchControls.setReturningAttributes(
+        new String[] {
+            "ds-task-log-message",
+            "ds-task-state"
+        });
+    String lastLogMsg = null;
+    while (!isOver)
+    {
+      try
+      {
+        Thread.sleep(500);
+      }
+      catch (Throwable t)
+      {
+      }
+      try
+      {
+        NamingEnumeration res = ctx.search(dn, filter, searchControls);
+        SearchResult sr = (SearchResult)res.next();
+        String logMsg = getFirstValue(sr, "ds-task-log-message");
+        if (logMsg != null)
+        {
+          if (!logMsg.equals(lastLogMsg))
+          {
+            LOG.log(Level.INFO, logMsg);
+            lastLogMsg = logMsg;
+          }
+        }
+        InstallerHelper helper = new InstallerHelper();
+        String state = getFirstValue(sr, "ds-task-state");
+
+        if (helper.isDone(state) || helper.isStoppedByError(state))
+        {
+          isOver = true;
+          Message errorMsg;
+          String server = ConnectionUtils.getHostPort(ctx);
+          if (lastLogMsg == null)
+          {
+            errorMsg = isPre ?
+                INFO_ERROR_DURING_PRE_EXTERNAL_INITIALIZATION_NO_LOG.get(
+                state, server) :
+                  INFO_ERROR_DURING_POST_EXTERNAL_INITIALIZATION_NO_LOG.get(
+                      state, server);
+          }
+          else
+          {
+            errorMsg = isPre ?
+                INFO_ERROR_DURING_PRE_EXTERNAL_INITIALIZATION_LOG.get(
+                lastLogMsg, state, server) :
+                  INFO_ERROR_DURING_POST_EXTERNAL_INITIALIZATION_LOG.get(
+                      lastLogMsg, state, server);
+          }
+
+          if (helper.isCompletedWithErrors(state))
+          {
+            LOG.log(Level.WARNING, "Completed with error: "+errorMsg);
+            println(errorMsg);
+          }
+          else if (!helper.isSuccessful(state) ||
+              helper.isStoppedByError(state))
+          {
+            LOG.log(Level.WARNING, "Error: "+errorMsg);
+            ReplicationCliReturnCode code = isPre?
+                ERROR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION:
+                  ERROR_LAUNCHING_POST_EXTERNAL_INITIALIZATION;
+            throw new ReplicationCliException(errorMsg, code, null);
+          }
+        }
+      }
+      catch (NameNotFoundException x)
+      {
+        isOver = true;
+      }
+      catch (NamingException ne)
+      {
+        Message msg = isPre ?
+            ERR_POOLING_PRE_EXTERNAL_INITIALIZATION.get():
+              ERR_POOLING_POST_EXTERNAL_INITIALIZATION.get();
+            throw new ReplicationCliException(
+                getThrowableMsg(msg, ne), ERROR_CONNECTING, ne);
+      }
+    }
+  }
+
+  /**
    * Initializes a suffix with the contents of a replica that has a given
    * replication id.
    * @param ctx the connection to the server whose suffix we want to initialize.
@@ -6035,4 +6793,29 @@
     }
     forceNonInteractive = false;
   }
+
+  /**
+   * Returns the replication domain ID for a given baseDN on the server.
+   * @param ctx the connection to the server.
+   * @param baseDN the baseDN for which we want the replication domain ID.
+   * @return the replication domain ID or -1 if the replication domain ID
+   * could not be found.
+   * @throws NamingException if an error occurred reading the configuration
+   * information.
+   */
+  private int getReplicationDomainId(InitialLdapContext ctx, String baseDN)
+  throws NamingException
+  {
+    int domainId = -1;
+    ServerDescriptor server = ServerDescriptor.createStandalone(ctx);
+    for (ReplicaDescriptor replica : server.getReplicas())
+    {
+      if (Utils.areDnsEqual(replica.getSuffix().getDN(), baseDN))
+      {
+        domainId = replica.getReplicationId();
+        break;
+      }
+    }
+    return domainId;
+  }
 }
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java
index b526099..10924ce 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/replicationcli/ReplicationCliReturnCode.java
@@ -164,7 +164,19 @@
   /**
    * Error seeding trustore.
    */
-  ERROR_SEEDING_TRUSTORE(22, ERR_REPLICATION_NO_MESSAGE.get());
+  ERROR_SEEDING_TRUSTORE(22, ERR_REPLICATION_NO_MESSAGE.get()),
+
+  /**
+   * Error launching pre external initialization.
+   */
+  ERROR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION(23,
+      ERR_REPLICATION_NO_MESSAGE.get()),
+
+  /**
+   * Error launching pre external initialization.
+   */
+  ERROR_LAUNCHING_POST_EXTERNAL_INITIALIZATION(24,
+      ERR_REPLICATION_NO_MESSAGE.get());
 
 
   private Message message;
diff --git a/opendj-sdk/opends/src/messages/messages/admin_tool.properties b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
index 290a789..b41bcb8 100644
--- a/opendj-sdk/opends/src/messages/messages/admin_tool.properties
+++ b/opendj-sdk/opends/src/messages/messages/admin_tool.properties
@@ -461,8 +461,6 @@
  communication with the source server
 INFO_DESCRIPTION_INITIALIZE_REPLICATION_STARTTLS_SOURCE=Use StartTLS to \
  secure communication with the source server
-INFO_REPLICATION_INITIALIZE_PROTOCOL_SOURCE=How do you want to connect to the \
- source server?
 INFO_DESCRIPTION_INITIALIZE_REPLICATION_HOST_DESTINATION=Directory server \
  hostname or IP address of the destination server whose contents will be \
  initialized
@@ -472,6 +470,9 @@
  secure communication with the destination server
 INFO_DESCRIPTION_INITIALIZE_REPLICATION_STARTTLS_DESTINATION=Use \
  StartTLS to secure communication with the destination server
+INFO_DESCRIPTION_EXTERNAL_INITIALIZATION_LOCAL=Use this option when only the \
+ contents of the specified directory server will be initialized with an \
+ external method (import-ldif command or binary copy)
 INFO_REPLICATION_TOOL_DESCRIPTION=This utility may be used to configure \
  replication between servers so that the data of the servers is synchronized.\
  For replication to work you must first to enable replication using the \
@@ -494,6 +495,20 @@
  being replicated with the contents on the specified server.  This operation \
  is required after enabling replication in order replication to work ({%s} \
  applied to each server can also be used for this purpose).
+INFO_DESCRIPTION_SUBCMD_PRE_EXTERNAL_INITIALIZATION=This subcommand must be \
+ called before initializing the contents of all the replicated servers using \
+ the tool import-ldif or the binary copy method for replication to work.  You \
+ must specify the list of Base DNs that will be initialized and you must \
+ provide the credentials of any of the servers that is being replicated.  \
+ After calling this subcommand, you must initialize the contents \
+ of all the servers in the topology and after the initialization is over you \
+ must call the subcommand {%s}.
+INFO_DESCRIPTION_SUBCMD_POST_EXTERNAL_INITIALIZATION=This subcommand must be \
+ called after initializing the contents of all the replicated servers using \
+ the tool import-ldif or the binary copy method for replication to work.  You \
+ must specify the list of Base DNs that have been initialized and you must \
+ provide the credentials of any of the servers that is being replicated.  See \
+ the usage of the subcommand {%s} for more information.
 INFO_DESCRIPTION_SUBCMD_ENABLE_REPLICATION=Updates the configuration of the \
  servers to replicate the data under the specified Base DN.  If one of the \
  specified servers is already replicating the data under the Base DN with \
@@ -599,16 +614,31 @@
 SEVERE_ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_ALL_REPLICATION=There are no \
  base DNs replicated in the server.  The base DNs must be replicated to be \
  able to use their contents to initialize the base DNs on the other servers.
+MILD_ERR_NO_SUFFIXES_AVAILABLE_TO_INITIALIZE_LOCAL_REPLICATION=There are no \
+ base DNs replicated in the server.
 MILD_ERR_REPLICATION_DISABLE_SUFFIXES_NOT_FOUND=The following base DNs could \
  not be found on the server:%n%s
- MILD_ERR_REPLICATION_INITIALIZE_ALL_SUFFIXES_NOT_FOUND=The following base \
+ MILD_ERR_REPLICATION_INITIALIZE_LOCAL_SUFFIXES_NOT_FOUND=The following base \
  DNs 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.
 MILD_ERR_NO_SUFFIXES_SELECTED_TO_INITIALIZE_ALL=You must choose at least one \
  base DN to initialize.
+INFO_REPLICATION_PRE_EXTERNAL_INITIALIZATION_LOCAL_PROMPT=Are you going to \
+ initialize only the contents of server %s (type 'no' if you will initialize \
+ contents of all replicated servers for the given Base DNs)?
+MILD_ERR_NO_SUFFIXES_SELECTED_TO_PRE_EXTERNAL_INITIALIZATION=You must specify \
+ the base DNs that will be initialized using the import-ldif command or the \
+ binary copy.
+MILD_ERR_NO_SUFFIXES_SELECTED_TO_POST_EXTERNAL_INITIALIZATION=You must specify \
+ the base DNs 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_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?
+INFO_REPLICATION_POST_EXTERNAL_INITIALIZATION_SUFFIX_PROMPT=Have you \
+ initialized with import-ldif or binary copy base DN %s?
 MILD_ERR_REPLICATION_READING_REGISTERED_SERVERS_CONFIRM_UPDATE_REMOTE=The \
  following errors were encountered reading the configuration of the existing \
  servers:%n%s%n%nIf you continue the replication tool will to try to update \
@@ -716,5 +746,37 @@
 INFO_REPLICATION_STATUS_SECURITY_ENABLED=Enabled
 INFO_REPLICATION_STATUS_SECURITY_DISABLED=Disabled
 INFO_REPLICATION_CRITICAL_ERROR_DETAILS=Details: %s
-  
-  
+INFO_PROGRESS_PRE_EXTERNAL_INITIALIZATION=Preparing base DN %s to be \
+ initialized externally
+INFO_PROGRESS_POST_EXTERNAL_INITIALIZATION=Updating replication information on \
+ base DN %s
+INFO_PROGRESS_PRE_INITIALIZATION_LOCAL_FINISHED_PROCEDURE=Now you can proceed \
+ to the initialization of the contents of the base DNs on server %s.  You can \
+ use the command import-ldif or the binary copy to do so.%n%nWhen the \
+ initialization is completed you must use the subcommand {%s} for replication \
+ to work with the new base DNs.
+INFO_PROGRESS_PRE_INITIALIZATION_FINISHED_PROCEDURE=Now you can proceed \
+ to the initialization of the contents of the base DNs on all the replicated \
+ servers.  You can use the command import-ldif or the binary copy to do \
+ so.%n%nWhen the initialization is completed you must use the subcommand \
+ {%s} for replication to work with the new base DNs contents.
+INFO_PROGRESS_POST_INITIALIZATION_FINISHED_PROCEDURE=Post initialization \
+ procedure completed successfully.
+SEVERE_ERR_POOLING_PRE_EXTERNAL_INITIALIZATION=Error reading the progress of \
+ the operation.
+SEVERE_ERR_POOLING_POST_EXTERNAL_INITIALIZATION=Error reading the progress of \
+ the operation.
+INFO_ERROR_DURING_PRE_EXTERNAL_INITIALIZATION_NO_LOG=Unexpected error during \
+ the operation.  Task state: %s.  Check the error logs of %s for more \
+ information.
+INFO_ERROR_DURING_PRE_EXTERNAL_INITIALIZATION_LOG=Unexpected error during the \
+ operation.  Last log details: %s.  Task state: %s.  Check the error logs of \
+ %s for more information.
+INFO_ERROR_DURING_POST_EXTERNAL_INITIALIZATION_NO_LOG=Unexpected error during \
+ the operation.  Task state: %s.  Check the error logs of %s for more \
+ information.
+INFO_ERROR_DURING_POST_EXTERNAL_INITIALIZATION_LOG=Unexpected error during the \
+ operation.  Last log details: %s.  Task state: %s.  Check the error logs of \
+ %s for more information.
+SEVERE_ERR_LAUNCHING_PRE_EXTERNAL_INITIALIZATION=Error launching the operation.
+SEVERE_ERR_LAUNCHING_POST_EXTERNAL_INITIALIZATION=Error launching the operation.

--
Gitblit v1.10.0