/**
   * Parse and validate the cli arguments
   *
   * @param ln parsed command line
   * @return parsed cli parameters wrapped in the CliParams
   * @throws InvalidArgumentException in case of nonexistent or incorrect cli args
   */
  protected CliParams parse(CommandLine ln, Properties defaults) throws InvalidArgumentException {
    l.debug("Parsing cli " + ln);
    CliParams cp = new CliParams();

    for (Option o : mandatoryOptions) {
      String name = o.getLongOpt();
      if (ln.hasOption(name)) cp.put(name, ln.getOptionValue(name));
      else if (defaults.getProperty(name) != null) {
        cp.put(name, defaults.getProperty(name));
      } else {
        throw new InvalidArgumentException("Missing the '" + name + "' commandline parameter.");
      }
    }

    for (Option o : optionalOptions) {
      String name = o.getLongOpt();
      if (ln.hasOption(name)) {
        cp.put(name, ln.getOptionValue(name));
      } else if (defaults.getProperty(name) != null) {
        cp.put(name, defaults.getProperty(name));
      }
    }

    if (cp.containsKey(CLI_PARAM_VERSION[0])) {
      l.info(
          "GoodData Notification Tool version 1.2.45"
              + ((BUILD_NUMBER.length() > 0) ? ", build " + BUILD_NUMBER : "."));
      System.exit(0);
    }

    // use default host if there is no host in the CLI params
    if (!cp.containsKey(CLI_PARAM_GDC_HOST[0])) {
      cp.put(CLI_PARAM_GDC_HOST[0], Defaults.DEFAULT_HOST);
    }

    l.debug("Using host " + cp.get(CLI_PARAM_GDC_HOST[0]));

    if (ln.getArgs().length == 0) {
      throw new InvalidArgumentException("No config file has been given, quitting.");
    }

    String configs = "";
    for (final String arg : ln.getArgs()) {
      if (configs.length() > 0) configs += "," + arg;
      else configs += arg;
    }
    cp.put(CLI_PARAM_CONFIG, configs);

    return cp;
  }
 /**
  * Loads default values of common parameters from a properties file searching the working
  * directory and user's home.
  *
  * @return default configuration
  */
 private static Properties loadDefaults() {
   final String[] dirs = new String[] {"user.dir", "user.home"};
   final Properties props = new Properties();
   for (final String d : dirs) {
     String path = System.getProperty(d) + File.separator + DEFAULT_PROPERTIES;
     File f = new File(path);
     if (f.exists() && f.canRead()) {
       try {
         FileInputStream is = new FileInputStream(f);
         props.load(is);
         l.debug("Successfully red the gdi configuration from '" + f.getAbsolutePath() + "'.");
         return props;
       } catch (IOException e) {
         l.warn(
             "Readable gdi configuration '"
                 + f.getAbsolutePath()
                 + "' found be error occurred reading it.");
         l.debug("Error reading gdi configuration '" + f.getAbsolutePath() + "': ", e);
       }
     }
   }
   return props;
 }