private void install() 
  throws ExInstaller {
    //Establish a SYS connection
    DatabaseConnection lDatabaseConnection;
    try {
      if(!mCommandLineWrapper.hasOption(CommandLineOption.PROMOTE_USER)){
        mCommandLineWrapper.overrideOption(CommandLineOption.PROMOTE_USER, "SYS");
      }
      lDatabaseConnection = DatabaseConnection.createConnection(mCommandLineWrapper, true, false, false);
    }
    catch (ExPromote e) {
      throw new ExInstaller("Failed to connect to database: " + e.getMessage(), e);
    }
    
    //Prompt user for promote user name
    String lPromoteUserName = mCommandLineWrapper.getOption(CommandLineOption.INSTALL_PROMOTE_USER);
    lPromoteUserName = XFUtil.nvl(lPromoteUserName, DatabaseConnection.DEFAULT_PROMOTE_USER).toUpperCase();

    String lArgPassword = null;

    if (mCommandLineWrapper.hasOption(CommandLineOption.INSTALL_PROMOTE_PASSWORD)){
      lArgPassword = mCommandLineWrapper.getOption(CommandLineOption.INSTALL_PROMOTE_PASSWORD);
    }
    
    //Create the new promote user
    String lNewPassword = createUser(lDatabaseConnection, lPromoteUserName, lArgPassword);
    
    Logger.logAndEcho("Setting user privileges...");
    
    //Run the initial install patch for issuing grants to the user
    runInstallPatch(lDatabaseConnection, lPromoteUserName, SET_PERMISSIONS_FILE_NAME);
        
    //Close existing connections
    lDatabaseConnection.closePromoteConnection();
    lDatabaseConnection.closeLoggingConnection();
    
    //RECONNECT as the new promote user
    mCommandLineWrapper.overrideOption(CommandLineOption.PROMOTE_USER, lPromoteUserName);
    mCommandLineWrapper.overrideOption(CommandLineOption.PROMOTE_PASSWORD, lNewPassword); 
    //Always use the JDBC string from the previous connection to avoid re-prompting the user for details
    mCommandLineWrapper.overrideOption(CommandLineOption.JDBC_CONNECT_STRING, lDatabaseConnection.getJDBCConnectString());
    try {
      lDatabaseConnection = DatabaseConnection.createConnection(mCommandLineWrapper, false, true, false);
    }
    catch (ExPromote e) {
      throw new ExInstaller("Failed to connect to database: " + e.getMessage(), e);
    }

    Logger.logAndEcho("Creating database objects..."); 
    
    //Run part 2
    PatchScript lInstallPatch = runInstallPatch(lDatabaseConnection, lPromoteUserName, CREATE_OBJECTS_FILE_NAME);
    
    //Log the success in the patch tables we just created
    PromotionController lPromotionController = new PromotionController(lDatabaseConnection, INSTALL_PROMOTION_LABEL);
    PatchRunController lPatchRunController = new PatchRunController(lDatabaseConnection, lPromotionController, lInstallPatch);
    try {
      lPromotionController.startPromote();
      lPatchRunController.validateAndStartPatchRun();
      lPatchRunController.endPatchRun(true);
      lPromotionController.endPromote(true);
    }
    catch (ExPromote e) {
      throw new ExInstaller("Failed to log installation", e);
    }
    catch (SQLException e) {
      throw new ExInstaller("Failed to log installation", e);
    }
        
    Logger.logAndEcho("Migrating legacy patches..."); 
    
    //Migrate patches but do not allow failure to propogate
    try {
      runInstallPatch(lDatabaseConnection, lPromoteUserName, MIGRATE_PATCHES_FILE_NAME);
    }
    catch (Throwable th){
      Logger.logAndEcho("Migration of legacy patches failed; see log for details");
      Logger.logError(th);
    }
    
    lDatabaseConnection.closePromoteConnection();
    lDatabaseConnection.closeLoggingConnection();    
  }