diff --git a/src/infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php b/src/infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php
index fdaa99ac7e..3ff87c11ab 100644
--- a/src/infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php
+++ b/src/infrastructure/diff/view/PHUIDiffInlineCommentDetailView.php
@@ -1,582 +1,599 @@
 <?php
 
 final class PHUIDiffInlineCommentDetailView
   extends PHUIDiffInlineCommentView {
 
   private $handles;
   private $markupEngine;
   private $editable;
   private $preview;
   private $allowReply;
   private $canMarkDone;
   private $objectOwnerPHID;
 
   public function isHidden() {
     return $this->getInlineComment()->isHidden();
   }
 
   public function setHandles(array $handles) {
     assert_instances_of($handles, 'PhabricatorObjectHandle');
     $this->handles = $handles;
     return $this;
   }
 
   public function setMarkupEngine(PhabricatorMarkupEngine $engine) {
     $this->markupEngine = $engine;
     return $this;
   }
 
   public function setEditable($editable) {
     $this->editable = $editable;
     return $this;
   }
 
   public function setPreview($preview) {
     $this->preview = $preview;
     return $this;
   }
 
   public function setAllowReply($allow_reply) {
     $this->allowReply = $allow_reply;
     return $this;
   }
 
   public function setCanMarkDone($can_mark_done) {
     $this->canMarkDone = $can_mark_done;
     return $this;
   }
 
   public function getCanMarkDone() {
     return $this->canMarkDone;
   }
 
   public function setObjectOwnerPHID($phid) {
     $this->objectOwnerPHID = $phid;
     return $this;
   }
 
   public function getObjectOwnerPHID() {
     return $this->objectOwnerPHID;
   }
 
   public function getAnchorName() {
     $inline = $this->getInlineComment();
     if ($inline->getID()) {
       return 'inline-'.$inline->getID();
     }
     return null;
   }
 
   public function getScaffoldCellID() {
     $anchor = $this->getAnchorName();
     if ($anchor) {
       return 'anchor-'.$anchor;
     }
     return null;
   }
 
   public function render() {
     require_celerity_resource('phui-inline-comment-view-css');
     $inline = $this->getInlineComment();
 
     $is_synthetic = false;
     if ($inline->getSyntheticAuthor()) {
       $is_synthetic = true;
     }
 
     $is_preview = $this->preview;
 
     $metadata = $this->getInlineCommentMetadata();
 
     $classes = array(
       'differential-inline-comment',
     );
 
     $sigil = 'differential-inline-comment';
     if ($is_preview) {
       $sigil = $sigil.' differential-inline-comment-preview';
 
       $classes[] = 'inline-comment-preview';
     } else {
       $classes[] = 'inline-comment-element';
     }
 
     $handles = $this->handles;
 
     $links = array();
 
     $draft_text = null;
     if (!$is_synthetic) {
       // This display is controlled by CSS
       $draft_text = id(new PHUITagView())
         ->setType(PHUITagView::TYPE_SHADE)
         ->setName(pht('Unsubmitted'))
         ->setSlimShady(true)
         ->setColor(PHUITagView::COLOR_RED)
         ->addClass('mml inline-draft-text');
     }
 
     $ghost_tag = null;
     $ghost = $inline->getIsGhost();
     $ghost_id = null;
     if ($ghost) {
       if ($ghost['new']) {
         $ghosticon = 'fa-fast-forward';
         $reason = pht('View on forward revision');
       } else {
         $ghosticon = 'fa-fast-backward';
         $reason = pht('View on previous revision');
       }
 
       $ghost_icon = id(new PHUIIconView())
         ->setIcon($ghosticon)
         ->addSigil('has-tooltip')
         ->setMetadata(
           array(
             'tip' => $reason,
             'size' => 300,
           ));
       $ghost_tag = phutil_tag(
         'a',
         array(
           'class' => 'ghost-icon',
           'href' => $ghost['href'],
           'target' => '_blank',
         ),
         $ghost_icon);
       $classes[] = 'inline-comment-ghost';
     }
 
     if ($inline->getReplyToCommentPHID()) {
       $classes[] = 'inline-comment-is-reply';
     }
 
     $viewer_phid = $this->getUser()->getPHID();
     $owner_phid = $this->getObjectOwnerPHID();
 
     if ($viewer_phid) {
       if ($viewer_phid == $owner_phid) {
         $classes[] = 'viewer-is-object-owner';
       }
     }
 
     $anchor_name = $this->getAnchorName();
 
     $action_buttons = array();
     $menu_items = array();
 
     if ($this->editable && !$is_preview) {
       $menu_items[] = array(
         'label' => pht('Edit Comment'),
         'icon' => 'fa-pencil',
         'action' => 'edit',
         'key' => 'e',
       );
     } else if ($is_preview) {
       $links[] = javelin_tag(
         'a',
         array(
           'class'  => 'inline-button-divider pml msl',
           'meta' => array(
             'inlineCommentID' => $inline->getID(),
           ),
           'sigil' => 'differential-inline-preview-jump',
         ),
         pht('View'));
 
       $action_buttons[] = id(new PHUIButtonView())
         ->setTag('a')
         ->setTooltip(pht('Delete'))
         ->setIcon('fa-trash-o')
         ->addSigil('differential-inline-delete')
         ->setMustCapture(true)
         ->setAuralLabel(pht('Delete'));
     }
 
     if (!$is_preview && $this->canHide()) {
       $menu_items[] = array(
         'label' => pht('Collapse'),
         'icon' => 'fa-times',
         'action' => 'collapse',
         'key' => 'q',
       );
     }
 
     $can_reply =
       (!$this->editable) &&
       (!$is_preview) &&
       ($this->allowReply) &&
 
       // NOTE: No product reason why you can't reply to synthetic comments,
       // but the reply mechanism currently sends the inline comment ID to the
       // server, not file/line information, and synthetic comments don't have
       // an inline comment ID.
       (!$is_synthetic);
 
     if ($can_reply) {
       $menu_items[] = array(
         'label' => pht('Reply to Comment'),
         'icon' => 'fa-reply',
         'action' => 'reply',
         'key' => 'r',
       );
 
       $menu_items[] = array(
         'label' => pht('Quote Comment'),
         'icon' => 'fa-quote-left',
         'action' => 'quote',
         'key' => 'R',
       );
     }
 
     if (!$is_preview) {
       $xaction_phid = $inline->getTransactionPHID();
       $storage = $inline->getStorageObject();
 
       if ($xaction_phid) {
         $menu_items[] = array(
           'label' => pht('View Raw Remarkup'),
           'icon' => 'fa-code',
           'action' => 'raw',
           'uri' => $storage->getRawRemarkupURI(),
         );
       }
     }
 
     if ($this->editable && !$is_preview) {
       $menu_items[] = array(
         'label' => pht('Delete Comment'),
         'icon' => 'fa-trash-o',
         'action' => 'delete',
       );
     }
 
     $done_button = null;
 
     $mark_done = $this->getCanMarkDone();
 
     // Allow users to mark their own draft inlines as "Done".
     if ($viewer_phid == $inline->getAuthorPHID()) {
       if ($inline->isDraft()) {
         $mark_done = true;
       }
     }
 
     if (!$is_synthetic) {
       $draft_state = false;
       switch ($inline->getFixedState()) {
         case PhabricatorInlineComment::STATE_DRAFT:
           $is_done = $mark_done;
           $draft_state = true;
           break;
         case PhabricatorInlineComment::STATE_UNDRAFT:
           $is_done = !$mark_done;
           $draft_state = true;
           break;
         case PhabricatorInlineComment::STATE_DONE:
           $is_done = true;
           break;
         default:
         case PhabricatorInlineComment::STATE_UNDONE:
           $is_done = false;
           break;
       }
 
       // If you don't have permission to mark the comment as "Done", you also
       // can not see the draft state.
       if (!$mark_done) {
         $draft_state = false;
       }
 
       if ($is_done) {
         $classes[] = 'inline-is-done';
       }
 
       if ($draft_state) {
         $classes[] = 'inline-state-is-draft';
       }
 
       if ($mark_done && !$is_preview) {
         $done_input = javelin_tag(
           'input',
           array(
             'type' => 'checkbox',
             'checked' => ($is_done ? 'checked' : null),
             'class' => 'differential-inline-done',
             'sigil' => 'differential-inline-done',
           ));
         $done_button = phutil_tag(
           'label',
           array(
             'class' => 'differential-inline-done-label ',
           ),
           array(
             $done_input,
             pht('Done'),
           ));
       } else {
         if ($is_done) {
           $icon = id(new PHUIIconView())->setIcon('fa-check sky msr');
           $label = pht('Done');
           $class = 'button-done';
         } else {
           $icon = null;
           $label = pht('Not Done');
           $class = 'button-not-done';
         }
         $done_button = phutil_tag(
           'div',
           array(
             'class' => 'done-label '.$class,
           ),
           array(
             $icon,
             $label,
           ));
       }
     }
 
     $content = $this->markupEngine->getOutput(
       $inline,
       PhabricatorInlineComment::MARKUP_FIELD_BODY);
 
     if ($is_preview) {
       $anchor = null;
     } else {
       $anchor = phutil_tag(
         'a',
         array(
           'name'    => $anchor_name,
           'id'      => $anchor_name,
           'class'   => 'differential-inline-comment-anchor',
         ),
         '');
     }
 
     if ($inline->isDraft() && !$is_synthetic) {
       $classes[] = 'inline-state-is-draft';
     }
     if ($is_synthetic) {
       $classes[] = 'differential-inline-comment-synthetic';
     }
     $classes = implode(' ', $classes);
 
     $author_owner = null;
     if ($is_synthetic) {
       $author = $inline->getSyntheticAuthor();
     } else {
       $author = $handles[$inline->getAuthorPHID()]->getName();
       if ($inline->getAuthorPHID() == $this->objectOwnerPHID) {
         $author_owner = id(new PHUITagView())
           ->setType(PHUITagView::TYPE_SHADE)
           ->setName(pht('Author'))
           ->setSlimShady(true)
           ->setColor(PHUITagView::COLOR_YELLOW)
           ->addClass('mml');
       }
     }
 
     $actions = null;
     if ($action_buttons || $menu_items) {
       $actions = new PHUIButtonBarView();
       $actions->setBorderless(true);
       $actions->addClass('inline-button-divider');
       foreach ($action_buttons as $button) {
         $actions->addButton($button);
       }
 
       if (!$is_preview) {
         $menu_button = id(new PHUIButtonView())
           ->setTag('a')
           ->setColor(PHUIButtonView::GREY)
           ->setDropdown(true)
           ->setAuralLabel(pht('Inline Actions'))
           ->addSigil('inline-action-dropdown');
 
         $actions->addButton($menu_button);
       }
     }
 
     $group_left = phutil_tag(
       'div',
       array(
         'class' => 'inline-head-left',
       ),
       array(
         $author,
         $author_owner,
         $draft_text,
         $ghost_tag,
       ));
 
     $group_right = phutil_tag(
       'div',
       array(
         'class' => 'inline-head-right',
       ),
       array(
         $done_button,
         $links,
         $actions,
       ));
 
     $snippet = id(new PhutilUTF8StringTruncator())
       ->setMaximumGlyphs(96)
       ->truncateString($inline->getContent());
     $metadata['snippet'] = pht('%s: %s', $author, $snippet);
 
     $metadata['menuItems'] = $menu_items;
 
     $suggestion_content = $this->newSuggestionView($inline);
 
     $inline_content = phutil_tag(
       'div',
       array(
         'class' => 'phabricator-remarkup',
       ),
       $content);
 
     $markup = javelin_tag(
       'div',
       array(
         'class' => $classes,
         'sigil' => $sigil,
         'meta'  => $metadata,
       ),
       array(
         javelin_tag(
           'div',
           array(
             'class' => 'differential-inline-comment-head grouped',
             'sigil' => 'differential-inline-header',
           ),
           array(
             $group_left,
             $group_right,
           )),
         phutil_tag(
           'div',
           array(
             'class' => 'differential-inline-comment-content',
           ),
           array(
             $suggestion_content,
             $inline_content,
           )),
       ));
 
     $summary = phutil_tag(
       'div',
       array(
         'class' => 'differential-inline-summary',
       ),
       array(
         phutil_tag('strong', array(), pht('%s:', $author)),
         ' ',
         $snippet,
       ));
 
     return array(
       $anchor,
       $markup,
       $summary,
     );
   }
 
   private function canHide() {
     $inline = $this->getInlineComment();
 
     if ($inline->isDraft()) {
       return false;
     }
 
     if (!$inline->getID()) {
       return false;
     }
 
     $viewer = $this->getUser();
     if (!$viewer->isLoggedIn()) {
       return false;
     }
 
     if (!$inline->supportsHiding()) {
       return false;
     }
 
     return true;
   }
 
   private function newSuggestionView(PhabricatorInlineComment $inline) {
     $content_state = $inline->getContentState();
     if (!$content_state->getContentHasSuggestion()) {
       return null;
     }
 
     $context = $inline->getInlineContext();
     if (!$context) {
       return null;
     }
 
     $head_lines = $context->getHeadLines();
     $head_lines = implode('', $head_lines);
 
     $tail_lines = $context->getTailLines();
     $tail_lines = implode('', $tail_lines);
 
     $old_lines = $context->getBodyLines();
     $old_lines = implode('', $old_lines);
     $old_lines = $head_lines.$old_lines.$tail_lines;
     if (strlen($old_lines) && !preg_match('/\n\z/', $old_lines)) {
       $old_lines .= "\n";
     }
 
     $new_lines = $content_state->getContentSuggestionText();
     $new_lines = $head_lines.$new_lines.$tail_lines;
     if (strlen($new_lines) && !preg_match('/\n\z/', $new_lines)) {
       $new_lines .= "\n";
     }
 
     if ($old_lines === $new_lines) {
       return null;
     }
 
     $viewer = $this->getViewer();
 
     $changeset = id(new PhabricatorDifferenceEngine())
       ->generateChangesetFromFileContent($old_lines, $new_lines);
 
     $changeset->setFilename($context->getFilename());
 
     $viewstate = new PhabricatorChangesetViewState();
 
     $parser = id(new DifferentialChangesetParser())
       ->setViewer($viewer)
       ->setViewstate($viewstate)
       ->setChangeset($changeset);
 
     $fragment = $inline->getInlineCommentCacheFragment();
     if ($fragment !== null) {
       $cache_key = sprintf(
         '%s.suggestion-view(v1, %s)',
         $fragment,
         PhabricatorHash::digestForIndex($new_lines));
       $parser->setRenderCacheKey($cache_key);
     }
 
     $renderer = new DifferentialChangesetOneUpRenderer();
     $renderer->setSimpleMode(true);
 
     $parser->setRenderer($renderer);
 
-    $diff_view = $parser->render(0, 0xFFFF, array());
+    // See PHI1896. If a user leaves an inline on a very long range with
+    // suggestions at the beginning and end, we'll hide context in the middle
+    // by default. We don't want to do this in the context of an inline
+    // suggestion, so build a mask to force display of all lines.
+
+    // (We don't know exactly how many lines the diff has, we just know that
+    // it can't have more lines than the old file plus the new file, so we're
+    // using that as an upper bound.)
+
+    $min = 0;
+
+    $old_len = count(phutil_split_lines($old_lines));
+    $new_len = count(phutil_split_lines($new_lines));
+    $max = ($old_len + $new_len);
+
+    $mask = array_fill($min, ($max - $min), true);
+
+    $diff_view = $parser->render($min, ($max - $min), $mask);
 
     $view = phutil_tag(
       'div',
       array(
         'class' => 'inline-suggestion-view PhabricatorMonospaced',
       ),
       $diff_view);
 
     return $view;
   }
 }