function OptionParser() {

  /** @type {string} */
  var usage = OptionParser.DEFAULT_USAGE;

  /** @type {boolean} */
  var mustParse = true;

  /** @type {!Object.<*>} */
  var parsedOptions = {};

  /** @type {!Array.<string>} */
  var extraArgs = [];

  /**
   * Sets the usage string. All occurences of "$0" will be replaced with the
   * current executable's name.
   * @param {string} usageStr The new usage string.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.usage = function(usageStr) {
    mustParse = true;
    usage = usageStr;
    return this;
  };

  /**
   * @type {!Object.<{
   *   help: string,
   *   parse: function(string): *,
   *   required: boolean,
   *   list: boolean,
   *   callback: function(*),
   *   default: *
   * }>}
   */
  var options = {};

  /**
   * Adds a new option to this parser.
   * @param {string} name The name of the option.
   * @param {function(string): *} parseFn The function to use for parsing the
   *     option. If this function has a "default" property, it will be used as
   *     the default value for the option if it was not provided on the command
   *     line. If not specified, the default value will be undefined. The
   *     default value may be overrideden using the "default" property in the
   *     option spec.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.addOption = function(name, parseFn, opt_spec) {
    checkOptionName(name, options);
    var spec = opt_spec || {};

    // Quoted notation for "default" to bypass annoying IDE syntax bug.
    var defaultValue = spec['default'] ||
        (!!spec.list ? [] : parseFn['default']);

    options[name] = {
      help: spec.help || '',
      parse: parseFn,
      required: !!spec.required,
      list: !!spec.list,
      callback: spec.callback || function() {},
      'default': defaultValue
    };
    mustParse = true;
    return this;
  };

  /**
   * Defines a boolean option. Option values may be one of {'', 'true', 'false',
   * '0', '1'}. In the case of the empty string (''), the option value will be
   * set to true.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
  */
  this.boolean = function(name, opt_spec) {
    return this.addOption(name, parseBoolean, opt_spec);
  };

  /**
   * Defines a numeric option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.number = function(name, opt_spec) {
    return this.addOption(name, parseNumber, opt_spec);
  };

  /**
   * Defines a path option. Each path will be resolved relative to the
   * current workin directory, if not absolute.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.path = function(name, opt_spec) {
    return this.addOption(name, path.resolve, opt_spec);
  };

  /**
   * Defines a basic string option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.string = function(name, opt_spec) {
    return this.addOption(name, parseString, opt_spec);
  };

  /**
   * Defines a regular expression based option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.regex = function(name, opt_spec) {
    return this.addOption(name, parseRegex, opt_spec);
  };

  /**
   * Returns the parsed command line options.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Object.<*>} The parsed options.
   */
  this.__defineGetter__('options', function() {
    parse();
    return parsedOptions;
  });

  /**
   * Returns the remaining command line arguments after all options have been
   * parsed.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Array.<string>} The remaining command line arguments.
   */
  this.__defineGetter__('argv', function() {
    parse();
    return extraArgs;
  });

  /**
   * Parses a list of arguments. After parsing, the options property of this
   * object will contain the value for each parsed flags, and the argv
   * property will contain all remaining command line arguments.
   * @throws {Error} If the arguments could not be parsed.
   */
  this.parse = parse;

  /**
   * Returns a formatted help message for this parser.
   * @return {string} The help message for this parser.
   */
  this.getHelpMsg = getHelpMsg;

  function getHelpMsg() {
    return formatHelpMsg(usage, options);
  }

  function parse() {
    if (!mustParse) {
      return;
    }

    parsedOptions = {};
    extraArgs = [];

    var args = process.argv.slice(2);
    var n = args.length;

    try {
      for (var i = 0; i < n; ++i) {
        var arg = args[i];
        if (arg === '--') {
          extraArgs = args.slice(i + 1);
          break;
        }

        var match = arg.match(OPTION_FLAG_REGEX);
        if (match) {
          // Special case --help.
          if (match[1] === 'help') {
            printHelpAndDie('', 0);
          }
          parseOption(match);
        } else {
          extraArgs = args.slice(i + 1);
          break;
        }
      }
    } catch (ex) {
      printHelpAndDie(ex.message, 1);
    }

    for (var name in options) {
      var option = options[name];
      if (!(name in parsedOptions)) {
        if (option.required) {
          printHelpAndDie('Missing required option: --' + name, 1);
        }
        parsedOptions[name] = option.list ? [] : option['default'];
      }
    }

    mustParse = false;
  }

  function printHelpAndDie(errorMessage, exitCode) {
    process.stdout.write(errorMessage + '\n');
    process.stdout.write(getHelpMsg());
    process.exit(exitCode);
  }

  function parseOption(match) {
    var option = options[match[1]];
    if (!option) {
      throw Error(JSON.stringify('--' + match[1]) + ' is not a valid option');
    }

    var value = match[2];
    if (typeof value !== 'undefined') {
      value = parseOptionValue(match[1], option, value);
    } else if (option.parse === parseBoolean) {
      value = true;
    } else {
      throw Error('Option ' + JSON.stringify('--' + option.name) +
          'requires an operand');
    }

    option.callback(value);

    if (option.list) {
      var array = parsedOptions[match[1]] || [];
      parsedOptions[match[1]] = array;
      array.push(value);
    } else {
      parsedOptions[match[1]] = value;
    }
  }
}
function OptionParser() {

  /** @type {string} */
  var usage = OptionParser.DEFAULT_USAGE;

  /** @type {boolean} */
  var mustParse = true;

  /** @type {!Object.<*>} */
  var parsedOptions = {};

  /** @type {!Array.<string>} */
  var extraArgs = [];

  /**
   * Sets the usage string. All occurences of "$0" will be replaced with the
   * current executable's name.
   * @param {string} usageStr The new usage string.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.usage = function(usageStr) {
    mustParse = true;
    usage = usageStr;
    return this;
  };

  /**
   * @type {!Object.<{
   *   help: string,
   *   parse: function(string): *,
   *   required: boolean,
   *   list: boolean,
   *   callback: function(*),
   *   default: *
   * }>}
   */
  var options = {};

  /**
   * Adds a new option to this parser.
   * @param {string} name The name of the option.
   * @param {function(string): *} parseFn The function to use for parsing the
   *     option. If this function has a "default" property, it will be used as
   *     the default value for the option if it was not provided on the command
   *     line. If not specified, the default value will be undefined. The
   *     default value may be overrideden using the "default" property in the
   *     option spec.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.addOption = function(name, parseFn, opt_spec) {
    checkOptionName(name, options);
    var spec = opt_spec || {};

    // Quoted notation for "default" to bypass annoying IDE syntax bug.
    var defaultValue = spec['default'] ||
        (!!spec.list ? [] : parseFn['default']);

    options[name] = {
      help: spec.help || '',
      parse: parseFn,
      required: !!spec.required,
      list: !!spec.list,
      callback: spec.callback || function() {},
      'default': defaultValue
    };
    mustParse = true;
    return this;
  };

  /**
   * Defines a boolean option. Option values may be one of {'', 'true', 'false',
   * '0', '1'}. In the case of the empty string (''), the option value will be
   * set to true.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
  */
  this.boolean = function(name, opt_spec) {
    return this.addOption(name, parseBoolean, opt_spec);
  };

  /**
   * Defines a numeric option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.number = function(name, opt_spec) {
    return this.addOption(name, parseNumber, opt_spec);
  };

  /**
   * Defines a path option. Each path will be resolved relative to the
   * current workin directory, if not absolute.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.path = function(name, opt_spec) {
    return this.addOption(name, path.resolve, opt_spec);
  };

  /**
   * Defines a basic string option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.string = function(name, opt_spec) {
    return this.addOption(name, parseString, opt_spec);
  };

  /**
   * Defines a regular expression based option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */
  this.regex = function(name, opt_spec) {
    return this.addOption(name, parseRegex, opt_spec);
  };

  /**
   * Returns the parsed command line options.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Object.<*>} The parsed options.
   */
  this.__defineGetter__('options', function() {
    parse();
    return parsedOptions;
  });

  /**
   * Returns the remaining command line arguments after all options have been
   * parsed.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Array.<string>} The remaining command line arguments.
   */
  this.__defineGetter__('argv', function() {
    parse();
    return extraArgs;
  });

  /**
   * Parses a list of arguments. After parsing, the options property of this
   * object will contain the value for each parsed flags, and the argv
   * property will contain all remaining command line arguments.
   * @throws {Error} If the arguments could not be parsed.
   */
  this.parse = parse;

  /**
   * Returns a formatted help message for this parser.
   * @return {string} The help message for this parser.
   */
  this.getHelpMsg = getHelpMsg;

  function getHelpMsg() {
    return formatHelpMsg(usage, options);
  }

  function parse() {
    if (!mustParse) {
      return;
    }

    parsedOptions = {};
    extraArgs = [];

    var args = process.argv.slice(2);
    var n = args.length;

    try {
      for (var i = 0; i < n; ++i) {
        var arg = args[i];
        if (arg === '--') {
          extraArgs = args.slice(i + 1);
          break;
        }

        var match = arg.match(OPTION_FLAG_REGEX);
        if (match) {
          // Special case --help.
          if (match[1] === 'help') {
            printHelpAndDie('', 0);
          }
          parseOption(match);
        } else {
          extraArgs = args.slice(i + 1);
          break;
        }
      }
    } catch (ex) {
      printHelpAndDie(ex.message, 1);
    }

    for (var name in options) {
      var option = options[name];
      if (!(name in parsedOptions)) {
        if (option.required) {
          printHelpAndDie('Missing required option: --' + name, 1);
        }
        parsedOptions[name] = option.list ? [] : option['default'];
      }
    }

    mustParse = false;
  }

  function printHelpAndDie(errorMessage, exitCode) {
    process.stdout.write(errorMessage + '\n');
    process.stdout.write(getHelpMsg());
    process.exit(exitCode);
  }

  function parseOption(match) {
    var option = options[match[1]];
    if (!option) {
      throw Error(JSON.stringify('--' + match[1]) + ' is not a valid option');
    }

    var value = match[2];
    if (typeof value !== 'undefined') {
      value = parseOptionValue(match[1], option, value);
    } else if (option.parse === parseBoolean) {
      value = true;
    } else {
      throw Error('Option ' + JSON.stringify('--' + option.name) +
          'requires an operand');
    }

    option.callback(value);

    if (option.list) {
      var array = parsedOptions[match[1]] || [];
      parsedOptions[match[1]] = array;
      array.push(value);
    } else {
      parsedOptions[match[1]] = value;
    }
  }
}
function OptionParser ( ) { /** @type {string} */ var usage = OptionParser . DEFAULT_USAGE ; /** @type {boolean} */ var mustParse = true ; /** @type {!Object.<*>} */ var parsedOptions = { } ; /** @type {!Array.<string>} */ var extraArgs = [ ] ; /**
   * Sets the usage string. All occurences of "$0" will be replaced with the
   * current executable's name.
   * @param {string} usageStr The new usage string.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . usage = function ( usageStr ) { mustParse = true ; usage = usageStr ; return this ; } ; /**
   * @type {!Object.<{
   *   help: string,
   *   parse: function(string): *,
   *   required: boolean,
   *   list: boolean,
   *   callback: function(*),
   *   default: *
   * }>}
   */ var options = { } ; /**
   * Adds a new option to this parser.
   * @param {string} name The name of the option.
   * @param {function(string): *} parseFn The function to use for parsing the
   *     option. If this function has a "default" property, it will be used as
   *     the default value for the option if it was not provided on the command
   *     line. If not specified, the default value will be undefined. The
   *     default value may be overrideden using the "default" property in the
   *     option spec.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . addOption = function ( name , parseFn , opt_spec ) { checkOptionName ( name , options ) ; var spec = opt_spec || { } ; // Quoted notation for "default" to bypass annoying IDE syntax bug. var defaultValue = spec [ 'default' ] || ( ! ! spec . list ? [ ] : parseFn [ 'default' ] ) ; options [ name ] = { help : spec . help || '' , parse : parseFn , required : ! ! spec . required , list : ! ! spec . list , callback : spec . callback || function ( ) { } , 'default' : defaultValue } ; mustParse = true ; return this ; } ; /**
   * Defines a boolean option. Option values may be one of {'', 'true', 'false',
   * '0', '1'}. In the case of the empty string (''), the option value will be
   * set to true.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
  */ this . boolean = function ( name , opt_spec ) { return this . addOption ( name , parseBoolean , opt_spec ) ; } ; /**
   * Defines a numeric option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . number = function ( name , opt_spec ) { return this . addOption ( name , parseNumber , opt_spec ) ; } ; /**
   * Defines a path option. Each path will be resolved relative to the
   * current workin directory, if not absolute.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . path = function ( name , opt_spec ) { return this . addOption ( name , path . resolve , opt_spec ) ; } ; /**
   * Defines a basic string option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . string = function ( name , opt_spec ) { return this . addOption ( name , parseString , opt_spec ) ; } ; /**
   * Defines a regular expression based option.
   * @param {string} name The name of the option.
   * @param {Object=} opt_spec The option spec.
   * @return {!OptionParser} A self reference.
   * @this {OptionParser}
   */ this . regex = function ( name , opt_spec ) { return this . addOption ( name , parseRegex , opt_spec ) ; } ; /**
   * Returns the parsed command line options.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Object.<*>} The parsed options.
   */ this . __defineGetter__ ( 'options' , function ( ) { parse ( ) ; return parsedOptions ; } ) ; /**
   * Returns the remaining command line arguments after all options have been
   * parsed.
   *
   * <p>The command line arguments will be re-parsed if this parser's
   * configuration has changed since the last access.
   *
   * @return {!Array.<string>} The remaining command line arguments.
   */ this . __defineGetter__ ( 'argv' , function ( ) { parse ( ) ; return extraArgs ; } ) ; /**
   * Parses a list of arguments. After parsing, the options property of this
   * object will contain the value for each parsed flags, and the argv
   * property will contain all remaining command line arguments.
   * @throws {Error} If the arguments could not be parsed.
   */ this . parse = parse ; /**
   * Returns a formatted help message for this parser.
   * @return {string} The help message for this parser.
   */ this . getHelpMsg = getHelpMsg ; function getHelpMsg ( ) { return formatHelpMsg ( usage , options ) ; } function parse ( ) { if ( ! mustParse ) { return ; } parsedOptions = { } ; extraArgs = [ ] ; var args = process . argv . slice ( 2 ) ; var n = args . length ; try { for ( var i = 0 ; i < n ; ++ i ) { var arg = args [ i ] ; if ( arg === '--' ) { extraArgs = args . slice ( i + 1 ) ; break ; } var match = arg . match ( OPTION_FLAG_REGEX ) ; if ( match ) { // Special case --help. if ( match [ 1 ] === 'help' ) { printHelpAndDie ( '' , 0 ) ; } parseOption ( match ) ; } else { extraArgs = args . slice ( i + 1 ) ; break ; } } } catch ( ex ) { printHelpAndDie ( ex . message , 1 ) ; } for ( var name in options ) { var option = options [ name ] ; if ( ! ( name in parsedOptions ) ) { if ( option . required ) { printHelpAndDie ( 'Missing required option: --' + name , 1 ) ; } parsedOptions [ name ] = option . list ? [ ] : option [ 'default' ] ; } } mustParse = false ; } function printHelpAndDie ( errorMessage , exitCode ) { process . stdout . write ( errorMessage + '\n' ) ; process . stdout . write ( getHelpMsg ( ) ) ; process . exit ( exitCode ) ; } function parseOption ( match ) { var option = options [ match [ 1 ] ] ; if ( ! option ) { throw Error ( JSON . stringify ( '--' + match [ 1 ] ) + ' is not a valid option' ) ; } var value = match [ 2 ] ; if ( typeof value !== 'undefined' ) { value = parseOptionValue ( match [ 1 ] , option , value ) ; } else if ( option . parse === parseBoolean ) { value = true ; } else { throw Error ( 'Option ' + JSON . stringify ( '--' + option . name ) + 'requires an operand' ) ; } option . callback ( value ) ; if ( option . list ) { var array = parsedOptions [ match [ 1 ] ] || [ ] ; parsedOptions [ match [ 1 ] ] = array ; array . push ( value ) ; } else { parsedOptions [ match [ 1 ] ] = value ; } } }
A command line option parser.  Will automatically parse the command line
arguments to this program upon accessing the {@code options} or {@code argv}
properies. The command line will only be re-parsed if this parser's
configuration has changed since the last access.
@constructor
A command line option parser . Will automatically parse the command line arguments to this program upon accessing the {
The option parser.