public function applyTransactions(ManiphestTask $task, array $transactions)
 {
     assert_instances_of($transactions, 'ManiphestTransaction');
     $email_cc = $task->getCCPHIDs();
     $email_to = array();
     $email_to[] = $task->getOwnerPHID();
     $pri_changed = $this->isCreate($transactions);
     foreach ($transactions as $key => $transaction) {
         $type = $transaction->getTransactionType();
         $new = $transaction->getNewValue();
         $email_to[] = $transaction->getAuthorPHID();
         $value_is_phid_set = false;
         switch ($type) {
             case ManiphestTransactionType::TYPE_NONE:
                 $old = null;
                 break;
             case ManiphestTransactionType::TYPE_STATUS:
                 $old = $task->getStatus();
                 break;
             case ManiphestTransactionType::TYPE_OWNER:
                 $old = $task->getOwnerPHID();
                 break;
             case ManiphestTransactionType::TYPE_CCS:
                 $old = $task->getCCPHIDs();
                 $value_is_phid_set = true;
                 break;
             case ManiphestTransactionType::TYPE_PRIORITY:
                 $old = $task->getPriority();
                 break;
             case ManiphestTransactionType::TYPE_ATTACH:
                 $old = $task->getAttached();
                 break;
             case ManiphestTransactionType::TYPE_TITLE:
                 $old = $task->getTitle();
                 break;
             case ManiphestTransactionType::TYPE_DESCRIPTION:
                 $old = $task->getDescription();
                 break;
             case ManiphestTransactionType::TYPE_PROJECTS:
                 $old = $task->getProjectPHIDs();
                 $value_is_phid_set = true;
                 break;
             case ManiphestTransactionType::TYPE_AUXILIARY:
                 $aux_key = $transaction->getMetadataValue('aux:key');
                 if (!$aux_key) {
                     throw new Exception("Expected 'aux:key' metadata on TYPE_AUXILIARY transaction.");
                 }
                 $old = $task->getAuxiliaryAttribute($aux_key);
                 break;
             default:
                 throw new Exception('Unknown action type.');
         }
         $old_cmp = $old;
         $new_cmp = $new;
         if ($value_is_phid_set) {
             // Normalize the old and new values if they are PHID sets so we don't
             // get any no-op transactions where the values differ only by keys,
             // order, duplicates, etc.
             if (is_array($old)) {
                 $old = array_filter($old);
                 $old = array_unique($old);
                 sort($old);
                 $old = array_values($old);
                 $old_cmp = $old;
             }
             if (is_array($new)) {
                 $new = array_filter($new);
                 $new = array_unique($new);
                 $transaction->setNewValue($new);
                 $new_cmp = $new;
                 sort($new_cmp);
                 $new_cmp = array_values($new_cmp);
             }
         }
         if ($old !== null && $old_cmp == $new_cmp) {
             if (count($transactions) > 1 && !$transaction->hasComments()) {
                 // If we have at least one other transaction and this one isn't
                 // doing anything and doesn't have any comments, just throw it
                 // away.
                 unset($transactions[$key]);
                 continue;
             } else {
                 $transaction->setOldValue(null);
                 $transaction->setNewValue(null);
                 $transaction->setTransactionType(ManiphestTransactionType::TYPE_NONE);
             }
         } else {
             switch ($type) {
                 case ManiphestTransactionType::TYPE_NONE:
                     break;
                 case ManiphestTransactionType::TYPE_STATUS:
                     $task->setStatus($new);
                     break;
                 case ManiphestTransactionType::TYPE_OWNER:
                     if ($new) {
                         $handles = id(new PhabricatorObjectHandleData(array($new)))->loadHandles();
                         $task->setOwnerOrdering($handles[$new]->getName());
                     } else {
                         $task->setOwnerOrdering(null);
                     }
                     $task->setOwnerPHID($new);
                     break;
                 case ManiphestTransactionType::TYPE_CCS:
                     $task->setCCPHIDs($new);
                     break;
                 case ManiphestTransactionType::TYPE_PRIORITY:
                     $task->setPriority($new);
                     $pri_changed = true;
                     break;
                 case ManiphestTransactionType::TYPE_ATTACH:
                     $task->setAttached($new);
                     break;
                 case ManiphestTransactionType::TYPE_TITLE:
                     $task->setTitle($new);
                     break;
                 case ManiphestTransactionType::TYPE_DESCRIPTION:
                     $task->setDescription($new);
                     break;
                 case ManiphestTransactionType::TYPE_PROJECTS:
                     $task->setProjectPHIDs($new);
                     break;
                 case ManiphestTransactionType::TYPE_AUXILIARY:
                     $aux_key = $transaction->getMetadataValue('aux:key');
                     $task->setAuxiliaryAttribute($aux_key, $new);
                     break;
                 default:
                     throw new Exception('Unknown action type.');
             }
             $transaction->setOldValue($old);
             $transaction->setNewValue($new);
         }
     }
     if ($pri_changed) {
         $subpriority = ManiphestTransactionEditor::getNextSubpriority($task->getPriority(), null);
         $task->setSubpriority($subpriority);
     }
     $task->save();
     foreach ($transactions as $transaction) {
         $transaction->setTaskID($task->getID());
         $transaction->save();
     }
     $email_to[] = $task->getOwnerPHID();
     $email_cc = array_merge($email_cc, $task->getCCPHIDs());
     $this->publishFeedStory($task, $transactions);
     // TODO: Do this offline via timeline
     PhabricatorSearchManiphestIndexer::indexTask($task);
     $this->sendEmail($task, $transactions, $email_to, $email_cc);
 }