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

Gaetan Boismal
23.50.2015 d45619eae8cf58ab3343158b1686bc068dc3818d
OPENDJ-1839 (checkpoint) code cleanup in InstallDS

* InstallDS.java
Rename ErrorReturnCode enum to InstallReturnCode.
Split very long methods in shorter ones.
Prevent code redundancy where it was possible.
Inline some local variables.
Add final keyword to all parameters and local variables.

* SecurityOptions.java
Add a method to create a certificate for a given type and use it in the old code.
2 files modified
1224 ■■■■ changed files
opendj-server-legacy/src/main/java/org/opends/quicksetup/SecurityOptions.java 216 ●●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDS.java 1008 ●●●● patch | view | raw | blame | history
opendj-server-legacy/src/main/java/org/opends/quicksetup/SecurityOptions.java
@@ -22,9 +22,11 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2015 ForgeRock AS
 */
package org.opends.quicksetup;
/**
 * Class used to describe the Security Options specified by the user.
 *
@@ -82,8 +84,9 @@
  /**
   * Creates a new instance of a SecurityOptions representing for no certificate
   * (no SSL or Start TLS).
   *
   * @return a new instance of a SecurityOptions representing for no certificate
   * (no SSL or Start TLS).
   *         (no SSL or Start TLS).
   */
  public static SecurityOptions createNoCertificateOptions()
  {
@@ -97,130 +100,174 @@
  /**
   * Creates a new instance of a SecurityOptions using a self-signed
   * certificate.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   *
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @return a new instance of a SecurityOptions using a self-signed
   * certificate.
   *         certificate.
   */
  public static SecurityOptions createSelfSignedCertificateOptions(
      boolean enableSSL, boolean enableStartTLS, int sslPort)
          boolean enableSSL, boolean enableStartTLS, int sslPort)
  {
    return createSelfSignedCertificateOptions(enableSSL, enableStartTLS,
        sslPort, SELF_SIGNED_CERT_ALIAS);
    return createSelfSignedCertificateOptions(enableSSL, enableStartTLS, sslPort, SELF_SIGNED_CERT_ALIAS);
  }
  /**
   * Creates a new instance of a SecurityOptions using a self-signed
   * certificate.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the key store to be used.
   *
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @param aliasToUse
   *          the alias of the certificate in the key store to be used.
   * @return a new instance of a SecurityOptions using a self-signed
   * certificate.
   *         certificate.
   */
  public static SecurityOptions createSelfSignedCertificateOptions(
      boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
  public static SecurityOptions createSelfSignedCertificateOptions(boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.SELF_SIGNED_CERTIFICATE);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
      return createOptionsForCertificatType(
              CertificateType.SELF_SIGNED_CERTIFICATE, null, null, enableSSL, enableStartTLS, sslPort, aliasToUse);
  }
  /**
   * Creates a new instance of a SecurityOptions using a Java Key Store.
   * @param keystorePath the path of the key store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the key store to be used.
   *
   * @param keystorePath
   *          the path of the key store.
   * @param keystorePwd
   *          the password of the key store.
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @param aliasToUse
   *          the alias of the certificate in the key store to be used.
   * @return a new instance of a SecurityOptions using a Java Key Store.
   */
  public static SecurityOptions createJKSCertificateOptions(String keystorePath,
      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  public static SecurityOptions createJKSCertificateOptions(String keystorePath, String keystorePwd, boolean enableSSL,
      boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.JKS);
    ops.setKeyStorePath(keystorePath);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
    return createOptionsForCertificatType(
            CertificateType.JKS, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasToUse);
  }
  /**
   * Creates a new instance of a SecurityOptions using a JCE Key Store.
   * @param keystorePath the path of the key store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   *
   * @param keystorePath
   *          the path of the key store.
   * @param keystorePwd
   *          the password of the key store.
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @param aliasToUse
   *          the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a JCE Key Store.
   */
  public static SecurityOptions createJCEKSCertificateOptions(
      String keystorePath,
      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  public static SecurityOptions createJCEKSCertificateOptions(String keystorePath, String keystorePwd,
      boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.JCEKS);
    ops.setKeyStorePath(keystorePath);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
    return createOptionsForCertificatType(
            CertificateType.JCEKS, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasToUse);
  }
  /**
   * Creates a new instance of a SecurityOptions using a PKCS#11 Key Store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   *
   * @param keystorePwd
   *          the password of the key store.
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @param aliasToUse
   *          the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a PKCS#11 Key Store.
   */
  public static SecurityOptions createPKCS11CertificateOptions(
      String keystorePwd, boolean enableSSL, boolean enableStartTLS,
      int sslPort, String aliasToUse)
  public static SecurityOptions createPKCS11CertificateOptions(String keystorePwd, boolean enableSSL,
      boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.PKCS11);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
    return createOptionsForCertificatType(
            CertificateType.PKCS11, null, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasToUse);
  }
  /**
   * Creates a new instance of a SecurityOptions using a PKCS#12 Key Store.
   * @param keystorePath the path of the key store.
   * @param keystorePwd the password of the key store.
   * @param enableSSL whether SSL is enabled or not.
   * @param enableStartTLS whether Start TLS is enabled or not.
   * @param sslPort the value of the LDAPS port.
   * @param aliasToUse the alias of the certificate in the keystore to be used.
   *
   * @param keystorePath
   *          the path of the key store.
   * @param keystorePwd
   *          the password of the key store.
   * @param enableSSL
   *          whether SSL is enabled or not.
   * @param enableStartTLS
   *          whether Start TLS is enabled or not.
   * @param sslPort
   *          the value of the LDAPS port.
   * @param aliasToUse
   *          the alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions using a PKCS#12 Key Store.
   */
  public static SecurityOptions createPKCS12CertificateOptions(
      String keystorePath, String keystorePwd, boolean enableSSL,
      boolean enableStartTLS, int sslPort, String aliasToUse)
  public static SecurityOptions createPKCS12CertificateOptions( String keystorePath, String keystorePwd,
          boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
  {
    SecurityOptions ops = new SecurityOptions();
    ops.setCertificateType(CertificateType.PKCS12);
    ops.setKeyStorePath(keystorePath);
    ops.setKeyStorePassword(keystorePwd);
    updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort,
        aliasToUse);
    return ops;
    return createOptionsForCertificatType(
            CertificateType.PKCS12, keystorePath, keystorePwd, enableSSL, enableStartTLS, sslPort, aliasToUse);
  }
  /**
   * Creates a new instance of a SecurityOptions using the provided type Key
   * Store.
   *
   * @param certType
   *          The Key Store type.
   * @param keystorePath
   *          The path of the key store (may be @null).
   * @param keystorePwd
   *          The password of the key store.
   * @param enableSSL
   *          Whether SSL is enabled or not.
   * @param enableStartTLS
   *          Whether Start TLS is enabled or not.
   * @param sslPort
   *          The value of the LDAPS port.
   * @param aliasToUse
   *          The alias of the certificate in the keystore to be used.
   * @return a new instance of a SecurityOptions.
   */
  public static SecurityOptions createOptionsForCertificatType(CertificateType certType, String keystorePath,
      String keystorePwd, boolean enableSSL, boolean enableStartTLS, int sslPort, String aliasToUse)
  {
      SecurityOptions ops = new SecurityOptions();
      if (keystorePath != null)
      {
        ops.setKeyStorePath(keystorePath);
      }
      if (keystorePwd != null)
      {
        ops.setKeyStorePassword(keystorePwd);
      }
      ops.setCertificateType(certType);
      updateCertificateOptions(ops, enableSSL, enableStartTLS, sslPort, aliasToUse);
      return ops;
  }
  /**
@@ -372,4 +419,5 @@
  {
    this.aliasToUse = aliasToUse;
  }
}
opendj-server-legacy/src/main/java/org/opends/server/tools/InstallDS.java
@@ -22,8 +22,8 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions Copyright 2011-2014 ForgeRock AS
 *      Portions Copyright 2011 profiq s.r.o.
 *      Portions Copyright 2011-2015 ForgeRock AS
 */
package org.opends.server.tools;
@@ -31,9 +31,12 @@
import static org.opends.messages.QuickSetupMessages.*;
import static org.opends.messages.ToolMessages.*;
import static org.opends.messages.UtilityMessages.*;
import static com.forgerock.opendj.cli.Utils.CONFIRMATION_MAX_TRIES;
import static com.forgerock.opendj.cli.Utils.canWrite;
import static org.forgerock.util.Utils.joinAsString;
import static com.forgerock.opendj.util.OperatingSystem.isWindows;
import java.io.BufferedReader;
@@ -102,8 +105,9 @@
 */
public class InstallDS extends ConsoleApplication
{
  private final PlainTextProgressMessageFormatter formatter =
    new PlainTextProgressMessageFormatter();
  private final PlainTextProgressMessageFormatter formatter = new PlainTextProgressMessageFormatter();
  /** Prefix for log files. */
  public static final String TMP_FILE_PREFIX = "opendj-setup-";
@@ -114,52 +118,39 @@
   * The enumeration containing the different return codes that the command-line
   * can have.
   */
  enum ErrorReturnCode
  private enum InstallReturnCode
  {
    /**
     * Successful setup.
     */
    SUCCESSFUL(0),
    /**
     * We did no have an error but the setup was not executed (displayed
     * version or usage).
     */
    /** We did no have an error but the setup was not executed (displayed version or usage). */
    SUCCESSFUL_NOP(0),
    /**
     * Unexpected error (potential bug).
     */
    /** Unexpected error (potential bug). */
    ERROR_UNEXPECTED(1),
    /**
     * Cannot parse arguments or data provided by user is not valid.
     */
    /** Cannot parse arguments or data provided by user is not valid. */
    ERROR_USER_DATA(2),
    /**
     * Error server already installed.
     */
    /** Error server already installed. */
    ERROR_SERVER_ALREADY_INSTALLED(3),
    /**
     * Error initializing server.
     */
    /** Error initializing server. */
    ERROR_INITIALIZING_SERVER(4),
    /**
     * The user failed providing password (for the keystore for instance).
     */
    /** The user failed providing password (for the keystore for instance). */
    ERROR_PASSWORD_LIMIT(5),
    /**
     * The user cancelled the setup.
     */
    /** The user cancelled the setup. */
    ERROR_USER_CANCELLED(6),
    /**
     * The user doesn't accept the license.
     */
    /** The user doesn't accept the license. */
    ERROR_LICENSE_NOT_ACCEPTED(7),
    /**
     * Incompatible java version.
     */
    /** Incompatible java version. */
    JAVA_VERSION_INCOMPATIBLE(8);
    private int returnCode;
    private ErrorReturnCode(int returnCode)
    private InstallReturnCode(int returnCode)
    {
      this.returnCode = returnCode;
    }
@@ -176,20 +167,16 @@
  }
  /**
   * Enumeration describing the different answer that the user can provide
   * when we ask to finalize the setup.  Note that the code associated
   * correspond to the order in the confirmation menu that is displayed at the
   * end of the setup in interactive mode.
   * Enumeration describing the different answer that the user can provide when
   * we ask to finalize the setup. Note that the code associated correspond to
   * the order in the confirmation menu that is displayed at the end of the
   * setup in interactive mode.
   */
  private enum ConfirmCode
  {
    /** Continue with the install. */
    CONTINUE(1),
    /** Provide information again. */
    PROVIDE_INFORMATION_AGAIN(2),
    /** Display equivalent command-line. */
    PRINT_EQUIVALENT_COMMAND_LINE(3),
    /** Cancel the install. */
    CANCEL(3);
    private int returnCode;
@@ -240,9 +227,12 @@
  /**
   * Constructor for the InstallDS 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.
   * @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)
  {
@@ -252,21 +242,22 @@
  /**
   * The main method for the InstallDS CLI tool.
   *
   * @param args the command-line arguments provided to this program.
   * @param args
   *          the command-line arguments provided to this program.
   */
  public static void main(String[] args)
  {
    int retCode = mainCLI(args, System.out, System.err, System.in);
    final int retCode = mainCLI(args, System.out, System.err, System.in);
    System.exit(retCode);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the setup tool.
   * 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 args
   *          the command-line arguments provided to this program.
   * @return The error code.
   */
  public static int mainCLI(String[] args)
@@ -275,48 +266,49 @@
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the setup tool.
   * 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  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.
   * @param args
   *          The command-line arguments provided to this program.
   * @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,
      OutputStream outStream, OutputStream errStream, InputStream inStream)
  public static int mainCLI(String[] args, OutputStream outStream, OutputStream errStream, InputStream inStream)
  {
    PrintStream out = NullOutputStream.wrapOrNullStream(outStream);
    final PrintStream out = NullOutputStream.wrapOrNullStream(outStream);
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
    PrintStream err = NullOutputStream.wrapOrNullStream(errStream);
    final PrintStream err = NullOutputStream.wrapOrNullStream(errStream);
    try {
      QuickSetupLog.initLogFileHandler(
              QuickSetupLog.isInitialized() ? null :
                File.createTempFile(TMP_FILE_PREFIX, LOG_FILE_SUFFIX));
    } catch (Throwable t) {
    } catch (final Throwable t) {
      System.err.println("Unable to initialize log");
      t.printStackTrace();
    }
    InstallDS install = new InstallDS(out, err, inStream);
    final InstallDS install = new InstallDS(out, err, inStream);
    return install.execute(args);
  }
  /**
   * Parses the provided command-line arguments and uses that information to
   * run the setup CLI.
   * 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 args
   *          the command-line arguments provided to this program.
   * @return the return code (SUCCESSFUL, USER_DATA_ERROR or BUG).
   */
  public int execute(String[] args)
@@ -326,12 +318,10 @@
    {
      argParser.initializeArguments();
    }
    catch (ArgumentException ae)
    catch (final ArgumentException ae)
    {
      LocalizableMessage message =
        ToolMessages.ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage());
      println(message);
      return ErrorReturnCode.ERROR_UNEXPECTED.getReturnCode();
      println(ToolMessages.ERR_CANNOT_INITIALIZE_ARGS.get(ae.getMessage()));
      return InstallReturnCode.ERROR_UNEXPECTED.getReturnCode();
    }
    // Validate user provided data
@@ -339,215 +329,59 @@
    {
      argParser.parseArguments(args);
    }
    catch (ArgumentException ae)
    catch (final ArgumentException ae)
    {
      LocalizableMessage message = ERR_ERROR_PARSING_ARGS.get(ae.getMessage());
      println(message);
      println(ERR_ERROR_PARSING_ARGS.get(ae.getMessage()));
      println();
      println(LocalizableMessage.raw(argParser.getUsage()));
      return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
      return InstallReturnCode.ERROR_USER_DATA.getReturnCode();
    }
    // Delete the log file that does not contain any information.  The test only
    // mode is called several times by the setup script and if we do not remove
    // it we have a lot of empty log files.
    if (argParser.testOnlyArg.isPresent())
    if (argParser.testOnlyArg.isPresent() && !testJVM())
    {
      try
      {
        QuickSetupLog.getLogFile().deleteOnExit();
      }
      catch (Throwable t)
      {
        logger.warn(LocalizableMessage.raw("Error while trying to update the contents of "+
            "the set-java-home file in test only mode: "+t, t));
      }
      // Test that we are running a compatible java 1.6 version.
      try
      {
        Utils.checkJavaVersion();
      }
      catch (IncompatibleVersionException ive)
      {
        println(ive.getMessageObject());
        return ErrorReturnCode.JAVA_VERSION_INCOMPATIBLE.getReturnCode();
      }
        return InstallReturnCode.JAVA_VERSION_INCOMPATIBLE.getReturnCode();
    }
    // If either the showUsage or testOnly or version arguments were provided,
    // then we're done.
    if (argParser.usageOrVersionDisplayed() ||
        argParser.testOnlyArg.isPresent())
    {
      return ErrorReturnCode.SUCCESSFUL_NOP.getReturnCode();
      return InstallReturnCode.SUCCESSFUL_NOP.getReturnCode();
    }
    try
    {
      checkInstallStatus();
    }
    catch (InitializationException ie)
    catch (final InitializationException ie)
    {
      println(ie.getMessageObject());
      return ErrorReturnCode.ERROR_SERVER_ALREADY_INSTALLED.getReturnCode();
      return InstallReturnCode.ERROR_SERVER_ALREADY_INSTALLED.getReturnCode();
    }
    // Check license
    if (LicenseFile.exists())
    if (!checkLicense())
    {
      PrintStream printStreamOut = getOutputStream();
      String licenseString = LicenseFile.getText();
      printStreamOut.println(licenseString);
      // If the user asks for acceptLicense, license is displayed
      // and automatically accepted.
      if (! argParser.acceptLicense.isPresent())
      {
        String yes = INFO_LICENSE_CLI_ACCEPT_YES.get().toString();
        String no = INFO_LICENSE_CLI_ACCEPT_NO.get().toString();
        String yesShort = INFO_PROMPT_YES_FIRST_LETTER_ANSWER.get().toString();
        String noShort = INFO_PROMPT_NO_FIRST_LETTER_ANSWER.get().toString();
        println(QuickSetupMessages.
            INFO_LICENSE_DETAILS_CLI_LABEL.get());
        BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
        // No-prompt arg automatically rejects the license.
        if (!argParser.noPromptArg.isPresent())
        {
          while (true)
          {
            print(INFO_LICENSE_CLI_ACCEPT_QUESTION.get(yes, no, no));
            try
            {
              String response = in.readLine();
              if (response == null
                  || response.equalsIgnoreCase(no)
                  || response.equalsIgnoreCase(noShort)
                  || response.length() == 0)
              {
                return ErrorReturnCode.ERROR_LICENSE_NOT_ACCEPTED.getReturnCode();
              }
              else if (response.equalsIgnoreCase(yes)
                  || response.equalsIgnoreCase(yesShort))
              {
                LicenseFile.setApproval(true);
                break;
              }
              else
              {
                println(
                    QuickSetupMessages.INFO_LICENSE_CLI_ACCEPT_INVALID_RESPONSE
                    .get());
              }
            }
            catch (IOException e)
            {
              println(
                  QuickSetupMessages.INFO_LICENSE_CLI_ACCEPT_INVALID_RESPONSE
                  .get());
            }
          }
        }
        else
        {
          return ErrorReturnCode.ERROR_LICENSE_NOT_ACCEPTED.getReturnCode();
        }
      }
      else
      {
        print(INFO_LICENSE_ACCEPT.get());
        print(INFO_PROMPT_YES_COMPLETE_ANSWER.get());
        LicenseFile.setApproval(true);
      }
      return InstallReturnCode.ERROR_LICENSE_NOT_ACCEPTED.getReturnCode();
    }
    boolean userApproved = false;
    UserData uData = new UserData();
    while (!userApproved)
    final UserData uData = new UserData();
    InstallReturnCode fillUserDataRC;
    try
    {
      try
      fillUserDataRC = fillUserData(uData, args);
      if (fillUserDataRC != InstallReturnCode.SUCCESSFUL)
      {
        if (isInteractive())
        {
          promptIfRequired(uData);
        }
        else
        {
          initializeUserDataWithParser(uData);
        }
      }
      catch (ClientException ce)
      {
        println(ce.getMessageObject());
        if (isPasswordTriesError(ce.getMessageObject()))
        {
          return ErrorReturnCode.ERROR_PASSWORD_LIMIT.getReturnCode();
        }
        else
        {
          return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
        }
      }
      catch (UserDataException ude)
      {
        println(ude.getMessageObject());
        if (isPasswordTriesError(ude.getMessageObject()))
        {
          return ErrorReturnCode.ERROR_PASSWORD_LIMIT.getReturnCode();
        }
        else
        {
          return ErrorReturnCode.ERROR_USER_DATA.getReturnCode();
        }
      }
      boolean promptAgain = true;
      if (!isInteractive())
      {
        userApproved = true;
      }
      else
      {
        printSummary(uData);
      }
      while (isInteractive() && promptAgain)
      {
        promptAgain = false;
        ConfirmCode confirm = askForConfirmation();
        switch (confirm)
        {
        case CONTINUE:
          userApproved = true;
          break;
        case CANCEL:
          logger.debug(LocalizableMessage.raw("User cancelled setup."));
          return ErrorReturnCode.ERROR_USER_CANCELLED.getReturnCode();
        case PRINT_EQUIVALENT_COMMAND_LINE:
          printEquivalentCommandLine(uData);
          promptAgain = true;
          break;
        default:
          // Reset the arguments
          try
          {
            resetArguments(uData);
            argParser.parseArguments(args);
          }
          catch (Throwable t)
          {
            logger.warn(LocalizableMessage.raw("Error resetting arg parser: "+t, t));
          }
          userApproved = false;
        }
      }
      if (!isInteractive())
      {
        userApproved = true;
        return fillUserDataRC.getReturnCode();
      }
    }
    catch (final UserDataException e)
    {
      return printAndReturnErrorCode(e.getMessageObject()).getReturnCode();
    }
    System.setProperty(Constants.CLI_JAVA_PROPERTY, "true");
    OfflineInstaller installer = new OfflineInstaller();
    final OfflineInstaller installer = new OfflineInstaller();
    installer.setUserData(uData);
    installer.setProgressMessageFormatter(formatter);
    installer.addProgressUpdateListener(
@@ -563,48 +397,216 @@
    println();
    installer.run();
    printStatusCommand();
    ApplicationException ue = installer.getRunError();
    final ApplicationException ue = installer.getRunError();
    if (ue != null)
    {
      return ue.getType().getReturnCode();
    }
    return InstallReturnCode.SUCCESSFUL.getReturnCode();
  }
  private InstallReturnCode fillUserData(UserData uData, String[] args) throws UserDataException
  {
    if (!isInteractive())
    {
      initializeUserDataWithParser(uData);
      return InstallReturnCode.SUCCESSFUL;
    }
    boolean userApproved = false;
    while (!userApproved)
    {
      try
      {
        promptIfRequired(uData);
      }
      catch (final ClientException ce)
      {
        return printAndReturnErrorCode(ce.getMessageObject());
      }
      boolean promptAgain = true;
      printSummary(uData);
      while (isInteractive() && promptAgain)
      {
        promptAgain = false;
        final ConfirmCode confirm = askForConfirmation();
        switch (confirm)
        {
        case CONTINUE:
          userApproved = true;
          break;
        case CANCEL:
          logger.debug(LocalizableMessage.raw("User cancelled setup."));
          return InstallReturnCode.ERROR_USER_CANCELLED;
        case PRINT_EQUIVALENT_COMMAND_LINE:
          printEquivalentCommandLine(uData);
          promptAgain = true;
          break;
        case PROVIDE_INFORMATION_AGAIN:
          // Reset the arguments
          try
          {
            resetArguments(uData);
            argParser.parseArguments(args);
          }
          catch (final Throwable t)
          {
            logger.warn(LocalizableMessage.raw("Error resetting arg parser: "+t, t));
          }
          userApproved = false;
        }
      }
    }
    return InstallReturnCode.SUCCESSFUL;
  }
  private boolean testJVM()
  {
    // Delete the log file that does not contain any information.  The test only
    // mode is called several times by the setup script and if we do not remove
    // it we have a lot of empty log files.
    try
    {
      QuickSetupLog.getLogFile().deleteOnExit();
    }
    catch (final Throwable t)
    {
      logger.warn(LocalizableMessage.raw("Error while trying to update the contents of "
          + "the set-java-home file in test only mode: " + t, t));
    }
    // Test that we are running a compatible java 1.6 version.
    try
    {
      Utils.checkJavaVersion();
    }
    catch (final IncompatibleVersionException ive)
    {
      println(ive.getMessageObject());
      return false;
    }
    return true;
  }
  private boolean checkLicense()
  {
    if (!LicenseFile.exists()) {
      return true;
    }
    final PrintStream printStreamOut = getOutputStream();
    final String licenseString = LicenseFile.getText();
    printStreamOut.println(licenseString);
    // If the user asks for acceptLicense, license is displayed
    // and automatically accepted.
    if (!argParser.acceptLicense.isPresent())
    {
      final String yes = INFO_LICENSE_CLI_ACCEPT_YES.get().toString();
      final String no = INFO_LICENSE_CLI_ACCEPT_NO.get().toString();
      final String yesShort = INFO_PROMPT_YES_FIRST_LETTER_ANSWER.get().toString();
      final String noShort = INFO_PROMPT_NO_FIRST_LETTER_ANSWER.get().toString();
      println(QuickSetupMessages.INFO_LICENSE_DETAILS_CLI_LABEL.get());
      final BufferedReader in = new BufferedReader(new InputStreamReader(getInputStream()));
      // No-prompt arg automatically rejects the license.
      if (!argParser.noPromptArg.isPresent())
      {
        while (true)
        {
          print(INFO_LICENSE_CLI_ACCEPT_QUESTION.get(yes, no, no));
          try
          {
            final String response = in.readLine();
            if (response == null
                || response.equalsIgnoreCase(no)
                || response.equalsIgnoreCase(noShort)
                || response.length() == 0)
            {
              return false;
            }
            else if (response.equalsIgnoreCase(yes)
                  || response.equalsIgnoreCase(yesShort))
            {
              LicenseFile.setApproval(true);
              break;
            }
            println(QuickSetupMessages.INFO_LICENSE_CLI_ACCEPT_INVALID_RESPONSE.get());
          }
          catch (final IOException e)
          {
            println(QuickSetupMessages.INFO_LICENSE_CLI_ACCEPT_INVALID_RESPONSE.get());
          }
        }
      }
      else
      {
        return false;
      }
    }
    else
    {
      print(INFO_LICENSE_ACCEPT.get());
      print(INFO_PROMPT_YES_COMPLETE_ANSWER.get());
      LicenseFile.setApproval(true);
    }
    return true;
  }
  private void printStatusCommand()
  {
    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();
    final String root = Utils.getInstallPathFromClasspath();
    if (isWindows())
    {
      String binDir = Utils.getPath(root,
      final 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,
      final String binDir = Utils.getPath(root,
          Installation.UNIX_BINARIES_PATH_RELATIVE);
      cmd = Utils.getPath(binDir, Installation.UNIX_STATUSCLI_FILE_NAME);
    }
    println();
    println(INFO_INSTALLDS_STATUS_COMMAND_LINE.get(cmd));
    println();
  }
    if (ue != null)
  private InstallReturnCode printAndReturnErrorCode(LocalizableMessage message)
  {
    println(message);
    if (StaticUtils.hasDescriptor(message, ERR_INSTALLDS_TOO_MANY_KEYSTORE_PASSWORD_TRIES))
    {
      return ue.getType().getReturnCode();
      return InstallReturnCode.ERROR_PASSWORD_LIMIT;
    }
    else
    {
      return ErrorReturnCode.SUCCESSFUL.getReturnCode();
    }
    return InstallReturnCode.ERROR_USER_DATA;
  }
  /**
   * 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.
   *
   * @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();
    final CurrentInstallStatus installStatus = new CurrentInstallStatus();
    if (installStatus.canOverwriteCurrentInstall())
    {
      if (isInteractive())
@@ -617,7 +619,7 @@
            throw new InitializationException(LocalizableMessage.EMPTY, null);
          }
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.error(LocalizableMessage.raw("Unexpected error: "+ce, ce));
          throw new InitializationException(LocalizableMessage.EMPTY, null);
@@ -630,8 +632,7 @@
    }
    else if (installStatus.isInstalled())
    {
      throw new InitializationException(installStatus.getInstallationMsg(),
          null);
      throw new InitializationException(installStatus.getInstallationMsg(), null);
    }
  }
@@ -676,64 +677,82 @@
  /**
   * 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
   * 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.
   *
   * @param uData
   *          the UserData object.
   * @throws UserDataException
   *           if something went wrong checking the data.
   */
  private void initializeUserDataWithParser(UserData uData)
  throws UserDataException
  private void initializeUserDataWithParser(UserData uData) throws UserDataException
  {
    List<LocalizableMessage> errorMessages = new LinkedList<LocalizableMessage>();
    uData.setQuiet(isQuiet());
    uData.setVerbose(isVerbose());
    uData.setConnectTimeout(getConnectTimeout());
    //  Check the validity of the directory manager DNs
    String dmDN = argParser.directoryManagerDNArg.getValue();
    try
    {
      new LdapName(dmDN);
      if (dmDN.trim().length() == 0)
      {
        errorMessages.add(ERR_INSTALLDS_EMPTY_DN_RESPONSE.get());
      }
    }
    catch (Exception e)
    {
      LocalizableMessage message =
        ERR_INSTALLDS_CANNOT_PARSE_DN.get(dmDN, e.getMessage());
      errorMessages.add(message);
    }
    uData.setDirectoryManagerDn(dmDN);
    uData.setDirectoryManagerPwd(argParser.getDirectoryManagerPassword());
    final List<LocalizableMessage> errorMessages = new LinkedList<LocalizableMessage>();
    final List<String> baseDNs = checkBaseDNs(errorMessages);
    setDirectoryManagerData(uData, errorMessages);
    setPorts(uData, errorMessages);
    setImportData(baseDNs, uData, errorMessages);
    setSecurityData(uData, errorMessages);
    // Check the validity of the base DNs
    List<String> baseDNs = argParser.baseDNArg.getValues();
    if (!errorMessages.isEmpty())
    {
      throw new UserDataException(null,
          Utils.getMessageFromCollection(errorMessages, formatter.getLineBreak().toString()));
    }
  }
  private List<String> checkBaseDNs(List<LocalizableMessage> errorMessages)
  {
    final List<String> baseDNs = argParser.baseDNArg.getValues();
    if (baseDNs.isEmpty() && argParser.baseDNArg.getDefaultValue() != null)
    {
      baseDNs.add(argParser.baseDNArg.getDefaultValue());
    }
    for (String baseDN : baseDNs)
    for (final String baseDN : baseDNs)
    {
      try
      {
        new LdapName(baseDN);
      }
      catch (Exception e)
      {
        LocalizableMessage message =
          ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN, e.getMessage());
        errorMessages.add(message);
      }
      checkBaseDN(baseDN, errorMessages);
    }
    return baseDNs;
  }
  private void setDirectoryManagerData(UserData uData, List<LocalizableMessage> errorMessages)
  {
    final String dmDN = argParser.directoryManagerDNArg.getValue();
    if (dmDN.trim().length() == 0)
    {
      errorMessages.add(ERR_INSTALLDS_EMPTY_DN_RESPONSE.get());
    }
    checkBaseDN(dmDN, errorMessages);
    uData.setDirectoryManagerDn(argParser.directoryManagerDNArg.getValue());
    uData.setDirectoryManagerPwd(argParser.getDirectoryManagerPassword());
  }
  private void checkBaseDN(String baseDN, List<LocalizableMessage> errorMessages)
  {
    try
    {
      int ldapPort = argParser.ldapPortArg.getIntValue();
      new LdapName(baseDN);
    }
    catch (final Exception e)
    {
      errorMessages.add(ERR_INSTALLDS_CANNOT_PARSE_DN.get(baseDN, e.getMessage()));
    }
  }
  private void setPorts(UserData uData, List<LocalizableMessage> errorMessages)
  {
    try
    {
      final int ldapPort = argParser.ldapPortArg.getIntValue();
      uData.setServerPort(ldapPort);
      int adminConnectorPort = argParser.adminConnectorPortArg.getIntValue();
      final int adminConnectorPort = argParser.adminConnectorPortArg.getIntValue();
      uData.setAdminConnectorPort(adminConnectorPort);
      if (!argParser.skipPortCheckArg.isPresent())
@@ -743,7 +762,7 @@
      }
      if (argParser.jmxPortArg.isPresent())
      {
        int jmxPort = argParser.jmxPortArg.getIntValue();
        final int jmxPort = argParser.jmxPortArg.getIntValue();
        uData.setServerJMXPort(jmxPort);
        if (!argParser.skipPortCheckArg.isPresent())
        {
@@ -751,41 +770,44 @@
        }
      }
    }
    catch (ArgumentException ae)
    catch (final ArgumentException ae)
    {
      errorMessages.add(ae.getMessageObject());
    }
  }
  private void setImportData(List<String> baseDNs, UserData uData, List<LocalizableMessage> errorMessages)
  {
    NewSuffixOptions dataOptions;
    if (argParser.importLDIFArg.isPresent())
    {
      // Check that the files exist
      List<String> nonExistingFiles = new LinkedList<String>();
      for (String file : argParser.importLDIFArg.getValues())
      final List<String> nonExistingFiles = new LinkedList<String>();
      for (final 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(joinAsString(", ", nonExistingFiles)));
      }
      String rejectedFile = argParser.rejectedImportFileArg.getValue();
      final String rejectedFile = argParser.rejectedImportFileArg.getValue();
      if (rejectedFile != null && !canWrite(rejectedFile))
      {
        errorMessages.add(ERR_INSTALLDS_CANNOT_WRITE_REJECTED.get(rejectedFile));
      }
      String skippedFile = argParser.skippedImportFileArg.getValue();
      final String skippedFile = argParser.skippedImportFileArg.getValue();
      if (skippedFile != null && !canWrite(skippedFile))
      {
        errorMessages.add(ERR_INSTALLDS_CANNOT_WRITE_SKIPPED.get(skippedFile));
      }
      dataOptions = NewSuffixOptions.createImportFromLDIF(baseDNs,
          argParser.importLDIFArg.getValues(),
      dataOptions = NewSuffixOptions.createImportFromLDIF(baseDNs, argParser.importLDIFArg.getValues(),
          rejectedFile, skippedFile);
    }
    else if (argParser.addBaseEntryArg.isPresent())
@@ -802,98 +824,83 @@
      dataOptions = NewSuffixOptions.createEmpty(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;
  private void setSecurityData(UserData uData, List<LocalizableMessage> errorMessages)
  {
    final boolean enableSSL = argParser.ldapsPortArg.isPresent();
    int sslPort = -1;
    try
    {
      ldapsPort = enableSSL ? argParser.ldapsPortArg.getIntValue() : -1;
      sslPort = enableSSL ? argParser.ldapsPortArg.getIntValue() : -1;
    }
    catch (ArgumentException ae)
    catch (final ArgumentException ae)
    {
      errorMessages.add(ae.getMessageObject());
    }
    if (enableSSL && !argParser.skipPortCheckArg.isPresent())
    {
      checkCanUsePort(ldapsPort, errorMessages);
      checkCanUsePort(sslPort, errorMessages);
    }
    SecurityOptions securityOptions;
    LinkedList<String> keystoreAliases = new LinkedList<String>();
    checkCertificate(sslPort, enableSSL, uData, errorMessages);
    uData.setEnableWindowsService(argParser.enableWindowsServiceArg.isPresent());
    uData.setStartServer(!argParser.doNotStartArg.isPresent());
  }
  private void checkCertificate(int sslPort, boolean enableSSL, UserData uData, List<LocalizableMessage> errorMessages)
  {
    final LinkedList<String> keystoreAliases = new LinkedList<String>();
    uData.setHostName(argParser.hostNameArg.getValue());
    final boolean enableStartTLS = argParser.enableStartTLSArg.isPresent();
    final String pwd = argParser.getKeyStorePassword();
    SecurityOptions.CertificateType certType = null;
    String pathToCertificat = null;
    if (argParser.generateSelfSignedCertificateArg.isPresent())
    {
      securityOptions = SecurityOptions.createSelfSignedCertificateOptions(
          enableSSL, enableStartTLS, ldapsPort);
      certType = SecurityOptions.CertificateType.SELF_SIGNED_CERTIFICATE;
    }
    else if (argParser.useJavaKeyStoreArg.isPresent())
    {
      String path = argParser.useJavaKeyStoreArg.getValue();
      checkCertificateInKeystore(SecurityOptions.CertificateType.JKS, path, pwd,
          certNickname, errorMessages, keystoreAliases);
      if (certNickname == null && !keystoreAliases.isEmpty())
      {
        certNickname = keystoreAliases.getFirst();
      }
      securityOptions = SecurityOptions.createJKSCertificateOptions(
          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
      certType = SecurityOptions.CertificateType.JKS;
      pathToCertificat = argParser.useJavaKeyStoreArg.getValue();
    }
    else if (argParser.useJCEKSArg.isPresent())
    {
      String path = argParser.useJCEKSArg.getValue();
      checkCertificateInKeystore(SecurityOptions.CertificateType.JCEKS, path,
          pwd, certNickname, errorMessages, keystoreAliases);
      if (certNickname == null && !keystoreAliases.isEmpty())
      {
        certNickname = keystoreAliases.getFirst();
      }
      securityOptions = SecurityOptions.createJCEKSCertificateOptions(
          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);
      if (certNickname == null && !keystoreAliases.isEmpty())
      {
        certNickname = keystoreAliases.getFirst();
      }
      securityOptions = SecurityOptions.createPKCS12CertificateOptions(
          path, pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
      certType = SecurityOptions.CertificateType.JCEKS;
      pathToCertificat = argParser.useJCEKSArg.getValue();
    }
    else if (argParser.usePkcs11Arg.isPresent())
    {
      checkCertificateInKeystore(SecurityOptions.CertificateType.PKCS11, null,
          pwd, certNickname, errorMessages, keystoreAliases);
      certType = SecurityOptions.CertificateType.PKCS11;
      pathToCertificat = argParser.usePkcs11Arg.getValue();
    }
    else if (argParser.usePkcs12Arg.isPresent())
    {
      certType = SecurityOptions.CertificateType.PKCS12;
      pathToCertificat = argParser.usePkcs12Arg.getValue();
    }
    else
    {
      certType = SecurityOptions.CertificateType.NO_CERTIFICATE;
    }
    String certNickname = argParser.certNicknameArg.getValue();
    if (pathToCertificat != null)
    {
      checkCertificateInKeystore(certType, pathToCertificat, pwd, certNickname, errorMessages, keystoreAliases);
      if (certNickname == null && !keystoreAliases.isEmpty())
      {
        certNickname = keystoreAliases.getFirst();
      }
      securityOptions = SecurityOptions.createPKCS11CertificateOptions(
          pwd, enableSSL, enableStartTLS, ldapsPort, certNickname);
    }
    else
    {
      securityOptions = SecurityOptions.createNoCertificateOptions();
    }
    final SecurityOptions securityOptions = SecurityOptions.createOptionsForCertificatType(
        certType, pathToCertificat, pwd, enableSSL, enableStartTLS, sslPort, certNickname);
    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()));
    }
  }
  private void checkCanUsePort(int port, List<LocalizableMessage> errorMessages)
@@ -918,10 +925,14 @@
   * 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.
   * @throws UserDataException if the user did not manage to provide the
   * keystore password after a certain number of tries.
   * @throws ClientException if something went wrong when reading inputs.
   *
   * @param uData
   *          the UserData object to be updated.
   * @throws UserDataException
   *           if the user did not manage to provide the keystore password after
   *           a certain number of tries.
   * @throws ClientException
   *           if something went wrong when reading inputs.
   */
  private void promptIfRequired(UserData uData) throws UserDataException, ClientException
  {
@@ -939,17 +950,21 @@
  /**
   * 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.
   * @throws UserDataException if something went wrong checking the data.
   * @throws ClientException if something went wrong checking passwords.
   * 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.
   * @throws UserDataException
   *           if something went wrong checking the data.
   * @throws ClientException
   *           if something went wrong checking passwords.
   */
  private void promptIfRequiredForDirectoryManager(UserData uData)
  throws UserDataException, ClientException
      throws UserDataException, ClientException
  {
    LinkedList<String> dns = promptIfRequiredForDNs(
    final LinkedList<String> dns = promptIfRequiredForDNs(
        argParser.directoryManagerDNArg, INFO_INSTALLDS_PROMPT_ROOT_DN.get(),
        true);
    uData.setDirectoryManagerDn(dns.getFirst());
@@ -960,8 +975,7 @@
    {
      if (nTries >= CONFIRMATION_MAX_TRIES)
      {
        throw new UserDataException(null,
            ERR_TRIES_LIMIT_REACHED.get(CONFIRMATION_MAX_TRIES));
        throw new UserDataException(null, ERR_TRIES_LIMIT_REACHED.get(CONFIRMATION_MAX_TRIES));
      }
      char[] pwd1 = null;
@@ -978,7 +992,7 @@
        }
      }
      char[] pwd2 = readPassword(INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get());
      final char[] pwd2 = readPassword(INFO_INSTALLDS_PROMPT_CONFIRM_ROOT_PASSWORD.get());
      if (Arrays.equals(pwd1, pwd2))
      {
        pwd = String.valueOf(pwd1);
@@ -1008,7 +1022,7 @@
  private LinkedList<String> promptIfRequiredForDNs(StringArgument arg,
      LocalizableMessage promptMsg, boolean includeLineBreak) throws UserDataException
  {
    LinkedList<String> dns = new LinkedList<String>();
    final LinkedList<String> dns = new LinkedList<String>();
    boolean usedProvided = false;
    boolean firstPrompt = true;
@@ -1029,12 +1043,12 @@
        }
        try
        {
          String dn = readInput(promptMsg, arg.getDefaultValue());
          final String dn = readInput(promptMsg, arg.getDefaultValue());
          firstPrompt = false;
          dns.add(dn);
          prompted = true;
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        }
@@ -1044,8 +1058,8 @@
        dns.addAll(arg.getValues());
        usedProvided = true;
      }
      List<String> toRemove = new LinkedList<String>();
      for (String dn : dns)
      final List<String> toRemove = new LinkedList<String>();
      for (final String dn : dns)
      {
        try
        {
@@ -1056,10 +1070,10 @@
            println(ERR_INSTALLDS_EMPTY_DN_RESPONSE.get());
          }
        }
        catch (Exception e)
        catch (final Exception e)
        {
          toRemove.add(dn);
          LocalizableMessage message = prompted ? ERR_INSTALLDS_INVALID_DN_RESPONSE.get() :
          final LocalizableMessage message = prompted ? ERR_INSTALLDS_INVALID_DN_RESPONSE.get() :
            ERR_INSTALLDS_CANNOT_PARSE_DN.get(dn, e.getMessage());
          println(message);
        }
@@ -1087,15 +1101,15 @@
  {
    uData.setHostName(promptForHostNameIfRequired());
    List<Integer> usedPorts = new LinkedList<Integer>();
    final List<Integer> usedPorts = new LinkedList<Integer>();
    //  Determine the LDAP port number.
    int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
    final int ldapPort = promptIfRequiredForPortData(argParser.ldapPortArg,
        INFO_INSTALLDS_PROMPT_LDAPPORT.get(), usedPorts, true);
    uData.setServerPort(ldapPort);
    usedPorts.add(ldapPort);
    //  Determine the Admin Connector port number.
    int adminConnectorPort =
    final int adminConnectorPort =
      promptIfRequiredForPortData(argParser.adminConnectorPortArg,
        INFO_INSTALLDS_PROMPT_ADMINCONNECTORPORT.get(), usedPorts, true);
    uData.setAdminConnectorPort(adminConnectorPort);
@@ -1103,7 +1117,7 @@
    if (argParser.jmxPortArg.isPresent())
    {
      int jmxPort = promptIfRequiredForPortData(argParser.jmxPortArg,
      final int jmxPort = promptIfRequiredForPortData(argParser.jmxPortArg,
          INFO_INSTALLDS_PROMPT_JMXPORT.get(), usedPorts, true);
      uData.setServerJMXPort(jmxPort);
    }
@@ -1155,7 +1169,7 @@
            {
              portNumber = readPort(promptMsg, defaultValue);
            }
            catch (ClientException ce)
            catch (final ClientException ce)
            {
              portNumber = -1;
              logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -1173,7 +1187,7 @@
        if (!argParser.skipPortCheckArg.isPresent()
            && !SetupUtils.canUseAsPort(portNumber))
        {
          LocalizableMessage message = getCannotBindErrorMessage(portNumber);
          final LocalizableMessage message = getCannotBindErrorMessage(portNumber);
          if (prompted || includeLineBreak)
          {
            println();
@@ -1192,7 +1206,7 @@
          portNumber = -1;
        }
      }
      catch (ArgumentException ae)
      catch (final ArgumentException ae)
      {
        println(ae.getMessageObject());
      }
@@ -1222,7 +1236,7 @@
        prompt = confirmAction(INFO_INSTALLDS_PROVIDE_BASE_DN_PROMPT.get(),
            true);
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        prompt = true;
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -1231,13 +1245,13 @@
    NewSuffixOptions dataOptions;
    if (!prompt)
    {
      List<String> baseDNs = new LinkedList<String>();
      final List<String> baseDNs = new LinkedList<String>();
      dataOptions = NewSuffixOptions.createEmpty(baseDNs);
    }
    else
    {
      // Check the validity of the base DNs
      List<String> baseDNs = promptIfRequiredForDNs(
      final List<String> baseDNs = promptIfRequiredForDNs(
          argParser.baseDNArg, INFO_INSTALLDS_PROMPT_BASEDN.get(), true);
      dataOptions = promptIfRequiredForDataOptions(baseDNs);
    }
@@ -1250,9 +1264,9 @@
    if (argParser.importLDIFArg.isPresent())
    {
      // Check that the files exist
      List<String> nonExistingFiles = new LinkedList<String>();
      List<String> importLDIFFiles = new LinkedList<String>();
      for (String file : argParser.importLDIFArg.getValues())
      final List<String> nonExistingFiles = new LinkedList<String>();
      final List<String> importLDIFFiles = new LinkedList<String>();
      for (final String file : argParser.importLDIFArg.getValues())
      {
        if (!Utils.fileExists(file))
        {
@@ -1273,7 +1287,7 @@
        println();
        try
        {
          String path = readInput(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
          final String path = readInput(INFO_INSTALLDS_PROMPT_IMPORT_FILE.get(),
              lastResetImportFile);
          if (!Utils.fileExists(path))
          {
@@ -1285,7 +1299,7 @@
            importLDIFFiles.add(path);
          }
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        }
@@ -1304,7 +1318,7 @@
              readInput(INFO_INSTALLDS_PROMPT_REJECTED_FILE.get(),
                  lastResetRejectedFile);
          }
          catch (ClientException ce)
          catch (final ClientException ce)
          {
            logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
          }
@@ -1324,7 +1338,7 @@
              readInput(INFO_INSTALLDS_PROMPT_SKIPPED_FILE.get(),
                  lastResetSkippedFile);
          }
          catch (ClientException ce)
          catch (final ClientException ce)
          {
            logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
          }
@@ -1345,11 +1359,11 @@
      {
        numUsers = argParser.sampleDataArg.getIntValue();
      }
      catch (ArgumentException ae)
      catch (final ArgumentException ae)
      {
        println();
        println(ae.getMessageObject());
        LocalizableMessage message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        final LocalizableMessage message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        numUsers = promptForInteger(message, 2000, 0, Integer.MAX_VALUE);
      }
      dataOptions = NewSuffixOptions.createAutomaticallyGenerated(baseDNs,
@@ -1362,16 +1376,16 @@
      final int POPULATE_TYPE_IMPORT_FROM_LDIF = 3;
      final int POPULATE_TYPE_GENERATE_SAMPLE_DATA = 4;
      int[] indexes = {POPULATE_TYPE_BASE_ONLY, POPULATE_TYPE_LEAVE_EMPTY,
      final int[] indexes = {POPULATE_TYPE_BASE_ONLY, POPULATE_TYPE_LEAVE_EMPTY,
          POPULATE_TYPE_IMPORT_FROM_LDIF, POPULATE_TYPE_GENERATE_SAMPLE_DATA};
      LocalizableMessage[] msgs = new LocalizableMessage[] {
      final LocalizableMessage[] msgs = new LocalizableMessage[] {
          INFO_INSTALLDS_POPULATE_OPTION_BASE_ONLY.get(),
          INFO_INSTALLDS_POPULATE_OPTION_LEAVE_EMPTY.get(),
          INFO_INSTALLDS_POPULATE_OPTION_IMPORT_LDIF.get(),
          INFO_INSTALLDS_POPULATE_OPTION_GENERATE_SAMPLE.get()
      };
      MenuBuilder<Integer> builder = new MenuBuilder<Integer>(this);
      final MenuBuilder<Integer> builder = new MenuBuilder<Integer>(this);
      builder.setPrompt(INFO_INSTALLDS_HEADER_POPULATE_TYPE.get());
      for (int i=0; i<indexes.length; i++)
@@ -1411,11 +1425,11 @@
        }
      }
      Menu<Integer> menu = builder.toMenu();
      final Menu<Integer> menu = builder.toMenu();
      int populateType;
      try
      {
        MenuResult<Integer> m = menu.run();
        final MenuResult<Integer> m = menu.run();
        if (m.isSuccess())
        {
          populateType = m.getValue();
@@ -1426,7 +1440,7 @@
          throw new RuntimeException();
        }
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        populateType = POPULATE_TYPE_BASE_ONLY;
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -1434,14 +1448,14 @@
      if (populateType == POPULATE_TYPE_IMPORT_FROM_LDIF)
      {
        List<String> importLDIFFiles = new LinkedList<String>();
        final List<String> importLDIFFiles = new LinkedList<String>();
        while (importLDIFFiles.isEmpty())
        {
          LocalizableMessage message = INFO_INSTALLDS_PROMPT_IMPORT_FILE.get();
          println();
          try
          {
            String path = readInput(message, null);
            final String path = readInput(message, null);
            if (Utils.fileExists(path))
            {
              importLDIFFiles.add(path);
@@ -1453,7 +1467,7 @@
              println(message);
            }
          }
          catch (ClientException ce)
          catch (final ClientException ce)
          {
            logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
          }
@@ -1472,7 +1486,7 @@
              rejectedFile =
                readInput(INFO_INSTALLDS_PROMPT_REJECTED_FILE.get(), null);
            }
            catch (ClientException ce)
            catch (final ClientException ce)
            {
              logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
            }
@@ -1491,7 +1505,7 @@
              skippedFile =
                readInput(INFO_INSTALLDS_PROMPT_SKIPPED_FILE.get(), null);
            }
            catch (ClientException ce)
            catch (final ClientException ce)
            {
              logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
            }
@@ -1502,7 +1516,7 @@
      }
      else if (populateType == POPULATE_TYPE_GENERATE_SAMPLE_DATA)
      {
        LocalizableMessage message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        final LocalizableMessage message = INFO_INSTALLDS_PROMPT_NUM_ENTRIES.get();
        int defaultValue;
        if (lastResetNumEntries != null)
        {
@@ -1512,7 +1526,7 @@
        {
          defaultValue = 2000;
        }
        int numUsers = promptForInteger(message, defaultValue, 0,
        final int numUsers = promptForInteger(message, defaultValue, 0,
            Integer.MAX_VALUE);
        dataOptions = NewSuffixOptions.createAutomaticallyGenerated(baseDNs,
@@ -1556,7 +1570,7 @@
    boolean enableStartTLS = false;
    int ldapsPort = -1;
    List<Integer> usedPorts = new LinkedList<Integer>();
    final List<Integer> usedPorts = new LinkedList<Integer>();
    usedPorts.add(uData.getServerPort());
    if (uData.getServerJMXPort() != -1)
    {
@@ -1569,7 +1583,7 @@
      println();
      try
      {
        boolean defaultValue = lastResetEnableSSL != null ? lastResetEnableSSL :
        final boolean defaultValue = lastResetEnableSSL != null ? lastResetEnableSSL :
          false;
        enableSSL = confirmAction(INFO_INSTALLDS_PROMPT_ENABLE_SSL.get(),
            defaultValue);
@@ -1579,7 +1593,7 @@
              INFO_INSTALLDS_PROMPT_LDAPSPORT.get(), usedPorts, false);
        }
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
      }
@@ -1597,12 +1611,12 @@
      println();
      try
      {
        boolean defaultValue = lastResetEnableStartTLS != null ?
        final boolean defaultValue = lastResetEnableStartTLS != null ?
            lastResetEnableStartTLS : false;
        enableStartTLS = confirmAction(INFO_INSTALLDS_ENABLE_STARTTLS.get(),
            defaultValue);
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
      }
@@ -1655,8 +1669,8 @@
      final int JCEKS = 3;
      final int PKCS12 = 4;
      final int PKCS11 = 5;
      int[] indexes = {SELF_SIGNED, JKS, JCEKS, PKCS12, PKCS11};
      LocalizableMessage[] msgs = {
      final int[] indexes = {SELF_SIGNED, JKS, JCEKS, PKCS12, PKCS11};
      final LocalizableMessage[] msgs = {
          INFO_INSTALLDS_CERT_OPTION_SELF_SIGNED.get(),
          INFO_INSTALLDS_CERT_OPTION_JKS.get(),
          INFO_INSTALLDS_CERT_OPTION_JCEKS.get(),
@@ -1665,7 +1679,7 @@
      };
      MenuBuilder<Integer> builder = new MenuBuilder<Integer>(this);
      final MenuBuilder<Integer> builder = new MenuBuilder<Integer>(this);
      builder.setPrompt(INFO_INSTALLDS_HEADER_CERT_TYPE.get());
      for (int i=0; i<indexes.length; i++)
@@ -1704,11 +1718,11 @@
        }
      }
      Menu<Integer> menu = builder.toMenu();
      final Menu<Integer> menu = builder.toMenu();
      int certType;
      try
      {
        MenuResult<Integer> m = menu.run();
        final MenuResult<Integer> m = menu.run();
        if (m.isSuccess())
        {
          certType = m.getValue();
@@ -1719,7 +1733,7 @@
          throw new RuntimeException();
        }
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        certType = SELF_SIGNED;
@@ -1784,14 +1798,14 @@
      else
      {
        println();
        LocalizableMessage message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
        final LocalizableMessage message = INFO_INSTALLDS_PROMPT_ENABLE_SERVICE.get();
        try
        {
          boolean defaultValue = (lastResetEnableWindowsService == null) ?
          final boolean defaultValue = (lastResetEnableWindowsService == null) ?
              false : lastResetEnableWindowsService;
          enableService = confirmAction(message, defaultValue);
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        }
@@ -1813,14 +1827,14 @@
    if (!argParser.doNotStartArg.isPresent())
    {
      println();
      LocalizableMessage message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
      final LocalizableMessage message = INFO_INSTALLDS_PROMPT_START_SERVER.get();
      try
      {
        boolean defaultValue = (lastResetStartServer == null) ?
        final boolean defaultValue = (lastResetStartServer == null) ?
            true : lastResetStartServer;
        startServer = confirmAction(message, defaultValue);
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        startServer = true;
@@ -1852,7 +1866,7 @@
    boolean errorWithPath = false;
    if (type != SecurityOptions.CertificateType.PKCS11)
    {
      File f = new File(path);
      final File f = new File(path);
      if (!f.exists())
      {
        errorMessages.add(INFO_KEYSTORE_PATH_DOES_NOT_EXIST.get());
@@ -1902,7 +1916,7 @@
          default:
            throw new IllegalArgumentException("Invalid type: "+type);
        }
        String[] aliases = certManager.getCertificateAliases();
        final String[] aliases = certManager.getCertificateAliases();
        if (aliases == null || aliases.length == 0)
        {
          // Could not retrieve any certificate
@@ -1927,7 +1941,7 @@
        else if (certManager.hasRealAliases())
        {
          Collections.addAll(nicknameList, aliases);
          String aliasString = joinAsString(", ", nicknameList);
          final String aliasString = joinAsString(", ", nicknameList);
          if (certNickname != null)
          {
            // Check if the certificate alias is in the list.
@@ -1949,7 +1963,7 @@
          }
        }
      }
      catch (KeyStoreException ke)
      catch (final KeyStoreException ke)
      {
        // issue OPENDJ-18, related to JDK bug
        if (StaticUtils.stackTraceContainsCause(ke, ArithmeticException.class))
@@ -2049,8 +2063,8 @@
      throw new IllegalStateException(
          "Called promptIfRequiredCertificate with invalid type: "+type);
    }
    List<LocalizableMessage> errorMessages = new LinkedList<LocalizableMessage>();
    LinkedList<String> keystoreAliases = new LinkedList<String>();
    final List<LocalizableMessage> errorMessages = new LinkedList<LocalizableMessage>();
    final LinkedList<String> keystoreAliases = new LinkedList<String>();
    boolean firstTry = true;
    int nPasswordPrompts = 0;
@@ -2072,7 +2086,7 @@
        {
          path = readInput(pathPrompt, defaultPathValue);
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          path = "";
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -2164,7 +2178,7 @@
      Collection<LocalizableMessage> msgs)
  {
    boolean found = false;
    for (LocalizableMessage msg : msgs)
    for (final LocalizableMessage msg : msgs)
    {
      if (StaticUtils.hasDescriptor(msg, INFO_KEYSTORE_PATH_DOES_NOT_EXIST) ||
          StaticUtils.hasDescriptor(msg, INFO_KEYSTORE_PATH_NOT_A_FILE) ||
@@ -2195,7 +2209,7 @@
      Collection<LocalizableMessage> msgs)
  {
    boolean found = false;
    for (LocalizableMessage msg : msgs)
    for (final LocalizableMessage msg : msgs)
    {
      if (StaticUtils.hasDescriptor(msg, INFO_JKS_KEYSTORE_DOES_NOT_EXIST) ||
          StaticUtils.hasDescriptor(msg, INFO_JCEKS_KEYSTORE_DOES_NOT_EXIST) ||
@@ -2226,7 +2240,7 @@
      Collection<LocalizableMessage> msgs)
  {
    boolean found = false;
    for (LocalizableMessage msg : msgs)
    for (final LocalizableMessage msg : msgs)
    {
      if (StaticUtils.hasDescriptor(msg, ERR_INSTALLDS_CERTNICKNAME_NOT_FOUND) ||
          StaticUtils.hasDescriptor(msg, ERR_INSTALLDS_MUST_PROVIDE_CERTNICKNAME))
@@ -2239,18 +2253,6 @@
  }
  /**
   * Tells if the error messages provided corresponds to a problem with the
   * password tries.
   * @param msg the message to analyze.
   * @return <CODE>true</CODE> if the error message provided corresponds to a
   * problem with the password tries and <CODE>false</CODE> otherwise.
   */
  private boolean isPasswordTriesError(LocalizableMessage msg)
  {
    return StaticUtils.hasDescriptor(msg, ERR_INSTALLDS_TOO_MANY_KEYSTORE_PASSWORD_TRIES);
  }
  /**
   * Interactively prompts (on standard output) the user to provide an integer
   * value.  The answer provided must be parseable as an integer, and may be
   * required to be within a given set of bounds.  It will keep prompting until
@@ -2279,7 +2281,7 @@
      {
        s = readInput(prompt, String.valueOf(defaultValue));
      }
      catch (ClientException ce)
      catch (final ClientException ce)
      {
        s = "";
        logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -2300,7 +2302,7 @@
      {
        try
        {
          int intValue = Integer.parseInt(s);
          final int intValue = Integer.parseInt(s);
          if (lowerBound != null && intValue < lowerBound)
          {
            println(ERR_INSTALLDS_INTEGER_BELOW_LOWER_BOUND.get(lowerBound));
@@ -2316,7 +2318,7 @@
            returnValue = intValue;
          }
        }
        catch (NumberFormatException nfe)
        catch (final NumberFormatException nfe)
        {
          println(ERR_INSTALLDS_INVALID_INTEGER_RESPONSE.get());
          println();
@@ -2337,7 +2339,7 @@
    String nickname = null;
    while (nickname == null)
    {
      for (String n : nicknames)
      for (final String n : nicknames)
      {
        try
        {
@@ -2347,7 +2349,7 @@
            break;
          }
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        }
@@ -2365,7 +2367,7 @@
    println();
    println();
    println(INFO_INSTALLDS_SUMMARY.get());
    LocalizableMessage[] labels =
    final LocalizableMessage[] labels =
    {
        INFO_SERVER_PORT_LABEL.get(),
        INFO_ADMIN_CONNECTOR_PORT_LABEL.get(),
@@ -2375,9 +2377,9 @@
        INFO_DIRECTORY_DATA_LABEL.get()
    };
    int jmxPort = uData.getServerJMXPort();
    final int jmxPort = uData.getServerJMXPort();
    LocalizableMessage[] values =
    final LocalizableMessage[] values =
    {
        LocalizableMessage.raw(String.valueOf(uData.getServerPort())),
        LocalizableMessage.raw(String.valueOf(uData.getAdminConnectorPort())),
@@ -2388,7 +2390,7 @@
        LocalizableMessage.raw(Utils.getDataDisplayString(uData)),
    };
    int maxWidth = 0;
    for (LocalizableMessage l : labels)
    for (final LocalizableMessage l : labels)
    {
      maxWidth = Math.max(maxWidth, l.length());
    }
@@ -2398,10 +2400,10 @@
      StringBuilder sb = new StringBuilder();
      if (values[i] != null)
      {
        LocalizableMessage l = labels[i];
        final LocalizableMessage l = labels[i];
        sb.append(l).append(" ");
        String[] lines = values[i].toString().split(Constants.LINE_SEPARATOR);
        final String[] lines = values[i].toString().split(Constants.LINE_SEPARATOR);
        for (int j=0; j<lines.length; j++)
        {
          if (j != 0)
@@ -2454,7 +2456,7 @@
    println(INFO_INSTALL_SETUP_EQUIVALENT_COMMAND_LINE.get());
    println();
    ArrayList<String> cmd = Utils.getSetupEquivalentCommandLine(uData);
    final ArrayList<String> cmd = Utils.getSetupEquivalentCommandLine(uData);
    println(LocalizableMessage.raw(
        Utils.getFormattedEquivalentCommandLine(cmd, formatter)));
  }
@@ -2473,18 +2475,18 @@
    println();
    println();
    LocalizableMessage[] msgs = new LocalizableMessage[] {
    final LocalizableMessage[] msgs = new LocalizableMessage[] {
        INFO_INSTALLDS_CONFIRM_INSTALL.get(),
        INFO_INSTALLDS_PROVIDE_DATA_AGAIN.get(),
        INFO_INSTALLDS_PRINT_EQUIVALENT_COMMAND_LINE.get(),
        INFO_INSTALLDS_CANCEL.get()
      };
    MenuBuilder<ConfirmCode> builder = new MenuBuilder<ConfirmCode>(this);
    final MenuBuilder<ConfirmCode> builder = new MenuBuilder<ConfirmCode>(this);
    builder.setPrompt(INFO_INSTALLDS_CONFIRM_INSTALL_PROMPT.get());
    int i=0;
    for (ConfirmCode code : ConfirmCode.values())
    for (final ConfirmCode code : ConfirmCode.values())
    {
      builder.addNumberedOption(msgs[i], MenuResult.success(code));
      i++;
@@ -2494,11 +2496,11 @@
            String.valueOf(ConfirmCode.CONTINUE.getReturnCode())),
            MenuResult.success(ConfirmCode.CONTINUE));
    Menu<ConfirmCode> menu = builder.toMenu();
    final Menu<ConfirmCode> menu = builder.toMenu();
    try
    {
      MenuResult<ConfirmCode> m = menu.run();
      final MenuResult<ConfirmCode> m = menu.run();
      if (m.isSuccess())
      {
        returnValue = m.getValue();
@@ -2509,7 +2511,7 @@
        throw new RuntimeException();
      }
    }
    catch (ClientException ce)
    catch (final ClientException ce)
    {
      returnValue = ConfirmCode.CANCEL;
      logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
@@ -2529,17 +2531,17 @@
          String.valueOf(uData.getServerPort()));
      argParser.adminConnectorPortArg.setDefaultValue(
          String.valueOf(uData.getAdminConnectorPort()));
      int jmxPort = uData.getServerJMXPort();
      final int jmxPort = uData.getServerJMXPort();
      if (jmxPort != -1)
      {
        argParser.jmxPortArg.setDefaultValue(String.valueOf(jmxPort));
      }
      LinkedList<String> baseDNs = uData.getNewSuffixOptions().getBaseDns();
      final LinkedList<String> baseDNs = uData.getNewSuffixOptions().getBaseDns();
      if (!baseDNs.isEmpty())
      {
        argParser.baseDNArg.setDefaultValue(baseDNs.getFirst());
      }
      NewSuffixOptions suffixOptions = uData.getNewSuffixOptions();
      final NewSuffixOptions suffixOptions = uData.getNewSuffixOptions();
      lastResetPopulateOption = suffixOptions.getType();
      if (lastResetPopulateOption ==
        NewSuffixOptions.Type.IMPORT_AUTOMATICALLY_GENERATED_DATA)
@@ -2553,7 +2555,7 @@
        lastResetRejectedFile = suffixOptions.getRejectedFile();
        lastResetSkippedFile = suffixOptions.getSkippedFile();
      }
      SecurityOptions sec = uData.getSecurityOptions();
      final SecurityOptions sec = uData.getSecurityOptions();
      if (sec.getEnableSSL())
      {
        argParser.ldapsPortArg.setDefaultValue(
@@ -2576,7 +2578,7 @@
      lastResetEnableWindowsService = uData.getEnableWindowsService();
      lastResetStartServer = uData.getStartServer();
    }
    catch (Throwable t)
    catch (final Throwable t)
    {
      logger.warn(LocalizableMessage.raw("Error resetting arguments: "+t, t));
    }
@@ -2599,7 +2601,7 @@
          hostName = readInput(INFO_INSTALLDS_PROMPT_HOST_NAME.get(),
              argParser.hostNameArg.getDefaultValue());
        }
        catch (ClientException ce)
        catch (final ClientException ce)
        {
          logger.warn(LocalizableMessage.raw("Error reading input: "+ce, ce));
        }