text: // protect against .hasOwnProperty attacks
  var hasOwnProperty = require('has');
  
  // Tables.
  exports.tables = {
    filter  : 'filter',     // The default table (if no -t option is passed). It contains the built-in chains INPUT (for packets destined to local sockets), FORWARD (for packets being routed through the box), and OUTPUT (for locally-generated packets).
    nat     : 'nat',        // Consulted when a packet that creates a new connection is encountered.  It consists of three built-ins: PREROUTING (for altering packets as soon as they come  in), OUTPUT (for altering locally-generated packets before routing), and POSTROUTING (for altering packets as they are about to go out).
    mangle  : 'mangle',     // Used for specialized packet alteration.  Until kernel 2.4.17 it had two built-in chains: PREROUTING (for altering incoming packets before routing) and OUTPUT (for altering locally-generated packets before routing).  Since kernel 2.4.18, three other built-in chains are also supported: INPUT (for packets coming into the box  itself),  FORWARD (for altering packets being routed through the box), and POSTROUTING (for altering packets as they are about to go out).
    raw     : 'raw',        // Used mainly for configuring exemptions from connection tracking in combination with the NOTRACK target.  It registers at the netfilter hooks with higher priority and is thus called before ip_conntrack, or any other IP tables.  It provides the following built-in chains: PREROUTING (for packets arriving via any network  interface)  OUTPUT (for packets generated by local processes)
    security: 'security'    // Used for Mandatory Access Control (MAC) networking rules, such as those enabled by the SECMARK and CONNSECMARK targets.  Mandatory Access Control is implemented by Linux Security Modules such as SELinux.  The security table is called after the filter table, allowing any Discretionary Access Control (DAC) rules in the  filter  table  to take effect before MAC rules.  This table provides the following built-in chains: INPUT (for packets coming into the box itself), OUTPUT (for altering locally-generated packets before routing), and FORWARD (for altering packets being routed through the box).
  };
  
  /**
   * Processes an iptables possible argument to build the actual query args.
   *
   * @param {String}  property      The property value to be processed (f.e: the content of the `protocol` property).
   * @param {String}  flag          The iptables related argument name (f.e: '--destination').
   * @param {Array}   args          The actual arguments construction where the cmd line is being saved to.
   * @param {Boolean} is_boolean    If true then the property is boolean and don't use a value. False otherwise. F.e: `fragment`.
   */
  function manage_arg(property, flag, args, is_boolean) {
    if (property != null) {
      var val = String(property);
      var index = val.indexOf('!');
      var is_boolean = is_boolean || false; // Defaults to false.
  
      if (index !== -1) {
        args.push('!', flag);
  
        if (!is_boolean) {
          args.push(val.slice(index + 1)); // To not include the ! character.
        }
      }
      else {
        args.push(flag);
  
        if (!is_boolean) {
          args.push(val);
        }
      }
    }
  }
  
  /**
   * Process common rule specs for `append`, `check`, `delete`, `insert` and `replace`.
   *
   * @param   {Object}  options
   * @returns {Array}
   */
  exports.processCommonRuleSpecs = function (options) {
    var args = [];
  
    manage_arg(options.protocol, '--protocol', args);
    manage_arg(options.source, '--source', args);
    manage_arg(options.destination, '--destination', args);
    manage_arg(options['in-interface'], '--in-interface', args);
    manage_arg(options['out-interface'], '--out-interface', args);
    manage_arg(options['source-port'], '--source-port', args);
    manage_arg(options['destination-port'], '--destination-port', args);
    manage_arg(options.fragment, '--fragment', args, true);
  
    /*
     * Matches processing.
     */
    if (options.matches != null) {
      for (var match in options.matches) {
        if (hasOwnProperty(options.matches, match)) {
          // Initial match load.
          args.push('--match', match);
  
          // Specific match options.
          var this_match = options.matches[match];
  
          if (this_match != null && typeof this_match === 'object') {
            for (var match_option in this_match) {
              if (hasOwnProperty(this_match, match_option)) {
                manage_arg(this_match[match_option], '--' + match_option, args);
              }
            }
          }
        }
      }
    }
  
    if (options.goto != null) {
      args.push('--goto', String(options.goto));
    }
  
    if (options.jump != null) {
      args.push('--jump', String(options.jump));
  
      // Target extension options.
      if (options.target_options != null && typeof options.target_options === 'object') {
        for (var target_option in options.target_options) {
          if (hasOwnProperty(options.target_options, target_option)) {
            manage_arg(options.target_options[target_option], '--' + target_option, args);
          }
        }
      }
    }
  
    /* Vittorio Foschi */
    manage_arg(options.to, '--to',args);
  
    return args;
  };
  