private function renderInlineCommentsForMail(PhabricatorLiskDAO $object, array $inlines)
 {
     $context_key = 'metamta.differential.unified-comment-context';
     $show_context = PhabricatorEnv::getEnvConfig($context_key);
     $changeset_ids = array();
     $line_numbers_by_changeset = array();
     foreach ($inlines as $inline) {
         $id = $inline->getComment()->getChangesetID();
         $changeset_ids[$id] = $id;
         $line_numbers_by_changeset[$id][] = $inline->getComment()->getLineNumber();
     }
     $changesets = id(new DifferentialChangesetQuery())->setViewer($this->getActor())->withIDs($changeset_ids)->needHunks(true)->execute();
     $inline_groups = DifferentialTransactionComment::sortAndGroupInlines($inlines, $changesets);
     if ($show_context) {
         $hunk_parser = new DifferentialHunkParser();
         $table = new DifferentialTransactionComment();
         $conn_r = $table->establishConnection('r');
         $queries = array();
         foreach ($line_numbers_by_changeset as $id => $line_numbers) {
             $queries[] = qsprintf($conn_r, '(changesetID = %d AND lineNumber IN (%Ld))', $id, $line_numbers);
         }
         $all_comments = id(new DifferentialTransactionComment())->loadAllWhere('transactionPHID IS NOT NULL AND (%Q)', implode(' OR ', $queries));
         $comments_by_line_number = array();
         foreach ($all_comments as $comment) {
             $comments_by_line_number[$comment->getChangesetID()][$comment->getLineNumber()][$comment->getID()] = $comment;
         }
         $author_phids = mpull($all_comments, 'getAuthorPHID');
         $authors = id(new PhabricatorPeopleQuery())->setViewer($this->getActor())->withPHIDs($author_phids)->execute();
         $authors_by_phid = mpull($authors, null, 'getPHID');
     }
     $section = new PhabricatorMetaMTAMailSection();
     foreach ($inline_groups as $changeset_id => $group) {
         $changeset = idx($changesets, $changeset_id);
         if (!$changeset) {
             continue;
         }
         foreach ($group as $inline) {
             $comment = $inline->getComment();
             $file = $changeset->getFilename();
             $start = $comment->getLineNumber();
             $len = $comment->getLineLength();
             if ($len) {
                 $range = $start . '-' . ($start + $len);
             } else {
                 $range = $start;
             }
             $inline_content = $comment->getContent();
             if (!$show_context) {
                 $section->addFragment("{$file}:{$range} {$inline_content}");
             } else {
                 $patch = $hunk_parser->makeContextDiff($changeset->getHunks(), $comment->getIsNewFile(), $comment->getLineNumber(), $comment->getLineLength(), 1);
                 $nested_comments = $this->nestCommentHistory($inline->getComment(), $comments_by_line_number, $authors_by_phid);
                 $section->addFragment('================')->addFragment(pht('Comment at: %s:%s', $file, $range))->addPlaintextFragment($patch)->addHTMLFragment($this->renderPatchHTMLForMail($patch))->addFragment('----------------')->addFragment($nested_comments)->addFragment(null);
             }
         }
     }
     return $section;
 }
 protected function processReceivedMail(PhabricatorMetaMTAReceivedMail $mail, PhabricatorUser $sender)
 {
     $attachments = $mail->getAttachments();
     $files = array();
     $errors = array();
     if ($attachments) {
         $files = id(new PhabricatorFileQuery())->setViewer($sender)->withPHIDs($attachments)->execute();
         foreach ($files as $index => $file) {
             if ($file->getMimeType() != 'text/plain') {
                 $errors[] = pht('Could not parse file %s; only files with mimetype text/plain ' . 'can be parsed via email.', $file->getName());
                 unset($files[$index]);
             }
         }
     }
     $diffs = array();
     foreach ($files as $file) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $file->loadFileData()));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[$file->getName()] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse attachment %s; only attachments (and mail bodies) ' . 'generated via "diff" commands can be parsed.', $file->getName());
         }
     }
     $body = $mail->getCleanTextBody();
     if ($body) {
         $call = new ConduitCall('differential.createrawdiff', array('diff' => $body));
         $call->setUser($sender);
         try {
             $result = $call->execute();
             $diffs[pht('Mail Body')] = $result['uri'];
         } catch (Exception $e) {
             $errors[] = pht('Could not parse mail body; only mail bodies (and attachments) ' . 'generated via "diff" commands can be parsed.');
         }
     }
     $subject_prefix = PhabricatorEnv::getEnvConfig('metamta.differential.subject-prefix');
     if (count($diffs)) {
         $subject = pht('You successfully created %d diff(s).', count($diffs));
     } else {
         $subject = pht('Diff creation failed; see body for %s error(s).', new PhutilNumber(count($errors)));
     }
     $body = new PhabricatorMetaMTAMailBody();
     $body->addRawSection($subject);
     if (count($diffs)) {
         $text_body = '';
         $html_body = array();
         $body_label = pht('%s DIFF LINK(S)', new PhutilNumber(count($diffs)));
         foreach ($diffs as $filename => $diff_uri) {
             $text_body .= $filename . ': ' . $diff_uri . "\n";
             $html_body[] = phutil_tag('a', array('href' => $diff_uri), $filename);
             $html_body[] = phutil_tag('br');
         }
         $body->addTextSection($body_label, $text_body);
         $body->addHTMLSection($body_label, $html_body);
     }
     if (count($errors)) {
         $body_section = new PhabricatorMetaMTAMailSection();
         $body_label = pht('%s ERROR(S)', new PhutilNumber(count($errors)));
         foreach ($errors as $error) {
             $body_section->addFragment($error);
         }
         $body->addTextSection($body_label, $body_section);
     }
     id(new PhabricatorMetaMTAMail())->addTos(array($sender->getPHID()))->setSubject($subject)->setSubjectPrefix($subject_prefix)->setFrom($sender->getPHID())->setBody($body->render())->saveAndSend();
 }