diff --git a/src/jio.storage/localstorage.js b/src/jio.storage/localstorage.js
index ffeabacd7551122551bcb069e94ec2cdf87f2f4d..7d9fa9e070c8524bf55de5c90796444f01ff0566 100644
--- a/src/jio.storage/localstorage.js
+++ b/src/jio.storage/localstorage.js
@@ -3,8 +3,11 @@
 * Released under the LGPL license.
 * http://www.gnu.org/licenses/lgpl.html
 */
+
 /*jslint indent: 2, maxlen: 80, sloppy: true, nomen: true */
-/*global jIO: true, localStorage: true, setTimeout: true */
+/*global jIO: true, localStorage: true, setTimeout: true,
+         complex_queries: true */
+
 /**
  * JIO Local Storage. Type = 'local'.
  * Local browser "database" storage.
@@ -359,47 +362,65 @@ jIO.addStorageType('local', function (spec, my) {
    * @param  {object} command The JIO command
    */
   that.allDocs = function (command) {
-    var i, j, file, items = 0,
-      s = new RegExp("^" + priv.localpath + "\\/[^/]+$"),
-      all_doc_response = {},
-      query_object = [], query_syntax, query_response = [];
-
-    query_syntax = command.getOption('query');
-    if (query_syntax === undefined) {
-      all_doc_response.rows = [];
-
+    var i, row, path_re, rows = [], document_list = [], option, document_object;
+    path_re = new RegExp(
+      "^" + complex_queries.stringEscapeRegexpCharacters(priv.localpath) +
+        "/[^/]+$"
+    );
+    option = command.cloneOption();
+    if (typeof complex_queries !== "object" ||
+        option.query === undefined && option.sort_on === undefined &&
+        option.select_list === undefined && option.include_docs === undefined) {
+      rows = [];
       for (i in localStorage) {
         if (localStorage.hasOwnProperty(i)) {
           // filter non-documents
-          if (s.test(i)) {
-            items += 1;
-            j = i.split('/').slice(-1)[0];
-
-            file = { value: {} };
-            file.id = j;
-            file.key = j;
+          if (path_re.test(i)) {
+            row = { value: {} };
+            row.id = i.split('/').slice(-1)[0];
+            row.key = row.id;
             if (command.getOption('include_docs')) {
-              file.doc = JSON.parse(localStorage.getItem(i));
+              row.doc = JSON.parse(localStorage.getItem(i));
             }
-            all_doc_response.rows.push(file);
+            rows.push(row);
           }
         }
       }
-      all_doc_response.total_rows = items;
-      that.success(all_doc_response);
+      that.success({"rows": rows, "total_rows": rows.length});
     } else {
       // create complex query object from returned results
       for (i in localStorage) {
         if (localStorage.hasOwnProperty(i)) {
-          if (s.test(i)) {
-            items += 1;
-            j = i.split('/').slice(-1)[0];
-            query_object.push(localstorage.getItem(i));
+          if (path_re.test(i)) {
+            document_list.push(localstorage.getItem(i));
           }
         }
       }
-      query_response = jIO.ComplexQueries.query(query_syntax, query_object);
-      that.success(query_response);
+      option.select_list = option.select_list || [];
+      option.select_list.push("_id");
+      if (option.include_docs === true) {
+        document_object = {};
+        document_list.forEach(function (meta) {
+          document_object[meta._id] = meta;
+        });
+      }
+      complex_queries.QueryFactory.create(option.query || "").
+        exec(document_list, option);
+      document_list = document_list.map(function (value) {
+        var o = {
+          "id": value._id,
+          "key": value._id
+        };
+        if (option.include_docs === true) {
+          o.doc = document_object[value._id];
+          delete document_object[value._id];
+        }
+        delete value._id;
+        o.value = value;
+        return o;
+      });
+      that.success({"total_rows": document_list.length,
+                    "rows": document_list});
     }
   };
 
diff --git a/test/jiotests.js b/test/jiotests.js
index 7e441cf17e83de39214c089b2418d96ebdf7d2c9..162c8edee7514eb0212d51a533acd2b3f3db78be 100644
--- a/test/jiotests.js
+++ b/test/jiotests.js
@@ -1161,7 +1161,7 @@ test ("AllDocs", function(){
     // include docs
     o.allDocsResponse = {};
     o.allDocsResponse.rows = [];
-    o.allDocsResponse.total_rows = 15;
+    o.allDocsResponse.total_rows = m;
     for (i = 0; i < m; i += 1) {
       o.allDocsResponse.rows.push({
         "id": "doc_"+(i < 10 ? "0"+i : i),
@@ -1173,7 +1173,7 @@ test ("AllDocs", function(){
 
     // alldocs
     o.spy(o, "value", o.allDocsResponse, "All docs (include docs)");
-    o.jio.allDocs({"include_docs":true}, function (err, response) {
+    o.jio.allDocs({"include_docs": true}, function (err, response) {
       if (response && response.rows) {
         response.rows.sort(function (a, b) {
           return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
@@ -1184,65 +1184,56 @@ test ("AllDocs", function(){
     o.tick(o);
 
     // complex queries
-    o.thisShouldBeTheAnswer4 = [
-        {"title": "Inception", "year": 2010},
-        {"title": "The Dark Knight", "year": 2008},
-        {"title": "Lord of the Rings - Return of the King", "year": 2003},
-        {"title": "Lord Of the Rings - Fellowship of the Ring", "year": 2001},
-        {"title": "Fight Club", "year": 1999}
-    ];
+    o.thisShouldBeTheAnswer4 = {"total_rows": 0, "rows": []};
+    o.allDocsResponse.rows.forEach(function (row) {
+      var new_row;
+      if (row.doc.year >= 1980) {
+        new_row = JSON.parse(JSON.stringify(row));
+        new_row.value.title = row.doc.title;
+        new_row.value.year = row.doc.year;
+        delete new_row.doc;
+        o.thisShouldBeTheAnswer4.rows.push(new_row);
+        o.thisShouldBeTheAnswer4.total_rows += 1;
+      }
+    });
+    o.thisShouldBeTheAnswer4.rows.sort(function (a, b) {
+      return a.value.year > b.value.year ? -1 :
+        a.value.year < b.value.year ? 1 : 0;
+    });
+    o.thisShouldBeTheAnswer4.total_rows = 5;
+    o.thisShouldBeTheAnswer4.rows.length = 5;
+
     o.spy(o, "value", o.thisShouldBeTheAnswer4,
       "allDocs (complex queries year >= 1980, all query options)");
     o.jio.allDocs({
-      "query":{
-        "query":'(year: >= "1980")',
-        "filter": {
-            "limit":[0,5],
-            "sort_on":[['year','descending']],
-            "select_list":['title','year']
-        },
-        "wildcard_character":'%'
-      }
+      "query": '(year: >= "1980")',
+      "limit": [0,5],
+      "sort_on": [["year", "descending"]],
+      "select_list": ["title", "year"]
     }, o.f);
     o.tick(o);
 
     // empty query returns all
-    o.thisShouldBeTheAnswer5 = [
-        {"title": "The Good, The Bad and The Ugly"},
-        {"title": "The Dark Knight"},
-        {"title": "Star Wars Episode V"},
-        {"title": "Shawshank Redemption"},
-        {"title": "Schindlers List"},
-        {"title": "Pulp Fiction"},
-        {"title": "One flew over the Cuckoo's Nest"},
-        {"title": "Lord of the Rings - Return of the King"},
-        {"title": "Lord Of the Rings - Fellowship of the Ring"},
-        {"title": "Inception"},
-        {"title": "Godfellas"},
-        {"title": "Godfather 2"},
-        {"title": "Godfather"},
-        {"title": "Fight Club"},
-        {"title": "12 Angry Men"}
-    ];
+    o.thisShouldBeTheAnswer5 = {"total_rows": 0, "rows": []};
+    o.allDocsResponse.rows.forEach(function (row) {
+      var new_row = JSON.parse(JSON.stringify(row));
+      new_row.value.title = row.doc.title;
+      o.thisShouldBeTheAnswer5.rows.push(new_row);
+      o.thisShouldBeTheAnswer5.total_rows += 1;
+    });
+    o.thisShouldBeTheAnswer5.rows.sort(function (a, b) {
+      return a.value.title > b.value.title ? -1 :
+        a.value.title < b.value.title ? 1 : 0;
+    });
+
     o.spy(o, "value", o.thisShouldBeTheAnswer5,
       "allDocs (empty query in complex query)");
 
     o.jio.allDocs({
-      "query":{
-        "filter": {
-            "sort_on":[['title','descending']],
-            "select_list":['title']
-        },
-        "wildcard_character":'%'
-      }
-    }, function (err, response) {
-      if (response && response.rows) {
-        response.rows.sort(function (a, b) {
-          return a.id > b.id ? 1 : a.id < b.id ? -1 : 0;
-        });
-      }
-      o.f(err, response);
-    });
+      "sort_on": [["title", "descending"]],
+      "select_list": ["title"],
+      "include_docs": true
+    }, o.f);
     o.tick(o);
 
     o.jio.stop();