From ceef7ba098240a8b10aee4f36d1653795652481c Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Fri, 27 Apr 2007 14:51:31 +0000
Subject: [PATCH] Move some of the panels specific of the installer to the package org.opends.quicksetup.installer.ui.

---
 opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties               |   96 
 opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java                     |   40 
 opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java                        |   38 
 opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java      |   36 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java   |  324 ++
 opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java                         |    7 
 opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java                |   38 
 opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java    |   43 
 opends/src/quicksetup/org/opends/quicksetup/Step.java                                    |   14 
 opends/src/ads/org/opends/admin/ads/ServerDescriptor.java                                |   90 
 opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java    |   76 
 opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java                     | 1088 +++++++++
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java         |  115 
 opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java                       |   47 
 opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java       |   16 
 opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java                      |   20 
 opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java                               |  100 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java           |  102 
 opends/src/ads/org/opends/admin/ads/ADSContextException.java                             |  176 +
 opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java                    |    4 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java          |    5 
 opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java                            |    1 
 opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java |    2 
 opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties             |    6 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java       |  540 ++++
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java        |    5 
 opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java              |  147 +
 opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java                     |   17 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java        |    7 
 opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java                           |   84 
 opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java                                |  151 +
 opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java               |    1 
 opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java                  |   11 
 opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java    |  155 +
 opends/src/quicksetup/org/opends/quicksetup/UserData.java                                |  236 +
 opends/src/statuspanel/org/opends/statuspanel/StatusCli.java                             |    4 
 opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java        |  116 +
 opends/build.xml                                                                         |   22 
 opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java            |  139 +
 opends/src/ads/org/opends/admin/ads/ADSContext.java                                      | 1917 +++++++++++++++++
 opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java                            |   40 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java      |   13 
 opends/src/quicksetup/org/opends/quicksetup/util/Utils.java                              |    1 
 opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java         |   10 
 opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java          |    8 
 opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java                        |   64 
 opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java   |  530 ++++
 47 files changed, 6,333 insertions(+), 369 deletions(-)

diff --git a/opends/build.xml b/opends/build.xml
index e800bb5..5a02e4a 100644
--- a/opends/build.xml
+++ b/opends/build.xml
@@ -77,6 +77,7 @@
   <property name="quicksetup.src.dir" location="src/quicksetup"       />
   <property name="quicksetup.classes.dir"
             location="${build.dir}/quicksetup/classes"                />
+	<property name="ads.src.dir" location="src/ads"       />
 
   <!-- Properties for use with the Status Panel.                      -->
   <property name="statuspanel.src.dir" location="src/statuspanel"       />
@@ -370,6 +371,12 @@
       <formatter type="plain" />
     </checkstyle>
 
+  	<checkstyle config="${checkstyle.dir}/opends-checkstyle.xml"
+  	  failOnViolation="true">
+  	  <fileset dir="${ads.src.dir}" includes="**/*.java" />
+  	  <formatter type="plain" />
+  	</checkstyle>
+  	
     <checkstyle config="${checkstyle.dir}/opends-checkstyle.xml"
          failOnViolation="true">
       <fileset dir="${quicksetup.src.dir}" includes="**/*.java" />
@@ -412,8 +419,7 @@
        depends="cleaninit,compilequicksetup,weave,compilestatuspanel"
        description="Recompile the Directory Server source files.">
   </target>
-
-
+	
 
   <!-- Compile the Directory Server source files. -->
   <target name="compile"
@@ -472,6 +478,18 @@
   <target name="compilequicksetup" depends="buildtools,weave"
           description="Compile the Quick Setup source files.">
     <mkdir dir="${quicksetup.classes.dir}" />
+  	<javac srcdir="${ads.src.dir}" destdir="${quicksetup.classes.dir}"
+				optimize="true" debug="on" debuglevel="lines,source" source="1.5"
+  	  	target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
+  	  	memoryMaximumSize="${MEM}">
+  	  	<compilerarg value="-Xlint:all" />
+  		  <classpath>
+  	  	  <fileset dir="${build.dir}/build-tools">
+  	  			<include name="build-tools.jar" />
+  	  		</fileset>
+  	  		<pathelement path="${classes.dir}"/>
+  	    </classpath>
+  	</javac>
     <javac srcdir="${src.dir}" destdir="${quicksetup.classes.dir}"
                debug="on" debuglevel="${build.debuglevel}" source="1.5"
                target="1.5" deprecation="true" fork="true" memoryInitialSize="${MEM}"
diff --git a/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opends/src/ads/org/opends/admin/ads/ADSContext.java
new file mode 100644
index 0000000..3a607b5
--- /dev/null
+++ b/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -0,0 +1,1917 @@
+/*
+ * 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.admin.ads;
+
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.Set;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Iterator;
+
+import javax.naming.InvalidNameException;
+import javax.naming.NameAlreadyBoundException;
+import javax.naming.NameNotFoundException;
+import javax.naming.NamingEnumeration;
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.NotContextException;
+import javax.naming.directory.DirContext;
+import javax.naming.directory.ModificationItem;
+import javax.naming.directory.SearchResult;
+import javax.naming.directory.Attribute;
+import javax.naming.directory.Attributes;
+import javax.naming.directory.BasicAttribute;
+import javax.naming.directory.BasicAttributes;
+import javax.naming.directory.SearchControls;
+import javax.naming.ldap.InitialLdapContext;
+import javax.naming.ldap.LdapContext;
+import javax.naming.ldap.LdapName;
+import javax.naming.ldap.Rdn;
+
+/**
+ * Class used to update and read the contents of the Administration Data.
+ */
+public class ADSContext
+{
+
+  /**
+   * Enumeration containing the different server properties that are stored in
+   * the ADS.
+   */
+  public enum ServerProperty
+  {
+    /**
+     * The ID used to identify the server.
+     */
+    ID("cn"),
+    /**
+     * The host name of the server.
+     */
+    HOSTNAME("hostname"),
+    /**
+     * The LDAP port of the server.
+     */
+    PORT("ldapport"),
+    /**
+     * The JMX port of the server.
+     */
+    JMX_PORT("jmxport"),
+    /**
+     * The LDAPS port of the server.
+     */
+    SECURE_PORT("ldapsport"),
+    /**
+     * The certificate used by the server.
+     */
+    CERTIFICATE("certificate"),
+    /**
+     * The path where the server is installed.
+     */
+    INSTANCE_PATH("instancepath"),
+    /**
+     * The description of the server.
+     */
+    DESCRIPTION("description"),
+    /**
+     * The OS of the machine where the server is installed.
+     */
+    HOST_OS("os"),
+    /**
+     * Whether LDAP is enabled or not.
+     */
+    LDAP_ENABLED("ldapEnabled"),
+    /**
+     * Whether LDAPS is enabled or not.
+     */
+    LDAPS_ENABLED("ldapsEnabled"),
+    /**
+     * Whether StartTLS is enabled or not.
+     */
+    STARTTLS_ENABLED("startTLSEnabled"),
+    /**
+     * Whether JMX is enabled or not.
+     */
+    JMX_ENABLED("jmxEnabled"),
+    /**
+     * The location of the server.
+     */
+    LOCATION("location"),
+    /**
+     * The groups to which this server belongs.
+     */
+    GROUPS("memberofgroups");
+
+    private String attrName;
+    /**
+     * Private constructor.
+     * @param n the name of the attribute.
+     */
+    private ServerProperty(String n)
+    {
+      attrName = n;
+    }
+
+    /**
+     * Returns the attribute name.
+     * @return the attribute name.
+     */
+    public String getAttributeName()
+    {
+      return attrName;
+    }
+  };
+
+  /**
+   * The list of server properties that are multivalued.
+   */
+  private final static Set<ServerProperty> MULTIVALUED_SERVER_PROPERTIES =
+    new HashSet<ServerProperty>();
+  static
+  {
+    MULTIVALUED_SERVER_PROPERTIES.add(ServerProperty.GROUPS);
+  }
+
+  /**
+   * Enumeration containing the different server group properties that are
+   * stored in the ADS.
+   */
+  public enum ServerGroupProperty
+  {
+    /**
+     * The UID of the server group.
+     */
+    UID("cn"),
+    /**
+     * The description of the server group.
+     */
+    DESCRIPTION("description"),
+    /**
+     * The members of the server group.
+     */
+    MEMBERS("members");
+
+    private String attrName;
+
+    /**
+     * Private constructor.
+     * @param n the attribute name.
+     */
+    private ServerGroupProperty(String n)
+    {
+      attrName = n;
+    }
+
+    /**
+     * Returns the attribute name.
+     * @return the attribute name.
+     */
+    public String getAttributeName()
+    {
+      return attrName;
+    }
+  };
+
+  /**
+   * The list of server group properties that are multivalued.
+   */
+  private final static
+  Set<ServerGroupProperty> MULTIVALUED_SERVER_GROUP_PROPERTIES =
+    new HashSet<ServerGroupProperty>();
+  static
+  {
+    MULTIVALUED_SERVER_GROUP_PROPERTIES.add(ServerGroupProperty.MEMBERS);
+  }
+
+  /**
+   * The enumeration containing the different Administrator properties.
+   */
+  public enum AdministratorProperty
+  {
+    /**
+     * The UID of the administrator.
+     */
+    UID,
+    /**
+     * The password of the administrator.
+     */
+    PASSWORD,
+    /**
+     * The description of the administrator.
+     */
+    DESCRIPTION,
+    /**
+     * The DN of the administrator.
+     */
+    ADMINISTRATOR_DN
+  };
+
+  /**
+   * Character used to separate hostname from ipath in RDN.
+   */
+  public final static String HNP_SEPARATOR = "@";
+
+  // The context used to retrieve information
+  InitialLdapContext dirContext;
+
+
+  /**
+   * Constructor of the ADSContext.
+   * @param dirContext the DirContext that must be used to retrieve information.
+   */
+  public ADSContext(InitialLdapContext dirContext)
+  {
+    this.dirContext = dirContext;
+  }
+
+
+  /**
+   * Returns the DirContext used to retrieve information by this ADSContext.
+   * @return the DirContext used to retrieve information by this ADSContext.
+   */
+  public InitialLdapContext getDirContext()
+  {
+    return dirContext;
+  }
+
+  /**
+   * Method called to register a server in the ADS.
+   * @param serverProperties the properties of the server.
+   * @throws ADSContextException if the server could not be registered.
+   */
+  public void registerServer(Map<ServerProperty, Object> serverProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerProperties(serverProperties);
+    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
+    try
+    {
+      DirContext ctx = dirContext.createSubcontext(dn, attrs);
+      ctx.close();
+    }
+    catch (NameAlreadyBoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ALREADY_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+
+  /**
+   * Method called to udpate the properties of a server in the ADS.
+   * @param serverProperties the new properties of the server.
+   * @throws ADSContextException if the server could not be registered.
+   */
+  public void updateServer(Map<ServerProperty, Object> serverProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerProperties(serverProperties);
+    BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
+    try
+    {
+      dirContext.modifyAttributes(dn, InitialLdapContext.REPLACE_ATTRIBUTE,
+          attrs);
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOT_YET_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Method called to unregister a server in the ADS.
+   * @param serverProperties the properties of the server.
+   * @throws ADSContextException if the server could not be unregistered.
+   */
+  public void unregisterServer(Map<ServerProperty, Object> serverProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerProperties(serverProperties);
+    try
+    {
+      dirContext.destroySubcontext(dn);
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOT_YET_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Returns whether a given server is already registered or not.
+   * @param serverProperties the server properties.
+   * @return <CODE>true</CODE> if the server was registered and
+   * <CODE>false</CODE> otherwise.
+   * @throws ADSContextException if something went wrong.
+   */
+  public boolean isServerAlreadyRegistered(
+      Map<ServerProperty, Object> serverProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerProperties(serverProperties);
+    return isExistingEntry(dn);
+  }
+
+  /**
+   * Returns whether a given administrator is already registered or not.
+   * @param adminProperties the administrator properties.
+   * @return <CODE>true</CODE> if the administrator was registered and
+   * <CODE>false</CODE> otherwise.
+   * @throws ADSContextException if something went wrong.
+   */
+  public boolean isAdministratorAlreadyRegistered(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromAdministratorProperties(adminProperties);
+    return isExistingEntry(dn);
+  }
+
+  /**
+   * A convenience method that takes some server properties as parameter and
+   * if there is no server registered associated with those properties,
+   * registers it and if it is already registered, updates it.
+   * @param serverProperties the server properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void registerOrUpdateServer(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    try
+    {
+      registerServer(serverProperties);
+    }
+    catch(ADSContextException x)
+    {
+      if (x.getError() == ADSContextException.ErrorType.ALREADY_REGISTERED)
+      {
+        updateServer(serverProperties);
+      }
+      else
+      {
+        throw x;
+      }
+    }
+  }
+
+  /**
+   * Returns the properties of a server for a given host name and installation
+   * path.
+   * @param hostname the host Name.
+   * @param ipath the installation path.
+   * @return the properties of a server for a given host name and installation
+   * path.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public Map<ServerProperty, Object> lookupServerRegistry(String hostname,
+      String ipath) throws ADSContextException
+  {
+    LdapName dn = makeDNFromHostnameAndPath(hostname, ipath);
+    Map<ServerProperty, Object> result;
+    try
+    {
+      result = makePropertiesFromServerAttrs(hostname, ipath,
+          dirContext.getAttributes(dn));
+    }
+    catch (NameNotFoundException x)
+    {
+      result = null;
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+
+  /**
+   * Returns a set containing the servers that are registered in the ADS.
+   * @return a set containing the servers that are registered in the ADS.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public Set<Map<ServerProperty,Object>> readServerRegistry()
+  throws ADSContextException
+  {
+    Set<Map<ServerProperty,Object>> result =
+      new HashSet<Map<ServerProperty,Object>>();
+    try
+    {
+      NamingEnumeration ne;
+      SearchControls sc = new SearchControls();
+
+      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+      ne = dirContext.search(getServerContainerDN(), "(objectclass=*)", sc);
+      while (ne.hasMore())
+      {
+        SearchResult sr = (SearchResult)ne.next();
+        Map<ServerProperty,Object> properties =
+          makePropertiesFromServerAttrs(sr.getName(), sr.getAttributes());
+        result.add(properties);
+      }
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.BROKEN_INSTALL);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+  /**
+   * Returns a set of the server properties that are registered in the ADS and
+   * that contain the properties specified in serverProperties.
+   * @param serverProperties the properties that are used as search criteria.
+   * @return a set of the server properties that are registered in the ADS and
+   * that contain the properties specified in serverProperties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public Set<Map<ServerProperty, Object>> searchServerRegistry(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    Set<Map<ServerProperty, Object>> result =
+      new HashSet<Map<ServerProperty, Object>>();
+    StringBuffer filter = new StringBuffer();
+
+    // Build the filter according the properties passed in serverProperties
+    int operandCount = 0;
+    if (serverProperties.containsKey(ServerProperty.HOSTNAME))
+    {
+      filter.append("(cn=");
+      filter.append(serverProperties.get(ServerProperty.HOSTNAME));
+      filter.append("*");
+      if (serverProperties.containsKey(ServerProperty.INSTANCE_PATH))
+      {
+        filter.append(HNP_SEPARATOR);
+        filter.append(serverProperties.get(ServerProperty.INSTANCE_PATH));
+      }
+      filter.append(")");
+      operandCount++;
+    }
+    if (serverProperties.containsKey(ServerProperty.PORT))
+    {
+      filter.append("(");
+      filter.append(ServerProperty.PORT);
+      filter.append("=");
+      filter.append(serverProperties.get(ServerProperty.PORT));
+      filter.append(")");
+      operandCount++;
+    }
+    if (operandCount >= 2)
+    {
+      filter.insert(0, '(');
+      filter.append("&)");
+    }
+
+    // Search the ADS
+    try
+    {
+      NamingEnumeration ne;
+      SearchControls sc = new SearchControls();
+
+      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+      ne = dirContext.search(getServerContainerDN(), filter.toString(), sc);
+      while (ne.hasMore())
+      {
+        SearchResult sr = (SearchResult)ne.next();
+        Map<ServerProperty, Object> properties = makePropertiesFromServerAttrs(
+            sr.getName(), sr.getAttributes());
+        result.add(properties);
+      }
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.BROKEN_INSTALL);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+  /**
+   * Creates a Server Group in the ADS.
+   * @param serverGroupProperties the properties of the server group to be
+   * created.
+   * @throws ADSContextException if somethings goes wrong.
+   */
+  public void createServerGroup(
+      Map<ServerGroupProperty, Object> serverGroupProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
+    BasicAttributes attrs = makeAttrsFromServerGroupProperties(
+        serverGroupProperties);
+    try
+    {
+      DirContext ctx = dirContext.createSubcontext(dn, attrs);
+      ctx.close();
+    }
+    catch (NameAlreadyBoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ALREADY_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Updates the properties of a Server Group in the ADS.
+   * @param serverGroupProperties the new properties of the server group to be
+   * updated.
+   * @throws ADSContextException if somethings goes wrong.
+   */
+  public void updateServerGroup(
+      Map<ServerGroupProperty, Object> serverGroupProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
+    BasicAttributes attrs =
+      makeAttrsFromServerGroupProperties(serverGroupProperties);
+    try
+    {
+      dirContext.modifyAttributes(dn, DirContext.REPLACE_ATTRIBUTE, attrs);
+    }
+    catch (NameAlreadyBoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ALREADY_REGISTERED);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Deletes a Server Group in the ADS.
+   * @param serverGroupProperties the properties of the server group to be
+   * deleted.
+   * @throws ADSContextException if somethings goes wrong.
+   */
+  public void deleteServerGroup(
+      Map<ServerGroupProperty, Object> serverGroupProperties)
+  throws ADSContextException
+  {
+    LdapName dn = makeDNFromServerGroupProperties(serverGroupProperties);
+    try
+    {
+      dirContext.destroySubcontext(dn);
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Returns a set containing the server groups that are defined in the ADS.
+   * @return a set containing the server groups that are defined in the ADS.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public Set<Map<ServerGroupProperty, Object>> readServerGroupRegistry()
+  throws ADSContextException
+  {
+    Set<Map<ServerGroupProperty, Object>> result =
+      new HashSet<Map<ServerGroupProperty, Object>>();
+    try
+    {
+      NamingEnumeration ne;
+      SearchControls sc = new SearchControls();
+
+      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+      ne = dirContext.search(getServerGroupContainerDN(), "(objectclass=*)",
+          sc);
+      while (ne.hasMore())
+      {
+        SearchResult sr = (SearchResult)ne.next();
+        Map<ServerGroupProperty, Object> properties =
+          makePropertiesFromServerGroupAttrs(sr.getAttributes());
+        result.add(properties);
+      }
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.BROKEN_INSTALL);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
+
+
+  /**
+   * Returns a set containing the administrators that are defined in the ADS.
+   * @return a set containing the administrators that are defined in the ADS.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public Set<Map<AdministratorProperty, Object>> readAdministratorRegistry()
+  throws ADSContextException
+  {
+    Set<Map<AdministratorProperty, Object>> result =
+      new HashSet<Map<AdministratorProperty, Object>>();
+    try {
+      NamingEnumeration ne;
+      SearchControls sc = new SearchControls();
+
+      sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
+      ne = dirContext.search(getAdministratorContainerDN(), "(objectclass=*)",
+          sc);
+      while (ne.hasMore())
+      {
+        SearchResult sr = (SearchResult)ne.next();
+
+        Map<AdministratorProperty, Object> properties =
+          makePropertiesFromAdministratorAttrs(
+              sr.getName(), sr.getAttributes());
+
+        result.add(properties);
+      }
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.BROKEN_INSTALL);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+  /**
+   * Creates the Administration Data in the server.
+   * NOTE: until we use the Administration Framework this does not work.
+   * TODO: remove the installPath parameter once we are integrated in the
+   * Administration Framework.
+   * The call to this method assumes that OpenDS.jar has already been loaded.
+   * So this should not be called by the Java Web Start before being sure that
+   * this jar is loaded.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void createAdminData() throws ADSContextException
+  {
+    // Add the administration suffix
+    createAdministrationSuffix();
+
+    // Create the DIT below the administration suffix
+    createTopContainerEntry();
+    createAdministratorContainerEntry();
+    createContainerEntry(getServerContainerDN());
+    createContainerEntry(getServerGroupContainerDN());
+  }
+
+  /**
+   * NOTE: this can only be called locally.
+   * The call to this method assumes that OpenDS.jar has already been loaded.
+   * So this should not be called by the Java Web Start before being sure that
+   * this jar is loaded.
+   * @param serverProperties the properties of the server to register.
+   * @param installPath the installation path of the server.
+   * @param backendName the backend where we create the administration data.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public static void createOfflineAdminData(
+      Map<ServerProperty, Object> serverProperties, String installPath,
+      String backendName)
+  throws ADSContextException
+  {
+    // Add the administration suffix
+    createOfflineAdministrationSuffix(installPath);
+
+    // Create the DIT below the administration suffix
+    try
+    {
+      File ldifFile = File.createTempFile("ads", ".ldif");
+      ldifFile.deleteOnExit();
+
+      LinkedList<String> lines = new LinkedList<String>();
+
+      lines.add("dn: "+getAdministrationSuffixDN());
+      lines.add("objectclass: extensibleobject");
+      lines.add("aci: "+getTopContainerACI());
+      lines.add("");
+
+      lines.add("dn: "+getAdministratorContainerDN());
+      lines.add("objectclass: groupOfUniqueNames");
+      lines.add("objectclass: groupofurls");
+      lines.add("memberURL: ldap:///" + getAdministratorContainerDN() +
+      "??one?(objectclass=*)");
+      lines.add("description: Group of identities which have full access.");
+
+      lines.add("dn: "+getServerContainerDN());
+      lines.add("objectclass: extensibleobject");
+      lines.add("");
+
+      lines.add("dn: "+getServerGroupContainerDN());
+      lines.add("objectclass: extensibleobject");
+      lines.add("");
+
+      LdapName dn = makeDNFromServerProperties(serverProperties);
+      BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
+      lines.add("dn: "+dn.toString());
+      NamingEnumeration<String> ids = attrs.getIDs();
+      while (ids.hasMoreElements())
+      {
+        String attrID = ids.nextElement();
+        Attribute attr = attrs.get(attrID);
+        try
+        {
+          NamingEnumeration values = attr.getAll();
+          while (values.hasMoreElements())
+          {
+            lines.add(attrID+": "+values.nextElement());
+          }
+        }
+        catch (NamingException ne)
+        {
+          // This should not happen
+          throw new ADSContextException(
+              ADSContextException.ErrorType.ERROR_UNEXPECTED, ne);
+        }
+      }
+
+      BufferedWriter writer = new BufferedWriter(new FileWriter(ldifFile));
+      for (String line : lines)
+      {
+        writer.write(line);
+        writer.newLine();
+      }
+
+      writer.flush();
+      writer.close();
+
+      ArrayList<String> argList = new ArrayList<String>();
+      argList.add("-C");
+      argList.add(
+          org.opends.server.extensions.ConfigFileHandler.class.getName());
+
+      argList.add("-c");
+      argList.add(installPath+File.separator+"config"+File.separator+
+          "config.ldif");
+
+      argList.add("-n");
+      argList.add(backendName);
+      argList.add("-t");
+      argList.add(ldifFile.getAbsolutePath());
+      argList.add("-S");
+      argList.add("0");
+
+      String[] args = new String[argList.size()];
+      argList.toArray(args);
+
+      try
+      {
+
+        int result = org.opends.server.tools.ImportLDIF.mainImportLDIF(args);
+
+        if (result != 0)
+        {
+          throw new ADSContextException(
+              ADSContextException.ErrorType.ERROR_UNEXPECTED);
+        }
+      } catch (Throwable t)
+      {
+//      This should not happen
+        throw new ADSContextException(
+            ADSContextException.ErrorType.ERROR_UNEXPECTED, t);
+      }
+    }
+    catch (IOException ioe)
+    {
+//    This should not happen
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, ioe);
+    }
+  }
+
+  /**
+   * Removes the administration data.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void removeAdminData() throws ADSContextException
+  {
+    removeAdministrationSuffix();
+  }
+
+
+  /**
+   * Returns <CODE>true</CODE> if the server contains Administration Data and
+   * <CODE>false</CODE> otherwise.
+   * @return <CODE>true</CODE> if the server contains Administration Data and
+   * <CODE>false</CODE> otherwise.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public boolean hasAdminData() throws ADSContextException
+  {
+    return isExistingEntry(nameFromDN(getAdministrationSuffixDN()));
+  }
+
+  /**
+   * Returns the DN of the administrator for a given UID.
+   * @param uid the UID to be used to generate the DN.
+   * @return the DN of the administrator for the given UID:
+   */
+  public static String getAdministratorDN(String uid)
+  {
+    return "cn=" + Rdn.escapeValue(uid) + "," + getAdministratorContainerDN();
+  }
+
+  /**
+   * Creates an Administrator in the ADS.
+   * @param adminProperties the properties of the administrator to be created.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void createAdministrator(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException {
+    LdapName dnCentralAdmin =
+      makeDNFromAdministratorProperties(adminProperties);
+    BasicAttributes attrs = makeAttrsFromAdministratorProperties(
+        adminProperties);
+
+    try
+    {
+      DirContext ctx = dirContext.createSubcontext(dnCentralAdmin, attrs);
+      ctx.close();
+    }
+    catch (NameAlreadyBoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ALREADY_REGISTERED);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Deletes the administrator in the ADS.
+   * @param adminProperties the properties of the administrator to be deleted.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void deleteAdministrator(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException {
+
+    LdapName dnCentralAdmin =
+      makeDNFromAdministratorProperties(adminProperties);
+
+    try
+    {
+      dirContext.destroySubcontext(dnCentralAdmin);
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOT_YET_REGISTERED);
+    }
+    catch (NotContextException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOT_YET_REGISTERED);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Updates and administrator registered in the ADS.
+   * @param adminProperties the new properties of the administrator.
+   * @throws ADSContextException if something goes wrong.
+   */
+  public void updateAdministrator(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException
+  {
+
+    LdapName dnCentralAdmin =
+      makeDNFromAdministratorProperties(adminProperties);
+    BasicAttributes attrs = makeAttrsFromAdministratorProperties(
+        adminProperties);
+
+    try
+    {
+      dirContext.modifyAttributes(dnCentralAdmin, DirContext.REPLACE_ATTRIBUTE,
+          attrs);
+    }
+    catch (NameNotFoundException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOT_YET_REGISTERED);
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch (NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Returns the DN of the suffix that contains the administration data.
+   * @return the DN of the suffix that contains the administration data.
+   */
+  public static String getAdministrationSuffixDN()
+  {
+    return "cn=admin data";
+  }
+
+  /**
+   * Used to modify the configuration on the server that must be managed; this
+   * setups the ACIs on the server so that the Administrator can access the
+   * server configuration.
+   * TODO: complete this.
+   * @param dirCtx the DirContext to the server that must be updated.
+   * @param enable whether to enable or disable the access to the server.
+   * @return <CODE>true</CODE> if something modified and <CODE>false</CODE>
+   * otherwise.
+   * @throws ADSContextException if the ACIs could not be set up.
+   */
+  public static boolean setupACIOnServer(LdapContext dirCtx,
+      boolean enable) throws ADSContextException
+  {
+    boolean result;
+    Attributes currentAttrs;
+    Attribute currentAttr, newAttr;
+    ModificationItem modItem;
+
+    try
+    {
+      // Get the ACI value on the root entry
+      currentAttrs = dirCtx.getAttributes("", new String[] { "aci" });
+      currentAttr = currentAttrs.get("aci");
+
+      // Check what ACIs values must be added or removed
+      newAttr = new BasicAttribute("aci");
+      modItem = null;
+      if (enable)
+      {
+        if ((currentAttr == null) || !currentAttr.contains(getAdminACI1()))
+        {
+          newAttr.add(getAdminACI1());
+        }
+        if ((currentAttr == null) || !currentAttr.contains(getAdminACI2()))
+        {
+          newAttr.add(getAdminACI2());
+        }
+        if (newAttr.size() >= 1)
+        {
+          modItem = new ModificationItem(LdapContext.ADD_ATTRIBUTE, newAttr);
+        }
+      }
+      else
+      {
+        if ((currentAttr != null) && currentAttr.contains(getAdminACI1()))
+        {
+          newAttr.add(getAdminACI1());
+        }
+        if ((currentAttr != null) && currentAttr.contains(getAdminACI2()))
+        {
+          newAttr.add(getAdminACI2());
+        }
+        if (newAttr.size() >= 1)
+        {
+          modItem = new ModificationItem(LdapContext.REMOVE_ATTRIBUTE, newAttr);
+        }
+      }
+
+      // Update the ACI values on the root entry
+      if (modItem != null)
+      {
+        dirCtx.modifyAttributes("", new ModificationItem[] { modItem});
+        result = true;
+      }
+      else
+      {
+        result = false;
+      }
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
+
+  /**
+   * This method returns the DN of the entry that corresponds to the given host
+   * name and installation path.
+   * @param hostname the host name.
+   * @param ipath the installation path.
+   * @return the DN of the entry that corresponds to the given host name and
+   * installation path.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static LdapName makeDNFromHostnameAndPath(String hostname,
+      String ipath) throws ADSContextException
+  {
+    String cnValue = Rdn.escapeValue(hostname + HNP_SEPARATOR + ipath);
+    return nameFromDN("cn=" + cnValue + "," + getServerContainerDN());
+  }
+
+
+  /**
+   * This method returns the DN of the entry that corresponds to the given
+   * server group properties.
+   * @param serverGroupProperties the server group properties
+   * @return the DN of the entry that corresponds to the given server group
+   * properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private LdapName makeDNFromServerGroupProperties(
+      Map<ServerGroupProperty, Object> serverGroupProperties)
+  throws ADSContextException
+  {
+    String serverGroupId = (String)serverGroupProperties.get(
+        ServerGroupProperty.UID);
+    if (serverGroupId == null)
+    {
+      throw new ADSContextException(ADSContextException.ErrorType.MISSING_NAME);
+    }
+    return nameFromDN("cn=" + Rdn.escapeValue(serverGroupId) + "," +
+          getServerGroupContainerDN());
+  }
+
+  /**
+   * This method returns the DN of the entry that corresponds to the given
+   * server properties.
+   * @param serverProperties the server properties.
+   * @return the DN of the entry that corresponds to the given server
+   * properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static LdapName makeDNFromServerProperties(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    String hostname = getHostname(serverProperties);
+    String ipath = getInstallPath(serverProperties);
+    return makeDNFromHostnameAndPath(hostname, ipath);
+  }
+
+  /**
+   * This method returns the DN of the entry that corresponds to the given
+   * administrator properties.
+   * @param adminProperties the administrator properties.
+   * @return the DN of the entry that corresponds to the given administrator
+   * properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private LdapName makeDNFromAdministratorProperties(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException
+  {
+    String adminUid = getAdministratorUID(adminProperties);
+
+    String dnCentralAdmin = getAdministratorDN(adminUid);
+
+    return nameFromDN(dnCentralAdmin);
+  }
+
+  /**
+   * Returns the attributes for some administrator properties.
+   * @param adminProperties the administrator properties.
+   * @return the attributes for the given administrator properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private BasicAttributes makeAttrsFromAdministratorProperties(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException
+  {
+    BasicAttributes attrs = new BasicAttributes();
+    String adminPassword = getAdministratorPassword(adminProperties);
+    attrs.put("objectclass", "person");
+    attrs.put("sn", "admin");
+    attrs.put("userPassword", adminPassword);
+    return attrs;
+  }
+
+  /**
+   * Returns the attributes for some server properties.
+   * @param serverProperties the server properties.
+   * @return the attributes for the given server properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static BasicAttributes makeAttrsFromServerProperties(
+      Map<ServerProperty, Object> serverProperties)
+  {
+    BasicAttributes result = new BasicAttributes();
+
+    // Transform 'properties' into 'attributes'
+    for (ServerProperty prop: serverProperties.keySet())
+    {
+      Attribute attr = makeAttrFromServerProperty(prop,
+          serverProperties.get(prop));
+      if (attr != null)
+      {
+        result.put(attr);
+      }
+    }
+    // Add the objectclass attribute value
+    result.put("objectclass", "extensibleobject");
+    return result;
+  }
+
+  /**
+   * Returns the attribute for a given server property.
+   * @param property the server property.
+   * @return the attribute for a given server property.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static Attribute makeAttrFromServerProperty(ServerProperty property,
+      Object value)
+  {
+    Attribute result;
+
+    switch(property)
+    {
+    case HOSTNAME:
+      result = null;
+      break;
+    case INSTANCE_PATH:
+      result = null;
+      break;
+    case GROUPS:
+      result = new BasicAttribute(ServerProperty.GROUPS.getAttributeName());
+      Iterator groupIterator = ((Set)value).iterator();
+      while (groupIterator.hasNext())
+      {
+        result.add(groupIterator.next());
+      }
+      break;
+    default:
+      result = new BasicAttribute(property.getAttributeName(), value);
+    }
+    return result;
+  }
+
+  /**
+   * Returns the attributes for some server group properties.
+   * @param serverProperties the server group properties.
+   * @return the attributes for the given server group properties.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private BasicAttributes makeAttrsFromServerGroupProperties(
+      Map<ServerGroupProperty, Object> serverGroupProperties)
+  {
+    BasicAttributes result = new BasicAttributes();
+
+    // Transform 'properties' into 'attributes'
+    for (ServerGroupProperty prop: serverGroupProperties.keySet())
+    {
+      Attribute attr = makeAttrFromServerGroupProperty(prop,
+          serverGroupProperties.get(prop));
+      if (attr != null)
+      {
+        result.put(attr);
+      }
+    }
+    // Add the objectclass attribute value
+    result.put("objectclass", "extensibleobject");
+    return result;
+  }
+
+  /**
+   * Returns the attribute for a given server group property.
+   * @param property the server group property.
+   * @return the attribute for a given server group property.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private Attribute makeAttrFromServerGroupProperty(
+      ServerGroupProperty property, Object value)
+  {
+    Attribute result;
+
+    switch(property)
+    {
+    case MEMBERS:
+      result = new BasicAttribute(
+          ServerGroupProperty.MEMBERS.getAttributeName());
+      Iterator memberIterator = ((Set)value).iterator();
+      while (memberIterator.hasNext())
+      {
+        result.add(memberIterator.next());
+      }
+      break;
+    default:
+      result = new BasicAttribute(property.getAttributeName(), value);
+    }
+
+    return result;
+  }
+
+  /**
+   * Returns the properties of a server group for some LDAP attributes.
+   * @param attrs the LDAP attributes.
+   * @return the properties of a server group for some LDAP attributes.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private Map<ServerGroupProperty, Object> makePropertiesFromServerGroupAttrs(
+      Attributes attrs) throws ADSContextException
+  {
+    HashMap<ServerGroupProperty, Object> result =
+      new HashMap<ServerGroupProperty, Object>();
+    try
+    {
+      NamingEnumeration ne = attrs.getAll();
+      while (ne.hasMore())
+      {
+        Attribute attr = (Attribute)ne.next();
+        String attrID = attr.getID();
+        Object value = null;
+
+        ServerGroupProperty prop = null;
+        ServerGroupProperty[] props = ServerGroupProperty.values();
+        for (int i=0; i<props.length && (prop == null); i++)
+        {
+          String v = props[i].getAttributeName();
+          if (attrID.equalsIgnoreCase(v))
+          {
+            prop = props[i];
+          }
+        }
+        if (prop == null)
+        {
+          throw new ADSContextException(
+              ADSContextException.ErrorType.ERROR_UNEXPECTED);
+        }
+
+        if (attr.size() >= 1 &&
+            MULTIVALUED_SERVER_GROUP_PROPERTIES.contains(prop))
+        {
+
+          Set<String> set = new HashSet<String>();
+          NamingEnumeration ae = attr.getAll();
+          while (ae.hasMore())
+          {
+            set.add((String)ae.next());
+          }
+          value = set;
+        }
+        else
+        {
+          value = attr.get(0);
+        }
+
+        result.put(prop, value);
+      }
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
+
+  /**
+   * Returns the properties of a server for some LDAP attributes.
+   * @param attrs the LDAP attributes.
+   * @return the properties of a server for some LDAP attributes.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private Map<ServerProperty, Object> makePropertiesFromServerAttrs(
+      Attributes attrs) throws ADSContextException
+  {
+    HashMap<ServerProperty, Object> result =
+      new HashMap<ServerProperty, Object>();
+    try
+    {
+      NamingEnumeration ne = attrs.getAll();
+      while (ne.hasMore())
+      {
+        Attribute attr = (Attribute)ne.next();
+        String attrID = attr.getID();
+        Object value = null;
+
+        if (attrID.endsWith(";binary"))
+        {
+          attrID = attrID.substring(0, attrID.lastIndexOf(";binary"));
+        }
+
+        ServerProperty prop = null;
+        ServerProperty[] props = ServerProperty.values();
+        for (int i=0; i<props.length && (prop == null); i++)
+        {
+          String v = props[i].getAttributeName();
+          if (attrID.equalsIgnoreCase(v))
+          {
+            prop = props[i];
+          }
+        }
+        if (prop == null)
+        {
+          throw new ADSContextException(
+              ADSContextException.ErrorType.ERROR_UNEXPECTED);
+        }
+
+        if (attr.size() >= 1 && MULTIVALUED_SERVER_PROPERTIES.contains(prop))
+        {
+          Set<String> set = new HashSet<String>();
+          NamingEnumeration ae = attr.getAll();
+          while (ae.hasMore())
+          {
+            set.add((String)ae.next());
+          }
+          value = set;
+        }
+        else
+        {
+          value = attr.get(0);
+        }
+
+        result.put(prop, value);
+      }
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
+
+  /**
+   * Returns the properties of a server group for an RDN and some LDAP
+   * attributes.
+   * @param rdnName the RDN.
+   * @param attrs the LDAP attributes.
+   * @return the properties of a server group for an RDN and some LDAP
+   * attributes.
+   * @throws ADSContextException if something goes wrong.
+   */
+  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String rdnName,
+      Attributes attrs) throws ADSContextException
+  {
+    String hostName, ipath;
+    LdapName nameObj;
+
+    nameObj = nameFromDN(rdnName);
+
+    //
+    // Extract the hostname and ipath from the dn
+    //
+    Rdn rdnObj = nameObj.getRdn(nameObj.size() - 1);
+    String hostNamePath = (String)Rdn.unescapeValue((String)rdnObj.getValue());
+    int sepIndex = hostNamePath.indexOf(HNP_SEPARATOR);
+    if (sepIndex != -1)
+    {
+      hostName = hostNamePath.substring(0, sepIndex);
+      ipath = hostNamePath.substring(sepIndex+1, hostNamePath.length());
+    }
+    else
+    { // Emergency logic...
+      hostName = hostNamePath;
+      ipath = "undefined";
+    }
+
+    //
+    // Delegate...
+    //
+    return makePropertiesFromServerAttrs(hostName, ipath, attrs);
+  }
+
+  /**
+   * Returns the properties of a server for some host name, installation path
+   * and LDAP attributes.
+   * @param hostName the host name.
+   * @param ipath the installation path.
+   * @param attrs the LDAP attributes.
+   * @return the properties of a server for the given host name, installation
+   * path and LDAP attributes.
+   * @throws ADSContextException if something goes wrong.
+   */
+  Map<ServerProperty, Object> makePropertiesFromServerAttrs(String hostName,
+      String ipath, Attributes attrs) throws ADSContextException
+  {
+    Map<ServerProperty, Object> result = new HashMap<ServerProperty, Object>();
+
+    //
+    // Put hostname and ipath
+    //
+    result.put(ServerProperty.HOSTNAME, hostName);
+    result.put(ServerProperty.INSTANCE_PATH, ipath);
+
+    //
+    // Get other properties from the attributes
+    //
+    result.putAll(makePropertiesFromServerAttrs(attrs));
+
+    return result;
+  }
+
+
+  /**
+   * Returns the properties of an administrator for some rdn and LDAP
+   * attributes.
+   * @param rdn the RDN.
+   * @param attrs the LDAP attributes.
+   * @return the properties of an administrator for the given rdn and LDAP
+   * attributes.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private Map<AdministratorProperty, Object>
+  makePropertiesFromAdministratorAttrs(String rdn, Attributes attrs)
+  throws ADSContextException
+  {
+    Map<AdministratorProperty, Object> result =
+      new HashMap<AdministratorProperty, Object>();
+    String dn = rdn + "," + getAdministratorContainerDN();
+    result.put(AdministratorProperty.ADMINISTRATOR_DN, dn);
+
+    try
+    {
+      NamingEnumeration ne = attrs.getAll();
+      while (ne.hasMore()) {
+        Attribute attr = (Attribute)ne.next();
+        String attrID = attr.getID();
+        Object value = null;
+
+        if (attrID.equalsIgnoreCase("cn"))
+        {
+          value = attr.get(0);
+          result.put(AdministratorProperty.UID, value);
+        }
+        else if (attrID.equalsIgnoreCase("userpassword"))
+        {
+          value = attr.get(0);
+          result.put(AdministratorProperty.PASSWORD, value);
+        }
+        else if (attrID.equalsIgnoreCase("description"))
+        {
+          value = attr.get(0);
+          result.put(AdministratorProperty.DESCRIPTION, value);
+        }
+      }
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+  /**
+   * Returns the parent entry of the server entries.
+   * @return the parent entry of the server entries.
+   */
+  private static String getServerContainerDN()
+  {
+    return "cn=Servers," + getAdministrationSuffixDN();
+  }
+
+  /**
+   * Returns the parent entry of the administrator entries.
+   * @return the parent entry of the administrator entries.
+   */
+  private static String getAdministratorContainerDN()
+  {
+    return "cn=Administrators," + getAdministrationSuffixDN();
+  }
+
+  /**
+   * Returns the parent entry of the server group entries.
+   * @return the parent entry of the server group entries.
+   */
+  private static String getServerGroupContainerDN()
+  {
+    return "cn=Server Groups," + getAdministrationSuffixDN();
+  }
+
+  /**
+   * Returns the host name for the given properties.
+   * @param serverProperties the server properties.
+   * @return the host name for the given properties.
+   * @throws ADSContextException if the host name could not be found or its
+   * value is not valid.
+   */
+  private static String getHostname(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    String result = (String)serverProperties.get(ServerProperty.HOSTNAME);
+    if (result == null)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.MISSING_HOSTNAME);
+    }
+    else if (result.length() == 0)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOVALID_HOSTNAME);
+    }
+    return result;
+  }
+
+  /**
+   * Returns the install path for the given properties.
+   * @param serverProperties the server properties.
+   * @return the install path for the given properties.
+   * @throws ADSContextException if the install path could not be found or its
+   * value is not valid.
+   */
+  private static String getInstallPath(
+      Map<ServerProperty, Object> serverProperties) throws ADSContextException
+  {
+    String result = (String)serverProperties.get(ServerProperty.INSTANCE_PATH);
+    if (result == null)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.MISSING_IPATH);
+    }
+    else if (result.length() == 0)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.NOVALID_IPATH);
+    }
+    return result;
+  }
+
+
+  /**
+   * Returns the Administrator UID for the given properties.
+   * @param adminProperties the server properties.
+   * @return the Administrator UID for the given properties.
+   * @throws ADSContextException if the administrator UID could not be found.
+   */
+  private String getAdministratorUID(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException {
+    String result = (String)adminProperties.get(
+        AdministratorProperty.UID);
+    if (result == null)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.MISSING_ADMIN_UID);
+    }
+    return result;
+  }
+
+  /**
+   * Returns the Administrator password for the given properties.
+   * @param adminProperties the server properties.
+   * @return the Administrator password for the given properties.
+   * @throws ADSContextException if the administrator password could not be
+   * found.
+   */
+  private String getAdministratorPassword(
+      Map<AdministratorProperty, Object> adminProperties)
+  throws ADSContextException {
+    String result = (String)adminProperties.get(
+        AdministratorProperty.PASSWORD);
+    if (result == null)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.MISSING_ADMIN_PASSWORD);
+    }
+    return result;
+  }
+
+
+  //
+  // LDAP utilities
+  //
+  /**
+   * Returns the LdapName object for the given dn.
+   * @return the LdapName object for the given dn.
+   * @throws ADSContextException if a valid LdapName could not be retrieved
+   * for the given dn.
+   */
+  private static LdapName nameFromDN(String dn) throws ADSContextException
+  {
+    LdapName result = null;
+    try
+    {
+      result = new LdapName(dn);
+    }
+    catch (InvalidNameException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+    return result;
+  }
+
+  /**
+   * Tells whether an entry with the provided DN exists.
+   * @return <CODE>true</CODE> if the entry exists and <CODE>false</CODE> if
+   * it does not.
+   * @throws ADSContextException if an error occurred while checking if the
+   * entry exists or not.
+   */
+  private boolean isExistingEntry(LdapName dn) throws ADSContextException
+  {
+    boolean result;
+
+    try
+    {
+      SearchControls sc = new SearchControls();
+
+      sc.setSearchScope(SearchControls.OBJECT_SCOPE);
+      result = getDirContext().search(dn, "(objectclass=*)", sc).hasMore();
+    }
+    catch (NameNotFoundException x)
+    {
+      result = false;
+    }
+    catch (NoPermissionException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ACCESS_PERMISSION);
+    }
+    catch(javax.naming.NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+
+    return result;
+  }
+
+  /**
+   * Creates a container entry with the given dn.
+   * @param dn the entry of the new entry to be created.
+   * @throws ADSContextException if the entry could not be created.
+   */
+  private void createContainerEntry(String dn) throws ADSContextException
+  {
+    BasicAttributes attrs = new BasicAttributes();
+
+    attrs.put("objectclass", "extensibleobject");
+    createEntry(dn, attrs);
+  }
+
+  /**
+   * Creates the administrator container entry.
+   * @throws ADSContextException if the entry could not be created.
+   */
+  private void createAdministratorContainerEntry() throws ADSContextException
+  {
+    BasicAttributes attrs = new BasicAttributes();
+
+    attrs.put("objectclass", "groupOfUniqueNames");
+    attrs.put("objectclass", "groupofurls");
+    attrs.put("memberURL", "ldap:///" + getAdministratorContainerDN() +
+        "??one?(objectclass=*)");
+    attrs.put("description", "Group of identities which have full access.");
+    createEntry(getAdministratorContainerDN(), attrs);
+  }
+
+
+  /**
+   * Creates the top container entry.
+   * @throws ADSContextException if the entry could not be created.
+   */
+  private void createTopContainerEntry() throws ADSContextException
+  {
+    BasicAttributes attrs = new BasicAttributes();
+
+    attrs.put("objectclass", "extensibleobject");
+    attrs.put("aci", getTopContainerACI());
+    createEntry(getAdministrationSuffixDN(), attrs);
+  }
+
+
+  /**
+   * Creates an entry with the provided dn and attributes.
+   * @param dn the dn of the entry.
+   * @param attrs the attributes of the entry.
+   * @throws ADSContextException if the entry could not be created.
+   */
+  private void createEntry(String dn, Attributes attrs)
+  throws ADSContextException {
+    try
+    {
+      DirContext ctx = getDirContext().createSubcontext(nameFromDN(dn), attrs);
+      ctx.close();
+    }
+    catch(NamingException x)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED, x);
+    }
+  }
+
+  /**
+   * Returns the DN of the ACI container entry.
+   * @return the DN of the ACI container entry.
+   */
+  private static String getTopContainerACI()
+  {
+    return
+    "(targetattr = \"*\")" +
+    "(version 3.0;" +
+    "acl \"Enable full access for Directory Services Managers group\";" +
+    "allow (all)" +
+    "(groupdn = \"ldap:///" + getAdministratorContainerDN() + "\");" +
+    ")";
+  }
+
+  /**
+   * Creates the Administration Suffix.
+   * @throws ADSContextException if something goes wrong.
+   */
+  private void createAdministrationSuffix()
+  throws ADSContextException
+  {
+    // TODO: use new administration framework.
+  }
+
+  /**
+   * Creates the Administration Suffix when the server is down.  This can only
+   * be called locally.
+   * @param installPath the installation path of the server
+   * @throws ADSContextException if something goes wrong.
+   */
+  private static void createOfflineAdministrationSuffix(String installPath)
+  throws ADSContextException
+  {
+    // TODO: the call to this method assumes
+    // that OpenDS.jar has already been loaded.  So this should not be called by
+    // the Java Web Start before being sure that this jar is loaded.
+    ArrayList<String> argList = new ArrayList<String>();
+    argList.add("-C");
+    argList.add(org.opends.server.extensions.ConfigFileHandler.class.getName());
+
+    argList.add("-c");
+    argList.add(installPath+File.separator+"config"+File.separator+
+        "config.ldif");
+
+    argList.add("-b");
+    argList.add(getAdministrationSuffixDN());
+
+    String[] args = new String[argList.size()];
+    argList.toArray(args);
+
+    int returnValue = org.opends.server.tools.ConfigureDS.configMain(args);
+
+    if (returnValue != 0)
+    {
+      throw new ADSContextException(
+          ADSContextException.ErrorType.ERROR_UNEXPECTED);
+    }
+  }
+
+  /**
+   * Removes the administration suffix.
+   * @throws ADSContextException
+   */
+  private void removeAdministrationSuffix() throws ADSContextException
+  {
+    // TODO: use new administration framework
+  }
+
+  /**
+   * Returns the first ACI required to provide access to administrators.
+   * @return the first ACI required to provide access to administrators.
+   */
+  private static String getAdminACI1()
+  {
+    return
+    "(targetattr = \"*\") " +
+    "(version 3.0; " +
+    "acl \"Enable full access for Global Administrators.\"; " +
+    "allow (all)(userdn = \"ldap:///" +
+    getAdministratorDN("*") +
+    "\");)";
+  }
+
+
+  /**
+   * Returns the second ACI required to provide access to administrators.
+   * @return the second ACI required to provide access to administrators.
+   */
+  private static String getAdminACI2()
+  {
+    return
+    "(targetattr = \"aci\") (targetscope = \"base\") " +
+    "(version 3.0; " +
+    "acl \"Enable root ACI modification by Global Administrators.\"; "+
+    "allow (all)(userdn = \"ldap:///" +
+    getAdministratorDN("*") +
+    "\");)";
+  }
+}
diff --git a/opends/src/ads/org/opends/admin/ads/ADSContextException.java b/opends/src/ads/org/opends/admin/ads/ADSContextException.java
new file mode 100644
index 0000000..0243f09
--- /dev/null
+++ b/opends/src/ads/org/opends/admin/ads/ADSContextException.java
@@ -0,0 +1,176 @@
+/*
+ * 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.admin.ads;
+
+/**
+ * This is the exception that is thrown in ADSContext.
+ * @see ADSContext.
+ *
+ */
+public class ADSContextException extends Exception {
+
+  private static final long serialVersionUID = 1984039711031042813L;
+
+  private String toString;
+
+  /**
+   * The enumeration containing the different error types.
+   *
+   */
+  public enum ErrorType
+  {
+    /**
+     * The host name is missing.
+     */
+    MISSING_HOSTNAME,
+    /**
+     * The host name is not valid.
+     */
+    NOVALID_HOSTNAME,
+    /**
+     * The installation path is missing.
+     */
+    MISSING_IPATH,
+    /**
+     * The installation path is not valid.
+     */
+    NOVALID_IPATH,
+    /**
+     * An access permission error.
+     */
+    ACCESS_PERMISSION,
+    /**
+     * The entity is already registered.
+     */
+    ALREADY_REGISTERED,
+    /**
+     * The installation is broken.
+     */
+    BROKEN_INSTALL,
+    /**
+     * The entity is not yet registered.
+     */
+    NOT_YET_REGISTERED,
+    /**
+     * The port is missing.
+     */
+    MISSING_PORT,
+    /**
+     * The port is not valid.
+     */
+    NOVALID_PORT,
+    /**
+     * The name is missing.
+     */
+    MISSING_NAME,
+    /**
+     * The administration UID is missing.
+     */
+    MISSING_ADMIN_UID,
+    /**
+     * The administratior password is missing.
+     */
+    MISSING_ADMIN_PASSWORD,
+    /**
+     * Unexpected error (potential bug).
+     */
+    ERROR_UNEXPECTED
+  };
+
+  ErrorType error;
+  Throwable embeddedException;
+
+  /**
+   * Creates an ADSContextException of the given error type.
+   * @param error the error type.
+   */
+  public ADSContextException(ErrorType error)
+  {
+    this.error = error;
+  }
+
+  /**
+   * Creates an ADSContextException of the given error type with the provided
+   * error cause.
+   * @param error the error type.
+   * @param x the throwable that generated this exception.
+   */
+  public ADSContextException(ErrorType error, Throwable x)
+  {
+    this.error = error;
+    this.embeddedException = x;
+  }
+
+  /**
+   * Returns the error type of this exception.
+   * @return the error type of this exception.
+   */
+  public ErrorType getError()
+  {
+    return error;
+  }
+
+  /**
+   * Returns the throwable that caused this exception.  It might be null.
+   * @return the throwable that caused this exception.
+   */
+  public Throwable getCause()
+  {
+    return embeddedException;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public String toString()
+  {
+    if (toString == null)
+    {
+      toString = "ADSContextException: error type"+error+".";
+      if (getCause() != null)
+      {
+        toString += "  Root cause: "+getCause().toString();
+      }
+    }
+    return toString;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void printStackTrace()
+  {
+    super.printStackTrace();
+    if (embeddedException != null)
+    {
+      System.out.println("embeddedException = {");
+      embeddedException.printStackTrace();
+      System.out.println("}");
+    }
+  }
+}
\ No newline at end of file
diff --git a/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java b/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
new file mode 100644
index 0000000..b7422cd
--- /dev/null
+++ b/opends/src/ads/org/opends/admin/ads/ReplicaDescriptor.java
@@ -0,0 +1,100 @@
+/*
+ * 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.admin.ads;
+
+/**
+ * The object of this class represent a Replica (i.e. a suffix in a given
+ * server).
+ */
+public class ReplicaDescriptor
+{
+  private SuffixDescriptor suffix;
+  private int entries = -1;
+  private ServerDescriptor server;
+
+  /**
+   * Returns the number of entries contained in the replica.
+   * @return the number of entries contained in the replica.
+   */
+  public int getEntries()
+  {
+    return entries;
+  }
+
+  /**
+   * Sets the number of entries contained in the replica.
+   * @param entries the number of entries contained in the replica.
+   */
+  public void setEntries(int entries)
+  {
+    this.entries = entries;
+  }
+
+  /**
+   * Returns the ServerDescriptor object associated with the server where this
+   * replica is located.
+   * @return the ServerDescriptor object associated with the server where this
+   * replica is located.
+   */
+  public ServerDescriptor getServer()
+  {
+    return server;
+  }
+
+  /**
+   * Sets the server where this replica is located.
+   * @param server the ServerDescriptor object associated with the server where
+   * this replica is located.
+   */
+  public void setServer(ServerDescriptor server)
+  {
+    this.server = server;
+  }
+
+  /**
+   * Returns the SuffixDescriptor object representing the suffix topology
+   * across servers to which this replica belongs.
+   * @return the SuffixDescriptor object representing the suffix topology
+   * across servers to which this replica belongs.
+   */
+  public SuffixDescriptor getSuffix()
+  {
+    return suffix;
+  }
+
+  /**
+   * Sets the SuffixDescriptor object representing the suffix topology
+   * across servers to which this replica belongs.
+   * @param suffix the SuffixDescriptor object representing the suffix topology
+   * across servers to which this replica belongs.
+   */
+  public void setSuffix(SuffixDescriptor suffix)
+  {
+    this.suffix = suffix;
+  }
+}
diff --git a/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
new file mode 100644
index 0000000..353277c
--- /dev/null
+++ b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -0,0 +1,90 @@
+/*
+ * 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.admin.ads;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * The object of this class represent an OpenDS server.
+ */
+public class ServerDescriptor
+{
+  private Map<ADSContext.ServerProperty, Object> adsProperties =
+    new HashMap<ADSContext.ServerProperty, Object>();
+  private Set<ReplicaDescriptor> replicas = new HashSet<ReplicaDescriptor>();
+
+  /**
+   * Returns the replicas contained on the server.
+   * @return the replicas contained on the server.
+   */
+  public Set<ReplicaDescriptor> getReplicas()
+  {
+    return replicas;
+  }
+
+  /**
+   * Sets the replicas contained on the server.
+   * @param replicas the replicas contained on the server.
+   */
+  public void setReplicas(Set<ReplicaDescriptor> replicas)
+  {
+    this.replicas = replicas;
+  }
+
+  /**
+   * Returns a Map containing the properties of the server.
+   * @return a Map containing the properties of the server.
+   */
+  public Map<ADSContext.ServerProperty, Object> getAdsProperties()
+  {
+    return adsProperties;
+  }
+
+  /**
+   * Tells whether this server is registered in the ADS or not.
+   * @return <CODE>true</CODE> if the server is registered in the ADS and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean isRegistered()
+  {
+    return !adsProperties.isEmpty();
+  }
+
+  /**
+   * Sets the properties of the server.
+   * @param adsProperties a Map containing the properties of the server.
+   */
+  public void setAdsProperties(
+      Map<ADSContext.ServerProperty, Object> adsProperties)
+  {
+    this.adsProperties = adsProperties;
+  }
+}
diff --git a/opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java b/opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java
new file mode 100644
index 0000000..16ca26a
--- /dev/null
+++ b/opends/src/ads/org/opends/admin/ads/SuffixDescriptor.java
@@ -0,0 +1,151 @@
+/*
+ * 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.admin.ads;
+
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * The object of this class represent a topology of replicas across servers
+ * that have the same suffix DN.  They may or might not be replicated.
+ */
+public class SuffixDescriptor
+{
+  private String suffixDN;
+  private Set<ReplicaDescriptor> replicas = new HashSet<ReplicaDescriptor>();
+
+  /**
+   * Returns the DN associated with this suffix descriptor.
+   * @return the DN associated with this suffix descriptor.
+   */
+  public String getDN()
+  {
+    return suffixDN;
+  }
+
+  /**
+   * Sets the DN associated with this suffix descriptor.
+   * @param suffixDN the DN associated with this suffix descriptor.
+   */
+  public void setDN(String suffixDN)
+  {
+    this.suffixDN = suffixDN;
+  }
+
+  /**
+   * Returns the replicas associated with this SuffixDescriptor.
+   * @return a Set containing the replicas associated with this
+   * SuffixDescriptor.
+   */
+  public Set<ReplicaDescriptor> getReplicas()
+  {
+    return replicas;
+  }
+
+  /**
+   * Sets the replicas associated with this SuffixDescriptor.
+   * @param replicas a Set containing the replicas associated with this
+   * SuffixDescriptor.
+   */
+  public void setReplicas(Set<ReplicaDescriptor> replicas)
+  {
+    this.replicas = replicas;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean equals(Object v)
+  {
+    // TODO: this is buggy code
+    boolean equals = false;
+    if (this != v)
+    {
+      if (v instanceof SuffixDescriptor)
+      {
+        SuffixDescriptor desc = (SuffixDescriptor)v;
+        equals = getDN().equals(desc.getDN());
+
+        if (equals)
+        {
+          equals = getReplicas().size() == desc.getReplicas().size();
+        }
+
+        if (equals)
+        {
+          for (ReplicaDescriptor repl : getReplicas())
+          {
+            boolean serverFound = false;
+            ServerDescriptor server = repl.getServer();
+            for (ReplicaDescriptor repl1 : desc.getReplicas())
+            {
+              serverFound = serversEqual(server, repl1.getServer());
+              if (serverFound)
+              {
+                break;
+              }
+            }
+            if (!serverFound)
+            {
+              equals = false;
+              break;
+            }
+          }
+        }
+
+      }
+    }
+    else
+    {
+      equals = true;
+    }
+    return equals;
+  }
+
+  /**
+   * Tells whether the two provided objects represent the same server or not.
+   * @param serv1 the first ServerDescriptor to compare.
+   * @param serv2 the second ServerDescriptor to compare.
+   * @return <CODE>true</CODE> if the two objects represent the same server
+   * and <CODE>false</CODE> otherwise.
+   */
+  private boolean serversEqual(ServerDescriptor serv1, ServerDescriptor serv2)
+  {
+    return serv1.getAdsProperties().equals(serv2.getAdsProperties());
+  }
+  /**
+   * {@inheritDoc}
+   */
+  public int hashCode()
+  {
+//  FIXME: this is buggy code
+    return getDN().hashCode();
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java b/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
index 6cdaa37..85201dd 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
@@ -109,7 +109,7 @@
       }
       else if (isInstalled)
       {
-        StringBuffer buf = new StringBuffer();
+        StringBuilder buf = new StringBuilder();
         buf.append("<ul>");
         for (String msg : msgs)
         {
@@ -412,7 +412,7 @@
   {
     if (configFileContents == null)
     {
-      StringBuffer buf = new StringBuffer();
+      StringBuilder buf = new StringBuilder();
       try
       {
         Installation installation = getInstallationFromClassPath();
diff --git a/opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java b/opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java
index 8e5e68a..92d6948 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/InstallerHelper.java
@@ -33,7 +33,6 @@
 import org.opends.quicksetup.i18n.ResourceProvider;
 import org.opends.quicksetup.webstart.JnlpProperties;
 import org.opends.quicksetup.util.Utils;
-import org.opends.server.tools.ConfigureWindowsService;
 
 /**
  * This is the only class that uses classes in org.opends.server (excluding the
@@ -94,9 +93,11 @@
     "error-enabling-windows-service");
 
     switch (code) {
-      case ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
+      case
+      org.opends.server.tools.ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
         break;
-      case ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
+      case
+      org.opends.server.tools.ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
         break;
       default:
         throw new QuickSetupException(
diff --git a/opends/src/quicksetup/org/opends/quicksetup/Step.java b/opends/src/quicksetup/org/opends/quicksetup/Step.java
index aa47899..d568dec 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/Step.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/Step.java
@@ -51,9 +51,21 @@
   SERVER_SETTINGS("server-settings-step"),
 
   /**
+   * Data Replication panel (standalone or replicated).
+   */
+  REPLICATION_OPTIONS("data-replication-step"),
+  /**
+   * Global Administrator creation panel.
+   */
+  CREATE_GLOBAL_ADMINISTRATOR("create-global-administrator-step"),
+  /**
+   * Suffixes to Replicate.
+   */
+  SUFFIXES_OPTIONS("suffixes-step"),
+  /**
    * Data Options panel (suffix dn, LDIF path, etc.).
    */
-  DATA_OPTIONS("data-options-step"),
+  NEW_SUFFIX_OPTIONS("data-options-step"),
 
   /**
    * Review panel for the install.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 5becaa4..e885b16 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -27,30 +27,60 @@
 
 package org.opends.quicksetup;
 
+import java.util.HashSet;
+
+import org.opends.admin.ads.SuffixDescriptor;
+import org.opends.quicksetup.installer.AuthenticationData;
+import org.opends.quicksetup.installer.DataReplicationOptions;
+import org.opends.quicksetup.installer.NewSuffixOptions;
+import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
 import org.opends.quicksetup.util.Utils;
 
 /**
- * Represents user specified input data to an application.
+ * This class is used to provide a data model for the different parameters
+ * that the user can provide in the installation wizard.
+ *
+ * @see DataOptions.
+ *
  */
-public class UserData {
-
+public class UserData
+{
   private String serverLocation;
+
   private int serverPort;
+
   private String directoryManagerDn;
+
   private String directoryManagerPwd;
-  private DataOptions dataOptions;
+
+  private String globalAdministratorUID;
+
+  private String globalAdministratorPassword;
+
   private SecurityOptions securityOptions;
   private int serverJMXPort;
+
   private boolean startServer;
+
   private boolean stopServer;
 
+  private NewSuffixOptions newSuffixOptions;
+
+  private DataReplicationOptions replicationOptions;
+
+  private boolean createAdministrator;
+
+  private SuffixesToReplicateOptions suffixesToReplicateOptions;
+
   /**
    * Creates a user data object with default values.
    */
   public UserData() {
     startServer = true;
 
-    DataOptions defaultDataOptions = new DefaultDataOptions();
+    NewSuffixOptions defaultNewSuffixOptions = new NewSuffixOptions(
+        NewSuffixOptions.Type.CREATE_BASE_ENTRY, "dc=example,dc=com");
+    setNewSuffixOptions(defaultNewSuffixOptions);
 
     setServerLocation(Utils.getDefaultServerLocation());
     // See what we can propose as port
@@ -62,7 +92,21 @@
 
     setDirectoryManagerDn("cn=Directory Manager");
 
-    setDataOptions(defaultDataOptions);
+    setNewSuffixOptions(defaultNewSuffixOptions);
+    AuthenticationData data = new AuthenticationData();
+    data.setDn("cn=Directory Manager");
+    data.setPort(389);
+    DataReplicationOptions repl = new DataReplicationOptions(
+        DataReplicationOptions.Type.STANDALONE, data);
+    setReplicationOptions(repl);
+    setGlobalAdministratorUID("admin");
+
+    SuffixesToReplicateOptions suffixes =
+      new SuffixesToReplicateOptions(
+          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES,
+          new HashSet<SuffixDescriptor>(),
+          new HashSet<SuffixDescriptor>());
+    setSuffixesToReplicateOptions(suffixes);
     SecurityOptions sec = SecurityOptions.createNoCertificateOptions();
     sec.setSslPort(getDefaultSslPort());
     sec.setCertificateUserName(getDefaultSelfSignedName());
@@ -106,6 +150,24 @@
   }
 
   /**
+   * Sets the server JMX port.
+   * @param serverJMXPort the new server JMX port.
+   */
+  public void setServerJMXPort(int serverJMXPort)
+  {
+    this.serverJMXPort = serverJMXPort;
+  }
+
+  /**
+   * Returns the server JMX port.
+   * @return the server JMX port.
+   */
+  public int getServerJMXPort()
+  {
+    return serverJMXPort;
+  }
+
+  /**
    * Returns the Directory Manager DN.
    * @return the Directory Manager DN.
    */
@@ -142,46 +204,6 @@
   }
 
   /**
-   * Returns the DataOptions object representing the data in the Data Options
-   * panel.
-   * @return the DataOptions object representing the data in the Data Options
-   * panel.
-   */
-  public DataOptions getDataOptions()
-  {
-    return dataOptions;
-  }
-
-  /**
-   * Sets the DataOptions object representing the data in the Data Options
-   * panel.
-   * @param dataOptions the DataOptions object representing the data in the Data
-   * Options panel.
-   */
-  public void setDataOptions(DataOptions dataOptions)
-  {
-    this.dataOptions = dataOptions;
-  }
-
-  /**
-   * Sets the server JMX port.
-   * @param serverJMXPort the new server JMX port.
-   */
-  public void setServerJMXPort(int serverJMXPort)
-  {
-    this.serverJMXPort = serverJMXPort;
-  }
-
-  /**
-   * Returns the server JMX port.
-   * @return the server JMX port.
-   */
-  public int getServerJMXPort()
-  {
-    return serverJMXPort;
-  }
-
-  /**
    * Returns <CODE>true</CODE> if the server must be started once the
    * installation is finished, <CODE>false</CODE> if not.
    * @return <CODE>true</CODE> if the server must be started once the
@@ -223,6 +245,127 @@
   }
 
   /**
+   * Returns the NewSuffixOptions object representing the data in the New Suffix
+   * Data Options panel.
+   * @return the NewSuffixOptions object representing the data in the New Suffix
+   * Data Options panel.
+   */
+  public NewSuffixOptions getNewSuffixOptions()
+  {
+    return newSuffixOptions;
+  }
+
+  /**
+   * Sets the NewSuffixOptions object representing the data in the New Suffix
+   * Data Options panel.
+   * @param newSuffixOptions the NewSuffixOptions object representing the data
+   * in the New Suffix Data Options panel.
+   */
+  public void setNewSuffixOptions(NewSuffixOptions newSuffixOptions)
+  {
+    this.newSuffixOptions = newSuffixOptions;
+  }
+
+  /**
+   * Returns the DataReplicationOptions object representing the data in the
+   * Data Replication panel.
+   * @return the DataReplicationOptions object representing the data in the
+   * Data Replication panel.
+   */
+  public DataReplicationOptions getReplicationOptions()
+  {
+    return replicationOptions;
+  }
+
+  /**
+   * Sets the DataReplicationOptions object representing the data in the
+   * Data Replication panel.
+   * @param replicationOptions the DataReplicationOptions object
+   * representing the data in the Data Replication panel.
+   */
+  public void setReplicationOptions(
+      DataReplicationOptions replicationOptions)
+  {
+    this.replicationOptions = replicationOptions;
+  }
+
+  /**
+   * Returns whether must create a global administrator or not.
+   * @return <CODE>true</CODE> if we must create a global administrator and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean mustCreateAdministrator()
+  {
+    return createAdministrator;
+  }
+
+  /**
+   * Sets whether must create a global administrator or not.
+   * @param createAdministrator whether we must create a global administrator or
+   * not.
+   */
+  public void createAdministrator(boolean createAdministrator)
+  {
+    this.createAdministrator = createAdministrator;
+  }
+
+  /**
+   * Returns the UID of the global administrator.
+   * @return the UID of the global administrator.
+   */
+  public String getGlobalAdministratorUID()
+  {
+    return globalAdministratorUID;
+  }
+
+  /**
+   * Sets the UID of the global administrator.
+   * @param globalAdministratorUID the UID of the global administrator.
+   */
+  public void setGlobalAdministratorUID(String globalAdministratorUID)
+  {
+    this.globalAdministratorUID = globalAdministratorUID;
+  }
+
+  /**
+   * Returns the password of the global administrator.
+   * @return the password of the global administrator.
+   */
+  public String getGlobalAdministratorPassword()
+  {
+    return globalAdministratorPassword;
+  }
+
+  /**
+   * Sets the password of the global administrator.
+   * @param globalAdministratorPwd the password of the global administrator.
+   */
+  public void setGlobalAdministratorPassword(String globalAdministratorPwd)
+  {
+    this.globalAdministratorPassword = globalAdministratorPwd;
+  }
+
+  /**
+   * Sets the suffixes to replicate options.
+   * @param suffixesToReplicateOptions the suffixes to replicate options
+   * object.
+   */
+  public void setSuffixesToReplicateOptions(
+      SuffixesToReplicateOptions suffixesToReplicateOptions)
+  {
+    this.suffixesToReplicateOptions = suffixesToReplicateOptions;
+  }
+
+  /**
+   * Returns the suffixes to replicate options.
+   * @return the suffixes to replicate options.
+   */
+  public SuffixesToReplicateOptions getSuffixesToReplicateOptions()
+  {
+    return suffixesToReplicateOptions;
+  }
+
+  /**
    * Returns the SecurityOptions representing the SSL/StartTLS configuration
    * chosen by the user.
    * @return the SecurityOptions representing the SSL/StartTLS configuration
@@ -318,7 +461,6 @@
     }
     return defaultJMXPort;
   }
-
   /**
    * Provides the default name for the self signed certificate that will be
    * created.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java b/opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java
new file mode 100644
index 0000000..147507d
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/AuthenticationData.java
@@ -0,0 +1,139 @@
+/*
+ * 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 2006-2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup.installer;
+
+/**
+ * This class is used to provide a data model for the different parameters used
+ * to connect to a server that we want to replicate contents with.
+ *
+ * @see DataReplicationOptions.
+ *
+ */
+public class AuthenticationData
+{
+  private String hostName;
+
+  private int port;
+
+  private String dn;
+
+  private String pwd;
+
+  private boolean useSecureConnection;
+
+  /**
+   * Sets the server LDAP port.
+   * @param port the server LDAP port.
+   */
+  public void setPort(int port)
+  {
+    this.port = port;
+  }
+
+  /**
+   * Returns the server LDAP port.
+   * @return the server LDAP port.
+   */
+  public int getPort()
+  {
+    return port;
+  }
+
+  /**
+   * Returns the Authentication DN.
+   * @return the Authentication DN.
+   */
+  public String getDn()
+  {
+    return dn;
+  }
+
+  /**
+   * Sets the Authentication DN.
+   * @param dn the Authentication DN.
+   */
+  public void setDn(String dn)
+  {
+    this.dn = dn;
+  }
+
+  /**
+   * Returns the authentication password.
+   * @return the authentication password.
+   */
+  public String getPwd()
+  {
+    return pwd;
+  }
+
+  /**
+   * Sets the authentication password.
+   * @param pwd the authentication password.
+   */
+  public void setPwd(String pwd)
+  {
+    this.pwd = pwd;
+  }
+
+  /**
+   * Returns the host name to connect to.
+   * @return the host name to connect to.
+   */
+  public String getHostName()
+  {
+    return hostName;
+  }
+
+  /**
+   * Sets the host name to connect to.
+   * @param hostName the host name to connect to.
+   */
+  public void setHostName(String hostName)
+  {
+    this.hostName = hostName;
+  }
+
+  /**
+   * Returns whether to use a secure connection or not.
+   * @return <CODE>true</CODE> if we must use a secure connection and
+   * <CODE>false</CODE> otherwise.
+   */
+  public boolean useSecureConnection()
+  {
+    return useSecureConnection;
+  }
+
+  /**
+   * Tells to use a secure connection or not.
+   * @param useSecureConnection use a secure connection or not.
+   */
+  public void setUseSecureConnection(boolean useSecureConnection)
+  {
+    this.useSecureConnection = useSecureConnection;
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java b/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
new file mode 100644
index 0000000..32d4596
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/DataReplicationOptions.java
@@ -0,0 +1,116 @@
+/*
+ * 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 2006-2007 Sun Microsystems, Inc.
+ */
+
+
+package org.opends.quicksetup.installer;
+
+/**
+ * This class is used to provide a data model for the Data Replication
+ * Options panel of the installer.
+ *
+ */
+public class DataReplicationOptions
+{
+  /**
+   * This enumeration is used to know what the user wants to do for the data
+   * (import data or not, what use as source of the data...).
+   *
+   */
+  public enum Type
+  {
+    /**
+     * Standalone server.
+     */
+    STANDALONE,
+    /**
+     * Replicate Contents and this is the first server in topology..
+     */
+    FIRST_IN_TOPOLOGY,
+    /**
+     * Replicate Contents of the new Suffix with existings server.
+     */
+    IN_EXISTING_TOPOLOGY
+  }
+
+  private Type type;
+  private AuthenticationData authenticationData;
+
+  /**
+   * Constructor for the DataReplicationOptions object.
+   *
+   * If the Data Replication Options is STANDALONE or FIRST_IN_TOPOLOGY no
+   * args are considered.
+   *
+   * If the Data Options is IN_EXISTING_TOPOLOGY the args is the authentication
+   * data on the remote server (AuthenticationData object).
+   *
+   * @param type the Type of DataReplicationOptions.
+   * @param args the different argument objects (depending on the Type
+   * specified)
+   */
+  public DataReplicationOptions(Type type, Object... args)
+  {
+    this.type = type;
+
+    switch (type)
+    {
+    case IN_EXISTING_TOPOLOGY:
+      authenticationData = (AuthenticationData)args[0];
+      break;
+
+    default:
+      // If there is something put it.
+      if ((args != null) && (args.length > 0))
+      {
+        authenticationData = (AuthenticationData)args[0];
+      }
+    }
+  }
+
+  /**
+   * Returns the type of DataReplicationOptions represented by this object
+   * (replicate or not).
+   *
+   * @return the type of DataReplicationOptions.
+   */
+  public Type getType()
+  {
+    return type;
+  }
+
+  /**
+   * Returns the AuthenticationData to the server used to replicate.
+   * If it is standalone returns null.
+   *
+   * @return the AuthenticationData to the server used to replicate.
+   */
+  public AuthenticationData getAuthenticationData()
+  {
+    return authenticationData;
+  }
+}
+
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java b/opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java
new file mode 100644
index 0000000..cce4795
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/GlobalAdministratorOptions.java
@@ -0,0 +1,76 @@
+/*
+ * 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 2006-2007 Sun Microsystems, Inc.
+ */
+
+package org.opends.quicksetup.installer;
+
+/**
+ * This class is used to provide a data model for the global administrator
+ * options.
+ *
+ */
+public class GlobalAdministratorOptions
+{
+  private String uid;
+
+  private String pwd;
+
+  /**
+   * Returns the UID of the global administrator.
+   * @return the UID of the global administrator.
+   */
+  public String getUid()
+  {
+    return uid;
+  }
+
+  /**
+   * Sets the UID of the global administrator.
+   * @param uid the UID of the global administrator.
+   */
+  public void setUid(String uid)
+  {
+    this.uid = uid;
+  }
+
+  /**
+   * Returns the password of the global administrator.
+   * @return the password of the global administrator.
+   */
+  public String getPwd()
+  {
+    return pwd;
+  }
+
+  /**
+   * Sets the password of the global administrator.
+   * @param pwd the password of the global administrator.
+   */
+  public void setPwd(String pwd)
+  {
+    this.pwd = pwd;
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java b/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
index 04c0f88..74456e7 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
@@ -180,5 +180,4 @@
 
     return org.opends.server.tools.InstallDS.installMain(newArgs);
   }
-
 }
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 150d39a..744e594 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -37,11 +37,26 @@
 import java.util.*;
 import java.awt.event.WindowEvent;
 
+import javax.naming.NamingException;
+import javax.naming.NoPermissionException;
+import javax.naming.ldap.InitialLdapContext;
+
+import org.opends.admin.ads.ADSContext;
+import org.opends.admin.ads.ADSContextException;
+import org.opends.admin.ads.ReplicaDescriptor;
+import org.opends.admin.ads.ServerDescriptor;
+import org.opends.admin.ads.SuffixDescriptor;
 import org.opends.quicksetup.ui.*;
 import org.opends.quicksetup.util.Utils;
 import org.opends.quicksetup.*;
 import org.opends.server.util.CertificateManager;
+import org.opends.quicksetup.installer.ui.DataOptionsPanel;
+import org.opends.quicksetup.installer.ui.DataReplicationPanel;
+import org.opends.quicksetup.installer.ui.GlobalAdministratorPanel;
 import org.opends.quicksetup.installer.ui.InstallReviewPanel;
+import org.opends.quicksetup.installer.ui.InstallWelcomePanel;
+import org.opends.quicksetup.installer.ui.ServerSettingsPanel;
+import org.opends.quicksetup.installer.ui.SuffixesToReplicatePanel;
 import org.opends.server.util.SetupUtils;
 
 import javax.naming.ldap.Rdn;
@@ -88,6 +103,17 @@
 
   private List<WizardStep> lstSteps = new ArrayList<WizardStep>();
 
+  private final HashSet<WizardStep> SUBSTEPS = new HashSet<WizardStep>();
+  {
+    SUBSTEPS.add(Step.CREATE_GLOBAL_ADMINISTRATOR);
+//  TODO: remove this comment once the replication code is in place.
+    SUBSTEPS.add(Step.SUFFIXES_OPTIONS);
+    //SUBSTEPS.add(Step.NEW_SUFFIX_OPTIONS);
+  }
+
+  private HashMap<WizardStep, WizardStep> hmPreviousSteps =
+    new HashMap<WizardStep, WizardStep>();
+
   /**
    * An static String that contains the class name of ConfigFileHandler.
    */
@@ -100,7 +126,12 @@
   public Installer() {
     lstSteps.add(WELCOME);
     lstSteps.add(SERVER_SETTINGS);
-    lstSteps.add(DATA_OPTIONS);
+    /*
+    lstSteps.add(REPLICATION_OPTIONS);
+    lstSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
+    lstSteps.add(SUFFIXES_OPTIONS);
+    */
+    lstSteps.add(NEW_SUFFIX_OPTIONS);
     lstSteps.add(REVIEW);
     lstSteps.add(PROGRESS);
   }
@@ -159,14 +190,57 @@
   /**
    * {@inheritDoc}
    */
-  public void previousClicked(WizardStep cStep) {
-    if (cStep == WELCOME) {
-      throw new IllegalStateException(
-          "Cannot click on previous from progress step");
-    } else if (cStep == PROGRESS) {
-      throw new IllegalStateException(
-          "Cannot click on previous from progress step");
+  public boolean isSubStep(WizardStep step)
+  {
+    return SUBSTEPS.contains(step);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isVisible(WizardStep step)
+  {
+    boolean isVisible;
+    if (step == CREATE_GLOBAL_ADMINISTRATOR)
+    {
+       isVisible = getUserData().mustCreateAdministrator();
     }
+    else if (step == NEW_SUFFIX_OPTIONS)
+    {
+      SuffixesToReplicateOptions suf =
+        getUserData().getSuffixesToReplicateOptions();
+      if (suf != null)
+      {
+        isVisible = suf.getType() !=
+          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES;
+      }
+      else
+      {
+        isVisible = false;
+      }
+    }
+    else if (step == SUFFIXES_OPTIONS)
+    {
+      DataReplicationOptions repl =
+        getUserData().getReplicationOptions();
+      if (repl != null)
+      {
+        isVisible =
+          (repl.getType() != DataReplicationOptions.Type.STANDALONE) &&
+          (repl.getType() != DataReplicationOptions.Type.FIRST_IN_TOPOLOGY);
+      }
+      else
+      {
+        isVisible = false;
+      }
+    }
+    else
+    {
+      isVisible = true;
+    }
+    // TODO: to delete the following line once the replication code works.
+    isVisible = true;
+    return isVisible;
   }
 
   /**
@@ -284,7 +358,13 @@
         p = new InstallWelcomePanel(this);
     } else if (step == SERVER_SETTINGS) {
         p = new ServerSettingsPanel(this);
-    } else if (step == DATA_OPTIONS) {
+    } else if (step == REPLICATION_OPTIONS) {
+      p = new DataReplicationPanel(this);
+    } else if (step == CREATE_GLOBAL_ADMINISTRATOR) {
+      p = new GlobalAdministratorPanel(this);
+    } else if (step == SUFFIXES_OPTIONS) {
+      p = new SuffixesToReplicatePanel(this);
+    } else if (step == NEW_SUFFIX_OPTIONS) {
         p = new DataOptionsPanel(this);
     } else if (step == REVIEW) {
         p = new InstallReviewPanel(this);
@@ -338,7 +418,13 @@
    * {@inheritDoc}
    */
   public void previousClicked(WizardStep cStep, QuickSetup qs) {
-    // do nothing;
+    if (cStep == WELCOME) {
+      throw new IllegalStateException(
+          "Cannot click on previous from progress step");
+    } else if (cStep == PROGRESS) {
+      throw new IllegalStateException(
+          "Cannot click on previous from progress step");
+    }
   }
 
   /**
@@ -349,7 +435,7 @@
   }
 
   /** Indicates the current progress step. */
-  protected InstallProgressStep status =
+  private InstallProgressStep status =
           InstallProgressStep.NOT_STARTED;
 
   /**
@@ -359,7 +445,6 @@
                                       UserData userData,
                                       WizardStep step) {
     if (!installStatus.isInstalled() || forceToDisplaySetup) {
-
       // Set the default button for the frame
       if (step == REVIEW) {
         dlg.setFocusOnButton(ButtonName.FINISH);
@@ -400,9 +485,49 @@
    */
   public WizardStep getNextWizardStep(WizardStep step) {
     WizardStep next = null;
-    int i = lstSteps.indexOf(step);
-    if (i != -1 && i + 1 < lstSteps.size()) {
-      next = lstSteps.get(i + 1);
+    if (step == Step.REPLICATION_OPTIONS)
+    {
+      if (getUserData().mustCreateAdministrator())
+      {
+        next = Step.CREATE_GLOBAL_ADMINISTRATOR;
+      }
+      else
+      {
+        switch (getUserData().getReplicationOptions().getType())
+        {
+        case FIRST_IN_TOPOLOGY:
+          next = Step.NEW_SUFFIX_OPTIONS;
+          break;
+        case STANDALONE:
+          next = Step.NEW_SUFFIX_OPTIONS;
+          break;
+        default:
+          next = Step.SUFFIXES_OPTIONS;
+        }
+      }
+    }
+    else if (step == Step.SUFFIXES_OPTIONS)
+    {
+      switch (getUserData().getSuffixesToReplicateOptions().
+          getType())
+      {
+      case REPLICATE_WITH_EXISTING_SUFFIXES:
+        next = Step.REVIEW;
+        break;
+      default:
+        next = Step.NEW_SUFFIX_OPTIONS;
+      }
+    }
+    else
+    {
+      int i = lstSteps.indexOf(step);
+      if (i != -1 && i + 1 < lstSteps.size()) {
+        next = lstSteps.get(i + 1);
+      }
+    }
+    if (next != null)
+    {
+      hmPreviousSteps.put(next, step);
     }
     return next;
   }
@@ -410,11 +535,36 @@
   /**
    * {@inheritDoc}
    */
+  public LinkedHashSet<WizardStep> getOrderedSteps()
+  {
+    LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
+    orderedSteps.add(WELCOME);
+    orderedSteps.add(SERVER_SETTINGS);
+    // TODO: remove this comment once the replication code is in place.
+    /*
+    orderedSteps.add(REPLICATION_OPTIONS);
+    orderedSteps.add(CREATE_GLOBAL_ADMINISTRATOR);
+    orderedSteps.add(SUFFIXES_OPTIONS);
+    */
+    orderedSteps.add(NEW_SUFFIX_OPTIONS);
+    orderedSteps.add(REVIEW);
+    orderedSteps.add(PROGRESS);
+    return orderedSteps;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   public WizardStep getPreviousWizardStep(WizardStep step) {
-    WizardStep prev = null;
-    int i = lstSteps.indexOf(step);
-    if (i != -1 && i > 0) {
-      prev = lstSteps.get(i - 1);
+    //  Try with the steps calculated in method getNextWizardStep.
+    WizardStep prev = hmPreviousSteps.get(step);
+
+    if (prev == null)
+    {
+      int i = lstSteps.indexOf(step);
+      if (i != -1 && i > 0) {
+        prev = lstSteps.get(i - 1);
+      }
     }
     return prev;
   }
@@ -432,8 +582,8 @@
     try
     {
       return SetupUtils.createTemplateFile(
-                  getUserData().getDataOptions().getBaseDn(),
-                  getUserData().getDataOptions().getNumberEntries());
+                  getUserData().getNewSuffixOptions().getBaseDn(),
+                  getUserData().getNewSuffixOptions().getNumberEntries());
     }
     catch (IOException ioe)
     {
@@ -527,8 +677,11 @@
     argList.add("-w");
     argList.add(getUserData().getDirectoryManagerPwd());
 
-    argList.add("-b");
-    argList.add(getUserData().getDataOptions().getBaseDn());
+    if (createNotReplicatedSuffix())
+    {
+      argList.add("-b");
+      argList.add(getUserData().getNewSuffixOptions().getBaseDn());
+    }
 
     String[] args = new String[argList.size()];
     argList.toArray(args);
@@ -665,12 +818,12 @@
    */
   protected void createBaseEntry() throws QuickSetupException {
     String[] arg =
-      { getUserData().getDataOptions().getBaseDn() };
+      { getUserData().getNewSuffixOptions().getBaseDn() };
     notifyListeners(getFormattedWithPoints(
         getMsg("progress-creating-base-entry", arg)));
 
     InstallerHelper helper = new InstallerHelper();
-    String baseDn = getUserData().getDataOptions().getBaseDn();
+    String baseDn = getUserData().getNewSuffixOptions().getBaseDn();
     File tempFile = helper.createBaseEntryTempFile(baseDn);
 
     ArrayList<String> argList = new ArrayList<String>();
@@ -718,7 +871,7 @@
    */
   protected void importLDIF() throws QuickSetupException {
     String[] arg =
-      { getUserData().getDataOptions().getLDIFPath() };
+      { getUserData().getNewSuffixOptions().getLDIFPath() };
     notifyListeners(getFormattedProgress(getMsg("progress-importing-ldif", arg))
         + getLineBreak());
 
@@ -731,7 +884,7 @@
     argList.add("-n");
     argList.add(getBackendName());
     argList.add("-l");
-    argList.add(getUserData().getDataOptions().getLDIFPath());
+    argList.add(getUserData().getNewSuffixOptions().getLDIFPath());
 
     String[] args = new String[argList.size()];
     argList.toArray(args);
@@ -762,7 +915,7 @@
    */
   protected void importAutomaticallyGenerated() throws QuickSetupException {
     File templatePath = createTemplateFile();
-    int nEntries = getUserData().getDataOptions().getNumberEntries();
+    int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
     String[] arg =
       { String.valueOf(nEntries) };
     notifyListeners(getFormattedProgress(getMsg(
@@ -886,11 +1039,28 @@
   public void updateUserData(WizardStep cStep, QuickSetup qs)
           throws UserDataException
   {
-    if (cStep == SERVER_SETTINGS) {
+    if (cStep == SERVER_SETTINGS)
+    {
       updateUserDataForServerSettingsPanel(qs);
-    } else if (cStep == DATA_OPTIONS) {
-      updateUserDataForDataOptionsPanel(qs);
-    } else if (cStep == REVIEW) {
+    }
+    else if (cStep == REPLICATION_OPTIONS)
+    {
+      updateUserDataForReplicationOptionsPanel(qs);
+    }
+    else if (cStep == CREATE_GLOBAL_ADMINISTRATOR)
+    {
+      updateUserDataForCreateAdministratorPanel(qs);
+    }
+    else if (cStep == SUFFIXES_OPTIONS)
+    {
+      updateUserDataForSuffixesOptionsPanel(qs);
+    }
+    else if (cStep == NEW_SUFFIX_OPTIONS)
+    {
+      updateUserDataForNewSuffixOptionsPanel(qs);
+    }
+    else if (cStep ==  REVIEW)
+    {
       updateUserDataForReviewPanel(qs);
     }
   }
@@ -905,6 +1075,324 @@
   }
 
   /**
+   * Sets the current status of the installation process.
+   * @param status the current status of the installation process.
+   */
+  protected void setStatus(InstallProgressStep status)
+  {
+    this.status = status;
+  }
+
+  /**
+   * This methods updates the data on the server based on the contents of the
+   * UserData object provided in the constructor.
+   * @throws QuickSetupException if something goes wrong.
+   */
+  protected void createData() throws QuickSetupException
+  {
+    if (createNotReplicatedSuffix())
+    {
+      switch (getUserData().getNewSuffixOptions().getType())
+      {
+      case CREATE_BASE_ENTRY:
+        status = InstallProgressStep.CREATING_BASE_ENTRY;
+        notifyListeners(getTaskSeparator());
+        createBaseEntry();
+        break;
+      case IMPORT_FROM_LDIF_FILE:
+        status = InstallProgressStep.IMPORTING_LDIF;
+        notifyListeners(getTaskSeparator());
+        importLDIF();
+        break;
+      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
+        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
+        notifyListeners(getTaskSeparator());
+        importAutomaticallyGenerated();
+        break;
+      }
+    }
+    else
+    {
+      /* We must replicate some suffixes: for the moment just create them. */
+      /* TODO: replicate them. */
+      Set<SuffixDescriptor> suffixesToReplicate =
+        getUserData().getSuffixesToReplicateOptions().getAvailableSuffixes();
+      for (SuffixDescriptor suffix: suffixesToReplicate)
+      {
+        notifyListeners(getFormattedWithPoints("Creating Suffix"));
+
+        ArrayList<String> argList = new ArrayList<String>();
+        argList.add("-C");
+        argList.add(CONFIG_CLASS_NAME);
+
+        argList.add("-c");
+        argList.add(getInstallation().getCurrentConfigurationFile().toString());
+
+        argList.add("-b");
+        argList.add(suffix.getDN());
+
+        String[] args = new String[argList.size()];
+        argList.toArray(args);
+        try
+        {
+          InstallerHelper helper = new InstallerHelper();
+          int result = helper.invokeConfigureServer(args);
+
+          if (result != 0)
+          {
+            throw new QuickSetupException(
+                QuickSetupException.Type.CONFIGURATION_ERROR,
+                getMsg("error-configuring"), null);
+          }
+        } catch (Throwable t)
+        {
+          throw new QuickSetupException(
+              QuickSetupException.Type.CONFIGURATION_ERROR,
+              getThrowableMsg("error-configuring", null, t), t);
+        }
+        notifyListeners(getFormattedDone());
+
+        // TO REMOVE
+        notifyListeners(
+            getFormattedProgress("One day we will replicate the suffixes!"));
+      }
+    }
+  }
+
+  /**
+   * This methods updates the ADS contents (and creates the according suffixes).
+   * @throws QuickSetupException if something goes wrong.
+   */
+  protected void updateADS() throws QuickSetupException
+  {
+    if (true) return;
+    /* First check if the remote server contains an ADS: if it is the case the
+     * best is to update its contents with the new data and then configure the
+     * local server to be replicated with the remote server.
+     */
+    DataReplicationOptions repl =
+      getUserData().getReplicationOptions();
+    boolean remoteServer =
+      repl.getType() == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
+    if (remoteServer)
+    {
+      // Try to connect
+      AuthenticationData auth = repl.getAuthenticationData();
+      String ldapUrl = getLdapUrl(auth);
+      String dn = auth.getDn();
+      String pwd = auth.getPwd();
+      InitialLdapContext ctx = null;
+      try
+      {
+        ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+            Utils.getDefaultLDAPTimeout(), null);
+
+        ADSContext adsContext = new ADSContext(ctx);
+        if (adsContext.hasAdminData())
+        {
+          /* Add global administrator if the user specified one. */
+          if (getUserData().mustCreateAdministrator())
+          {
+            try
+            {
+              String[] arg = {getHostDisplay(auth)};
+              notifyListeners(getFormattedWithPoints(
+                  getMsg("creating-administrator", arg)));
+              adsContext.createAdministrator(getAdministratorProperties());
+              notifyListeners(getFormattedDone());
+            }
+            catch (ADSContextException ade)
+            {
+              if (ade.getError() ==
+                ADSContextException.ErrorType.ALREADY_REGISTERED)
+              {
+                notifyListeners(getFormattedWarning(
+                    getMsg("administrator-already-registered")));
+              }
+              else
+              {
+                throw ade;
+              }
+            }
+          }
+
+          Map<ADSContext.ServerProperty, Object> serverProperties =
+            getNewServerProperties();
+
+          /* Register new server data. */
+          adsContext.registerServer(serverProperties);
+
+          /* Configure local server to have an ADS and replicate it */
+          // TODO
+          notifyListeners(getFormattedProgress(
+              "Here we create the new server ADS and we replicate it.\n"));
+        }
+        else
+        {
+          /* TODO: We need to integrate in remote framework to make this work.
+           */
+          /*
+          adsContext.createAdminData();
+          adsContext.createAdministrator(getAdministratorProperties());
+          adsContext.registerServer(
+              getRemoteServerProperties(adsContext.getDirContext()));
+          adsContext.registerServer(getNewServerProperties());
+          */
+          notifyListeners(getFormattedProgress(
+              "Here we update the server in "+getHostDisplay(auth)+"\n"));
+
+          /* Configure local server to have an ADS and replicate it */
+          // TODO
+          notifyListeners(getFormattedProgress(
+              "Here we create the new server ADS and we replicate it.\n"));
+
+        }
+      }
+      catch (NoPermissionException x)
+      {
+        String[] arg = {getHostDisplay(auth)};
+        throw new QuickSetupException(
+            QuickSetupException.Type.CONFIGURATION_ERROR,
+            getMsg("cannot-connect-to-remote-permissions", arg), x);
+      }
+      catch (NamingException ne)
+      {
+        String[] arg = {getHostDisplay(auth)};
+        throw new QuickSetupException(
+            QuickSetupException.Type.CONFIGURATION_ERROR,
+            getMsg("cannot-connect-to-remote-generic", arg), ne);
+      }
+      catch (ADSContextException ace)
+      {
+        String[] args = {getHostDisplay(auth), ace.toString()};
+        throw new QuickSetupException(
+            QuickSetupException.Type.CONFIGURATION_ERROR,
+            getMsg("remote-ads-exception", args), ace);
+      }
+      finally
+      {
+        if (ctx != null)
+        {
+          try
+          {
+            ctx.close();
+          }
+          catch (Throwable t)
+          {
+          }
+        }
+      }
+    }
+    else
+    {
+      notifyListeners(getFormattedWithPoints(getMsg("creating-ads")));
+      Map<ADSContext.ServerProperty, Object> serverProperties =
+        getNewServerProperties();
+      try
+      {
+        ADSContext.createOfflineAdminData(serverProperties,
+            getUserData().getServerLocation(), getBackendName());
+      }
+      catch (ADSContextException ace)
+      {
+        throw new QuickSetupException(
+            QuickSetupException.Type.CONFIGURATION_ERROR,
+            getMsg("local-ads-exception"), ace);
+      }
+      notifyListeners(getFormattedDone());
+    }
+  }
+
+  /**
+   * Tells whether we must create a suffix that we are not going to replicate
+   * with other servers or not.
+   * @return <CODE>true</CODE> if we must create a new suffix and
+   * <CODE>false</CODE> otherwise.
+   */
+  private boolean createNotReplicatedSuffix()
+  {
+    boolean createSuffix;
+
+    DataReplicationOptions repl =
+      getUserData().getReplicationOptions();
+
+    SuffixesToReplicateOptions suf =
+      getUserData().getSuffixesToReplicateOptions();
+
+    createSuffix =
+      (repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY) ||
+      (repl.getType() == DataReplicationOptions.Type.STANDALONE) ||
+      (suf.getType() ==
+        SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
+
+    return createSuffix;
+  }
+
+  private String getLdapUrl(AuthenticationData auth)
+  {
+    return "ldap://"+auth.getHostName()+":"+auth.getPort();
+  }
+
+  private String getHostDisplay(AuthenticationData auth)
+  {
+    return auth.getHostName()+":"+auth.getPort();
+  }
+
+  private Map<ADSContext.ServerProperty, Object> getNewServerProperties()
+  {
+    Map<ADSContext.ServerProperty, Object> serverProperties =
+      new HashMap<ADSContext.ServerProperty, Object>();
+    // TODO: this might not work
+    try
+    {
+      serverProperties.put(ADSContext.ServerProperty.HOSTNAME,
+          java.net.InetAddress.getLocalHost().getHostName());
+    }
+    catch (Throwable t)
+    {
+      t.printStackTrace();
+    }
+    serverProperties.put(ADSContext.ServerProperty.PORT,
+        String.valueOf(getUserData().getServerPort()));
+    serverProperties.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
+
+    // TODO: even if the user does not configure SSL maybe we should choose
+    // a secure port that is not being used and that we can actually use.
+    serverProperties.put(ADSContext.ServerProperty.SECURE_PORT, "636");
+    serverProperties.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
+
+    serverProperties.put(ADSContext.ServerProperty.JMX_PORT,
+        String.valueOf(getUserData().getServerJMXPort()));
+    serverProperties.put(ADSContext.ServerProperty.JMX_ENABLED, "true");
+
+    serverProperties.put(ADSContext.ServerProperty.INSTANCE_PATH,
+        getUserData().getServerLocation());
+
+    String serverID = serverProperties.get(ADSContext.ServerProperty.HOSTNAME)+
+    ":"+getUserData().getServerPort();
+    /* TODO: do we want to ask this specifically to the user? */
+    serverProperties.put(ADSContext.ServerProperty.ID, serverID);
+
+    serverProperties.put(ADSContext.ServerProperty.HOST_OS,
+        Utils.getOSString());
+    return serverProperties;
+  }
+
+  private Map<ADSContext.AdministratorProperty, Object>
+  getAdministratorProperties()
+  {
+    Map<ADSContext.AdministratorProperty, Object> adminProperties =
+      new HashMap<ADSContext.AdministratorProperty, Object>();
+    adminProperties.put(ADSContext.AdministratorProperty.UID,
+        getUserData().getGlobalAdministratorUID());
+    adminProperties.put(ADSContext.AdministratorProperty.UID,
+        getUserData().getGlobalAdministratorPassword());
+    adminProperties.put(ADSContext.AdministratorProperty.DESCRIPTION,
+        getMsg("global-administrator-description"));
+    return adminProperties;
+  }
+
+  /**
    * Validate the data provided by the user in the server settings panel and
    * update the userData object according to that content.
    *
@@ -1186,11 +1674,392 @@
    *           valid.
    *
    */
-  private void updateUserDataForDataOptionsPanel(QuickSetup qs)
+  private void updateUserDataForReplicationOptionsPanel(QuickSetup qs)
       throws UserDataException {
+    boolean hasGlobalAdministrators = false;
+    String host = null;
+    Integer port = null;
+    String dn = null;
+    String pwd = null;
     ArrayList<String> errorMsgs = new ArrayList<String>();
 
-    DataOptions dataOptions = null;
+    DataReplicationOptions.Type type = (DataReplicationOptions.Type)
+      qs.getFieldValue(FieldName.REPLICATION_OPTIONS);
+    host = qs.getFieldStringValue(FieldName.REMOTE_SERVER_HOST);
+    dn = qs.getFieldStringValue(FieldName.REMOTE_SERVER_DN);
+    pwd = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PWD);
+
+    switch (type)
+    {
+    case IN_EXISTING_TOPOLOGY:
+    {
+      // Check host name
+      if ((host == null) || (host.length() == 0))
+      {
+        errorMsgs.add(getMsg("empty-remote-host"));
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
+      }
+      else
+      {
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, false);
+      }
+
+      // Check port
+      String sPort = qs.getFieldStringValue(FieldName.REMOTE_SERVER_PORT);
+      try
+      {
+        port = Integer.parseInt(sPort);
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, false);
+      }
+      catch (Throwable t)
+      {
+        errorMsgs.add(getMsg("invalid-remote-port"));
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
+      }
+
+      // Check dn
+      if ((dn == null) || (dn.length() == 0))
+      {
+        errorMsgs.add(getMsg("empty-remote-dn"));
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+      }
+      else
+      {
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, false);
+      }
+
+      // Check password
+      if ((pwd == null) || (pwd.length() == 0))
+      {
+        errorMsgs.add(getMsg("empty-remote-pwd"));
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+      }
+      else
+      {
+        qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, false);
+      }
+
+      if (errorMsgs.size() == 0)
+      {
+        // Try to connect
+        String ldapUrl = "ldap://"+host+":"+port;
+        InitialLdapContext ctx = null;
+        try
+        {
+          try
+          {
+            ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+                Utils.getDefaultLDAPTimeout(), null);
+          }
+          catch (Throwable t)
+          {
+            // Try using a global administrator
+            dn = ADSContext.getAdministratorDN(dn);
+            ctx = Utils.createLdapContext(ldapUrl, dn, pwd,
+                Utils.getDefaultLDAPTimeout(), null);
+          }
+
+          ADSContext adsContext = new ADSContext(ctx);
+          if (adsContext.hasAdminData())
+          {
+            /* Check if there are already global administrators */
+            Set administrators = adsContext.readAdministratorRegistry();
+            if (administrators.size() > 0)
+            {
+              hasGlobalAdministrators = true;
+            }
+            updateUserDataWithSuffixesInADS(adsContext);
+          }
+          else
+          {
+            getUserData().setSuffixesToReplicateOptions(
+                new SuffixesToReplicateOptions(
+                    SuffixesToReplicateOptions.Type.
+                    REPLICATE_WITH_EXISTING_SUFFIXES,
+                    staticSuffixes(),
+                    staticSuffixes()));
+          }
+        }
+        catch (NoPermissionException x)
+        {
+          String[] arg = {host+":"+port};
+          errorMsgs.add(getMsg("cannot-connect-to-remote-permissions", arg));
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+        }
+        catch (NamingException ne)
+        {
+          String[] arg = {host+":"+port};
+          errorMsgs.add(getMsg("cannot-connect-to-remote-generic", arg));
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_HOST, true);
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PORT, true);
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_DN, true);
+          qs.displayFieldInvalid(FieldName.REMOTE_SERVER_PWD, true);
+        }
+        catch (ADSContextException ace)
+        {
+          String[] args = {host+":"+port, ace.toString()};
+          errorMsgs.add(getMsg("remote-ads-exception", args));
+        }
+        finally
+        {
+          if (ctx != null)
+          {
+            try
+            {
+              ctx.close();
+            }
+            catch (Throwable t)
+            {
+            }
+          }
+        }
+      }
+      break;
+    }
+    case STANDALONE:
+    {
+      Set<SuffixDescriptor> available;
+      SuffixesToReplicateOptions repl =
+        getUserData().getSuffixesToReplicateOptions();
+
+      if (repl != null)
+      {
+        available = repl.getAvailableSuffixes();
+      }
+      else
+      {
+        available = new HashSet<SuffixDescriptor>();
+      }
+
+      Set<SuffixDescriptor> chosen;
+      if (repl != null)
+      {
+        chosen = repl.getSuffixes();
+      }
+      else
+      {
+        chosen = new HashSet<SuffixDescriptor>();
+      }
+
+      getUserData().setSuffixesToReplicateOptions(
+          new SuffixesToReplicateOptions(
+              SuffixesToReplicateOptions.Type.NO_SUFFIX_TO_REPLICATE,
+              available,
+              chosen));
+      break;
+    }
+    case FIRST_IN_TOPOLOGY:
+    {
+      Set<SuffixDescriptor> available;
+      SuffixesToReplicateOptions repl =
+        getUserData().getSuffixesToReplicateOptions();
+
+      if (repl != null)
+      {
+        available = repl.getAvailableSuffixes();
+      }
+      else
+      {
+        available = new HashSet<SuffixDescriptor>();
+      }
+
+      Set<SuffixDescriptor> chosen;
+      if (repl != null)
+      {
+        chosen = repl.getSuffixes();
+      }
+      else
+      {
+        chosen = new HashSet<SuffixDescriptor>();
+      }
+      getUserData().setSuffixesToReplicateOptions(
+          new SuffixesToReplicateOptions(
+              SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY,
+              available,
+              chosen));
+      break;
+    }
+    default:
+      throw new IllegalStateException("Do not know what to do with type: "+
+          type);
+    }
+
+    if (errorMsgs.size() == 0)
+    {
+      AuthenticationData auth = new AuthenticationData();
+      auth.setHostName(host);
+      if (port != null)
+      {
+        auth.setPort(port);
+      }
+      auth.setDn(dn);
+      auth.setPwd(pwd);
+
+      DataReplicationOptions repl = new DataReplicationOptions(type,
+          auth);
+      getUserData().setReplicationOptions(repl);
+
+      getUserData().createAdministrator(!hasGlobalAdministrators &&
+      type == DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
+
+    }
+    if (errorMsgs.size() > 0)
+    {
+      throw new UserDataException(Step.REPLICATION_OPTIONS,
+          Utils.getStringFromCollection(errorMsgs, "\n"));
+    }
+  }
+
+  /**
+   * Validate the data provided by the user in the create global administrator
+   * panel and update the UserInstallData object according to that content.
+   *
+   * @throws an
+   *           UserInstallDataException if the data provided by the user is not
+   *           valid.
+   *
+   */
+  private void updateUserDataForCreateAdministratorPanel(QuickSetup qs)
+  throws UserDataException
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+
+    // Check the Global Administrator UID
+    String uid = qs.getFieldStringValue(FieldName.GLOBAL_ADMINISTRATOR_UID);
+
+    if ((uid == null) || (uid.trim().length() == 0))
+    {
+      errorMsgs.add(getMsg("empty-administrator-uid"));
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_UID, true);
+    }
+    else
+    {
+      getUserData().setGlobalAdministratorUID(uid);
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_UID, false);
+    }
+
+    // Check the provided passwords
+    String pwd1 = qs.getFieldStringValue(FieldName.GLOBAL_ADMINISTRATOR_PWD);
+    String pwd2 = qs.getFieldStringValue(
+        FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM);
+    if (pwd1 == null)
+    {
+      pwd1 = "";
+    }
+
+    boolean pwdValid = true;
+    if (!pwd1.equals(pwd2))
+    {
+      errorMsgs.add(getMsg("not-equal-pwd"));
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM, true);
+      pwdValid = false;
+
+    }
+    if (pwd1.length() < MIN_DIRECTORY_MANAGER_PWD)
+    {
+      errorMsgs.add(getMsg(("pwd-too-short"), new String[]
+        { String.valueOf(MIN_DIRECTORY_MANAGER_PWD) }));
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD, true);
+      if ((pwd2 == null) || (pwd2.length() < MIN_DIRECTORY_MANAGER_PWD))
+      {
+        qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
+            true);
+      }
+      pwdValid = false;
+    }
+
+    if (pwdValid)
+    {
+      getUserData().setDirectoryManagerPwd(pwd1);
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD, false);
+      qs.displayFieldInvalid(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM, false);
+    }
+
+    if (errorMsgs.size() > 0)
+    {
+      throw new UserDataException(Step.CREATE_GLOBAL_ADMINISTRATOR,
+          Utils.getStringFromCollection(errorMsgs, "\n"));
+    }
+  }
+
+  /**
+   * Validate the data provided by the user in the replicate suffixes options
+   * panel and update the UserInstallData object according to that content.
+   *
+   * @throws an
+   *           UserInstallDataException if the data provided by the user is not
+   *           valid.
+   *
+   */
+  private void updateUserDataForSuffixesOptionsPanel(QuickSetup qs)
+  throws UserDataException
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+    if (qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE_OPTIONS) ==
+      SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES)
+    {
+      Set s = (Set)qs.getFieldValue(FieldName.SUFFIXES_TO_REPLICATE);
+      if (s.size() == 0)
+      {
+        errorMsgs.add(getMsg("no-suffixes-chosen-to-replicate"));
+        qs.displayFieldInvalid(FieldName.SUFFIXES_TO_REPLICATE, true);
+      }
+      else
+      {
+        Set<SuffixDescriptor> chosen = new HashSet<SuffixDescriptor>();
+        for (Object o: s)
+        {
+          chosen.add((SuffixDescriptor)o);
+        }
+        qs.displayFieldInvalid(FieldName.SUFFIXES_TO_REPLICATE, false);
+        Set<SuffixDescriptor> available = getUserData().
+        getSuffixesToReplicateOptions().getAvailableSuffixes();
+
+        SuffixesToReplicateOptions options =
+          new SuffixesToReplicateOptions(
+          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES,
+              available,
+              chosen);
+        getUserData().setSuffixesToReplicateOptions(options);
+      }
+    }
+    else
+    {
+      Set<SuffixDescriptor> available = getUserData().
+      getSuffixesToReplicateOptions().getAvailableSuffixes();
+      Set<SuffixDescriptor> chosen = getUserData().
+      getSuffixesToReplicateOptions().getSuffixes();
+      SuffixesToReplicateOptions options =
+        new SuffixesToReplicateOptions(
+            SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY,
+            available,
+            chosen);
+      getUserData().setSuffixesToReplicateOptions(options);
+    }
+
+    if (errorMsgs.size() > 0)
+    {
+      throw new UserDataException(Step.SUFFIXES_OPTIONS,
+          Utils.getStringFromCollection(errorMsgs, "\n"));
+    }
+  }
+
+  /**
+   * Validate the data provided by the user in the new suffix data options panel
+   * and update the UserInstallData object according to that content.
+   *
+   * @throws an
+   *           UserInstallDataException if the data provided by the user is not
+   *           valid.
+   *
+   */
+  private void updateUserDataForNewSuffixOptionsPanel(QuickSetup qs)
+      throws UserDataException
+  {
+    ArrayList<String> errorMsgs = new ArrayList<String>();
+
+    NewSuffixOptions dataOptions = null;
 
     // Check the base dn
     boolean validBaseDn = false;
@@ -1214,8 +2083,8 @@
     }
 
     // Check the data options
-    DataOptions.Type type =
-        (DataOptions.Type) qs.getFieldValue(FieldName.DATA_OPTIONS);
+    NewSuffixOptions.Type type =
+        (NewSuffixOptions.Type) qs.getFieldValue(FieldName.DATA_OPTIONS);
 
     switch (type)
     {
@@ -1231,7 +2100,7 @@
         qs.displayFieldInvalid(FieldName.LDIF_PATH, true);
       } else if (validBaseDn)
       {
-        dataOptions = new DataOptions(type, baseDn, ldifPath);
+        dataOptions = new NewSuffixOptions(type, baseDn, ldifPath);
         qs.displayFieldInvalid(FieldName.LDIF_PATH, false);
       }
       break;
@@ -1274,7 +2143,7 @@
       if (startErrors == errorMsgs.size() && validBaseDn)
       {
         // No validation errors
-        dataOptions = new DataOptions(type, baseDn, new Integer(nEntries));
+        dataOptions = new NewSuffixOptions(type, baseDn, new Integer(nEntries));
       }
       break;
 
@@ -1283,22 +2152,23 @@
       qs.displayFieldInvalid(FieldName.NUMBER_ENTRIES, false);
       if (validBaseDn)
       {
-        dataOptions = new DataOptions(type, baseDn);
+        dataOptions = new NewSuffixOptions(type, baseDn);
       }
     }
 
     if (dataOptions != null)
     {
-      getUserData().setDataOptions(dataOptions);
+      getUserData().setNewSuffixOptions(dataOptions);
     }
 
     if (errorMsgs.size() > 0)
     {
-      throw new UserDataException(Step.DATA_OPTIONS,
+      throw new UserDataException(Step.NEW_SUFFIX_OPTIONS,
           Utils.getStringFromCollection(errorMsgs, "\n"));
     }
   }
 
+
   /**
    * Update the userData object according to the content of the review
    * panel.
@@ -1324,6 +2194,142 @@
     return 15 * 1024 * 1024;
   }
 
+  private Map<ADSContext.ServerProperty, Object> getRemoteServerProperties(
+      InitialLdapContext ctx) throws NamingException
+  {
+    // TODO: use administration framework.
+    return new HashMap<ADSContext.ServerProperty, Object>();
+  }
+
+  /**
+   * Update the UserInstallData object according to the content of the review
+   * panel.
+   */
+  private void updateUserDataWithSuffixesInADS(ADSContext adsContext)
+  {
+    SuffixesToReplicateOptions suf =
+      getUserData().getSuffixesToReplicateOptions();
+    SuffixesToReplicateOptions.Type type;
+    Set<SuffixDescriptor> suffixes = null;
+    if (suf == null)
+    {
+      type = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
+    }
+    else
+    {
+      type = suf.getType();
+    }
+    // TODO: get the suffixes using the adsContext.
+    if (suffixes == null)
+    {
+      suffixes = new HashSet<SuffixDescriptor>();
+    }
+    suffixes = staticSuffixes();
+    getUserData().setSuffixesToReplicateOptions(
+        new SuffixesToReplicateOptions(type, suffixes, suffixes));
+  }
+
+  private Set<SuffixDescriptor> staticSuffixes()
+  {
+    ServerDescriptor server1 = new ServerDescriptor();
+    Map<ADSContext.ServerProperty, Object> serverProp1 =
+      new HashMap<ADSContext.ServerProperty, Object>();
+    serverProp1.put(ADSContext.ServerProperty.HOSTNAME, "potato.france");
+    serverProp1.put(ADSContext.ServerProperty.PORT, "389");
+    serverProp1.put(ADSContext.ServerProperty.SECURE_PORT, "689");
+    serverProp1.put(ADSContext.ServerProperty.LDAP_ENABLED, "true");
+    serverProp1.put(ADSContext.ServerProperty.LDAPS_ENABLED, "false");
+    serverProp1.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl1");
+    server1.setAdsProperties(serverProp1);
+
+    ServerDescriptor server2 = new ServerDescriptor();
+    Map<ADSContext.ServerProperty, Object> serverProp2 =
+      new HashMap<ADSContext.ServerProperty, Object>();
+    serverProp2.put(ADSContext.ServerProperty.HOSTNAME, "skalariak.france");
+    serverProp2.put(ADSContext.ServerProperty.PORT, "389");
+    serverProp2.put(ADSContext.ServerProperty.SECURE_PORT, "689");
+    serverProp2.put(ADSContext.ServerProperty.LDAP_ENABLED, "false");
+    serverProp2.put(ADSContext.ServerProperty.LDAPS_ENABLED, "true");
+    serverProp2.put(ADSContext.ServerProperty.INSTANCE_PATH, "/tmp/jvl2");
+    server2.setAdsProperties(serverProp2);
+
+    SuffixDescriptor suffix1 = new SuffixDescriptor();
+    suffix1.setDN("dc=example,dc=com");
+    Set<ReplicaDescriptor> replicas1 = new HashSet<ReplicaDescriptor>();
+
+    SuffixDescriptor suffix2 = new SuffixDescriptor();
+    suffix2.setDN("dc=for real,dc=com");
+    Set<ReplicaDescriptor> replicas2 = new HashSet<ReplicaDescriptor>();
+
+    SuffixDescriptor suffix3 = new SuffixDescriptor();
+    suffix3.setDN("dc=s3,dc=com");
+    Set<ReplicaDescriptor> replicas3 = new HashSet<ReplicaDescriptor>();
+
+    SuffixDescriptor suffix4 = new SuffixDescriptor();
+    suffix4.setDN("dc=s4,dc=com");
+    Set<ReplicaDescriptor> replicas4 = new HashSet<ReplicaDescriptor>();
+
+
+    ReplicaDescriptor replica1 = new ReplicaDescriptor();
+    replica1.setSuffix(suffix1);
+    replica1.setServer(server1);
+    replica1.setEntries(1002);
+    replicas1.add(replica1);
+
+    ReplicaDescriptor replica2 = new ReplicaDescriptor();
+    replica2.setSuffix(suffix1);
+    replica2.setServer(server2);
+    replica2.setEntries(1003);
+    replicas1.add(replica2);
+
+    suffix1.setReplicas(replicas1);
+
+    ReplicaDescriptor replica3 = new ReplicaDescriptor();
+    replica3.setSuffix(suffix2);
+    replica3.setServer(server2);
+    replicas2.add(replica3);
+
+    suffix2.setReplicas(replicas2);
+
+    ReplicaDescriptor replica5 = new ReplicaDescriptor();
+    replica5.setSuffix(suffix3);
+    replica5.setServer(server1);
+    replica5.setEntries(1003);
+    replicas3.add(replica5);
+
+    ReplicaDescriptor replica6 = new ReplicaDescriptor();
+    replica6.setSuffix(suffix3);
+    replica6.setServer(server2);
+    replica6.setEntries(1003);
+    replicas3.add(replica6);
+
+    suffix3.setReplicas(replicas3);
+
+    ReplicaDescriptor replica7 = new ReplicaDescriptor();
+    replica7.setSuffix(suffix4);
+    replica7.setServer(server1);
+    replica7.setEntries(1003);
+    replicas4.add(replica7);
+
+    ReplicaDescriptor replica8 = new ReplicaDescriptor();
+    replica8.setSuffix(suffix3);
+    replica8.setServer(server2);
+    replica8.setEntries(1003);
+    replicas4.add(replica8);
+
+    suffix4.setReplicas(replicas4);
+
+    Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
+    suffixes.add(suffix1);
+    suffixes.add(suffix2);
+    suffixes.add(suffix3);
+    suffixes.add(suffix4);
+
+    //suffixes.clear();
+
+    return suffixes;
+  }
+
   /**
    * Returns the keystore path to be used for generating a self-signed
    * certificate.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java b/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
new file mode 100644
index 0000000..56e52e0
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
@@ -0,0 +1,147 @@
+/*
+ * 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 2006-2007 Sun Microsystems, Inc.
+ */
+
+
+package org.opends.quicksetup.installer;
+
+
+/**
+ * This class is used to provide a data model for the Data Options panel of the
+ * installer.
+ *
+ */
+public class NewSuffixOptions
+{
+  /**
+   * This enumeration is used to know what the user wants to do for the data
+   * (import data or not, what use as source of the data...).
+   *
+   */
+  public enum Type
+  {
+    /**
+     * Do nothing.
+     */
+    NOTHING,
+    /**
+     * Create base entry.
+     */
+    CREATE_BASE_ENTRY,
+    /**
+     * Do not add any entry to the suffix.
+     */
+    LEAVE_DATABASE_EMPTY,
+    /**
+     * Import data from an LDIF file.
+     */
+    IMPORT_FROM_LDIF_FILE,
+    /**
+     * Generate data and import it to the suffix.
+     */
+    IMPORT_AUTOMATICALLY_GENERATED_DATA
+  }
+
+  private Type type = Type.NOTHING;
+
+  private String baseDn;
+
+  private String ldifPath;
+
+  private int numberEntries = 2000;
+
+  /**
+   * Constructor for the NewSuffixOptions object.
+   *
+   * If the Data Options is IMPORT_FROM_LDIF_FILE the args are the baseDn and
+   * a String with the ldif location.
+   *
+   * If the Data Options is IMPORT_AUTOMATICALLY_GENERATED_DATA the args
+   * are the baseDn and an Integer with the number of entries.
+   *
+   * For the rest of the types the args are just the baseDn.
+   *
+   * @param type the Type of NewSuffixOptions.
+   * @param args the different argument objects (depending on the Type
+   * specified)
+   */
+  public NewSuffixOptions(Type type, Object... args)
+  {
+    this.type = type;
+    baseDn = (String) args[0];
+
+    switch (type)
+    {
+    case IMPORT_FROM_LDIF_FILE:
+      ldifPath = (String) args[1];
+      break;
+
+    case IMPORT_AUTOMATICALLY_GENERATED_DATA:
+      numberEntries = ((Integer) args[1]).intValue();
+      break;
+    }
+  }
+
+  /**
+   * Returns the type of NewSuffixOptions represented by this object (import
+   * data or not, what use as source of the data...).
+   *
+   * @return the type of NewSuffixOptions.
+   */
+  public Type getType()
+  {
+    return type;
+  }
+
+  /**
+   * Returns the path of the LDIF file used to import data.
+   * @return the path of the LDIF file used to import data.
+   */
+  public String getLDIFPath()
+  {
+    return ldifPath;
+  }
+
+  /**
+   * Returns the number of entries that will be automatically generated.
+   *
+   * @return the number of entries that will be automatically generated.
+   */
+  public int getNumberEntries()
+  {
+    return numberEntries;
+  }
+
+  /**
+   * Returns the base DN of the suffix that will be created in the server.
+   *
+   * @return the base DN of the suffix that will be created in the server.
+   */
+  public String getBaseDn()
+  {
+    return baseDn;
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java b/opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java
new file mode 100644
index 0000000..d5b543b
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/SuffixesToReplicateOptions.java
@@ -0,0 +1,155 @@
+/*
+ * 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 2006-2007 Sun Microsystems, Inc.
+ */
+
+
+package org.opends.quicksetup.installer;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.opends.admin.ads.SuffixDescriptor;
+
+/**
+ * This class is used to provide a data model for the Suffix to Replicate
+ * Options panel of the installer.
+ *
+ */
+public class SuffixesToReplicateOptions
+{
+  /**
+   * This enumeration is used to know what the user wants to do for the data
+   * (import data or not, what use as source of the data...).
+   *
+   */
+  public enum Type
+  {
+    /**
+     * Do not replicate suffix.
+     */
+    NO_SUFFIX_TO_REPLICATE,
+    /**
+     * This is a new suffix in topology..
+     */
+    NEW_SUFFIX_IN_TOPOLOGY,
+    /**
+     * Replicate Contents of the new Suffix with existings server.
+     */
+    REPLICATE_WITH_EXISTING_SUFFIXES
+  }
+
+  private Type type;
+  private Set<SuffixDescriptor> availableSuffixes;
+  private Set<SuffixDescriptor> suffixesToReplicate;
+
+  /**
+   * Constructor for the SuffixesToReplicateOptions object.
+   *
+   * If the Data Replicate Options is NO_SUFFIX_TO_REPLICATE or
+   * NEW_SUFFIX_IN_TOPOLOGY no args are considered.
+   *
+   * If the Data Options is REPLICATE_WITH_EXISTING_SUFFIXES a Set of
+   * SuffixDescriptor is passed as argument.
+   *
+   * @param type the Type of DataReplicationOptions.
+   * @param args the different argument objects (depending on the Type
+   * specified)
+   */
+  public SuffixesToReplicateOptions(Type type, Object... args)
+  {
+    this.type = type;
+
+    switch (type)
+    {
+    case REPLICATE_WITH_EXISTING_SUFFIXES:
+      Set s = (Set)args[0];
+      availableSuffixes = new HashSet<SuffixDescriptor>();
+      for (Object o: s)
+      {
+        availableSuffixes.add((SuffixDescriptor)o);
+      }
+      s = (Set)args[1];
+      suffixesToReplicate = new HashSet<SuffixDescriptor>();
+      for (Object o: s)
+      {
+        suffixesToReplicate.add((SuffixDescriptor)o);
+      }
+      break;
+
+    default:
+      // If there is something put it.
+      if ((args != null) && (args.length > 0))
+      {
+        s = (Set)args[0];
+        availableSuffixes = new HashSet<SuffixDescriptor>();
+        for (Object o: s)
+        {
+          availableSuffixes.add((SuffixDescriptor)o);
+        }
+        s = (Set)args[1];
+        suffixesToReplicate = new HashSet<SuffixDescriptor>();
+        for (Object o: s)
+        {
+          suffixesToReplicate.add((SuffixDescriptor)o);
+        }
+      }
+    }
+  }
+
+  /**
+   * Returns the type of SuffixesToReplicateOptions represented by this object
+   * (replicate or not).
+   *
+   * @return the type of SuffixesToReplicateOptions.
+   */
+  public Type getType()
+  {
+    return type;
+  }
+
+  /**
+   * Returns the set of suffixes that we must replicate with.
+   * If there are no suffixes to replicate with returns null.
+   *
+   * @return the set of suffixes that we must replicate with.
+   */
+  public Set<SuffixDescriptor> getAvailableSuffixes()
+  {
+    return availableSuffixes;
+  }
+
+  /**
+   * Returns the set of suffixes that we must replicate with.
+   * If there are no suffixes to replicate with returns null.
+   *
+   * @return the set of suffixes that we must replicate with.
+   */
+  public Set<SuffixDescriptor> getSuffixes()
+  {
+    return suffixesToReplicate;
+  }
+}
+
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java b/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
index d4f8bbd..9a5da9a 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -71,6 +71,7 @@
     initMaps();
     PrintStream origErr = System.err;
     PrintStream origOut = System.out;
+
     try
     {
       PrintStream err = new ErrorPrintStream();
@@ -78,56 +79,41 @@
       System.setErr(err);
       System.setOut(out);
 
-      status = InstallProgressStep.CONFIGURING_SERVER;
+      setStatus(InstallProgressStep.CONFIGURING_SERVER);
       configureServer();
 
-      switch (getUserData().getDataOptions().getType())
-      {
-      case CREATE_BASE_ENTRY:
-        status = InstallProgressStep.CREATING_BASE_ENTRY;
-        notifyListeners(getTaskSeparator());
-        createBaseEntry();
-        break;
-      case IMPORT_FROM_LDIF_FILE:
-        status = InstallProgressStep.IMPORTING_LDIF;
-        notifyListeners(getTaskSeparator());
-        importLDIF();
-        break;
-      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
-        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
-        notifyListeners(getTaskSeparator());
-        importAutomaticallyGenerated();
-        break;
-      }
+      createData();
+
+      updateADS();
 
       writeJavaHome();
 
       if (Utils.isWindows())
       {
           notifyListeners(getTaskSeparator());
-          status = InstallProgressStep.ENABLING_WINDOWS_SERVICE;
+          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
           enableWindowsService();
       }
 
       if (getUserData().getStartServer())
       {
         notifyListeners(getTaskSeparator());
-        status = InstallProgressStep.STARTING_SERVER;
+        setStatus(InstallProgressStep.STARTING_SERVER);
         new ServerController(this).startServer();
       }
 
-      status = InstallProgressStep.FINISHED_SUCCESSFULLY;
+      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
       notifyListeners(null);
 
     } catch (QuickSetupException ex)
     {
-      status = InstallProgressStep.FINISHED_WITH_ERROR;
+      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
       String html = getFormattedError(ex, true);
       notifyListeners(html);
     }
     catch (Throwable t)
     {
-      status = InstallProgressStep.FINISHED_WITH_ERROR;
+      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
       QuickSetupException ex = new QuickSetupException(
           QuickSetupException.Type.BUG, getThrowableMsg("bug-msg", t), t);
       String msg = getFormattedError(ex, true);
@@ -182,7 +168,7 @@
         new ArrayList<InstallProgressStep>();
     totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
     steps.add(InstallProgressStep.CONFIGURING_SERVER);
-    switch (getUserData().getDataOptions().getType())
+    switch (getUserData().getNewSuffixOptions().getType())
     {
     case CREATE_BASE_ENTRY:
       steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
similarity index 82%
rename from opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
rename to opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
index e285a0c..2595212 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/DataOptionsPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
@@ -25,11 +25,13 @@
  *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
 
-package org.opends.quicksetup.ui;
+package org.opends.quicksetup.installer.ui;
 
 import java.awt.Component;
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.util.HashMap;
@@ -45,7 +47,13 @@
 import javax.swing.text.JTextComponent;
 
 import org.opends.quicksetup.event.BrowseActionListener;
-import org.opends.quicksetup.DataOptions;
+import org.opends.quicksetup.installer.NewSuffixOptions;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.LabelFieldDescriptor;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
+import org.opends.quicksetup.ui.Utilities;
 import org.opends.quicksetup.UserData;
 
 /**
@@ -67,8 +75,8 @@
   private HashMap<FieldName, JTextComponent> hmFields =
       new HashMap<FieldName, JTextComponent>();
 
-  private HashMap<DataOptions.Type, JRadioButton> hmRadioButtons =
-      new HashMap<DataOptions.Type, JRadioButton>();
+  private HashMap<NewSuffixOptions.Type, JRadioButton> hmRadioButtons =
+      new HashMap<NewSuffixOptions.Type, JRadioButton>();
 
   private JButton ldifBrowseButton;
 
@@ -84,6 +92,7 @@
     populateComponentMaps();
     addDocumentListeners();
     addFocusListeners();
+    addActionListeners();
   }
 
   /**
@@ -95,7 +104,7 @@
 
     if (fieldName == FieldName.DATA_OPTIONS)
     {
-      for (DataOptions.Type type : hmRadioButtons.keySet())
+      for (NewSuffixOptions.Type type : hmRadioButtons.keySet())
       {
         if (hmRadioButtons.get(type).isSelected())
         {
@@ -188,7 +197,7 @@
     panel.add(auxPanel, gbc);
 
     int h1 = getLabel(FieldName.DATA_OPTIONS).getPreferredSize().height;
-    int h2 = getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY).
+    int h2 = getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY).
     getPreferredSize().height;
     int additionalInset = Math.abs(h2 - h1) / 2;
     gbc.gridwidth = GridBagConstraints.RELATIVE;
@@ -224,10 +233,10 @@
     gbc.insets = UIFactory.getEmptyInsets();
     gbc.weightx = 1.0;
     gbc.fill = GridBagConstraints.HORIZONTAL;
-    panel.add(getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY), gbc);
+    panel.add(getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY), gbc);
     gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
-    panel.add(getRadioButton(DataOptions.Type.LEAVE_DATABASE_EMPTY), gbc);
-    panel.add(getRadioButton(DataOptions.Type.IMPORT_FROM_LDIF_FILE), gbc);
+    panel.add(getRadioButton(NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY), gbc);
+    panel.add(getRadioButton(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE), gbc);
 
     JPanel auxPanel =
         createBrowseButtonPanel(FieldName.LDIF_PATH, getLDIFBrowseButton());
@@ -239,7 +248,7 @@
 
     gbc.insets.left = 0;
     panel.add(getRadioButton(
-            DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA),
+            NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA),
         gbc);
 
     auxPanel = createNumberEntriesPanel();
@@ -336,19 +345,19 @@
     switch (fieldName)
     {
     case DIRECTORY_BASE_DN:
-      value = defaultUserData.getDataOptions().getBaseDn();
+      value = defaultUserData.getNewSuffixOptions().getBaseDn();
       break;
 
     case DATA_OPTIONS:
-      value = defaultUserData.getDataOptions().getType();
+      value = defaultUserData.getNewSuffixOptions().getType();
       break;
 
     case LDIF_PATH:
-      value = defaultUserData.getDataOptions().getLDIFPath();
+      value = defaultUserData.getNewSuffixOptions().getLDIFPath();
       break;
 
     case NUMBER_ENTRIES:
-      value = defaultUserData.getDataOptions().getNumberEntries();
+      value = defaultUserData.getNewSuffixOptions().getNumberEntries();
       break;
 
     default:
@@ -437,7 +446,7 @@
         UIFactory.makeJRadioButton(getMsg("create-base-entry-label", arg),
             getMsg("create-base-entry-tooltip"),
             UIFactory.TextStyle.SECONDARY_FIELD_VALID);
-    hmRadioButtons.put(DataOptions.Type.CREATE_BASE_ENTRY, rb);
+    hmRadioButtons.put(NewSuffixOptions.Type.CREATE_BASE_ENTRY, rb);
 
     dataLabel.setLabelFor(rb);
 
@@ -445,13 +454,13 @@
         UIFactory.makeJRadioButton(getMsg("leave-database-empty-label"),
             getMsg("leave-database-empty-tooltip"),
             UIFactory.TextStyle.SECONDARY_FIELD_VALID);
-    hmRadioButtons.put(DataOptions.Type.LEAVE_DATABASE_EMPTY, rb);
+    hmRadioButtons.put(NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, rb);
 
     rb =
         UIFactory.makeJRadioButton(getMsg("import-data-from-ldif-label"),
             getMsg("import-data-from-ldif-tooltip"),
             UIFactory.TextStyle.SECONDARY_FIELD_VALID);
-    hmRadioButtons.put(DataOptions.Type.IMPORT_FROM_LDIF_FILE, rb);
+    hmRadioButtons.put(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE, rb);
 
     rb =
         UIFactory.makeJRadioButton(
@@ -459,18 +468,19 @@
             getMsg("import-automatically-generated-tooltip"),
             UIFactory.TextStyle.SECONDARY_FIELD_VALID);
     hmRadioButtons
-        .put(DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, rb);
+        .put(NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, rb);
 
-    DataOptions.Type defaultType =
-        (DataOptions.Type) getDefaultValue(FieldName.DATA_OPTIONS);
+    NewSuffixOptions.Type defaultType =
+        (NewSuffixOptions.Type) getDefaultValue(FieldName.DATA_OPTIONS);
 
     ButtonGroup buttonGroup = new ButtonGroup();
-    for (DataOptions.Type type : hmRadioButtons.keySet())
+    for (NewSuffixOptions.Type type : hmRadioButtons.keySet())
     {
       rb = hmRadioButtons.get(type);
       rb.setSelected(type == defaultType);
       buttonGroup.add(rb);
     }
+    checkEnablingState();
   }
 
   /**
@@ -510,7 +520,7 @@
 
         String newLabel = getMsg("create-base-entry-label", arg);
         JRadioButton rb =
-          getRadioButton(DataOptions.Type.CREATE_BASE_ENTRY);
+          getRadioButton(NewSuffixOptions.Type.CREATE_BASE_ENTRY);
         rb.setText(newLabel);
       }
 
@@ -538,12 +548,13 @@
         lastFocusComponent = e.getComponent();
         if (lastFocusComponent == getField(FieldName.LDIF_PATH))
         {
-          getRadioButton(DataOptions.Type.IMPORT_FROM_LDIF_FILE).setSelected(
-              true);
-        } else if (lastFocusComponent == getField(FieldName.NUMBER_ENTRIES))
+          getRadioButton(NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE).
+          setSelected(true);
+        }
+        else if (lastFocusComponent == getField(FieldName.NUMBER_ENTRIES))
         {
           getRadioButton(
-              DataOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
+              NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
               .setSelected(true);
         }
       }
@@ -567,6 +578,43 @@
   }
 
   /**
+   * Adds the required focus listeners to the fields.
+   */
+  private void addActionListeners()
+  {
+    final ActionListener l = new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        checkEnablingState();
+      }
+    };
+    for (JRadioButton rb : hmRadioButtons.values())
+    {
+      rb.addActionListener(l);
+    }
+  }
+
+  /**
+   * Enables/disables the fields.
+   */
+  private void checkEnablingState()
+  {
+    boolean importLDIF = getRadioButton(
+        NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE).isSelected();
+    boolean automaticData = getRadioButton(
+        NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA).
+        isSelected();
+
+    getField(FieldName.LDIF_PATH).setEnabled(importLDIF);
+    getLDIFBrowseButton().setEnabled(importLDIF);
+    getField(FieldName.NUMBER_ENTRIES).setEnabled(automaticData);
+
+    getLabel(FieldName.LDIF_PATH).setEnabled(importLDIF);
+    getLabel(FieldName.NUMBER_ENTRIES).setEnabled(automaticData);
+  }
+
+  /**
    * Returns the label associated with the given field name.
    * @param fieldName the field name for which we want to retrieve the JLabel.
    * @return the label associated with the given field name.
@@ -593,7 +641,7 @@
    * JRadioButton.
    * @return the JRadioButton associated with the given DataOptions.Type object.
    */
-  private JRadioButton getRadioButton(DataOptions.Type type)
+  private JRadioButton getRadioButton(NewSuffixOptions.Type type)
   {
     return hmRadioButtons.get(type);
   }
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
new file mode 100644
index 0000000..be58712
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataReplicationPanel.java
@@ -0,0 +1,540 @@
+/*
+ * 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.quicksetup.installer.ui;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.HashMap;
+
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.event.DocumentEvent;
+import javax.swing.event.DocumentListener;
+import javax.swing.text.JTextComponent;
+
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.installer.AuthenticationData;
+import org.opends.quicksetup.installer.DataReplicationOptions;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.LabelFieldDescriptor;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
+
+/**
+ * This class is used to display the replication options for the server
+ * that is being installed.
+ */
+public class DataReplicationPanel extends QuickSetupStepPanel
+{
+  private static final long serialVersionUID = -1721551487477733587L;
+  private Component lastFocusComponent;
+  private UserData defaultUserData;
+
+  private JRadioButton rbStandalone;
+  private JRadioButton rbReplicated;
+  private JCheckBox cbTopologyExists;
+  private HashMap<FieldName, JLabel> hmLabels =
+    new HashMap<FieldName, JLabel>();
+  private HashMap<FieldName, JTextComponent> hmFields =
+    new HashMap<FieldName, JTextComponent>();
+
+  /**
+   * Constructor of the panel.
+   * @param application Application represented by this panel and used to
+   * initialize the fields of the panel.
+   */
+  public DataReplicationPanel(GuiApplication application)
+  {
+    super(application);
+    this.defaultUserData = application.getUserData();
+    populateComponentMaps();
+    addDocumentListeners();
+    addFocusListeners();
+    addActionListeners();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Object getFieldValue(FieldName fieldName)
+  {
+    Object value = null;
+
+    if (fieldName == FieldName.REPLICATION_OPTIONS)
+    {
+      if (rbStandalone.isSelected())
+      {
+        value = DataReplicationOptions.Type.STANDALONE;
+      }
+      else if (cbTopologyExists.isSelected())
+      {
+        value =
+          DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY;
+      }
+      else
+      {
+        value = DataReplicationOptions.Type.FIRST_IN_TOPOLOGY;
+      }
+    }
+    else
+    {
+      JTextComponent field = getField(fieldName);
+      if (field != null)
+      {
+        value = field.getText();
+      }
+    }
+
+    return value;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
+  {
+    JLabel label = getLabel(fieldName);
+    if (label != null)
+    {
+      UIFactory.TextStyle style;
+
+      if (invalid)
+      {
+        style = UIFactory.TextStyle.SECONDARY_FIELD_INVALID;
+      } else
+      {
+        style = UIFactory.TextStyle.SECONDARY_FIELD_VALID;
+      }
+
+      UIFactory.setTextStyle(label, style);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Component createInputPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets = UIFactory.getEmptyInsets();
+    panel.add(rbStandalone, gbc);
+
+    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
+    panel.add(rbReplicated, gbc);
+
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.insets.left = UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
+    panel.add(cbTopologyExists, gbc);
+
+    JPanel auxPanel = new JPanel(new GridBagLayout());
+    auxPanel.setOpaque(false);
+    gbc.insets.left = 2 * UIFactory.LEFT_INSET_RADIO_SUBORDINATE;
+    panel.add(auxPanel, gbc);
+
+    // Add the server location widgets
+    FieldName[] fields =
+    {
+      FieldName.REMOTE_SERVER_HOST,
+      FieldName.REMOTE_SERVER_PORT,
+      FieldName.REMOTE_SERVER_DN,
+      FieldName.REMOTE_SERVER_PWD
+    };
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    for (int i=0; i<fields.length; i++)
+    {
+      if (i != 0)
+      {
+        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+      }
+      else
+      {
+        gbc.insets.top = 0;
+      }
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      gbc.weightx = 0.0;
+      gbc.insets.left = 0;
+      gbc.anchor = GridBagConstraints.WEST;
+      auxPanel.add(getLabel(fields[i]), gbc);
+
+      JPanel aux2Panel = new JPanel(new GridBagLayout());
+      aux2Panel.setOpaque(false);
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      gbc.weightx = 0.0;
+      aux2Panel.add(getField(fields[i]), gbc);
+
+      gbc.gridwidth = GridBagConstraints.REMAINDER;
+      gbc.insets.left = 0;
+      gbc.weightx = 1.0;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      aux2Panel.add(Box.createHorizontalGlue(), gbc);
+
+      gbc.weightx = 1.0;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      gbc.insets = UIFactory.getEmptyInsets();
+      gbc.gridwidth = GridBagConstraints.REMAINDER;
+      auxPanel.add(aux2Panel, gbc);
+    }
+
+    addVerticalGlue(panel);
+
+    return panel;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getInstructions()
+  {
+    return getMsg("data-replication-options-panel-instructions");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getTitle()
+  {
+    return getMsg("data-replication-options-panel-title");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void endDisplay()
+  {
+    if (lastFocusComponent != null)
+    {
+      lastFocusComponent.requestFocusInWindow();
+    }
+  }
+
+  /**
+   * Returns the default value for the provided field Name.
+   * @param fieldName the field name for which we want to get the default
+   * value.
+   * @return the default value for the provided field Name.
+   */
+  private Object getDefaultValue(FieldName fieldName)
+  {
+    Object value = null;
+    AuthenticationData auth =
+      defaultUserData.getReplicationOptions().getAuthenticationData();
+    switch (fieldName)
+    {
+    case REMOTE_SERVER_DN:
+      value = auth.getDn();
+      break;
+
+    case REMOTE_SERVER_PWD:
+      value = auth.getPwd();
+      break;
+
+    case REMOTE_SERVER_HOST:
+      value = auth.getHostName();
+      break;
+
+    case REMOTE_SERVER_PORT:
+      value = auth.getPort();
+      break;
+
+    case REPLICATION_OPTIONS:
+      value = defaultUserData.getReplicationOptions().getType();
+      break;
+
+    default:
+      throw new IllegalArgumentException("Unknown field name: " +
+          fieldName);
+    }
+
+    return value;
+  }
+
+  /**
+   * Returns the default string value for the provided field Name.
+   * @param fieldName the field name for which we want to get the default
+   * string value.
+   * @return the default value for the provided field Name.
+   */
+  private String getDefaultStringValue(FieldName fieldName)
+  {
+    String value = null;
+
+    Object v = getDefaultValue(fieldName);
+    if (v != null)
+    {
+      if (v instanceof String)
+      {
+        value = (String) v;
+      } else
+      {
+        value = String.valueOf(v);
+      }
+    }
+    return value;
+  }
+
+  /**
+   * Creates the components and populates the Maps with them.
+   */
+  private void populateComponentMaps()
+  {
+    HashMap<FieldName, LabelFieldDescriptor> hm =
+        new HashMap<FieldName, LabelFieldDescriptor>();
+
+    hm.put(FieldName.REMOTE_SERVER_DN, new LabelFieldDescriptor(
+        getMsg("remote-server-dn-label"), getMsg("remote-server-dn-tooltip"),
+        LabelFieldDescriptor.FieldType.TEXTFIELD,
+        LabelFieldDescriptor.LabelType.SECONDARY, UIFactory.DN_FIELD_SIZE));
+
+    hm.put(FieldName.REMOTE_SERVER_PWD, new LabelFieldDescriptor(
+        getMsg("remote-server-pwd-label"), getMsg("remote-server-pwd-tooltip"),
+        LabelFieldDescriptor.FieldType.PASSWORD,
+        LabelFieldDescriptor.LabelType.SECONDARY,
+        UIFactory.PASSWORD_FIELD_SIZE));
+
+    hm.put(FieldName.REMOTE_SERVER_HOST, new LabelFieldDescriptor(
+        getMsg("remote-server-host-label"),
+        getMsg("remote-server-host-tooltip"),
+        LabelFieldDescriptor.FieldType.TEXTFIELD,
+        LabelFieldDescriptor.LabelType.SECONDARY,
+        UIFactory.HOST_FIELD_SIZE));
+
+    hm.put(FieldName.REMOTE_SERVER_PORT, new LabelFieldDescriptor(
+        getMsg("remote-server-port-label"),
+        getMsg("remote-server-port-tooltip"),
+        LabelFieldDescriptor.FieldType.TEXTFIELD,
+        LabelFieldDescriptor.LabelType.SECONDARY,
+        UIFactory.PORT_FIELD_SIZE));
+
+    for (FieldName fieldName : hm.keySet())
+    {
+      JTextComponent field;
+      LabelFieldDescriptor desc = hm.get(fieldName);
+
+      String defaultValue = getDefaultStringValue(fieldName);
+      field = UIFactory.makeJTextComponent(desc, defaultValue);
+
+      hmFields.put(fieldName, field);
+
+      JLabel l = UIFactory.makeJLabel(desc);
+
+      l.setLabelFor(field);
+
+      hmLabels.put(fieldName, l);
+    }
+
+    ButtonGroup buttonGroup = new ButtonGroup();
+    rbStandalone =
+      UIFactory.makeJRadioButton(getMsg("standalone-server-label"),
+          getMsg("standalone-server-tooltip"),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbStandalone.setOpaque(false);
+    rbReplicated =
+      UIFactory.makeJRadioButton(getMsg("replicated-server-label"),
+          getMsg("replicated-server-tooltip"),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbReplicated.setOpaque(false);
+    buttonGroup.add(rbStandalone);
+    buttonGroup.add(rbReplicated);
+
+    DataReplicationOptions.Type type =
+      defaultUserData.getReplicationOptions().getType();
+    cbTopologyExists = UIFactory.makeJCheckBox(getMsg("topology-exists-label"),
+        getMsg("topology-exists-tooltip"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    cbTopologyExists.setOpaque(false);
+    rbStandalone.setSelected(type ==
+      DataReplicationOptions.Type.STANDALONE);
+    rbReplicated.setSelected(type !=
+      DataReplicationOptions.Type.STANDALONE);
+    cbTopologyExists.setSelected(type ==
+      DataReplicationOptions.Type.IN_EXISTING_TOPOLOGY);
+    checkEnablingState();
+  }
+
+  /**
+   * Adds all the required document listeners to the fields.
+   */
+  private void addDocumentListeners()
+  {
+    FieldName[] fields = {
+        FieldName.REMOTE_SERVER_DN,
+        FieldName.REMOTE_SERVER_PWD,
+        FieldName.REMOTE_SERVER_HOST,
+        FieldName.REMOTE_SERVER_PORT
+    };
+    for (int i=0; i<fields.length; i++)
+    {
+      JTextComponent tf = getField(fields[i]);
+      tf.getDocument().addDocumentListener(new DocumentListener()
+      {
+        public void changedUpdate(DocumentEvent ev)
+        {
+          if (!rbReplicated.isSelected())
+          {
+            rbReplicated.setSelected(true);
+          }
+          if (!cbTopologyExists.isSelected())
+          {
+            cbTopologyExists.setSelected(true);
+          }
+        }
+
+        public void insertUpdate(DocumentEvent ev)
+        {
+          changedUpdate(ev);
+        }
+
+        public void removeUpdate(DocumentEvent ev)
+        {
+          changedUpdate(ev);
+        }
+      });
+    }
+  }
+
+  /**
+   * Adds the required focus listeners to the fields.
+   */
+  private void addFocusListeners()
+  {
+    final FocusListener l = new FocusListener()
+    {
+      public void focusGained(FocusEvent e)
+      {
+        lastFocusComponent = e.getComponent();
+        if (lastFocusComponent instanceof JTextComponent)
+        {
+          rbReplicated.setSelected(true);
+          cbTopologyExists.setSelected(true);
+        }
+      }
+
+      public void focusLost(FocusEvent e)
+      {
+      }
+    };
+
+    for (JTextComponent tf : hmFields.values())
+    {
+      tf.addFocusListener(l);
+    }
+    rbReplicated.addFocusListener(l);
+    rbStandalone.addFocusListener(l);
+    cbTopologyExists.addFocusListener(l);
+
+    lastFocusComponent = rbStandalone;
+  }
+
+  /**
+   * Adds the required focus listeners to the fields.
+   */
+  private void addActionListeners()
+  {
+    final ActionListener l = new ActionListener()
+    {
+      public void actionPerformed(ActionEvent e)
+      {
+        checkEnablingState();
+      }
+    };
+    rbReplicated.addActionListener(l);
+    rbStandalone.addActionListener(l);
+    cbTopologyExists.addActionListener(l);
+    cbTopologyExists.addActionListener(new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        if (cbTopologyExists.isSelected())
+        {
+          rbReplicated.setSelected(true);
+        }
+      }
+    });
+  }
+
+  /**
+   * Enables/disables the fields.
+   */
+  private void checkEnablingState()
+  {
+    boolean enableFields = rbReplicated.isSelected() &&
+    cbTopologyExists.isSelected();
+
+    for (JTextComponent tf : hmFields.values())
+    {
+      tf.setEnabled(enableFields);
+    }
+
+    for (JLabel l : hmLabels.values())
+    {
+      l.setEnabled(enableFields);
+    }
+
+    cbTopologyExists.setEnabled(rbReplicated.isSelected());
+  }
+
+  /**
+   * Returns the label associated with the given field name.
+   * @param fieldName the field name for which we want to retrieve the JLabel.
+   * @return the label associated with the given field name.
+   */
+  private JLabel getLabel(FieldName fieldName)
+  {
+    return hmLabels.get(fieldName);
+  }
+
+  /**
+   * Returns the JTextComponent associated with the given field name.
+   * @param fieldName the field name for which we want to retrieve the
+   * JTextComponent.
+   * @return the JTextComponent associated with the given field name.
+   */
+  private JTextComponent getField(FieldName fieldName)
+  {
+    return hmFields.get(fieldName);
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java
new file mode 100644
index 0000000..fd772ba
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/GlobalAdministratorPanel.java
@@ -0,0 +1,324 @@
+/*
+ * 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.quicksetup.installer.ui;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.HashMap;
+
+import javax.swing.Box;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.text.JTextComponent;
+
+
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.LabelFieldDescriptor;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
+
+/**
+ * This class is used to set the global administrator parameters.
+ */
+public class GlobalAdministratorPanel extends QuickSetupStepPanel
+{
+  private static final long serialVersionUID = 4266485298770553875L;
+
+  private UserData defaultUserData;
+
+  private Component lastFocusComponent;
+
+  private HashMap<FieldName, JLabel> hmLabels =
+      new HashMap<FieldName, JLabel>();
+
+  private HashMap<FieldName, JTextComponent> hmFields =
+      new HashMap<FieldName, JTextComponent>();
+
+  /**
+   * Constructor of the panel.
+   * @param application Application represented by this panel and used to
+   * initialize the fields of the panel.
+   */
+  public GlobalAdministratorPanel(GuiApplication application)
+  {
+    super(application);
+    this.defaultUserData = application.getUserData();
+    populateLabelAndFieldMaps();
+    addFocusListeners();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Object getFieldValue(FieldName fieldName)
+  {
+    Object value = null;
+    JTextComponent field = getField(fieldName);
+    if (field != null)
+    {
+      value = field.getText();
+    }
+
+    return value;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
+  {
+    JLabel label = getLabel(fieldName);
+    if (label != null)
+    {
+      if (invalid)
+      {
+        UIFactory.setTextStyle(label,
+            UIFactory.TextStyle.PRIMARY_FIELD_INVALID);
+      } else
+      {
+        UIFactory
+            .setTextStyle(label, UIFactory.TextStyle.PRIMARY_FIELD_VALID);
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Component createInputPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets = UIFactory.getEmptyInsets();
+
+    // Add the server location widgets
+    FieldName[] fields =
+    {
+      FieldName.GLOBAL_ADMINISTRATOR_UID,
+      FieldName.GLOBAL_ADMINISTRATOR_PWD,
+      FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM
+    };
+
+    gbc.insets = UIFactory.getEmptyInsets();
+    for (int i=0; i<fields.length; i++)
+    {
+      if (i != 0)
+      {
+        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+      }
+      else
+      {
+        gbc.insets.top = 0;
+      }
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      gbc.weightx = 0.0;
+      gbc.insets.left = 0;
+      gbc.anchor = GridBagConstraints.WEST;
+      panel.add(getLabel(fields[i]), gbc);
+
+      JPanel auxPanel = new JPanel(new GridBagLayout());
+      auxPanel.setOpaque(false);
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      gbc.insets.left = UIFactory.LEFT_INSET_SECONDARY_FIELD;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      gbc.weightx = 0.0;
+      auxPanel.add(getField(fields[i]), gbc);
+
+      gbc.gridwidth = GridBagConstraints.REMAINDER;
+      gbc.insets.left = 0;
+      gbc.weightx = 1.0;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      auxPanel.add(Box.createHorizontalGlue(), gbc);
+
+      gbc.weightx = 1.0;
+      gbc.fill = GridBagConstraints.HORIZONTAL;
+      gbc.insets = UIFactory.getEmptyInsets();
+      gbc.gridwidth = GridBagConstraints.REMAINDER;
+      panel.add(auxPanel, gbc);
+    }
+
+    addVerticalGlue(panel);
+
+    return panel;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getInstructions()
+  {
+    return getMsg("global-administrator-panel-instructions");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getTitle()
+  {
+    return getMsg("global-administrator-panel-title");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void endDisplay()
+  {
+    if (lastFocusComponent != null)
+    {
+      lastFocusComponent.requestFocusInWindow();
+    }
+  }
+
+  /**
+   * Returns the default value for the provided field Name.
+   * @param fieldName the field name for which we want to get the default
+   * value.
+   * @return the default value for the provided field Name.
+   */
+  private String getDefaultValue(FieldName fieldName)
+  {
+    String value = null;
+    switch (fieldName)
+    {
+    case GLOBAL_ADMINISTRATOR_UID:
+      value = defaultUserData.getGlobalAdministratorUID();
+      break;
+
+    case GLOBAL_ADMINISTRATOR_PWD:
+      value = defaultUserData.getGlobalAdministratorPassword();
+      break;
+
+    case GLOBAL_ADMINISTRATOR_PWD_CONFIRM:
+      value = defaultUserData.getGlobalAdministratorPassword();
+      break;
+
+    default:
+      throw new IllegalArgumentException("Unknown field name: " +
+          fieldName);
+    }
+
+    return value;
+  }
+
+  /**
+   * Creates the components and populates the Maps with them.
+   */
+  private void populateLabelAndFieldMaps()
+  {
+    HashMap<FieldName, LabelFieldDescriptor> hm =
+        new HashMap<FieldName, LabelFieldDescriptor>();
+
+    hm.put(FieldName.GLOBAL_ADMINISTRATOR_UID, new LabelFieldDescriptor(
+        getMsg("global-administrator-uid-label"),
+        getMsg("global-administrator-uid-tooltip"),
+        LabelFieldDescriptor.FieldType.TEXTFIELD,
+        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.UID_FIELD_SIZE));
+
+    hm.put(FieldName.GLOBAL_ADMINISTRATOR_PWD, new LabelFieldDescriptor(
+        getMsg("global-administrator-pwd-label"),
+        getMsg("global-administrator-pwd-tooltip"),
+        LabelFieldDescriptor.FieldType.PASSWORD,
+        LabelFieldDescriptor.LabelType.PRIMARY, UIFactory.PASSWORD_FIELD_SIZE));
+
+    hm.put(FieldName.GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
+        new LabelFieldDescriptor(
+        getMsg("global-administrator-pwd-confirm-label"),
+        getMsg("global-administrator-pwd-confirm-tooltip"),
+        LabelFieldDescriptor.FieldType.PASSWORD,
+        LabelFieldDescriptor.LabelType.PRIMARY,
+        UIFactory.PASSWORD_FIELD_SIZE));
+
+    for (FieldName fieldName : hm.keySet())
+    {
+      LabelFieldDescriptor desc = hm.get(fieldName);
+      String defaultValue = getDefaultValue(fieldName);
+      JTextComponent field = UIFactory.makeJTextComponent(desc, defaultValue);
+      JLabel label = UIFactory.makeJLabel(desc);
+
+      hmFields.put(fieldName, field);
+      label.setLabelFor(field);
+
+      hmLabels.put(fieldName, label);
+    }
+  }
+
+  /**
+   * Returns the label associated with the given field name.
+   * @param fieldName the field name for which we want to retrieve the JLabel.
+   * @return the label associated with the given field name.
+   */
+  private JLabel getLabel(FieldName fieldName)
+  {
+    return hmLabels.get(fieldName);
+  }
+
+  /**
+   * Returns the JTextComponent associated with the given field name.
+   * @param fieldName the field name for which we want to retrieve the
+   * JTextComponent.
+   * @return the JTextComponent associated with the given field name.
+   */
+  private JTextComponent getField(FieldName fieldName)
+  {
+    return hmFields.get(fieldName);
+  }
+
+  /**
+   * Adds the required focus listeners to the fields.
+   */
+  private void addFocusListeners()
+  {
+    final FocusListener l = new FocusListener()
+    {
+      public void focusGained(FocusEvent e)
+      {
+        lastFocusComponent = e.getComponent();
+      }
+
+      public void focusLost(FocusEvent e)
+      {
+      }
+    };
+
+    for (JTextComponent tf : hmFields.values())
+    {
+      tf.addFocusListener(l);
+    }
+    lastFocusComponent = getField(FieldName.GLOBAL_ADMINISTRATOR_PWD);
+  }
+}
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
index 5bfc2cf..07296a3 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -27,14 +27,18 @@
 
 package org.opends.quicksetup.installer.ui;
 
-import org.opends.quicksetup.DataOptions;
+import org.opends.admin.ads.SuffixDescriptor;
 import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.installer.DataReplicationOptions;
+import org.opends.quicksetup.installer.NewSuffixOptions;
+import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
 import org.opends.quicksetup.ui.*;
 
 import javax.swing.*;
 import javax.swing.text.JTextComponent;
 import java.awt.*;
 import java.util.HashMap;
+import java.util.Set;
 
 /**
  * This is the panel that contains the Review Panel.
@@ -80,10 +84,19 @@
         getSecurityOptionsString(userData.getSecurityOptions(), false));
     setFieldValue(FieldName.DIRECTORY_MANAGER_DN, userData
         .getDirectoryManagerDn());
-    setFieldValue(FieldName.DIRECTORY_BASE_DN, userData.getDataOptions()
-        .getBaseDn());
-    setFieldValue(FieldName.DATA_OPTIONS, getDisplayString(userData
-        .getDataOptions()));
+    setFieldValue(FieldName.DATA_OPTIONS, getDataDisplayString(userData));
+    if (userData.mustCreateAdministrator())
+    {
+      setFieldValue(FieldName.GLOBAL_ADMINISTRATOR_UID,
+          String.valueOf(userData.getGlobalAdministratorUID()));
+      getField(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(true);
+      getLabel(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(true);
+    }
+    else
+    {
+      getField(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
+      getLabel(FieldName.GLOBAL_ADMINISTRATOR_UID).setVisible(false);
+    }
   }
 
   /**
@@ -147,8 +160,8 @@
         LabelFieldDescriptor.FieldType.READ_ONLY,
         LabelFieldDescriptor.LabelType.PRIMARY, 0));
 
-    hm.put(FieldName.DIRECTORY_BASE_DN, new LabelFieldDescriptor(
-        getMsg("base-dn-label"), getMsg("base-dn-tooltip"),
+    hm.put(FieldName.GLOBAL_ADMINISTRATOR_UID, new LabelFieldDescriptor(
+        getMsg("global-administrator-uid-label"), null,
         LabelFieldDescriptor.FieldType.READ_ONLY,
         LabelFieldDescriptor.LabelType.PRIMARY, 0));
 
@@ -208,35 +221,70 @@
    * @param options the DataOptions of the user.
    * @return the localized string describing the DataOptions chosen by the user.
    */
-  private String getDisplayString(DataOptions options)
+  private String getDataDisplayString(UserData userInstallData)
   {
     String msg;
 
-    switch (options.getType())
+    boolean createSuffix = false;
+
+    DataReplicationOptions repl =
+      userInstallData.getReplicationOptions();
+
+    SuffixesToReplicateOptions suf =
+      userInstallData.getSuffixesToReplicateOptions();
+
+    createSuffix =
+      repl.getType() == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY ||
+      repl.getType() == DataReplicationOptions.Type.STANDALONE ||
+      suf.getType() == SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
+
+    if (createSuffix)
     {
-    case CREATE_BASE_ENTRY:
-      msg = getMsg("review-create-base-entry-label", new String[]
-        { options.getBaseDn() });
+      String arg2;
 
-      break;
+      NewSuffixOptions options = userInstallData.getNewSuffixOptions();
+      switch (options.getType())
+      {
+      case CREATE_BASE_ENTRY:
+        arg2 = getMsg("review-create-base-entry-label",
+            new String[] { options.getBaseDn() });
 
-    case LEAVE_DATABASE_EMPTY:
-      msg = getMsg("review-leave-database-empty-label");
-      break;
+        break;
 
-    case IMPORT_FROM_LDIF_FILE:
-      msg = getMsg("review-import-ldif", new String[]
-        { options.getLDIFPath() });
-      break;
+      case LEAVE_DATABASE_EMPTY:
+        arg2 = getMsg("review-leave-database-empty-label");
+        break;
 
-    case IMPORT_AUTOMATICALLY_GENERATED_DATA:
-      msg = getMsg("review-import-automatically-generated", new String[]
-        { String.valueOf(options.getNumberEntries()) });
-      break;
+      case IMPORT_FROM_LDIF_FILE:
+        arg2 = getMsg("review-import-ldif",
+            new String[] { options.getLDIFPath() });
+        break;
 
-    default:
-      throw new IllegalArgumentException("Unknow type: " + options.getType());
+      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
+        arg2 = getMsg("review-import-automatically-generated",
+            new String[] { String.valueOf(options.getNumberEntries()) });
+        break;
 
+      default:
+        throw new IllegalArgumentException("Unknow type: " + options.getType());
+      }
+
+      msg = getMsg("review-create-suffix",
+          new String[] {options.getBaseDn(), arg2});
+    }
+    else
+    {
+      StringBuilder buf = new StringBuilder();
+      Set<SuffixDescriptor> suffixes = suf.getSuffixes();
+      for (SuffixDescriptor suffix : suffixes)
+      {
+        if (buf.length() > 0)
+        {
+          buf.append("\n");
+        }
+        buf.append(suffix.getDN());
+      }
+      msg = getMsg("review-replicate-suffix", new String[] {buf.toString()});
     }
 
     return msg;
@@ -260,8 +308,7 @@
           {
             FieldName.SERVER_LOCATION, FieldName.SERVER_PORT,
             FieldName.SECURITY_OPTIONS, FieldName.DIRECTORY_MANAGER_DN,
-            FieldName.DIRECTORY_BASE_DN,
-            FieldName.DATA_OPTIONS
+            FieldName.GLOBAL_ADMINISTRATOR_UID, FieldName.DATA_OPTIONS
           };
     }
     else
@@ -270,8 +317,8 @@
         new FieldName[]
           {
             FieldName.SERVER_PORT, FieldName.SECURITY_OPTIONS,
-            FieldName.DIRECTORY_MANAGER_DN,
-            FieldName.DIRECTORY_BASE_DN, FieldName.DATA_OPTIONS
+            FieldName.DIRECTORY_MANAGER_DN, FieldName.GLOBAL_ADMINISTRATOR_UID,
+            FieldName.DATA_OPTIONS
           };
     }
 
@@ -304,13 +351,7 @@
       gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
 
       gbc.gridwidth = GridBagConstraints.REMAINDER;
-      panel.add(auxPanel, gbc);
-
-      gbc.insets = UIFactory.getEmptyInsets();
-      gbc.gridwidth = GridBagConstraints.REMAINDER;
-      gbc.weightx = 1.0;
-      auxPanel.add(getField(fieldNames[i]), gbc);
-    }
+      panel.add(getField(fieldNames[i]), gbc);    }
 
     return panel;
   }
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/InstallWelcomePanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java
similarity index 93%
rename from opends/src/quicksetup/org/opends/quicksetup/ui/InstallWelcomePanel.java
rename to opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java
index 651a131..42e5ba0 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/InstallWelcomePanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallWelcomePanel.java
@@ -25,10 +25,13 @@
  *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
 
-package org.opends.quicksetup.ui;
+package org.opends.quicksetup.installer.ui;
 
 import java.awt.Component;
 
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
 import org.opends.quicksetup.util.Utils;
 import org.opends.quicksetup.Installation;
 
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
similarity index 99%
rename from opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
rename to opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
index 0a79f0c..f9e844f 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/SecurityOptionsDialog.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SecurityOptionsDialog.java
@@ -25,7 +25,7 @@
  *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
 
-package org.opends.quicksetup.ui;
+package org.opends.quicksetup.installer.ui;
 
 import java.awt.Component;
 import java.awt.GridBagConstraints;
@@ -59,6 +59,7 @@
 import org.opends.quicksetup.event.MinimumSizeComponentListener;
 import org.opends.quicksetup.i18n.ResourceProvider;
 import org.opends.quicksetup.installer.Installer;
+import org.opends.quicksetup.ui.UIFactory;
 import org.opends.quicksetup.util.BackgroundTask;
 import org.opends.quicksetup.util.Utils;
 import org.opends.server.util.CertificateManager;
@@ -133,15 +134,7 @@
       }
     });
     setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
-    UIFactory.IconType ic;
-    if (Utils.isMacOS())
-    {
-      ic = UIFactory.IconType.MINIMIZED_MAC;
-    }
-    else
-    {
-      ic = UIFactory.IconType.MINIMIZED;
-    }
+
     Utils.centerOnComponent(this, parent);
   }
 
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java
similarity index 97%
rename from opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
rename to opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java
index 426fea9..2499687 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/SelectAliasDialog.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SelectAliasDialog.java
@@ -22,10 +22,10 @@
  * CDDL HEADER END
  *
  *
- *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
+ *      Portions Copyright 2007 Sun Microsystems, Inc.
  */
 
-package org.opends.quicksetup.ui;
+package org.opends.quicksetup.installer.ui;
 
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
@@ -46,6 +46,7 @@
 
 import org.opends.quicksetup.event.MinimumSizeComponentListener;
 import org.opends.quicksetup.i18n.ResourceProvider;
+import org.opends.quicksetup.ui.UIFactory;
 import org.opends.quicksetup.util.Utils;
 
 /**
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
similarity index 98%
rename from opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
rename to opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
index 145438c..e81db0a 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/ServerSettingsPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/ServerSettingsPanel.java
@@ -25,7 +25,7 @@
  *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
 
-package org.opends.quicksetup.ui;
+package org.opends.quicksetup.installer.ui;
 
 import java.awt.Component;
 import java.awt.GridBagConstraints;
@@ -45,6 +45,11 @@
 import javax.swing.text.JTextComponent;
 
 import org.opends.quicksetup.event.BrowseActionListener;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.LabelFieldDescriptor;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
 import org.opends.quicksetup.util.Utils;
 import org.opends.quicksetup.SecurityOptions;
 import org.opends.quicksetup.UserData;
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
new file mode 100644
index 0000000..63420ab
--- /dev/null
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/ui/SuffixesToReplicatePanel.java
@@ -0,0 +1,530 @@
+/*
+ * 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.quicksetup.installer.ui;
+
+import java.awt.Component;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.FocusEvent;
+import java.awt.event.FocusListener;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Set;
+import java.util.TreeSet;
+
+import javax.swing.Box;
+import javax.swing.ButtonGroup;
+import javax.swing.JCheckBox;
+import javax.swing.JEditorPane;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+import javax.swing.JRadioButton;
+import javax.swing.JScrollPane;
+import javax.swing.SwingConstants;
+import javax.swing.border.EmptyBorder;
+
+import org.opends.admin.ads.ADSContext;
+import org.opends.admin.ads.ReplicaDescriptor;
+import org.opends.admin.ads.ServerDescriptor;
+import org.opends.admin.ads.SuffixDescriptor;
+
+
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.installer.SuffixesToReplicateOptions;
+import org.opends.quicksetup.ui.FieldName;
+import org.opends.quicksetup.ui.GuiApplication;
+import org.opends.quicksetup.ui.QuickSetupStepPanel;
+import org.opends.quicksetup.ui.UIFactory;
+
+/**
+ * This class is used to provide a data model for the list of suffixes that
+ * we have to replicate on the new server.
+ */
+public class SuffixesToReplicatePanel extends QuickSetupStepPanel
+implements Comparator<SuffixDescriptor>
+{
+  private static final long serialVersionUID = -8051367953737385327L;
+  private Component lastFocusComponent;
+  private UserData defaultUserData;
+  private TreeSet<SuffixDescriptor> orderedSuffixes =
+    new TreeSet<SuffixDescriptor>(this);
+  private HashMap<SuffixDescriptor, JCheckBox> hmCheckBoxes =
+    new HashMap<SuffixDescriptor, JCheckBox>();
+  private Set<JEditorPane> suffixLabels = new HashSet<JEditorPane>();
+
+  private JRadioButton rbCreateNewSuffix;
+  private JRadioButton rbReplicate;
+  private JLabel noSuffixLabel;
+  private Component labelGlue;
+  private JPanel checkBoxPanel;
+  private JScrollPane scroll;
+
+  /**
+   * Constructor of the panel.
+   * @param application Application represented by this panel and used to
+   * initialize the fields of the panel.
+   */
+  public SuffixesToReplicatePanel(GuiApplication application)
+  {
+    super(application);
+    this.defaultUserData = application.getUserData();
+    createComponents();
+    addFocusListeners();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public Object getFieldValue(FieldName fieldName)
+  {
+    Object value = null;
+
+    if (fieldName == FieldName.SUFFIXES_TO_REPLICATE_OPTIONS)
+    {
+      if (rbCreateNewSuffix.isSelected())
+      {
+        value = SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY;
+      }
+      else
+      {
+        value =
+          SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES;
+      }
+    }
+    else if (fieldName == FieldName.SUFFIXES_TO_REPLICATE)
+    {
+      Set<SuffixDescriptor> suffixes = new HashSet<SuffixDescriptor>();
+      for (SuffixDescriptor suffix:orderedSuffixes)
+      {
+        if (hmCheckBoxes.get(suffix).isSelected())
+        {
+          suffixes.add(suffix);
+        }
+      }
+      value = suffixes;
+    }
+
+    return value;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void displayFieldInvalid(FieldName fieldName, boolean invalid)
+  {
+    if (fieldName == FieldName.SUFFIXES_TO_REPLICATE)
+    {
+      UIFactory.TextStyle style;
+      if (invalid)
+      {
+        style = UIFactory.TextStyle.SECONDARY_FIELD_INVALID;
+      } else
+      {
+        style = UIFactory.TextStyle.SECONDARY_FIELD_VALID;
+      }
+
+      UIFactory.setTextStyle(rbReplicate, style);
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public int compare(SuffixDescriptor desc1, SuffixDescriptor desc2)
+  {
+    int result = 0;
+    result = compareSuffixDN(desc1, desc2);
+    if (result == 0)
+    {
+      result = compareSuffixStrings(desc1, desc2);
+    }
+    return result;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Component createInputPanel()
+  {
+    JPanel panel = new JPanel(new GridBagLayout());
+    panel.setOpaque(false);
+
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.weightx = 1.0;
+    gbc.anchor = GridBagConstraints.NORTHWEST;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.gridwidth = GridBagConstraints.REMAINDER;
+    gbc.insets = UIFactory.getEmptyInsets();
+    panel.add(rbCreateNewSuffix, gbc);
+
+    gbc.insets.top = UIFactory.TOP_INSET_RADIOBUTTON;
+    panel.add(rbReplicate, gbc);
+
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.insets.left = UIFactory.LEFT_INSET_SUBPANEL_SUBORDINATE;
+
+    // Add the checkboxes
+    checkBoxPanel = new JPanel(new GridBagLayout());
+    checkBoxPanel.setOpaque(false);
+    gbc.insets.top = 0;
+    gbc.anchor = GridBagConstraints.NORTH;
+    gbc.weighty = 1.0;
+    gbc.fill = GridBagConstraints.BOTH;
+    scroll = new JScrollPane(checkBoxPanel);
+    scroll.setBorder(new EmptyBorder(0, 0, 0, 0));
+    scroll.setViewportBorder(new EmptyBorder(0, 0, 0, 0));
+    scroll.setOpaque(false);
+    scroll.getViewport().setOpaque(false);
+
+    panel.add(scroll, gbc);
+
+    gbc.weighty = 0.0;
+    gbc.fill = GridBagConstraints.HORIZONTAL;
+    gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+    gbc.anchor = GridBagConstraints.NORTHEAST;
+    panel.add(noSuffixLabel, gbc);
+    noSuffixLabel.setVisible(false);
+
+    labelGlue = Box.createVerticalGlue();
+    gbc.fill = GridBagConstraints.VERTICAL;
+    gbc.weighty = 1.0;
+    panel.add(labelGlue, gbc);
+    labelGlue.setVisible(false);
+
+    return panel;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getInstructions()
+  {
+    return getMsg("suffixes-to-replicate-panel-instructions");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected String getTitle()
+  {
+    return getMsg("suffixes-to-replicate-panel-title");
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void beginDisplay(UserData data)
+  {
+    TreeSet<SuffixDescriptor> array = orderSuffixes(
+        data.getSuffixesToReplicateOptions().getAvailableSuffixes());
+    Set<SuffixDescriptor> chosen =
+      data.getSuffixesToReplicateOptions().getSuffixes();
+    if (!array.equals(orderedSuffixes))
+    {
+      orderedSuffixes.clear();
+      orderedSuffixes.addAll(array);
+      hmCheckBoxes.clear();
+      for (SuffixDescriptor suffix : orderedSuffixes)
+      {
+        JCheckBox cb = UIFactory.makeJCheckBox(suffix.getDN(),
+            getMsg("suffixes-to-replicate-dn-tooltip"),
+            UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+        cb.setOpaque(false);
+        cb.setSelected(chosen.contains(suffix));
+        cb.addActionListener(new ActionListener()
+        {
+          public void actionPerformed(ActionEvent ev)
+          {
+            if (((JCheckBox)ev.getSource()).isSelected())
+            {
+              rbReplicate.setSelected(true);
+            }
+          }
+        });
+        hmCheckBoxes.put(suffix, cb);
+      }
+      populateCheckBoxPanel();
+      boolean display = orderedSuffixes.size() > 0;
+
+      noSuffixLabel.setVisible(!display);
+      labelGlue.setVisible(!display);
+      scroll.setVisible(display);
+    }
+    checkEnablingState();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void endDisplay()
+  {
+    if (lastFocusComponent != null)
+    {
+      lastFocusComponent.requestFocusInWindow();
+    }
+  }
+
+  /**
+   * Creates the components of this panel.
+   */
+  private void createComponents()
+  {
+    ButtonGroup buttonGroup = new ButtonGroup();
+    rbCreateNewSuffix =
+      UIFactory.makeJRadioButton(getMsg("create-new-suffix-label"),
+          getMsg("create-new-suffix-tooltip"),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbCreateNewSuffix.setOpaque(false);
+    rbReplicate =
+      UIFactory.makeJRadioButton(getMsg("replicate-with-suffixes-label"),
+          getMsg("replicate-with-suffixes-tooltip"),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+    rbReplicate.setOpaque(false);
+    buttonGroup.add(rbCreateNewSuffix);
+    buttonGroup.add(rbReplicate);
+
+    SuffixesToReplicateOptions.Type type =
+      defaultUserData.getSuffixesToReplicateOptions().getType();
+    rbCreateNewSuffix.setSelected(type ==
+      SuffixesToReplicateOptions.Type.NEW_SUFFIX_IN_TOPOLOGY);
+    rbReplicate.setSelected(type ==
+      SuffixesToReplicateOptions.Type.REPLICATE_WITH_EXISTING_SUFFIXES);
+
+    noSuffixLabel = UIFactory.makeJLabel(UIFactory.IconType.NO_ICON,
+        getMsg("suffix-list-empty"),
+        UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+
+    ActionListener l = new ActionListener()
+    {
+      public void actionPerformed(ActionEvent ev)
+      {
+        checkEnablingState();
+      }
+    };
+    rbCreateNewSuffix.addActionListener(l);
+    rbReplicate.addActionListener(l);
+  }
+
+  /**
+   * Adds the required focus listeners to the fields.
+   */
+  private void addFocusListeners()
+  {
+    final FocusListener l = new FocusListener()
+    {
+      public void focusGained(FocusEvent e)
+      {
+        lastFocusComponent = e.getComponent();
+      }
+
+      public void focusLost(FocusEvent e)
+      {
+      }
+    };
+    rbReplicate.addFocusListener(l);
+    rbCreateNewSuffix.addFocusListener(l);
+
+    lastFocusComponent = rbReplicate;
+  }
+
+  private void populateCheckBoxPanel()
+  {
+    checkBoxPanel.removeAll();
+    suffixLabels.clear();
+    GridBagConstraints gbc = new GridBagConstraints();
+    gbc.fill = GridBagConstraints.BOTH;
+    gbc.anchor = GridBagConstraints.NORTH;
+    boolean first = true;
+    for (SuffixDescriptor suffix : orderedSuffixes)
+    {
+      gbc.insets.left = 0;
+      gbc.weightx = 0.0;
+      if (!first)
+      {
+        gbc.insets.top = UIFactory.TOP_INSET_SECONDARY_FIELD;
+      }
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      JCheckBox cb = hmCheckBoxes.get(suffix);
+      cb.setVerticalAlignment(SwingConstants.TOP);
+      checkBoxPanel.add(cb, gbc);
+      gbc.insets.left = UIFactory.LEFT_INSET_PRIMARY_FIELD;
+      gbc.weightx = 1.0;
+      gbc.gridwidth = GridBagConstraints.REMAINDER;
+      JEditorPane l = UIFactory.makeTextPane(getSuffixString(suffix),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+      l.setOpaque(false);
+      suffixLabels.add(l);
+
+      /* Use a prototype label to get the additional insets */
+      JEditorPane proto = UIFactory.makeTextPane(suffix.getDN(),
+          UIFactory.TextStyle.SECONDARY_FIELD_VALID);
+
+      gbc.insets.top += Math.abs(cb.getPreferredSize().height -
+          proto.getPreferredSize().height) / 2;
+      checkBoxPanel.add(l, gbc);
+      first = false;
+    }
+    addVerticalGlue(checkBoxPanel);
+  }
+
+  private String getSuffixString(SuffixDescriptor desc)
+  {
+    TreeSet<String> replicaDisplays = new TreeSet<String>();
+    for (ReplicaDescriptor rep: desc.getReplicas())
+    {
+      replicaDisplays.add(getReplicaDisplay(rep));
+    }
+    StringBuilder buf = new StringBuilder();
+    for (String display: replicaDisplays)
+    {
+      if (buf.length() > 0)
+      {
+        buf.append("\n");
+      }
+      buf.append(display);
+    }
+    return buf.toString();
+  }
+
+  private String getReplicaDisplay(ReplicaDescriptor replica)
+  {
+    String display;
+
+    ServerDescriptor server = replica.getServer();
+
+    String serverDisplay = getServerDisplay(server);
+
+    int nEntries = replica.getEntries();
+
+    if (nEntries > 0)
+    {
+      String[] args = {serverDisplay, String.valueOf(nEntries)};
+      display = getMsg("suffix-list-replica-display-entries", args);
+    }
+    else
+    {
+      String[] arg = {serverDisplay};
+      display = getMsg("suffix-list-replica-display-no-entries", arg);
+    }
+
+    return display;
+  }
+
+
+  //TODO: only handles server that have ADSProperties.
+  private String getServerDisplay(ServerDescriptor server)
+  {
+    String display;
+    String hostName = (String)server.getAdsProperties().get(
+        ADSContext.ServerProperty.HOSTNAME);
+    boolean secure = false;
+    int port = -1;
+
+    if (hostName == null)
+    {
+      hostName = getMsg("suffix-list-unknown-label");
+    }
+
+    if (!"true".equalsIgnoreCase((String)server.getAdsProperties().get(
+        ADSContext.ServerProperty.LDAP_ENABLED)))
+    {
+      if ("true".equalsIgnoreCase((String)server.getAdsProperties().get(
+          ADSContext.ServerProperty.LDAPS_ENABLED)))
+      {
+        secure = true;
+      }
+    }
+
+    try
+    {
+      if (secure)
+      {
+        port = Integer.parseInt((String)server.getAdsProperties().get(
+            ADSContext.ServerProperty.SECURE_PORT));
+      }
+      else
+      {
+        port = Integer.parseInt((String)server.getAdsProperties().get(
+            ADSContext.ServerProperty.PORT));
+      }
+    }
+    catch (Throwable t)
+    {
+    }
+
+    if (port == -1)
+    {
+      display = hostName+":"+getMsg("suffix-list-unknown-label");
+    }
+    else
+    {
+      display = hostName+":"+port;
+    }
+    return display;
+  }
+
+  private TreeSet<SuffixDescriptor> orderSuffixes(
+  Set<SuffixDescriptor> suffixes)
+  {
+    TreeSet<SuffixDescriptor> ordered = new TreeSet<SuffixDescriptor>(this);
+    ordered.addAll(suffixes);
+
+    return ordered;
+  }
+
+  private int compareSuffixDN(SuffixDescriptor desc1, SuffixDescriptor desc2)
+  {
+    return desc1.getDN().compareTo(desc2.getDN());
+  }
+
+  private int compareSuffixStrings(SuffixDescriptor desc1,
+      SuffixDescriptor desc2)
+  {
+    return getSuffixString(desc1).compareTo(getSuffixString(desc2));
+  }
+
+  private void checkEnablingState()
+  {
+    boolean enable = rbReplicate.isSelected();
+    for (JCheckBox cb : hmCheckBoxes.values())
+    {
+      cb.setEnabled(enable);
+    }
+
+    for (JEditorPane p : suffixLabels)
+    {
+      p.setEnabled(enable);
+    }
+
+    noSuffixLabel.setEnabled(enable);
+  }
+}
+
diff --git a/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java b/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
index 412ae0e..bb9cf9a 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/installer/webstart/WebStartInstaller.java
@@ -83,7 +83,7 @@
   public WebStartInstaller()
   {
     initLoader();
-    status = InstallProgressStep.NOT_STARTED;
+    setStatus(InstallProgressStep.NOT_STARTED);
   }
 
   /**
@@ -102,13 +102,13 @@
       System.setErr(err);
       System.setOut(out);
 
-      status = InstallProgressStep.DOWNLOADING;
+      setStatus(InstallProgressStep.DOWNLOADING);
 
       InputStream in =
           getZipInputStream(getRatio(InstallProgressStep.EXTRACTING));
       notifyListeners(getTaskSeparator());
 
-      status = InstallProgressStep.EXTRACTING;
+      setStatus(InstallProgressStep.EXTRACTING);
       createParentDirectoryIfRequired();
       extractZipFiles(in, getRatio(InstallProgressStep.EXTRACTING),
           getRatio(InstallProgressStep.CONFIGURING_SERVER));
@@ -116,56 +116,41 @@
 
       setInstallation(new Installation(getUserData().getServerLocation()));
 
-      status = InstallProgressStep.CONFIGURING_SERVER;
+      setStatus(InstallProgressStep.CONFIGURING_SERVER);
       configureServer();
 
-      switch (getUserData().getDataOptions().getType())
-      {
-      case CREATE_BASE_ENTRY:
-        status = InstallProgressStep.CREATING_BASE_ENTRY;
-        notifyListeners(getTaskSeparator());
-        createBaseEntry();
-        break;
-      case IMPORT_FROM_LDIF_FILE:
-        status = InstallProgressStep.IMPORTING_LDIF;
-        notifyListeners(getTaskSeparator());
-        importLDIF();
-        break;
-      case IMPORT_AUTOMATICALLY_GENERATED_DATA:
-        status = InstallProgressStep.IMPORTING_AUTOMATICALLY_GENERATED;
-        notifyListeners(getTaskSeparator());
-        importAutomaticallyGenerated();
-        break;
-      }
+      createData();
+
+      updateADS();
 
       writeJavaHome();
 
       if (Utils.isWindows())
       {
           notifyListeners(getTaskSeparator());
-          status = InstallProgressStep.ENABLING_WINDOWS_SERVICE;
+          setStatus(InstallProgressStep.ENABLING_WINDOWS_SERVICE);
           enableWindowsService();
       }
 
       if (getUserData().getStartServer())
       {
         notifyListeners(getTaskSeparator());
-        status = InstallProgressStep.STARTING_SERVER;
+        setStatus(InstallProgressStep.STARTING_SERVER);
         new ServerController(this).startServer();
       }
 
-      status = InstallProgressStep.FINISHED_SUCCESSFULLY;
+      setStatus(InstallProgressStep.FINISHED_SUCCESSFULLY);
       notifyListeners(null);
 
     } catch (QuickSetupException ex)
     {
-      status = InstallProgressStep.FINISHED_WITH_ERROR;
+      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
       String html = getFormattedError(ex, true);
       notifyListeners(html);
     }
     catch (Throwable t)
     {
-      status = InstallProgressStep.FINISHED_WITH_ERROR;
+      setStatus(InstallProgressStep.FINISHED_WITH_ERROR);
       QuickSetupException ex = new QuickSetupException(
           QuickSetupException.Type.BUG, getThrowableMsg("bug-msg", t), t);
       String msg = getFormattedError(ex, true);
@@ -233,7 +218,7 @@
     totalTime += hmTime.get(InstallProgressStep.CONFIGURING_SERVER);
     steps.add(InstallProgressStep.CONFIGURING_SERVER);
 
-    switch (getUserData().getDataOptions().getType())
+    switch (getUserData().getNewSuffixOptions().getType())
     {
     case CREATE_BASE_ENTRY:
       steps.add(InstallProgressStep.CREATING_BASE_ENTRY);
@@ -354,7 +339,7 @@
    */
   protected String getOpenDSClassPath()
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     String[] jars = getOpenDSJarPaths();
     for (int i = 0; i < jars.length; i++)
     {
diff --git a/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties b/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
index 6771129..a9ce247 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
+++ b/opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -127,8 +127,8 @@
 cli-uninstall-confirm-prompt={0}\n[{1}]:
 cli-uninstall-string-prompt={0}\n[{1}]:
 cli-uninstall-error-reading-stdin=Unexpected error reading standard input.
-cli-uninstall-what-to-delete=Do you want to remove all components of OpenDS or \
-select the components to remove?\n\
+cli-uninstall-what-to-delete=Do you want to remove all components of \
+OpenDS or select the components to remove?\n\
 1. Remove all components\n\
 2. Select the components to be removed\n\
 3. Neither; Quit the uninstaller
@@ -307,7 +307,24 @@
 not-equal-pwd=The passwords you have provided do not match.
 pwd-too-short=The minimum length required for the Administrative User \
 password is {0} characters.
-# Data Options Panel
+# Data Replication Panel
+empty-remote-host=You must provide the fully qualified name of the host.
+invalid-remote-port=The provided port is not valid.
+empty-remote-dn=You must provide a value for the Administrative User.
+empty-remote-pwd=You must provide an Admin User password.
+cannot-connect-to-remote-permissions=You do not have enough access rights \
+to read the configuration in {0}. \nProvide credentials with enough rights.
+cannot-connect-to-remote-generic=Could not connect to {0}. \nCheck that the \
+server is running and that the provided credentials are valid.
+remote-ads-exception=An unexpected error occurred reading the \
+configuration in {0}.\nThe error is: {1}
+no-suffixes-chosen-to-replicate=You must select at least one suffix to \
+replicate contents with.
+# Create Global Administrator Panel
+empty-administrator-uid=You must provide a Global Administrative User ID.
+empty-administrator-pwd=You must provide a Global Administrative User \
+Password.
+# New Suffix Options Panel
 empty-base-dn=You must provide a Directory Base DN.
 not-a-base-dn=The provided Directory Base DN is not a valid DN.
 base-dn-is-configuration-dn=The provided Directory Base DN is used for \
@@ -338,7 +355,10 @@
 #
 welcome-step=Welcome
 server-settings-step=Server Settings
-data-options-step=Data Options
+data-replication-step=Topology Options
+create-global-administrator-step=Global Administrator
+suffixes-step=Data Replication
+data-options-step=Directory Data
 review-step=Review
 progress-step=Progress
 confirm-uninstall-step=Uninstall Options
@@ -468,6 +488,70 @@
 pkcs12-certificate=Use existing PKCS#12 File
 
 #
+# Data Replication Panel specific labels
+#
+data-replication-options-panel-title=Topology Options
+data-replication-options-panel-instructions=Choose the Data \
+Replication Options.
+remote-server-dn-label=Admin User:
+remote-server-dn-tooltip=The DN or the UID of an administrator in the OpenDS \
+you want to replicate data with.
+remote-server-pwd-label=Admin Password:
+remote-server-pwd-tooltip=The password of an administrator in the OpenDS \
+you want to replicate data with.
+remote-server-host-label=Host Name:
+remote-server-host-tooltip=The fully qualified name of the host where the \
+OpenDS you want to replicate data with is located.
+remote-server-port-label=Port:
+remote-server-port-tooltip=The LDAP port of the OpenDS you want to \
+replicate data with.
+standalone-server-label=This will be a standalone server
+standalone-server-tooltip=Check this if you do not want to replicate the \
+data on the server that you are creating with other servers.
+replicated-server-label=This server will be part of a replication \
+topology
+replicated-server-tooltip=Check this if you want to replicate the data on \
+the server that you are creating with other servers.
+topology-exists-label=There is already a server in the topology
+topology-exists-tooltip=Check this if you already created a server that you \
+want to replicate data with.
+
+#
+# Global Administrator specific labels
+#
+global-administrator-panel-instructions=Provide the informaton to create a \
+Global Administrator that will able to manage your whole replication \
+topology.
+global-administrator-panel-title=Create Global Administrator
+global-administrator-uid-label=Global Administrator ID:
+global-administrator-uid-tooltip=The Global Administrator ID.
+global-administrator-pwd-label=Global Administrator Password:
+global-administrator-pwd-tooltip=The Global Administrator Password.
+global-administrator-pwd-confirm-label=Global Administrator Password \
+(confirm):
+global-administrator-pwd-confirm-tooltip=Confirm the password of the \
+Global Administrator.
+
+#
+# Suffixes to Replicate Panel specific labels
+#
+suffixes-to-replicate-panel-instructions=Choose whether to create suffixes \
+as defined on remote servers or to create a new suffix.
+suffixes-to-replicate-panel-title=Data Replication
+create-new-suffix-label=Create first instance of suffix to be replicated
+create-new-suffix-tooltip=Check this to create a new suffix.
+replicate-with-suffixes-label=Create local instance of existing suffixes and \
+configure replication:
+replicate-with-suffixes-tooltip=Check this to Create Suffixes whose \
+Contents are replicated with Existing Suffixes.
+suffixes-to-replicate-dn-tooltip=The Distinguished Name (DN) of the suffix \
+to replicate.
+suffix-list-replica-display-entries={0}  ({1} entries)
+suffix-list-replica-display-no-entries={0}  (no entries)
+suffix-list-unknown-label=<unknown>
+suffix-list-empty=-No Suffixes Found-
+
+#
 # Security Options dialog specific labels
 #
 security-options-dialog-title=OpenDS QuickSetup
@@ -546,7 +630,7 @@
 #
 # Data Options Panel specific labels
 #
-data-options-panel-title=Data Options
+data-options-panel-title=Directory Data
 data-options-panel-instructions=Choose options for the LDAP data to be hosted \
 by OpenDS.
 base-dn-label=Directory Base DN:
@@ -580,6 +664,8 @@
 review-import-ldif=Import Data from LDIF File ({0})
 review-import-automatically-generated=Import Automatically-Generated Data ({0} \
 Entries)
+review-create-suffix=Create New Suffix {0}.\nSuffix Data: {1}
+review-replicate-suffix=Replicate contents with suffixes:\n{0}
 start-server-label=Start Server when Configuration has Completed
 start-server-tooltip=Check this check box if you want to start the server once \
 the installation and configuration has completed
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java b/opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java
index c08efbf..189cdaa 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/CurrentStepPanel.java
@@ -120,7 +120,6 @@
    */
   private void createLayout(GuiApplication app)
   {
-
     Set<? extends WizardStep> steps = app.getWizardSteps();
     if (steps != null) {
       for (WizardStep step : steps) {
@@ -194,21 +193,30 @@
   {
     final CardLayout cl = (CardLayout) (getLayout());
 
-    // Show the 'loading...' panel and invoke begin
-    // display in another thread in case the panel
-    // taske a while to initialize.
-    cl.show(this, LOADING_PANEL);
-    new Thread(new Runnable() {
-      public void run() {
-        getPanel(step).beginDisplay(userData);
-        SwingUtilities.invokeLater(new Runnable() {
-          public void run() {
-            cl.show(CurrentStepPanel.this, step.toString());
-            getPanel(step).endDisplay();
-          }
-        });
-      }
-    },"panel begin display thread").start();
+    if (getPanel(step).blockingBeginDisplay())
+    {
+      // Show the 'loading...' panel and invoke begin
+      // display in another thread in case the panel
+      // taske a while to initialize.
+      cl.show(this, LOADING_PANEL);
+      new Thread(new Runnable() {
+        public void run() {
+          getPanel(step).beginDisplay(userData);
+          SwingUtilities.invokeLater(new Runnable() {
+            public void run() {
+              cl.show(CurrentStepPanel.this, step.toString());
+              getPanel(step).endDisplay();
+            }
+          });
+        }
+      },"panel begin display thread").start();
+    }
+    else
+    {
+      getPanel(step).beginDisplay(userData);
+      cl.show(CurrentStepPanel.this, step.toString());
+      getPanel(step).endDisplay();
+    }
   }
 
   /**
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java b/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
index 9855187..6faf772 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/DirectoryManagerAuthenticationDialog.java
@@ -342,7 +342,7 @@
         {
           InitialLdapContext ctx =
             Utils.createLdapContext(installStatus.getLdapUrl(), tfDn.getText(),
-              tfPwd.getText(), 3000, null);
+              tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
 
           /*
            * Search for the config to check that it is the directory manager.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java b/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
index 01fbf9b..5415ca7 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/FieldName.java
@@ -82,6 +82,46 @@
    */
   NUMBER_ENTRIES,
   /**
+   * The value associated with this is a DataReplicationOptions.Type.
+   */
+  REPLICATION_OPTIONS,
+  /**
+   * The value associated with this is a SuffixesToReplicateOptions.Type.
+   */
+  SUFFIXES_TO_REPLICATE_OPTIONS,
+  /**
+   * The value associated with this is a Set of SuffixDescriptor.
+   */
+  SUFFIXES_TO_REPLICATE,
+  /**
+   * The value associated with this is a String.
+   */
+  REMOTE_SERVER_DN,
+  /**
+   * The value associated with this is a String.
+   */
+  REMOTE_SERVER_PWD,
+  /**
+   * The value associated with this is a String.
+   */
+  REMOTE_SERVER_HOST,
+  /**
+   * The value associated with this is a String.
+   */
+  REMOTE_SERVER_PORT,
+  /**
+   * The value associated with this is a String.
+   */
+  GLOBAL_ADMINISTRATOR_UID,
+  /**
+   * The value associated with this is a String.
+   */
+  GLOBAL_ADMINISTRATOR_PWD,
+  /**
+   * The value associated with this is a String.
+   */
+  GLOBAL_ADMINISTRATOR_PWD_CONFIRM,
+  /**
    * The value associated with this is a Boolean.
    */
   SERVER_START,
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java b/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
index e7c8a91..48c8fe5 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/GuiApplication.java
@@ -32,6 +32,7 @@
 
 import javax.swing.*;
 import java.awt.event.WindowEvent;
+import java.util.LinkedHashSet;
 import java.util.Set;
 import java.util.logging.Logger;
 
@@ -178,6 +179,52 @@
   abstract public WizardStep getPreviousWizardStep(WizardStep step);
 
   /**
+   * Indicates whether or not the provided <code>step</code> is a sub step or
+   * not.
+   * @param step WizardStep for which the return value indicates whether
+   * or not is a sub step.
+   * @return boolean where true indicates the provided <code>step</code> is a
+   * substep.
+   */
+  public boolean isSubStep(WizardStep step)
+  {
+    return false;
+  }
+
+  /**
+   * Indicates whether or not the provided <code>step</code> is visible or
+   * not.
+   * @param step WizardStep for which the return value indicates whether
+   * or not is visible.
+   * @return boolean where true indicates the provided <code>step</code> is
+   * visible.
+   */
+  public boolean isVisible(WizardStep step)
+  {
+    return false;
+  }
+
+  /**
+   * Returns the list of all the steps in an ordered manner.  This is required
+   * because in the case of an application with substeps the user of the other
+   * interfaces is not enough.  This is a default implementation that uses
+   * the getNextWizardStep method to calculate the list that work for
+   * applications with no substeps.
+   * @return a list containing ALL the steps (including substeps) in an ordered
+   * manner.
+   */
+  public LinkedHashSet<WizardStep> getOrderedSteps()
+  {
+    LinkedHashSet<WizardStep> orderedSteps = new LinkedHashSet<WizardStep>();
+    WizardStep step = getFirstWizardStep();
+    orderedSteps.add(step);
+    while (null != (step = getNextWizardStep(step))) {
+      orderedSteps.add(step);
+    }
+    return orderedSteps;
+  }
+
+  /**
    * Indicates whether or not the user is allowed to return to a previous
    * step from <code>step</code>.
    * @param step WizardStep for which the the return value indicates whether
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java b/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
index c956a7f..410ad11 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupDialog.java
@@ -44,7 +44,6 @@
 import org.opends.quicksetup.event.ButtonActionListener;
 import org.opends.quicksetup.event.ButtonEvent;
 import org.opends.quicksetup.event.MinimumSizeComponentListener;
-import org.opends.quicksetup.i18n.ResourceProvider;
 import org.opends.quicksetup.ProgressDescriptor;
 import org.opends.quicksetup.util.ProgressMessageFormatter;
 import org.opends.quicksetup.util.Utils;
@@ -176,10 +175,9 @@
   public void setDisplayedStep(WizardStep step, UserData userData)
   {
     displayedStep = step;
-
-    // First call the panels to do the required updates on their layout
+    //  First call the panels to do the required updates on their layout
     getButtonsPanel().setDisplayedStep(step);
-    getStepsPanel().setDisplayedStep(step);
+    getStepsPanel().setDisplayedStep(step, userData);
     getCurrentStepPanel().setDisplayedStep(step, userData);
   }
 
@@ -426,17 +424,6 @@
     return buttonsPanel;
   }
 
-  /* Different commodity methods to retrieve localized messages */
-  private String getMsg(String key)
-  {
-    return getI18n().getMsg(key);
-  }
-
-  private ResourceProvider getI18n()
-  {
-    return ResourceProvider.getInstance();
-  }
-
   /**
    * Returns the button corresponding to the buttonName.
    * @param buttonName the ButtonName for which we want to get the button.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java b/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
index 15decb0..0bd74e3 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetupStepPanel.java
@@ -108,6 +108,17 @@
   }
 
   /**
+   * Tells whether the method beginDisplay can be long and so should be called
+   * outside the event thread.
+   * @return <CODE>true</CODE> if the method beginDisplay can be long and so
+   * should be called outside the event thread and <CODE>true</CODE> otherwise.
+   */
+  public boolean blockingBeginDisplay()
+  {
+    return false;
+  }
+
+  /**
    * Called when a progress change must be reflected in the panels.  Only
    * ProgressPanel overwrites this method and for all the others it stays empty.
    * @param descriptor the descriptor of the Installation progress.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java b/opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java
index 82301d7..6d46b37 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/StepsPanel.java
@@ -30,13 +30,14 @@
 import java.awt.GridBagConstraints;
 import java.awt.GridBagLayout;
 
-import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.LinkedHashSet;
 
 import javax.swing.Box;
 import javax.swing.JLabel;
 import javax.swing.JPanel;
 
+import org.opends.quicksetup.UserData;
 import org.opends.quicksetup.WizardStep;
 
 /**
@@ -55,6 +56,8 @@
 
   HashMap<WizardStep, JLabel> hmIcons = new HashMap<WizardStep, JLabel>();
 
+  HashMap<WizardStep, JPanel> hmSubPanels = new HashMap<WizardStep, JPanel>();
+
   /**
    * Creates a StepsPanel.
    * @param app Application whose steps this class represents
@@ -70,8 +73,9 @@
    * as parameter.
    *
    * @param step the step in the wizard.
+   * @param userData the data provided by the user.
    */
-  public void setDisplayedStep(WizardStep step)
+  public void setDisplayedStep(WizardStep step, UserData userData)
   {
     for (WizardStep s : getApplication().getWizardSteps())
     {
@@ -79,7 +83,8 @@
       {
         getIcon(s).setVisible(true);
         UIFactory.setTextStyle(getLabel(s), UIFactory.TextStyle.CURRENT_STEP);
-      } else
+      }
+      else
       {
         if (getIcon(s) != null)
         {
@@ -91,6 +96,11 @@
               UIFactory.TextStyle.NOT_CURRENT_STEP);
         }
       }
+
+      if (getApplication().isSubStep(s))
+      {
+        setStepVisible(s, getApplication().isVisible(s));
+      }
     }
   }
 
@@ -112,19 +122,15 @@
     gbc.anchor = GridBagConstraints.WEST;
 
     HashMap<WizardStep, String> hmText = new HashMap<WizardStep, String>();
-    ArrayList<WizardStep> orderedSteps = new ArrayList<WizardStep>();
-
-    WizardStep step = app.getFirstWizardStep();
-    hmText.put(step, getMsg(step.getMessageKey()));
-    orderedSteps.add(step);
-    while (null != (step = app.getNextWizardStep(step))) {
-      hmText.put(step, getMsg(step.getMessageKey()));
-      orderedSteps.add(step);
-    }
-
+    LinkedHashSet<WizardStep> orderedSteps = app.getOrderedSteps();
+    boolean first = true;
     for (WizardStep s : orderedSteps)
     {
-      if (s != orderedSteps.get(0))
+      hmText.put(s, getMsg(s.getMessageKey()));
+
+      JPanel subPanel = new JPanel(new GridBagLayout());
+      subPanel.setOpaque(false);
+      if (!first)
       {
         gbc.insets.top = UIFactory.TOP_INSET_STEP;
       }
@@ -137,25 +143,49 @@
       JLabel iconLabel =
           UIFactory.makeJLabel(UIFactory.IconType.CURRENT_STEP, null,
               UIFactory.TextStyle.NO_STYLE);
+      if (getApplication().isSubStep(s))
+      {
+        gbcAux.insets.left = UIFactory.LEFT_INSET_SUBSTEP;
+      }
+      else
+      {
+        gbcAux.insets.left = 0;
+      }
+
       auxPanel.add(iconLabel, gbcAux);
       int width = (int) iconLabel.getPreferredSize().getWidth();
+      if (getApplication().isSubStep(s))
+      {
+        width += UIFactory.LEFT_INSET_SUBSTEP;
+      }
+      gbcAux.insets.left = 0;
       auxPanel.add(Box.createHorizontalStrut(width), gbcAux);
 
       hmIcons.put(s, iconLabel);
 
-      gbc.gridwidth = GridBagConstraints.RELATIVE;
-      mainPanel.add(auxPanel, gbc);
+      gbc.gridwidth = 3;
+      gbc.weightx = 0.0;
+      subPanel.add(auxPanel, gbc);
 
       JLabel stepLabel =
           UIFactory.makeJLabel(UIFactory.IconType.NO_ICON, hmText.get(s),
               UIFactory.TextStyle.CURRENT_STEP);
       hmLabels.put(s, stepLabel);
       gbc.insets.left = UIFactory.LEFT_INSET_STEP;
+      gbc.gridwidth = GridBagConstraints.RELATIVE;
+      subPanel.add(stepLabel, gbc);
+      gbc.insets = UIFactory.getEmptyInsets();
       gbc.gridwidth = GridBagConstraints.REMAINDER;
-      mainPanel.add(stepLabel, gbc);
+      gbc.weightx = 1.0;
+      subPanel.add(Box.createHorizontalGlue(), gbc);
+
+      mainPanel.add(subPanel, gbc);
+      hmSubPanels.put(s, subPanel);
 
       stepLabel.setLabelFor(this);
       iconLabel.setLabelFor(stepLabel);
+
+      first = false;
     }
 
     gbc.insets.left = 0;
@@ -201,4 +231,24 @@
   {
     return hmIcons.get(step);
   }
+
+  /**
+   * Returns the sub-panel associated with the given step.
+   * @param step the step for which we want to retrieve the sub-panel.
+   * @return the sub-panel associated with the given step.
+   */
+  private JPanel getSubPanel(WizardStep step)
+  {
+    return hmSubPanels.get(step);
+  }
+
+  private void setStepVisible(WizardStep step, boolean visible)
+  {
+    JPanel subPanel = getSubPanel(step);
+    // Check done to minimize possible flickering.
+    if (visible != subPanel.isVisible())
+    {
+      subPanel.setVisible(visible);
+    }
+  }
 }
diff --git a/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java b/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
index e012b80..7da1f9d 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/ui/UIFactory.java
@@ -1184,6 +1184,7 @@
     return buf.toString();
   }
 
+
   /**
    * Returns a table created with the provided model and renderers.
    * @param tableModel the table model.
diff --git a/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java b/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java
index 15e3fc2..e95cf93 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/ChooseVersionPanel.java
@@ -76,6 +76,14 @@
   /**
    * {@inheritDoc}
    */
+  public boolean blockingBeginDisplay()
+  {
+    return true;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   public void beginDisplay(UserData data) {
     super.beginDisplay(data);
     if (!loadBuildListAttempted) {
diff --git a/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java b/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
index 9b255bd..63324ad 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/upgrader/ui/UpgraderReviewPanel.java
@@ -78,6 +78,14 @@
   /**
    * {@inheritDoc}
    */
+  public boolean blockingBeginDisplay()
+  {
+    return true;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
   protected String getTitle() {
     return getMsg("upgrade-review-panel-title");
   }
@@ -93,8 +101,6 @@
    * {@inheritDoc}
    */
   protected JPanel createFieldsPanel() {
-    UpgradeUserData uud = (UpgradeUserData)getUserData();
-
     JPanel p = UIFactory.makeJPanel();
 
     LabelFieldDescriptor serverDescriptor = new LabelFieldDescriptor(
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java b/opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java
index cf25189..e71a829 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/HtmlProgressMessageFormatter.java
@@ -208,7 +208,7 @@
     String html = getHtml(text);
     String points = SPACE + getHtml(getMsg("progress-points")) + SPACE;
 
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     buf.append(UIFactory.applyFontToHtml(html, UIFactory.PROGRESS_FONT))
         .append(
             UIFactory.applyFontToHtml(points, UIFactory.PROGRESS_POINTS_FONT));
@@ -251,7 +251,7 @@
             UIFactory.PROGRESS_FONT);
     String closeDiv = "</div>";
 
-    StringBuffer stackBuf = new StringBuffer();
+    StringBuilder stackBuf = new StringBuilder();
     stackBuf.append(getHtmlStack(ex));
     Throwable root = ex.getCause();
     while (root != null)
@@ -263,7 +263,7 @@
     String stackText =
         UIFactory.applyFontToHtml(stackBuf.toString(), UIFactory.STACK_FONT);
 
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
 
     String msg = ex.getMessage();
     if (msg != null)
@@ -361,7 +361,7 @@
    */
   private String getHtml(String text)
   {
-    StringBuffer buffer = new StringBuffer();
+    StringBuilder buffer = new StringBuilder();
     if (text != null) {
       text = text.replaceAll("\r\n", "\n");
       String[] lines = text.split("[\n\r\u0085\u2028\u2029]");
@@ -388,7 +388,7 @@
    */
   private String escape(String rawString)
   {
-    StringBuffer buffer = new StringBuffer();
+    StringBuilder buffer = new StringBuilder();
     for (int i = 0; i < rawString.length(); i++)
     {
       char c = rawString.charAt(i);
@@ -451,7 +451,7 @@
    */
   private String getHtmlStack(Throwable ex)
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     StackTraceElement[] stack = ex.getStackTrace();
     for (int i = 0; i < stack.length; i++)
     {
@@ -500,7 +500,7 @@
   private String getErrorWithStackHtml(String openDiv, String hideText,
       String showText, String stackText, String closeDiv, boolean hide)
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
 
     String params =
         getUrlParams(openDiv, hideText, showText, stackText, closeDiv, hide);
@@ -539,7 +539,7 @@
   private String getUrlParams(String openDiv, String hideText,
       String showText, String stackText, String closeDiv, boolean hide)
   {
-    StringBuffer buf = new StringBuffer();
+    StringBuilder buf = new StringBuilder();
     buf.append(openDiv + PARAM_SEPARATOR);
     buf.append(hideText + PARAM_SEPARATOR);
     buf.append(showText + PARAM_SEPARATOR);
diff --git a/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 3f72ada..2f35537 100644
--- a/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -1170,6 +1170,7 @@
   }
 
   /**
+
    * Returns the max size in character of a line to be displayed in the command
    * line.
    * @return the max size in character of a line to be displayed in the command
diff --git a/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java b/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
index 6b41336..c4c5a5a 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
+++ b/opends/src/statuspanel/org/opends/statuspanel/BaseDNDescriptor.java
@@ -42,13 +42,13 @@
   public enum Type
   {
     /**
-     * The base DN is not synchronized.
+     * The base DN is not replicated.
      */
-    NOT_SYNCHRONIZED,
+    NOT_REPLICATED,
     /**
-     * The base DN is synchronized.
+     * The base DN is replicated.
      */
-    SYNCHRONIZED
+    REPLICATED
   };
 
   private int missingChanges;
@@ -59,8 +59,8 @@
 
   /**
    * Constructor for this class.
-   * @param type the type of synchronization.
-   * @param baseDn the base DN associated with the Synchronization.
+   * @param type the type of replication.
+   * @param baseDn the base DN associated with the Replication.
    * @param db the database containing this base DN.
    * @param ageOfOldestMissingChange the number of missing changes.
    * @param missingChanges the number of missing changes.
@@ -118,9 +118,9 @@
   }
 
   /**
-   * Returns the number of missing changes in the synchronization topology for
+   * Returns the number of missing changes in the replication topology for
    * this base DN.
-   * @return the number of missing changes in the synchronization topology for
+   * @return the number of missing changes in the replication topology for
    * this base DN.
    */
   public int getMissingChanges()
@@ -130,9 +130,9 @@
 
   /**
    * Returns the age of the oldest missing change in seconds in the
-   * synchronization topology for this base DN.
+   * replication topology for this base DN.
    * @return the age of the oldest missing change in seconds in the
-   * synchronization topology for this base DN.
+   * replication topology for this base DN.
    */
   public int getAgeOfOldestMissingChange()
   {
diff --git a/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java b/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
index 5b22f9b..291bb86 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
+++ b/opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
@@ -39,6 +39,7 @@
 import org.opends.server.util.LDIFReader;
 import org.opends.server.types.Attribute;
 import org.opends.server.types.AttributeValue;
+import org.opends.server.types.DN;
 import org.opends.server.types.Entry;
 import org.opends.server.types.LDIFImportConfig;
 import org.opends.server.types.ObjectClass;
@@ -65,9 +66,9 @@
     DirectoryServer.getObjectClass("ds-cfg-root-dn", true);
   private final ObjectClass syncProviderOc =
     DirectoryServer.getObjectClass("ds-cfg-synchronization-provider", true);
-  private final ObjectClass syncConfigOc =
-    DirectoryServer.getObjectClass("ds-cfg-synchronization-provider-config",
-    true);
+  private final ObjectClass replicationConfigOc =
+    DirectoryServer.getObjectClass("ds-cfg-replication-domain-config", true);
+  private DN replicationDomainDN;
 
   private HashSet<ListenerDescriptor> listeners =
     new HashSet<ListenerDescriptor>();
@@ -75,8 +76,8 @@
     new HashSet<DatabaseDescriptor>();
   private HashSet<String> administrativeUsers = new HashSet<String>();
   private String errorMessage;
-  private boolean synchronizationConfigured = false;
-  private HashSet<String> synchronizedSuffixes = new HashSet<String>();
+  private boolean replicationConfigured = false;
+  private HashSet<String> replicatedSuffixes = new HashSet<String>();
 
   /**
    * Default constructor.
@@ -97,8 +98,8 @@
     listeners.clear();
     databases.clear();
     administrativeUsers.clear();
-    synchronizationConfigured = false;
-    synchronizedSuffixes.clear();
+    replicationConfigured = false;
+    replicatedSuffixes.clear();
     try
     {
       Installation installation =
@@ -111,7 +112,7 @@
       {
         updateConfig(entry);
       }
-      updateSynchronization();
+      updateReplication();
     }
     catch (IOException ioe)
     {
@@ -263,9 +264,9 @@
    {
      updateConfigWithSyncProviderEntry(entry);
    }
-   else if (entry.hasObjectClass(syncConfigOc))
+   else if (entry.hasObjectClass(replicationConfigOc))
    {
-     updateConfigWithSyncConfig(entry);
+     updateConfigWithReplConfig(entry);
    }
   }
 
@@ -405,7 +406,7 @@
   }
 
   /**
-   * Updates the synchronization configuration data we expose to the user with
+   * Updates the replication configuration data we expose to the user with
    * the provided entry object.
    * @param entry the entry to analyze.
    */
@@ -414,24 +415,24 @@
     if ("true".equalsIgnoreCase(getFirstValue(entry,
         "ds-cfg-synchronization-provider-enabled")))
     {
-      synchronizationConfigured = true;
+      replicationConfigured = true;
     }
     else
     {
-      synchronizationConfigured = false;
+      replicationConfigured = false;
     }
   }
 
 
   /**
-   * Updates the databases suffixes with the list of synchronized suffixes
+   * Updates the databases suffixes with the list of replicated suffixes
    * found.
    */
-  private void updateSynchronization()
+  private void updateReplication()
   {
-    if (synchronizationConfigured)
+    if (replicationConfigured)
     {
-      for (String suffixDn: synchronizedSuffixes)
+      for (String suffixDn: replicatedSuffixes)
       {
         BaseDNDescriptor replica = null;
         for (DatabaseDescriptor db: databases)
@@ -452,20 +453,37 @@
         }
         if (replica != null)
         {
-          replica.setType(BaseDNDescriptor.Type.SYNCHRONIZED);
+          replica.setType(BaseDNDescriptor.Type.REPLICATED);
         }
       }
     }
   }
 
   /**
-   * Updates the synchronization configuration data we expose to the user with
+   * Updates the replication configuration data we expose to the user with
    * the provided entry object.
    * @param entry the entry to analyze.
    */
-  private void updateConfigWithSyncConfig(Entry entry)
+  private void updateConfigWithReplConfig(Entry entry)
   {
-    synchronizedSuffixes.addAll(getValues(entry, "ds-cfg-synchronization-dn"));
+    if (replicationDomainDN == null)
+    {
+      try
+      {
+        replicationDomainDN = DN.decode(
+            "cn=domains,cn=Multimaster Synchronization,"+
+            "cn=Synchronization Providers,cn=config");
+      }
+      catch (Throwable t)
+      {
+        // Bug
+        throw new IllegalStateException("Bug: "+t, t);
+      }
+    }
+    if (entry.getDN().isDescendantOf(replicationDomainDN))
+    {
+      replicatedSuffixes.addAll(getValues(entry, "ds-cfg-replication-dn"));
+    }
   }
 
   /**
@@ -517,11 +535,11 @@
   }
 
   /**
-   * Create a non synchronized base DN descriptor.
+   * Create a non replicated base DN descriptor.
    */
   private BaseDNDescriptor getBaseDNDescriptor(Entry entry, String baseDn)
   {
-    return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_SYNCHRONIZED,
+    return new BaseDNDescriptor(BaseDNDescriptor.Type.NOT_REPLICATED,
         baseDn, null, -1, -1);
   }
 }
diff --git a/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java b/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
index 81ab1c9..64575b4 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
+++ b/opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
@@ -59,8 +59,8 @@
     new HashSet<DatabaseDescriptor>();
   private HashSet<String> administrativeUsers = new HashSet<String>();
   private String errorMessage;
-  private boolean synchronizationConfigured = false;
-  private HashSet<String> synchronizedSuffixes = new HashSet<String>();
+  private boolean replicationConfigured = false;
+  private HashSet<String> replicatedSuffixes = new HashSet<String>();
   private HashMap<String, Integer> hmMissingChanges =
     new HashMap<String, Integer>();
   private HashMap<String, Integer> hmAgeOfOldestMissingChanges =
@@ -157,8 +157,8 @@
     listeners.clear();
     databases.clear();
     administrativeUsers.clear();
-    synchronizationConfigured = false;
-    synchronizedSuffixes.clear();
+    replicationConfigured = false;
+    replicatedSuffixes.clear();
     hmMissingChanges.clear();
     hmAgeOfOldestMissingChanges.clear();
     javaVersion = null;
@@ -169,7 +169,7 @@
       InitialLdapContext ctx = getDirContext();
       updateAdministrativeUsers(ctx);
       updateListeners(ctx);
-      updateSynchronization(ctx);
+      updateReplication(ctx);
       updateDatabases(ctx);
       javaVersion = getJavaVersion(ctx);
       openConnections = getOpenConnections(ctx);
@@ -341,12 +341,12 @@
   }
 
   /**
-   * Updates the synchronization configuration data we expose to the user with
+   * Updates the replication configuration data we expose to the user with
    * the provided InitialLdapContext.
    * @param ctx the InitialLdapContext to use to update the configuration.
    * @throws NamingException if there was an error.
    */
-  private void updateSynchronization(InitialLdapContext ctx)
+  private void updateReplication(InitialLdapContext ctx)
   throws NamingException
   {
     SearchControls ctls = new SearchControls();
@@ -371,7 +371,7 @@
         if ("true".equalsIgnoreCase(getFirstValue(sr,
           "ds-cfg-synchronization-provider-enabled")))
         {
-          synchronizationConfigured = true;
+          replicationConfigured = true;
         }
       }
     }
@@ -383,9 +383,9 @@
     ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
     ctls.setReturningAttributes(
         new String[] {
-            "ds-cfg-synchronization-dn"
+            "ds-cfg-replication-dn"
         });
-    filter = "(objectclass=ds-cfg-synchronization-provider-config)";
+    filter = "(objectclass=ds-cfg-replication-domain-config)";
 
     jndiName = new LdapName(
       "cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config");
@@ -398,7 +398,7 @@
       {
         SearchResult sr = (SearchResult)syncProviders.next();
 
-        synchronizedSuffixes.addAll(getValues(sr, "ds-cfg-synchronization-dn"));
+        replicatedSuffixes.addAll(getValues(sr, "ds-cfg-replication-dn"));
       }
     }
     catch (NameNotFoundException nse)
@@ -415,7 +415,7 @@
 
     jndiName = new LdapName("cn=monitor");
 
-    if (synchronizedSuffixes.size() > 0)
+    if (replicatedSuffixes.size() > 0)
     {
       try
       {
@@ -427,7 +427,7 @@
 
           String dn = getFirstValue(sr, "base-dn");
 
-          for (String baseDn: synchronizedSuffixes)
+          for (String baseDn: replicatedSuffixes)
           {
 
             if (Utils.areDnsEqual(dn, baseDn))
@@ -632,8 +632,8 @@
   }
 
   /**
-   * Create the base DN descriptor.  Assumes that the synchronizedSuffixes Set
-   * and synchronizationConfigured have already been initialized.
+   * Create the base DN descriptor.  Assumes that the replicatedSuffixes Set
+   * and replicationConfigured have already been initialized.
    */
   private BaseDNDescriptor getBaseDNDescriptor(InitialLdapContext ctx,
       String baseDn)
@@ -645,9 +645,9 @@
     String mapSuffixDn = null;
 
     boolean replicated = false;
-    if (synchronizationConfigured)
+    if (replicationConfigured)
     {
-      for (String suffixDn: synchronizedSuffixes)
+      for (String suffixDn: replicatedSuffixes)
       {
         if (Utils.areDnsEqual(baseDn, suffixDn))
         {
@@ -659,7 +659,7 @@
     }
     if (replicated)
     {
-      type = BaseDNDescriptor.Type.SYNCHRONIZED;
+      type = BaseDNDescriptor.Type.REPLICATED;
 
       Integer missing = hmMissingChanges.get(mapSuffixDn);
       Integer age = hmAgeOfOldestMissingChanges.get(mapSuffixDn);
@@ -676,7 +676,7 @@
     }
     else
     {
-      type = BaseDNDescriptor.Type.NOT_SYNCHRONIZED;
+      type = BaseDNDescriptor.Type.NOT_REPLICATED;
     }
 
     return new BaseDNDescriptor(type, baseDn, null, ageOfOldestMissingChange,
diff --git a/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java b/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
index 8f3e675..e1dbac3 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
+++ b/opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
@@ -940,7 +940,7 @@
       labelWidth = Math.max(labelWidth, labels[i].length());
     }
 
-    String synchronizedLabel = getMsg("suffix-synchronized-label", false);
+    String replicatedLabel = getMsg("suffix-replicated-label", false);
     for (int i=0; i<tableModel.getRowCount(); i++)
     {
       if (i > 0)
@@ -1007,7 +1007,7 @@
         {
           // If the suffix is not replicated we do not have to display these
           // lines.
-          if (!synchronizedLabel.equals(tableModel.getValueAt(i, 3)))
+          if (!replicatedLabel.equals(tableModel.getValueAt(i, 3)))
           {
             doWrite = false;
           }
diff --git a/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties b/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
index 25eccf5..405b7c4 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
+++ b/opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -86,7 +86,7 @@
 backendid-column=Backend ID
 basedn-column=Base DN
 number-entries-column=Entries
-synchronized-column=Synchronization
+replicated-column=Replication
 missing-changes-column=Missing Changes
 age-of-oldest-missing-change-column=<html>Age of Oldest<br>Missing \
 Change (hh:mm:ss)
@@ -110,8 +110,8 @@
 re-authenticating.\nDetails: {0}
 no-dbs-found=-No LDAP Databases Found-
 no-listeners-found=-No Listener Ports Found-
-suffix-synchronized-label=Enabled
-suffix-not-synchronized-label=Disabled
+suffix-replicated-label=Enabled
+suffix-not-replicated-label=Disabled
 
 #
 # Progress Dialog
diff --git a/opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java b/opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java
index d6ce8b5..5ba295e 100644
--- a/opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java
+++ b/opends/src/statuspanel/org/opends/statuspanel/ui/DatabasesTableModel.java
@@ -55,7 +55,7 @@
     getMsg("basedn-column"),
     getMsg("backendid-column"),
     getMsg("number-entries-column"),
-    getMsg("synchronized-column"),
+    getMsg("replicated-column"),
     getMsg("missing-changes-column"),
     getMsg("age-of-oldest-missing-change-column")
   };
@@ -123,7 +123,7 @@
 
       if (result == 0)
       {
-        result = compareSync(desc1, desc2);
+        result = compareRepl(desc1, desc2);
       }
 
       if (result == 0)
@@ -153,7 +153,7 @@
 
       if (result == 0)
       {
-        result = compareSync(desc1, desc2);
+        result = compareRepl(desc1, desc2);
       }
 
       if (result == 0)
@@ -182,7 +182,7 @@
 
       if (result == 0)
       {
-        result = compareSync(desc1, desc2);
+        result = compareRepl(desc1, desc2);
       }
 
       if (result == 0)
@@ -197,7 +197,7 @@
     }
     else if (sortColumn == 3)
     {
-      result = compareSync(desc1, desc2);
+      result = compareRepl(desc1, desc2);
 
       if (result == 0)
       {
@@ -245,7 +245,7 @@
 
       if (result == 0)
       {
-        result = compareSync(desc1, desc2);
+        result = compareRepl(desc1, desc2);
       }
 
       if (result == 0)
@@ -274,7 +274,7 @@
 
       if (result == 0)
       {
-        result = compareSync(desc1, desc2);
+        result = compareRepl(desc1, desc2);
       }
 
       if (result == 0)
@@ -328,7 +328,7 @@
     }
     else if (col == 3)
     {
-      v = getStringForSyncState(desc);
+      v = getStringForReplState(desc);
     }
     else if (col == 4)
     {
@@ -423,7 +423,7 @@
     return desc1.getDn().compareTo(desc2.getDn());
   }
 
-  private int compareSync(BaseDNDescriptor desc1, BaseDNDescriptor desc2)
+  private int compareRepl(BaseDNDescriptor desc1, BaseDNDescriptor desc2)
   {
     return (String.valueOf(desc1.getType()).compareTo(
         String.valueOf(desc2.getType())));
@@ -473,7 +473,7 @@
   /**
    * Returns the Object describing the number of missing changes of a given Base
    * DN.  The Object will be a String unless the base DN is
-   * synchronized and we could not find a valid value (in this case we return
+   * replicated and we could not find a valid value (in this case we return
    * an Integer with the invalid value).
    * @param rep the Base DN object to handle.
    * @return the Object describing the number of missing changes of
@@ -482,7 +482,7 @@
   private Object getValueForMissingChanges(BaseDNDescriptor rep)
   {
     Object v;
-    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
+    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
     {
       v = new Integer(rep.getMissingChanges());
     }
@@ -496,7 +496,7 @@
   /**
    * Returns the Object describing the age of oldest missing change of
    * a given Base DN.  The Object will be a String unless the base DN is
-   * synchronized and we could not find a valid value (in this case we return
+   * replicated and we could not find a valid value (in this case we return
    * an Integer with the invalid value).
    * @param rep the Base DN object to handle.
    * @return the Object describing the age of oldest missing change of
@@ -505,7 +505,7 @@
   private Object getValueForOldestMissingChange(BaseDNDescriptor rep)
   {
     Object v;
-    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
+    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
     {
       int age = rep.getAgeOfOldestMissingChange();
       if (age >= 0)
@@ -538,22 +538,22 @@
   }
 
   /**
-   * Returns the localized String describing the synchronization state of
+   * Returns the localized String describing the replication state of
    * a given Base DN.
    * @param rep the Base DN object to handle.
-   * @return the localized String describing the synchronization state of
+   * @return the localized String describing the replication state of
    * a given Base DN.
    */
-  private String getStringForSyncState(BaseDNDescriptor rep)
+  private String getStringForReplState(BaseDNDescriptor rep)
   {
     String s;
-    if (rep.getType() == BaseDNDescriptor.Type.SYNCHRONIZED)
+    if (rep.getType() == BaseDNDescriptor.Type.REPLICATED)
     {
-      s = getMsg("suffix-synchronized-label");
+      s = getMsg("suffix-replicated-label");
     }
     else
     {
-      s = getMsg("suffix-not-synchronized-label");
+      s = getMsg("suffix-not-replicated-label");
     }
     return s;
   }

--
Gitblit v1.10.0