diff --git a/include/ajax.search.php b/include/ajax.search.php
index 7e0452dd296d27fbf8a7ffc3d27ed9cec9824ab8..0ef01784bde6a313007dcffbcc13b279e2bb03a7 100644
--- a/include/ajax.search.php
+++ b/include/ajax.search.php
@@ -32,10 +32,19 @@ class SearchAjaxAPI extends AjaxController {
             'root' => 'T',
         ));
         $search->config = $_SESSION['advsearch'];
-        $form = $search->getForm();
-        $matches = $search->getSupportedMatches();
+        $this->_tryAgain($search, $search->getForm());
+    }
 
-        include STAFFINC_DIR . 'templates/advanced-search.tmpl.php';
+    function editSearch($id) {
+        global $thisstaff;
+
+        $search = SavedSearch::lookup($id);
+        if (!$thisstaff)
+            Http::response(403, 'Agent login is required');
+        elseif (!$search || !$search->checkAccess($thisstaff))
+            Http::response(404, 'No such saved search');
+
+        $this->_tryAgain($search, $search->getForm());
     }
 
     function addField($name) {
@@ -66,62 +75,68 @@ class SearchAjaxAPI extends AjaxController {
     }
 
     function doSearch() {
-        global $thisstaff;
-
         $search = SavedSearch::create(array('root' => 'T'));
-
         $form = $search->getForm($_POST);
-        if (!$form->isValid()) {
-            $matches = $search->getSupportedMatches();
-            include STAFFINC_DIR . 'templates/advanced-search.tmpl.php';
+        if (false === $this->_setupSearch($search, $form)) {
             return;
         }
-        $_SESSION['advsearch'] = $search->isolateCriteria($form->getClean());
 
         Http::response(200, $this->encode(array(
             'redirect' => 'tickets.php?queue=adhoc',
         )));
     }
 
+    function _hasErrors(SavedSearch $search, $form) {
+        if (!$form->isValid()) {
+            $this->_tryAgain($search, $form);
+            return true;
+        }
+    }
+
+    function _setupSearch(SavedSearch $search, $form, $key='advsearch') {
+        $form = $search->getForm($vars);
+        if ($this->_hasErrors($search, $form))
+            return false;
+
+        $_SESSION[$key] = $search->isolateCriteria($form->getClean());
+    }
+
+    function _tryAgain($search, $form, $errors=array()) {
+        $matches = $search->getSupportedMatches();
+        include STAFFINC_DIR . 'templates/advanced-search.tmpl.php';
+    }
+
     function saveSearch($id) {
         global $thisstaff;
 
         $search = SavedSearch::lookup($id);
-        if (!$search || !$search->checkAccess($thisstaff))
-            Http::response(404, 'No such saved search');
-        elseif (!$thisstaff)
+        if (!$thisstaff)
             Http::response(403, 'Agent login is required');
+        elseif (!$search || !$search->checkAccess($thisstaff))
+            Http::response(404, 'No such saved search');
 
-        return self::_saveSearch($search);
+        if (false === $this->_saveSearch($search))
+            return;
+
+        Http::response(200, $this->encode(array(
+            'redirect' => 'tickets.php?queue='.Format::htmlchars($search->id),
+        )));
     }
 
-    function _saveSearch($search) {
-        $data = array();
-        foreach ($_POST['form'] as $id=>$info) {
-            $name = $info['name'];
-            if (substr($name, -2) == '[]')
-                $data[substr($name, 0, -2)][] = $info['value'];
-            else
-                $data[$name] = $info['value'];
-        }
-        $form = $search->getForm($data);
-        $form->setSource($data);
-        if (!$data || !$form->isValid()) {
-            Http::response(422, 'Validation errors exist on criteria');
+    function _saveSearch(SavedSearch $search) {
+        $form = $search->getForm($_POST);
+        $errors = array();
+        if (!$search->update($_POST, $form, $errors)
+            || !$search->save()
+        ) {
+            return $this->_tryAgain($search, $form, $errors);
         }
 
-        $search->config = JsonDataEncoder::encode($form->getState());
-        if (isset($_POST['name']))
-            $search->title = Format::htmlchars($_POST['name']);
-        elseif ($search->__new__)
-            Http::response(400, 'A name is required');
-        if (!$search->save()) {
-            Http::response(500, 'Unable to update search. Internal error occurred');
+        if (false === $this->_setupSearch($search, $form)) {
+            return false;
         }
-        Http::response(201, $this->encode(array(
-            'id' => $search->id,
-            'title' => $search->title,
-        )));
+
+        return true;
     }
 
     function createSearch() {
@@ -130,28 +145,14 @@ class SearchAjaxAPI extends AjaxController {
         if (!$thisstaff)
             Http::response(403, 'Agent login is required');
 
-        $search = SavedSearch::create();
+        $search = SavedSearch::create(array('root' => 'T'));
         $search->staff_id = $thisstaff->getId();
-        return self::_saveSearch($search);
-    }
-
-    function loadSearch($id) {
-        global $thisstaff;
-
-        if (!$thisstaff) {
-            Http::response(403, 'Agent login is required');
-        }
-        elseif (!($search = SavedSearch::lookup($id))) {
-            Http::response(404, 'No such saved search');
-        }
-
-        if ($state = JsonDataParser::parse($search->config)) {
-            $form = $search->loadFromState($state);
-            $form->loadState($state);
-        }
-        $matches = SavedSearch::getSupportedTicketMatches();
+        if (false === $this->_saveSearch($search))
+            return;
 
-        include STAFFINC_DIR . 'templates/advanced-search.tmpl.php';
+        Http::response(200, $this->encode(array(
+            'redirect' => 'tickets.php?queue='.Format::htmlchars($search->id),
+        )));
     }
 
     function deleteSearch($id) {
@@ -225,7 +226,7 @@ class SearchAjaxAPI extends AjaxController {
             Http::response(400, sprintf('%s: No such searchable field'),
                 Format::htmlchars($_GET['field']));
         }
-      
+
         list($label, $field) = $fields[$_GET['field']];
         // Ensure `name` is preserved
         $field_name = $_GET['field'];
diff --git a/include/class.forms.php b/include/class.forms.php
index a5057f3a5ec0906ca0fde20ad1f8f454eba21250..34c162a14c33945f94598b75afdb57ddd31a5bdd 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -3164,6 +3164,8 @@ class InlineFormField extends FormField {
         $form = $this->get('form');
         if (is_array($form)) {
             $form = new SimpleForm($form, $data ?: $this->value ?: $this->getSource());
+            // Ensure unique, but predictable form and field IDs
+            $form->setId(sprintf('%u', crc32($this->get('name')) >> 1));
         }
         return $form;
     }
diff --git a/include/class.orm.php b/include/class.orm.php
index 5fcf7359cb258185ba12052403ed6f2ebf48af4b..1c3ba561798665864e700e79ad9b902b7efac243 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -114,8 +114,17 @@ class ModelMeta implements ArrayAccess {
         }
     }
 
+    /**
+     * Merge this class's meta-data into the recieved child meta-data.
+     * When a model extends another model, the meta data for the two models
+     * is merged to form the child's meta data. Returns the merged, child
+     * meta-data.
+     */
     function extend(ModelMeta $child, $meta) {
         $this->subclasses[$child->model] = $child;
+        // Merge 'joins' settings (instead of replacing)
+        if (isset($this->meta['joins']))
+            $meta['joins'] += $this->meta['joins'];
         return $meta + $this->meta + self::$base;
     }
 
diff --git a/include/class.queue.php b/include/class.queue.php
index 66781c5e00da4348222110f9533cd22d131a96f2..5952d9933668504fa585f773b90566e99680589d 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -23,21 +23,10 @@ class CustomQueue extends SavedSearch {
             'columns' => array(
                 'reverse' => 'QueueColumn.queue',
             ),
-            'staff' => array(
-                'constraint' => array(
-                    'staff_id' => 'Staff.staff_id',
-                )
-            ),
-            'parent' => array(
-                'constraint' => array(
-                    'parent_id' => 'CustomQueue.id',
-                ),
-                'null' => true,
-            ),
             'children' => array(
                 'reverse' => 'CustomQueue.parent',
-            )
-        ),
+            ),
+        )
     );
 
     static function queues() {
@@ -96,21 +85,6 @@ class CustomQueue extends SavedSearch {
         ));
     }
 
-    function buildPath() {
-        if (!$this->id)
-            return;
-
-        $path = $this->parent ? $this->parent->getPath() : '';
-        return $path . "/{$this->id}";
-    }
-
-    function getFullName() {
-        $base = $this->getName();
-        if ($this->parent)
-            $base = sprintf("%s / %s", $this->parent->getFullName(), $base);
-        return $base;
-    }
-
     function inheritCriteria() {
         return $this->flags & self::FLAG_INHERIT_CRITERIA;
     }
@@ -171,22 +145,11 @@ class CustomQueue extends SavedSearch {
     }
 
     function update($vars, &$errors=array()) {
-        // TODO: Move this to SavedSearch::update() and adjust
-        //       AjaxSearch::_saveSearch()
-        $form = $this->getForm($vars);
-        if (!$vars || !$form->isValid()) {
-            $errors['criteria'] = __('Validation errors exist on criteria');
-        }
-        else {
-            $this->config = JsonDataEncoder::encode(
-                $this->isolateCriteria($form->getClean()));
-        }
+        if (!parent::update($vars, false, $errors))
+            return false;
 
         // Set basic queue information
-        $this->title = $vars['name'];
-        $this->parent_id = $vars['parent_id'];
         $this->filter = $vars['filter'];
-        $this->path = $this->buildPath();
         $this->setFlag(self::FLAG_INHERIT_CRITERIA, isset($vars['inherit']));
 
         // Update queue columns (but without save)
diff --git a/include/class.search.php b/include/class.search.php
index dd913b3d31714bc9eec59691c1b59728f1a78c41..93322cc7248b08eabe7b801c01d76383bdfd5757 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -657,11 +657,23 @@ MysqlSearchBackend::register();
  * updated - (date:auto_update) time of last update
  */
 class SavedSearch extends VerySimpleModel {
-
     static $meta = array(
         'table' => QUEUE_TABLE,
         'pk' => array('id'),
         'ordering' => array('sort'),
+        'joins' => array(
+            'staff' => array(
+                'constraint' => array(
+                    'staff_id' => 'Staff.staff_id',
+                )
+            ),
+            'parent' => array(
+                'constraint' => array(
+                    'parent_id' => 'CustomQueue.id',
+                ),
+                'null' => true,
+            ),
+        ),
     );
 
     const FLAG_PUBLIC =         0x0001; // Shows up in e'eryone's saved searches
@@ -717,6 +729,14 @@ class SavedSearch extends VerySimpleModel {
         return $this->criteria ?: array();
     }
 
+    /**
+     * Fetch an AdvancedSearchForm instance for use in displaying or
+     * configuring this search in the user interface.
+     *
+     * Parameters:
+     * $search - <array> Request parameters ($_POST) used to update the
+     *      search beyond the current configuration of the search criteria
+     */
     function getForm($source=null) {
         $searchable = $this->getCurrentSearchFields($source);
         $fields = array(
@@ -769,6 +789,19 @@ class SavedSearch extends VerySimpleModel {
         return $form;
     }
 
+    /**
+     * Fetch a bucket of fields for a custom search. The fields should be
+     * added to a form before display. One searchable field may encompass 10
+     * or more actual fields because fields are expanded to support multiple
+     * search methods along with the fields for each search method. This
+     * method returns all the FormField instances for all the searchable
+     * model fields currently in use.
+     *
+     * Parameters:
+     * $source - <array> data from a request. $source['fields'] is expected
+     *      to contain a list extra fields by ORM path, of newly added
+     *      fields not yet saved in this object's getCriteria().
+     */
     function getCurrentSearchFields($source=array()) {
         static $basic = array(
             'Ticket' => array(
@@ -802,6 +835,12 @@ class SavedSearch extends VerySimpleModel {
         return $core;
     }
 
+    /**
+     * Fetch all supported ORM fields searchable by this search object. The
+     * returned list represents searchable fields, keyed by the ORM path.
+     * Use ::getCurrentSearchFields() or ::getSearchField() to retrieve for
+     * use in the user interface.
+     */
     function getSupportedMatches() {
         return static::getSearchableFields($this->getRoot());
     }
@@ -867,12 +906,6 @@ class SavedSearch extends VerySimpleModel {
             }
         }
 
-        // Cache the base fields early so that if recursive calls looks for
-        // this base model, the base fields can be returned without
-        // requiring recursion.
-        if ($cache)
-            $cache[$base] = $fields;
-
         if ($recurse) {
             $exclude[$base] = 1;
             foreach ($base::getMeta('joins') as $path=>$j) {
@@ -890,11 +923,20 @@ class SavedSearch extends VerySimpleModel {
             }
         }
 
-        if ($cache)
-            $cache[$base] = $fields;
         return $fields;
     }
 
+    /**
+     * Fetch the FormField instances used when for configuring a searchable
+     * field in the user interface. This is the glue between a field
+     * representing a searchable model field and the configuration of that
+     * search in the user interface.
+     *
+     * Parameters:
+     * $F - <array<string, FormField>> the label and the FormField instance
+     *      representing the configurable search
+     * $name - <string> ORM path for the search
+     */
     static function getSearchField($F, $name) {
         list($label, $field) = $F;
 
@@ -1161,10 +1203,29 @@ class SavedSearch extends VerySimpleModel {
             && $thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING);
     }
 
+    function buildPath() {
+        if (!$this->id)
+            return;
+
+        $path = $this->parent ? $this->parent->getPath() : '';
+        return $path . "/{$this->id}";
+    }
+
+    function getFullName() {
+        $base = $this->getName();
+        if ($this->parent)
+            $base = sprintf("%s / %s", $this->parent->getFullName(), $base);
+        return $base;
+    }
+
     function isAQueue() {
         return $this->hasFlag(self::FLAG_QUEUE);
     }
 
+    function isPrivate() {
+        return !$this->isAQueue() && !$this->hasFlag(self::FLAG_PUBLIC);
+    }
+
     protected function hasFlag($flag) {
         return $this->flags & $flag !== 0;
     }
@@ -1190,6 +1251,31 @@ class SavedSearch extends VerySimpleModel {
             $this->updated = SqlFunction::NOW();
         return parent::save($refetch || $this->dirty);
     }
+
+    function update($vars, $form=false, &$errors=array()) {
+        // TODO: Move this to SavedSearch::update() and adjust
+        //       AjaxSearch::_saveSearch()
+        $form = $form ?: $this->getForm($vars);
+        if (!$vars || !$form->isValid()) {
+            $errors['criteria'] = __('Validation errors exist on criteria');
+        }
+        else {
+            $this->config = JsonDataEncoder::encode(
+                $this->isolateCriteria($form->getClean()));
+        }
+
+        // Set basic search information
+        if (!$vars['name'])
+            $errors['name'] = __('A title is required');
+
+        $this->title = $vars['name'];
+        $this->parent_id = @$vars['parent_id'] ?: 0;
+        $this->path = $this->buildPath();
+        // Personal queues _always_ inherit from their parent
+        $this->setFlag(self::FLAG_INHERIT_CRITERIA, $this->parent_id > 0);
+
+        return count($errors) === 0;
+    }
 }
 
 class AdhocSearch
diff --git a/include/staff/templates/advanced-search.tmpl.php b/include/staff/templates/advanced-search.tmpl.php
index 201cb66b0af583203453613a784ad76059bf8ae6..454ef70d100529dfc10a966c5e16fee69a0d2143 100644
--- a/include/staff/templates/advanced-search.tmpl.php
+++ b/include/staff/templates/advanced-search.tmpl.php
@@ -1,126 +1,60 @@
+<?php
+$parent_id = $_REQUEST['parent_id'] ?: $search->parent_id;
+if ($parent_id
+    && (!($queue = CustomQueue::lookup($parent_id)))
+) {
+    $parent_id = null;
+}
+?>
 <div id="advanced-search" class="advanced-search">
 <h3 class="drag-handle"><?php echo __('Advanced Ticket Search');?></h3>
 <a class="close" href=""><i class="icon-remove-circle"></i></a>
 <hr/>
 <form action="#tickets/search" method="post" name="search">
-<div class="row">
-<div class="span6">
-    <input type="hidden" name="a" value="search">
-    <?php include STAFFINC_DIR . 'templates/advanced-search-criteria.tmpl.php'; ?>
-</div>
-<div class="span6" style="border-left:1px solid #888;position:relative;padding-bottom:26px;">
-<div style="margin-bottom: 0.5em;"><b style="font-size: 110%;"><?php echo __('Saved Searches'); ?></b></div>
-<hr>
-<div id="saved-searches" class="accordian" style="max-height:200px;overflow-y:auto;">
-<?php foreach (SavedSearch::forStaff($thisstaff) as $S) { ?>
-    <dt class="saved-search">
-        <a href="#" class="load-search"><?php echo $S->title; ?>
-        <i class="icon-chevron-down pull-right"></i>
-        </a>
-    </dt>
-    <dd>
-        <span>
-            <button type="button" onclick="javascript:$(this).closest('form').attr({
-'method': 'get', 'action': '#tickets/search/<?php echo $S->id; ?>'}).trigger('submit');"><i class="icon-chevron-left"></i> <?php echo __('Load'); ?></button>
-            <button type="button" onclick="javascript:
-var that = this;
-$.ajax({
-    url: 'ajax.php/tickets/search/<?php echo $S->id; ?>',
-    type: 'POST',
-    data: {'form': $(this).closest('.dialog').find('form[name=search]').serializeArray()},
-    dataType: 'json',
-    success: function(json) {
-      if (!json.id)
-        return;
-      $(that).closest('dd').effect('highlight');
-    }
-});
-return false;
-"><i class="icon-save"></i> <?php echo __('Update'); ?></button>
-        </span>
-        <span class="pull-right">
-            <button type="button" title="<?php echo __('Delete'); ?>" onclick="javascript:
-    if (!confirm(__('You sure?'))) return false;
-    var that = this;
-    $.ajax({
-        'url': 'ajax.php/tickets/search/<?php echo $S->id; ?>',
-        'type': 'delete',
-        'dataType': 'json',
-        'success': function(json) {
-            if (json.success) {
-                $(that).closest('dd').prev('dt').slideUp().next('dd').slideUp();
-            }
-        }
-    });
-    return false;
-"><i class="icon-trash"></i></button>
-        </span>
-    </dd>
-<?php } ?>
-</div>
-<div style="position:absolute;bottom:0">
-<hr>
-    <form method="post">
-    <div class="attached input">
-    <input name="title" type="text" size="27" placeholder="<?php
-        echo __('Enter a title for the search'); ?>"/>
-        <a class="attached button" href="#tickets/search/create" onclick="javascript:
-$.ajax({
-    url: 'ajax.php/' + $(this).attr('href').substr(1),
-    type: 'POST',
-    data: {'name': $(this).closest('form').find('[name=title]').val(),
-           'form': $(this).closest('.dialog').find('form[name=search]').serializeArray()},
-    dataType: 'json',
-    success: function(json) {
-      if (!json.id)
-        return;
-      $('<dt>')
-        .append($('<a>').text(' ' + json.title)
-          .prepend($('<i>').addClass('icon-chevron-left'))
-        ).appendTo($('#saved-searches'));
-    }
-});
-return false;
-"><i class="icon-save"></i></a>
+  <div class="flex row">
+    <div class="span6">
+      <select name="parent_id">
+          <option value="0" <?php
+              if (!$parent_id) echo 'selected="selected"';
+              ?>><?php echo '—'.__("My Searches").'—'; ?></option>
+          <?php foreach (CustomQueue::queues()
+              ->filter(array('parent_id' => 0))
+              as $q) { ?>
+          <option value="<?php echo $q->id; ?>"
+              <?php if ($parent_id == $q->id) echo 'selected="selected"'; ?>
+              ><?php echo $q->getFullName(); ?></option>
+<?php       } ?>
+      </select>
+    </div><div class="span6">
+      <input name="name" type="text" size="30" 
+        value="<?php echo Format::htmlchars($search->getName()); ?>"
+        placeholder="<?php
+        echo __('Enter a title for the search queue'); ?>"/>
+      <div class="error"><?php echo Format::htmlchars($errors['name']); ?></div>
     </div>
-</div>
-</div>
-</div>
-
-<hr/>
-<div>
-    <div id="search-hint" class="pull-left">
+  </div>
+  <hr/>
+  <div class="flex row">
+    <div class="span12">
+      <input type="hidden" name="a" value="search">
+      <?php include STAFFINC_DIR . 'templates/advanced-search-criteria.tmpl.php'; ?>
     </div>
+  </div>
+
+  <hr/>
+  <div>
     <div class="buttons pull-right">
-        <button class="button" type="submit" id="do_search"><i class="icon-search"></i>
-            <?php echo __('Search'); ?></button>
+      <button class="button" type="submit" name="submit" value="search"
+        id="do_search"><i class="icon-search"></i>
+        <?php echo __('Search'); ?></button>
+      <button class="green button" type="submit" name="submit" value="save"
+        onclick="javascript:
+          var form = $(this).closest('form');
+          form.attr('action', form.attr('action') + '/' + <?php echo
+            $search->id ?: "'create'"; ?>);"
+        ><i class="icon-save"></i>
+        <?php echo __('Save'); ?>
+      </button>
     </div>
-</div>
-
+  </div>
 </form>
-
-<style type="text/css">
-#advanced-search .span6 .select2 {
-  max-width: 300px !important;
-}
-</style>
-
-<script type="text/javascript">
-$(function() {
-  $('#advanced-search [data-dropdown]').dropdown();
-
-  var I = setInterval(function() {
-    var A = $('#saved-searches.accordian');
-    if (!A.length) return;
-    clearInterval(I);
-
-    var allPanels = $('dd', A).hide();
-    $('dt > a', A).click(function() {
-      $('dt', A).removeClass('active');
-      allPanels.slideUp();
-      $(this).parent().addClass('active').next().slideDown();
-      return false;
-    });
-  }, 200);
-});
-</script>
diff --git a/include/staff/templates/queue-navigation.tmpl.php b/include/staff/templates/queue-navigation.tmpl.php
index 0e78f83301f64c373a2f9a04a88fe05db0edf420..c736e3759862a6783f9ef582eb9d9d0dd0bd4009 100644
--- a/include/staff/templates/queue-navigation.tmpl.php
+++ b/include/staff/templates/queue-navigation.tmpl.php
@@ -4,30 +4,31 @@
 // $q - <CustomQueue> object for this navigation entry
 // $selected - <bool> true if this queue is currently active
 // $child_selected - <bool> true if the selected queue is a descendent
-$queue = $q;
-$selected = $_REQUEST['queue'] == $queue->getId();
+$this_queue = $q;
+$selected = $_REQUEST['queue'] == $this_queue->getId();
 ?>
 <li class="item <?php if ($child_selected) echo 'child active';
     elseif ($selected) echo 'active'; ?>">
-  <a href="<?php echo $queue->getHref(); ?>"><i class="icon-sort-down pull-right"></i><?php echo $queue->getName(); ?></a>
+  <a href="<?php echo $this_queue->getHref(); ?>"><i class="icon-sort-down pull-right"></i><?php echo $this_queue->getName(); ?></a>
   <div class="customQ-dropdown">
     <ul class="scroll-height">
       <!-- Start Dropdown and child queues -->
-      <?php foreach ($queue->getPublicChildren() as $q) {
+      <?php foreach ($this_queue->getPublicChildren() as $q) {
           include 'queue-subnavigation.tmpl.php';
       } ?>
       <!-- Dropdown Titles -->
       <li>
         <h4><?php echo __('Personal Queues'); ?></h4>
       </li>
-      <?php foreach ($queue->getMyChildren() as $q) {
+      <?php foreach ($this_queue->getMyChildren() as $q) {
         include 'queue-subnavigation.tmpl.php';
       } ?>
     </ul>
     <!-- Add Queue button sticky at the bottom -->
     <div class="add-queue">
       <a class="flush-right full-width" onclick="javascript:
-        $.dialog('ajax.php/tickets/search', 201);">
+        var pid = <?php echo $this_queue->getId() ?: 0; ?>;
+        $.dialog('ajax.php/tickets/search?parent_id='+pid, 201);">
         <div class="add pull-right"><i class="green icon-plus-sign"></i></div>
           <span><?php echo __('Add personal queue'); ?></span>
       </a>
diff --git a/include/staff/templates/queue-savedsearches-nav.tmpl.php b/include/staff/templates/queue-savedsearches-nav.tmpl.php
index 38a367b183da7587392b4d0957e1ae3f5df979b2..d4f5d2f1fafa69dbb8c3e6f063f9241ac42da7f5 100644
--- a/include/staff/templates/queue-savedsearches-nav.tmpl.php
+++ b/include/staff/templates/queue-savedsearches-nav.tmpl.php
@@ -6,12 +6,13 @@
 // $adhoc - not FALSE if an adhoc advanced search exists
 ?>
 <li class="item <?php if ($child_selected) echo 'child active'; ?>">
-  <a><i class="icon-sort-down pull-right"></i><?php echo __('Search');
+  <a href="tickets.php?queue=adhoc"><i class="icon-sort-down pull-right"></i><?php echo __('Search');
   ?></a>
   <div class="customQ-dropdown">
     <ul class="scroll-height">
       <!-- Start Dropdown and child queues -->
       <?php foreach ($searches->findAll(array(
+            'parent_id' => 0,
             'flags__hasbit' => SavedSearch::FLAG_PUBLIC,
       )) as $q) {
           include 'queue-subnavigation.tmpl.php';
@@ -22,6 +23,7 @@
       </li>
       <?php foreach ($searches->findAll(array(
             'staff_id' => $thisstaff->getId(),
+            'parent_id' => 0,
             Q::not(array(
                 'flags__hasbit' => SavedSearch::FLAG_PUBLIC
             ))
diff --git a/include/staff/templates/queue-subnavigation.tmpl.php b/include/staff/templates/queue-subnavigation.tmpl.php
index 9bd90855f654529795edbc5ab25cd5d4ed658069..29962c02e0878e0ff5d3c4b9cef4b2a83a2f6b74 100644
--- a/include/staff/templates/queue-subnavigation.tmpl.php
+++ b/include/staff/templates/queue-subnavigation.tmpl.php
@@ -26,7 +26,10 @@ global $thisstaff;
         </li>
         <?php } ?>
         <li>
-          <a href="queues.php?id=<?php echo $q->getId(); ?>">
+          <a href="<?php
+    echo $queue->isPrivate()
+        ? sprintf('#" data-dialog="ajax.php/tickets/search/%d', $queue->getId())
+        : sprintf('queues.php?id=%d', $queue->getId()); ?>">
             <i class="icon-fixed-width icon-pencil"></i>
             <?php echo __('Edit'); ?></a>
         </li>
diff --git a/scp/ajax.php b/scp/ajax.php
index 1351b9fbc58c606076286c55bbc71cd8127be9a9..5bf9f155df950debcaa6e05709ca15393693b840 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -169,8 +169,7 @@ $dispatcher = patterns('',
         url('^search', patterns('ajax.search.php:SearchAjaxAPI',
             url_get('^$', 'getAdvancedSearchDialog'),
             url_post('^$', 'doSearch'),
-            url_get('^quick$', 'doQuickSearch'),
-            url_get('^/(?P<id>\d+)$', 'loadSearch'),
+            url_get('^/(?P<id>\d+)$', 'editSearch'),
             url_post('^/(?P<id>\d+)$', 'saveSearch'),
             url_delete('^/(?P<id>\d+)$', 'deleteSearch'),
             url_post('^/create$', 'createSearch'),
diff --git a/scp/css/scp.css b/scp/css/scp.css
index bcb53c5b73acae51eb881523722734a8dd40436e..8913828cd911578f6f3d5a67025b4f7e7a14436f 100644
--- a/scp/css/scp.css
+++ b/scp/css/scp.css
@@ -2266,13 +2266,43 @@ fieldset {
 
 .row {
     display: table-row;
+    width: 100%;
 }
 
-.row .span6 {
-    display: table-cell;
-    width: 48%;
+.row > [class~=" span"],
+.row > [class^="span"] {
     padding: 5px 10px;
     vertical-align: top;
+    display: table-cell;
+}
+.row > [class~=" span"] > select,
+.row > [class^="span"] > select,
+.row > [class~=" span"] > input,
+.row > [class^="span"] > input {
+    width: 100%;
+    max-width: 100%;
+}
+.row .span3 {
+    width: 23%;
+    width: calc(25% - 5px);
+}
+.row .span6 {
+    width: 48%;
+    width: calc(50% - 5px);
+}
+.row .span9 {
+    width: 73%;
+    width: calc(75% - 5px);
+}
+.row .span12 {
+    width: 100%;
+}
+.flex.row {
+    display: initial;
+}
+.flex.row > [class~=" span"],
+.flex.row > [class^="span"] {
+    display: inline-block;
 }
 
 .search-dropdown {