diff --git a/src/applications/pholio/controller/PholioController.php b/src/applications/pholio/controller/PholioController.php
index ad402eb4e3..533945c7c3 100644
--- a/src/applications/pholio/controller/PholioController.php
+++ b/src/applications/pholio/controller/PholioController.php
@@ -1,40 +1,22 @@
 <?php
 
 abstract class PholioController extends PhabricatorController {
 
-  public function buildSideNavView($for_app = false) {
-    $user = $this->getRequest()->getUser();
-
-    $nav = new AphrontSideNavFilterView();
-    $nav->setBaseURI(new PhutilURI($this->getApplicationURI()));
-
-    id(new PholioMockSearchEngine())
-      ->setViewer($user)
-      ->addNavigationItems($nav->getMenu());
-
-    if ($for_app) {
-      $nav->addFilter('new/', pht('Create Mock'));
-    }
-
-    $nav->selectFilter(null);
-
-    return $nav;
+  public function buildApplicationMenu() {
+    return $this->newApplicationMenu()
+      ->setSearchEngine(new PholioMockSearchEngine());
   }
 
   protected function buildApplicationCrumbs() {
     $crumbs = parent::buildApplicationCrumbs();
 
     $crumbs->addAction(
       id(new PHUIListItemView())
         ->setName(pht('Create Mock'))
         ->setHref($this->getApplicationURI('new/'))
         ->setIcon('fa-plus-square'));
 
     return $crumbs;
   }
 
-  public function buildApplicationMenu() {
-    return $this->buildSideNavView(true)->getMenu();
-  }
-
 }
diff --git a/src/applications/pholio/controller/PholioMockEditController.php b/src/applications/pholio/controller/PholioMockEditController.php
index 18423e0050..857f21909b 100644
--- a/src/applications/pholio/controller/PholioMockEditController.php
+++ b/src/applications/pholio/controller/PholioMockEditController.php
@@ -1,394 +1,397 @@
 <?php
 
 final class PholioMockEditController extends PholioController {
 
   public function handleRequest(AphrontRequest $request) {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
 
     if ($id) {
       $mock = id(new PholioMockQuery())
         ->setViewer($viewer)
         ->needImages(true)
         ->requireCapabilities(
           array(
             PhabricatorPolicyCapability::CAN_VIEW,
             PhabricatorPolicyCapability::CAN_EDIT,
           ))
         ->withIDs(array($id))
         ->executeOne();
 
       if (!$mock) {
         return new Aphront404Response();
       }
 
       $title = pht('Edit Mock');
 
       $is_new = false;
       $mock_images = $mock->getImages();
       $files = mpull($mock_images, 'getFile');
       $mock_images = mpull($mock_images, null, 'getFilePHID');
     } else {
       $mock = PholioMock::initializeNewMock($viewer);
 
       $title = pht('Create Mock');
 
       $is_new = true;
       $files = array();
       $mock_images = array();
     }
 
     if ($is_new) {
       $v_projects = array();
     } else {
       $v_projects = PhabricatorEdgeQuery::loadDestinationPHIDs(
         $mock->getPHID(),
         PhabricatorProjectObjectHasProjectEdgeType::EDGECONST);
       $v_projects = array_reverse($v_projects);
     }
 
     $e_name = true;
     $e_images = count($mock_images) ? null : true;
     $errors = array();
     $posted_mock_images = array();
 
     $v_name = $mock->getName();
     $v_desc = $mock->getDescription();
     $v_status = $mock->getStatus();
     $v_view = $mock->getViewPolicy();
     $v_edit = $mock->getEditPolicy();
     $v_cc = PhabricatorSubscribersQuery::loadSubscribersForPHID(
       $mock->getPHID());
     $v_space = $mock->getSpacePHID();
 
     if ($request->isFormPost()) {
       $xactions = array();
 
       $type_name = PholioTransaction::TYPE_NAME;
       $type_desc = PholioTransaction::TYPE_DESCRIPTION;
       $type_status = PholioTransaction::TYPE_STATUS;
       $type_view = PhabricatorTransactions::TYPE_VIEW_POLICY;
       $type_edit = PhabricatorTransactions::TYPE_EDIT_POLICY;
       $type_cc   = PhabricatorTransactions::TYPE_SUBSCRIBERS;
       $type_space = PhabricatorTransactions::TYPE_SPACE;
 
       $v_name = $request->getStr('name');
       $v_desc = $request->getStr('description');
       $v_status = $request->getStr('status');
       $v_view = $request->getStr('can_view');
       $v_edit = $request->getStr('can_edit');
       $v_cc   = $request->getArr('cc');
       $v_projects = $request->getArr('projects');
       $v_space = $request->getStr('spacePHID');
 
       $mock_xactions = array();
       $mock_xactions[$type_name] = $v_name;
       $mock_xactions[$type_desc] = $v_desc;
       $mock_xactions[$type_status] = $v_status;
       $mock_xactions[$type_view] = $v_view;
       $mock_xactions[$type_edit] = $v_edit;
       $mock_xactions[$type_cc]   = array('=' => $v_cc);
       $mock_xactions[$type_space] = $v_space;
 
       if (!strlen($request->getStr('name'))) {
         $e_name = pht('Required');
         $errors[] = pht('You must give the mock a name.');
       }
 
       $file_phids = $request->getArr('file_phids');
       if ($file_phids) {
         $files = id(new PhabricatorFileQuery())
           ->setViewer($viewer)
           ->withPHIDs($file_phids)
           ->execute();
         $files = mpull($files, null, 'getPHID');
         $files = array_select_keys($files, $file_phids);
       } else {
         $files = array();
       }
 
       if (!$files) {
         $e_images = pht('Required');
         $errors[] = pht('You must add at least one image to the mock.');
       } else {
         $mock->setCoverPHID(head($files)->getPHID());
       }
 
       foreach ($mock_xactions as $type => $value) {
         $xactions[$type] = id(new PholioTransaction())
           ->setTransactionType($type)
           ->setNewValue($value);
       }
 
       $order = $request->getStrList('imageOrder');
       $sequence_map = array_flip($order);
       $replaces = $request->getArr('replaces');
       $replaces_map = array_flip($replaces);
 
       /**
        * Foreach file posted, check to see whether we are replacing an image,
        * adding an image, or simply updating image metadata. Create
        * transactions for these cases as appropos.
        */
       foreach ($files as $file_phid => $file) {
         $replaces_image_phid = null;
         if (isset($replaces_map[$file_phid])) {
           $old_file_phid = $replaces_map[$file_phid];
           if ($old_file_phid != $file_phid) {
             $old_image = idx($mock_images, $old_file_phid);
             if ($old_image) {
               $replaces_image_phid = $old_image->getPHID();
             }
           }
         }
 
         $existing_image = idx($mock_images, $file_phid);
 
         $title = (string)$request->getStr('title_'.$file_phid);
         $description = (string)$request->getStr('description_'.$file_phid);
         $sequence = $sequence_map[$file_phid];
 
         if ($replaces_image_phid) {
           $replace_image = id(new PholioImage())
             ->setReplacesImagePHID($replaces_image_phid)
             ->setFilePhid($file_phid)
             ->attachFile($file)
             ->setName(strlen($title) ? $title : $file->getName())
             ->setDescription($description)
             ->setSequence($sequence);
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(
               PholioTransaction::TYPE_IMAGE_REPLACE)
             ->setNewValue($replace_image);
           $posted_mock_images[] = $replace_image;
         } else if (!$existing_image) { // this is an add
           $add_image = id(new PholioImage())
             ->setFilePhid($file_phid)
             ->attachFile($file)
             ->setName(strlen($title) ? $title : $file->getName())
             ->setDescription($description)
             ->setSequence($sequence);
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(PholioTransaction::TYPE_IMAGE_FILE)
             ->setNewValue(
               array('+' => array($add_image)));
           $posted_mock_images[] = $add_image;
         } else {
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(PholioTransaction::TYPE_IMAGE_NAME)
             ->setNewValue(
               array($existing_image->getPHID() => $title));
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(
               PholioTransaction::TYPE_IMAGE_DESCRIPTION)
               ->setNewValue(
                 array($existing_image->getPHID() => $description));
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(
               PholioTransaction::TYPE_IMAGE_SEQUENCE)
               ->setNewValue(
                 array($existing_image->getPHID() => $sequence));
 
           $posted_mock_images[] = $existing_image;
         }
       }
       foreach ($mock_images as $file_phid => $mock_image) {
         if (!isset($files[$file_phid]) && !isset($replaces[$file_phid])) {
           // this is an outright delete
           $xactions[] = id(new PholioTransaction())
             ->setTransactionType(PholioTransaction::TYPE_IMAGE_FILE)
             ->setNewValue(
               array('-' => array($mock_image)));
         }
       }
 
       if (!$errors) {
         $proj_edge_type = PhabricatorProjectObjectHasProjectEdgeType::EDGECONST;
         $xactions[] = id(new PholioTransaction())
           ->setTransactionType(PhabricatorTransactions::TYPE_EDGE)
           ->setMetadataValue('edge:type', $proj_edge_type)
           ->setNewValue(array('=' => array_fuse($v_projects)));
 
         $mock->openTransaction();
         $editor = id(new PholioMockEditor())
           ->setContentSourceFromRequest($request)
           ->setContinueOnNoEffect(true)
           ->setActor($viewer);
 
         $xactions = $editor->applyTransactions($mock, $xactions);
 
         $mock->saveTransaction();
 
         return id(new AphrontRedirectResponse())
           ->setURI('/M'.$mock->getID());
       }
     }
 
     if ($id) {
       $submit = id(new AphrontFormSubmitControl())
         ->addCancelButton('/M'.$id)
         ->setValue(pht('Save'));
     } else {
       $submit = id(new AphrontFormSubmitControl())
         ->addCancelButton($this->getApplicationURI())
         ->setValue(pht('Create'));
     }
 
     $policies = id(new PhabricatorPolicyQuery())
       ->setViewer($viewer)
       ->setObject($mock)
       ->execute();
 
     // NOTE: Make this show up correctly on the rendered form.
     $mock->setViewPolicy($v_view);
     $mock->setEditPolicy($v_edit);
 
     $image_elements = array();
     if ($posted_mock_images) {
       $display_mock_images = $posted_mock_images;
     } else {
       $display_mock_images = $mock_images;
     }
     foreach ($display_mock_images as $mock_image) {
       $image_elements[] = id(new PholioUploadedImageView())
         ->setUser($viewer)
         ->setImage($mock_image)
         ->setReplacesPHID($mock_image->getFilePHID());
     }
 
     $list_id = celerity_generate_unique_node_id();
     $drop_id = celerity_generate_unique_node_id();
     $order_id = celerity_generate_unique_node_id();
 
     $list_control = phutil_tag(
       'div',
       array(
         'id' => $list_id,
         'class' => 'pholio-edit-list',
       ),
       $image_elements);
 
     $drop_control = phutil_tag(
       'div',
       array(
         'id' => $drop_id,
         'class' => 'pholio-edit-drop',
       ),
       pht('Drag and drop images here to add them to the mock.'));
 
     $order_control = phutil_tag(
       'input',
       array(
         'type' => 'hidden',
         'name' => 'imageOrder',
         'id' => $order_id,
       ));
 
     Javelin::initBehavior(
       'pholio-mock-edit',
       array(
         'listID' => $list_id,
         'dropID' => $drop_id,
         'orderID' => $order_id,
         'uploadURI' => '/file/dropupload/',
         'renderURI' => $this->getApplicationURI('image/upload/'),
         'pht' => array(
           'uploading' => pht('Uploading Image...'),
           'uploaded' => pht('Upload Complete...'),
           'undo' => pht('Undo'),
           'removed' => pht('This image will be removed from the mock.'),
         ),
       ));
 
     require_celerity_resource('pholio-edit-css');
     $form = id(new AphrontFormView())
       ->setUser($viewer)
       ->appendChild($order_control)
       ->appendChild(
         id(new AphrontFormTextControl())
         ->setName('name')
         ->setValue($v_name)
         ->setLabel(pht('Name'))
         ->setError($e_name))
       ->appendChild(
         id(new PhabricatorRemarkupControl())
         ->setName('description')
         ->setValue($v_desc)
         ->setLabel(pht('Description'))
         ->setUser($viewer));
 
     if ($id) {
       $form->appendChild(
         id(new AphrontFormSelectControl())
         ->setLabel(pht('Status'))
         ->setName('status')
         ->setValue($mock->getStatus())
         ->setOptions($mock->getStatuses()));
     } else {
       $form->addHiddenInput('status', 'open');
     }
 
     $form
       ->appendControl(
         id(new AphrontFormTokenizerControl())
           ->setLabel(pht('Projects'))
           ->setName('projects')
           ->setValue($v_projects)
           ->setDatasource(new PhabricatorProjectDatasource()))
       ->appendControl(
         id(new AphrontFormTokenizerControl())
           ->setLabel(pht('Subscribers'))
           ->setName('cc')
           ->setValue($v_cc)
           ->setUser($viewer)
           ->setDatasource(new PhabricatorMetaMTAMailableDatasource()))
       ->appendChild(
         id(new AphrontFormPolicyControl())
           ->setUser($viewer)
           ->setCapability(PhabricatorPolicyCapability::CAN_VIEW)
           ->setPolicyObject($mock)
           ->setPolicies($policies)
           ->setSpacePHID($v_space)
           ->setName('can_view'))
       ->appendChild(
         id(new AphrontFormPolicyControl())
           ->setUser($viewer)
           ->setCapability(PhabricatorPolicyCapability::CAN_EDIT)
           ->setPolicyObject($mock)
           ->setPolicies($policies)
           ->setName('can_edit'))
       ->appendChild(
         id(new AphrontFormMarkupControl())
           ->setValue($list_control))
       ->appendChild(
         id(new AphrontFormMarkupControl())
           ->setValue($drop_control)
           ->setError($e_images))
       ->appendChild($submit);
 
     $form_box = id(new PHUIObjectBoxView())
       ->setHeaderText($title)
       ->setFormErrors($errors)
       ->setForm($form);
 
     $crumbs = $this->buildApplicationCrumbs();
     if (!$is_new) {
       $crumbs->addTextCrumb($mock->getMonogram(), '/'.$mock->getMonogram());
     }
     $crumbs->addTextCrumb($title);
 
     $content = array(
       $crumbs,
       $form_box,
     );
 
     $this->addExtraQuicksandConfig(
       array('mockEditConfig' => true));
-    return $this->buildApplicationPage(
-      $content,
-      array(
-        'title' => $title,
+
+    return $this->newPage()
+      ->setTitle($title)
+      ->setCrumbs($crumbs)
+      ->appendChild(
+        array(
+          $form_box,
       ));
   }
 
 }
diff --git a/src/applications/pholio/controller/PholioMockListController.php b/src/applications/pholio/controller/PholioMockListController.php
index b4fa17fc8a..56d513d9ea 100644
--- a/src/applications/pholio/controller/PholioMockListController.php
+++ b/src/applications/pholio/controller/PholioMockListController.php
@@ -1,20 +1,15 @@
 <?php
 
 final class PholioMockListController extends PholioController {
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function handleRequest(AphrontRequest $request) {
-    $querykey = $request->getURIData('queryKey');
-
-    $controller = id(new PhabricatorApplicationSearchController())
-      ->setQueryKey($querykey)
-      ->setSearchEngine(new PholioMockSearchEngine())
-      ->setNavigation($this->buildSideNavView());
-
-    return $this->delegateToController($controller);
+    return id(new PholioMockSearchEngine())
+      ->setController($this)
+      ->buildResponse();
   }
 
 }
diff --git a/src/applications/pholio/controller/PholioMockViewController.php b/src/applications/pholio/controller/PholioMockViewController.php
index c5c6fed16c..8e527ddc57 100644
--- a/src/applications/pholio/controller/PholioMockViewController.php
+++ b/src/applications/pholio/controller/PholioMockViewController.php
@@ -1,211 +1,208 @@
 <?php
 
 final class PholioMockViewController extends PholioController {
 
   private $maniphestTaskPHIDs = array();
 
   private function setManiphestTaskPHIDs($maniphest_task_phids) {
     $this->maniphestTaskPHIDs = $maniphest_task_phids;
     return $this;
   }
   private function getManiphestTaskPHIDs() {
     return $this->maniphestTaskPHIDs;
   }
 
   public function shouldAllowPublic() {
     return true;
   }
 
   public function handleRequest(AphrontRequest $request) {
     $viewer = $request->getViewer();
     $id = $request->getURIData('id');
     $image_id = $request->getURIData('imageID');
 
     $mock = id(new PholioMockQuery())
       ->setViewer($viewer)
       ->withIDs(array($id))
       ->needImages(true)
       ->needInlineComments(true)
       ->executeOne();
 
     if (!$mock) {
       return new Aphront404Response();
     }
 
     $phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
       $mock->getPHID(),
       PholioMockHasTaskEdgeType::EDGECONST);
     $this->setManiphestTaskPHIDs($phids);
 
     $engine = id(new PhabricatorMarkupEngine())
       ->setViewer($viewer);
     $engine->addObject($mock, PholioMock::MARKUP_FIELD_DESCRIPTION);
 
     $title = $mock->getName();
 
     if ($mock->isClosed()) {
       $header_icon = 'fa-ban';
       $header_name = pht('Closed');
       $header_color = 'dark';
     } else {
       $header_icon = 'fa-square-o';
       $header_name = pht('Open');
       $header_color = 'bluegrey';
     }
 
     $header = id(new PHUIHeaderView())
       ->setHeader($title)
       ->setUser($viewer)
       ->setStatus($header_icon, $header_color, $header_name)
       ->setPolicyObject($mock);
 
     $timeline = $this->buildTransactionTimeline(
       $mock,
       new PholioTransactionQuery(),
       $engine);
     $timeline->setMock($mock);
 
     $actions = $this->buildActionView($mock);
     $properties = $this->buildPropertyView($mock, $engine, $actions);
 
     require_celerity_resource('pholio-css');
     require_celerity_resource('pholio-inline-comments-css');
 
     $comment_form_id = celerity_generate_unique_node_id();
     $mock_view = id(new PholioMockImagesView())
       ->setRequestURI($request->getRequestURI())
       ->setCommentFormID($comment_form_id)
       ->setUser($viewer)
       ->setMock($mock)
       ->setImageID($image_id);
     $this->addExtraQuicksandConfig(
       array('mockViewConfig' => $mock_view->getBehaviorConfig()));
 
     $output = id(new PHUIObjectBoxView())
       ->setHeaderText(pht('Image'))
       ->appendChild($mock_view);
 
     $add_comment = $this->buildAddCommentView($mock, $comment_form_id);
 
     $crumbs = $this->buildApplicationCrumbs();
     $crumbs->addTextCrumb('M'.$mock->getID(), '/M'.$mock->getID());
 
     $object_box = id(new PHUIObjectBoxView())
       ->setHeader($header)
       ->addPropertyList($properties);
 
     $thumb_grid = id(new PholioMockThumbGridView())
       ->setUser($viewer)
       ->setMock($mock);
 
-    $content = array(
-      $crumbs,
-      $object_box,
-      $output,
-      $thumb_grid,
-      $timeline,
-      $add_comment,
-    );
-
-    return $this->buildApplicationPage(
-      $content,
-      array(
-        'title' => 'M'.$mock->getID().' '.$title,
-        'pageObjects' => array($mock->getPHID()),
+    return $this->newPage()
+      ->setTitle('M'.$mock->getID().' '.$title)
+      ->setCrumbs($crumbs)
+      ->setPageObjectPHIDs(array($mock->getPHID()))
+      ->appendChild(
+        array(
+          $object_box,
+          $output,
+          $thumb_grid,
+          $timeline,
+          $add_comment,
       ));
   }
 
   private function buildActionView(PholioMock $mock) {
     $viewer = $this->getViewer();
 
     $actions = id(new PhabricatorActionListView())
       ->setUser($viewer)
       ->setObjectURI($this->getRequest()->getRequestURI())
       ->setObject($mock);
 
     $can_edit = PhabricatorPolicyFilter::hasCapability(
       $viewer,
       $mock,
       PhabricatorPolicyCapability::CAN_EDIT);
 
     $actions->addAction(
       id(new PhabricatorActionView())
       ->setIcon('fa-pencil')
       ->setName(pht('Edit Mock'))
       ->setHref($this->getApplicationURI('/edit/'.$mock->getID().'/'))
       ->setDisabled(!$can_edit)
       ->setWorkflow(!$can_edit));
 
     $actions->addAction(
       id(new PhabricatorActionView())
       ->setIcon('fa-anchor')
       ->setName(pht('Edit Maniphest Tasks'))
       ->setHref("/search/attach/{$mock->getPHID()}/TASK/edge/")
       ->setDisabled(!$viewer->isLoggedIn())
       ->setWorkflow(true));
 
     return $actions;
   }
 
   private function buildPropertyView(
     PholioMock $mock,
     PhabricatorMarkupEngine $engine,
     PhabricatorActionListView $actions) {
 
     $viewer = $this->getViewer();
 
     $properties = id(new PHUIPropertyListView())
       ->setUser($viewer)
       ->setObject($mock)
       ->setActionList($actions);
 
     $properties->addProperty(
       pht('Author'),
       $viewer->renderHandle($mock->getAuthorPHID()));
 
     $properties->addProperty(
       pht('Created'),
       phabricator_datetime($mock->getDateCreated(), $viewer));
 
     if ($this->getManiphestTaskPHIDs()) {
       $properties->addProperty(
         pht('Maniphest Tasks'),
         $viewer->renderHandleList($this->getManiphestTaskPHIDs()));
     }
 
     $properties->invokeWillRenderEvent();
 
     $properties->addSectionHeader(
         pht('Description'),
         PHUIPropertyListView::ICON_SUMMARY);
 
     $properties->addImageContent(
         $engine->getOutput($mock, PholioMock::MARKUP_FIELD_DESCRIPTION));
 
     return $properties;
   }
 
   private function buildAddCommentView(PholioMock $mock, $comment_form_id) {
     $viewer = $this->getViewer();
 
     $draft = PhabricatorDraft::newFromUserAndKey($viewer, $mock->getPHID());
 
     $is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
     $title = $is_serious
       ? pht('Add Comment')
       : pht('History Beckons');
 
     $form = id(new PhabricatorApplicationTransactionCommentView())
       ->setUser($viewer)
       ->setObjectPHID($mock->getPHID())
       ->setFormID($comment_form_id)
       ->setDraft($draft)
       ->setHeaderText($title)
       ->setSubmitButtonName(pht('Add Comment'))
       ->setAction($this->getApplicationURI('/comment/'.$mock->getID().'/'))
       ->setRequestURI($this->getRequest()->getRequestURI());
 
     return $form;
   }
 
 }