public static function parseArgvWithSpec($argv, ArgumentsSpec $arguments_spec) {
    $data_offset_count = 0;
    $usage = $arguments_spec->getUsage();

    // start with self
    $args_data_out = array(
      'self'          => $argv[0],
      'options'       => array(),
      'data'          => array(),
      'numbered_data' => array(),
    );

    // normalize argv
    $argv_tokens = self::tokenizeArgvData($argv, $arguments_spec);

    foreach($argv_tokens as $argv_token) {
      switch ($argv_token['type']) {
        case self::TOKEN_OPTION:
          $args_data_out['options'][$argv_token['key']] = $argv_token['value'];
          break;

        case self::TOKEN_DATA:
          $args_data_out['numbered_data'][$argv_token['offset']] = $argv_token['value'];
          if ($argv_token['key'] !== null) {  
            $args_data_out['data'][$argv_token['key']] = $argv_token['value'];
          }
          break;
      }
    }

    return $args_data_out;


  }