From 4fab9c68f1e4755b7381ecf9bd86c8b30417bd8f Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 05 Sep 2007 06:40:30 +0000
Subject: [PATCH] The following changes are targetted to fix a certain number of issues related to the setup command line:

---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java                |  235 ++
 opendj-sdk/opends/resource/setup                                                               |    2 
 opendj-sdk/opends/build.xml                                                                    |    9 
 opendj-sdk/opends/resource/setup-gui.bat                                                       |   89 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java |   24 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java         |  220 ++
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java                         |    3 
 opendj-sdk/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java              |  604 +++++++
 opendj-sdk/opends/resource/setup.bat                                                           |   10 
 /dev/null                                                                                      |  305 ---
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java         |   29 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java                           |   47 
 opendj-sdk/opends/src/messages/messages/tools.properties                                       |  127 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java               |   36 
 opendj-sdk/opends/resource/setup-gui                                                           |  131 +
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java    |   13 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java      |   23 
 opendj-sdk/opends/src/messages/messages/quicksetup.properties                                  |   46 
 opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java                       |   27 
 opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java  |    4 
 opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java                            | 2681 ++++++++++++++++++---------------
 21 files changed, 2,978 insertions(+), 1,687 deletions(-)

diff --git a/opendj-sdk/opends/build.xml b/opendj-sdk/opends/build.xml
index 24934bb..7edae79 100644
--- a/opendj-sdk/opends/build.xml
+++ b/opendj-sdk/opends/build.xml
@@ -875,12 +875,13 @@
       <fileset file="${resource.dir}/README" />
     </copy>
 
-    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup,uninstall,uninstall-gui,upgrade"
+    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup,setup-gui,uninstall,uninstall-gui,upgrade"
          eol="lf" />
-    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup.bat,uninstall.bat,uninstall-gui.bat,upgrade.bat"
+    <fixcrlf srcDir="${resource.dir}" destDir="${pdir}" includes="setup.bat,setup-gui.bat,uninstall.bat,uninstall-gui.bat,upgrade.bat"
          eol="crlf" />
 
     <chmod file="${pdir}/setup" perm="755" />
+  	<chmod file="${pdir}/setup-gui" perm="755" />
     <chmod file="${pdir}/uninstall" perm="755" />
   	<chmod file="${pdir}/uninstall-gui" perm="755" />
     <chmod file="${pdir}/upgrade" perm="755" />
@@ -900,7 +901,7 @@
        description="Package the Directory Server for distribution.">
     <zip destfile="${package.dir}/${SHORT_NAME}-${VERSION_NUMBER_STRING}.zip">
       <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/**/*"
-           excludes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/*,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
+           excludes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/*,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
            filemode="644" dirmode="755" />
       <zipfileset dir="${package.dir}"
            includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_client-script.sh,${SHORT_NAME}-${VERSION_NUMBER_STRING}/lib/_server-script.sh"
@@ -910,7 +911,7 @@
            filemode="755" dirmode="755" />
       <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/bin/README_WINDOWS.txt"
            filemode="644" dirmode="755" />
-      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
+      <zipfileset dir="${package.dir}" includes="${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup,${SHORT_NAME}-${VERSION_NUMBER_STRING}/setup-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall,${SHORT_NAME}-${VERSION_NUMBER_STRING}/uninstall-gui,${SHORT_NAME}-${VERSION_NUMBER_STRING}/upgrade"
            filemode="755" dirmode="755" />
     </zip>
     <property name="package.built" value="true"/>
diff --git a/opendj-sdk/opends/resource/setup b/opendj-sdk/opends/resource/setup
index e35fd7a..df90093 100755
--- a/opendj-sdk/opends/resource/setup
+++ b/opendj-sdk/opends/resource/setup
@@ -118,7 +118,7 @@
 
 
 # Launch the setup process.
-"${JAVA_BIN}" org.opends.quicksetup.installer.InstallLauncher -P setup "${@}"
+"${JAVA_BIN}" -Dorg.opends.server.scriptName=setup org.opends.server.tools.InstallDS "${@}"
 
 # return part
 RETURN_CODE=$?
diff --git a/opendj-sdk/opends/resource/setup-gui b/opendj-sdk/opends/resource/setup-gui
new file mode 100644
index 0000000..b8963ba
--- /dev/null
+++ b/opendj-sdk/opends/resource/setup-gui
@@ -0,0 +1,131 @@
+#!/bin/sh
+#
+# 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.
+
+
+# See if JAVA_HOME is set.  If not, then see if there is a java executable in
+# the path and try to figure it out.
+if test -z "${JAVA_BIN}"
+then
+  if test -z "${JAVA_HOME}"
+  then
+    if test -f "${INSTANCE_ROOT}/lib/set-java-home"
+    then
+      . "${INSTANCE_ROOT}/bin/set-java-home"
+      JAVA_BIN="${JAVA_HOME}/bin/java"
+      export JAVA_BIN
+    else
+      JAVA_BIN=`which java 2> /dev/null`
+      if test ${?} -eq 0
+      then
+        export JAVA_BIN
+      else
+        echo "Please set JAVA_HOME to the root of a Java 5  (or later) installation."
+        exit 1
+      fi
+    fi
+  else
+    JAVA_BIN="${JAVA_HOME}/bin/java"
+    export JAVA_BIN
+  fi
+fi
+
+
+# Explicitly set the PATH, LD_LIBRARY_PATH, LD_PRELOAD, and other important
+# system environment variables for security and compatibility reasons.
+PATH=/bin:/usr/bin
+LD_LIBRARY_PATH=
+LD_LIBRARY_PATH_32=
+LD_LIBRARY_PATH_64=
+LD_PRELOAD=
+LD_PRELOAD_32=
+LD_PRELOAD_64=
+export PATH LD_LIBRARY_PATH LD_LIBRARY_PATH_32 LD_LIBRARY_PATH_64 \
+       LD_PRELOAD LD_PRELOAD_32 LD_PRELOAD_34
+
+
+# Capture the current working directory so that we can change to it later.
+# Then capture the location of this script and the Directory Server instance
+# root so that we can use them to create appropriate paths.
+WORKING_DIR=`pwd`
+
+cd `dirname "${0}"`
+SCRIPT_DIR=`pwd`
+
+INSTANCE_ROOT=${SCRIPT_DIR}
+export INSTANCE_ROOT
+
+cd "${WORKING_DIR}"
+
+
+# Configure the appropriate CLASSPATH.
+CLASSPATH=${INSTANCE_ROOT}/classes
+for JAR in ${INSTANCE_ROOT}/lib/*.jar
+do
+  CLASSPATH=${CLASSPATH}:${JAR}
+done
+export CLASSPATH
+
+
+# Determine whether the detected Java environment is acceptable for use.
+if test -z "${JAVA_ARGS}"
+then
+  "${JAVA_BIN}" -client org.opends.server.tools.InstallDS -t 2> /dev/null
+  if test ${?} -eq 0
+  then
+    JAVA_ARGS="-client"
+  else
+    "${JAVA_BIN}" org.opends.server.tools.InstallDS -t 2> /dev/null
+    if test ${?} -ne 0
+    then
+      echo "ERROR:  The detected Java version could not be used.  Please set "
+      echo "        JAVA_HOME to the root of a Java 5 (or later) installation."
+      exit 1
+    fi
+  fi
+else
+  "${JAVA_BIN}" ${JAVA_ARGS} org.opends.server.tools.InstallDS -t 2> /dev/null
+  if test ${?} -ne 0
+  then
+    echo "ERROR:  The detected Java version could not be used.  Please set "
+    echo "        JAVA_HOME to the root of a Java 5 (or later) installation."
+    exit 1
+  fi
+fi
+
+
+# Launch the setup process.
+"${JAVA_BIN}" org.opends.quicksetup.installer.SetupGuiLauncher "${@}"
+
+# return part
+RETURN_CODE=$?
+if test ${RETURN_CODE} -eq 50
+then
+  # Version info was on requested
+  exit 0
+else
+  exit ${RETURN_CODE}
+fi
\ No newline at end of file
diff --git a/opendj-sdk/opends/resource/setup-gui.bat b/opendj-sdk/opends/resource/setup-gui.bat
new file mode 100644
index 0000000..2fb7df6
--- /dev/null
+++ b/opendj-sdk/opends/resource/setup-gui.bat
@@ -0,0 +1,89 @@
+
+@echo off
+rem CDDL HEADER START
+rem
+rem The contents of this file are subject to the terms of the
+rem Common Development and Distribution License, Version 1.0 only
+rem (the "License").  You may not use this file except in compliance
+rem with the License.
+rem
+rem You can obtain a copy of the license at
+rem trunk/opends/resource/legal-notices/OpenDS.LICENSE
+rem or https://OpenDS.dev.java.net/OpenDS.LICENSE.
+rem See the License for the specific language governing permissions
+rem and limitations under the License.
+rem
+rem When distributing Covered Code, include this CDDL HEADER in each
+rem file and include the License file at
+rem trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
+rem add the following below this CDDL HEADER, with the fields enclosed
+rem by brackets "[]" replaced with your own identifying information:
+rem      Portions Copyright [yyyy] [name of copyright owner]
+rem
+rem CDDL HEADER END
+rem
+rem
+rem      Portions Copyright 2007 Sun Microsystems, Inc.
+
+setlocal
+for %%i in (%~sf0) do set DIR_HOME=%%~dPsi.
+
+set INSTANCE_ROOT=%DIR_HOME%
+
+:checkJavaBin
+if "%JAVA_BIN%" == "" goto noJavaBin
+goto setClassPath
+
+:noJavaBin
+if "%JAVA_HOME%" == "" goto noJavaHome
+if not exist "%JAVA_HOME%\bin\java.exe" goto noJavaHome
+set JAVA_BIN=%JAVA_HOME%\bin\java.exe
+goto setClassPath
+
+:noJavaHome
+if not exist "%DIR_HOME%\lib\set-java-home.bat" goto noSetJavaHome
+call "%DIR_HOME%\lib\set-java-home.bat"
+set JAVA_BIN=%JAVA_HOME%\bin\java.exe
+goto setClassPath
+
+:noSetJavaHome
+echo Error: JAVA_HOME environment variable is not set.
+echo        Please set it to a valid Java 5 (or later) installation.
+pause
+goto end
+
+:noValidJavaHome
+echo ERROR:  The detected Java version could not be used.  Please set 
+echo         JAVA_HOME to to a valid Java 5 (or later) installation.
+pause
+goto end
+
+:setClassPath
+FOR %%x in ("%DIR_HOME%\lib\*.jar") DO call "%DIR_HOME%\lib\setcp.bat" %%x
+set CLASSPATH=%DIR_HOME%\classes;%CLASSPATH%
+
+set PATH=%SystemRoot%
+
+rem Test that the provided JDK is 1.5 compatible.
+"%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
+if not %errorlevel% == 0 goto noValidJavaHome
+
+if "%~1" == "" goto callLaunch
+goto callJava
+
+:callLaunch
+"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.SetupGuiLauncher
+goto end
+
+:callJava
+"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.SetupGuiLauncher %*
+
+rem return part
+if %errorlevel% == 50 goto version
+goto end
+
+:version
+rem version information was requested. Return code should be 0.
+exit /B 0
+
+:end
diff --git a/opendj-sdk/opends/resource/setup.bat b/opendj-sdk/opends/resource/setup.bat
index 07ba26f..53c601b 100644
--- a/opendj-sdk/opends/resource/setup.bat
+++ b/opendj-sdk/opends/resource/setup.bat
@@ -84,15 +84,7 @@
 "%JAVA_BIN%" org.opends.server.tools.InstallDS -t > NUL 2>&1
 if not %errorlevel% == 0 goto noValidJavaHome
 
-if "%~1" == "" goto callLaunch
-goto callJava
-
-:callLaunch
-"%DIR_HOME%\lib\winlauncher.exe" launch "%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat
-goto end
-
-:callJava
-"%JAVA_BIN%" %JAVA_ARGS% org.opends.quicksetup.installer.InstallLauncher -P setup.bat %*
+"%JAVA_BIN%" %JAVA_ARGS% -Dorg.opends.server.scriptName=setup.bat org.opends.server.tools.InstallDS %*
 
 rem return part
 if %errorlevel% == 50 goto version
diff --git a/opendj-sdk/opends/src/messages/messages/quicksetup.properties b/opendj-sdk/opends/src/messages/messages/quicksetup.properties
index 66cc353..cca56d7 100644
--- a/opendj-sdk/opends/src/messages/messages/quicksetup.properties
+++ b/opendj-sdk/opends/src/messages/messages/quicksetup.properties
@@ -219,7 +219,7 @@
 INFO_DETAILS_LABEL=Details:
 INFO_DIRECTORY_DATA_LABEL=Directory Data:
 INFO_DIRECTORY_EXISTS_NOT_EMPTY=The directory %s is not empty.
-INFO_DIRECTORY_MANAGER_DN_IS_CONFIG_DN=The provided Administrative User DN is \
+INFO_DIRECTORY_MANAGER_DN_IS_CONFIG_DN=The provided Root User DN is \
  used for the configuration of the Directory Server.
 INFO_DIRECTORY_NOT_WRITABLE=You do not have write access on the directory %s. \
  You must have file right access on the Installation directory.
@@ -237,9 +237,9 @@
 INFO_EMPTY_ADMINISTRATOR_UID=You must provide a Global Administrative User \
  ID.
 INFO_EMPTY_BASE_DN=You must provide a Directory Base DN.
-INFO_EMPTY_DIRECTORY_MANAGER_DN=You must provide an Administrative User DN.
+INFO_EMPTY_DIRECTORY_MANAGER_DN=You must provide an Root User DN.
 INFO_EMPTY_HOST_NAME=You must provide the name of the host.
-INFO_EMPTY_PWD=You must provide the password of the Administrative User.
+INFO_EMPTY_PWD=You must provide the password of the Root User.
 INFO_EMPTY_REMOTE_DN=You must provide a value for the Administrative User.
 INFO_EMPTY_REMOTE_HOST=You must provide the fully qualified name of the host.
 INFO_EMPTY_REMOTE_PWD=You must provide an Admin User password.
@@ -259,12 +259,12 @@
  communication.
 INFO_ERROR_ACCESSING_JKS_KEYSTORE=Could not access the JKS key store.  Check \
  that the contents of the file correspond to a valid JKS key store, that you \
- have access rights to it and that the provided password is valid.
+ have access rights to it and that the provided PIN is valid.
 INFO_ERROR_ACCESSING_PKCS11_KEYSTORE=Could not access the PKCS#11 key store. \
- Check that is installed and that the provided password is valid.
+ Check that is installed and that the provided PIN is valid.
 INFO_ERROR_ACCESSING_PKCS12_KEYSTORE=Could not access the PKCS#12 key store. \
  Check that the contents of the file correspond to a valid PKCS#12 key store, \
- that you have access rights to it and that the provided password is valid.
+ that you have access rights to it and that the provided PIN is valid.
 INFO_ERROR_APPLY_LDIF_ADD=Error processing add operation of %s: %s
 INFO_ERROR_APPLY_LDIF_DELETE=Error processing delete operation of %s: %s
 INFO_ERROR_APPLY_LDIF_MODIFY=Error processing modification operation of %s: \
@@ -483,7 +483,7 @@
 INFO_HOST_NAME_TOOLTIP=Enter the name of the host.
 INFO_HTML_SEPARATOR_COLOR=666666
 INFO_IMPORT_AUTOMATICALLY_GENERATED_LABEL=Import Automatically-Generated \
- Example Data
+ Sample Data
 INFO_IMPORT_AUTOMATICALLY_GENERATED_TOOLTIP=Populate the base DN with \
  automatically-generated LDAP data
 INFO_IMPORT_DATA_FROM_LDIF_LABEL=Import Data from LDIF File
@@ -520,6 +520,9 @@
 INFO_INSTALLANDUPGRADER_RBUPGRADE_LABEL=Upgrade Existing Server Instance
 INFO_INSTALLANDUPGRADER_RBUPGRADE_TOOLTIP=Select to upgrade an existing \
  server instance.
+INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG_CLI=The Directory Server \
+ contains some database files.%nThe setup will delete the contents of these \
+ database files.
 INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG=The Directory Server \
  contains some database files.<br>If you continue with the setup the contents \
  of these database files will be deleted.
@@ -528,6 +531,9 @@
 INFO_INSTALLSTATUS_INSTALLED=OpenDS Server Already Configured<br> QuickSetup \
  can only be used with OpenDS Servers that have not yet been configured.  The \
  current server:%s
+INFO_INSTALLSTATUS_INSTALLED_CLI=OpenDS Server Already Configured%n %s \
+ command-line can only be used with OpenDS Servers that have not yet been \
+ configured.  The current server:%s
 INFO_INSTALLSTATUS_NOT_INSTALLED=The Directory Server is not installed.
 INFO_INSTALLSTATUS_SERVERRUNNING=Is currently running on port %s
 INFO_INSTRUCTIONS_COLOR=000,000,000
@@ -555,9 +561,9 @@
 INFO_KEYSTORE_PATH_NOT_A_FILE=The provided key store path is not a file.
 INFO_KEYSTORE_PATH_NOT_PROVIDED=You must provide the path of the key store.
 INFO_KEYSTORE_PATH_TOOLTIP=Absolute path to the keystore.
-INFO_KEYSTORE_PWD_EMPTY=You must provide the password of the key store.
-INFO_KEYSTORE_PWD_LABEL=Key Store Password:
-INFO_KEYSTORE_PWD_TOOLTIP=Provide the password required to access the \
+INFO_KEYSTORE_PWD_EMPTY=You must provide the PIN of the key store.
+INFO_KEYSTORE_PWD_LABEL=Key Store PIN:
+INFO_KEYSTORE_PWD_TOOLTIP=Provide the PIN (password) required to access the \
  existing key store.
 INFO_KEYSTORE_TYPE_LABEL=Key Store Type:
 INFO_LDIF_FILE_DOES_NOT_EXIST=The provided LDIF file does not exist.
@@ -580,10 +586,10 @@
 INFO_NO_SUFFIXES_CHOSEN_TO_REPLICATE=You must select at least one base DN to \
  replicate contents with.
 INFO_NOT_A_BASE_DN=The provided Directory Base DN is not a valid DN.
-INFO_NOT_A_DIRECTORY_MANAGER_DN=The provided Administrative User DN is not a \
+INFO_NOT_A_DIRECTORY_MANAGER_DN=The provided Root User DN is not a \
  valid DN.
 INFO_NOT_A_DIRECTORY_MANAGER_IN_CONFIG=The provided DN is not one of the \
- Administrative User DN.
+ Root User DN.
 INFO_NOT_AVAILABLE_LABEL=<not available>
 INFO_NOT_ENOUGH_DISK_SPACE=There is not enough free disk space under %s.%nAt \
  least %s megabytes of free disk space are required to install OpenDS.
@@ -638,7 +644,7 @@
 INFO_PKCS12_CERTIFICATE_TOOLTIP=Select this option if you have a PKCS#12 \
  certificate.
 INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST=No certificates for the PCKS#12 key store \
- could be found.  Check that the provided path and password are valid and that \
+ could be found.  Check that the provided path and PIN are valid and that \
  the key store contains certificates.
 INFO_PREVIOUS_BUTTON_LABEL=< Previous
 INFO_PREVIOUS_BUTTON_TOOLTIP=Go to Previous Step
@@ -653,6 +659,7 @@
 INFO_PROGRESS_CREATING_ADS_ON_REMOTE=Creating Registration Configuration on \
  %s
 INFO_PROGRESS_CREATING_BASE_ENTRY=Creating Base Entry %s
+INFO_PROGRESS_CREATING_BASE_ENTRIES=Creating Base Entry for the base DNs
 INFO_PROGRESS_DELETING_DIRECTORY=Deleting directory %s
 INFO_PROGRESS_DELETING_EXTERNAL_DB_FILES=Deleting Database Files outside the \
  Installation Path:
@@ -674,6 +681,7 @@
 INFO_PROGRESS_IMPORT_AUTOMATICALLY_GENERATED=Importing \
  Automatically-Generated Data (%s Entries):
 INFO_PROGRESS_IMPORTING_LDIF=Importing LDIF file %s:
+INFO_PROGRESS_IMPORTING_LDIFS=Importing LDIF files %s:
 INFO_PROGRESS_INITIALIZING_ADS=Initializing Registration information
 INFO_PROGRESS_INITIALIZING_SUFFIX=Initializing base DN %s with the contents \
  from %s:
@@ -693,7 +701,7 @@
 INFO_PROGRESS_UPDATING_CERTIFICATES=Configuring Certificates
 INFO_PROGRESSBAR_INITIAL_LABEL=Starting...
 INFO_PROGRESSBAR_TOOLTIP=Progress Bar
-INFO_PWD_TOO_SHORT=The minimum length required for the Administrative User \
+INFO_PWD_TOO_SHORT=The minimum length required for the Root User \
  password is %s characters.
 INFO_QUIT_BUTTON_INSTALL_TOOLTIP=Quit Setup
 INFO_QUIT_BUTTON_LABEL=Quit
@@ -795,15 +803,15 @@
  alias.
 INFO_SELECT_ALIAS_TITLE=OpenDS QuickSetup
 INFO_SELF_SIGNED_CERTIFICATE=Create a new Self-Signed Certificate
-INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL=Administrative User DN:
+INFO_SERVER_DIRECTORY_MANAGER_DN_LABEL=Root User DN:
 INFO_SERVER_DIRECTORY_MANAGER_DN_TOOLTIP=Enter the distinguished name (DN) of \
- the Administrative User account that will used for managing OpenDS
+ the inital Root User account that will used for managing OpenDS
 INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_LABEL=Password (confirm):
 INFO_SERVER_DIRECTORY_MANAGER_PWD_CONFIRM_TOOLTIP=Re-enter the password for \
- the OpenDS Administrative User account
+ the OpenDS inital Root User account
 INFO_SERVER_DIRECTORY_MANAGER_PWD_LABEL=Password:
 INFO_SERVER_DIRECTORY_MANAGER_PWD_TOOLTIP=Enter a password for the OpenDS \
- Administrative User account
+ inital Root User account
 INFO_SERVER_ERROR=Error on %s:
 INFO_SERVER_LOCATION_LABEL=Installation Path:
 INFO_SERVER_LOCATION_PARENT_TOOLTIP=Enter the full path to the parent \
@@ -823,7 +831,7 @@
 INFO_SERVER_SECURITY_TOOLTIP=The LDAP Secure Access Configuration for the new \
  OpenDS server.
 INFO_SERVER_SETTINGS_PANEL_INSTRUCTIONS=Enter a port to listen for LDAP \
- requests and enter a password for the OpenDS administrative user.
+ requests and enter a password for the OpenDS initial Root user.
 INFO_SERVER_SETTINGS_PANEL_INSTRUCTIONS_WEBSTART=Choose a location for the \
  server files and enter a password for the OpenDS administrative user.
 INFO_SERVER_SETTINGS_PANEL_TITLE=Server Settings
diff --git a/opendj-sdk/opends/src/messages/messages/tools.properties b/opendj-sdk/opends/src/messages/messages/tools.properties
index 1655a2d..fc8c231 100644
--- a/opendj-sdk/opends/src/messages/messages/tools.properties
+++ b/opendj-sdk/opends/src/messages/messages/tools.properties
@@ -216,9 +216,9 @@
 INFO_DESCRIPTION_ENCODING_115=Use the specified character set for \
  command-line input
 INFO_DESCRIPTION_VERBOSE_116=Use verbose mode
-INFO_DESCRIPTION_KEYSTOREPATH_117=Certificate keystore path
+INFO_DESCRIPTION_KEYSTOREPATH_117=Certificate key store path
 INFO_DESCRIPTION_TRUSTSTOREPATH_118=Certificate trust store path
-INFO_DESCRIPTION_KEYSTOREPASSWORD_119=Certificate keystore PIN
+INFO_DESCRIPTION_KEYSTOREPASSWORD_119=Certificate key store PIN
 INFO_DESCRIPTION_HOST_120=Directory server hostname or IP address
 INFO_DESCRIPTION_PORT_121=Directory server port number
 INFO_DESCRIPTION_SHOWUSAGE_122=Display this usage information
@@ -669,9 +669,9 @@
 INFO_STOPDS_DESCRIPTION_STOP_TIME_384=Time to begin the shutdown in \
  YYYYMMDDhhmmss format (local time)
 INFO_STOPDS_DESCRIPTION_TRUST_ALL_385=Trust all server SSL certificates
-INFO_STOPDS_DESCRIPTION_KSFILE_386=Certificate keystore path
-INFO_STOPDS_DESCRIPTION_KSPW_387=Certificate keystore PIN
-INFO_STOPDS_DESCRIPTION_KSPWFILE_388=Certificate keystore PIN file
+INFO_STOPDS_DESCRIPTION_KSFILE_386=Certificate key store path
+INFO_STOPDS_DESCRIPTION_KSPW_387=Certificate key store PIN
+INFO_STOPDS_DESCRIPTION_KSPWFILE_388=Certificate key store PIN file
 INFO_STOPDS_DESCRIPTION_TSFILE_389=Certificate trust store path
 INFO_STOPDS_DESCRIPTION_TSPW_390=Certificate trust store PIN
 INFO_STOPDS_DESCRIPTION_TSPWFILE_391=Certificate trust store PIN file
@@ -861,7 +861,7 @@
 INFO_INSTALLDS_DESCRIPTION_LDAPPORT_493=Specifies the port on which the \
  Directory Server should listen for LDAP communication
 INFO_INSTALLDS_DESCRIPTION_SKIPPORT_494=Skip the check to determine whether \
- the specified LDAP port is usable
+ the specified ports are usable
 INFO_INSTALLDS_DESCRIPTION_ROOTDN_495=Specifies the DN for the initial root \
  user for the Directory Server
 INFO_INSTALLDS_DESCRIPTION_ROOTPW_496=Specifies the password for the initial \
@@ -886,7 +886,7 @@
 INFO_INSTALLDS_PROMPT_IMPORT_505=Do you wish to populate the directory \
  database with information from an existing LDIF file?
 INFO_INSTALLDS_PROMPT_IMPORT_FILE_506=Please specify the path to the LDIF \
- file containing the data to import
+ file containing the data to import:
 SEVERE_ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS_507=ERROR:  You may not \
  provide both the %s and the %s arguments at the same time
 INFO_INSTALLDS_PROMPT_ADDBASE_508=Would you like to have the base %s entry \
@@ -906,9 +906,9 @@
  for the initial root user.  When performing a quiet installation, this must \
  be provided using either the %s or the %s argument
 INFO_INSTALLDS_PROMPT_ROOT_PASSWORD_514=Please provide the password to use \
- for the initial root user
+ for the initial root user:
 INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD_515=Please re-enter the password \
- for confirmation
+ for confirmation:
 INFO_INSTALLDS_STATUS_CONFIGURING_DS_516=Applying the requested configuration \
  to the Directory Server...
 INFO_INSTALLDS_STATUS_CREATING_BASE_LDIF_517=Creating a temporary LDIF file \
@@ -1186,10 +1186,10 @@
  communication with the Directory Server
 INFO_LDAPPWMOD_DESCRIPTION_BLIND_TRUST_648=Blindly trust any SSL certificate \
  presented by the server
-INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_649=The path to the keystore to use when \
+INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_649=The path to the key store to use when \
  establishing SSL/TLS communication with the server
 INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PINFILE_650=The path to a file containing \
- the PIN needed to access the contents of the keystore
+ the PIN needed to access the contents of the key store
 INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_651=The path to the trust store to use \
  when establishing SSL/TLS communication with the server
 INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PINFILE_652=The path to a file \
@@ -1252,8 +1252,8 @@
  from a Directory Server backend in LDIF form
 INFO_LDIFIMPORT_TOOL_DESCRIPTION_687=This utility may be used to import LDIF \
  data into a Directory Server backend
-INFO_INSTALLDS_TOOL_DESCRIPTION_688=This utility may be used to define a base \
- configuration for the Directory Server
+INFO_INSTALLDS_TOOL_DESCRIPTION_688=This utility may be used to setup the \
+ Directory Server
 INFO_LDAPCOMPARE_TOOL_DESCRIPTION_689=This utility may be used to perform \
  LDAP compare operations in the Directory Server
 INFO_LDAPDELETE_TOOL_DESCRIPTION_690=This utility may be used to perform LDAP \
@@ -1292,7 +1292,7 @@
 SEVERE_ERR_TOOL_SASLEXTERNAL_NEEDS_SSL_OR_TLS_706=SASL EXTERNAL \
  authentication may only be requested if SSL or StartTLS is used
 SEVERE_ERR_TOOL_SASLEXTERNAL_NEEDS_KEYSTORE_707=SASL EXTERNAL authentication \
- may only be used if a client certificate keystore is specified
+ may only be used if a client certificate key store is specified
 INFO_LDAPSEARCH_PSEARCH_CHANGE_TYPE_708=# Persistent search change type:  %s
 INFO_LDAPSEARCH_PSEARCH_PREVIOUS_DN_709=# Persistent search previous entry \
  DN:  %s
@@ -1310,7 +1310,7 @@
 INFO_LDAPSEARCH_ACCTUSABLE_LOCKED_718=#   The account is locked
 INFO_LDAPSEARCH_ACCTUSABLE_TIME_UNTIL_UNLOCK_719=#   Time until the account \
  is unlocked:  %s
-INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE_720=Certificate keystore PIN file
+INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE_720=Certificate key store PIN file
 INFO_DESCRIPTION_TRUSTSTOREPASSWORD_721=Certificate trust store PIN
 INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE_722=Certificate trust store PIN file
 INFO_LISTBACKENDS_TOOL_DESCRIPTION_723=This utility may be used to list the \
@@ -1353,10 +1353,10 @@
 INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA_753=Specifies that the database should \
  be populated with the specified number of sample entries
 INFO_INSTALLDS_HEADER_POPULATE_TYPE_754=Options for populating the database:
-INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY_755=Only create the base entry
-INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY_756=Leave the database empty
-INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF_757=Import data from an LDIF file
-INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE_758=Load \
+INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY_755=1.  Only create the base entry
+INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY_756=2.  Leave the database empty
+INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF_757=3.  Import data from an LDIF file
+INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE_758=4.  Load \
  automatically-generated sample data
 INFO_INSTALLDS_PROMPT_POPULATE_CHOICE_759=Database population selection:
 SEVERE_ERR_INSTALLDS_NO_SUCH_LDIF_FILE_780=ERROR:  The specified LDIF file %s \
@@ -1366,7 +1366,7 @@
 SEVERE_ERR_INSTALLDS_CANNOT_CREATE_TEMPLATE_FILE_782=ERROR:  Cannot create \
  the template file for generating sample data:  %s
 INFO_LDAPPWMOD_DESCRIPTION_KEYSTORE_PIN_783=The PIN needed to access the \
- contents of the keystore
+ contents of the key store
 INFO_LDAPPWMOD_DESCRIPTION_TRUSTSTORE_PIN_784=The PIN needed to access the \
  contents of the trust store
 INFO_LDIFEXPORT_DESCRIPTION_EXCLUDE_OPERATIONAL_785=Exclude operational \
@@ -1548,7 +1548,7 @@
  occurred while attempting to update the trust manager provider DN used for \
  LDAPS communication: %s
 INFO_CONFIGDS_DESCRIPTION_KEYMANAGER_PATH_870=Specifies the path of the \
- keystore to be used by the key manager provider
+ key store to be used by the key manager provider
 INFO_CONFIGDS_DESCRIPTION_CERTNICKNAME_871=Specifies the nickname of the \
  certificate that the connection handler should use when accepting SSL-based \
  connections or performing StartTLS negotiation
@@ -1622,9 +1622,9 @@
  get and set password policy state information
 INFO_PWPSTATE_DESCRIPTION_SASLOPTIONS_1103=SASL bind options
 INFO_PWPSTATE_DESCRIPTION_TRUST_ALL_1104=Trust all server SSL certificates
-INFO_PWPSTATE_DESCRIPTION_KSFILE_1105=Certificate keystore path
-INFO_PWPSTATE_DESCRIPTION_KSPW_1106=Certificate keystore PIN
-INFO_PWPSTATE_DESCRIPTION_KSPWFILE_1107=Certificate keystore PIN file
+INFO_PWPSTATE_DESCRIPTION_KSFILE_1105=Certificate key store path
+INFO_PWPSTATE_DESCRIPTION_KSPW_1106=Certificate key store PIN
+INFO_PWPSTATE_DESCRIPTION_KSPWFILE_1107=Certificate key store PIN file
 INFO_PWPSTATE_DESCRIPTION_TSFILE_1108=Certificate trust store path
 INFO_PWPSTATE_DESCRIPTION_TSPW_1109=Certificate trust store PIN
 INFO_PWPSTATE_DESCRIPTION_TSPWFILE_1110=Certificate trust store PIN file
@@ -1885,9 +1885,9 @@
 INFO_LDAP_CONN_DESCRIPTION_BINDPWFILE_1306=Bind password file
 INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS_1307=SASL bind options
 INFO_LDAP_CONN_DESCRIPTION_TRUST_ALL_1308=Trust all server SSL certificates
-INFO_LDAP_CONN_DESCRIPTION_KSFILE_1309=Certificate keystore path
-INFO_LDAP_CONN_DESCRIPTION_KSPW_1310=Certificate keystore PIN
-INFO_LDAP_CONN_DESCRIPTION_KSPWFILE_1311=Certificate keystore PIN file
+INFO_LDAP_CONN_DESCRIPTION_KSFILE_1309=Certificate key store path
+INFO_LDAP_CONN_DESCRIPTION_KSPW_1310=Certificate key store PIN
+INFO_LDAP_CONN_DESCRIPTION_KSPWFILE_1311=Certificate key store PIN file
 INFO_LDAP_CONN_DESCRIPTION_TSFILE_1312=Certificate trust store path
 INFO_LDAP_CONN_DESCRIPTION_TSPW_1313=Certificate trust store PIN
 INFO_LDAP_CONN_DESCRIPTION_TSPWFILE_1314=Certificate trust store PIN file
@@ -2007,6 +2007,77 @@
  passed to the JVM when running the server
 SEVERE_ERR_CREATERC_JAVA_HOME_DOESNT_EXIST_1378=The directory %s specified \
  as the JAVA_HOME path does not exist or is not a directory
-SEVERE_ERR_UPGRADE_INCOMPATIBLE_ARGS_1379=The argument '%s' is incompatible \
+INFO_INSTALLDS_STATUS_COMMAND_LINE_1379=To see basic server configuration \
+status and configuration you can launch %s
+INFO_INSTALLDS_PROMPT_ENABLE_SSL_1380=Do you want to enable SSL?
+INFO_INSTALLDS_PROMPT_LDAPSPORT_1381=On which port would you like the \
+ Directory Server to accept connections from LDAPS clients?
+INFO_INSTALLDS_ENABLE_STARTTLS_1382=Do you want to enable Start TLS?
+INFO_INSTALLDS_PROMPT_JKS_PATH_1383=Java Key Store (JKS) path:
+INFO_INSTALLDS_PROMPT_PKCS12_PATH_1384=PKCS#12 key Store path:
+INFO_INSTALLDS_PROMPT_KEYSTORE_PASSWORD_1385=Key store PIN:
+INFO_INSTALLDS_PROMPT_CERTNICKNAME_1386=Use nickname %s?
+INFO_INSTALLDS_HEADER_CERT_TYPE_1387=Certificate server options:
+INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED_1388=1.  Generate self-signed \
+ certificate (recommended for testing purposes only)
+INFO_INSTALLDS_CERT_OPTION_JKS_1389=2.  Use an existing certificate located on \
+ a Java Key Store (JKS)
+INFO_INSTALLDS_CERT_OPTION_PKCS12_1390=3.  Use an existing certificate located \
+ on a PKCS#12 key store
+INFO_INSTALLDS_CERT_OPTION_PKCS11_1391=4.  Use an existing certificate on a \
+ PKCS#11 token
+INFO_INSTALLDS_PROMPT_CERT_TYPE_CHOICE_1392=Certificate type selection:
+INFO_INSTALLDS_PROMPT_START_SERVER_1393=Do you want to start the server when \
+ the configuration is completed?
+SEVERE_ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND_1394=The provided certificate \
+ nickname could not be found.  The key store contains the following \
+ certificate nicknames: %s
+SEVERE_ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME_1395=The key store contains the \
+ following certificate nicknames: %s.%nYou have to provide the nickname of the \
+ certificate you want to use
+INFO_INSTALLDS_DESCRIPTION_DO_NOT_START_1396=Do not start the server when the \
+ configuration is completed
+INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS_1397=Enable StartTLS to allow \
+ secure communication with the server using the LDAP port
+INFO_INSTALLDS_DESCRIPTION_LDAPSPORT_1398=Specifies the port on which the \
+ Directory Server should listen for LDAPS communication.  The LDAPS port will \
+ be configured and SSL will be enabled only if this argument is explicitly \
+ specified
+INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED_1399=Specifies to generate a \
+ self-signed certificate that the server should use when accepting SSL-based \
+ connections or performing StartTLS negotiation
+INFO_INSTALLDS_DESCRIPTION_USE_PKCS11_1400=Specifies to use a certificate in a \
+ PKCS#11 token that the server should use when accepting SSL-based \
+ connections or performing StartTLS negotiation
+INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE_1401=Specifies the path of a Java \
+ Key Store (JKS) containing a certificate to be used as the server certificate
+INFO_INSTALLDS_DESCRIPTION_USE_PKCS12_1402=Specifies the path of a PKCS#12 key \
+ store containing the certificate that the server should use when accepting \
+ SSL-based connections or performing StartTLS negotiation
+INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_1403=Certificate key store PIN.  \
+ A PIN is required when you specify to use an existing certificate (JKS, \
+ PKCS#12 or PKCS#11) as server certificate
+INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE_1404=Certificate key store \
+ PIN file.  A PIN is required when you specify to use an existing certificate \
+ (JKS, PKCS#12 or PKCS#11) as server certificate
+INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME_1405=Specifies the nickname of the \
+ certificate that the server should use when accepting SSL-based \
+ connections or performing StartTLS negotiation
+SEVERE_ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED_1406=You have \
+ specified several certificate types to be used.  Only one certificate type \
+ (self-signed, JKS, PKCS#12 or PCKS#11) is allowed
+SEVERE_ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS_1407=You have \
+ chosen to enable SSL or StartTLS.  You must specify which type of certificate \
+ you want the server to use
+SEVERE_ERR_INSTALLDS_NO_KEYSTORE_PASSWORD_1408=You must provide the PIN of the \
+ keystore to retrieve the certificate to be used by the server.  You can use \
+ {%s} or {%s}
+INFO_INSTALLDS_DESCRIPTION_NO_PROMPT_1409=Perform an installation in \
+ non-interactive mode.  If some data in the command is missing the user will \
+ not be prompted and the tool will fail
+SEVERE_ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED_1410=You have specified to use a \
+ certificate as server certificate.  You must enable SSL (using option {%s}) \
+ or Start TLS (using option %s)
+SEVERE_ERR_UPGRADE_INCOMPATIBLE_ARGS_1411=The argument '%s' is incompatible \
  with '%s'
 
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
index d806213..65bfcc9 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/CurrentInstallStatus.java
@@ -95,21 +95,39 @@
       isInstalled = msgs.size() > 0;
       if (canOverwriteCurrentInstall)
       {
-        installationMsg =
-          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG.get();
+        installationMsg = !Utils.isCli()?
+          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG.get() :
+          INFO_INSTALLSTATUS_CANOVERWRITECURRENTINSTALL_MSG_CLI.get();
       }
       else if (isInstalled)
       {
         MessageBuilder buf = new MessageBuilder();
-        buf.append("<ul>");
-        for (Message msg : msgs)
+        if (Utils.isCli())
         {
-          buf.append("\n<li>");
-          buf.append(msg);
-          buf.append("</li>");
+          buf = new MessageBuilder();
+          for (Message msg : msgs)
+          {
+            buf.append(Constants.LINE_SEPARATOR);
+            buf.append("- "+msg);
+          }
+          String cmd = Utils.isWindows() ?
+              Installation.WINDOWS_SETUP_FILE_NAME :
+                Installation.UNIX_SETUP_FILE_NAME;
+          installationMsg =
+            INFO_INSTALLSTATUS_INSTALLED_CLI.get(cmd, buf.toString());
         }
-        buf.append("</ul>");
-        installationMsg = INFO_INSTALLSTATUS_INSTALLED.get( buf.toString() );
+        else
+        {
+          buf.append("<ul>");
+          for (Message msg : msgs)
+          {
+            buf.append("\n<li>");
+            buf.append(msg);
+            buf.append("</li>");
+          }
+          buf.append("</ul>");
+          installationMsg = INFO_INSTALLSTATUS_INSTALLED.get( buf.toString() );
+        }
       }
     }
     if (!isInstalled)
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
index 5514825..5b06e72 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/Installation.java
@@ -139,6 +139,16 @@
   public static final String WINDOWS_SETUP_FILE_NAME = "setup.bat";
 
   /**
+   * The UNIX GUI setup script file name.
+   */
+  public static final String UNIX_SETUP_GUI_FILE_NAME = "setup-gui";
+
+  /**
+   * The Windows GUI setup batch file name.
+   */
+  public static final String WINDOWS_SETUP_GUI_FILE_NAME = "setup-gui.bat";
+
+  /**
    * The UNIX uninstall script file name.
    */
   public static final String UNIX_UNINSTALL_FILE_NAME = "uninstall";
@@ -744,6 +754,23 @@
   }
 
   /**
+   * Gets the status command file appropriate for the current operating
+   * system.
+   * @return File object representing the status command
+   */
+  public File getStatusCommandFile() {
+    File statusPanelCommandFile;
+    if (Utils.isWindows()) {
+      statusPanelCommandFile = new File(getBinariesDirectory(),
+              WINDOWS_STATUSCLI_FILE_NAME);
+    } else {
+      statusPanelCommandFile = new File(getBinariesDirectory(),
+              UNIX_STATUSCLI_FILE_NAME);
+    }
+    return statusPanelCommandFile;
+  }
+
+  /**
    * Gets information about the build that was used to produce the bits
    * for this installation.
    * @return BuildInformation object describing this installation
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
index 1afa23a..2e9dfed 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -29,6 +29,7 @@
 
 import java.util.HashMap;
 import java.util.HashSet;
+import java.util.LinkedList;
 import java.util.Map;
 
 import org.opends.admin.ads.ServerDescriptor;
@@ -63,7 +64,7 @@
   private String globalAdministratorPassword;
 
   private SecurityOptions securityOptions;
-  private int serverJMXPort;
+  private int serverJMXPort = -1;
 
   private boolean startServer;
 
@@ -87,6 +88,10 @@
 
   private boolean forceOnError;
 
+  private String configurationFile;
+
+  private String configurationClass;
+
   /**
    * Creates a user data object with default values.
    */
@@ -96,8 +101,10 @@
     enableWindowsService = false;
     forceOnError = true;
 
+    LinkedList<String> baseDn = new LinkedList<String>();
+    baseDn.add("dc=example,dc=com");
     NewSuffixOptions defaultNewSuffixOptions = new NewSuffixOptions(
-        NewSuffixOptions.Type.CREATE_BASE_ENTRY, "dc=example,dc=com");
+        NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDn);
     setNewSuffixOptions(defaultNewSuffixOptions);
 
     // See what we can propose as port
@@ -655,4 +662,40 @@
     this.remoteWithNoReplicationPort.clear();
     this.remoteWithNoReplicationPort.putAll(remoteWithNoReplicationPort);
   }
+
+  /**
+   * Returns the configuration file to be used.
+   * @return the configuration file to be used.
+   */
+  public String getConfigurationFile()
+  {
+    return configurationFile;
+  }
+
+  /**
+   * Sets the configuration file to be used.
+   * @param configurationFile the configuration file to be used.
+   */
+  public void setConfigurationFile(String configurationFile)
+  {
+    this.configurationFile = configurationFile;
+  }
+
+  /**
+   * Returns the configuration class to be used.
+   * @return the configuration class to be used.
+   */
+  public String getConfigurationClassName()
+  {
+    return configurationClass;
+  }
+
+  /**
+   * Sets the configuration class to be used.
+   * @param configurationClass the configuration class to be used.
+   */
+  public void setConfigurationClassName(String configurationClass)
+  {
+    this.configurationClass = configurationClass;
+  }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
deleted file mode 100644
index 102ecae..0000000
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/InstallLauncher.java
+++ /dev/null
@@ -1,305 +0,0 @@
-/*
- * 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 org.opends.messages.Message;
-import static org.opends.messages.QuickSetupMessages.*;
-import static org.opends.messages.ToolMessages.*;
-import static org.opends.server.tools.ToolConstants.*;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.logging.Logger;
-import java.util.logging.Level;
-
-import org.opends.quicksetup.Launcher;
-import org.opends.quicksetup.CliApplication;
-import org.opends.quicksetup.Installation;
-import org.opends.quicksetup.QuickSetupLog;
-import org.opends.quicksetup.util.Utils;
-import org.opends.server.util.ServerConstants;
-import org.opends.server.util.SetupUtils;
-import org.opends.server.util.args.ArgumentParser;
-import org.opends.server.util.args.BooleanArgument;
-import org.opends.server.util.args.FileBasedArgument;
-import org.opends.server.util.args.IntegerArgument;
-import org.opends.server.util.args.StringArgument;
-
-/**
- * This class is called by the setup command lines to launch the installation of
- * the Directory Server. It just checks the command line arguments and the
- * environment and determines whether the graphical or the command line
- * based setup much be launched.
- */
-public class InstallLauncher extends Launcher {
-
-  /** Prefix for log files. */
-  static public final String LOG_FILE_PREFIX = "opends-setup-";
-
-  /** Suffix for log files. */
-  static public final String LOG_FILE_SUFFIX = ".log";
-
-  static private final Logger LOG =
-          Logger.getLogger(InstallLauncher.class.getName());
-
-  /**
-   * The main method which is called by the setup command lines.
-   *
-   * @param args the arguments passed by the command lines.  In the case
-   * we want to launch the cli setup they are basically the arguments that we
-   * will pass to the org.opends.server.tools.InstallDS class.
-   */
-  public static void main(String[] args) {
-    try {
-      QuickSetupLog.initLogFileHandler(
-              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX));
-    } catch (Throwable t) {
-      System.err.println("Unable to initialize log");
-      t.printStackTrace();
-    }
-    new InstallLauncher(args).launch();
-  }
-
-  private ArgumentParser argParser;
-
-  /**
-   * Creates a launcher.
-   *
-   * @param args the arguments passed by the command lines.
-   */
-  public InstallLauncher(String[] args) {
-    super(args);
-
-    String scriptName;
-    if (Utils.isWindows()) {
-      scriptName = Installation.WINDOWS_SETUP_FILE_NAME;
-    } else {
-      scriptName = Installation.UNIX_SETUP_FILE_NAME;
-    }
-    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
-
-    argParser = new ArgumentParser(getClass().getName(),
-        INFO_SETUP_LAUNCHER_USAGE_DESCRIPTION.get(),
-        false);
-    BooleanArgument   addBaseEntry;
-    BooleanArgument   cliMode;
-    BooleanArgument   showUsage;
-    BooleanArgument   quietInstall;
-    BooleanArgument   skipPortCheck;
-    BooleanArgument   enableWindowsService;
-    FileBasedArgument rootPWFile;
-    IntegerArgument   ldapPort;
-    IntegerArgument   jmxPort;
-    IntegerArgument   sampleData;
-    StringArgument    baseDN;
-    StringArgument    importLDIF;
-    StringArgument    rootDN;
-    StringArgument    rootPWString;
-
-    try
-    {
-      cliMode = new BooleanArgument("cli", 'c', OPTION_LONG_CLI,
-          INFO_INSTALLDS_DESCRIPTION_CLI.get());
-      argParser.addArgument(cliMode);
-
-      quietInstall = new BooleanArgument("quiet",
-          OPTION_SHORT_QUIET,
-          OPTION_LONG_QUIET,
-          INFO_INSTALLDS_DESCRIPTION_SILENT.get());
-      argParser.addArgument(quietInstall);
-
-      baseDN = new StringArgument("basedn", OPTION_SHORT_BASEDN,
-          OPTION_LONG_BASEDN, false, true, true,
-          OPTION_VALUE_BASEDN,
-          "dc=example,dc=com", null,
-          INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
-      argParser.addArgument(baseDN);
-
-      addBaseEntry = new BooleanArgument("addbase", 'a', "addBaseEntry",
-          INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
-      argParser.addArgument(addBaseEntry);
-
-      importLDIF = new StringArgument("importldif", OPTION_SHORT_LDIF_FILE,
-          OPTION_LONG_LDIF_FILE, false,
-          true, true, OPTION_VALUE_LDIF_FILE,
-          null, null,
-          INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
-      argParser.addArgument(importLDIF);
-
-      sampleData = new IntegerArgument("sampledata", 'd', "sampleData", false,
-          false, true, "{numEntries}", 0, null,
-          true, 0, false, 0,
-          INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
-      argParser.addArgument(sampleData);
-
-      ldapPort = new IntegerArgument("ldapport", OPTION_SHORT_PORT,
-          "ldapPort", false, false,
-          true, OPTION_VALUE_PORT, 389,
-          null, true, 1, true, 65535,
-          INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
-      argParser.addArgument(ldapPort);
-
-      jmxPort = new IntegerArgument("jmxport", 'x', "jmxPort", false, false,
-          true, "{jmxPort}",
-          SetupUtils.getDefaultJMXPort(), null, true,
-          1, true, 65535,
-          INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
-      argParser.addArgument(jmxPort);
-
-      skipPortCheck = new BooleanArgument("skipportcheck", 'S', "skipPortCheck",
-          INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
-      argParser.addArgument(skipPortCheck);
-
-      rootDN = new StringArgument("rootdn",OPTION_SHORT_ROOT_USER_DN,
-          OPTION_LONG_ROOT_USER_DN, false, true,
-          true, OPTION_VALUE_ROOT_USER_DN,
-          "cn=Directory Manager",
-          null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
-      argParser.addArgument(rootDN);
-
-      rootPWString = new StringArgument("rootpwstring", OPTION_SHORT_BINDPWD,
-          "rootUserPassword",
-          false, false, true,
-          "{password}", null,
-          null,
-          INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
-      argParser.addArgument(rootPWString);
-
-      rootPWFile = new FileBasedArgument("rootpwfile",
-          OPTION_SHORT_BINDPWD_FILE,
-          "rootUserPasswordFile", false, false,
-          OPTION_VALUE_BINDPWD_FILE,
-          null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
-      argParser.addArgument(rootPWFile);
-
-      enableWindowsService = new BooleanArgument("enablewindowsservice", 'e',
-          "enableWindowsService",
-          INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
-      if (SetupUtils.isWindows())
-      {
-        argParser.addArgument(enableWindowsService);
-      }
-
-      showUsage = new BooleanArgument("help", OPTION_SHORT_HELP,
-          OPTION_LONG_HELP,
-          INFO_INSTALLDS_DESCRIPTION_HELP.get());
-      argParser.addArgument(showUsage);
-      argParser.setUsageArgument(showUsage);
-    }
-    catch (Throwable t)
-    {
-      System.out.println("ERROR: "+t);
-      t.printStackTrace();
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  protected void guiLaunchFailed(String logFileName) {
-    if (logFileName != null)
-    {
-      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED_DETAILS.get(
-              logFileName));
-    }
-    else
-    {
-      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED.get());
-    }
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  public ArgumentParser getArgumentParser() {
-    return this.argParser;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  protected void willLaunchGui() {
-    System.out.println(INFO_SETUP_LAUNCHER_LAUNCHING_GUI.get());
-    System.setProperty("org.opends.quicksetup.Application.class",
-            "org.opends.quicksetup.installer.offline.OfflineInstaller");
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  protected Message getFrameTitle() {
-    return INFO_FRAME_INSTALL_TITLE.get();
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  protected CliApplication createCliApplication() {
-    // Setup currently has no implemented CliApplication
-    // but rather relies on InstallDS from the server
-    // package.  Note that launchCli is overloaded
-    // to run this application instead of the default
-    // behavior in Launcher
-    return null;
-  }
-
-  /**
-   * {@inheritDoc}
-   */
-  @Override
-  protected int launchCli(CliApplication cliApp) {
-    System.setProperty("org.opends.quicksetup.cli", "true");
-
-    if (Utils.isWindows()) {
-      System.setProperty("org.opends.server.scriptName",
-              Installation.WINDOWS_SETUP_FILE_NAME);
-    } else {
-      System.setProperty("org.opends.server.scriptName",
-              Installation.UNIX_SETUP_FILE_NAME);
-    }
-    ArrayList<String> newArgList = new ArrayList<String>();
-    if (args != null) {
-      for (String arg : args) {
-        if (!arg.equalsIgnoreCase("--cli") &&
-                !arg.equalsIgnoreCase("-c")) {
-          newArgList.add(arg);
-        }
-      }
-    }
-    newArgList.add("--configClass");
-    newArgList.add("org.opends.server.extensions.ConfigFileHandler");
-    newArgList.add("--configFile");
-    Installation installation = Installation.getLocal();
-    newArgList.add(Utils.getPath(installation.getCurrentConfigurationFile()));
-
-    String[] newArgs = new String[newArgList.size()];
-    newArgList.toArray(newArgs);
-    LOG.log(Level.INFO, "Launching 'installMain' with args " +
-            Utils.listToString(newArgList, " "));
-    return org.opends.server.tools.InstallDS.installMain(newArgs);
-  }
-}
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
index 8e358a0..913b6ba 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/Installer.java
@@ -156,7 +156,7 @@
   /**
    * An static String that contains the class name of ConfigFileHandler.
    */
-  protected static final String CONFIG_CLASS_NAME =
+  protected static final String DEFAULT_CONFIG_CLASS_NAME =
       "org.opends.server.extensions.ConfigFileHandler";
 
   /** Alias of a self-signed certificate. */
@@ -180,8 +180,8 @@
       if (!QuickSetupLog.isInitialized())
         QuickSetupLog.initLogFileHandler(
                 File.createTempFile(
-                        InstallLauncher.LOG_FILE_PREFIX,
-                        InstallLauncher.LOG_FILE_SUFFIX));
+                    SetupGuiLauncher.LOG_FILE_PREFIX,
+                    SetupGuiLauncher.LOG_FILE_SUFFIX));
     } catch (IOException e) {
       System.err.println("Failed to initialize log");
     }
@@ -708,29 +708,34 @@
   }
 
   /**
-   * Creates a template file based in the contents of the UserData object.
-   * This template file is used to generate automatically data.  To generate
+   * Creates the template files based in the contents of the UserData object.
+   * These templates files are used to generate automatically data.  To generate
    * the template file the code will basically take into account the value of
    * the base dn and the number of entries to be generated.
    *
-   * @return the file object pointing to the create template file.
+   * @return a list of file objects pointing to the create template files.
    * @throws ApplicationException if an error occurs.
    */
-  protected File createTemplateFile() throws ApplicationException {
+  private LinkedList<File> createTemplateFiles() throws ApplicationException {
+    LinkedList<File> files = new LinkedList<File>();
     try
     {
-      return SetupUtils.createTemplateFile(
-                  getUserData().getNewSuffixOptions().getBaseDn(),
-                  getUserData().getNewSuffixOptions().getNumberEntries());
+      int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
+
+      for (String baseDn : getUserData().getNewSuffixOptions().getBaseDns())
+      {
+        files.add(SetupUtils.createTemplateFile(baseDn, nEntries));
+      }
     }
     catch (IOException ioe)
     {
       Message failedMsg = getThrowableMsg(
-              INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
+          INFO_ERROR_CREATING_TEMP_FILE.get(), ioe);
       throw new ApplicationException(
           ReturnCode.FILE_SYSTEM_ACCESS_ERROR,
           failedMsg, ioe);
     }
+    return files;
   }
 
   /**
@@ -743,10 +748,10 @@
 
     ArrayList<String> argList = new ArrayList<String>();
     argList.add("-C");
-    argList.add(CONFIG_CLASS_NAME);
+    argList.add(getConfigurationClassName());
 
     argList.add("-c");
-    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
+    argList.add(getConfigurationFile());
     argList.add("-p");
     argList.add(String.valueOf(getUserData().getServerPort()));
 
@@ -811,10 +816,12 @@
     }
 
     // For the moment do not enable JMX
-    /*
-    argList.add("-x");
-    argList.add(String.valueOf(getUserData().getServerJMXPort()));
-     */
+    if (getUserData().getServerJMXPort() > 0)
+    {
+      argList.add("-x");
+      argList.add(String.valueOf(getUserData().getServerJMXPort()));
+    }
+
     argList.add("-D");
     argList.add(getUserData().getDirectoryManagerDn());
 
@@ -823,8 +830,13 @@
 
     if (createNotReplicatedSuffix())
     {
-      argList.add("-b");
-      argList.add(getUserData().getNewSuffixOptions().getBaseDn());
+      LinkedList<String> baseDns =
+        getUserData().getNewSuffixOptions().getBaseDns();
+      for (String baseDn : baseDns)
+      {
+        argList.add("-b");
+        argList.add(baseDn);
+      }
     }
     else
     {
@@ -976,26 +988,44 @@
    * @throws ApplicationException if something goes wrong.
    */
   private void createBaseEntry() throws ApplicationException {
-    notifyListeners(getFormattedWithPoints(
-        INFO_PROGRESS_CREATING_BASE_ENTRY.get(
-                getUserData().getNewSuffixOptions().getBaseDn())));
+    LinkedList<String> baseDns =
+      getUserData().getNewSuffixOptions().getBaseDns();
+    if (baseDns.size() == 1)
+    {
+      notifyListeners(getFormattedWithPoints(
+        INFO_PROGRESS_CREATING_BASE_ENTRY.get(baseDns.getFirst())));
+    }
+    else
+    {
+      notifyListeners(getFormattedWithPoints(
+          INFO_PROGRESS_CREATING_BASE_ENTRIES.get()));
+    }
 
     InstallerHelper helper = new InstallerHelper();
-    String baseDn = getUserData().getNewSuffixOptions().getBaseDn();
-    File tempFile = helper.createBaseEntryTempFile(baseDn);
 
+    LinkedList<File> ldifFiles = new LinkedList<File>();
+
+    for (String baseDn : baseDns)
+    {
+      ldifFiles.add(helper.createBaseEntryTempFile(baseDn));
+    }
     ArrayList<String> argList = new ArrayList<String>();
     argList.add("-C");
-    argList.add(CONFIG_CLASS_NAME);
+    argList.add(getConfigurationClassName());
 
     argList.add("-f");
-    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
+    argList.add(getConfigurationFile());
 
     argList.add("-n");
     argList.add(getBackendName());
 
-    argList.add("-l");
-    argList.add(tempFile.getAbsolutePath());
+    for (File f : ldifFiles)
+    {
+      argList.add("-l");
+      argList.add(f.getAbsolutePath());
+    }
+
+    argList.add("-F");
 
     argList.add("-q");
 
@@ -1034,23 +1064,36 @@
    * @throws ApplicationException if something goes wrong.
    */
   private void importLDIF() throws ApplicationException {
+    LinkedList<String> ldifPaths =
+      getUserData().getNewSuffixOptions().getLDIFPaths();
     MessageBuilder mb = new MessageBuilder();
-    mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIF.get(
-            getUserData().getNewSuffixOptions().getLDIFPath())));
+    if (ldifPaths.size() > 1)
+    {
+      mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIFS.get(
+            getStringFromCollection(ldifPaths, ", "))));
+    }
+    else
+    {
+      mb.append(getFormattedProgress(INFO_PROGRESS_IMPORTING_LDIF.get(
+          ldifPaths.getFirst())));
+    }
     mb.append(getLineBreak());
     notifyListeners(mb.toMessage());
 
     ArrayList<String> argList = new ArrayList<String>();
     argList.add("-C");
-    argList.add(CONFIG_CLASS_NAME);
+    argList.add(getConfigurationClassName());
 
     argList.add("-f");
-    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
+    argList.add(getConfigurationFile());
     argList.add("-n");
     argList.add(getBackendName());
-    argList.add("-l");
-    argList.add(getUserData().getNewSuffixOptions().getLDIFPath());
-
+    for (String ldifPath : ldifPaths)
+    {
+      argList.add("-l");
+      argList.add(ldifPath);
+    }
+    argList.add("-F");
     String[] args = new String[argList.size()];
     argList.toArray(args);
 
@@ -1079,7 +1122,7 @@
    * @throws ApplicationException if something goes wrong.
    */
   private void importAutomaticallyGenerated() throws ApplicationException {
-    File templatePath = createTemplateFile();
+    LinkedList<File> templatePaths = createTemplateFiles();
     int nEntries = getUserData().getNewSuffixOptions().getNumberEntries();
     MessageBuilder mb = new MessageBuilder();
     mb.append(getFormattedProgress(
@@ -1088,40 +1131,46 @@
     mb.append(getLineBreak());
     notifyListeners(mb.toMessage());
 
-    ArrayList<String> argList = new ArrayList<String>();
-    argList.add("-C");
-    argList.add(CONFIG_CLASS_NAME);
-
-    argList.add("-f");
-    argList.add(getPath(getInstallation().getCurrentConfigurationFile()));
-    argList.add("-n");
-    argList.add(getBackendName());
-    argList.add("-t");
-    argList.add(templatePath.getAbsolutePath());
-    argList.add("-s"); // seed
-    argList.add("0");
-
-    String[] args = new String[argList.size()];
-    argList.toArray(args);
-
-    try
+    for (File templatePath : templatePaths)
     {
-      InstallerHelper helper = new InstallerHelper();
-      int result = helper.invokeImportLDIF(args);
+      ArrayList<String> argList = new ArrayList<String>();
+      argList.add("-C");
+      argList.add(getConfigurationClassName());
 
-      if (result != 0)
+      argList.add("-f");
+      argList.add(getConfigurationFile());
+      argList.add("-n");
+      argList.add(getBackendName());
+      argList.add("-t");
+      argList.add(templatePath.getAbsolutePath());
+      argList.add("-s"); // seed
+      argList.add("0");
+
+      // append: each file contains data for each base DN.
+      argList.add("-a");
+
+      String[] args = new String[argList.size()];
+      argList.toArray(args);
+
+      try
+      {
+        InstallerHelper helper = new InstallerHelper();
+        int result = helper.invokeImportLDIF(args);
+
+        if (result != 0)
+        {
+          throw new ApplicationException(
+              ReturnCode.CONFIGURATION_ERROR,
+              INFO_ERROR_IMPORT_LDIF_TOOL_RETURN_CODE.get(
+                  Integer.toString(result)), null);
+        }
+      } catch (Throwable t)
       {
         throw new ApplicationException(
             ReturnCode.CONFIGURATION_ERROR,
-            INFO_ERROR_IMPORT_LDIF_TOOL_RETURN_CODE.get(
-                    Integer.toString(result)), null);
+            getThrowableMsg(INFO_ERROR_IMPORT_AUTOMATICALLY_GENERATED.get(
+                listToString(argList, " "), t.getLocalizedMessage()), t), t);
       }
-    } catch (Throwable t)
-    {
-      throw new ApplicationException(
-          ReturnCode.CONFIGURATION_ERROR,
-          getThrowableMsg(INFO_ERROR_IMPORT_AUTOMATICALLY_GENERATED.get(
-                  listToString(argList, " "), t.getLocalizedMessage()), t), t);
     }
   }
 
@@ -1313,12 +1362,16 @@
     if (getUserData().getReplicationOptions().getType()
             == DataReplicationOptions.Type.FIRST_IN_TOPOLOGY)
     {
-      String dn = getUserData().getNewSuffixOptions().getBaseDn();
-      dns.add(dn);
+      LinkedList<String> baseDns =
+        getUserData().getNewSuffixOptions().getBaseDns();
+      dns.addAll(baseDns);
       HashSet<String> h = new HashSet<String>();
       h.add(getLocalReplicationServer());
       adsServers.add(getLocalReplicationServer());
-      replicationServers.put(dn, h);
+      for (String dn : baseDns)
+      {
+        replicationServers.put(dn, h);
+      }
     }
     else
     {
@@ -3235,7 +3288,12 @@
         qs.displayFieldInvalid(FieldName.LDIF_PATH, true);
       } else if (validBaseDn)
       {
-        dataOptions = new NewSuffixOptions(type, baseDn, ldifPath);
+        LinkedList<String> baseDns = new LinkedList<String>();
+        baseDns.add(baseDn);
+        LinkedList<String> ldifPaths = new LinkedList<String>();
+        ldifPaths.add(ldifPath);
+
+        dataOptions = new NewSuffixOptions(type, baseDns, ldifPaths);
         qs.displayFieldInvalid(FieldName.LDIF_PATH, false);
       }
       break;
@@ -3277,7 +3335,10 @@
       if (startErrors == errorMsgs.size() && validBaseDn)
       {
         // No validation errors
-        dataOptions = new NewSuffixOptions(type, baseDn, new Integer(nEntries));
+        LinkedList<String> baseDns = new LinkedList<String>();
+        baseDns.add(baseDn);
+        dataOptions = new NewSuffixOptions(type, baseDns,
+            new Integer(nEntries));
       }
       break;
 
@@ -3286,7 +3347,9 @@
       qs.displayFieldInvalid(FieldName.NUMBER_ENTRIES, false);
       if (validBaseDn)
       {
-        dataOptions = new NewSuffixOptions(type, baseDn);
+        LinkedList<String> baseDns = new LinkedList<String>();
+        baseDns.add(baseDn);
+        dataOptions = new NewSuffixOptions(type, baseDns);
       }
     }
 
@@ -3901,6 +3964,38 @@
     }
   }
 
+  /**
+   * Returns the configuration file path to be used when invoking the
+   * command-lines.
+   * @return the configuration file path to be used when invoking the
+   * command-lines.
+   */
+  private String getConfigurationFile()
+  {
+    String file = getUserData().getConfigurationFile();
+    if (file == null)
+    {
+      file = getPath(getInstallation().getCurrentConfigurationFile());
+    }
+    return file;
+  }
+
+  /**
+   * Returns the configuration class name to be used when invoking the
+   * command-lines.
+   * @return the configuration class name to be used when invoking the
+   * command-lines.
+   */
+  private String getConfigurationClassName()
+  {
+    String className = getUserData().getConfigurationClassName();
+    if (className == null)
+    {
+      className = DEFAULT_CONFIG_CLASS_NAME;
+    }
+    return className;
+  }
+
   private String getLocalReplicationServer()
   {
     return getUserData().getHostName()+":"+
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
index 56e52e0..714223c 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/NewSuffixOptions.java
@@ -28,6 +28,8 @@
 
 package org.opends.quicksetup.installer;
 
+import java.util.LinkedList;
+
 
 /**
  * This class is used to provide a data model for the Data Options panel of the
@@ -67,9 +69,9 @@
 
   private Type type = Type.NOTHING;
 
-  private String baseDn;
+  private LinkedList<String> baseDns = new LinkedList<String>();
 
-  private String ldifPath;
+  private LinkedList<String> ldifPaths = new LinkedList<String>();
 
   private int numberEntries = 2000;
 
@@ -91,12 +93,19 @@
   public NewSuffixOptions(Type type, Object... args)
   {
     this.type = type;
-    baseDn = (String) args[0];
-
+    LinkedList<?> v = (LinkedList<?>)args[0];
+    for (Object o : v)
+    {
+      baseDns.add((String)o);
+    }
     switch (type)
     {
     case IMPORT_FROM_LDIF_FILE:
-      ldifPath = (String) args[1];
+      v = (LinkedList<?>)args[1];
+      for (Object o : v)
+      {
+        ldifPaths.add((String)o);
+      }
       break;
 
     case IMPORT_AUTOMATICALLY_GENERATED_DATA:
@@ -120,9 +129,10 @@
    * 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()
+  public LinkedList<String> getLDIFPaths()
   {
-    return ldifPath;
+    LinkedList<String> copy = new LinkedList<String>(ldifPaths);
+    return copy;
   }
 
   /**
@@ -140,8 +150,9 @@
    *
    * @return the base DN of the suffix that will be created in the server.
    */
-  public String getBaseDn()
+  public LinkedList<String> getBaseDns()
   {
-    return baseDn;
+    LinkedList<String> copy = new LinkedList<String>(baseDns);
+    return copy;
   }
 }
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java
new file mode 100644
index 0000000..4240331
--- /dev/null
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/SetupGuiLauncher.java
@@ -0,0 +1,220 @@
+/*
+ * 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;
+
+import static org.opends.messages.QuickSetupMessages.*;
+import static org.opends.messages.ToolMessages.INFO_DESCRIPTION_SHOWUSAGE;
+import static org.opends.server.tools.ToolConstants.OPTION_LONG_HELP;
+import static org.opends.server.tools.ToolConstants.OPTION_SHORT_HELP;
+
+import java.io.File;
+import java.util.logging.Logger;
+
+import org.opends.quicksetup.ReturnCode;
+import org.opends.quicksetup.CliApplication;
+import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.Launcher;
+import org.opends.quicksetup.QuickSetupLog;
+import org.opends.quicksetup.installer.offline.OfflineInstaller;
+import org.opends.quicksetup.util.Utils;
+import org.opends.messages.Message;
+import org.opends.messages.ToolMessages;
+import org.opends.server.util.ServerConstants;
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.ArgumentParser;
+import org.opends.server.util.args.BooleanArgument;
+
+/**
+ * This class is called by the setup GUI command line to launch the setup
+ * of the Directory Server. It just checks the command line arguments and the
+ * environment and determines whether the graphical or the command line
+ * based setup much be launched.
+ */
+public class SetupGuiLauncher extends Launcher {
+
+  /** Prefix for log files. */
+  static public final String LOG_FILE_PREFIX = "opends-setup-gui-";
+
+  /** Suffix for log files. */
+  static public final String LOG_FILE_SUFFIX = ".log";
+
+  static private final Logger LOG =
+          Logger.getLogger(SetupGuiLauncher.class.getName());
+
+  /**
+   * The main method which is called by the setup GUI command lines.
+   *
+   * @param args the arguments passed by the command lines.  In the case
+   * we want to launch the cli setup they are basically the arguments that we
+   * will pass to the org.opends.server.tools.InstallDS class.
+   */
+  public static void main(String[] args) {
+    try {
+      QuickSetupLog.initLogFileHandler(
+              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX),
+              "org.opends.quicksetup.installer");
+
+    } catch (Throwable t) {
+      System.err.println("Unable to initialize log");
+      t.printStackTrace();
+    }
+    new SetupGuiLauncher(args).launch();
+  }
+
+  private ArgumentParser argParser;
+
+  /**
+   * Creates a launcher.
+   *
+   * @param args the arguments passed by the command lines.
+   */
+  public SetupGuiLauncher(String[] args) {
+    super(args);
+    String scriptName;
+    if (Utils.isWindows()) {
+      scriptName = Installation.WINDOWS_SETUP_GUI_FILE_NAME;
+    } else {
+      scriptName = Installation.UNIX_SETUP_GUI_FILE_NAME;
+    }
+    System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName);
+    initializeParser();
+  }
+
+  /**
+   * Initialize the contents of the argument parser.
+   */
+  protected void initializeParser()
+  {
+    argParser = new ArgumentParser(getClass().getName(),
+        INFO_SETUP_LAUNCHER_USAGE_DESCRIPTION.get(),
+        false);
+    try
+    {
+      BooleanArgument showUsageArg = new BooleanArgument("showUsage",
+          OPTION_SHORT_HELP,
+          OPTION_LONG_HELP, INFO_DESCRIPTION_SHOWUSAGE.get());
+      argParser.addArgument(showUsageArg);
+      argParser.setUsageArgument(showUsageArg);
+      argParser.parseArguments(args);
+    }
+    catch (ArgumentException ae)
+    {
+      System.err.println(org.opends.server.util.StaticUtils.wrapText(
+          ToolMessages.ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()),
+          Utils.getCommandLineMaxLineWidth()));
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void launch() {
+    if (shouldPrintVersion())
+    {
+      if (!argParser.usageOrVersionDisplayed())
+      {
+        printVersion();
+      }
+      System.exit(ReturnCode.PRINT_VERSION.getReturnCode());
+    }
+    else if (shouldPrintUsage()) {
+      if (!argParser.usageOrVersionDisplayed())
+      {
+        printUsage(false);
+      }
+      System.exit(ReturnCode.SUCCESSFUL.getReturnCode());
+    } else {
+      willLaunchGui();
+      int exitCode = launchGui(args);
+      if (exitCode != 0) {
+        File logFile = QuickSetupLog.getLogFile();
+        if (logFile != null)
+        {
+          guiLaunchFailed(logFile.toString());
+        }
+        else
+        {
+          guiLaunchFailed(null);
+        }
+        System.exit(exitCode);
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected boolean isCli() {
+    return false;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public ArgumentParser getArgumentParser() {
+    return this.argParser;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected void guiLaunchFailed(String logFileName) {
+    if (logFileName != null)
+    {
+      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED_DETAILS.get(
+              logFileName));
+    }
+    else
+    {
+      System.err.println(INFO_SETUP_LAUNCHER_GUI_LAUNCHED_FAILED.get());
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected void willLaunchGui() {
+    System.out.println(INFO_SETUP_LAUNCHER_LAUNCHING_GUI.get());
+    System.setProperty("org.opends.quicksetup.Application.class",
+            OfflineInstaller.class.getName());
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected Message getFrameTitle() {
+    return INFO_FRAME_INSTALL_TITLE.get();
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  protected CliApplication createCliApplication() {
+    return null;
+  }
+}
\ No newline at end of file
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
index 470b427..342920b 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/offline/OfflineInstaller.java
@@ -74,6 +74,8 @@
   private HashMap<InstallProgressStep, Message> hmSummary =
       new HashMap<InstallProgressStep, Message>();
 
+  private ApplicationException runError;
+
   private static final Logger LOG =
     Logger.getLogger(OfflineInstaller.class.getName());
   /**
@@ -82,12 +84,13 @@
    */
   public void run()
   {
-    initMaps();
+    runError = null;
     PrintStream origErr = System.err;
     PrintStream origOut = System.out;
-
     try
     {
+      initMaps();
+
       System.setErr(getApplicationErrorStream());
       System.setOut(getApplicationOutputStream());
 
@@ -181,6 +184,7 @@
         notifyListeners(html);
         LOG.log(Level.SEVERE, "Error installing.", ex);
       }
+      runError = ex;
     }
     catch (Throwable t)
     {
@@ -203,9 +207,13 @@
       Message msg = getFormattedError(ex, true);
       notifyListeners(msg);
       LOG.log(Level.SEVERE, "Error installing.", t);
+      runError = ex;
     }
-    System.setErr(origErr);
-    System.setOut(origOut);
+    finally
+    {
+      System.setErr(origErr);
+      System.setOut(origOut);
+    }
   }
 
   /**
@@ -225,6 +233,14 @@
   }
 
   /**
+   * {@inheritDoc}
+   */
+  public ApplicationException getRunError()
+  {
+    return runError;
+  }
+
+  /**
    * Called when the user elects to cancel this operation.
    */
   protected void uninstall() {
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
index 4325187..45c4293 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/DataOptionsPanel.java
@@ -38,6 +38,7 @@
 import java.awt.event.FocusEvent;
 import java.awt.event.FocusListener;
 import java.util.HashMap;
+import java.util.LinkedList;
 
 import javax.swing.Box;
 import javax.swing.ButtonGroup;
@@ -348,7 +349,16 @@
     switch (fieldName)
     {
     case DIRECTORY_BASE_DN:
-      value = defaultUserData.getNewSuffixOptions().getBaseDn();
+      LinkedList<String> defaults =
+        defaultUserData.getNewSuffixOptions().getBaseDns();
+      if ((defaults != null) && !defaults.isEmpty())
+      {
+        value = defaults.getFirst();
+      }
+      else
+      {
+        value = null;
+      }
       break;
 
     case DATA_OPTIONS:
@@ -356,7 +366,16 @@
       break;
 
     case LDIF_PATH:
-      value = defaultUserData.getNewSuffixOptions().getLDIFPath();
+      defaults =
+        defaultUserData.getNewSuffixOptions().getLDIFPaths();
+      if ((defaults != null) && !defaults.isEmpty())
+      {
+        value = defaults.getFirst();
+      }
+      else
+      {
+        value = null;
+      }
       break;
 
     case NUMBER_ENTRIES:
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
index d4cfe80..7df31a8 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/installer/ui/InstallReviewPanel.java
@@ -294,10 +294,12 @@
       Message arg2;
 
       NewSuffixOptions options = userInstallData.getNewSuffixOptions();
+
       switch (options.getType())
       {
       case CREATE_BASE_ENTRY:
-        arg2 = INFO_REVIEW_CREATE_BASE_ENTRY_LABEL.get(options.getBaseDn());
+        arg2 = INFO_REVIEW_CREATE_BASE_ENTRY_LABEL.get(
+            options.getBaseDns().getFirst());
 
         break;
 
@@ -306,7 +308,7 @@
         break;
 
       case IMPORT_FROM_LDIF_FILE:
-        arg2 = INFO_REVIEW_IMPORT_LDIF.get(options.getLDIFPath());
+        arg2 = INFO_REVIEW_IMPORT_LDIF.get(options.getLDIFPaths().getFirst());
         break;
 
       case IMPORT_AUTOMATICALLY_GENERATED_DATA:
@@ -315,10 +317,11 @@
         break;
 
       default:
-        throw new IllegalArgumentException("Unknow type: " + options.getType());
+        throw new IllegalArgumentException("Unknown type: "+options.getType());
       }
 
-      msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDn(), arg2);
+      msg = INFO_REVIEW_CREATE_SUFFIX.get(options.getBaseDns().getFirst(),
+          arg2);
     }
     else
     {
@@ -334,9 +337,9 @@
       }
       msg = INFO_REVIEW_REPLICATE_SUFFIX.get(buf.toString());
     }
-
     return msg.toString();
   }
+
    /**
     * Returns the String representing the replication port configuration.
     * @param userInstallData the DataOptions of the user.
diff --git a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
index 670e82d..0cc093c 100644
--- a/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
+++ b/opendj-sdk/opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -1209,7 +1209,8 @@
     else if (name.endsWith(".sh"))
     {
       perm = "755";
-    } else if (name.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
+    } else if (name.endsWith(Installation.UNIX_SETUP_GUI_FILE_NAME) ||
+            name.endsWith(Installation.UNIX_SETUP_FILE_NAME) ||
             name.endsWith(Installation.UNIX_UNINSTALL_GUI_FILE_NAME) ||
             name.endsWith(Installation.UNIX_UNINSTALL_FILE_NAME) ||
             name.endsWith(Installation.UNIX_UPGRADE_FILE_NAME))
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java b/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java
index b9eb537..123d86a 100644
--- a/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDS.java
@@ -24,1153 +24,1627 @@
  *
  *      Portions Copyright 2006-2007 Sun Microsystems, Inc.
  */
+
 package org.opends.server.tools;
-import org.opends.messages.Message;
 
+import static org.opends.messages.AdminToolMessages.*;
+import static org.opends.messages.QuickSetupMessages.*;
+import static org.opends.messages.ToolMessages.*;
 
-
-import java.io.ByteArrayOutputStream;
 import java.io.File;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.io.PrintStream;
+import java.security.KeyStoreException;
+import java.util.Collection;
 import java.util.LinkedList;
-import java.util.Set;
+import java.util.logging.Logger;
 
+import org.opends.messages.Message;
+import org.opends.quicksetup.ApplicationException;
+import org.opends.quicksetup.CliApplicationHelper;
+import org.opends.quicksetup.Constants;
+import org.opends.quicksetup.CurrentInstallStatus;
+import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.QuickSetupLog;
+import org.opends.quicksetup.SecurityOptions;
+import org.opends.quicksetup.UserData;
+import org.opends.quicksetup.UserDataException;
+import org.opends.quicksetup.event.ProgressUpdateEvent;
+import org.opends.quicksetup.event.ProgressUpdateListener;
+import org.opends.quicksetup.installer.NewSuffixOptions;
+import org.opends.quicksetup.installer.offline.OfflineInstaller;
+import org.opends.quicksetup.util.PlainTextProgressMessageFormatter;
+import org.opends.quicksetup.util.Utils;
 import org.opends.server.core.DirectoryServer;
-import org.opends.server.extensions.ConfigFileHandler;
 import org.opends.server.types.DN;
-import org.opends.server.types.ExistingFileBehavior;
-import org.opends.server.types.LDIFExportConfig;
+import org.opends.server.types.InitializationException;
+import org.opends.server.types.NullOutputStream;
+import org.opends.server.util.CertificateManager;
 import org.opends.server.util.SetupUtils;
-import org.opends.server.util.LDIFWriter;
-import org.opends.server.util.PasswordReader;
 import org.opends.server.util.args.ArgumentException;
-import org.opends.server.util.args.ArgumentParser;
-import org.opends.server.util.args.BooleanArgument;
-import org.opends.server.util.args.FileBasedArgument;
 import org.opends.server.util.args.IntegerArgument;
 import org.opends.server.util.args.StringArgument;
 
-import static org.opends.messages.ToolMessages.*;
-import static org.opends.server.util.ServerConstants.*;
-import static org.opends.server.util.StaticUtils.*;
-import static org.opends.server.tools.ToolConstants.*;
-
-
-
 /**
  * This class provides a very simple mechanism for installing the OpenDS
  * Directory Service.  It performs the following tasks:
  * <UL>
+ *   <LI>Checks if the server is already installed and running</LI>
  *   <LI>Ask the user what base DN should be used for the data</LI>
  *   <LI>Ask the user whether to create the base entry, or to import LDIF</LI>
  *   <LI>Ask the user for the LDAP port and make sure it's available</LI>
  *   <LI>Ask the user for the default root DN and password</LI>
+ *   <LI>Ask the user to enable SSL or not and for the type of certificate that
+ *   the server must use</LI>
  *   <LI>Ask the user if they want to start the server when done installing</LI>
  * </UL>
  */
-public class InstallDS
+public class InstallDS  extends CliApplicationHelper
 {
-  /**
-   * The fully-qualified name of this class.
-   */
-  private static final String CLASS_NAME = "org.opends.server.tools.InstallDS";
+  private PlainTextProgressMessageFormatter formatter =
+    new PlainTextProgressMessageFormatter();
+  /** Prefix for log files. */
+  static public final String LOG_FILE_PREFIX = "opends-setup-";
 
-
+  /** Suffix for log files. */
+  static public final String LOG_FILE_SUFFIX = ".log";
 
   /**
-   * Indicates whether we think we're running on a Windows system.
-   */
-  private static final boolean isWindows = SetupUtils.isWindows();
-
-
-
-  /**
-   * The version string for the server.
-   */
-  private static String versionString;
-
-
-
-  /**
-   * The name of the program used to launch this installation process.
-   */
-  private static String programName;
-
-
-
-  /**
-   * The value that indicates that only the base entry should be created.
-   */
-  private static final int POPULATE_TYPE_BASE_ONLY = 1;
-
-
-
-  /**
-   * The value that indicates that the database should be left empty.
-   */
-  private static final int POPULATE_TYPE_LEAVE_EMPTY = 2;
-
-
-
-  /**
-   * The value that indicates that data should be imported from an LDIF file.
-   */
-  private static final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
-
-
-
-  /**
-   * The value that indicates that the database should be populated with sample
-   * data.
-   */
-  private static final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
-
-
-
-  /**
-   * Invokes the <CODE>installMain</CODE> method with the provided arguments.
+   * The enumeration containing the different return codes that the command-line
+   * can have.
    *
-   * @param  args  The command-line arguments to use for this program.
    */
-  public static void main(String[] args)
+  enum ErrorReturnCode
   {
-    int exitCode = installMain(args);
-    if (exitCode != 0)
+    /**
+     * Successful setup.
+     */
+    SUCCESSFUL(0),
+    /**
+     * We did no have an error but the setup was not executed (displayed
+     * version or usage).
+     */
+    SUCCESSFUL_NOP(0),
+    /**
+     * Unexpected error (potential bug).
+     */
+    ERROR_UNEXPECTED(1),
+    /**
+     * Cannot parse arguments or data provided by user is not valid.
+     */
+    ERROR_USER_DATA(2),
+    /**
+     * Error server already installed.
+     */
+    ERROR_SERVER_ALREADY_INSTALLED(3),
+    /**
+     * Error initializing server.
+     */
+    ERROR_INITIALIZING_SERVER(4);
+
+    private int returnCode;
+    private ErrorReturnCode(int returnCode)
     {
-      System.exit(filterExitCode(exitCode));
+      this.returnCode = returnCode;
     }
+
+    /**
+     * Get the corresponding return code value.
+     *
+     * @return The corresponding return code value.
+     */
+    public int getReturnCode()
+    {
+      return returnCode;
+    }
+  };
+
+  /**
+   * The Logger.
+   */
+  static private final Logger LOG = Logger.getLogger(InstallDS.class.getName());
+
+  // The argument parser
+  private InstallDSArgumentParser argParser;
+
+  /**
+   * Constructor for the SetupCli object.
+   *
+   * @param out the print stream to use for standard output.
+   * @param err the print stream to use for standard error.
+   * @param in the input stream to use for standard input.
+   */
+  public InstallDS(PrintStream out, PrintStream err, InputStream in)
+  {
+    super(out, err, in);
   }
 
+  /**
+   * The main method for the setup CLI tool.
+   *
+   * @param args the command-line arguments provided to this program.
+   */
 
+  public static void main(String[] args)
+  {
+    int retCode = mainCLI(args, true, System.out, System.err, System.in);
+
+    System.exit(retCode);
+  }
 
   /**
-   * Prompts the user for the necessary information, installs the OpenDS
-   * software in the appropriate location, and gives it the desired
-   * configuration.
+   * Parses the provided command-line arguments and uses that information to
+   * run the setup tool.
    *
-   * @param  args  The command-line arguments to use for this program.
+   * @param args the command-line arguments provided to this program.
    *
-   * @return  A value of zero if the installation process was successful, or a
-   *          nonzero value if a problem occurred.
+   * @return The error code.
    */
-  public static int installMain(String[] args)
-  {
-    // Construct the product version string and the setup filename.
-    versionString = DirectoryServer.getVersionString();
 
-    if (isWindows)
+  public static int mainCLI(String[] args)
+  {
+    return mainCLI(args, true, System.out, System.err, System.in);
+  }
+
+  /**
+   * Parses the provided command-line arguments and uses that information to
+   * run the setup tool.
+   *
+   * @param  args              The command-line arguments provided to this
+   *                           program.
+   * @param initializeServer   Indicates whether to initialize the server.
+   * @param  outStream         The output stream to use for standard output, or
+   *                           <CODE>null</CODE> if standard output is not
+   *                           needed.
+   * @param  errStream         The output stream to use for standard error, or
+   *                           <CODE>null</CODE> if standard error is not
+   *                           needed.
+   * @param  inStream          The input stream to use for standard input.
+   * @return The error code.
+   */
+
+  public static int mainCLI(String[] args, boolean initializeServer,
+      OutputStream outStream, OutputStream errStream, InputStream inStream)
+  {
+    PrintStream out;
+    if (outStream == null)
     {
-      programName = "setup.bat";
+      out = NullOutputStream.printStream();
     }
     else
     {
-      programName = "setup";
+      out = new PrintStream(outStream);
     }
 
+    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
 
-    // Create and initialize the argument parser for this program.
-    Message toolDescription = INFO_INSTALLDS_TOOL_DESCRIPTION.get();
-    ArgumentParser argParser = new ArgumentParser(CLASS_NAME, toolDescription,
-                                                  false);
-    BooleanArgument   addBaseEntry;
-    BooleanArgument   cliMode;
-    BooleanArgument   testOnly;
-    BooleanArgument   showUsage;
-    BooleanArgument   quietInstall;
-    BooleanArgument   skipPortCheck;
-    BooleanArgument   enableWindowsService;
-    FileBasedArgument rootPWFile;
-    IntegerArgument   ldapPort;
-    IntegerArgument   jmxPort;
-    IntegerArgument   sampleData;
-    StringArgument    baseDN;
-    StringArgument    configClass;
-    StringArgument    configFile;
-    StringArgument    importLDIF;
-    StringArgument    progName;
-    StringArgument    rootDN;
-    StringArgument    rootPWString;
+    PrintStream err;
+    if (errStream == null)
+    {
+      err = NullOutputStream.printStream();
+    }
+    else
+    {
+      err = new PrintStream(errStream);
+    }
 
+    try {
+      QuickSetupLog.initLogFileHandler(
+              File.createTempFile(LOG_FILE_PREFIX, LOG_FILE_SUFFIX),
+              "org.opends.server.tools");
+      QuickSetupLog.disableConsoleLogging();
+    } catch (Throwable t) {
+      System.err.println("Unable to initialize log");
+      t.printStackTrace();
+    }
+
+    InstallDS install = new InstallDS(out, err, inStream);
+
+    return install.execute(args, initializeServer);
+  }
+
+  /**
+   * Parses the provided command-line arguments and uses that information to
+   * run the setup CLI.
+   *
+   * @param args the command-line arguments provided to this program.
+   * @param  initializeServer  Indicates whether to initialize the server.
+   *
+   * @return the return code (SUCCESSFUL, USER_DATA_ERROR or BUG.
+   */
+  public int execute(String[] args, boolean initializeServer)
+  {
+    argParser = new InstallDSArgumentParser(InstallDS.class.getName());
     try
     {
-      testOnly = new BooleanArgument(
-              "test", 't', "testOnly",
-              INFO_INSTALLDS_DESCRIPTION_TESTONLY.get());
-      testOnly.setHidden(true);
-      argParser.addArgument(testOnly);
-
-      progName = new StringArgument(
-              "progname", 'P', "programName", false,
-              false, true, "{programName}", programName,
-              null, INFO_INSTALLDS_DESCRIPTION_PROGNAME.get());
-      progName.setHidden(true);
-      argParser.addArgument(progName);
-
-      configFile = new StringArgument(
-              "configfile", 'c', "configFile", false,
-              false, true, "{configFile}", null, null,
-              INFO_DESCRIPTION_CONFIG_FILE.get());
-      configFile.setHidden(true);
-      argParser.addArgument(configFile);
-
-      configClass = new StringArgument(
-              "configclass", OPTION_SHORT_CONFIG_CLASS,
-              OPTION_LONG_CONFIG_CLASS, false,
-              false, true, OPTION_VALUE_CONFIG_CLASS,
-              ConfigFileHandler.class.getName(), null,
-              INFO_DESCRIPTION_CONFIG_CLASS.get());
-      configClass.setHidden(true);
-      argParser.addArgument(configClass);
-
-      // NOTE:  This argument isn't actually used for anything, but it provides
-      // consistency with the setup script, which does take a --cli option.
-      cliMode = new BooleanArgument(
-              "cli", null, OPTION_LONG_CLI,
-              INFO_INSTALLDS_DESCRIPTION_CLI.get());
-      argParser.addArgument(cliMode);
-
-      quietInstall = new BooleanArgument(
-              "quiet", OPTION_SHORT_QUIET,
-              OPTION_LONG_QUIET,
-              INFO_INSTALLDS_DESCRIPTION_SILENT.get());
-      argParser.addArgument(quietInstall);
-
-      baseDN = new StringArgument(
-              "basedn", OPTION_SHORT_BASEDN,
-              OPTION_LONG_BASEDN, false, true, true,
-              OPTION_VALUE_BASEDN,
-              "dc=example,dc=com", null,
-              INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
-      argParser.addArgument(baseDN);
-
-      addBaseEntry = new BooleanArgument(
-              "addbase", 'a', "addBaseEntry",
-              INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
-      argParser.addArgument(addBaseEntry);
-
-      importLDIF = new StringArgument(
-              "importldif", OPTION_SHORT_LDIF_FILE,
-              OPTION_LONG_LDIF_FILE, false,
-              true, true, OPTION_VALUE_LDIF_FILE,
-              null, null,
-              INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
-      argParser.addArgument(importLDIF);
-
-      sampleData = new IntegerArgument(
-              "sampledata", 'd', "sampleData", false,
-              false, true, "{numEntries}", 0, null,
-              true, 0, false, 0,
-              INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
-      argParser.addArgument(sampleData);
-
-      ldapPort = new IntegerArgument(
-              "ldapport", OPTION_SHORT_PORT,
-              "ldapPort", false, false,
-              true, OPTION_VALUE_PORT, 389,
-              null, true, 1, true, 65535,
-              INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
-      argParser.addArgument(ldapPort);
-
-      jmxPort = new IntegerArgument(
-              "jmxport", 'x', "jmxPort", false, false,
-              true, "{jmxPort}",
-              SetupUtils.getDefaultJMXPort(), null, true,
-              1, true, 65535,
-              INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
-      argParser.addArgument(jmxPort);
-
-      skipPortCheck = new BooleanArgument(
-              "skipportcheck", 'S', "skipPortCheck",
-              INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
-      argParser.addArgument(skipPortCheck);
-
-      rootDN = new StringArgument(
-              "rootdn",OPTION_SHORT_ROOT_USER_DN,
-              OPTION_LONG_ROOT_USER_DN, false, true,
-              true, OPTION_VALUE_ROOT_USER_DN,
-              "cn=Directory Manager",
-              null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
-      argParser.addArgument(rootDN);
-
-      rootPWString = new StringArgument(
-              "rootpwstring", OPTION_SHORT_BINDPWD,
-              "rootUserPassword",
-              false, false, true,
-              "{password}", null,
-              null,
-              INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
-      argParser.addArgument(rootPWString);
-
-      rootPWFile = new FileBasedArgument(
-              "rootpwfile",
-              OPTION_SHORT_BINDPWD_FILE,
-              "rootUserPasswordFile", false, false,
-              OPTION_VALUE_BINDPWD_FILE,
-              null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
-      argParser.addArgument(rootPWFile);
-
-      enableWindowsService = new BooleanArgument(
-              "enablewindowsservice", 'e',
-              "enableWindowsService",
-              INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
-      if (SetupUtils.isWindows())
-      {
-        argParser.addArgument(enableWindowsService);
-      }
-
-      showUsage = new BooleanArgument("help", OPTION_SHORT_HELP,
-                                      OPTION_LONG_HELP,
-                                      INFO_INSTALLDS_DESCRIPTION_HELP.get());
-      argParser.addArgument(showUsage);
-      argParser.setUsageArgument(showUsage);
+      argParser.initializeArguments();
     }
     catch (ArgumentException ae)
     {
-      System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
-      System.err.println(argParser.getUsage());
-      return 1;
+      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
+      printErrorMessage(message);
+      return ErrorReturnCode.ERROR_UNEXPECTED.getReturnCode();
     }
 
-
-    // Parse all of the configuration arguments.
+    // Validate user provided data
     try
     {
       argParser.parseArguments(args);
     }
     catch (ArgumentException ae)
     {
-      System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
-      System.err.println(argParser.getUsage());
-      return 1;
+      Message message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
+      printErrorMessage(message);
+      printLineBreak();
+      printErrorMessage(argParser.getUsage());
+
+      return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
     }
 
-
-    // If either the showUsage or testOnly or version arguments were provided,
+    //  If either the showUsage or testOnly or version arguments were provided,
     // then we're done.
-    if (argParser.usageOrVersionDisplayed() || testOnly.isPresent())
+    if (argParser.usageOrVersionDisplayed() ||
+        argParser.testOnlyArg.isPresent())
     {
-      return 0;
+      return ErrorReturnCode.SUCCESSFUL_NOP.getReturnCode();
     }
 
     try
     {
-      Set<Integer> ports = new HashSet<Integer>();
-      if (ldapPort.isPresent())
-      {
-        ports.add(ldapPort.getIntValue());
-      }
-      if (jmxPort.isPresent())
-      {
-        if (ports.contains(jmxPort.getIntValue()))
-        {
-          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
-                  String.valueOf(jmxPort.getIntValue()));
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-          System.err.println(argParser.getUsage());
-          return 1;
-        }
-        else
-        {
-          ports.add(jmxPort.getIntValue());
-        }
-      }
+      checkInstallStatus();
     }
-    catch (ArgumentException ae)
+    catch (InitializationException ie)
     {
-      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
+      printErrorMessage(ie.getMessageObject());
+      return ErrorReturnCode.ERROR_SERVER_ALREADY_INSTALLED.getReturnCode();
     }
 
-    // Make sure that the user didn't provide conflicting arguments.
-    if (addBaseEntry.isPresent())
+    if (initializeServer)
     {
-      if (importLDIF.isPresent())
+      try
       {
-        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
-                addBaseEntry.getLongIdentifier(),
-                importLDIF.getLongIdentifier());
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
+        initializeDirectoryServer(argParser.configFileArg.getValue(),
+            argParser.configClassArg.getValue());
       }
-      else if (sampleData.isPresent())
+      catch (InitializationException ie)
       {
-        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
-                addBaseEntry.getLongIdentifier(),
-                sampleData.getLongIdentifier());
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
+        printErrorMessage(ie.getMessageObject());
+        return ErrorReturnCode.ERROR_INITIALIZING_SERVER.getReturnCode();
       }
     }
-    else if (importLDIF.isPresent() && sampleData.isPresent())
-    {
-      Message message = ERR_TOOL_CONFLICTING_ARGS.get(
-              importLDIF.getLongIdentifier(),
-              sampleData.getLongIdentifier());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
-    }
 
+    UserData uData = new UserData();
 
-    // Make sure the path to the configuration file was given.
-    String configFileName;
-    if (configFile.isPresent())
+    if (isInteractive())
     {
-      configFileName = configFile.getValue();
+      promptIfRequired(uData);
     }
     else
     {
-      Message message = ERR_INSTALLDS_NO_CONFIG_FILE.get(
-              configFile.getLongIdentifier());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
+      try
+      {
+        initializeUserDataWithParser(uData);
+      }
+      catch (UserDataException ude)
+      {
+        printErrorMessage(ude.getMessageObject());
+        return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
+      }
     }
 
+    OfflineInstaller installer = new OfflineInstaller();
+    installer.setUserData(uData);
+    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
+    installer.setProgressMessageFormatter(formatter);
+    installer.addProgressUpdateListener(
+        new ProgressUpdateListener() {
+          public void progressUpdate(ProgressUpdateEvent ev) {
+            if (ev.getNewLogs() != null)
+            {
+              printProgressMessage(ev.getNewLogs());
+            }
+          }
+        });
+    printProgressLineBreak();
 
-    // Get the configuration handler class name.
-    String configClassName = configClass.getValue();
+    installer.run();
 
+    ApplicationException ue = installer.getRunError();
 
-    // If this isn't a quiet install, then print the version string.
-    if (! quietInstall.isPresent())
+    String cmd;
+    // Use this instead a call to Installation to avoid to launch a new JVM
+    // just to retrieve a path.
+    String root = Utils.getInstallPathFromClasspath();
+    if (SetupUtils.isWindows())
     {
-      System.out.println(versionString);
-      System.out.println();
-
-      Message message = INFO_INSTALLDS_INITIALIZING.get();
-      System.out.println(wrapText(message, MAX_LINE_WIDTH));
+      String binDir = Utils.getPath(root,
+          Installation.WINDOWS_BINARIES_PATH_RELATIVE);
+      cmd = Utils.getPath(binDir, Installation.WINDOWS_STATUSCLI_FILE_NAME);
     }
+    else
+    {
+      String binDir = Utils.getPath(root,
+          Installation.UNIX_BINARIES_PATH_RELATIVE);
+      cmd = Utils.getPath(binDir, Installation.UNIX_STATUSCLI_FILE_NAME);
+    }
+    printProgressLineBreak();
+    printProgressLineBreak();
+    printProgressMessage(INFO_INSTALLDS_STATUS_COMMAND_LINE.get(cmd));
+    printProgressLineBreak();
 
+    if (ue != null)
+    {
+      return ue.getType().getReturnCode();
+    }
+    else
+    {
+      return ErrorReturnCode.SUCCESSFUL.getReturnCode();
+    }
+  }
+
+  /**
+   * Checks if the server is installed or not.
+   * @throws InitializationException if the server is already installed and
+   * configured or if the user did not accept to overwrite the existing
+   * databases.
+   */
+  private void checkInstallStatus() throws InitializationException
+  {
+    CurrentInstallStatus installStatus = new CurrentInstallStatus();
+    if (installStatus.canOverwriteCurrentInstall())
+    {
+      if (isInteractive())
+      {
+        printLine(installStatus.getInstallationMsg(), true);
+        if (!confirm(INFO_CLI_DO_YOU_WANT_TO_CONTINUE.get()))
+        {
+          throw new InitializationException(Message.EMPTY, null);
+        }
+      }
+      else
+      {
+        printWarningMessage(installStatus.getInstallationMsg());
+      }
+    }
+    else if (installStatus.isInstalled())
+    {
+      throw new InitializationException(installStatus.getInstallationMsg(),
+          null);
+    }
+  }
+
+  /**
+   * Initialize the directory server to be able to perform the operations
+   * required during the installation.
+   * @param configFile the configuration file to be used to initialize the
+   * server.
+   * @param configClass the configuration class to be used to initialize the
+   * server.
+   * @throws InitializationException if there was an error during
+   * initialization.
+   */
+  private void initializeDirectoryServer(String configFile, String configClass)
+  throws InitializationException
+  {
+    printProgressLineBreak();
+    printProgressMessage(DirectoryServer.getVersionString());
+    printProgressLineBreak();
+    printProgressMessage(INFO_INSTALLDS_INITIALIZING.get());
+    printProgressLineBreak();
 
     // Perform a base-level initialization that will be required to get
     // minimal functionality like DN parsing to work.
     DirectoryServer directoryServer = DirectoryServer.getInstance();
-    directoryServer.bootstrapClient();
+    DirectoryServer.bootstrapClient();
 
     try
     {
-      directoryServer.initializeJMX();
+      DirectoryServer.initializeJMX();
     }
-    catch (Exception e)
+    catch (Throwable t)
     {
       Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_JMX.get(
-              String.valueOf(configFile.getValue()),
-              e.getMessage());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
+              String.valueOf(configFile), t.getMessage());
+      throw new InitializationException(message, t);
     }
 
     try
     {
-      directoryServer.initializeConfiguration(configClass.getValue(),
-                                              configFile.getValue());
+      directoryServer.initializeConfiguration(configClass, configFile);
     }
-    catch (Exception e)
+    catch (Throwable t)
     {
       Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_CONFIG.get(
-              String.valueOf(configFile.getValue()),
-                                  e.getMessage());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
+              configFile, t.getMessage());
+      throw new InitializationException(message, t);
     }
 
     try
     {
       directoryServer.initializeSchema();
     }
-    catch (Exception e)
+    catch (Throwable t)
     {
       Message message = ERR_INSTALLDS_CANNOT_INITIALIZE_SCHEMA.get(
-              String.valueOf(configFile.getValue()),
-                                  e.getMessage());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
+              configFile, t.getMessage());
+      throw new InitializationException(message, t);
     }
+  }
 
+  /**
+   * {@inheritDoc}
+   */
+  protected boolean isQuiet()
+  {
+    return argParser.quietArg.isPresent();
+  }
 
-    // Determine the LDAP port number.
-    int ldapPortNumber;
-    if (quietInstall.isPresent() || ldapPort.isPresent())
+  /**
+   * {@inheritDoc}
+   */
+  protected boolean isInteractive()
+  {
+    return !argParser.noPromptArg.isPresent();
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line.  It assumes that it is being called in no
+   * prompt mode.
+   * @param uData the UserData object.
+   * @throws UserDataException if something went wrong checking the data.
+   */
+  private void initializeUserDataWithParser(UserData uData)
+  throws UserDataException
+  {
+    LinkedList<Message> errorMessages = new LinkedList<Message>();
+    uData.setConfigurationClassName(argParser.configClassArg.getValue());
+    uData.setConfigurationFile(argParser.configFileArg.getValue());
+    uData.setQuiet(isQuiet());
+    //  Check the validity of the directory manager DNs
+    String dmDN = argParser.directoryManagerDNArg.getValue();
+
+    try
+    {
+      DN.decode(dmDN);
+    }
+    catch (Exception e)
+    {
+      Message message =
+        ERR_INSTALLDS_CANNOT_PARSE_DN.get(dmDN, e.getMessage());
+      errorMessages.add(message);
+    }
+    uData.setDirectoryManagerDn(dmDN);
+
+    uData.setDirectoryManagerPwd(argParser.getDirectoryManagerPassword());
+
+    // Check the validity of the base DNs
+    LinkedList<String> baseDNs = argParser.baseDNArg.getValues();
+    if (baseDNs.isEmpty())
+    {
+      baseDNs.add(argParser.baseDNArg.getDefaultValue());
+    }
+    for (String baseDN : baseDNs)
     {
       try
       {
-        ldapPortNumber = ldapPort.getIntValue();
-
-        if (! skipPortCheck.isPresent())
-        {
-          // Check if the port can be used.
-          if (!SetupUtils.canUseAsPort(ldapPortNumber))
-          {
-            Message message;
-            if (SetupUtils.isPriviledgedPort(ldapPortNumber))
-            {
-
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
-                      ldapPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            else
-            {
-
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            return 1;
-          }
-        }
-      }
-      catch (ArgumentException ae)
-      {
-        System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else
-    {
-      while (true)
-      {
-        Message message = INFO_INSTALLDS_PROMPT_LDAPPORT.get();
-        ldapPortNumber = promptForInteger(message, 389, 1, 65535);
-
-        if (skipPortCheck.isPresent())
-        {
-            break;
-        }
-        else
-        {
-          // Check if the port can be used.
-          if (SetupUtils.canUseAsPort(ldapPortNumber))
-          {
-              break;
-          }
-          else
-          {
-            if (SetupUtils.isPriviledgedPort(ldapPortNumber))
-            {
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
-                      ldapPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            else
-            {
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-          }
-        }
-      }
-    }
-
-//  Determine the JMX port number.
-    int jmxPortNumber;
-    if (quietInstall.isPresent() || jmxPort.isPresent())
-    {
-      try
-      {
-        jmxPortNumber = jmxPort.getIntValue();
-
-        if (! skipPortCheck.isPresent())
-        {
-          // Check if the port can be used.
-          if (!SetupUtils.canUseAsPort(jmxPortNumber))
-          {
-            Message message;
-            if (SetupUtils.isPriviledgedPort(jmxPortNumber))
-            {
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
-                      jmxPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            else
-            {
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            return 1;
-          }
-        }
-      }
-      catch (ArgumentException ae)
-      {
-        System.err.println(wrapText(ae.getMessage(), MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else
-    {
-      /* Do not ask for the JMX port if the user did not provide it.*/
-      jmxPortNumber = -1;
-      /*
-      while (true)
-      {
-        Message message = INFO_INSTALLDS_PROMPT_JMXPORT.get();
-        jmxPortNumber = promptForInteger(message,
-            SetupUtils.getDefaultJMXPort(), 1, 65535);
-
-        if (skipPortCheck.isPresent())
-        {
-            break;
-        }
-        else
-        {
-          // Check if the port can be used.
-          if (SetupUtils.canUseAsPort(jmxPortNumber))
-          {
-              break;
-          }
-          else
-          {
-            if (SetupUtils.isPriviledgedPort(jmxPortNumber))
-            {
-
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
-                        jmxPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-            else
-            {
-              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPortNumber);
-              System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            }
-          }
-        }
-      }
-      */
-    }
-
-
-    // Determine the initial root user DN.
-    LinkedList<DN> rootDNs;
-    if (rootDN.isPresent())
-    {
-      rootDNs = new LinkedList<DN>();
-      for (String s : rootDN.getValues())
-      {
-        try
-        {
-          rootDNs.add(DN.decode(s));
-        }
-        catch (Exception e)
-        {
-          Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
-                  s, e.getMessage());
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-          return 1;
-        }
-      }
-    }
-    else if (quietInstall.isPresent())
-    {
-      rootDNs = new LinkedList<DN>();
-      try
-      {
-        rootDNs.add(DN.decode(rootDN.getDefaultValue()));
-      }
-      catch (Exception e)
-      {
-        Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
-                rootDN.getDefaultValue(),
-                                    e.getMessage());
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else
-    {
-      Message message = INFO_INSTALLDS_PROMPT_ROOT_DN.get();
-      rootDNs = new LinkedList<DN>();
-      rootDNs.add(promptForDN(message, rootDN.getDefaultValue()));
-    }
-
-
-    // Determine the initial root user password.
-    String rootPassword;
-    if (rootPWString.isPresent())
-    {
-      rootPassword = rootPWString.getValue();
-
-      if (rootPWFile.isPresent())
-      {
-        Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
-                rootPWString.getLongIdentifier(),
-                rootPWFile.getLongIdentifier());
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else if (rootPWFile.isPresent())
-    {
-      rootPassword = rootPWFile.getValue();
-    }
-    else if (quietInstall.isPresent())
-    {
-      Message message = ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
-              rootPWString.getLongIdentifier(),
-              rootPWFile.getLongIdentifier());
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      return 1;
-    }
-    else
-    {
-      Message initialPrompt = INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get();
-
-      Message confirmPrompt = INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get();
-
-      rootPassword =
-           new String(promptForPassword(initialPrompt, confirmPrompt));
-    }
-
-
-    // Determine the directory base DN.
-    LinkedList<DN> baseDNs;
-    if (baseDN.isPresent())
-    {
-      baseDNs = new LinkedList<DN>();
-      for (String s : baseDN.getValues())
-      {
-        try
-        {
-          baseDNs.add(DN.decode(s));
-        }
-        catch (Exception e)
-        {
-
-          Message message = ERR_INSTALLDS_CANNOT_PARSE_DN.get(
-                  s, e.getMessage());
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-          return 1;
-        }
-      }
-    }
-    else if (quietInstall.isPresent())
-    {
-      try
-      {
-        baseDNs = new LinkedList<DN>();
-        baseDNs.add(DN.decode(baseDN.getDefaultValue()));
+        DN.decode(baseDN);
       }
       catch (Exception e)
       {
         Message message =
-                ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN.getDefaultValue(),
-                                    e.getMessage());
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
+          ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN, e.getMessage());
+        errorMessages.add(message);
       }
     }
-    else
-    {
-      Message message = INFO_INSTALLDS_PROMPT_BASEDN.get();
 
-      baseDNs = new LinkedList<DN>();
-      baseDNs.add(promptForDN(message, baseDN.getDefaultValue()));
-    }
-
-
-    // Determine how to populate the database.
-    int                populateType = POPULATE_TYPE_LEAVE_EMPTY;
-    int                numUsers     = -1;
-    LinkedList<String> ldifFiles    = null;
-    if (addBaseEntry.isPresent())
+    try
     {
-      populateType = POPULATE_TYPE_BASE_ONLY;
-    }
-    else if (importLDIF.isPresent())
-    {
-      ldifFiles    = importLDIF.getValues();
-      populateType = POPULATE_TYPE_IMPORT_FROM_LDIF;
-    }
-    else if (sampleData.isPresent())
-    {
-      try
+      int ldapPort = argParser.ldapPortArg.getIntValue();
+      uData.setServerPort(ldapPort);
+      if (!argParser.skipPortCheckArg.isPresent())
       {
-        numUsers     = sampleData.getIntValue();
-        populateType = POPULATE_TYPE_GENERATE_SAMPLE_DATA;
-      }
-      catch (Exception e)
-      {
-        // This should never happen.
-        e.printStackTrace();
-        return 1;
-      }
-    }
-    else if (quietInstall.isPresent())
-    {
-      populateType = POPULATE_TYPE_LEAVE_EMPTY;
-    }
-    else
-    {
-      System.out.println(wrapText(
-              INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(),
-              MAX_LINE_WIDTH));
-
-      System.out.println(wrapText("1.  " +
-              INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(),
-              MAX_LINE_WIDTH));
-
-      System.out.println(wrapText("2.  " +
-              INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(),
-              MAX_LINE_WIDTH));
-
-      System.out.println(wrapText("3.  " +
-              INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(),
-              MAX_LINE_WIDTH));
-
-      System.out.println(wrapText("4.  " +
-              INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(),
-              MAX_LINE_WIDTH));
-
-      populateType = promptForInteger(
-              INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(), 1, 1, 4);
-      System.out.println();
-
-      if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
-      {
-        ldifFiles = new LinkedList<String>();
-        while (true)
+        // Check if the port can be used.
+        if (!SetupUtils.canUseAsPort(ldapPort))
         {
-          Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
-          String path    = promptForString(message, "");
-          if (new File(path).exists())
+          Message message;
+          if (SetupUtils.isPriviledgedPort(ldapPort))
           {
-            ldifFiles.add(path);
-            System.out.println();
-            break;
+            message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+                ldapPort);
           }
           else
           {
-
-            message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
-            System.err.println(wrapText(message, MAX_LINE_WIDTH));
-            System.err.println();
+            message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapPort);
+          }
+          errorMessages.add(message);
+        }
+      }
+      if (argParser.jmxPortArg.isPresent())
+      {
+        int jmxPort = argParser.jmxPortArg.getIntValue();
+        uData.setServerPort(jmxPort);
+        //   Check if the port can be used.
+        if (!argParser.skipPortCheckArg.isPresent())
+        {
+          if (!SetupUtils.canUseAsPort(jmxPort))
+          {
+            Message message;
+            if (SetupUtils.isPriviledgedPort(jmxPort))
+            {
+              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+                  jmxPort);
+            }
+            else
+            {
+              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(jmxPort);
+            }
+            errorMessages.add(message);
           }
         }
       }
+    }
+    catch (ArgumentException ae)
+    {
+      errorMessages.add(ae.getMessageObject());
+    }
+
+
+
+    NewSuffixOptions dataOptions;
+    if (argParser.importLDIFArg.isPresent())
+    {
+      // Check that the files exist
+      LinkedList<String> nonExistingFiles = new LinkedList<String>();
+      for (String file : argParser.importLDIFArg.getValues())
+      {
+        if (!Utils.fileExists(file))
+        {
+          nonExistingFiles.add(file);
+        }
+      }
+      if (nonExistingFiles.size() > 0)
+      {
+        errorMessages.add(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
+            Utils.getStringFromCollection(nonExistingFiles, ", ")));
+      }
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE, baseDNs,
+          argParser.importLDIFArg.getValues());
+    }
+    else if (argParser.addBaseEntryArg.isPresent())
+    {
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
+    }
+    else if (argParser.sampleDataArg.isPresent())
+    {
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA, baseDNs,
+          new Integer(argParser.sampleDataArg.getValue()));
+    }
+    else
+    {
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
+    }
+    uData.setNewSuffixOptions(dataOptions);
+
+    // Check that the security data provided is valid.
+    String certNickname = argParser.certNicknameArg.getValue();
+    String pwd = argParser.getKeyStorePassword();
+    boolean enableSSL = argParser.ldapsPortArg.isPresent();
+    boolean enableStartTLS = argParser.enableStartTLSArg.isPresent();
+    int ldapsPort = -1;
+
+    try
+    {
+      ldapsPort = enableSSL ? argParser.ldapsPortArg.getIntValue() : -1;
+    }
+    catch (ArgumentException ae)
+    {
+      errorMessages.add(ae.getMessageObject());
+    }
+    if (enableSSL)
+    {
+      if (!argParser.skipPortCheckArg.isPresent())
+      {
+        if (!SetupUtils.canUseAsPort(ldapsPort))
+        {
+          if (SetupUtils.isPriviledgedPort(ldapsPort))
+          {
+            errorMessages.add(
+                ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(ldapsPort));
+          }
+          else
+          {
+            errorMessages.add(ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(ldapsPort));
+          }
+        }
+      }
+    }
+    SecurityOptions securityOptions;
+    LinkedList<String> keystoreAliases = new LinkedList<String>();
+    if (argParser.generateSelfSignedCertificateArg.isPresent())
+    {
+      securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+          enableSSL, enableStartTLS, ldapsPort);
+    }
+    else if (argParser.useJavaKeyStoreArg.isPresent())
+    {
+      String path = argParser.useJavaKeyStoreArg.getValue();
+      checkCertificateInKeystore(SecurityOptions.CertificateType.JKS, path, pwd,
+          certNickname, errorMessages, keystoreAliases);
+      securityOptions = SecurityOptions.createJKSCertificateOptions(
+          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+    }
+    else if (argParser.usePkcs12Arg.isPresent())
+    {
+      String path = argParser.usePkcs12Arg.getValue();
+      checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS12, path,
+          pwd, certNickname, errorMessages, keystoreAliases);
+      securityOptions = SecurityOptions.createPKCS12CertificateOptions(
+          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+    }
+    else if (argParser.usePkcs11Arg.isPresent())
+    {
+      checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS11, null,
+          pwd, certNickname, errorMessages, keystoreAliases);
+      securityOptions = SecurityOptions.createPKCS11CertificateOptions(
+          pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+    }
+    else
+    {
+      securityOptions = SecurityOptions.createNoCertificateOptions();
+    }
+    uData.setSecurityOptions(securityOptions);
+
+    uData.setEnableWindowsService(
+        argParser.enableWindowsServiceArg.isPresent());
+    uData.setStartServer(!argParser.doNotStartArg.isPresent());
+
+
+    if (errorMessages.size() > 0)
+    {
+      throw new UserDataException(null,
+          Utils.getMessageFromCollection(errorMessages,
+              formatter.getLineBreak().toString()));
+    }
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line. If the user did not provide explicitly some
+   * data or if the provided data is not valid, it prompts the user to provide
+   * it.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequired(UserData uData)
+  {
+    uData.setConfigurationClassName(argParser.configClassArg.getValue());
+    uData.setConfigurationFile(argParser.configFileArg.getValue());
+    uData.setQuiet(isQuiet());
+
+    promptIfRequiredForDirectoryManager(uData);
+    promptIfRequiredForPortData(uData);
+    promptIfRequiredForImportData(uData);
+    promptIfRequiredForSecurityData(uData);
+    promptIfRequiredForWindowsService(uData);
+    promptIfRequiredForStartServer(uData);
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the Directory Manager parameters.
+   * If the user did not provide explicitly some data or if the provided data is
+   * not valid, it prompts the user to provide it.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequiredForDirectoryManager(UserData uData)
+  {
+    LinkedList<String> dns = promptIfRequiredForDNs(
+        argParser.directoryManagerDNArg, INFO_INSTALLDS_PROMPT_ROOT_DN.get(),
+        true);
+    uData.setDirectoryManagerDn(dns.getFirst());
+
+    String pwd = argParser.getDirectoryManagerPassword();
+    while (pwd == null)
+    {
+      printLineBreak();
+      String pwd1 = null;
+      // Prompt for password and confirm.
+      while (pwd1 == null)
+      {
+        pwd1 = promptForPassword(INFO_INSTALLDS_PROMPT_ROOT_PASSWORD.get());
+        if ("".equals(pwd1))
+        {
+          pwd1 = null;
+          printLineBreak();
+          printErrorMessage(INFO_EMPTY_PWD.get());
+        }
+      }
+      String pwd2 =
+        promptForPassword(INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get());
+
+      if (pwd1.equals(pwd2))
+      {
+        pwd = pwd1;
+      }
+      else
+      {
+        printLineBreak();
+        printErrorMessage(ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get());
+      }
+    }
+    uData.setDirectoryManagerPwd(pwd);
+  }
+
+  /**
+   * This method returns a list of DNs.  It checks that the provided list of
+   * actually contain some values.  If no valid values are found it prompts
+   * the user to provide a valid DN.
+   * @param arg the Argument that the user provided to specify the DNs.
+   * @param promptMsg the prompt message to be displayed.
+   * @param includeLineBreak whether to include a line break before the first
+   * prompt or not.
+   * @return a list of valid DNs.
+   */
+  private LinkedList<String> promptIfRequiredForDNs(StringArgument arg,
+      Message promptMsg, boolean includeLineBreak)
+  {
+    LinkedList<String> dns = new LinkedList<String>();
+
+    boolean usedProvided = false;
+    boolean firstPrompt = true;
+    while (dns.isEmpty())
+    {
+      boolean prompted = false;
+      if (usedProvided || !arg.isPresent())
+      {
+        if (firstPrompt && includeLineBreak)
+        {
+          printLineBreak();
+        }
+        String dn = promptForString(promptMsg, arg.getDefaultValue());
+        firstPrompt = false;
+        dns.add(dn);
+        prompted = true;
+      }
+      else
+      {
+        dns.addAll(arg.getValues());
+      }
+      LinkedList<String> toRemove = new LinkedList<String>();
+      for (String dn : dns)
+      {
+        try
+        {
+          DN.decode(dn);
+        }
+        catch (Exception e)
+        {
+          toRemove.add(dn);
+          Message message = prompted ? ERR_INSTALLDS_INVALID_DN_RESPONSE.get() :
+            ERR_INSTALLDS_CANNOT_PARSE_DN.get(dn, e.getMessage());
+          printErrorMessage(message);
+        }
+      }
+      if (toRemove.size() > 0)
+      {
+        printLineBreak();
+      }
+      dns.removeAll(toRemove);
+    }
+    return dns;
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the LDAP and JMX port parameters.
+   * If the user did not provide explicitly some data or if the provided data is
+   * not valid, it prompts the user to provide it.
+   * Note: this method does not update nor check the LDAPS port.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequiredForPortData(UserData uData)
+  {
+    LinkedList<Integer> usedPorts = new LinkedList<Integer>();
+    //  Determine the LDAP port number.
+    int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
+        INFO_INSTALLDS_PROMPT_LDAPPORT.get(), usedPorts, true);
+    uData.setServerPort(ldapPort);
+    usedPorts.add(ldapPort);
+    if (argParser.jmxPortArg.isPresent())
+    {
+      int jmxPort = promptIfRequiredForPortData(argParser.jmxPortArg,
+          INFO_INSTALLDS_PROMPT_JMXPORT.get(), usedPorts, true);
+      uData.setServerJMXPort(jmxPort);
+    }
+    else
+    {
+      uData.setServerJMXPort(-1);
+    }
+  }
+
+  /**
+   * This method returns a valid port value.  It checks that the provided
+   * argument contains a valid port. If a valid port is not found it prompts
+   * the user to provide a valid port.
+   * @param arg the Argument that the user provided to specify the port.
+   * @param promptMsg the prompt message to be displayed.
+   * @param usedPorts the list of ports the user provided before for other
+   * connection handlers.
+   * @param includeLineBreak whether to include a line break before the first
+   * prompt or not.
+   * @return a valid port number.
+   */
+  private int promptIfRequiredForPortData(IntegerArgument portArg,
+      Message promptMsg, Collection<Integer> usedPorts,
+      boolean includeLineBreak)
+  {
+    int portNumber = -1;
+    boolean usedProvided = false;
+    boolean firstPrompt = true;
+    while (portNumber == -1)
+    {
+      try
+      {
+        boolean prompted = false;
+        if (usedProvided || !portArg.isPresent())
+        {
+          int defaultValue = -1;
+          if (portArg.getDefaultValue() != null)
+          {
+            defaultValue = Integer.parseInt(portArg.getDefaultValue());
+          }
+          if (firstPrompt && includeLineBreak)
+          {
+            printLineBreak();
+          }
+          portNumber = promptForPort(promptMsg, defaultValue);
+          prompted = true;
+          firstPrompt = false;
+        }
+        else
+        {
+          portNumber = portArg.getIntValue();
+          usedProvided = true;
+        }
+
+        if (!argParser.skipPortCheckArg.isPresent())
+        {
+          // Check if the port can be used.
+          if (!SetupUtils.canUseAsPort(portNumber))
+          {
+            Message message;
+            if (SetupUtils.isPriviledgedPort(portNumber))
+            {
+              if (prompted || includeLineBreak)
+              {
+                printLineBreak();
+              }
+              message = ERR_INSTALLDS_CANNOT_BIND_TO_PRIVILEGED_PORT.get(
+                  portNumber);
+              printErrorMessage(message);
+              portNumber = -1;
+            }
+            else
+            {
+              if (prompted || includeLineBreak)
+              {
+                printLineBreak();
+              }
+              message = ERR_INSTALLDS_CANNOT_BIND_TO_PORT.get(portNumber);
+              printErrorMessage(message);
+              printLineBreak();
+              portNumber = -1;
+            }
+          }
+        }
+        if (portNumber != -1)
+        {
+          if (usedPorts.contains(portNumber))
+          {
+            Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
+                String.valueOf(portNumber));
+            printErrorMessage(message);
+            printLineBreak();
+            portNumber = -1;
+          }
+        }
+      }
+      catch (ArgumentException ae)
+      {
+        printErrorMessage(ae.getMessage());
+      }
+    }
+    return portNumber;
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the base DN and data import parameters.
+   * If the user did not provide explicitly some data or if the provided data is
+   * not valid, it prompts the user to provide it.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequiredForImportData(UserData uData)
+  {
+    // Check the validity of the base DNs
+    LinkedList<String> baseDNs = promptIfRequiredForDNs(
+        argParser.baseDNArg, INFO_INSTALLDS_PROMPT_BASEDN.get(), true);
+
+    NewSuffixOptions dataOptions;
+    if (argParser.importLDIFArg.isPresent())
+    {
+      // Check that the files exist
+      LinkedList<String> nonExistingFiles = new LinkedList<String>();
+      LinkedList<String> importLDIFFiles = new LinkedList<String>();
+      for (String file : argParser.importLDIFArg.getValues())
+      {
+        if (!Utils.fileExists(file))
+        {
+          nonExistingFiles.add(file);
+        }
+        else
+        {
+          importLDIFFiles.add(file);
+        }
+      }
+      if (nonExistingFiles.size() > 0)
+      {
+        printLineBreak();
+        printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(
+            Utils.getStringFromCollection(nonExistingFiles, ", ")));
+      }
+      while (importLDIFFiles.isEmpty())
+      {
+        printLineBreak();
+        String path = promptForString(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
+            null);
+        if (!Utils.fileExists(path))
+        {
+          printLineBreak();
+          printErrorMessage(ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path));
+        }
+        else
+        {
+          importLDIFFiles.add(path);
+        }
+      }
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
+          baseDNs, importLDIFFiles);
+    }
+    else if (argParser.addBaseEntryArg.isPresent())
+    {
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.CREATE_BASE_ENTRY,
+          baseDNs);
+    }
+    else if (argParser.sampleDataArg.isPresent())
+    {
+      int numUsers;
+      try
+      {
+        numUsers = argParser.sampleDataArg.getIntValue();
+      }
+      catch (ArgumentException ae)
+      {
+        printLineBreak();
+        printErrorMessage(ae.getMessageObject());
+        Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
+        numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
+      }
+      dataOptions = new NewSuffixOptions(
+          NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
+          baseDNs, numUsers);
+    }
+    else
+    {
+      final int POPULATE_TYPE_BASE_ONLY = 1;
+      final int POPULATE_TYPE_LEAVE_EMPTY = 2;
+      final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
+      final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
+      Message[] options = new Message[] {
+          Message.raw(String.valueOf(POPULATE_TYPE_BASE_ONLY)),
+          Message.raw(String.valueOf(POPULATE_TYPE_LEAVE_EMPTY)),
+          Message.raw(String.valueOf(POPULATE_TYPE_IMPORT_FROM_LDIF)),
+          Message.raw(String.valueOf(POPULATE_TYPE_GENERATE_SAMPLE_DATA))
+        };
+      printLineBreak();
+      printLine(INFO_INSTALLDS_HEADER_POPULATE_TYPE.get(), true);
+      printLine(INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(), true);
+      printLine(INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(), true);
+      printLine(INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(), true);
+      printLine(INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get(), true);
+
+
+      Message answer = promptConfirm(
+          INFO_INSTALLDS_PROMPT_POPULATE_CHOICE.get(),
+            options[0], options);
+      int populateType = new Integer(answer.toString());
+
+      if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
+      {
+        LinkedList<String> importLDIFFiles = new LinkedList<String>();
+        while (importLDIFFiles.isEmpty())
+        {
+          Message message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
+          printLineBreak();
+          String path = promptForString(message, null);
+          if (Utils.fileExists(path))
+          {
+            importLDIFFiles.add(path);
+          }
+          else
+          {
+            message = ERR_INSTALLDS_NO_SUCH_LDIF_FILE.get(path);
+            printLineBreak();
+            printErrorMessage(message);
+          }
+        }
+        dataOptions = new NewSuffixOptions(
+            NewSuffixOptions.Type.IMPORT_FROM_LDIF_FILE,
+            baseDNs, importLDIFFiles);
+      }
       else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
       {
         Message message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
-        numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
-        System.out.println();
+        int numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
+
+        dataOptions = new NewSuffixOptions(
+            NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA,
+            baseDNs, numUsers);
+      }
+      else if (populateType == POPULATE_TYPE_LEAVE_EMPTY)
+      {
+        dataOptions = new NewSuffixOptions(
+            NewSuffixOptions.Type.LEAVE_DATABASE_EMPTY, baseDNs);
+      }
+      else if (populateType == POPULATE_TYPE_BASE_ONLY)
+      {
+        dataOptions = new NewSuffixOptions(
+            NewSuffixOptions.Type.CREATE_BASE_ENTRY, baseDNs);
+      }
+      else
+      {
+        throw new IllegalStateException("Unexpected populateType: "+
+            populateType);
       }
     }
+    uData.setNewSuffixOptions(dataOptions);
+  }
 
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the security parameters.
+   * If the user did not provide explicitly some data or if the provided data is
+   * not valid, it prompts the user to provide it.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequiredForSecurityData(UserData uData)
+  {
+    // Check that the security data provided is valid.
+    boolean enableSSL = false;
+    boolean enableStartTLS = false;
+    int ldapsPort = -1;
+
+    LinkedList<Integer> usedPorts = new LinkedList<Integer>();
+    usedPorts.add(uData.getServerPort());
+    if (uData.getServerJMXPort() != -1)
+    {
+      usedPorts.add(uData.getServerJMXPort());
+    }
+
+    // Ask to enable SSL
+    ldapsPort = -1;
+    if (!argParser.ldapsPortArg.isPresent())
+    {
+      printLineBreak();
+      enableSSL = confirm(INFO_INSTALLDS_PROMPT_ENABLE_SSL.get(), false);
+      if (enableSSL)
+      {
+        ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
+            INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, false);
+      }
+    }
+    else
+    {
+      ldapsPort = promptIfRequiredForPortData(argParser.ldapsPortArg,
+          INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, true);
+      enableSSL = true;
+    }
+
+    // Ask to enable Start TLS
+    if (!argParser.enableStartTLSArg.isPresent())
+    {
+      printLineBreak();
+      enableStartTLS = confirm(INFO_INSTALLDS_ENABLE_STARTTLS.get(),
+          argParser.enableStartTLSArg.isPresent());
+    }
+    else
+    {
+      enableStartTLS = true;
+    }
+
+    SecurityOptions securityOptions;
+    if (argParser.generateSelfSignedCertificateArg.isPresent())
+    {
+      securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+          enableSSL, enableStartTLS, ldapsPort);
+    }
+    else if (argParser.useJavaKeyStoreArg.isPresent())
+    {
+      securityOptions =
+        createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
+            enableSSL, enableStartTLS, ldapsPort);
+    }
+    else if (argParser.usePkcs12Arg.isPresent())
+    {
+      securityOptions =
+        createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS12,
+            enableSSL, enableStartTLS, ldapsPort);
+    }
+    else if (argParser.usePkcs11Arg.isPresent())
+    {
+      securityOptions =
+        createSecurityOptionsPrompting(SecurityOptions.CertificateType.PKCS11,
+            enableSSL, enableStartTLS, ldapsPort);
+    }
+    else
+    {
+      if (!enableSSL && !enableStartTLS)
+      {
+        // If the user did not want to enable SSL or start TLS do not ask
+        // to create a certificate.
+        securityOptions = SecurityOptions.createNoCertificateOptions();
+      }
+      else
+      {
+        final int SELF_SIGNED = 1;
+        final int JKS = 2;
+        final int PKCS12 = 3;
+        final int PKCS11 = 4;
+        Message[] options = new Message[] {
+            Message.raw(String.valueOf(SELF_SIGNED)),
+            Message.raw(String.valueOf(JKS)),
+            Message.raw(String.valueOf(PKCS12)),
+            Message.raw(String.valueOf(PKCS11))
+          };
+        printLineBreak();
+        printLine(INFO_INSTALLDS_HEADER_CERT_TYPE.get(), true);
+        printLine(INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED.get(), true);
+        printLine(INFO_INSTALLDS_CERT_OPTION_JKS.get(), true);
+        printLine(INFO_INSTALLDS_CERT_OPTION_PKCS12.get(), true);
+        printLine(INFO_INSTALLDS_CERT_OPTION_PKCS11.get(), true);
+
+        Message answer = promptConfirm(
+            INFO_INSTALLDS_PROMPT_CERT_TYPE_CHOICE.get(),
+              options[0], options);
+        int certType = new Integer(answer.toString());
+
+        if (certType == SELF_SIGNED)
+        {
+          securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
+                enableSSL, enableStartTLS, ldapsPort);
+        }
+        else if (certType == JKS)
+        {
+          securityOptions =
+            createSecurityOptionsPrompting(SecurityOptions.CertificateType.JKS,
+                enableSSL, enableStartTLS, ldapsPort);
+        }
+        else if (certType == PKCS12)
+        {
+          securityOptions =
+            createSecurityOptionsPrompting(
+                SecurityOptions.CertificateType.PKCS12, enableSSL,
+                enableStartTLS, ldapsPort);
+        }
+        else if (certType == PKCS11)
+        {
+          securityOptions =
+            createSecurityOptionsPrompting(
+                SecurityOptions.CertificateType.PKCS11, enableSSL,
+                enableStartTLS, ldapsPort);
+        }
+        else
+        {
+          throw new IllegalStateException("Unexpected cert type: "+ certType);
+        }
+      }
+    }
+    uData.setSecurityOptions(securityOptions);
+  }
+
+  /**
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the Windows Service parameters.
+   * If the user did not provide explicitly the data, it prompts the user to
+   * provide it.
+   * @param uData the UserData object to be updated.
+   */
+  private void promptIfRequiredForWindowsService(UserData uData)
+  {
     boolean enableService = false;
     // If we are in Windows ask if the server must run as a windows service.
     if (SetupUtils.isWindows())
     {
-      if (quietInstall.isPresent())
-      {
-        enableService = enableWindowsService.isPresent();
-      }
-      else if (enableWindowsService.isPresent())
+      if (argParser.enableWindowsServiceArg.isPresent())
       {
         enableService = true;
       }
       else
       {
+        printLineBreak();
         Message message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
-        enableService = promptForBoolean(message, Boolean.TRUE);
+        enableService = confirm(message, false);
       }
     }
-
-    // At this point, we should be able to invoke the ConfigureDS utility to
-    // apply the requested configuration.
-    ArrayList<String> argList = new ArrayList<String>();
-    argList.add("-C");
-    argList.add(configClassName);
-    argList.add("-c");
-    argList.add(configFileName);
-    argList.add("-p");
-    argList.add(String.valueOf(ldapPortNumber));
-    if (jmxPortNumber != -1)
-    {
-      argList.add("-x");
-      argList.add(String.valueOf(jmxPortNumber));
-    }
-
-    for (DN dn : baseDNs)
-    {
-      argList.add("-b");
-      argList.add(dn.toString());
-    }
-
-    for (DN dn : rootDNs)
-    {
-      argList.add("-D");
-      argList.add(dn.toString());
-    }
-
-    argList.add("-w");
-    argList.add(rootPassword);
-
-    String[] configureDSArguments = new String[argList.size()];
-    argList.toArray(configureDSArguments);
-
-    if (! quietInstall.isPresent())
-    {
-      System.out.println();
-
-      Message message = INFO_INSTALLDS_STATUS_CONFIGURING_DS.get();
-      System.out.println(wrapText(message, MAX_LINE_WIDTH));
-    }
-
-    int returnValue = ConfigureDS.configMain(configureDSArguments);
-    if (returnValue != 0)
-    {
-      return returnValue;
-    }
-
-
-    // If we need to create a base LDIF file or a template file, then do so now.
-    if (populateType == POPULATE_TYPE_BASE_ONLY)
-    {
-      // Create a temporary LDIF file that will hold the entry to add.
-      if (! quietInstall.isPresent())
-      {
-        Message message = INFO_INSTALLDS_STATUS_CREATING_BASE_LDIF.get();
-        System.out.println(wrapText(message, MAX_LINE_WIDTH));
-      }
-
-      try
-      {
-        File   ldifFile     = File.createTempFile("opends-base-entry", ".ldif");
-        String ldifFilePath = ldifFile.getAbsolutePath();
-        ldifFile.deleteOnExit();
-
-        LDIFExportConfig exportConfig =
-             new LDIFExportConfig(ldifFilePath, ExistingFileBehavior.OVERWRITE);
-        LDIFWriter writer = new LDIFWriter(exportConfig);
-
-        for (DN dn : baseDNs)
-        {
-          writer.writeEntry(createEntry(dn));
-        }
-
-        writer.close();
-
-        if (ldifFiles == null)
-        {
-          ldifFiles = new LinkedList<String>();
-        }
-        ldifFiles.add(ldifFilePath);
-      }
-      catch (Exception e)
-      {
-        Message message = ERR_INSTALLDS_CANNOT_CREATE_BASE_ENTRY_LDIF.get(
-                String.valueOf(e));
-
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-    else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
-    {
-      try
-      {
-        File templateFile = SetupUtils.createTemplateFile(
-                                 baseDNs.getFirst().toString(), numUsers);
-        if (ldifFiles == null)
-        {
-          ldifFiles = new LinkedList<String>();
-        }
-        ldifFiles.add(templateFile.getAbsolutePath());
-      }
-      catch (Exception e)
-      {
-        Message message = ERR_INSTALLDS_CANNOT_CREATE_TEMPLATE_FILE.get(
-                String.valueOf(e));
-
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        return 1;
-      }
-    }
-
-    if ((ldifFiles != null) && (! ldifFiles.isEmpty()))
-    {
-      if (! quietInstall.isPresent())
-      {
-        Message message = INFO_INSTALLDS_STATUS_IMPORTING_LDIF.get();
-        System.out.println(wrapText(message, MAX_LINE_WIDTH));
-      }
-
-      // Use the ImportLDIF tool to perform the import.
-      argList = new ArrayList<String>();
-      argList.add("-C");
-      argList.add(configClassName);
-      argList.add("-f");
-      argList.add(configFileName);
-      argList.add("-n");
-      argList.add("userRoot");
-
-      for (String s : ldifFiles)
-      {
-        if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
-        {
-          argList.add("-t");
-        }
-        else
-        {
-          argList.add("-l");
-        }
-        argList.add(s);
-      }
-
-      if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
-      {
-        argList.add("-s");
-        argList.add("0");
-      }
-
-      if (populateType == POPULATE_TYPE_BASE_ONLY)
-      {
-        argList.add("-q");
-      }
-
-      String[] importLDIFArguments = new String[argList.size()];
-      argList.toArray(importLDIFArguments);
-
-      returnValue = ImportLDIF.mainImportLDIF(importLDIFArguments);
-      if (returnValue != 0)
-      {
-        Message message = ERR_INSTALLDS_IMPORT_UNSUCCESSFUL.get();
-        System.out.println(wrapText(message, MAX_LINE_WIDTH));
-        return returnValue;
-      }
-      else
-      {
-        Message message = INFO_INSTALLDS_IMPORT_SUCCESSFUL.get();
-        System.out.println(wrapText(message, MAX_LINE_WIDTH));
-      }
-    }
-
-
-    // Try to write a file that can be used to set the JAVA_HOME environment
-    // variable for the administrative scripts and client tools provided with
-    // the server.  If this fails, then it's not a big deal.
-    try
-    {
-      String serverRoot = System.getenv("INSTANCE_ROOT");
-      if ((serverRoot == null) || (serverRoot.length() == 0))
-      {
-        File f = new File(configFileName);
-        serverRoot = f.getParentFile().getParentFile().getAbsolutePath();
-      }
-
-      // This isn't likely to happen, and it's not a serious problem even if it
-      // does.
-      SetupUtils.writeSetJavaHome(serverRoot);
-    } catch (Exception e) {}
-
-    if (enableService)
-    {
-      Message message = INFO_INSTALLDS_ENABLING_WINDOWS_SERVICE.get();
-      System.out.println(wrapText(message, MAX_LINE_WIDTH));
-      int code = ConfigureWindowsService.enableService(System.out,
-          System.err);
-
-      switch (code)
-      {
-      case ConfigureWindowsService.SERVICE_ENABLE_SUCCESS:
-        break;
-      case ConfigureWindowsService.SERVICE_ALREADY_ENABLED:
-        break;
-      default:
-        // It did not work.
-        return code;
-      }
-    }
-
-    // If we've gotten here, then everything seems to have gone smoothly.
-    if (! quietInstall.isPresent())
-    {
-      Message message = INFO_INSTALLDS_STATUS_SUCCESS.get();
-      System.out.println(wrapText(message, MAX_LINE_WIDTH));
-    }
-
-    return 0;
+    uData.setEnableWindowsService(enableService);
   }
 
-
-
   /**
-   * Interactively prompts (on standard output) the user to provide a Boolean
-   * value.  The answer provided must be one of "true", "t", "yes", "y",
-   * "false", "f", "no", or "n", ignoring capitalization.  It will keep
-   * prompting until an acceptable value is given.
-   *
-   * @param  prompt        The prompt to present to the user.
-   * @param  defaultValue  The default value to assume if the user presses ENTER
-   *                       without typing anything, or <CODE>null</CODE> if
-   *                       there should not be a default and the user must
-   *                       explicitly provide a value.
-   *
-   * @return  The <CODE>boolean</CODE> value read from the user input.
+   * This method updates the contents of a UserData object with what the user
+   * specified in the command-line for the Directory Manager parameters.
+   * If the user did not provide explicitly the data, it prompts the user to
+   * provide it.
+   * @param uData the UserData object to be updated.
    */
-  private static boolean promptForBoolean(Message prompt, Boolean defaultValue)
+  private void promptIfRequiredForStartServer(UserData uData)
   {
-    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
-    while (true)
+    boolean startServer = false;
+    if (!argParser.doNotStartArg.isPresent())
     {
-      System.out.println();
-      System.out.println(wrappedPrompt);
+      printLineBreak();
+      Message message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
+      startServer = confirm(message);
+    }
+    uData.setStartServer(startServer);
+  }
 
-      if (defaultValue == null)
+  /**
+   * Checks that the provided parameters are valid to access an existing
+   * keystore.  This method adds the encountered errors to the provided
+   * list of Message.  It also adds the alias (nicknames) found to the provided
+   * list of String.
+   * @param type the type of keystore.
+   * @param path the path of the keystore.
+   * @param pwd the password (PIN) to access the keystore.
+   * @param certNickname the certificate nickname that we are looking for (or
+   * null if we just one to get the one that is in the keystore).
+   * @param errorMessages the list that will be updated with the errors
+   * encountered.
+   * @param nicknameList the list that will be updated with the nicknames found
+   * in the keystore.
+   */
+  private void checkCertificateInKeystore(SecurityOptions.CertificateType type,
+      String path, String pwd, String certNickname,
+      LinkedList<Message> errorMessages, LinkedList<String> nicknameList)
+  {
+    boolean errorWithPath = false;
+    if (type != SecurityOptions.CertificateType.PKCS11)
+    {
+      File f = new File(path);
+      if (!f.exists())
       {
-        System.out.print(": ");
+        errorMessages.add(INFO_KEYSTORE_PATH_DOES_NOT_EXIST.get());
+        errorWithPath = true;
       }
-      else
+      else if (!f.isFile())
       {
-        System.out.print("[");
-
-        if (defaultValue)
+        errorMessages.add(INFO_KEYSTORE_PATH_NOT_A_FILE.get());
+        errorWithPath = true;
+      }
+    }
+    if (!errorWithPath)
+    {
+      try
+      {
+        CertificateManager certManager;
+        switch (type)
         {
-          System.out.print(INFO_INSTALLDS_PROMPT_VALUE_YES.get());
+          case JKS:
+          certManager = new CertificateManager(
+              path,
+              CertificateManager.KEY_STORE_TYPE_JKS,
+              pwd);
+          break;
+
+          case PKCS12:
+          certManager = new CertificateManager(
+              path,
+              CertificateManager.KEY_STORE_TYPE_PKCS12,
+              pwd);
+          break;
+
+          case PKCS11:
+          certManager = new CertificateManager(
+              CertificateManager.KEY_STORE_PATH_PKCS11,
+              CertificateManager.KEY_STORE_TYPE_PKCS11,
+              pwd);
+          break;
+
+          default:
+            throw new IllegalArgumentException("Invalid type: "+type);
+        }
+        String[] aliases = certManager.getCertificateAliases();
+        if ((aliases == null) || (aliases.length == 0))
+        {
+          // Could not retrieve any certificate
+          switch (type)
+          {
+          case JKS:
+            errorMessages.add(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST.get());
+            break;
+
+          case PKCS12:
+            errorMessages.add(INFO_JKS_KEYSTORE_DOES_NOT_EXIST.get());
+            break;
+          case PKCS11:
+            errorMessages.add(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST.get());
+            break;
+          default:
+            throw new IllegalArgumentException("Invalid type: "+type);
+          }
         }
         else
         {
-          System.out.print(INFO_INSTALLDS_PROMPT_VALUE_NO.get());
+          for (int i=0; i<aliases.length; i++)
+          {
+            nicknameList.add(aliases[i]);
+          }
+          String aliasString = Utils.getStringFromCollection(nicknameList,
+              ", ");
+          if (certNickname != null)
+          {
+            // Check if the cert alias is in the list.
+            boolean found = false;
+            for (int i=0; i<aliases.length && !found; i++)
+            {
+              found = aliases[i].equalsIgnoreCase(certNickname);
+            }
+            if (!found)
+            {
+              errorMessages.add(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND.get(
+                  aliasString));
+            }
+          }
+          else if (aliases.length > 1)
+          {
+            errorMessages.add(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME.get(
+                aliasString));
+          }
         }
-
-        System.out.print("]: ");
       }
-
-      System.out.flush();
-
-      String response = toLowerCase(readLine());
-      if (response.equals("true") || response.equals("yes") ||
-          response.equals("t") || response.equals("y"))
+      catch (KeyStoreException ke)
       {
-        return true;
-      }
-      else if (response.equals("false") || response.equals("no") ||
-               response.equals("f") || response.equals("n"))
-      {
-        return false;
-      }
-      else if (response.equals(""))
-      {
-        if (defaultValue == null)
+        // Could not access to the keystore: because the password is no good,
+        // because the provided file is not a valid keystore, etc.
+        switch (type)
         {
-          Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+        case JKS:
+          errorMessages.add(INFO_ERROR_ACCESSING_JKS_KEYSTORE.get());
+          break;
+
+        case PKCS12:
+          errorMessages.add(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE.get());
+          break;
+        case PKCS11:
+          errorMessages.add(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE.get());
+          break;
+        default:
+          throw new IllegalArgumentException("Invalid type: "+type);
         }
-        else
-        {
-          return defaultValue;
-        }
-      }
-      else
-      {
-        Message message = ERR_INSTALLDS_INVALID_YESNO_RESPONSE.get();
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
       }
     }
   }
 
+  /**
+   * Creates a SecurityOptions object that corresponds to the provided
+   * parameters.  If the parameters are not valid, it prompts the user to
+   * provide them.
+   * @param type the keystore type.
+   * @param enableSSL whether to enable SSL or not.
+   * @param enableStartTLS whether to enable StartTLS or not.
+   * @param ldapsPort the LDAPS port to use.
+   * @return a SecurityOptions object that corresponds to the provided
+   * parameters (or to what the user provided after being prompted).
+   */
+  private SecurityOptions createSecurityOptionsPrompting(
+      SecurityOptions.CertificateType type, boolean enableSSL,
+      boolean enableStartTLS, int ldapsPort)
+  {
+    SecurityOptions securityOptions;
+    String path;
+    String certNickname = argParser.certNicknameArg.getValue();
+    String pwd = argParser.getKeyStorePassword();
+    Message pathPrompt;
+    String defaultPathValue;
 
+    switch (type)
+    {
+    case JKS:
+      path = argParser.useJavaKeyStoreArg.getValue();
+      pathPrompt = INFO_INSTALLDS_PROMPT_JKS_PATH.get();
+      defaultPathValue = argParser.useJavaKeyStoreArg.getValue();
+      break;
+    case PKCS11:
+      path = null;
+      defaultPathValue = null;
+      pathPrompt = null;
+      break;
+    case PKCS12:
+      path = argParser.usePkcs12Arg.getValue();
+      defaultPathValue = argParser.usePkcs12Arg.getValue();
+      pathPrompt = INFO_INSTALLDS_PROMPT_PKCS12_PATH.get();
+      break;
+    default:
+      throw new IllegalStateException(
+          "Called promptIfRequiredCertificate with invalid type: "+type);
+    }
+    LinkedList<Message> errorMessages = new LinkedList<Message>();
+    LinkedList<String> keystoreAliases = new LinkedList<String>();
+    boolean firstTry = true;
+
+    while ((errorMessages.size() > 0) || firstTry)
+    {
+      boolean prompted = false;
+      if (errorMessages.size() > 0)
+      {
+        printLineBreak();
+        printErrorMessage(Utils.getMessageFromCollection(errorMessages,
+            formatter.getLineBreak().toString()));
+      }
+
+      if (type != SecurityOptions.CertificateType.PKCS11)
+      {
+        if (containsKeyStorePathErrorMessage(errorMessages) || (path == null))
+        {
+          printLineBreak();
+          path = promptForString(pathPrompt, defaultPathValue);
+          prompted = true;
+          if (pwd != null)
+          {
+            errorMessages.clear();
+            keystoreAliases.clear();
+            checkCertificateInKeystore(type, path, pwd, certNickname,
+                errorMessages, keystoreAliases);
+            if (!errorMessages.isEmpty())
+            {
+              // Reset password: this might be a new keystore
+              pwd = null;
+            }
+          }
+        }
+      }
+      if (containsKeyStorePasswordErrorMessage(errorMessages) ||
+          (pwd == null))
+      {
+        if (!prompted)
+        {
+          printLineBreak();
+        }
+        pwd = promptForPassword(
+            INFO_INSTALLDS_PROMPT_KEYSTORE_PASSWORD.get());
+      }
+      if (containsCertNicknameErrorMessage(errorMessages))
+      {
+        if (!prompted)
+        {
+          printLineBreak();
+        }
+        certNickname = promptForCertificateNickname(keystoreAliases);
+      }
+      errorMessages.clear();
+      keystoreAliases.clear();
+      checkCertificateInKeystore(type, path, pwd, certNickname, errorMessages,
+          keystoreAliases);
+      firstTry = false;
+    }
+    if (certNickname == null)
+    {
+      certNickname = keystoreAliases.getFirst();
+    }
+    switch (type)
+    {
+      case JKS:
+        securityOptions = SecurityOptions.createJKSCertificateOptions(
+        path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+        break;
+      case PKCS12:
+        securityOptions = SecurityOptions.createPKCS12CertificateOptions(
+            path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+        break;
+      case PKCS11:
+        securityOptions = SecurityOptions.createPKCS11CertificateOptions(
+            pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
+        break;
+      default:
+        throw new IllegalStateException(
+            "Called createSecurityOptionsPrompting with invalid type: "+type);
+    }
+    return securityOptions;
+  }
+
+  /**
+   * Tells if any of the error messages provided corresponds to a problem
+   * with the key store path.
+   * @param msgs the messages to analyze.
+   * @return <CODE>true</CODE> if any of the error messages provided corresponds
+   * to a problem with the key store path and <CODE>false</CODE> otherwise.
+   */
+  private boolean containsKeyStorePathErrorMessage(Collection<Message> msgs)
+  {
+    boolean found = false;
+    for (Message msg : msgs)
+    {
+      if (msg.getDescriptor().equals(INFO_KEYSTORE_PATH_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_KEYSTORE_PATH_NOT_A_FILE) ||
+          msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
+      {
+        found = true;
+        break;
+      }
+    }
+    return found;
+  }
+
+  /**
+   * Tells if any of the error messages provided corresponds to a problem
+   * with the key store password.
+   * @param msgs the messages to analyze.
+   * @return <CODE>true</CODE> if any of the error messages provided corresponds
+   * to a problem with the key store password and <CODE>false</CODE> otherwise.
+   */
+  private boolean containsKeyStorePasswordErrorMessage(Collection<Message> msgs)
+  {
+    boolean found = false;
+    for (Message msg : msgs)
+    {
+      if (msg.getDescriptor().equals(INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_PKCS12_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_PKCS11_KEYSTORE_DOES_NOT_EXIST) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_JKS_KEYSTORE) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS12_KEYSTORE) ||
+          msg.getDescriptor().equals(INFO_ERROR_ACCESSING_PKCS11_KEYSTORE))
+      {
+        found = true;
+        break;
+      }
+    }
+    return found;
+  }
+
+  /**
+   * Tells if any of the error messages provided corresponds to a problem
+   * with the certificate nickname.
+   * @param msgs the messages to analyze.
+   * @return <CODE>true</CODE> if any of the error messages provided corresponds
+   * to a problem with the certificate nickname and <CODE>false</CODE>
+   * otherwise.
+   */
+  private boolean containsCertNicknameErrorMessage(Collection<Message> msgs)
+  {
+    boolean found = false;
+    for (Message msg : msgs)
+    {
+      if (msg.getDescriptor().equals(ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND) ||
+          msg.getDescriptor().equals(ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME))
+      {
+        found = true;
+        break;
+      }
+    }
+    return found;
+  }
 
   /**
    * Interactively prompts (on standard output) the user to provide an integer
@@ -1190,308 +1664,81 @@
    *
    * @return  The <CODE>int</CODE> value read from the user input.
    */
-  private static int promptForInteger(Message prompt, Integer defaultValue,
+  private int promptForInteger(Message prompt, Integer defaultValue,
                                       Integer lowerBound, Integer upperBound)
   {
-    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
-    while (true)
+    int returnValue = -1;
+    while (returnValue == -1)
     {
-      System.out.println();
-      System.out.println(wrappedPrompt);
-
-      if (defaultValue == null)
-      {
-        System.out.print(": ");
-      }
-      else
-      {
-        System.out.print("[");
-        System.out.print(defaultValue);
-        System.out.print("]: ");
-      }
-
-      System.out.flush();
-
-      String response = readLine();
-      if (response.equals(""))
+      String s = promptForString(prompt, String.valueOf(defaultValue));
+      if (s.equals(""))
       {
         if (defaultValue == null)
         {
           Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          printErrorMessage(message);
+          printLineBreak();
         }
         else
         {
-          return defaultValue;
+          returnValue = defaultValue;
         }
       }
       else
       {
         try
         {
-          int intValue = Integer.parseInt(response);
+          int intValue = Integer.parseInt(s);
           if ((lowerBound != null) && (intValue < lowerBound))
           {
             Message message =
                 ERR_INSTALLDS_INTEGER_BELOW_LOWER_BOUND.get(lowerBound);
-            System.err.println(wrapText(message, MAX_LINE_WIDTH));
+            printErrorMessage(message);
+            printLineBreak();
           }
           else if ((upperBound != null) && (intValue > upperBound))
           {
             Message message =
                 ERR_INSTALLDS_INTEGER_ABOVE_UPPER_BOUND.get(upperBound);
-            System.err.println(wrapText(message, MAX_LINE_WIDTH));
+            printErrorMessage(message);
+            printLineBreak();
           }
           else
           {
-            return intValue;
+            returnValue = intValue;
           }
         }
         catch (NumberFormatException nfe)
         {
           Message message = ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
+          printErrorMessage(message);
+          printLineBreak();
         }
       }
     }
+    return returnValue;
   }
 
-
-
   /**
-   * Interactively prompts (on standard output) the user to provide a DN value.
-   * Any non-empty string will be allowed if it can be parsed as a valid DN (the
-   * empty string will indicate that the default should be used, if there is
-   * one).
-   *
-   * @param  prompt        The prompt to present to the user.
-   * @param  defaultValue  The default value to assume if the user presses ENTER
-   *                       without typing anything, or <CODE>null</CODE> if
-   *                       there should not be a default and the user must
-   *                       explicitly provide a value.
-   *
-   * @return  The DN value read from the user.
+   * Prompts the user to accept on the certificates that appears on the list
+   * and returns the chosen certificate nickname.
+   * @param nicknames the list of certificates the user must choose from.
+   * @return the chosen certificate nickname.
    */
-  private static DN promptForDN(Message prompt, String defaultValue)
+  private String promptForCertificateNickname(LinkedList<String> nicknames)
   {
-    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
-    while (true)
+    String nickname = null;
+    while (nickname == null)
     {
-      System.out.println();
-      System.out.println(wrappedPrompt);
-
-      if (defaultValue == null)
+      for (String n : nicknames)
       {
-        System.out.print(": ");
-      }
-      else
-      {
-        System.out.print("[");
-        System.out.print(defaultValue);
-        System.out.print("]: ");
-      }
-
-      System.out.flush();
-
-      String response = readLine();
-      if (response.equals(""))
-      {
-        if (defaultValue == null)
+        if (confirm(INFO_INSTALLDS_PROMPT_CERTNICKNAME.get(n)))
         {
-          Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        }
-        else
-        {
-          try
-          {
-            return DN.decode(defaultValue);
-          }
-          catch (Exception e)
-          {
-            Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
-            System.err.println(wrapText(message, MAX_LINE_WIDTH));
-          }
-        }
-      }
-      else
-      {
-        try
-        {
-          return DN.decode(response);
-        }
-        catch (Exception e)
-        {
-          Message message = ERR_INSTALLDS_INVALID_DN_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        }
-      }
-    }
-  }
-
-
-
-  /**
-   * Interactively prompts (on standard output) the user to provide a string
-   * value.  Any non-empty string will be allowed (the empty string will
-   * indicate that the default should be used, if there is one).
-   *
-   * @param  prompt        The prompt to present to the user.
-   * @param  defaultValue  The default value to assume if the user presses ENTER
-   *                       without typing anything, or <CODE>null</CODE> if
-   *                       there should not be a default and the user must
-   *                       explicitly provide a value.
-   *
-   * @return  The string value read from the user.
-   */
-  private static String promptForString(Message prompt, String defaultValue)
-  {
-      System.out.println();
-    String wrappedPrompt = wrapText(prompt, MAX_LINE_WIDTH);
-
-    while (true)
-    {
-      System.out.println(wrappedPrompt);
-
-      if (defaultValue == null)
-      {
-        System.out.print(": ");
-      }
-      else
-      {
-        System.out.print("[");
-        System.out.print(defaultValue);
-        System.out.print("]: ");
-      }
-
-      System.out.flush();
-
-      String response = readLine();
-      if (response.equals(""))
-      {
-        if (defaultValue == null)
-        {
-          Message message = ERR_INSTALLDS_INVALID_STRING_RESPONSE.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        }
-        else
-        {
-          return defaultValue;
-        }
-      }
-      else
-      {
-        return response;
-      }
-    }
-  }
-
-
-
-  /**
-   * Interactively prompts (on standard output) the user to provide a string
-   * value.  The response that the user provides will not be echoed, and it must
-   * be entered twice for confirmation.  No default value will be allowed, and
-   * the string entered must contain at least one character.
-   *
-   * @param  initialPrompt  The initial prompt to present to the user.
-   * @param  reEntryPrompt  The prompt to present to the user when requesting
-   *                        that the value be re-entered for confirmation.
-   *
-   * @return  The string value read from the user.
-   */
-  private static char[] promptForPassword(Message initialPrompt,
-                                          Message reEntryPrompt)
-  {
-    String wrappedInitialPrompt = wrapText(initialPrompt, MAX_LINE_WIDTH);
-    String wrappedReEntryPrompt = wrapText(reEntryPrompt, MAX_LINE_WIDTH);
-
-    while (true)
-    {
-      System.out.println();
-      System.out.print(wrappedInitialPrompt);
-      System.out.print(": ");
-      System.out.flush();
-
-      char[] password = PasswordReader.readPassword();
-      if ((password == null) || (password.length == 0))
-      {
-        Message message = ERR_INSTALLDS_INVALID_PASSWORD_RESPONSE.get();
-        System.err.println(wrapText(message, MAX_LINE_WIDTH));
-      }
-      else
-      {
-        System.out.print(wrappedReEntryPrompt);
-        System.out.print(": ");
-        System.out.flush();
-        char[] confirmedPassword = PasswordReader.readPassword();
-        if ((confirmedPassword == null) ||
-            (! Arrays.equals(password, confirmedPassword)))
-        {
-          Message message = ERR_INSTALLDS_PASSWORDS_DONT_MATCH.get();
-          System.err.println(wrapText(message, MAX_LINE_WIDTH));
-        }
-        else
-        {
-          return password;
-        }
-      }
-    }
-  }
-
-
-
-  /**
-   * Reads a line of text from standard input.
-   *
-   * @return  The line of text read from standard input, or <CODE>null</CODE>
-   *          if the end of the stream is reached or an error occurs while
-   *          attempting to read the response.
-   */
-  private static String readLine()
-  {
-    try
-    {
-      ByteArrayOutputStream baos = new ByteArrayOutputStream();
-
-      while (true)
-      {
-        int b = System.in.read();
-        if ((b < 0) || (b == '\n'))
-        {
+          nickname = n;
           break;
         }
-        else if (b == '\r')
-        {
-          int b2 = System.in.read();
-          if (b2 == '\n')
-          {
-            break;
-          }
-          else
-          {
-            baos.write(b);
-            baos.write(b2);
-          }
-        }
-        else
-        {
-          baos.write(b);
-        }
       }
-
-      return new String(baos.toByteArray(), "UTF-8");
     }
-    catch (Exception e)
-    {
-      Message message =
-          ERR_INSTALLDS_ERROR_READING_FROM_STDIN.get(String.valueOf(e));
-      System.err.println(wrapText(message, MAX_LINE_WIDTH));
-
-      return null;
-    }
+    return nickname;
   }
 }
-
diff --git a/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java b/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
new file mode 100644
index 0000000..cb98fd6
--- /dev/null
+++ b/opendj-sdk/opends/src/server/org/opends/server/tools/InstallDSArgumentParser.java
@@ -0,0 +1,604 @@
+/*
+ * 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.server.tools;
+
+import static org.opends.messages.ToolMessages.*;
+import static org.opends.server.tools.ToolConstants.*;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import org.opends.messages.Message;
+import org.opends.quicksetup.Constants;
+import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.util.Utils;
+import org.opends.server.extensions.ConfigFileHandler;
+import org.opends.server.util.SetupUtils;
+import org.opends.server.util.args.ArgumentException;
+import org.opends.server.util.args.ArgumentParser;
+import org.opends.server.util.args.BooleanArgument;
+import org.opends.server.util.args.FileBasedArgument;
+import org.opends.server.util.args.IntegerArgument;
+import org.opends.server.util.args.StringArgument;
+
+/**
+ * Class used to parse the arguments of the setup command-line and to check
+ * that there are not conflicting arguments (nor missing arguments in no prompt
+ * mode).
+ * Note that this class does not perform checks involving network (like if
+ * a given port is free) nor the validity of the certificate information
+ * provided.
+ */
+class InstallDSArgumentParser extends ArgumentParser
+{
+  BooleanArgument   testOnlyArg;
+  BooleanArgument   addBaseEntryArg;
+  BooleanArgument   showUsageArg;
+  BooleanArgument   quietArg;
+  BooleanArgument   noPromptArg;
+  BooleanArgument   skipPortCheckArg;
+  BooleanArgument   enableWindowsServiceArg;
+  BooleanArgument   doNotStartArg;
+  BooleanArgument   enableStartTLSArg;
+  BooleanArgument   generateSelfSignedCertificateArg;
+  BooleanArgument   usePkcs11Arg;
+  FileBasedArgument directoryManagerPwdFileArg;
+  FileBasedArgument keyStorePasswordFileArg;
+  IntegerArgument   ldapPortArg;
+  IntegerArgument   ldapsPortArg;
+  IntegerArgument   jmxPortArg;
+  IntegerArgument   sampleDataArg;
+  StringArgument    baseDNArg;
+  StringArgument    configClassArg;
+  StringArgument    configFileArg;
+  StringArgument    importLDIFArg;
+  StringArgument    directoryManagerDNArg;
+  StringArgument    directoryManagerPwdStringArg;
+  StringArgument    useJavaKeyStoreArg;
+  StringArgument    usePkcs12Arg;
+  StringArgument    keyStorePasswordArg;
+  StringArgument    certNicknameArg;
+  StringArgument    progNameArg;
+
+  private static final Logger LOG = Logger.getLogger(
+      InstallDSArgumentParser.class.getName());
+
+  /**
+   * The default constructor for this class.
+   * @param mainClassName the class name of the main class for the command-line
+   * that is being used.
+   */
+  public InstallDSArgumentParser(String mainClassName)
+  {
+    super(mainClassName, INFO_INSTALLDS_TOOL_DESCRIPTION.get(), false);
+  }
+
+  /**
+   * Initializes the arguments without parsing them.
+   * @throws ArgumentException if there was an error creating or adding the
+   * arguments.  If this occurs is likely to be a bug.
+   */
+  public void initializeArguments() throws ArgumentException
+  {
+    testOnlyArg = new BooleanArgument(
+        "test", 't', "testOnly",
+        INFO_INSTALLDS_DESCRIPTION_TESTONLY.get());
+    testOnlyArg.setHidden(true);
+    addArgument(testOnlyArg);
+
+    configFileArg = new StringArgument(
+        "configfile", 'c', "configFile", false,
+        false, true, "{configFile}", getDefaultConfigFile(), null,
+        INFO_DESCRIPTION_CONFIG_FILE.get());
+    configFileArg.setHidden(true);
+    addArgument(configFileArg);
+
+    configClassArg = new StringArgument(
+        "configclass", OPTION_SHORT_CONFIG_CLASS,
+        OPTION_LONG_CONFIG_CLASS, false,
+        false, true, OPTION_VALUE_CONFIG_CLASS,
+        ConfigFileHandler.class.getName(), null,
+        INFO_DESCRIPTION_CONFIG_CLASS.get());
+    configClassArg.setHidden(true);
+    addArgument(configClassArg);
+
+    String defaultProgName;
+    if (SetupUtils.isWindows())
+    {
+      defaultProgName = Installation.WINDOWS_SETUP_FILE_NAME;
+    }
+    else
+    {
+      defaultProgName = Installation.UNIX_SETUP_FILE_NAME;
+    }
+    progNameArg = new StringArgument(
+        "progname", 'P', "programName", false,
+        false, true, "{programName}", defaultProgName,
+        null, INFO_INSTALLDS_DESCRIPTION_PROGNAME.get());
+    progNameArg.setHidden(true);
+    addArgument(progNameArg);
+
+    quietArg = new BooleanArgument(
+        "quiet", OPTION_SHORT_QUIET,
+        OPTION_LONG_QUIET,
+        INFO_INSTALLDS_DESCRIPTION_SILENT.get());
+    addArgument(quietArg);
+
+    noPromptArg = new BooleanArgument(
+        OPTION_LONG_NO_PROMPT,
+        OPTION_SHORT_NO_PROMPT,
+        OPTION_LONG_NO_PROMPT,
+        INFO_INSTALLDS_DESCRIPTION_NO_PROMPT.get());
+    addArgument(noPromptArg);
+
+    baseDNArg = new StringArgument(
+        "basedn", OPTION_SHORT_BASEDN,
+        OPTION_LONG_BASEDN, false, true, true,
+        OPTION_VALUE_BASEDN,
+        "dc=example,dc=com", null,
+        INFO_INSTALLDS_DESCRIPTION_BASEDN.get());
+    addArgument(baseDNArg);
+
+    addBaseEntryArg = new BooleanArgument(
+        "addbase", 'a', "addBaseEntry",
+        INFO_INSTALLDS_DESCRIPTION_ADDBASE.get());
+    addArgument(addBaseEntryArg);
+
+    importLDIFArg = new StringArgument(
+        "importldif", OPTION_SHORT_LDIF_FILE,
+        OPTION_LONG_LDIF_FILE, false,
+        true, true, OPTION_VALUE_LDIF_FILE,
+        null, null,
+        INFO_INSTALLDS_DESCRIPTION_IMPORTLDIF.get());
+    addArgument(importLDIFArg);
+
+    sampleDataArg = new IntegerArgument(
+        "sampledata", 'd', "sampleData", false,
+        false, true, "{numEntries}", 0, null,
+        true, 0, false, 0,
+        INFO_INSTALLDS_DESCRIPTION_SAMPLE_DATA.get());
+    addArgument(sampleDataArg);
+
+    ldapPortArg = new IntegerArgument(
+        "ldapport", OPTION_SHORT_PORT,
+        "ldapPort", false, false,
+        true, OPTION_VALUE_PORT, 389,
+        null, true, 1, true, 65535,
+        INFO_INSTALLDS_DESCRIPTION_LDAPPORT.get());
+    addArgument(ldapPortArg);
+
+    jmxPortArg = new IntegerArgument(
+        "jmxport", 'x', "jmxPort", false, false,
+        true, "{jmxPort}",
+        SetupUtils.getDefaultJMXPort(), null, true,
+        1, true, 65535,
+        INFO_INSTALLDS_DESCRIPTION_JMXPORT.get());
+    addArgument(jmxPortArg);
+
+    skipPortCheckArg = new BooleanArgument(
+        "skipportcheck", 'S', "skipPortCheck",
+        INFO_INSTALLDS_DESCRIPTION_SKIPPORT.get());
+    addArgument(skipPortCheckArg);
+
+    directoryManagerDNArg = new StringArgument(
+        "rootdn",OPTION_SHORT_ROOT_USER_DN,
+        OPTION_LONG_ROOT_USER_DN, false, false,
+        true, OPTION_VALUE_ROOT_USER_DN,
+        "cn=Directory Manager",
+        null, INFO_INSTALLDS_DESCRIPTION_ROOTDN.get());
+    addArgument(directoryManagerDNArg);
+
+    directoryManagerPwdStringArg = new StringArgument(
+        "rootpwstring", OPTION_SHORT_BINDPWD,
+        "rootUserPassword",
+        false, false, true,
+        "{password}", null,
+        null,
+        INFO_INSTALLDS_DESCRIPTION_ROOTPW.get());
+    addArgument(directoryManagerPwdStringArg);
+
+    directoryManagerPwdFileArg = new FileBasedArgument(
+        "rootpwfile",
+        OPTION_SHORT_BINDPWD_FILE,
+        "rootUserPasswordFile", false, false,
+        OPTION_VALUE_BINDPWD_FILE,
+        null, null, INFO_INSTALLDS_DESCRIPTION_ROOTPWFILE.get());
+    addArgument(directoryManagerPwdFileArg);
+
+    enableWindowsServiceArg = new BooleanArgument(
+        "enablewindowsservice", 'e',
+        "enableWindowsService",
+        INFO_INSTALLDS_DESCRIPTION_ENABLE_WINDOWS_SERVICE.get());
+    if (SetupUtils.isWindows())
+    {
+      addArgument(enableWindowsServiceArg);
+    }
+
+    doNotStartArg = new BooleanArgument(
+        "donotstart", 'O', "donotstart",
+        INFO_INSTALLDS_DESCRIPTION_DO_NOT_START.get());
+    addArgument(doNotStartArg);
+
+    enableStartTLSArg = new BooleanArgument(
+        "enableStartTLS", OPTION_SHORT_START_TLS, "enableStartTLS",
+        INFO_INSTALLDS_DESCRIPTION_ENABLE_STARTTLS.get());
+    addArgument(enableStartTLSArg);
+
+    ldapsPortArg = new IntegerArgument(
+        "ldapsport", OPTION_SHORT_USE_SSL,
+        "ldapsPort", false, false,
+        true, OPTION_VALUE_PORT, 636,
+        null, true, 1, true, 65535,
+        INFO_INSTALLDS_DESCRIPTION_LDAPSPORT.get());
+    addArgument(ldapsPortArg);
+
+    generateSelfSignedCertificateArg = new BooleanArgument(
+        "generateSelfSignedCertificate",
+        null, "generateSelfSignedCertificate",
+        INFO_INSTALLDS_DESCRIPTION_USE_SELF_SIGNED.get());
+    addArgument(generateSelfSignedCertificateArg);
+
+    usePkcs11Arg = new BooleanArgument("usePkcs11Keystore",
+        null, "usePkcs11Keystore",
+        INFO_INSTALLDS_DESCRIPTION_USE_PKCS11.get());
+    addArgument(usePkcs11Arg);
+
+    useJavaKeyStoreArg = new StringArgument("useJavaKeystore",
+        null, "useJavaKeystore", false, false,
+        true, OPTION_VALUE_KEYSTOREPATH, null, null,
+        INFO_INSTALLDS_DESCRIPTION_USE_JAVAKEYSTORE.get());
+    addArgument(useJavaKeyStoreArg);
+
+    usePkcs12Arg = new StringArgument("usePkcs12keyStore",
+        null, "usePkcs12keyStore", false, false,
+        true, OPTION_VALUE_KEYSTOREPATH, null, null,
+        INFO_INSTALLDS_DESCRIPTION_USE_PKCS12.get());
+    addArgument(usePkcs12Arg);
+
+    keyStorePasswordArg = new StringArgument("keystorePassword",
+        OPTION_SHORT_KEYSTORE_PWD,
+        OPTION_LONG_KEYSTORE_PWD, false, false, true,
+        OPTION_VALUE_KEYSTORE_PWD, null, null,
+        INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD.get());
+    addArgument(keyStorePasswordArg);
+
+    keyStorePasswordFileArg = new FileBasedArgument("keystorePasswordFile",
+        OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false,
+        false, OPTION_VALUE_KEYSTORE_PWD_FILE, null, null,
+        INFO_INSTALLDS_DESCRIPTION_KEYSTOREPASSWORD_FILE.get());
+    addArgument(keyStorePasswordFileArg);
+
+    certNicknameArg = new StringArgument("certnickname",
+        OPTION_SHORT_CERT_NICKNAME, OPTION_LONG_CERT_NICKNAME,
+        false, false, true, OPTION_VALUE_CERT_NICKNAME, null, null,
+        INFO_INSTALLDS_DESCRIPTION_CERT_NICKNAME.get());
+    addArgument(certNicknameArg);
+
+    showUsageArg = new BooleanArgument("help", OPTION_SHORT_HELP,
+        OPTION_LONG_HELP,
+        INFO_INSTALLDS_DESCRIPTION_HELP.get());
+    addArgument(showUsageArg);
+    setUsageArgument(showUsageArg);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override()
+  public void parseArguments(String[] args) throws ArgumentException
+  {
+    LinkedHashSet<Message> errorMessages = new LinkedHashSet<Message>();
+    try
+    {
+      super.parseArguments(args);
+    }
+    catch (ArgumentException ae)
+    {
+      LOG.log(Level.SEVERE, "Error parsing arguments: "+ae, ae);
+      errorMessages.add(ae.getMessageObject());
+    }
+
+    checkConfigFileArg(errorMessages);
+    checkServerPassword(errorMessages);
+    checkProvidedPorts(errorMessages);
+    checkImportDataArguments(errorMessages);
+    checkSecurityArguments(errorMessages);
+
+    if (errorMessages.size() > 0)
+    {
+      Message message = ERR_CANNOT_INITIALIZE_ARGS.get(
+          Utils.getMessageFromCollection(errorMessages,
+              Constants.LINE_SEPARATOR));
+      throw new ArgumentException(message);
+    }
+  }
+
+  /**
+   * Returns the directory manager password provided by the user.  This method
+   * should be called after a call to parseArguments.
+   * @return the directory manager password provided by the user.
+   */
+  public String getDirectoryManagerPassword()
+  {
+    String pwd = null;
+    if (directoryManagerPwdStringArg.isPresent())
+    {
+      pwd = directoryManagerPwdStringArg.getValue();
+    }
+    else if (directoryManagerPwdFileArg.isPresent())
+    {
+      pwd = directoryManagerPwdFileArg.getValue();
+    }
+    return pwd;
+  }
+
+  /**
+   * Returns the key store password provided by the user.  This method should be
+   * called after a call to parseArguments.
+   * @return the key store password provided by the user.
+   */
+  public String getKeyStorePassword()
+  {
+    String pwd = null;
+    if (keyStorePasswordArg.isPresent())
+    {
+      pwd = keyStorePasswordArg.getValue();
+    }
+    else if (keyStorePasswordArg.isPresent())
+    {
+      pwd = keyStorePasswordFileArg.getValue();
+    }
+    return pwd;
+  }
+
+  /**
+   * Checks that we have a config file value (at least the default value).
+   * @param errorMessages the list of messages to which we add the error
+   * messages describing the problems encountered during the execution of the
+   * checking.
+   */
+  private void checkConfigFileArg(Collection<Message> errorMessages)
+  {
+    //  Make sure the path to the configuration file was given.
+    if (configFileArg.getValue() == null)
+    {
+      Message message = ERR_INSTALLDS_NO_CONFIG_FILE.get(
+              configFileArg.getLongIdentifier());
+      errorMessages.add(message);
+    }
+  }
+
+  /**
+   * Checks that there are no conflicts with the directory manager passwords.
+   * If we are in no prompt mode, check that the password was provided.
+   * @param errorMessages the list of messages to which we add the error
+   * messages describing the problems encountered during the execution of the
+   * checking.
+   */
+  private void checkServerPassword(Collection<Message> errorMessages)
+  {
+    if (directoryManagerPwdStringArg.isPresent() &&
+        directoryManagerPwdFileArg.isPresent())
+    {
+      Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
+          directoryManagerPwdStringArg.getLongIdentifier(),
+          directoryManagerPwdFileArg.getLongIdentifier());
+      errorMessages.add(message);
+    }
+
+    if (noPromptArg.isPresent() && !directoryManagerPwdStringArg.isPresent() &&
+        !directoryManagerPwdFileArg.isPresent())
+    {
+      Message message = ERR_INSTALLDS_NO_ROOT_PASSWORD.get(
+          directoryManagerPwdStringArg.getLongIdentifier(),
+          directoryManagerPwdFileArg.getLongIdentifier());
+      errorMessages.add(message);
+    }
+  }
+
+  /**
+   * Checks that there are no conflicts with the provided ports (like if the
+   * user provided the same port for different protocols).
+   * @param errorMessages the list of messages to which we add the error
+   * messages describing the problems encountered during the execution of the
+   * checking.
+   */
+  private void checkProvidedPorts(Collection<Message> errorMessages)
+  {
+    /**
+     * Check that the provided ports do not match.
+     */
+    try
+    {
+      Set<Integer> ports = new HashSet<Integer>();
+      ports.add(ldapPortArg.getIntValue());
+
+      if (jmxPortArg.isPresent())
+      {
+        if (ports.contains(jmxPortArg.getIntValue()))
+        {
+          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
+                  String.valueOf(jmxPortArg.getIntValue()));
+          errorMessages.add(message);
+        }
+        else
+        {
+          ports.add(jmxPortArg.getIntValue());
+        }
+      }
+      if (ldapsPortArg.isPresent())
+      {
+        if (ports.contains(ldapsPortArg.getIntValue()))
+        {
+          Message message = ERR_CONFIGDS_PORT_ALREADY_SPECIFIED.get(
+                  String.valueOf(ldapsPortArg.getIntValue()));
+          errorMessages.add(message);
+        }
+        else
+        {
+          ports.add(ldapsPortArg.getIntValue());
+        }
+      }
+    }
+    catch (ArgumentException ae)
+    {
+      LOG.log(Level.SEVERE, "Unexpected error.  "+
+          "Assuming that it is caused by a previous parsing issue: "+ae, ae);
+    }
+  }
+
+  /**
+   * Checks that there are no conflicts with the import data arguments.
+   * @param errorMessages the list of messages to which we add the error
+   * messages describing the problems encountered during the execution of the
+   * checking.
+   */
+  private void checkImportDataArguments(Collection<Message> errorMessages)
+  {
+    //  Make sure that the user didn't provide conflicting arguments.
+    if (addBaseEntryArg.isPresent())
+    {
+      if (importLDIFArg.isPresent())
+      {
+        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
+                addBaseEntryArg.getLongIdentifier(),
+                importLDIFArg.getLongIdentifier());
+        errorMessages.add(message);
+      }
+      else if (sampleDataArg.isPresent())
+      {
+        Message message = ERR_TOOL_CONFLICTING_ARGS.get(
+                addBaseEntryArg.getLongIdentifier(),
+                sampleDataArg.getLongIdentifier());
+        errorMessages.add(message);
+      }
+    }
+    else if (importLDIFArg.isPresent() && sampleDataArg.isPresent())
+    {
+      Message message = ERR_TOOL_CONFLICTING_ARGS.get(
+              importLDIFArg.getLongIdentifier(),
+              sampleDataArg.getLongIdentifier());
+      errorMessages.add(message);
+    }
+  }
+
+  /**
+   * Checks that there are no conflicts with the security arguments.
+   * If we are in no prompt mode, check that all the information required has
+   * been provided (but not if this information is valid: we do not try to
+   * open the keystores or to check that the LDAPS port is in use).
+   * @param errorMessages the list of messages to which we add the error
+   * messages describing the problems encountered during the execution of the
+   * checking.
+   */
+  private void checkSecurityArguments(Collection<Message> errorMessages)
+  {
+    boolean certificateRequired = ldapsPortArg.isPresent() ||
+    enableStartTLSArg.isPresent();
+
+    int certificateType = 0;
+    if (generateSelfSignedCertificateArg.isPresent())
+    {
+      certificateType++;
+    }
+    if (useJavaKeyStoreArg.isPresent())
+    {
+      certificateType++;
+    }
+    if (usePkcs11Arg.isPresent())
+    {
+      certificateType++;
+    }
+    if (usePkcs12Arg.isPresent())
+    {
+      certificateType++;
+    }
+
+    if (certificateType > 1)
+    {
+      errorMessages.add(ERR_INSTALLDS_SEVERAL_CERTIFICATE_TYPE_SPECIFIED.get());
+    }
+
+    if (certificateRequired && noPromptArg.isPresent() &&
+        (certificateType == 0))
+    {
+      errorMessages.add(
+          ERR_INSTALLDS_CERTIFICATE_REQUIRED_FOR_SSL_OR_STARTTLS.get());
+    }
+
+    if (certificateType == 1)
+    {
+      if (!generateSelfSignedCertificateArg.isPresent())
+      {
+        // Check that we have only a password.
+        if (keyStorePasswordArg.isPresent() &&
+            keyStorePasswordFileArg.isPresent())
+        {
+          Message message = ERR_INSTALLDS_TWO_CONFLICTING_ARGUMENTS.get(
+              keyStorePasswordArg.getLongIdentifier(),
+              keyStorePasswordFileArg.getLongIdentifier());
+          errorMessages.add(message);
+        }
+
+        // Check that we have one password in no prompt mode.
+        if (noPromptArg.isPresent() && !keyStorePasswordArg.isPresent() &&
+            !keyStorePasswordFileArg.isPresent())
+        {
+          Message message = ERR_INSTALLDS_NO_KEYSTORE_PASSWORD.get(
+              keyStorePasswordArg.getLongIdentifier(),
+              keyStorePasswordFileArg.getLongIdentifier());
+          errorMessages.add(message);
+        }
+      }
+      if (noPromptArg.isPresent() && !ldapsPortArg.isPresent() &&
+          !enableStartTLSArg.isPresent())
+      {
+        Message message = ERR_INSTALLDS_SSL_OR_STARTTLS_REQUIRED.get(
+            ldapsPortArg.getLongIdentifier(),
+            enableStartTLSArg.getLongIdentifier());
+        errorMessages.add(message);
+      }
+    }
+  }
+
+  /**
+   * Returns the default config file retrieved by inspecting the class loader.
+   * @return the default config file retrieved by inspecting the class loader.
+   */
+  private String getDefaultConfigFile()
+  {
+    // Use this instead of Installation.getLocal() because making that call
+    // starts a new JVM and the command-line becomes less responsive.
+    String root = Utils.getInstallPathFromClasspath();
+    String configDir = Utils.getPath(root, Installation.CONFIG_PATH_RELATIVE);
+    return Utils.getPath(configDir, Installation.CURRENT_CONFIG_FILE_NAME);
+  }
+}
diff --git a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java
index 61b1bc3..ebaabc3 100644
--- a/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java
+++ b/opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/quicksetup/TestUtilities.java
@@ -95,14 +95,14 @@
     } else {
       args.add(new File(root, "setup.bat").getPath());
     }
-    args.add("--cli");
-    args.add("-Q");
+    args.add("-n");
     args.add("-p");
     args.add(Integer.toString(ldapPort));
     args.add("-x");
     args.add(Integer.toString(jmxPort));
     args.add("-w");
     args.add(DIRECTORY_MANAGER_PASSWORD);
+    args.add("-O");
 
     ProcessBuilder pb = new ProcessBuilder(args);
     Process p = pb.start();

--
Gitblit v1.10.0