diff --git a/include/ajax.search.php b/include/ajax.search.php
index eb1ef6ed36f534e2e1ad525e13cb4c3e8057e223..4a735f304055ed761ce9c148564aef6edc6ff62f 100644
--- a/include/ajax.search.php
+++ b/include/ajax.search.php
@@ -28,9 +28,13 @@ class SearchAjaxAPI extends AjaxController {
         if (!$thisstaff)
             Http::response(403, 'Agent login required');
 
-        $search = SavedSearch::create(array(
+        $search = new SavedSearch(array(
             'root' => 'T',
+            'parent_id' => @$_GET['parent_id'] ?: 0,
         ));
+        if ($search->parent_id) {
+            $search->flags |= SavedSearch::FLAG_INHERIT_COLUMNS;
+        }
         if (isset($_SESSION[$context])) {
             // Use the most recent search
             if (!$key) {
@@ -60,7 +64,7 @@ class SearchAjaxAPI extends AjaxController {
         if (!$thisstaff)
             Http::response(403, 'Agent login required');
 
-        $search = SavedSearch::create(array('root'=>'T'));
+        $search = new SavedSearch(array('root'=>'T'));
         $searchable = $search->getSupportedMatches();
         if (!($F = $searchable[$name]))
             Http::response(404, 'No such field: ', print_r($name, true));
@@ -82,7 +86,7 @@ class SearchAjaxAPI extends AjaxController {
     }
 
     function doSearch() {
-        $search = SavedSearch::create(array('root' => 'T'));
+        $search = new SavedSearch(array('root' => 'T'));
         $form = $search->getForm($_POST);
         if (false === $this->_setupSearch($search, $form)) {
             return;
@@ -164,7 +168,7 @@ class SearchAjaxAPI extends AjaxController {
     function _saveSearch(SavedSearch $search) {
         $form = $search->getForm($_POST);
         $errors = array();
-        if (!$search->update($_POST, $form, $errors)
+        if (!$search->update($_POST, $errors)
             || !$search->save()
         ) {
             return $this->_tryAgain($search, $form, $errors);
diff --git a/include/class.queue.php b/include/class.queue.php
index 461f2d02352db216c276d1bb85d80f77e2d517b1..0dab778b6f605480d52c0bb216d23a477895ccb3 100644
--- a/include/class.queue.php
+++ b/include/class.queue.php
@@ -60,7 +60,7 @@ class CustomQueue extends VerySimpleModel {
 
     function __onload() {
         // Ensure valid state
-        if ($this->hasFlag(self::FLAG_INHERIT_COLUMNS) || !$this->parent_id)
+        if ($this->hasFlag(self::FLAG_INHERIT_COLUMNS) && !$this->parent_id)
             $this->clearFlag(self::FLAG_INHERIT_COLUMNS);
     }
 
@@ -454,7 +454,7 @@ class CustomQueue extends VerySimpleModel {
         return $items;
     }
 
-    function getColumns() {
+    function getColumns($use_template=false) {
         if ($this->columns_id
             && ($q = CustomQueue::lookup($this->columns_id))
         ) {
@@ -471,6 +471,10 @@ class CustomQueue extends VerySimpleModel {
             return $this->columns;
         }
 
+        // Use the columns of the "Open" queue as a default template
+        if ($use_template && ($template = CustomQueue::lookup(1)))
+            return $template->getColumns();
+
         // Last resort — use standard columns
         foreach (array(
             QueueColumn::placeholder(array(
@@ -732,7 +736,11 @@ class CustomQueue extends VerySimpleModel {
             $this->parent_id > 0 && isset($vars['inherit-columns']));
 
         // Update queue columns (but without save)
-        if (isset($vars['columns'])) {
+        if (!isset($vars['columns']) && $this->parent) {
+            // No columns -- imply column inheritance
+            $this->setFlag(self::FLAG_INHERIT_COLUMNS);
+        }
+        if (isset($vars['columns']) && !$this->hasFlag(self::FLAG_INHERIT_COLUMNS)) {
             $new = $vars['columns'];
             $order = array_keys($new);
             foreach ($this->columns as $col) {
@@ -764,10 +772,6 @@ class CustomQueue extends VerySimpleModel {
             // Re-sort the in-memory columns array
             $this->columns->sort(function($c) { return $c->sort; });
         }
-        elseif ($this->parent) {
-            // No columns -- imply column inheritance
-            $this->setFlag(self::FLAG_INHERIT_COLUMNS);
-        }
 
         // TODO: Move this to SavedSearch::update() and adjust
         //       AjaxSearch::_saveSearch()
diff --git a/include/class.search.php b/include/class.search.php
index efbbdd3a90b093a32418d9ce9f604032313610b4..7dc62a5144c0c917eb392ba02dc109aaa49f9c66 100644
--- a/include/class.search.php
+++ b/include/class.search.php
@@ -660,7 +660,7 @@ class SavedSearch extends CustomQueue {
         ->exclude(array('flags__hasbit'=>self::FLAG_QUEUE));
     }
 
-    function update($vars, $form=false, &$errors=array()) {
+    function update($vars, &$errors=array()) {
         if (!parent::update($vars, $errors))
             return false;
 
diff --git a/include/staff/queue.inc.php b/include/staff/queue.inc.php
index cf116e4886bd8f8f364b85da2a1cf1380f72cda7..39f0f8007539e5c36eef6f1cd1c828c179aabfa5 100644
--- a/include/staff/queue.inc.php
+++ b/include/staff/queue.inc.php
@@ -136,77 +136,7 @@ else {
         <br><?php echo __(
         "Add, remove, and customize the content of the columns in this queue using the options below. Click a column header to manage or resize it"); ?></p>
     </div>
-    <table class="table two-column">
-<?php if ($queue->parent) { ?>
-      <tbody>
-        <tr>
-          <td colspan="3">
-            <input type="checkbox" name="inherit-columns" <?php
-              if ($queue->inheritColumns()) echo 'checked="checked"'; ?>
-              onchange="javascript:$(this).closest('table').find('.if-not-inherited').toggle(!$(this).prop('checked'));" />
-            <?php echo __('Inherit columns from the parent queue'); ?>
-            <br /><br />
-          </td>
-        </tr>
-      </tbody>
-<?php } ?>
-      <tbody class="if-not-inherited <?php if ($queue->inheritColumns()) echo 'hidden'; ?>">
-        <tr class="header">
-          <td style="width:36%"><small><b><?php echo __('Heading and Width'); ?></b></small></td>
-          <td><small><b><?php echo __('Column Details'); ?></b></small></td>
-          <td><small><b><?php echo __('Sortable'); ?></b></small></td>
-        </tr>
-      </tbody>
-      <tbody class="sortable-rows if-not-inherited <?php if ($queue->inheritColumns()) echo 'hidden'; ?>">
-        <tr id="column-template" class="hidden">
-          <td>
-            <i class="faded-more icon-sort"></i>
-            <input type="text" size="25" data-name="heading"
-              data-translate-tag="" />
-            <input type="text" size="5" data-name="width" />
-          </td>
-          <td>
-            <input type="hidden" data-name="queue_id"
-              value="<?php echo $queue->getId(); ?>"/>
-            <input type="hidden" data-name="column_id" />
-            <div>
-            <a class="inline action-button"
-                href="#" onclick="javascript:
-                var colid = $(this).closest('tr').find('[data-name=column_id]').val();
-                $.dialog('ajax.php/tickets/search/column/edit/' + colid, 201);
-                return false;
-                "><i class="icon-cog"></i> <?php echo __('Config'); ?></a>
-            </div>
-          </td>
-          <td>
-            <input type="checkbox" data-name="sortable">
-            <a href="#" class="pull-right drop-column" title="<?php echo __('Delete');
-              ?>"><i class="icon-trash"></i></a>
-          </td>
-        </tr>
-      </tbody>
-      <tbody class="if-not-inherited <?php if ($queue->inheritColumns()) echo 'hidden'; ?>">
-        <tr class="header">
-          <td colspan="3"></td>
-        </tr>
-        <tr>
-          <td colspan="3" id="append-column">
-            <i class="icon-plus-sign"></i>
-            <select id="add-column" data-quick-add="queue-column">
-              <option value="">— <?php echo __('Add a column'); ?> —</option>
-<?php foreach (QueueColumn::objects() as $C) { ?>
-              <option value="<?php echo $C->id; ?>"><?php echo
-                  Format::htmlchars($C->name); ?></option>
-<?php } ?>
-              <option value="0" data-quick-add>&mdash; <?php echo __('Add New');?> &mdash;</option>
-            </select>
-            <button type="button" class="green button">
-              <?php echo __('Add'); ?>
-            </button>
-          </td>
-        </tr>
-      </tbody>
-    </table>
+    <?php include STAFFINC_DIR . "templates/queue-columns.tmpl.php"; ?>
   </div>
     
     
@@ -293,64 +223,3 @@ else {
   </p>
 
 </form>
-
-<script>
-var addColumn = function(colid, info) {
-  if (!colid) return;
-  var copy = $('#column-template').clone(),
-      name_prefix = 'columns[' + colid + ']';
-  info['column_id'] = colid;
-  copy.find('input[data-name]').each(function() {
-    var $this = $(this),
-        name = $this.data('name');
-
-    if (info[name] !== undefined) {
-      if ($this.is(':checkbox'))
-        $this.prop('checked', info[name]);
-      else
-        $this.val(info[name]);
-    }
-    $this.attr('name', name_prefix + '[' + name + ']');
-  });
-  copy.find('span').text(info['name']);
-  copy.attr('id', '').show().insertBefore($('#column-template'));
-  copy.removeClass('hidden');
-  if (info['trans'] !== undefined) {
-    var input = copy.find('input[data-translate-tag]')
-      .attr('data-translate-tag', info['trans']);
-    if ($.fn.translatable)
-      input.translatable();
-    // Else it will be made translatable when the JS library is loaded
-  }
-  copy.find('a.drop-column').click(function() {
-    $('<option>')
-      .attr('value', copy.find('input[data-name=column_id]').val())
-      .text(info.name)
-      .insertBefore($('#add-column')
-        .find('[data-quick-add]')
-      );
-    copy.fadeOut(function() { $(this).remove(); });
-    return false;
-  });
-  var selected = $('#add-column').find('option[value=' + colid + ']');
-  selected.remove();
-};
-
-$('#append-column').find('button').on('click', function() {
-  var selected = $('#add-column').find(':selected'),
-      id = parseInt(selected.val());
-  if (!id)
-      return;
-  addColumn(id, {name: selected.text(), heading: selected.text(), width: 100, sortable: 1});
-  return false;
-});
-
-<?php foreach ($queue->columns as $C) {
-  echo sprintf('addColumn(%d, {name: %s, heading: %s, width: %d, trans: %s,
-  sortable: %s});',
-    $C->column_id, JsonDataEncoder::encode($C->name),
-    JsonDataEncoder::encode($C->heading), $C->width,
-    JsonDataEncoder::encode($C->getTranslateTag('heading')),
-    $C->isSortable() ? 1 : 0);
-} ?>
-</script>
diff --git a/include/staff/templates/advanced-search.tmpl.php b/include/staff/templates/advanced-search.tmpl.php
index f0e3c65aab2d3bb4244c2eb72f148a43ad704bd3..33949c8291382174b12203537da588ae1121d86f 100644
--- a/include/staff/templates/advanced-search.tmpl.php
+++ b/include/staff/templates/advanced-search.tmpl.php
@@ -1,7 +1,7 @@
 <?php
 $parent_id = $_REQUEST['parent_id'] ?: $search->parent_id;
 if ($parent_id
-    && (!($queue = CustomQueue::lookup($parent_id)))
+    && (!($parent = CustomQueue::lookup($parent_id)))
 ) {
     $parent_id = null;
 }
@@ -10,7 +10,9 @@ if ($parent_id
 <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="flex row">
     <div class="span6">
       <select name="parent_id">
@@ -32,16 +34,22 @@ foreach (CustomQueue::queues()->order_by('sort', 'title') as $q) { ?>
       <div class="error"><?php echo Format::htmlchars($errors['name']); ?></div>
     </div>
   </div>
-  <hr/>
+
+<ul class="tabs">
+    <li class="active"><a href="#criteria"><?php echo __('Criteria'); ?></a></li>
+    <li><a href="#columns"><?php echo __('Columns'); ?></a></li>
+</ul>
+
+<div class="tab_content" id="criteria">
   <div class="flex row">
     <div class="span12">
-<?php if ($queue) { ?>
+<?php if ($parent) { ?>
       <div class="faded" style="margin-bottom: 1em">
       <div>
         <strong><?php echo __('Inherited Criteria'); ?></strong>
       </div>
       <div>
-        <?php echo nl2br(Format::htmlchars($queue->describeCriteria())); ?>
+        <?php echo nl2br(Format::htmlchars($parent->describeCriteria())); ?>
       </div>
       </div>
 <?php } ?>
@@ -50,6 +58,14 @@ foreach (CustomQueue::queues()->order_by('sort', 'title') as $q) { ?>
     </div>
   </div>
 
+</div>
+
+<div class="tab_content hidden" id="columns">
+    <?php 
+    $queue = $search;
+    include STAFFINC_DIR . "templates/queue-columns.tmpl.php"; ?>
+</div>
+
   <hr/>
   <div>
     <div class="buttons pull-right">
@@ -66,4 +82,30 @@ foreach (CustomQueue::queues()->order_by('sort', 'title') as $q) { ?>
       </button>
     </div>
   </div>
+
 </form>
+
+<script>
++function() {
+   // Return a helper with preserved width of cells
+   var fixHelper = function(e, ui) {
+      ui.children().each(function() {
+          $(this).width($(this).width());
+      });
+      return ui;
+   };
+   // Sortable tables for dynamic forms objects
+   $('.sortable-rows').sortable({
+       'helper': fixHelper,
+       'cursor': 'move',
+       'stop': function(e, ui) {
+           var attr = ui.item.parent('tbody').data('sort'),
+               offset = parseInt($('#sort-offset').val(), 10) || 0;
+           warnOnLeave(ui.item);
+           $('input[name^='+attr+']', ui.item.parent('tbody')).each(function(i, el) {
+               $(el).val(i + 1 + offset);
+           });
+       }
+   });
+}();
+</script>
diff --git a/include/staff/templates/queue-columns.tmpl.php b/include/staff/templates/queue-columns.tmpl.php
new file mode 100644
index 0000000000000000000000000000000000000000..233a7c411defb2f853a22d3563502719efa4f262
--- /dev/null
+++ b/include/staff/templates/queue-columns.tmpl.php
@@ -0,0 +1,163 @@
+<table class="table">
+<?php
+if ($queue->parent) { ?>
+  <tbody>
+    <tr>
+      <td colspan="3">
+        <input type="checkbox" name="inherit-columns" <?php
+          if ($queue->inheritColumns()) echo 'checked="checked"'; ?>
+          onchange="javascript:$(this).closest('table').find('.if-not-inherited').toggle(!$(this).prop('checked'));" />
+        <?php echo __('Inherit columns from the parent queue'); ?>
+        <br /><br />
+      </td>
+    </tr>
+  </tbody>
+<?php }
+      // Adhoc Advanced search does not have customizable columns, but saved
+      // ones do
+      elseif ($queue->__new__) { ?>
+  <tbody>
+    <tr>
+      <td colspan="3">
+        <input type="checkbox" name="inherit-columns" <?php
+          if (count($queue->columns) == 0) echo 'checked="checked"';
+          if ($queue instanceof SavedSearch) echo 'disabled="disabled"'; ?>
+          onchange="javascript:$(this).closest('table').find('.if-not-inherited').toggle(!$(this).prop('checked'));" />
+        <?php echo __('Use standard columns'); ?>
+        <br /><br />
+      </td>
+    </tr>
+  </tbody>
+<?php }
+$hidden_cols = $queue->inheritColumns() || count($queue->columns) === 0;
+?>
+  <tbody class="if-not-inherited <?php if ($hidden_cols) echo 'hidden'; ?>">
+    <tr class="header">
+      <td nowrap><small><b><?php echo __('Heading and Width'); ?></b></small></td>
+      <td><small><b><?php echo __('Column Details'); ?></b></small></td>
+      <td><small><b><?php echo __('Sortable'); ?></b></small></td>
+    </tr>
+  </tbody>
+  <tbody class="sortable-rows if-not-inherited <?php if ($hidden_cols) echo 'hidden'; ?>">
+    <tr id="column-template" class="hidden">
+      <td nowrap>
+        <i class="faded-more icon-sort"></i>
+        <input type="hidden" data-name="column_id" />
+        <input type="text" size="25" data-name="heading"
+          data-translate-tag="" />
+        <input type="text" size="5" data-name="width" />
+      </td>
+      <td>
+<?php if (!$queue instanceof SavedSearch) { ?>
+        <div>
+        <a class="inline action-button"
+            href="#" onclick="javascript:
+            var colid = $(this).closest('tr').find('[data-name=column_id]').val();
+            $.dialog('ajax.php/tickets/search/column/edit/' + colid, 201);
+            return false;
+            "><i class="icon-cog"></i> <?php echo __('Config'); ?></a>
+        </div>
+<?php }
+      else { ?>
+        <input type="text" style="border:none;background:transparent" data-name="name" />
+<?php } ?>
+      </td>
+      <td>
+        <input type="checkbox" data-name="sortable"/>
+        <a href="#" class="pull-right drop-column" title="<?php echo __('Delete');
+          ?>"><i class="icon-trash"></i></a>
+      </td>
+    </tr>
+  </tbody>
+  <tbody class="if-not-inherited <?php if ($hidden_cols) echo 'hidden'; ?>">
+    <tr class="header">
+      <td colspan="3"></td>
+    </tr>
+    <tr>
+      <td colspan="3" id="append-column">
+        <i class="icon-plus-sign"></i>
+        <select id="add-column" data-quick-add="queue-column">
+          <option value="">— <?php echo __('Add a column'); ?> —</option>
+<?php foreach (QueueColumn::objects() as $C) { ?>
+          <option value="<?php echo $C->id; ?>"><?php echo
+              Format::htmlchars($C->name); ?></option>
+<?php } ?>
+<?php if (!$queue instanceof SavedSearch) { ?>
+          <option value="0" data-quick-add>&mdash; <?php echo __('Add New');?> &mdash;</option>
+<?php } ?>
+        </select>
+        <button type="button" class="green button">
+          <?php echo __('Add'); ?>
+        </button>
+      </td>
+    </tr>
+  </tbody>
+</table>
+
+<script>
++function() {
+var Q = setInterval(function() {
+  if ($('#append-column').length == 0)
+    return;
+  clearInterval(Q);
+
+  var addColumn = function(colid, info) {
+    if (!colid) return;
+    var copy = $('#column-template').clone(),
+        name_prefix = 'columns[' + colid + ']';
+    info['column_id'] = colid;
+    copy.find('input[data-name]').each(function() {
+      var $this = $(this),
+          name = $this.data('name');
+
+      if (info[name] !== undefined) {
+        if ($this.is(':checkbox'))
+          $this.prop('checked', info[name]);
+        else
+          $this.val(info[name]);
+      }
+      $this.attr('name', name_prefix + '[' + name + ']');
+    });
+    copy.find('span').text(info['name']);
+    copy.attr('id', '').show().insertBefore($('#column-template'));
+    copy.removeClass('hidden');
+    if (info['trans'] !== undefined) {
+      var input = copy.find('input[data-translate-tag]')
+        .attr('data-translate-tag', info['trans']);
+      if ($.fn.translatable)
+        input.translatable();
+      // Else it will be made translatable when the JS library is loaded
+    }
+    copy.find('a.drop-column').click(function() {
+      $('<option>')
+        .attr('value', copy.find('input[data-name=column_id]').val())
+        .text(info.name)
+        .insertBefore($('#add-column')
+          .find('[data-quick-add]')
+        );
+      copy.fadeOut(function() { $(this).remove(); });
+      return false;
+    });
+    var selected = $('#add-column').find('option[value=' + colid + ']');
+    selected.remove();
+  };
+
+  $('#append-column').find('button').on('click', function() {
+    var selected = $('#add-column').find(':selected'),
+        id = parseInt(selected.val());
+    if (!id)
+        return;
+    addColumn(id, {name: selected.text(), heading: selected.text(), width: 100, sortable: 1});
+    return false;
+  });
+<?php foreach ($queue->getColumns(true) as $C) {
+  echo sprintf('addColumn(%d, {name: %s, heading: %s, width: %d, trans: %s,
+  sortable: %s});',
+    $C->column_id, JsonDataEncoder::encode($C->name),
+    JsonDataEncoder::encode($C->heading), $C->width,
+    JsonDataEncoder::encode($C->getTranslateTag('heading')),
+    $C->isSortable() ? 1 : 0);
+} ?>
+}, 25);
+}();
+</script>
diff --git a/include/staff/templates/queue-tickets.tmpl.php b/include/staff/templates/queue-tickets.tmpl.php
index 664a8d6e151fce4312b5af48c484f55bebc80f6a..50f94fab984f046d999ea614c2c36a48b02b1443 100644
--- a/include/staff/templates/queue-tickets.tmpl.php
+++ b/include/staff/templates/queue-tickets.tmpl.php
@@ -208,8 +208,12 @@ foreach ($tickets as $T) {
     }
     foreach ($columns as $C) {
         list($contents, $styles) = $C->render($T);
-        $style = $styles ? 'style="'.$styles.'"' : '';
-        echo "<td $style><div $style>$contents</div></td>";
+        if ($style = $styles ? 'style="'.$styles.'"' : '') {
+            echo "<td $style><div $style>$contents</div></td>";
+        }
+        else {
+            echo "<td>$contents</td>";
+        }
     }
     echo '</tr>';
 }
diff --git a/scp/tickets.php b/scp/tickets.php
index f1b6f48b191dd96b173f66e554c5a7ad10893bd4..783a27830c8f411892dae17cb497bb04227a1afd 100644
--- a/scp/tickets.php
+++ b/scp/tickets.php
@@ -94,16 +94,16 @@ if (!$ticket) {
         && strpos($queue_id, 'adhoc') === 0
     ) {
         list(,$key) = explode(',', $queue_id, 2);
-        // XXX: De-duplicate and simplify this code
-        $queue = new AdhocSearch(array(
-            'id' => $queue_id,
-            'root' => 'T',
-        ));
         // For queue=queue, use the most recent search
         if (!$key) {
             reset($_SESSION['advsearch']);
             $key = key($_SESSION['advsearch']);
         }
+        // XXX: De-duplicate and simplify this code
+        $queue = new AdhocSearch(array(
+            'id' => "adhoc,$key",
+            'root' => 'T',
+        ));
         $queue->config = $_SESSION['advsearch'][$key];
     }