public function applyExternalEffects($object, $value)
 {
     $old = $this->generateOldValue($object);
     $new = $value;
     $paths = $object->getPaths();
     $diffs = PhabricatorOwnersPath::getTransactionValueChanges($old, $new);
     list($rem, $add) = $diffs;
     $set = PhabricatorOwnersPath::getSetFromTransactionValue($rem);
     foreach ($paths as $path) {
         $ref = $path->getRef();
         if (PhabricatorOwnersPath::isRefInSet($ref, $set)) {
             $path->delete();
         }
     }
     foreach ($add as $ref) {
         $path = PhabricatorOwnersPath::newFromRef($ref)->setPackageID($object->getID())->save();
     }
 }
 protected function applyCustomExternalTransaction(PhabricatorLiskDAO $object, PhabricatorApplicationTransaction $xaction)
 {
     switch ($xaction->getTransactionType()) {
         case PhabricatorOwnersPackageTransaction::TYPE_NAME:
         case PhabricatorOwnersPackageTransaction::TYPE_PRIMARY:
         case PhabricatorOwnersPackageTransaction::TYPE_DESCRIPTION:
         case PhabricatorOwnersPackageTransaction::TYPE_AUDITING:
             return;
         case PhabricatorOwnersPackageTransaction::TYPE_OWNERS:
             $old = $xaction->getOldValue();
             $new = $xaction->getNewValue();
             // TODO: needOwners this
             $owners = $object->loadOwners();
             $owners = mpull($owners, null, 'getUserPHID');
             $rem = array_diff($old, $new);
             foreach ($rem as $phid) {
                 if (isset($owners[$phid])) {
                     $owners[$phid]->delete();
                     unset($owners[$phid]);
                 }
             }
             $add = array_diff($new, $old);
             foreach ($add as $phid) {
                 $owners[$phid] = id(new PhabricatorOwnersOwner())->setPackageID($object->getID())->setUserPHID($phid)->save();
             }
             // TODO: Attach owners here
             return;
         case PhabricatorOwnersPackageTransaction::TYPE_PATHS:
             $old = $xaction->getOldValue();
             $new = $xaction->getNewValue();
             // TODO: needPaths this
             $paths = $object->loadPaths();
             $diffs = PhabricatorOwnersPath::getTransactionValueChanges($old, $new);
             list($rem, $add) = $diffs;
             $set = PhabricatorOwnersPath::getSetFromTransactionValue($rem);
             foreach ($paths as $path) {
                 $ref = $path->getRef();
                 if (PhabricatorOwnersPath::isRefInSet($ref, $set)) {
                     $path->delete();
                 }
             }
             foreach ($add as $ref) {
                 $path = PhabricatorOwnersPath::newFromRef($ref)->setPackageID($object->getID())->save();
             }
             return;
     }
     return parent::applyCustomExternalTransaction($object, $xaction);
 }