diff --git a/include/ajax.search.php b/include/ajax.search.php
index f886875b71ec6acf6649babf361ee86ffbdc28ea..55dd5aa014083d3453b5cc864351a4ac51b3bbd4 100644
--- a/include/ajax.search.php
+++ b/include/ajax.search.php
@@ -104,7 +104,7 @@ class SearchAjaxAPI extends AjaxController {
         $_SESSION['advsearch'] = $form->getState();
 
         Http::response(200, $this->encode(array(
-            'redirect' => 'tickets.php?advanced',
+            'redirect' => 'tickets.php?queue=adhoc',
         )));
     }
 
diff --git a/include/class.config.php b/include/class.config.php
index 74954e42c26ff5d593eee30103825c22eba39bb2..20c09e1dd26d94a713e95bec75ff0e17e17ff6d4 100644
--- a/include/class.config.php
+++ b/include/class.config.php
@@ -1254,7 +1254,7 @@ class OsticketConfig extends Config {
             return false;
 
         // Sort ticket queues
-        $queues = CustomQueue::objects()->all();
+        $queues = CustomQueue::queues()->all();
         foreach ($vars['qsort'] as $queue_id => $sort) {
             if ($q = $queues->findFirst(array('id' => $queue_id))) {
                 $q->sort = $sort;
diff --git a/include/class.forms.php b/include/class.forms.php
index e71d132fea3b0d78e54892131797e37ef5ca03bc..a5057f3a5ec0906ca0fde20ad1f8f454eba21250 100644
--- a/include/class.forms.php
+++ b/include/class.forms.php
@@ -4140,7 +4140,7 @@ class FreeTextWidget extends Widget {
             echo Format::viewableImages($config['content']); ?></div>
         </div>
         <?php
-        if (($attachments=$this->field->getFiles())) { ?>
+        if (($attachments = $this->field->getFiles()) && count($attachments)) { ?>
             <section class="freetext-files">
             <div class="title"><?php echo __('Related Resources'); ?></div>
             <?php foreach ($attachments as $attach) { ?>
diff --git a/include/class.orm.php b/include/class.orm.php
index 8b0fdedefb756fce7c49c00319813c5234d5b7b3..762e3d2f446774fbd999e44850187b7d80e3e1b2 100644
--- a/include/class.orm.php
+++ b/include/class.orm.php
@@ -2165,13 +2165,17 @@ class SqlCompiler {
             'regex' => function($a, $b) { return preg_match("/$a/iu", $b); },
             'hasbit' => function($a, $b) { return ($a & $b) == $b; },
         ); }
+        // TODO: Support Q expressions
+        if ($check instanceof Q)
+            return $check->evaluate($record, $field);
+
         list($field, $path, $operator) = self::splitCriteria($field);
         if (!isset($ops[$operator]))
             throw new OrmException($operator.': Unsupported operator');
 
         if ($path)
             $record = $record->getByPath($path);
-        // TODO: Support Q expressions
+
         return $ops[$operator]($record->get($field), $check);
     }
 
@@ -3372,6 +3376,26 @@ class Q implements Serializable {
         return new static($constraints);
     }
 
+    function evaluate($record, $field) {
+        // Start with FALSE for OR and TRUE for AND
+        $result = !$this->ored;
+        foreach ($this->constraints as $check) {
+            $R = SqlCompiler::evaluate($record, $field, $check);
+            if ($this->ored) {
+                if ($result |= $R)
+                    break;
+            }
+            elseif (!$R) {
+                // Anything AND false
+                $result = false;
+                break;
+            }
+        }
+        if ($this->negated)
+            $result = !$result;
+        return $result;
+    }
+
     function serialize() {
         return serialize(array($this->negated, $this->ored, $this->constraints));
     }
diff --git a/include/class.queue.php b/include/class.queue.php
index 69a9363157e3cd84c79112b0f163206071f7d456..2317a3f4aabb06050ae8d5c413fe3991205c1934 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -40,7 +40,7 @@ class CustomQueue extends SavedSearch {
         ),
     );
 
-    static function objects() {
+    static function queues() {
         return parent::objects()->filter(array(
             'flags__hasbit' => static::FLAG_QUEUE
         ));
@@ -108,14 +108,6 @@ class CustomQueue extends SavedSearch {
         $col->queue = $this;
     }
 
-    function getId() {
-        return $this->id;
-    }
-
-    function getRoot() {
-        return 'Ticket';
-    }
-
     function getStatus() {
         return 'bogus';
     }
@@ -143,10 +135,6 @@ class CustomQueue extends SavedSearch {
         ));
     }
 
-    function getPath() {
-        return $this->path ?: $this->buildPath();
-    }
-
     function buildPath() {
         if (!$this->id)
             return;
@@ -162,12 +150,6 @@ class CustomQueue extends SavedSearch {
         return $base;
     }
 
-    function getHref() {
-        // TODO: Get base page from getRoot();
-        $root = $this->getRoot();
-        return 'tickets.php?queue='.$this->getId();
-    }
-
     function inheritCriteria() {
         return $this->flags & self::FLAG_INHERIT_CRITERIA;
     }
diff --git a/include/class.search.php b/include/class.search.php
index 70da8d0fa8d507bcdbff2b293bfff1af0bb4121e..d7d44eff5003d23959eff714d6600dcfeb49d9bd 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -679,10 +679,28 @@ class SavedSearch extends VerySimpleModel {
         ->exclude(array('flags__hasbit'=>self::FLAG_QUEUE));
     }
 
+    function getId() {
+        return $this->id;
+    }
+
     function getName() {
         return $this->title;
     }
 
+    function getHref() {
+        // TODO: Get base page from getRoot();
+        $root = $this->getRoot();
+        return 'tickets.php?queue='.$this->getId();
+    }
+
+    function getRoot() {
+        return 'Ticket';
+    }
+
+    function getPath() {
+        return $this->path ?: $this->buildPath();
+    }
+
     function getCriteria() {
         if (!isset($this->criteria)) {
             $this->criteria = JsonDataParser::decode($this->config);
@@ -1112,10 +1130,14 @@ class SavedSearch extends VerySimpleModel {
 
         // For saved searches (not queues), staff can have a permission to
         // see all records
-        return !$this->hasFlag(self::FLAG_QUEUE)
+        return !$this->isAQueue()
             && $thisstaff->hasPerm(SearchBackend::PERM_EVERYTHING);
     }
 
+    function isAQueue() {
+        return $this->hasFlag(self::FLAG_QUEUE);
+    }
+
     protected function hasFlag($flag) {
         return $this->flags & $flag !== 0;
     }
diff --git a/include/staff/queue.inc.php b/include/staff/queue.inc.php
index ff03e04d2a29b2ffc4a8b14cb018cc5b733b7fb7..bff6a39b79735ddeb2ebb399bcc2c92353faf347 100644
--- a/include/staff/queue.inc.php
+++ b/include/staff/queue.inc.php
@@ -74,7 +74,7 @@ else {
         <div><strong><?php echo __("Parent Queue"); ?>:</strong></div>
         <select name="parent_id">
           <option value="0">— <?php echo __('Top-Level Queue'); ?> —</option>
-<?php foreach (CustomQueue::objects() as $cq) {
+<?php foreach (CustomQueue::queues() as $cq) {
         if ($cq->getId() == $queue->getId())
           continue;
 ?>
diff --git a/include/staff/queues-ticket.inc.php b/include/staff/queues-ticket.inc.php
index 74ff8662c42812b9c39e74c9878c51a3a2676b85..6ddb5c598ae47865ab9342547a037f2aa2e1acf4 100644
--- a/include/staff/queues-ticket.inc.php
+++ b/include/staff/queues-ticket.inc.php
@@ -17,7 +17,7 @@ require_once INCLUDE_DIR . 'class.queue.php';
             </td>
             <td>
                 <select name="default_ticket_queue">
-<?php foreach (CustomQueue::objects() as $cq) {
+<?php foreach (CustomQueue::queues() as $cq) {
 ?>
                   <option value="<?php echo $cq->id; ?>"
             <?php if ($cq->getId() == $config['default_ticket_queue']) echo 'selected="selected"'; ?>
@@ -78,7 +78,7 @@ require_once INCLUDE_DIR . 'class.queue.php';
     </thead>
     <tbody class="sortable-rows" data-sort="qsort">
 <?php
-$all_queues = CustomQueue::objects()->all();
+$all_queues = CustomQueue::queues()->all();
 $emitLevel = function($queues, $level=0) use ($all_queues, &$emitLevel) { 
     $queues->sort(function($a) { return $a->sort; });
     foreach ($queues as $q) { ?>
diff --git a/include/staff/templates/queue-savedsearches-nav.tmpl.php b/include/staff/templates/queue-savedsearches-nav.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..38a367b183da7587392b4d0957e1ae3f5df979b2
--- /dev/null
+++ b/include/staff/templates/queue-savedsearches-nav.tmpl.php
@@ -0,0 +1,41 @@
+<?php
+//
+// Calling conventions
+// $searches = All visibile saved searches
+// $child_selected - <bool> true if the selected queue is a descendent
+// $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>
+  <div class="customQ-dropdown">
+    <ul class="scroll-height">
+      <!-- Start Dropdown and child queues -->
+      <?php foreach ($searches->findAll(array(
+            'flags__hasbit' => SavedSearch::FLAG_PUBLIC,
+      )) as $q) {
+          include 'queue-subnavigation.tmpl.php';
+      } ?>
+      <!-- Dropdown Titles -->
+      <li>
+        <h4><?php echo __('Personal Queues'); ?></h4>
+      </li>
+      <?php foreach ($searches->findAll(array(
+            'staff_id' => $thisstaff->getId(),
+            Q::not(array(
+                'flags__hasbit' => SavedSearch::FLAG_PUBLIC
+            ))
+      )) 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);">
+        <div class="add pull-right"><i class="green icon-plus-sign"></i></div>
+          <span><?php echo __('Add personal queue'); ?></span>
+      </a>
+    </div>
+  </div>
+</li>
diff --git a/include/staff/templates/queue-subnavigation.tmpl.php b/include/staff/templates/queue-subnavigation.tmpl.php
index da26d870f67b1968a8e0f25dd331ff84634c3406..9bd90855f654529795edbc5ab25cd5d4ed658069 100644
--- a/include/staff/templates/queue-subnavigation.tmpl.php
+++ b/include/staff/templates/queue-subnavigation.tmpl.php
@@ -2,7 +2,7 @@
 // Calling conventions
 // $q - <CustomQueue> object for this navigation entry
 $queue = $q;
-$children = $queue->getPublicChildren();
+$children = $queue instanceof CustomQueue ? $queue->getPublicChildren() : array();
 $hasChildren = count($children) > 0;
 $selected = $_REQUEST['queue'] == $q->getId();
 global $thisstaff;
diff --git a/scp/queues.php b/scp/queues.php
index dc95a569764f0df20832efec6e5108a0fb23fea3..a227238adfeb64826093f9cce4de77104353ed2a 100644
--- a/scp/queues.php
+++ b/scp/queues.php
@@ -44,6 +44,7 @@ if ($_POST) {
 
     case 'create':
         $queue = CustomQueue::create(array(
+            'flags' => CustomQueue::FLAG_PUBLIC,
             'root' => $_POST['root'] ?: 'Ticket'
         ));
 
diff --git a/scp/tickets.php b/scp/tickets.php
index 5d7db9168ea226fd793458c9dedb0e3a2c44803f..1587110b0d111dd780988da6ef6f69b64894565d 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -60,7 +60,9 @@ if (!$ticket) {
 
 require_once INCLUDE_DIR . 'class.queue.php';
 $queue_id = @$_REQUEST['queue'] ?: $cfg->getDefaultTicketQueueId();
-$queue = CustomQueue::lookup($queue_id);
+if ((int) $queue_id) {
+    $queue = CustomQueue::lookup($queue_id);
+}
 
 // Configure form for file uploads
 $response_form = new SimpleForm(array(
@@ -371,7 +373,7 @@ $nav->setTabActive('tickets');
 $nav->addSubNavInfo('jb-overflowmenu', 'customQ_nav');
 
 // Fetch ticket queues organized by root and sub-queues
-$queues = CustomQueue::objects()
+$queues = CustomQueue::queues()
     ->filter(Q::any(array(
         'flags__hasbit' => CustomQueue::FLAG_PUBLIC,
         'staff_id' => $thisstaff->getId(),
@@ -391,20 +393,39 @@ as $q) {
 }
 
 if (isset($_SESSION['advsearch'])) {
-    // XXX: De-duplicate and simplify this code
-    TicketForm::ensureDynamicDataView();
-    $search = SavedSearch::create();
-    $form = $search->getFormFromSession('advsearch');
-    $tickets = TicketModel::objects();
-    $tickets = $search->mangleQuerySet($tickets, $form);
-    $count = $tickets->count();
-    $nav->addSubMenu(array('desc' => __('Search').' ('.number_format($count).')',
-                           'title'=>__('Advanced Ticket Search'),
-                           'href'=>'tickets.php?status=search',
-                           'iconclass'=>'Ticket'),
-                        (!$_REQUEST['status'] || $_REQUEST['status']=='search'));
+        // XXX: De-duplicate and simplify this code
+    $adhoc = SavedSearch::create(array('title' => __("Advanced Search")));
+    $form = $adhoc->getFormFromSession('advsearch');
+    $adhoc->config = $form->getState();
+
+    if ($_REQUEST['queue'] == 'adhoc')
+        $queue = $adhoc;
 }
 
+// Add my advanced searches
+$nav->addSubMenu(function() use ($queue, $adhoc) {
+    global $thisstaff;
+    // A queue is selected if it is the one being displayed. It is
+    // "child" selected if its ID is in the path of the one selected
+    $child_selected = $queue && !$queue->isAQueue();
+    $searches = SavedSearch::objects()
+        ->filter(Q::any(array(
+            'flags__hasbit' => SavedSearch::FLAG_PUBLIC,
+            'staff_id' => $thisstaff->getId(),
+        )))
+        ->exclude(array(
+            'flags__hasbit' => SavedSearch::FLAG_QUEUE
+        ))
+        ->all();
+
+    if (isset($adhoc)) {
+        // TODO: Add "Ad Hoc Search" to the personal children
+    }
+
+    include STAFFINC_DIR . 'templates/queue-savedsearches-nav.tmpl.php';
+});
+
+
 if ($thisstaff->hasPerm(TicketModel::PERM_CREATE, false)) {
     $nav->addSubMenu(array('desc'=>__('New Ticket'),
                            'title'=> __('Open a New Ticket'),
@@ -458,10 +479,6 @@ if($ticket) {
         $tickets = $queue->getQuery(false, $quick_filter);
     }
 
-    //Clear active submenu on search with no status
-    if($_REQUEST['a']=='search' && !$_REQUEST['status'])
-        $nav->setActiveSubMenu(-1);
-
     //set refresh rate if the user has it configured
     if(!$_POST && !$_REQUEST['a'] && ($min=(int)$thisstaff->getRefreshRate())) {
         $js = "+function(){ var qq = setInterval(function() { if ($.refreshTicketView === undefined) return; clearInterval(qq); $.refreshTicketView({$min}*60000); }, 200); }();";