diff --git a/src/applications/almanac/storage/AlmanacDevice.php b/src/applications/almanac/storage/AlmanacDevice.php
index 19ee3f89ff..d0994174b3 100644
--- a/src/applications/almanac/storage/AlmanacDevice.php
+++ b/src/applications/almanac/storage/AlmanacDevice.php
@@ -1,253 +1,253 @@
 <?php
 
 final class AlmanacDevice
   extends AlmanacDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorCustomFieldInterface,
     PhabricatorApplicationTransactionInterface,
     PhabricatorProjectInterface,
     PhabricatorSSHPublicKeyInterface,
     AlmanacPropertyInterface,
     PhabricatorDestructibleInterface {
 
   protected $name;
   protected $nameIndex;
   protected $mailKey;
   protected $viewPolicy;
   protected $editPolicy;
   protected $isLocked;
 
   private $customFields = self::ATTACHABLE;
   private $almanacProperties = self::ATTACHABLE;
 
   public static function initializeNewDevice() {
     return id(new AlmanacDevice())
       ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
       ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)
       ->attachAlmanacProperties(array())
       ->setIsLocked(0);
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text128',
         'nameIndex' => 'bytes12',
         'mailKey' => 'bytes20',
         'isLocked' => 'bool',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_name' => array(
           'columns' => array('nameIndex'),
           'unique' => true,
         ),
         'key_nametext' => array(
           'columns' => array('name'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(AlmanacDevicePHIDType::TYPECONST);
   }
 
   public function save() {
     AlmanacNames::validateServiceOrDeviceName($this->getName());
 
     $this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
 
     if (!$this->mailKey) {
       $this->mailKey = Filesystem::readRandomCharacters(20);
     }
 
     return parent::save();
   }
 
   public function getURI() {
     return '/almanac/device/view/'.$this->getName().'/';
   }
 
 
   /**
    * Find locked services which are bound to this device, updating the device
    * lock flag if necessary.
    *
    * @return list<phid> List of locking service PHIDs.
    */
   public function rebuildDeviceLocks() {
     $services = id(new AlmanacServiceQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withDevicePHIDs(array($this->getPHID()))
       ->withLocked(true)
       ->execute();
 
     $locked = (bool)count($services);
 
     if ($locked != $this->getIsLocked()) {
       $this->setIsLocked((int)$locked);
       $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
         queryfx(
           $this->establishConnection('w'),
           'UPDATE %T SET isLocked = %d WHERE id = %d',
           $this->getTableName(),
           $this->getIsLocked(),
           $this->getID());
       unset($unguarded);
     }
 
     return $this;
   }
 
 
 /* -(  AlmanacPropertyInterface  )------------------------------------------- */
 
 
   public function attachAlmanacProperties(array $properties) {
     assert_instances_of($properties, 'AlmanacProperty');
     $this->almanacProperties = mpull($properties, null, 'getFieldName');
     return $this;
   }
 
   public function getAlmanacProperties() {
     return $this->assertAttached($this->almanacProperties);
   }
 
   public function hasAlmanacProperty($key) {
     $this->assertAttached($this->almanacProperties);
     return isset($this->almanacProperties[$key]);
   }
 
   public function getAlmanacProperty($key) {
     return $this->assertAttachedKey($this->almanacProperties, $key);
   }
 
   public function getAlmanacPropertyValue($key, $default = null) {
     if ($this->hasAlmanacProperty($key)) {
       return $this->getAlmanacProperty($key)->getFieldValue();
     } else {
       return $default;
     }
   }
 
   public function getAlmanacPropertyFieldSpecifications() {
     return array();
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         if ($this->getIsLocked()) {
           return PhabricatorPolicies::POLICY_NOONE;
         } else {
           return $this->getEditPolicy();
         }
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     if ($capability === PhabricatorPolicyCapability::CAN_EDIT) {
       if ($this->getIsLocked()) {
         return pht(
           'This device is bound to a locked service, so it can not '.
           'be edited.');
       }
     }
 
     return null;
   }
 
 
 /* -(  PhabricatorCustomFieldInterface  )------------------------------------ */
 
 
   public function getCustomFieldSpecificationForRole($role) {
     return array();
   }
 
   public function getCustomFieldBaseClass() {
     return 'AlmanacCustomField';
   }
 
   public function getCustomFields() {
     return $this->assertAttached($this->customFields);
   }
 
   public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
     $this->customFields = $fields;
     return $this;
   }
 
 
 /* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
 
 
   public function getApplicationTransactionEditor() {
     return new AlmanacDeviceEditor();
   }
 
   public function getApplicationTransactionObject() {
     return $this;
   }
 
   public function getApplicationTransactionTemplate() {
     return new AlmanacDeviceTransaction();
   }
 
   public function willRenderTimeline(
     PhabricatorApplicationTransactionView $timeline,
     AphrontRequest $request) {
 
     return $timeline;
   }
 
 
 /* -(  PhabricatorSSHPublicKeyInterface  )----------------------------------- */
 
 
   public function getSSHPublicKeyManagementURI(PhabricatorUser $viewer) {
     return $this->getURI();
   }
 
   public function getSSHKeyDefaultName() {
     return $this->getName();
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $interfaces = id(new AlmanacInterfaceQuery())
-      ->setViewer(PhabricatorUser::getOmnipotentUser())
+      ->setViewer($engine->getViewer())
       ->withDevicePHIDs(array($this->getPHID()))
       ->execute();
     foreach ($interfaces as $interface) {
       $engine->destroyObject($interface);
     }
 
     $this->delete();
   }
 
 }
diff --git a/src/applications/almanac/storage/AlmanacInterface.php b/src/applications/almanac/storage/AlmanacInterface.php
index 5ab892cef7..729e95aa9a 100644
--- a/src/applications/almanac/storage/AlmanacInterface.php
+++ b/src/applications/almanac/storage/AlmanacInterface.php
@@ -1,132 +1,132 @@
 <?php
 
 final class AlmanacInterface
   extends AlmanacDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorDestructibleInterface {
 
   protected $devicePHID;
   protected $networkPHID;
   protected $address;
   protected $port;
 
   private $device = self::ATTACHABLE;
   private $network = self::ATTACHABLE;
 
   public static function initializeNewInterface() {
     return id(new AlmanacInterface());
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'address' => 'text64',
         'port' => 'uint32',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_location' => array(
           'columns' => array('networkPHID', 'address', 'port'),
         ),
         'key_device' => array(
           'columns' => array('devicePHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       AlmanacInterfacePHIDType::TYPECONST);
   }
 
   public function getDevice() {
     return $this->assertAttached($this->device);
   }
 
   public function attachDevice(AlmanacDevice $device) {
     $this->device = $device;
     return $this;
   }
 
   public function getNetwork() {
     return $this->assertAttached($this->network);
   }
 
   public function attachNetwork(AlmanacNetwork $network) {
     $this->network = $network;
     return $this;
   }
 
   public function toAddress() {
     return AlmanacAddress::newFromParts(
       $this->getNetworkPHID(),
       $this->getAddress(),
       $this->getPort());
   }
 
   public function getAddressHash() {
     return $this->toAddress()->toHash();
   }
 
   public function renderDisplayAddress() {
     return $this->getAddress().':'.$this->getPort();
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     return $this->getDevice()->getPolicy($capability);
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return $this->getDevice()->hasAutomaticCapability($capability, $viewer);
   }
 
   public function describeAutomaticCapability($capability) {
     $notes = array(
       pht('An interface inherits the policies of the device it belongs to.'),
       pht(
         'You must be able to view the network an interface resides on to '.
         'view the interface.'),
     );
 
     if ($capability === PhabricatorPolicyCapability::CAN_EDIT) {
       if ($this->getDevice()->getIsLocked()) {
         $notes[] = pht(
           'The device for this interface is locked, so it can not be edited.');
       }
     }
 
     return $notes;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $bindings = id(new AlmanacBindingQuery())
-      ->setViewer($this->getViewer())
+      ->setViewer($engine->getViewer())
       ->withInterfacePHIDs(array($this->getPHID()))
       ->execute();
     foreach ($bindings as $binding) {
       $engine->destroyObject($binding);
     }
 
     $this->delete();
   }
 
 }
diff --git a/src/applications/almanac/storage/AlmanacNetwork.php b/src/applications/almanac/storage/AlmanacNetwork.php
index 92d4b8fa47..a623248fd9 100644
--- a/src/applications/almanac/storage/AlmanacNetwork.php
+++ b/src/applications/almanac/storage/AlmanacNetwork.php
@@ -1,117 +1,117 @@
 <?php
 
 final class AlmanacNetwork
   extends AlmanacDAO
   implements
     PhabricatorApplicationTransactionInterface,
     PhabricatorPolicyInterface,
     PhabricatorDestructibleInterface {
 
   protected $name;
   protected $mailKey;
   protected $viewPolicy;
   protected $editPolicy;
 
   public static function initializeNewNetwork() {
     return id(new AlmanacNetwork())
       ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
       ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN);
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text128',
         'mailKey' => 'bytes20',
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(AlmanacNetworkPHIDType::TYPECONST);
   }
 
   public function save() {
     if (!$this->mailKey) {
       $this->mailKey = Filesystem::readRandomCharacters(20);
     }
 
     return parent::save();
   }
 
   public function getURI() {
     return '/almanac/network/'.$this->getID().'/';
   }
 
 
 /* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
 
 
   public function getApplicationTransactionEditor() {
     return new AlmanacNetworkEditor();
   }
 
   public function getApplicationTransactionObject() {
     return $this;
   }
 
   public function getApplicationTransactionTemplate() {
     return new AlmanacNetworkTransaction();
   }
 
   public function willRenderTimeline(
     PhabricatorApplicationTransactionView $timeline,
     AphrontRequest $request) {
 
     return $timeline;
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return $this->getEditPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $interfaces = id(new AlmanacInterfaceQuery())
-      ->setViewer(PhabricatorUser::getOmnipotentUser())
+      ->setViewer($engine->getViewer())
       ->withNetworkPHIDs(array($this->getPHID()))
       ->execute();
 
     foreach ($interfaces as $interface) {
       $engine->destroyObject($interface);
     }
 
     $this->delete();
   }
 
 }
diff --git a/src/applications/almanac/storage/AlmanacService.php b/src/applications/almanac/storage/AlmanacService.php
index 36c7761e22..b351f0d3fc 100644
--- a/src/applications/almanac/storage/AlmanacService.php
+++ b/src/applications/almanac/storage/AlmanacService.php
@@ -1,234 +1,234 @@
 <?php
 
 final class AlmanacService
   extends AlmanacDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorCustomFieldInterface,
     PhabricatorApplicationTransactionInterface,
     PhabricatorProjectInterface,
     AlmanacPropertyInterface,
     PhabricatorDestructibleInterface {
 
   protected $name;
   protected $nameIndex;
   protected $mailKey;
   protected $viewPolicy;
   protected $editPolicy;
   protected $serviceClass;
   protected $isLocked;
 
   private $customFields = self::ATTACHABLE;
   private $almanacProperties = self::ATTACHABLE;
   private $bindings = self::ATTACHABLE;
   private $serviceType = self::ATTACHABLE;
 
   public static function initializeNewService() {
     return id(new AlmanacService())
       ->setViewPolicy(PhabricatorPolicies::POLICY_USER)
       ->setEditPolicy(PhabricatorPolicies::POLICY_ADMIN)
       ->attachAlmanacProperties(array())
       ->setIsLocked(0);
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text128',
         'nameIndex' => 'bytes12',
         'mailKey' => 'bytes20',
         'serviceClass' => 'text64',
         'isLocked' => 'bool',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_name' => array(
           'columns' => array('nameIndex'),
           'unique' => true,
         ),
         'key_nametext' => array(
           'columns' => array('name'),
         ),
         'key_class' => array(
           'columns' => array('serviceClass'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(AlmanacServicePHIDType::TYPECONST);
   }
 
   public function save() {
     AlmanacNames::validateServiceOrDeviceName($this->getName());
 
     $this->nameIndex = PhabricatorHash::digestForIndex($this->getName());
 
     if (!$this->mailKey) {
       $this->mailKey = Filesystem::readRandomCharacters(20);
     }
 
     return parent::save();
   }
 
   public function getURI() {
     return '/almanac/service/view/'.$this->getName().'/';
   }
 
   public function getBindings() {
     return $this->assertAttached($this->bindings);
   }
 
   public function attachBindings(array $bindings) {
     $this->bindings = $bindings;
     return $this;
   }
 
   public function getServiceType() {
     return $this->assertAttached($this->serviceType);
   }
 
   public function attachServiceType(AlmanacServiceType $type) {
     $this->serviceType = $type;
     return $this;
   }
 
 
 /* -(  AlmanacPropertyInterface  )------------------------------------------- */
 
 
   public function attachAlmanacProperties(array $properties) {
     assert_instances_of($properties, 'AlmanacProperty');
     $this->almanacProperties = mpull($properties, null, 'getFieldName');
     return $this;
   }
 
   public function getAlmanacProperties() {
     return $this->assertAttached($this->almanacProperties);
   }
 
   public function hasAlmanacProperty($key) {
     $this->assertAttached($this->almanacProperties);
     return isset($this->almanacProperties[$key]);
   }
 
   public function getAlmanacProperty($key) {
     return $this->assertAttachedKey($this->almanacProperties, $key);
   }
 
   public function getAlmanacPropertyValue($key, $default = null) {
     if ($this->hasAlmanacProperty($key)) {
       return $this->getAlmanacProperty($key)->getFieldValue();
     } else {
       return $default;
     }
   }
 
   public function getAlmanacPropertyFieldSpecifications() {
     return $this->getServiceType()->getFieldSpecifications();
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         if ($this->getIsLocked()) {
           return PhabricatorPolicies::POLICY_NOONE;
         } else {
           return $this->getEditPolicy();
         }
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_EDIT:
         if ($this->getIsLocked()) {
           return pht('This service is locked and can not be edited.');
         }
         break;
     }
 
     return null;
   }
 
 
 /* -(  PhabricatorCustomFieldInterface  )------------------------------------ */
 
 
   public function getCustomFieldSpecificationForRole($role) {
     return array();
   }
 
   public function getCustomFieldBaseClass() {
     return 'AlmanacCustomField';
   }
 
   public function getCustomFields() {
     return $this->assertAttached($this->customFields);
   }
 
   public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
     $this->customFields = $fields;
     return $this;
   }
 
 
 /* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
 
 
   public function getApplicationTransactionEditor() {
     return new AlmanacServiceEditor();
   }
 
   public function getApplicationTransactionObject() {
     return $this;
   }
 
   public function getApplicationTransactionTemplate() {
     return new AlmanacServiceTransaction();
   }
 
   public function willRenderTimeline(
     PhabricatorApplicationTransactionView $timeline,
     AphrontRequest $request) {
 
     return $timeline;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $bindings = id(new AlmanacBindingQuery())
-      ->setViewer(PhabricatorUser::getOmnipotentUser())
+      ->setViewer($engine->getViewer())
       ->withServicePHIDs(array($this->getPHID()))
       ->execute();
     foreach ($bindings as $binding) {
       $engine->destroyObject($binding);
     }
 
     $this->delete();
   }
 
 }
diff --git a/src/applications/differential/storage/DifferentialRevision.php b/src/applications/differential/storage/DifferentialRevision.php
index 74f3ff34d7..e6baa678e9 100644
--- a/src/applications/differential/storage/DifferentialRevision.php
+++ b/src/applications/differential/storage/DifferentialRevision.php
@@ -1,581 +1,581 @@
 <?php
 
 final class DifferentialRevision extends DifferentialDAO
   implements
     PhabricatorTokenReceiverInterface,
     PhabricatorPolicyInterface,
     PhabricatorFlaggableInterface,
     PhrequentTrackableInterface,
     HarbormasterBuildableInterface,
     PhabricatorSubscribableInterface,
     PhabricatorCustomFieldInterface,
     PhabricatorApplicationTransactionInterface,
     PhabricatorMentionableInterface,
     PhabricatorDestructibleInterface,
     PhabricatorProjectInterface {
 
   protected $title = '';
   protected $originalTitle;
   protected $status;
 
   protected $summary = '';
   protected $testPlan = '';
 
   protected $authorPHID;
   protected $lastReviewerPHID;
 
   protected $lineCount = 0;
   protected $attached = array();
 
   protected $mailKey;
   protected $branchName;
   protected $arcanistProjectPHID;
   protected $repositoryPHID;
   protected $viewPolicy = PhabricatorPolicies::POLICY_USER;
   protected $editPolicy = PhabricatorPolicies::POLICY_USER;
 
   private $relationships = self::ATTACHABLE;
   private $commits = self::ATTACHABLE;
   private $activeDiff = self::ATTACHABLE;
   private $diffIDs = self::ATTACHABLE;
   private $hashes = self::ATTACHABLE;
   private $repository = self::ATTACHABLE;
 
   private $reviewerStatus = self::ATTACHABLE;
   private $customFields = self::ATTACHABLE;
   private $drafts = array();
   private $flags = array();
 
   const TABLE_COMMIT          = 'differential_commit';
 
   const RELATION_REVIEWER     = 'revw';
   const RELATION_SUBSCRIBED   = 'subd';
 
   public static function initializeNewRevision(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
       ->setViewer($actor)
       ->withClasses(array('PhabricatorDifferentialApplication'))
       ->executeOne();
 
     $view_policy = $app->getPolicy(
       DifferentialDefaultViewCapability::CAPABILITY);
 
     return id(new DifferentialRevision())
       ->setViewPolicy($view_policy)
       ->setAuthorPHID($actor->getPHID())
       ->attachRelationships(array())
       ->setStatus(ArcanistDifferentialRevisionStatus::NEEDS_REVIEW);
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'attached'      => self::SERIALIZATION_JSON,
         'unsubscribed'  => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'title' => 'text255',
         'originalTitle' => 'text255',
         'status' => 'text32',
         'summary' => 'text',
         'testPlan' => 'text',
         'authorPHID' => 'phid?',
         'lastReviewerPHID' => 'phid?',
         'lineCount' => 'uint32?',
         'mailKey' => 'bytes40',
         'branchName' => 'text255?',
         'arcanistProjectPHID' => 'phid?',
         'repositoryPHID' => 'phid?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'authorPHID' => array(
           'columns' => array('authorPHID', 'status'),
         ),
         'repositoryPHID' => array(
           'columns' => array('repositoryPHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function getMonogram() {
     $id = $this->getID();
     return "D{$id}";
   }
 
   public function setTitle($title) {
     $this->title = $title;
     if (!$this->getID()) {
       $this->originalTitle = $title;
     }
     return $this;
   }
 
   public function loadIDsByCommitPHIDs($phids) {
     if (!$phids) {
       return array();
     }
     $revision_ids = queryfx_all(
       $this->establishConnection('r'),
       'SELECT * FROM %T WHERE commitPHID IN (%Ls)',
       self::TABLE_COMMIT,
       $phids);
     return ipull($revision_ids, 'revisionID', 'commitPHID');
   }
 
   public function loadCommitPHIDs() {
     if (!$this->getID()) {
       return ($this->commits = array());
     }
 
     $commits = queryfx_all(
       $this->establishConnection('r'),
       'SELECT commitPHID FROM %T WHERE revisionID = %d',
       self::TABLE_COMMIT,
       $this->getID());
     $commits = ipull($commits, 'commitPHID');
 
     return ($this->commits = $commits);
   }
 
   public function getCommitPHIDs() {
     return $this->assertAttached($this->commits);
   }
 
   public function getActiveDiff() {
     // TODO: Because it's currently technically possible to create a revision
     // without an associated diff, we allow an attached-but-null active diff.
     // It would be good to get rid of this once we make diff-attaching
     // transactional.
 
     return $this->assertAttached($this->activeDiff);
   }
 
   public function attachActiveDiff($diff) {
     $this->activeDiff = $diff;
     return $this;
   }
 
   public function getDiffIDs() {
     return $this->assertAttached($this->diffIDs);
   }
 
   public function attachDiffIDs(array $ids) {
     rsort($ids);
     $this->diffIDs = array_values($ids);
     return $this;
   }
 
   public function attachCommitPHIDs(array $phids) {
     $this->commits = array_values($phids);
     return $this;
   }
 
   public function getAttachedPHIDs($type) {
     return array_keys(idx($this->attached, $type, array()));
   }
 
   public function setAttachedPHIDs($type, array $phids) {
     $this->attached[$type] = array_fill_keys($phids, array());
     return $this;
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       DifferentialRevisionPHIDType::TYPECONST);
   }
 
   public function loadActiveDiff() {
     return id(new DifferentialDiff())->loadOneWhere(
       'revisionID = %d ORDER BY id DESC LIMIT 1',
       $this->getID());
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->mailKey = Filesystem::readRandomCharacters(40);
     }
     return parent::save();
   }
 
   public function loadRelationships() {
     if (!$this->getID()) {
       $this->relationships = array();
       return;
     }
 
     $data = array();
 
     $subscriber_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
       $this->getPHID(),
       PhabricatorObjectHasSubscriberEdgeType::EDGECONST);
     $subscriber_phids = array_reverse($subscriber_phids);
     foreach ($subscriber_phids as $phid) {
       $data[] = array(
         'relation' => self::RELATION_SUBSCRIBED,
         'objectPHID' => $phid,
         'reasonPHID' => null,
       );
     }
 
     $reviewer_phids = PhabricatorEdgeQuery::loadDestinationPHIDs(
       $this->getPHID(),
       DifferentialRevisionHasReviewerEdgeType::EDGECONST);
     $reviewer_phids = array_reverse($reviewer_phids);
     foreach ($reviewer_phids as $phid) {
       $data[] = array(
         'relation' => self::RELATION_REVIEWER,
         'objectPHID' => $phid,
         'reasonPHID' => null,
       );
     }
 
     return $this->attachRelationships($data);
   }
 
   public function attachRelationships(array $relationships) {
     $this->relationships = igroup($relationships, 'relation');
     return $this;
   }
 
   public function getReviewers() {
     return $this->getRelatedPHIDs(self::RELATION_REVIEWER);
   }
 
   public function getCCPHIDs() {
     return $this->getRelatedPHIDs(self::RELATION_SUBSCRIBED);
   }
 
   private function getRelatedPHIDs($relation) {
     $this->assertAttached($this->relationships);
 
     return ipull($this->getRawRelations($relation), 'objectPHID');
   }
 
   public function getRawRelations($relation) {
     return idx($this->relationships, $relation, array());
   }
 
   public function getPrimaryReviewer() {
     $reviewers = $this->getReviewers();
     $last = $this->lastReviewerPHID;
     if (!$last || !in_array($last, $reviewers)) {
       return head($this->getReviewers());
     }
     return $last;
   }
 
   public function getHashes() {
     return $this->assertAttached($this->hashes);
   }
 
   public function attachHashes(array $hashes) {
     $this->hashes = $hashes;
     return $this;
   }
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         return $this->getViewPolicy();
       case PhabricatorPolicyCapability::CAN_EDIT:
         return $this->getEditPolicy();
     }
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $user) {
     // A revision's author (which effectively means "owner" after we added
     // commandeering) can always view and edit it.
     $author_phid = $this->getAuthorPHID();
     if ($author_phid) {
       if ($user->getPHID() == $author_phid) {
         return true;
       }
     }
 
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     $description = array(
       pht('The owner of a revision can always view and edit it.'),
     );
 
     switch ($capability) {
       case PhabricatorPolicyCapability::CAN_VIEW:
         $description[] = pht(
           "A revision's reviewers can always view it.");
         $description[] = pht(
           'If a revision belongs to a repository, other users must be able '.
           'to view the repository in order to view the revision.');
         break;
     }
 
     return $description;
   }
 
   public function getUsersToNotifyOfTokenGiven() {
     return array(
       $this->getAuthorPHID(),
     );
   }
 
   public function getReviewerStatus() {
     return $this->assertAttached($this->reviewerStatus);
   }
 
   public function attachReviewerStatus(array $reviewers) {
     assert_instances_of($reviewers, 'DifferentialReviewer');
 
     $this->reviewerStatus = $reviewers;
     return $this;
   }
 
   public function getRepository() {
     return $this->assertAttached($this->repository);
   }
 
   public function attachRepository(PhabricatorRepository $repository = null) {
     $this->repository = $repository;
     return $this;
   }
 
   public function isClosed() {
     return DifferentialRevisionStatus::isClosedStatus($this->getStatus());
   }
 
   public function getFlag(PhabricatorUser $viewer) {
     return $this->assertAttachedKey($this->flags, $viewer->getPHID());
   }
 
   public function attachFlag(
     PhabricatorUser $viewer,
     PhabricatorFlag $flag = null) {
     $this->flags[$viewer->getPHID()] = $flag;
     return $this;
   }
 
   public function getDrafts(PhabricatorUser $viewer) {
     return $this->assertAttachedKey($this->drafts, $viewer->getPHID());
   }
 
   public function attachDrafts(PhabricatorUser $viewer, array $drafts) {
     $this->drafts[$viewer->getPHID()] = $drafts;
     return $this;
   }
 
 
 /* -(  HarbormasterBuildableInterface  )------------------------------------- */
 
 
   public function getHarbormasterBuildablePHID() {
     return $this->loadActiveDiff()->getPHID();
   }
 
   public function getHarbormasterContainerPHID() {
     return $this->getPHID();
   }
 
   public function getBuildVariables() {
     return array();
   }
 
   public function getAvailableBuildVariables() {
     return array();
   }
 
 
 /* -(  PhabricatorSubscribableInterface  )----------------------------------- */
 
 
   public function isAutomaticallySubscribed($phid) {
     if ($phid == $this->getAuthorPHID()) {
       return true;
     }
 
     // TODO: This only happens when adding or removing CCs, and is safe from a
     // policy perspective, but the subscription pathway should have some
     // opportunity to load this data properly. For now, this is the only case
     // where implicit subscription is not an intrinsic property of the object.
     if ($this->reviewerStatus == self::ATTACHABLE) {
       $reviewers = id(new DifferentialRevisionQuery())
         ->setViewer(PhabricatorUser::getOmnipotentUser())
         ->withPHIDs(array($this->getPHID()))
         ->needReviewerStatus(true)
         ->executeOne()
         ->getReviewerStatus();
     } else {
       $reviewers = $this->getReviewerStatus();
     }
 
     foreach ($reviewers as $reviewer) {
       if ($reviewer->getReviewerPHID() == $phid) {
         return true;
       }
     }
 
     return false;
   }
 
   public function shouldShowSubscribersProperty() {
     return true;
   }
 
   public function shouldAllowSubscription($phid) {
     return true;
   }
 
 
 /* -(  PhabricatorCustomFieldInterface  )------------------------------------ */
 
 
   public function getCustomFieldSpecificationForRole($role) {
     return PhabricatorEnv::getEnvConfig('differential.fields');
   }
 
   public function getCustomFieldBaseClass() {
     return 'DifferentialCustomField';
   }
 
   public function getCustomFields() {
     return $this->assertAttached($this->customFields);
   }
 
   public function attachCustomFields(PhabricatorCustomFieldAttachment $fields) {
     $this->customFields = $fields;
     return $this;
   }
 
 
 /* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
 
 
   public function getApplicationTransactionEditor() {
     return new DifferentialTransactionEditor();
   }
 
   public function getApplicationTransactionObject() {
     return $this;
   }
 
   public function getApplicationTransactionTemplate() {
     return new DifferentialTransaction();
   }
 
   public function willRenderTimeline(
     PhabricatorApplicationTransactionView $timeline,
     AphrontRequest $request) {
     $viewer = $request->getViewer();
 
     $render_data = $timeline->getRenderData();
     $left = $request->getInt('left', idx($render_data, 'left'));
     $right = $request->getInt('right', idx($render_data, 'right'));
 
     $diffs = id(new DifferentialDiffQuery())
       ->setViewer($request->getUser())
       ->withIDs(array($left, $right))
       ->execute();
     $diffs = mpull($diffs, null, 'getID');
     $left_diff = $diffs[$left];
     $right_diff = $diffs[$right];
 
     $old_ids = $request->getStr('old', idx($render_data, 'old'));
     $new_ids = $request->getStr('new', idx($render_data, 'new'));
     $old_ids = array_filter(explode(',', $old_ids));
     $new_ids = array_filter(explode(',', $new_ids));
 
     $type_inline = DifferentialTransaction::TYPE_INLINE;
     $changeset_ids = array_merge($old_ids, $new_ids);
     $inlines = array();
     foreach ($timeline->getTransactions() as $xaction) {
       if ($xaction->getTransactionType() == $type_inline) {
         $inlines[] = $xaction->getComment();
         $changeset_ids[] = $xaction->getComment()->getChangesetID();
       }
     }
 
     if ($changeset_ids) {
       $changesets = id(new DifferentialChangesetQuery())
         ->setViewer($request->getUser())
         ->withIDs($changeset_ids)
         ->execute();
       $changesets = mpull($changesets, null, 'getID');
     } else {
       $changesets = array();
     }
 
     foreach ($inlines as $key => $inline) {
       $inlines[$key] = DifferentialInlineComment::newFromModernComment(
         $inline);
     }
 
     $query = id(new DifferentialInlineCommentQuery())
       ->setViewer($viewer);
 
     // NOTE: This is a bit sketchy: this method adjusts the inlines as a
     // side effect, which means it will ultimately adjust the transaction
     // comments and affect timeline rendering.
     $query->adjustInlinesForChangesets(
       $inlines,
       array_select_keys($changesets, $old_ids),
       array_select_keys($changesets, $new_ids),
       $this);
 
     return $timeline
       ->setChangesets($changesets)
       ->setRevision($this)
       ->setLeftDiff($left_diff)
       ->setRightDiff($right_diff);
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
       $diffs = id(new DifferentialDiffQuery())
-        ->setViewer(PhabricatorUser::getOmnipotentUser())
+        ->setViewer($engine->getViewer())
         ->withRevisionIDs(array($this->getID()))
         ->execute();
       foreach ($diffs as $diff) {
         $engine->destroyObject($diff);
       }
 
       $conn_w = $this->establishConnection('w');
 
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE revisionID = %d',
         self::TABLE_COMMIT,
         $this->getID());
 
       // we have to do paths a little differentally as they do not have
       // an id or phid column for delete() to act on
       $dummy_path = new DifferentialAffectedPath();
       queryfx(
         $conn_w,
         'DELETE FROM %T WHERE revisionID = %d',
         $dummy_path->getTableName(),
         $this->getID());
 
       $this->delete();
     $this->saveTransaction();
   }
 
 }
diff --git a/src/applications/diviner/storage/DivinerLiveBook.php b/src/applications/diviner/storage/DivinerLiveBook.php
index 68a6f8a0ec..ef7a9bb277 100644
--- a/src/applications/diviner/storage/DivinerLiveBook.php
+++ b/src/applications/diviner/storage/DivinerLiveBook.php
@@ -1,108 +1,108 @@
 <?php
 
 final class DivinerLiveBook extends DivinerDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorDestructibleInterface {
 
   protected $name;
   protected $viewPolicy;
   protected $configurationData = array();
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_SERIALIZATION => array(
         'configurationData' => self::SERIALIZATION_JSON,
       ),
       self::CONFIG_COLUMN_SCHEMA => array(
         'name' => 'text64',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_phid' => null,
         'phid' => array(
           'columns' => array('phid'),
           'unique' => true,
         ),
         'name' => array(
           'columns' => array('name'),
           'unique' => true,
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function getConfig($key, $default = null) {
     return idx($this->configurationData, $key, $default);
   }
 
   public function setConfig($key, $value) {
     $this->configurationData[$key] = $value;
     return $this;
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       DivinerBookPHIDType::TYPECONST);
   }
 
   public function getTitle() {
     return $this->getConfig('title', $this->getName());
   }
 
   public function getShortTitle() {
     return $this->getConfig('short', $this->getTitle());
   }
 
   public function getPreface() {
     return $this->getConfig('preface');
   }
 
   public function getGroupName($group) {
     $groups = $this->getConfig('groups', array());
     $spec = idx($groups, $group, array());
     return idx($spec, 'name', $group);
   }
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
     );
   }
 
   public function getPolicy($capability) {
     return PhabricatorPolicies::getMostOpenPolicy();
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $this->openTransaction();
       $atoms = id(new DivinerAtomQuery())
-        ->setViewer(PhabricatorUser::getOmnipotentUser())
+        ->setViewer($engine->getViewer())
         ->withBookPHIDs(array($this->getPHID()))
         ->withIncludeGhosts(true)
         ->withIncludeUndocumentable(true)
         ->execute();
 
       foreach ($atoms as $atom) {
         $engine->destroyObject($atom);
       }
 
       $this->delete();
     $this->saveTransaction();
   }
 
 }
diff --git a/src/applications/files/controller/PhabricatorFileTransformController.php b/src/applications/files/controller/PhabricatorFileTransformController.php
index 5062fe76fc..0e7e2b73d7 100644
--- a/src/applications/files/controller/PhabricatorFileTransformController.php
+++ b/src/applications/files/controller/PhabricatorFileTransformController.php
@@ -1,124 +1,124 @@
 <?php
 
 final class PhabricatorFileTransformController
   extends PhabricatorFileController {
 
   public function shouldRequireLogin() {
     return false;
   }
 
   public function handleRequest(AphrontRequest $request) {
     $viewer = $this->getViewer();
 
     // NOTE: This is a public/CDN endpoint, and permission to see files is
     // controlled by knowing the secret key, not by authentication.
 
     $is_regenerate = $request->getBool('regenerate');
 
     $source_phid = $request->getURIData('phid');
     $file = id(new PhabricatorFileQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withPHIDs(array($source_phid))
       ->executeOne();
     if (!$file) {
       return new Aphront404Response();
     }
 
     $secret_key = $request->getURIData('key');
     if (!$file->validateSecretKey($secret_key)) {
       return new Aphront403Response();
     }
 
     $transform = $request->getURIData('transform');
     $xform = id(new PhabricatorTransformedFile())
       ->loadOneWhere(
         'originalPHID = %s AND transform = %s',
         $source_phid,
         $transform);
 
     if ($xform) {
       if ($is_regenerate) {
         $this->destroyTransform($xform);
       } else {
         return $this->buildTransformedFileResponse($xform);
       }
     }
 
     $xforms = PhabricatorFileTransform::getAllTransforms();
     if (!isset($xforms[$transform])) {
       return new Aphront404Response();
     }
 
     $xform = $xforms[$transform];
 
     // We're essentially just building a cache here and don't need CSRF
     // protection.
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
 
     $xformed_file = null;
     if ($xform->canApplyTransform($file)) {
       try {
         $xformed_file = $xforms[$transform]->applyTransform($file);
       } catch (Exception $ex) {
         // In normal transform mode, we ignore failures and generate a
         // default transform below. If we're explicitly regenerating the
         // thumbnail, rethrow the exception.
         if ($is_regenerate) {
           throw $ex;
         }
       }
     }
 
     if (!$xformed_file) {
       $xformed_file = $xform->getDefaultTransform($file);
     }
 
     if (!$xformed_file) {
       return new Aphront400Response();
     }
 
     $xform = id(new PhabricatorTransformedFile())
       ->setOriginalPHID($source_phid)
       ->setTransform($transform)
       ->setTransformedPHID($xformed_file->getPHID())
       ->save();
 
     return $this->buildTransformedFileResponse($xform);
   }
 
   private function buildTransformedFileResponse(
     PhabricatorTransformedFile $xform) {
 
     $file = id(new PhabricatorFileQuery())
       ->setViewer(PhabricatorUser::getOmnipotentUser())
       ->withPHIDs(array($xform->getTransformedPHID()))
       ->executeOne();
     if (!$file) {
       return new Aphront404Response();
     }
 
     // TODO: We could just delegate to the file view controller instead,
     // which would save the client a roundtrip, but is slightly more complex.
 
     return $file->getRedirectResponse();
   }
 
   private function destroyTransform(PhabricatorTransformedFile $xform) {
+    $engine = new PhabricatorDestructionEngine();
     $file = id(new PhabricatorFileQuery())
-      ->setViewer(PhabricatorUser::getOmnipotentUser())
+      ->setViewer($engine->getViewer())
       ->withPHIDs(array($xform->getTransformedPHID()))
       ->executeOne();
 
     $unguarded = AphrontWriteGuard::beginScopedUnguardedWrites();
 
     if (!$file) {
       $xform->delete();
     } else {
-      $engine = new PhabricatorDestructionEngine();
       $engine->destroyObject($file);
     }
 
     unset($unguarded);
   }
 
 }
diff --git a/src/applications/files/storage/PhabricatorFileChunk.php b/src/applications/files/storage/PhabricatorFileChunk.php
index b69a421fed..eaa10acd63 100644
--- a/src/applications/files/storage/PhabricatorFileChunk.php
+++ b/src/applications/files/storage/PhabricatorFileChunk.php
@@ -1,105 +1,105 @@
 <?php
 
 final class PhabricatorFileChunk extends PhabricatorFileDAO
   implements
     PhabricatorPolicyInterface,
     PhabricatorDestructibleInterface {
 
   protected $chunkHandle;
   protected $byteStart;
   protected $byteEnd;
   protected $dataFilePHID;
 
   private $dataFile = self::ATTACHABLE;
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_TIMESTAMPS => false,
       self::CONFIG_COLUMN_SCHEMA => array(
         'chunkHandle' => 'bytes12',
         'byteStart' => 'uint64',
         'byteEnd' => 'uint64',
         'dataFilePHID' => 'phid?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'key_file' => array(
           'columns' => array('chunkHandle', 'byteStart', 'byteEnd'),
         ),
         'key_data' => array(
           'columns' => array('dataFilePHID'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public static function newChunkHandle() {
     $seed = Filesystem::readRandomBytes(64);
     return PhabricatorHash::digestForIndex($seed);
   }
 
   public static function initializeNewChunk($handle, $start, $end) {
     return id(new PhabricatorFileChunk())
       ->setChunkHandle($handle)
       ->setByteStart($start)
       ->setByteEnd($end);
   }
 
   public function attachDataFile(PhabricatorFile $file = null) {
     $this->dataFile = $file;
     return $this;
   }
 
   public function getDataFile() {
     return $this->assertAttached($this->dataFile);
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
     );
   }
 
 
   public function getPolicy($capability) {
     // These objects are low-level and only accessed through the storage
     // engine, so policies are mostly just in place to let us use the common
     // query infrastructure.
     return PhabricatorPolicies::getMostOpenPolicy();
   }
 
 
   public function hasAutomaticCapability($capability, PhabricatorUser $viewer) {
     return false;
   }
 
 
   public function describeAutomaticCapability($capability) {
     return null;
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     $data_phid = $this->getDataFilePHID();
     if ($data_phid) {
       $data_file = id(new PhabricatorFileQuery())
-        ->setViewer(PhabricatorUser::getOmnipotentUser())
+        ->setViewer($engine->getViewer())
         ->withPHIDs(array($data_phid))
         ->executeOne();
       if ($data_file) {
         $engine->destroyObject($data_file);
       }
     }
 
     $this->delete();
   }
 
 }
diff --git a/src/applications/paste/storage/PhabricatorPaste.php b/src/applications/paste/storage/PhabricatorPaste.php
index 9eb88a77b4..3a0ae754e7 100644
--- a/src/applications/paste/storage/PhabricatorPaste.php
+++ b/src/applications/paste/storage/PhabricatorPaste.php
@@ -1,209 +1,209 @@
 <?php
 
 final class PhabricatorPaste extends PhabricatorPasteDAO
   implements
     PhabricatorSubscribableInterface,
     PhabricatorTokenReceiverInterface,
     PhabricatorFlaggableInterface,
     PhabricatorMentionableInterface,
     PhabricatorPolicyInterface,
     PhabricatorProjectInterface,
     PhabricatorDestructibleInterface,
     PhabricatorApplicationTransactionInterface {
 
   protected $title;
   protected $authorPHID;
   protected $filePHID;
   protected $language;
   protected $parentPHID;
   protected $viewPolicy;
   protected $editPolicy;
   protected $mailKey;
 
   private $content = self::ATTACHABLE;
   private $rawContent = self::ATTACHABLE;
 
   public static function initializeNewPaste(PhabricatorUser $actor) {
     $app = id(new PhabricatorApplicationQuery())
       ->setViewer($actor)
       ->withClasses(array('PhabricatorPasteApplication'))
       ->executeOne();
 
     $view_policy = $app->getPolicy(PasteDefaultViewCapability::CAPABILITY);
     $edit_policy = $app->getPolicy(PasteDefaultEditCapability::CAPABILITY);
 
     return id(new PhabricatorPaste())
       ->setTitle('')
       ->setAuthorPHID($actor->getPHID())
       ->setViewPolicy($view_policy)
       ->setEditPolicy($edit_policy);
   }
 
   public function getURI() {
     return '/P'.$this->getID();
   }
 
   protected function getConfiguration() {
     return array(
       self::CONFIG_AUX_PHID => true,
       self::CONFIG_COLUMN_SCHEMA => array(
         'title' => 'text255',
         'language' => 'text64',
         'mailKey' => 'bytes20',
         'parentPHID' => 'phid?',
 
         // T6203/NULLABILITY
         // Pastes should always have a view policy.
         'viewPolicy' => 'policy?',
       ),
       self::CONFIG_KEY_SCHEMA => array(
         'parentPHID' => array(
           'columns' => array('parentPHID'),
         ),
         'authorPHID' => array(
           'columns' => array('authorPHID'),
         ),
         'key_dateCreated' => array(
           'columns' => array('dateCreated'),
         ),
         'key_language' => array(
           'columns' => array('language'),
         ),
       ),
     ) + parent::getConfiguration();
   }
 
   public function generatePHID() {
     return PhabricatorPHID::generateNewPHID(
       PhabricatorPastePastePHIDType::TYPECONST);
   }
 
   public function save() {
     if (!$this->getMailKey()) {
       $this->setMailKey(Filesystem::readRandomCharacters(20));
     }
     return parent::save();
   }
 
   public function getFullName() {
     $title = $this->getTitle();
     if (!$title) {
       $title = pht('(An Untitled Masterwork)');
     }
     return 'P'.$this->getID().' '.$title;
   }
 
   public function getContent() {
     return $this->assertAttached($this->content);
   }
 
   public function attachContent($content) {
     $this->content = $content;
     return $this;
   }
 
   public function getRawContent() {
     return $this->assertAttached($this->rawContent);
   }
 
   public function attachRawContent($raw_content) {
     $this->rawContent = $raw_content;
     return $this;
   }
 
 /* -(  PhabricatorSubscribableInterface  )----------------------------------- */
 
 
   public function isAutomaticallySubscribed($phid) {
     return ($this->authorPHID == $phid);
   }
 
   public function shouldShowSubscribersProperty() {
     return true;
   }
 
   public function shouldAllowSubscription($phid) {
     return true;
   }
 
 
 /* -(  PhabricatorTokenReceiverInterface  )---------------------------------- */
 
   public function getUsersToNotifyOfTokenGiven() {
     return array(
       $this->getAuthorPHID(),
     );
   }
 
 
 /* -(  PhabricatorPolicyInterface  )----------------------------------------- */
 
 
   public function getCapabilities() {
     return array(
       PhabricatorPolicyCapability::CAN_VIEW,
       PhabricatorPolicyCapability::CAN_EDIT,
     );
   }
 
   public function getPolicy($capability) {
     if ($capability == PhabricatorPolicyCapability::CAN_VIEW) {
       return $this->viewPolicy;
     } else if ($capability == PhabricatorPolicyCapability::CAN_EDIT) {
       return $this->editPolicy;
     }
     return PhabricatorPolicies::POLICY_NOONE;
   }
 
   public function hasAutomaticCapability($capability, PhabricatorUser $user) {
     return ($user->getPHID() == $this->getAuthorPHID());
   }
 
   public function describeAutomaticCapability($capability) {
     return pht('The author of a paste can always view and edit it.');
   }
 
 
 /* -(  PhabricatorDestructibleInterface  )----------------------------------- */
 
 
   public function destroyObjectPermanently(
     PhabricatorDestructionEngine $engine) {
 
     if ($this->filePHID) {
       $file = id(new PhabricatorFileQuery())
-        ->setViewer(PhabricatorUser::getOmnipotentUser())
+        ->setViewer($engine->getViewer())
         ->withPHIDs(array($this->filePHID))
         ->executeOne();
       if ($file) {
         $engine->destroyObject($file);
       }
     }
 
     $this->delete();
   }
 
 
 /* -(  PhabricatorApplicationTransactionInterface  )------------------------- */
 
 
   public function getApplicationTransactionEditor() {
     return new PhabricatorPasteEditor();
   }
 
   public function getApplicationTransactionObject() {
     return $this;
   }
 
   public function getApplicationTransactionTemplate() {
     return new PhabricatorPasteTransaction();
   }
 
   public function willRenderTimeline(
     PhabricatorApplicationTransactionView $timeline,
     AphrontRequest $request) {
 
     return $timeline;
   }
 
 }
diff --git a/src/applications/system/engine/PhabricatorDestructionEngine.php b/src/applications/system/engine/PhabricatorDestructionEngine.php
index b55b336052..c5b813169c 100644
--- a/src/applications/system/engine/PhabricatorDestructionEngine.php
+++ b/src/applications/system/engine/PhabricatorDestructionEngine.php
@@ -1,124 +1,128 @@
 <?php
 
 final class PhabricatorDestructionEngine extends Phobject {
 
   private $rootLogID;
 
+  public function getViewer() {
+    return PhabricatorUser::getOmnipotentUser();
+  }
+
   public function destroyObject(PhabricatorDestructibleInterface $object) {
     $log = id(new PhabricatorSystemDestructionLog())
       ->setEpoch(time())
       ->setObjectClass(get_class($object));
 
     if ($this->rootLogID) {
       $log->setRootLogID($this->rootLogID);
     }
 
     $object_phid = null;
     if (method_exists($object, 'getPHID')) {
       try {
         $object_phid = $object->getPHID();
         $log->setObjectPHID($object_phid);
       } catch (Exception $ex) {
         // Ignore.
       }
     }
 
     if (method_exists($object, 'getMonogram')) {
       try {
         $log->setObjectMonogram($object->getMonogram());
       } catch (Exception $ex) {
         // Ignore.
       }
     }
 
     $log->save();
 
     if (!$this->rootLogID) {
       $this->rootLogID = $log->getID();
     }
 
     $object->destroyObjectPermanently($this);
 
     if ($object_phid) {
       $this->destroyEdges($object_phid);
 
       if ($object instanceof PhabricatorApplicationTransactionInterface) {
         $template = $object->getApplicationTransactionTemplate();
         $this->destroyTransactions($template, $object_phid);
       }
 
       $this->destroyWorkerTasks($object_phid);
       $this->destroyNotifications($object_phid);
     }
 
     // Nuke any Herald transcripts of the object, because they may contain
     // field data.
 
     // TODO: Define an interface so we don't have to do this for transactions
     // and other objects with no Herald adapters?
     $transcripts = id(new HeraldTranscript())->loadAllWhere(
       'objectPHID = %s',
       $object_phid);
     foreach ($transcripts as $transcript) {
       $transcript->destroyObjectPermanently($this);
     }
 
     // TODO: Remove stuff from search indexes?
     // TODO: PhabricatorFlaggableInterface
     // TODO: PhabricatorTokenReceiverInterface
   }
 
   private function destroyEdges($src_phid) {
     try {
       $edges = id(new PhabricatorEdgeQuery())
         ->withSourcePHIDs(array($src_phid))
         ->execute();
     } catch (Exception $ex) {
       // This is (presumably) a "no edges for this PHID type" exception.
       return;
     }
 
     $editor = new PhabricatorEdgeEditor();
     foreach ($edges as $type => $type_edges) {
       foreach ($type_edges as $src => $src_edges) {
         foreach ($src_edges as $dst => $edge) {
           $editor->removeEdge($edge['src'], $edge['type'], $edge['dst']);
         }
       }
     }
     $editor->save();
   }
 
   private function destroyTransactions(
     PhabricatorApplicationTransaction $template,
     $object_phid) {
 
     $xactions = $template->loadAllWhere('objectPHID = %s', $object_phid);
     foreach ($xactions as $xaction) {
       $this->destroyObject($xaction);
     }
   }
 
   private function destroyWorkerTasks($object_phid) {
     $tasks = id(new PhabricatorWorkerActiveTask())->loadAllWhere(
       'objectPHID = %s',
       $object_phid);
 
     foreach ($tasks as $task) {
       $task->archiveTask(
         PhabricatorWorkerArchiveTask::RESULT_CANCELLED,
         0);
     }
   }
 
   private function destroyNotifications($object_phid) {
     $notifications = id(new PhabricatorFeedStoryNotification())->loadAllWhere(
       'primaryObjectPHID = %s',
       $object_phid);
 
     foreach ($notifications as $notification) {
       $notification->delete();
     }
   }
 
 }