diff --git a/include/class.json.php b/include/class.json.php
index ad5ac65c12e3da2c939faecdb67dfec3f049c635..66edb7623e4944cc4ab30b763740993294652f5a 100644
--- a/include/class.json.php
+++ b/include/class.json.php
@@ -21,25 +21,39 @@
 include_once "JSON.php";
 
 class JsonDataParser {
-    function parse($stream) {
+    function parse($stream, $tidy=false) {
         if (is_resource($stream)) {
             $contents = '';
             while (!feof($stream))
                 $contents .= fread($stream, 8192);
         } else
             $contents = $stream;
+
+        if ($contents && $tidy)
+            $contents = self::tidy($contents);
+
         return self::decode($contents);
     }
 
-    function decode($contents) {
-        if (function_exists("json_decode")) {
-            return json_decode($contents, true);
-        } else {
-            # Create associative arrays rather than 'objects'
-            $decoder = new Services_JSON(SERVICES_JSON_LOOSE_TYPE);
-            return $decoder->decode($contents);
-        }
+    static function decode($contents, $assoc=true) {
+        if (function_exists("json_decode"))
+            return json_decode($contents, $assoc);
+
+        $decoder = new Services_JSON($assoc ? SERVICES_JSON_LOOSE_TYPE : 0);
+        return $decoder->decode($contents);
     }
+
+    static function tidy($content) {
+
+        // Clean up doubly quoted JSON
+        $content = str_replace(
+                array(':"{', '}"', '\"'),
+                array(':{', '}', '"'),
+                $content);
+        // return trimmed content.
+        return trim($content);
+    }
+
     function lastError() {
         if (function_exists("json_last_error")) {
             $errors = array(
diff --git a/include/class.queue.php b/include/class.queue.php
index b037d4eee0769d5e7ad4d291e1cc5e24d1b9537e..284853a4412dea0b370935835be42cfa5c3a89e0 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -123,7 +123,9 @@ class CustomQueue extends VerySimpleModel {
                 && !isset($this->criteria['conditions'])
             ) {
                 // TODO: Upgrade old ORM path names
-                $this->criteria = $this->isolateCriteria($this->criteria);
+                // Parse criteria out of JSON if any.
+                $this->criteria = self::isolateCriteria($this->criteria,
+                        $this->getRoot());
             }
         }
         $criteria = $this->criteria ?: array();
@@ -460,11 +462,13 @@ class CustomQueue extends VerySimpleModel {
      * field name being search, the method used for searhing, and the method-
      * specific data entered in the UI.
      */
-    function isolateCriteria($criteria, $root=null) {
-        $searchable = static::getSearchableFields($root ?: $this->getRoot());
-        $items = array();
+    static function isolateCriteria($criteria, $base='Ticket') {
+
         if (!is_array($criteria))
             return null;
+
+        $items = array();
+        $searchable = static::getSearchableFields($base);
         foreach ($criteria as $k=>$v) {
             if (substr($k, -7) === '+method') {
                 list($name,) = explode('+', $k, 2);
@@ -477,9 +481,8 @@ class CustomQueue extends VerySimpleModel {
 
                 // Lookup the field to search this condition
                 list($label, $field) = $searchable[$name];
-
-                // Get the search method and value
-                $method = $v;
+                // Get the search method
+                $method = is_array($v) ? key($v) : $v;
                 // Not all search methods require a value
                 $value = $criteria["{$name}+{$method}"];
 
@@ -1154,7 +1157,8 @@ class CustomQueue extends VerySimpleModel {
         }
         else {
             $this->config = JsonDataEncoder::encode([
-                'criteria' => $this->isolateCriteria($form->getClean()),
+                'criteria' => self::isolateCriteria($form->getClean(),
+                    $this->getRoot()),
                 'conditions' => $conditions,
             ]);
             // Clear currently set criteria.and conditions.
@@ -1650,8 +1654,8 @@ class QueueColumnCondition {
      * field name being search, the method used for searhing, and the method-
      * specific data entered in the UI.
      */
-    static function isolateCriteria($criteria, $root='Ticket') {
-        $searchable = CustomQueue::getSearchableFields($root);
+    static function isolateCriteria($criteria, $base='Ticket') {
+        $searchable = CustomQueue::getSearchableFields($base);
         foreach ($criteria as $k=>$v) {
             if (substr($k, -7) === '+method') {
                 list($name,) = explode('+', $k, 2);
diff --git a/include/mysqli.php b/include/mysqli.php
index 998d286590d08ff8f8ea6c78ad072b28ee7600f2..efb459f334b9d8a6ffc7899fca51caf08d2f25cc 100644
--- a/include/mysqli.php
+++ b/include/mysqli.php
@@ -234,7 +234,7 @@ function db_fetch_field($res) {
     return ($res) ? $res->fetch_field() : NULL;
 }
 
-function db_assoc_array($res, $mode=false) {
+function db_assoc_array($res, $mode=MYSQLI_ASSOC) {
     $result = array();
     if($res && db_num_rows($res)) {
         while ($row=db_fetch_array($res, $mode))
diff --git a/include/upgrader/streams/core/934b8db8-ad9d0a5f.task.php b/include/upgrader/streams/core/934b8db8-ad9d0a5f.task.php
index 29a3a4b8c71c1a2cfbf191f03f8cb8fc2fb032c8..886bcf6ebb0a7f53102efc66672e18073a032e29 100644
--- a/include/upgrader/streams/core/934b8db8-ad9d0a5f.task.php
+++ b/include/upgrader/streams/core/934b8db8-ad9d0a5f.task.php
@@ -9,14 +9,32 @@ class QueueSortCreator extends MigrationTask {
         foreach ($columns as $C) {
             QueueColumn::__create($C);
         }
-        // Make room for the new queues starting at ID 1
-        $id = new SqlField('id');
-        CustomQueue::objects()->update(['id' => $id->plus(30)]);
+
+        // Save old records
+        $old = db_assoc_array(db_query('SELECT * FROM '.QUEUE_TABLE));
+        // Truncate Queue table - make room for the new queues starting at ID 1
+        db_query('TRUNCATE TABLE '.QUEUE_TABLE);
         $queues = $i18n->getTemplate('queue.yaml')->getData();
         foreach ($queues as $C) {
             CustomQueue::__create($C);
         }
 
+        // Re-insert old saved searches
+        foreach ($old ?: array() as $row) {
+            // Only save entries with "valid" criteria
+            if (!$row['title']
+                    || !($config = JsonDataParser::parse($row['config'], true))
+                    || !($criteria = CustomQueue::isolateCriteria($criteria)))
+                continue;
+
+            $row['config'] = JsonDataEncoder::encode(array(
+                        'criteria' => $criteria, 'conditions' => array()));
+            $row['root'] = 'T';
+            CustomQueue::__create(array_intersect_key($row, array_flip(
+                            array('staff_id', 'title', 'config', 'flags',
+                                'root', 'created', 'updated'))));
+        }
+
         $columns = $i18n->getTemplate('queue_sort.yaml')->getData();
         foreach ($columns as $C) {
             QueueSort::__create($C);