diff --git a/handlers/views_json_query_handler_argument_query_string.inc b/handlers/views_json_query_handler_argument_query_string.inc
new file mode 100644
index 0000000..7c012cc
--- /dev/null
+++ b/handlers/views_json_query_handler_argument_query_string.inc
@@ -0,0 +1,68 @@
+<?php
+
+/**
+ * @file
+ * Definition of views_handler_argument_null.
+ */
+
+/**
+ * Argument handler for query string parameter in a JSON file URL.
+ *
+ * @ingroup views_argument_handlers
+ */
+class views_json_query_handler_argument_query_string extends views_handler_argument {
+
+  /**
+   * {@inheritdoc}
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['name'] = array('default' => '');
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+      '#default_value' => $this->options['name'],
+      '#description' => t('The name of the query string parameter, as used in the JSON file URI.'),
+      '#required' => TRUE,
+    );
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function default_actions($which = NULL) {
+    $keys = array('ignore', 'not found', 'default', 'access denied');
+    if ($which) {
+      if (in_array($which, $keys)) {
+        return parent::default_actions($which);
+      }
+      return;
+    }
+    $actions = parent::default_actions();
+    foreach (array_keys($actions) as $key) {
+      if (!in_array($key, $keys)) {
+        unset($actions[$key]);
+      }
+    }
+    return $actions;
+  }
+
+  function validate_argument_basic($arg) {
+    return parent::validate_argument_basic($arg);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function query($group_by = FALSE) {
+    $this->query->query_string[$this->options['name']] = $this->argument;
+  }
+}
diff --git a/handlers/views_json_query_handler_filter.inc b/handlers/views_json_query_handler_filter.inc
index f8f0358..d22c2dc 100755
--- a/handlers/views_json_query_handler_filter.inc
+++ b/handlers/views_json_query_handler_filter.inc
@@ -14,6 +14,8 @@ class views_json_query_handler_filter extends views_handler_filter_string {
   function option_definition() {
     $options = parent::option_definition();
     $options['key'] = array('default' => '');
+    // where does this really go?
+    $this->definition['allow empty'] = TRUE;
     return $options;
   }
 
@@ -114,10 +116,10 @@ class views_json_query_handler_filter extends views_handler_filter_string {
    * Generate.
    */
   function generate() {
-    $operator = $this->options['operator'];
+    // make sure we pass the operator so the filter conditions are handled correctly
+    $operator = $this->operator;
     $key = $this->options['key'];
     $value = $this->options['value'];
-
     return array($key, $operator, $value);
   }
 
diff --git a/handlers/views_json_query_handler_filter_query_string.inc b/handlers/views_json_query_handler_filter_query_string.inc
new file mode 100755
index 0000000..394cfd4
--- /dev/null
+++ b/handlers/views_json_query_handler_filter_query_string.inc
@@ -0,0 +1,135 @@
+<?php
+/**
+ * @file
+ * Base filter handler for views_json_query.
+ */
+
+class views_json_query_handler_filter_query_string extends views_handler_filter_string {
+
+  /**
+   * {@inheritdoc}
+   */
+  public $no_operator = TRUE;
+
+  /**
+   * {@inheritdoc}
+   */
+  function option_definition() {
+    $options = parent::option_definition();
+    $options['name'] = array('default' => '');
+    return $options;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function operators() {
+
+    $operators = array(
+      '=' => array(
+        'title' => t('Is equal to'),
+        'short' => t('='),
+        'method' => 'op_equal',
+        'values' => 1,
+      ),
+      '!=' => array(
+        'title' => t('Is not equal to'),
+        'short' => t('!='),
+        'method' => 'op_equal',
+        'values' => 1,
+      ),
+      'contains' => array(
+        'title' => t('Contains'),
+        'short' => t('contains'),
+        'method' => 'op_contains',
+        'values' => 1,
+      ),
+      '!contains' => array(
+        'title' => t('Does not contain'),
+        'short' => t('!has'),
+        'method' => 'op_not',
+        'values' => 1,
+      ),
+      'shorterthan' => array(
+        'title' => t('Length is shorter than'),
+        'short' => t('shorter than'),
+        'method' => 'op_shorter',
+        'values' => 1,
+      ),
+      'longerthan' => array(
+        'title' => t('Length is longer than'),
+        'short' => t('longer than'),
+        'method' => 'op_longer',
+        'values' => 1,
+      ),
+    );
+
+    // If the definition allows for the empty operator, add it.
+    if (!empty($this->definition['allow empty'])) {
+      $operators += array(
+        'empty' => array(
+          'title' => t('Is empty (NULL)'),
+          'method' => 'op_empty',
+          'short' => t('empty'),
+          'values' => 0,
+        ),
+        'not empty' => array(
+          'title' => t('Is not empty (NOT NULL)'),
+          'method' => 'op_empty',
+          'short' => t('not empty'),
+          'values' => 0,
+        ),
+      );
+    }
+
+    return $operators;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function options_form(&$form, &$form_state) {
+    parent::options_form($form, $form_state);
+    $form['name'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Name'),
+      '#default_value' => $this->options['name'],
+      '#description' => t('The name of the query string parameter, as used in the JSON file URI.'),
+      '#required' => TRUE,
+    );
+  }
+
+  function value_form(&$form, &$form_state) {
+    $form['value'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Value'),
+      '#size' => 30,
+      '#default_value' => $this->value,
+    );
+    if (!empty($form_state['exposed'])) {
+      $identifier = $this->options['expose']['identifier'];
+      if (!isset($form_state['input'][$identifier])) {
+        $form_state['input'][$identifier] = $this->value;
+      }
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function query() {
+    $this->query->query_string[$this->options['name']] = $this->value;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  function ui_name($short = FALSE) {
+    if (!empty($this->options['ui_name'])) {
+      $title = check_plain($this->options['ui_name']);
+      return $title;
+    }
+    $title = ($short && isset($this->definition['title short'])) ? $this->definition['title short'] : $this->definition['title'];
+    return t('!title: !name', array('!name' => $this->options['name'], '!title' => $title));
+  }
+}
diff --git a/views_json_query.info b/views_json_query.info
index b3f3418..03b873b 100755
--- a/views_json_query.info
+++ b/views_json_query.info
@@ -8,4 +8,7 @@ files[] = views_json_query_plugin_query_json.inc
 ; Handlers
 files[] = handlers/views_json_query_handler_field.inc
 files[] = handlers/views_json_query_handler_filter.inc
+files[] = handlers/views_json_query_handler_filter_query_string.inc
 files[] = handlers/views_json_query_handler_sort.inc
+files[] = handlers/views_json_query_handler_argument_query_string.inc
+
diff --git a/views_json_query.views.inc b/views_json_query.views.inc
index 2ce825e..c704af0 100755
--- a/views_json_query.views.inc
+++ b/views_json_query.views.inc
@@ -32,6 +32,17 @@ function views_json_query_views_data() {
     ),
   );
 
+  $data['json']['query_string'] = array(
+    'title' => t('Query String'),
+    'help' => t("Parameter in the query string of the JSON file's URL."),
+    'filter' => array(
+      'handler' => 'views_json_query_handler_filter_query_string',
+    ),
+    'argument' => array(
+      'handler' => 'views_json_query_handler_argument_query_string',
+    ),
+  );
+
   return $data;
 }
 
diff --git a/views_json_query_plugin_query_json.inc b/views_json_query_plugin_query_json.inc
index 2590d25..8f7506e 100755
--- a/views_json_query_plugin_query_json.inc
+++ b/views_json_query_plugin_query_json.inc
@@ -17,7 +17,11 @@ class views_json_query_plugin_query_json extends views_plugin_query {
 
     if (isset($this->filter)) {
       foreach ($this->filter as $filter) {
-        $filters[] = $filter->generate();
+        // set the filter value for grouped filters
+        $filter->options['value'] = $filter->value;
+        if ($filter instanceof views_json_query_handler_filter) {
+          $filters[] = $filter->generate();
+        }
       }
     }
     // @todo Add an option for the filters to be 'and' or 'or'.
@@ -32,9 +36,32 @@ class views_json_query_plugin_query_json extends views_plugin_query {
 
     // Let the pager modify the query to add limits.
     $this->pager->query();
+    // Build the JSON file URL.
+    $json_file = $this->options['json_file'];
+    if (!empty($view->build_info['substitutions'])) {
+      $json_file = strtr($json_file, $view->build_info['substitutions']);
+    }
+    $parsed = parse_url($json_file);
+    $query_string = drupal_get_query_array(isset($parsed['query']) ? $parsed['query'] : array());
+    // Add query string parameters from filters.
+    if (isset($this->query_string)) {
+      foreach ($this->query_string as $k => $v) {
+        $query_string[$k] = $v;
+      }
+    }
+    // Add pagination query string argument.
+    if ($this->options['enable_pagination_query_parameters']) {
+      if (isset($view->query->offset)) {
+        $query_string[$this->options['pagination_offset_query_parameter']] = $view->query->offset;
+      }
+      if (isset($view->query->limit)) {
+        $query_string[$this->options['pagination_limit_query_parameter']] = $view->query->limit;
+      }
+    }
+    // Rebuild the JSON file URL.
+    $view->query->options['json_file'] = "{$parsed['scheme']}://{$parsed['host']}{$parsed['path']}?" . drupal_http_build_query($query_string);
 
     $view->build_info['query'] = $this->query();
-
     $view->build_info['query_args'] = array();
   }
 
@@ -71,6 +98,7 @@ class views_json_query_plugin_query_json extends views_plugin_query {
         $headers['If-Modified-Since'] = $last_headers['last-modified'];
       }
     }
+    // Rebuild the JSON file URL.
 
     $result = drupal_http_request($uri, array('headers' => $headers));
     if (isset($result->error)) {
@@ -200,6 +228,7 @@ class views_json_query_plugin_query_json extends views_plugin_query {
   function ops($op, $l, $r) {
     $table = array(
       '=' => create_function('$l,$r', 'return $l === $r;'),
+      'not empty' => create_function('$l,$r', 'return !empty($l);'),
       '!=' => create_function('$l,$r', 'return $l !== $r;'),
       'contains' => create_function('$l, $r', 'return strpos($l, $r) !== false;'),
       '!contains' => create_function('$l, $r', 'return strpos($l, $r) === false;'),
@@ -239,12 +268,16 @@ class views_json_query_plugin_query_json extends views_plugin_query {
 
     try {
       if ($this->pager->use_count_query() || !empty($view->get_total_rows)) {
-        // Hackish execute_count_query implementation.
-        $this->pager->total_items = count($ret);
-        if (!empty($this->pager->options['offset'])) {
-          $this->pager->total_items -= $this->pager->options['offset'];
+        if (!empty($this->options['total_items_apath'])) {
+          $this->pager->total_items = $this->apath($this->options['total_items_apath'], $ret);
+        }
+        else {
+          // Hackish execute_count_query implementation.
+          $this->pager->total_items = count($rows);
+          if (!empty($this->pager->options['offset'])) {
+            $this->pager->total_items -= $this->pager->options['offset'];
+          }
         }
-
         $this->pager->update_page_info();
       }
 
@@ -259,7 +292,7 @@ class views_json_query_plugin_query_json extends views_plugin_query {
         $new_row = $this->parse_row(NULL, $row, $row);
         $result[] = (object) $new_row;
       }
- 
+
       if (!empty($this->orderby)) {
         // Array reverse, because the most specific are first.
         foreach (array_reverse($this->orderby) as $orderby) {
@@ -294,7 +327,7 @@ class views_json_query_plugin_query_json extends views_plugin_query {
    * becomes:
    * $row->person/name/first_name = "John",
    * $row->person/name/last_name = "Doe"
-   */   
+   */
   function parse_row($parent_key, $parent_row, &$row) {
     $props = get_object_vars($parent_row);
 
@@ -320,7 +353,7 @@ class views_json_query_plugin_query_json extends views_plugin_query {
 
     return $row;
   }
- 
+
   /**
    * Add signature.
    */
@@ -334,6 +367,10 @@ class views_json_query_plugin_query_json extends views_plugin_query {
     $options = parent::option_definition();
     $options['json_file'] = array('default' => '');
     $options['row_apath'] = array('default' => '');
+    $options['total_items_apath'] = array('default' => '');
+    $options['enable_pagination_query_parameters'] = array('default' => FALSE);
+    $options['pagination_offset_query_parameter'] = array('default' => 'offset');
+    $options['pagination_limit_query_parameter'] = array('default' => 'limit');
     $options['show_errors'] = array('default' => TRUE);
 
     return $options;
@@ -357,6 +394,30 @@ class views_json_query_plugin_query_json extends views_plugin_query {
       '#description' => t("Apath to records.<br />Apath is just a simple array item find method. Ex:<br /><pre>array('data' => \n\tarray('records' => \n\t\tarray(\n\t\t\tarray('name' => 'yarco', 'sex' => 'male'),\n\t\t\tarray('name' => 'someone', 'sex' => 'male')\n\t\t)\n\t)\n)</pre><br />You want 'records', so Apath could be set to 'data/records'. <br />Notice: prefix '/' or postfix '/' will be trimed, so never mind you add it or not."),
       '#required' => TRUE,
     );
+    $form['total_items_apath'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Row Count Apath'),
+      '#default_value' => $this->options['total_items_apath'],
+      '#description' => t("Apath to records count."),
+      '#required' => FALSE,
+    );
+    $form['enable_pagination_query_parameters'] = array(
+      '#type' => 'checkbox',
+      '#title' => t('Enable pagination query parameters '),
+      '#default_value' => $this->options['enable_pagination_query_parameters'],
+    );
+    $form['pagination_offset_query_parameter'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Offset parameter name '),
+      '#default_value' => $this->options['pagination_offset_query_parameter'],
+      '#description' => t('The name of the pagination offset parameter'),
+    );
+    $form['pagination_limit_query_parameter'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Limit parameter name '),
+      '#default_value' => $this->options['pagination_limit_query_parameter'],
+      '#description' => t('The name of the pagination limit parameter'),
+    );
     $form['show_errors'] = array(
       '#type' => 'checkbox',
       '#title' => t('Show Json errors'),
