docs: public static void generate(String args[], String preferences, Properties inputProps) throws Exception {
          String base;
          base = inputProps.getProperty("rdeck.base");
          if ((null == ENV_JAVA_HOME || "".equals(ENV_JAVA_HOME)) && (null == JAVA_HOME || "".equals(JAVA_HOME))){
              throw new Exception("property: java.home, not defined");
          }
          if(null==base) {
              base = SYSTEM_RDECK_BASE;
          }
          if (null == base || "".equals(base))
              throw new Exception("property: rdeck.base, not defined");
  
          File baseDir = new File(base);
          if (!baseDir.isDirectory()) {
              if (baseDir.exists()) {
                  throw new Exception(base + " exists and is not a directory");
              }
              if (!baseDir.mkdirs()) {
                  throw new Exception(base + " does not exist and cannot be created");
              }
          }
  
          // the properties used to generate the preferences.properties file
          Properties systemProperties = System.getProperties();
          Properties defaultProperties = new Properties();
  
          //
          // bootstrap the rdeck.base, ant.home, and java.home
          //
          String jhome = ENV_JAVA_HOME;
          if(null==jhome) {
              jhome = JAVA_HOME;
          }
          defaultProperties.setProperty("user.java_home", forwardSlashPath(jhome));
          defaultProperties.setProperty("user.java_home.win", backSlashPath(jhome));
          defaultProperties.setProperty("java.home", forwardSlashPath(jhome));
          defaultProperties.setProperty("java.home.win", backSlashPath(jhome));
          defaultProperties.setProperty("rdeck.base", forwardSlashPath(base));
          defaultProperties.setProperty("rdeck.base.win", backSlashPath(base));
  
          //
          // additional properties needed for successful rdeck setup, based on above
          // bootstrapping properties
          //
          defaultProperties.setProperty("framework.projects.dir", forwardSlashPath(Constants.getFrameworkProjectsDir(
              base)));
          defaultProperties.setProperty("framework.projects.dir.win", backSlashPath(Constants.getFrameworkProjectsDir(
              base)));
          defaultProperties.setProperty("framework.rdeck.base", forwardSlashPath(base));
          defaultProperties.setProperty("framework.rdeck.base.win", backSlashPath(base));
          final String configDir = Constants.getFrameworkConfigDir(base);
          defaultProperties.setProperty("framework.etc.dir", forwardSlashPath(configDir));
          defaultProperties.setProperty("framework.etc.dir.win", backSlashPath(configDir));
          defaultProperties.setProperty("framework.var.dir", forwardSlashPath(Constants.getBaseVar(base)));
          defaultProperties.setProperty("framework.var.dir.win", backSlashPath(Constants.getBaseVar(base)));
          defaultProperties.setProperty("framework.logs.dir", forwardSlashPath(Constants.getFrameworkLogsDir(base)));
          defaultProperties.setProperty("framework.logs.dir.win", backSlashPath(Constants.getFrameworkLogsDir(base)));
  
          Enumeration propEnum = systemProperties.propertyNames();
          //list of path properties to convert slashes on
          HashSet<String> paths=new HashSet<String>();
          paths.add("user.home");
          while (propEnum.hasMoreElements()) {
              String propName = (String) propEnum.nextElement();
              String propType = propName.split("\\.")[0];
              String value = systemProperties.getProperty(propName);
              if(paths.contains(propName)) {
                  value = forwardSlashPath(value);
              }
              defaultProperties.setProperty(propName, value);
          }
  
          // load the default properties
          loadResourcesDefaults(defaultProperties, RUNDECK_DEFAULTS_PROPERTIES_NAME);
          defaultProperties.putAll(inputProps);
          parseNonReqOptionsAsProperties(defaultProperties, args);
  
          // expand all keyValues within defaultProperties against keys within same defaultProperties
          // and return new expandedDefaultProperties
          Properties expandedDefaultProperties = PropertyUtil.expand(defaultProperties);
  
          // parse any --<framework|modules>-<property>-<name>=&lt;value&gt; as
          // <framework|modules>.<property>.<name>=&lt;value&gt; and ensure it is a valid property
  
          // ensure ${rdeck_base}/etc exists
          File rdeck_base_etc = new File(configDir);
          if (!rdeck_base_etc.isDirectory()) {
              if (!rdeck_base_etc.mkdir()) {
                  throw new Exception("Unable to create directory: " + configDir);
              }
          }
  
          // generate the preferences.properties file into ${rdeck.base}/etc from expandedDefaultProperties
          final FileOutputStream fileOutputStream = new FileOutputStream(preferences);
          try {
              expandedDefaultProperties.store(fileOutputStream, "rdeck setup preferences");
          } finally {
              fileOutputStream.close();
          }
  
      }