diff --git a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
index 0abcaf5..e0d5f1d 100644
--- a/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
+++ b/polygerrit-ui/app/elements/diff/gr-diff-host/gr-diff-host_test.ts
@@ -630,16 +630,11 @@
       element.blame = [];
       await element.updateComplete;
       assertIsDefined(element.diffElement);
-      const setBlameSpy = sinon.spy(
-        element.diffElement.diffBuilder,
-        'setBlame'
-      );
       const isBlameLoadedStub = sinon.stub();
       element.addEventListener('is-blame-loaded-changed', isBlameLoadedStub);
       element.clearBlame();
       await element.updateComplete;
       assert.isNull(element.blame);
-      assert.isTrue(setBlameSpy.calledWithExactly(null));
       assert.isTrue(isBlameLoadedStub.calledOnce);
       assert.isFalse(isBlameLoadedStub.args[0][0].detail.value);
     });
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts
deleted file mode 100644
index 1452e0f..0000000
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element.ts
+++ /dev/null
@@ -1,574 +0,0 @@
-/**
- * @license
- * Copyright 2016 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-import '../gr-diff-processor/gr-diff-processor';
-import '../../../elements/shared/gr-hovercard/gr-hovercard';
-import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
-import {
-  GrDiffBuilder,
-  DiffContextExpandedEventDetail,
-  isImageDiffBuilder,
-  isBinaryDiffBuilder,
-} from './gr-diff-builder';
-import {GrDiffBuilderImage} from './gr-diff-builder-image';
-import {GrDiffBuilderBinary} from './gr-diff-builder-binary';
-import {BlameInfo, ImageInfo} from '../../../types/common';
-import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
-import {CoverageRange, DiffLayer} from '../../../types/types';
-import {
-  GrDiffProcessor,
-  GroupConsumer,
-  KeyLocations,
-} from '../gr-diff-processor/gr-diff-processor';
-import {
-  CommentRangeLayer,
-  GrRangedCommentLayer,
-} from '../gr-ranged-comment-layer/gr-ranged-comment-layer';
-import {GrCoverageLayer} from '../gr-coverage-layer/gr-coverage-layer';
-import {DiffViewMode, LineNumber, RenderPreferences} from '../../../api/diff';
-import {createDefaultDiffPrefs, Side} from '../../../constants/constants';
-import {GrDiffLine} from '../gr-diff/gr-diff-line';
-import {
-  GrDiffGroup,
-  GrDiffGroupType,
-  hideInContextControl,
-} from '../gr-diff/gr-diff-group';
-import {getLineNumber, getSideByLineEl} from '../gr-diff/gr-diff-utils';
-import {fireAlert, fire} from '../../../utils/event-util';
-import {assertIsDefined} from '../../../utils/common-util';
-
-const TRAILING_WHITESPACE_PATTERN = /\s+$/;
-const COMMIT_MSG_PATH = '/COMMIT_MSG';
-const COMMIT_MSG_LINE_LENGTH = 72;
-
-declare global {
-  interface HTMLElementEventMap {
-    /**
-     * Fired when the diff begins rendering - both for full renders and for
-     * partial rerenders.
-     */
-    'render-start': CustomEvent<{}>;
-    /**
-     * Fired when the diff finishes rendering text content - both for full
-     * renders and for partial rerenders.
-     */
-    'render-content': CustomEvent<{}>;
-  }
-}
-
-export function getLineNumberCellWidth(prefs: DiffPreferencesInfo) {
-  return prefs.font_size * 4;
-}
-
-function annotateSymbols(
-  contentEl: HTMLElement,
-  line: GrDiffLine,
-  separator: string | RegExp,
-  className: string
-) {
-  const split = line.text.split(separator);
-  if (!split || split.length < 2) {
-    return;
-  }
-  for (let i = 0, pos = 0; i < split.length - 1; i++) {
-    // Skip forward by the length of the content
-    pos += split[i].length;
-
-    GrAnnotation.annotateElement(contentEl, pos, 1, `gr-diff ${className}`);
-
-    pos++;
-  }
-}
-
-// TODO: Rename the class and the file and remove "element". This is not an
-// element anymore.
-export class GrDiffBuilderElement implements GroupConsumer {
-  diff?: DiffInfo;
-
-  diffElement?: HTMLTableElement;
-
-  viewMode?: string;
-
-  isImageDiff?: boolean;
-
-  baseImage: ImageInfo | null = null;
-
-  revisionImage: ImageInfo | null = null;
-
-  path?: string;
-
-  prefs: DiffPreferencesInfo = createDefaultDiffPrefs();
-
-  renderPrefs?: RenderPreferences;
-
-  useNewImageDiffUi = false;
-
-  /**
-   * Layers passed in from the outside.
-   *
-   * See `layersInternal` for where these layers will end up together with the
-   * internal layers.
-   */
-  layers: DiffLayer[] = [];
-
-  // visible for testing
-  builder?: GrDiffBuilder;
-
-  /**
-   * All layers, both from the outside and the default ones. See `layers` for
-   * the property that can be set from the outside.
-   */
-  // visible for testing
-  layersInternal: DiffLayer[] = [];
-
-  // visible for testing
-  showTabs?: boolean;
-
-  // visible for testing
-  showTrailingWhitespace?: boolean;
-
-  private coverageLayerLeft = new GrCoverageLayer(Side.LEFT);
-
-  private coverageLayerRight = new GrCoverageLayer(Side.RIGHT);
-
-  private rangeLayer?: GrRangedCommentLayer;
-
-  // visible for testing
-  processor?: GrDiffProcessor;
-
-  /**
-   * Groups are mostly just passed on to the diff builder (this.builder). But
-   * we also keep track of them here for being able to fire a `render-content`
-   * event when .element of each group has rendered.
-   *
-   * TODO: Refactor DiffBuilderElement and DiffBuilders with a cleaner
-   * separation of responsibilities.
-   */
-  private groups: GrDiffGroup[] = [];
-
-  updateCommentRanges(ranges: CommentRangeLayer[]) {
-    this.rangeLayer?.updateRanges(ranges);
-  }
-
-  updateCoverageRanges(rs: CoverageRange[]) {
-    this.coverageLayerLeft.setRanges(rs.filter(r => r?.side === Side.LEFT));
-    this.coverageLayerRight.setRanges(rs.filter(r => r?.side === Side.RIGHT));
-  }
-
-  render(keyLocations: KeyLocations): Promise<void> {
-    assertIsDefined(this.diff, 'diff');
-    assertIsDefined(this.diffElement, 'diff table');
-
-    // Setting up annotation layers must happen after plugins are
-    // installed, and |render| satisfies the requirement, however,
-    // |attached| doesn't because in the diff view page, the element is
-    // attached before plugins are installed.
-    this.setupAnnotationLayers();
-
-    this.showTabs = this.prefs.show_tabs;
-    this.showTrailingWhitespace = this.prefs.show_whitespace_errors;
-
-    this.cleanup();
-    this.builder = this.getDiffBuilder();
-    this.init();
-
-    // TODO: Just pass along the diff model here instead of setting many
-    // individual properties.
-    this.processor = new GrDiffProcessor();
-    this.processor.consumer = this;
-    this.processor.context = this.prefs.context;
-    this.processor.keyLocations = keyLocations;
-    if (this.renderPrefs?.num_lines_rendered_at_once) {
-      this.processor.asyncThreshold =
-        this.renderPrefs.num_lines_rendered_at_once;
-    }
-
-    this.clearDiffContent();
-    this.builder.addColumns(
-      this.diffElement,
-      getLineNumberCellWidth(this.prefs)
-    );
-
-    const isBinary = !!(this.isImageDiff || this.diff.binary);
-
-    fire(this.diffElement, 'render-start', {});
-    return (
-      this.processor
-        .process(this.diff.content, isBinary)
-        .then(async () => {
-          if (isImageDiffBuilder(this.builder)) {
-            this.builder.renderImageDiff();
-          } else if (isBinaryDiffBuilder(this.builder)) {
-            this.builder.renderBinaryDiff();
-          }
-          await this.untilGroupsRendered();
-          fire(this.diffElement, 'render-content', {});
-        })
-        // Mocha testing does not like uncaught rejections, so we catch
-        // the cancels which are expected and should not throw errors in
-        // tests.
-        .catch(e => {
-          if (!e.isCanceled) return Promise.reject(e);
-          return;
-        })
-    );
-  }
-
-  // visible for testing
-  async untilGroupsRendered(groups: readonly GrDiffGroup[] = this.groups) {
-    return Promise.all(groups.map(g => g.waitUntilRendered()));
-  }
-
-  private onDiffContextExpanded = (
-    e: CustomEvent<DiffContextExpandedEventDetail>
-  ) => {
-    // Don't stop propagation. The host may listen for reporting or
-    // resizing.
-    this.replaceGroup(e.detail.contextGroup, e.detail.groups);
-  };
-
-  // visible for testing
-  setupAnnotationLayers() {
-    this.rangeLayer = new GrRangedCommentLayer();
-
-    const layers: DiffLayer[] = [
-      this.createTrailingWhitespaceLayer(),
-      this.createIntralineLayer(),
-      this.createTabIndicatorLayer(),
-      this.createSpecialCharacterIndicatorLayer(),
-      this.rangeLayer,
-      this.coverageLayerLeft,
-      this.coverageLayerRight,
-    ];
-
-    if (this.layers) {
-      layers.push(...this.layers);
-    }
-    this.layersInternal = layers;
-  }
-
-  getContentTdByLine(lineNumber: LineNumber, side?: Side) {
-    if (!this.builder) return undefined;
-    return this.builder.getContentTdByLine(lineNumber, side);
-  }
-
-  getContentTdByLineEl(lineEl?: Element): Element | undefined {
-    if (!lineEl) return undefined;
-    const line = getLineNumber(lineEl);
-    if (!line) return undefined;
-    const side = getSideByLineEl(lineEl);
-    return this.getContentTdByLine(line, side);
-  }
-
-  getLineElByNumber(lineNumber: LineNumber, side?: Side) {
-    if (!this.builder) return undefined;
-    return this.builder.getLineElByNumber(lineNumber, side);
-  }
-
-  getLineNumberRows() {
-    if (!this.builder) return [];
-    return this.builder.getLineNumberRows();
-  }
-
-  getLineNumEls(side: Side) {
-    if (!this.builder) return [];
-    return this.builder.getLineNumEls(side);
-  }
-
-  /**
-   * When the line is hidden behind a context expander, expand it.
-   *
-   * @param lineNum A line number to expand. Using number here because other
-   *   special case line numbers are never hidden, so it does not make sense
-   *   to expand them.
-   * @param side The side the line number refer to.
-   */
-  unhideLine(lineNum: number, side: Side) {
-    if (!this.builder) return;
-    const group = this.builder.findGroup(side, lineNum);
-    // Cannot unhide a line that is not part of the diff.
-    if (!group) return;
-    // If it's already visible, great!
-    if (group.type !== GrDiffGroupType.CONTEXT_CONTROL) return;
-    const lineRange = group.lineRange[side];
-    const lineOffset = lineNum - lineRange.start_line;
-    const newGroups = [];
-    const groups = hideInContextControl(
-      group.contextGroups,
-      0,
-      lineOffset - 1 - this.prefs.context
-    );
-    // If there is a context group, it will be the first group because we
-    // start hiding from 0 offset
-    if (groups[0].type === GrDiffGroupType.CONTEXT_CONTROL) {
-      newGroups.push(groups.shift()!);
-    }
-    newGroups.push(
-      ...hideInContextControl(
-        groups,
-        lineOffset + 1 + this.prefs.context,
-        // Both ends inclusive, so difference is the offset of the last line.
-        // But we need to pass the first line not to hide, which is the element
-        // after.
-        lineRange.end_line - lineRange.start_line + 1
-      )
-    );
-    this.replaceGroup(group, newGroups);
-  }
-
-  /**
-   * Replace the group of a context control section by rendering the provided
-   * groups instead. This happens in response to expanding a context control
-   * group.
-   *
-   * @param contextGroup The context control group to replace
-   * @param newGroups The groups that are replacing the context control group
-   */
-  private replaceGroup(
-    contextGroup: GrDiffGroup,
-    newGroups: readonly GrDiffGroup[]
-  ) {
-    if (!this.builder) return;
-    fire(this.diffElement, 'render-start', {});
-    this.builder.replaceGroup(contextGroup, newGroups);
-    this.groups = this.groups.filter(g => g !== contextGroup);
-    this.groups.push(...newGroups);
-    this.untilGroupsRendered(newGroups).then(() => {
-      fire(this.diffElement, 'render-content', {});
-    });
-  }
-
-  /**
-   * This is meant to be called when the gr-diff component re-connects, or when
-   * the diff is (re-)rendered.
-   *
-   * Make sure that this method is symmetric with cleanup(), which is called
-   * when gr-diff disconnects.
-   */
-  init() {
-    this.cleanup();
-    this.diffElement?.addEventListener(
-      'diff-context-expanded-internal-new',
-      this.onDiffContextExpanded
-    );
-    this.builder?.init();
-  }
-
-  /**
-   * This is meant to be called when the gr-diff component disconnects, or when
-   * the diff is (re-)rendered.
-   *
-   * Make sure that this method is symmetric with init(), which is called when
-   * gr-diff re-connects.
-   */
-  cleanup() {
-    this.processor?.cancel();
-    this.builder?.cleanup();
-    this.diffElement?.removeEventListener(
-      'diff-context-expanded-internal-new',
-      this.onDiffContextExpanded
-    );
-  }
-
-  // visible for testing
-  handlePreferenceError(pref: string): never {
-    const message =
-      `The value of the '${pref}' user preference is ` +
-      'invalid. Fix in diff preferences';
-    assertIsDefined(this.diffElement, 'diff table');
-    fireAlert(this.diffElement, message);
-    throw Error(`Invalid preference value: ${pref}`);
-  }
-
-  // visible for testing
-  getDiffBuilder(): GrDiffBuilder {
-    assertIsDefined(this.diff, 'diff');
-    assertIsDefined(this.diffElement, 'diff table');
-    if (isNaN(this.prefs.tab_size) || this.prefs.tab_size <= 0) {
-      this.handlePreferenceError('tab size');
-    }
-
-    if (isNaN(this.prefs.line_length) || this.prefs.line_length <= 0) {
-      this.handlePreferenceError('diff width');
-    }
-
-    const localPrefs = {...this.prefs};
-    if (this.path === COMMIT_MSG_PATH) {
-      // override line_length for commit msg the same way as
-      // in gr-diff
-      localPrefs.line_length = COMMIT_MSG_LINE_LENGTH;
-    }
-
-    let builder = null;
-    if (this.isImageDiff) {
-      builder = new GrDiffBuilderImage(
-        this.diff,
-        localPrefs,
-        this.diffElement,
-        this.baseImage,
-        this.revisionImage,
-        this.renderPrefs,
-        this.useNewImageDiffUi
-      );
-    } else if (this.diff.binary) {
-      return new GrDiffBuilderBinary(this.diff, localPrefs, this.diffElement);
-    } else if (this.viewMode === DiffViewMode.SIDE_BY_SIDE) {
-      this.renderPrefs = {
-        ...this.renderPrefs,
-        view_mode: DiffViewMode.SIDE_BY_SIDE,
-      };
-      builder = new GrDiffBuilder(
-        this.diff,
-        localPrefs,
-        this.diffElement,
-        this.layersInternal,
-        this.renderPrefs
-      );
-    } else if (this.viewMode === DiffViewMode.UNIFIED) {
-      this.renderPrefs = {
-        ...this.renderPrefs,
-        view_mode: DiffViewMode.UNIFIED,
-      };
-      builder = new GrDiffBuilder(
-        this.diff,
-        localPrefs,
-        this.diffElement,
-        this.layersInternal,
-        this.renderPrefs
-      );
-    }
-    if (!builder) {
-      throw Error(`Unsupported diff view mode: ${this.viewMode}`);
-    }
-    return builder;
-  }
-
-  private clearDiffContent() {
-    assertIsDefined(this.diffElement, 'diff table');
-    this.diffElement.innerHTML = '';
-  }
-
-  /**
-   * Called when the processor starts converting the diff information from the
-   * server into chunks.
-   */
-  clearGroups() {
-    if (!this.builder) return;
-    this.groups = [];
-    this.builder.clearGroups();
-  }
-
-  /**
-   * Called when the processor is done converting a chunk of the diff.
-   */
-  addGroup(group: GrDiffGroup) {
-    if (!this.builder) return;
-    this.builder.addGroups([group]);
-    this.groups.push(group);
-  }
-
-  // visible for testing
-  createIntralineLayer(): DiffLayer {
-    return {
-      // Take a DIV.contentText element and a line object with intraline
-      // differences to highlight and apply them to the element as
-      // annotations.
-      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
-        const HL_CLASS = 'gr-diff intraline';
-        for (const highlight of line.highlights) {
-          // The start and end indices could be the same if a highlight is
-          // meant to start at the end of a line and continue onto the
-          // next one. Ignore it.
-          if (highlight.startIndex === highlight.endIndex) {
-            continue;
-          }
-
-          // If endIndex isn't present, continue to the end of the line.
-          const endIndex =
-            highlight.endIndex === undefined
-              ? GrAnnotation.getStringLength(line.text)
-              : highlight.endIndex;
-
-          GrAnnotation.annotateElement(
-            contentEl,
-            highlight.startIndex,
-            endIndex - highlight.startIndex,
-            HL_CLASS
-          );
-        }
-      },
-    };
-  }
-
-  // visible for testing
-  createTabIndicatorLayer(): DiffLayer {
-    const show = () => this.showTabs;
-    return {
-      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
-        // If visible tabs are disabled, do nothing.
-        if (!show()) {
-          return;
-        }
-
-        // Find and annotate the locations of tabs.
-        annotateSymbols(contentEl, line, '\t', 'tab-indicator');
-      },
-    };
-  }
-
-  private createSpecialCharacterIndicatorLayer(): DiffLayer {
-    return {
-      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
-        // Find and annotate the locations of soft hyphen (\u00AD)
-        annotateSymbols(contentEl, line, '\u00AD', 'special-char-indicator');
-        // Find and annotate Stateful Unicode directional controls
-        annotateSymbols(
-          contentEl,
-          line,
-          /[\u202A-\u202E\u2066-\u2069]/,
-          'special-char-warning'
-        );
-      },
-    };
-  }
-
-  // visible for testing
-  createTrailingWhitespaceLayer(): DiffLayer {
-    const show = () => this.showTrailingWhitespace;
-
-    return {
-      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
-        if (!show()) {
-          return;
-        }
-
-        const match = line.text.match(TRAILING_WHITESPACE_PATTERN);
-        if (match) {
-          // Normalize string positions in case there is unicode before or
-          // within the match.
-          const index = GrAnnotation.getStringLength(
-            line.text.substr(0, match.index)
-          );
-          const length = GrAnnotation.getStringLength(match[0]);
-          GrAnnotation.annotateElement(
-            contentEl,
-            index,
-            length,
-            'gr-diff trailing-whitespace'
-          );
-        }
-      },
-    };
-  }
-
-  setBlame(blame: BlameInfo[] | null) {
-    if (!this.builder) return;
-    this.builder.setBlame(blame ?? []);
-  }
-
-  updateRenderPrefs(renderPrefs: RenderPreferences) {
-    this.builder?.updateRenderPrefs(renderPrefs);
-  }
-}
diff --git a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element_test.ts b/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element_test.ts
deleted file mode 100644
index f6f0cb3..0000000
--- a/polygerrit-ui/app/embed/diff/gr-diff-builder/gr-diff-builder-element_test.ts
+++ /dev/null
@@ -1,628 +0,0 @@
-/**
- * @license
- * Copyright 2016 Google LLC
- * SPDX-License-Identifier: Apache-2.0
- */
-import '../../../test/common-test-setup';
-import {
-  createConfig,
-  createEmptyDiff,
-} from '../../../test/test-data-generators';
-import './gr-diff-builder-element';
-import {stubBaseUrl, waitUntil} from '../../../test/test-utils';
-import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
-import {GrDiffLine} from '../gr-diff/gr-diff-line';
-import {
-  DiffContent,
-  DiffLayer,
-  DiffPreferencesInfo,
-  DiffViewMode,
-  GrDiffLineType,
-  Side,
-} from '../../../api/diff';
-import {stubRestApi} from '../../../test/test-utils';
-import {waitForEventOnce} from '../../../utils/event-util';
-import {GrDiffBuilderElement} from './gr-diff-builder-element';
-import {createDefaultDiffPrefs} from '../../../constants/constants';
-import {KeyLocations} from '../gr-diff-processor/gr-diff-processor';
-import {fixture, html, assert} from '@open-wc/testing';
-import {GrDiffRow} from './gr-diff-row';
-import {GrDiffBuilder} from './gr-diff-builder';
-import {querySelectorAll} from '../../../utils/dom-util';
-
-const DEFAULT_PREFS = createDefaultDiffPrefs();
-
-suite('gr-diff-builder tests', () => {
-  let element: GrDiffBuilderElement;
-  let builder: GrDiffBuilder;
-  let diffTable: HTMLTableElement;
-
-  const setBuilderPrefs = (prefs: Partial<DiffPreferencesInfo>) => {
-    builder = new GrDiffBuilder(
-      createEmptyDiff(),
-      {...createDefaultDiffPrefs(), ...prefs},
-      diffTable
-    );
-  };
-
-  const line = (text: string) => {
-    const line = new GrDiffLine(GrDiffLineType.BOTH);
-    line.text = text;
-    return line;
-  };
-
-  setup(async () => {
-    diffTable = await fixture(html`<table id="diffTable"></table>`);
-    element = new GrDiffBuilderElement();
-    element.diffElement = diffTable;
-    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
-    stubRestApi('getProjectConfig').returns(Promise.resolve(createConfig()));
-    stubBaseUrl('/r');
-    setBuilderPrefs({});
-  });
-
-  [DiffViewMode.UNIFIED, DiffViewMode.SIDE_BY_SIDE].forEach(mode => {
-    test(`line_length used for regular files under ${mode}`, () => {
-      element.path = '/a.txt';
-      element.viewMode = mode;
-      element.diff = createEmptyDiff();
-      element.prefs = {
-        ...createDefaultDiffPrefs(),
-        tab_size: 4,
-        line_length: 50,
-      };
-      builder = element.getDiffBuilder();
-      assert.equal(builder.prefs.line_length, 50);
-    });
-
-    test(`line_length ignored for commit msg under ${mode}`, () => {
-      element.path = '/COMMIT_MSG';
-      element.viewMode = mode;
-      element.diff = createEmptyDiff();
-      element.prefs = {
-        ...createDefaultDiffPrefs(),
-        tab_size: 4,
-        line_length: 50,
-      };
-      builder = element.getDiffBuilder();
-      assert.equal(builder.prefs.line_length, 72);
-    });
-  });
-
-  test('_handlePreferenceError throws with invalid preference', () => {
-    element.prefs = {...createDefaultDiffPrefs(), tab_size: 0};
-    assert.throws(() => element.getDiffBuilder());
-  });
-
-  test('_handlePreferenceError triggers alert and javascript error', () => {
-    const errorStub = sinon.stub();
-    diffTable.addEventListener('show-alert', errorStub);
-    assert.throws(() => element.handlePreferenceError('tab size'));
-    assert.equal(
-      errorStub.lastCall.args[0].detail.message,
-      "The value of the 'tab size' user preference is invalid. " +
-        'Fix in diff preferences'
-    );
-  });
-
-  suite('intraline differences', () => {
-    let el: HTMLElement;
-    let str: string;
-    let annotateElementSpy: sinon.SinonSpy;
-    let layer: DiffLayer;
-    const lineNumberEl = document.createElement('td');
-
-    function slice(str: string, start: number, end?: number) {
-      return Array.from(str).slice(start, end).join('');
-    }
-
-    setup(async () => {
-      el = await fixture(html`
-        <div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
-      `);
-      str = el.textContent ?? '';
-      annotateElementSpy = sinon.spy(GrAnnotation, 'annotateElement');
-      layer = element.createIntralineLayer();
-    });
-
-    test('annotate no highlights', () => {
-      layer.annotate(el, lineNumberEl, line(str), Side.LEFT);
-
-      // The content is unchanged.
-      assert.isFalse(annotateElementSpy.called);
-      assert.equal(el.childNodes.length, 1);
-      assert.instanceOf(el.childNodes[0], Text);
-      assert.equal(str, el.childNodes[0].textContent);
-    });
-
-    test('annotate with highlights', () => {
-      const l = line(str);
-      l.highlights = [
-        {contentIndex: 0, startIndex: 6, endIndex: 12},
-        {contentIndex: 0, startIndex: 18, endIndex: 22},
-      ];
-      const str0 = slice(str, 0, 6);
-      const str1 = slice(str, 6, 12);
-      const str2 = slice(str, 12, 18);
-      const str3 = slice(str, 18, 22);
-      const str4 = slice(str, 22);
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isTrue(annotateElementSpy.called);
-      assert.equal(el.childNodes.length, 5);
-
-      assert.instanceOf(el.childNodes[0], Text);
-      assert.equal(el.childNodes[0].textContent, str0);
-
-      assert.notInstanceOf(el.childNodes[1], Text);
-      assert.equal(el.childNodes[1].textContent, str1);
-
-      assert.instanceOf(el.childNodes[2], Text);
-      assert.equal(el.childNodes[2].textContent, str2);
-
-      assert.notInstanceOf(el.childNodes[3], Text);
-      assert.equal(el.childNodes[3].textContent, str3);
-
-      assert.instanceOf(el.childNodes[4], Text);
-      assert.equal(el.childNodes[4].textContent, str4);
-    });
-
-    test('annotate without endIndex', () => {
-      const l = line(str);
-      l.highlights = [{contentIndex: 0, startIndex: 28}];
-
-      const str0 = slice(str, 0, 28);
-      const str1 = slice(str, 28);
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isTrue(annotateElementSpy.called);
-      assert.equal(el.childNodes.length, 2);
-
-      assert.instanceOf(el.childNodes[0], Text);
-      assert.equal(el.childNodes[0].textContent, str0);
-
-      assert.notInstanceOf(el.childNodes[1], Text);
-      assert.equal(el.childNodes[1].textContent, str1);
-    });
-
-    test('annotate ignores empty highlights', () => {
-      const l = line(str);
-      l.highlights = [{contentIndex: 0, startIndex: 28, endIndex: 28}];
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isFalse(annotateElementSpy.called);
-      assert.equal(el.childNodes.length, 1);
-    });
-
-    test('annotate handles unicode', () => {
-      // Put some unicode into the string:
-      str = str.replace(/\s/g, '💢');
-      el.textContent = str;
-      const l = line(str);
-      l.highlights = [{contentIndex: 0, startIndex: 6, endIndex: 12}];
-
-      const str0 = slice(str, 0, 6);
-      const str1 = slice(str, 6, 12);
-      const str2 = slice(str, 12);
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isTrue(annotateElementSpy.called);
-      assert.equal(el.childNodes.length, 3);
-
-      assert.instanceOf(el.childNodes[0], Text);
-      assert.equal(el.childNodes[0].textContent, str0);
-
-      assert.notInstanceOf(el.childNodes[1], Text);
-      assert.equal(el.childNodes[1].textContent, str1);
-
-      assert.instanceOf(el.childNodes[2], Text);
-      assert.equal(el.childNodes[2].textContent, str2);
-    });
-
-    test('annotate handles unicode w/o endIndex', () => {
-      // Put some unicode into the string:
-      str = str.replace(/\s/g, '💢');
-      el.textContent = str;
-
-      const l = line(str);
-      l.highlights = [{contentIndex: 0, startIndex: 6}];
-
-      const str0 = slice(str, 0, 6);
-      const str1 = slice(str, 6);
-      const numHighlightedChars = GrAnnotation.getStringLength(str1);
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isTrue(annotateElementSpy.calledWith(el, 6, numHighlightedChars));
-      assert.equal(el.childNodes.length, 2);
-
-      assert.instanceOf(el.childNodes[0], Text);
-      assert.equal(el.childNodes[0].textContent, str0);
-
-      assert.notInstanceOf(el.childNodes[1], Text);
-      assert.equal(el.childNodes[1].textContent, str1);
-    });
-  });
-
-  suite('tab indicators', () => {
-    let layer: DiffLayer;
-    const lineNumberEl = document.createElement('td');
-
-    setup(() => {
-      element.showTabs = true;
-      layer = element.createTabIndicatorLayer();
-    });
-
-    test('does nothing with empty line', () => {
-      const l = line('');
-      const el = document.createElement('div');
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isFalse(annotateElementStub.called);
-    });
-
-    test('does nothing with no tabs', () => {
-      const str = 'lorem ipsum no tabs';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isFalse(annotateElementStub.called);
-    });
-
-    test('annotates tab at beginning', () => {
-      const str = '\tlorem upsum';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.equal(annotateElementStub.callCount, 1);
-      const args = annotateElementStub.getCalls()[0].args;
-      assert.equal(args[0], el);
-      assert.equal(args[1], 0, 'offset of tab indicator');
-      assert.equal(args[2], 1, 'length of tab indicator');
-      assert.include(args[3], 'tab-indicator');
-    });
-
-    test('does not annotate when disabled', () => {
-      element.showTabs = false;
-
-      const str = '\tlorem upsum';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.isFalse(annotateElementStub.called);
-    });
-
-    test('annotates multiple in beginning', () => {
-      const str = '\t\tlorem upsum';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.equal(annotateElementStub.callCount, 2);
-
-      let args = annotateElementStub.getCalls()[0].args;
-      assert.equal(args[0], el);
-      assert.equal(args[1], 0, 'offset of tab indicator');
-      assert.equal(args[2], 1, 'length of tab indicator');
-      assert.include(args[3], 'tab-indicator');
-
-      args = annotateElementStub.getCalls()[1].args;
-      assert.equal(args[0], el);
-      assert.equal(args[1], 1, 'offset of tab indicator');
-      assert.equal(args[2], 1, 'length of tab indicator');
-      assert.include(args[3], 'tab-indicator');
-    });
-
-    test('annotates intermediate tabs', () => {
-      const str = 'lorem\tupsum';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-
-      assert.equal(annotateElementStub.callCount, 1);
-      const args = annotateElementStub.getCalls()[0].args;
-      assert.equal(args[0], el);
-      assert.equal(args[1], 5, 'offset of tab indicator');
-      assert.equal(args[2], 1, 'length of tab indicator');
-      assert.include(args[3], 'tab-indicator');
-    });
-  });
-
-  suite('layers', () => {
-    let initialLayersCount = 0;
-    let withLayerCount = 0;
-    setup(() => {
-      const layers: DiffLayer[] = [];
-      element.layers = layers;
-      element.showTrailingWhitespace = true;
-      element.setupAnnotationLayers();
-      initialLayersCount = element.layersInternal.length;
-    });
-
-    test('no layers', () => {
-      element.setupAnnotationLayers();
-      assert.equal(element.layersInternal.length, initialLayersCount);
-    });
-
-    suite('with layers', () => {
-      const layers: DiffLayer[] = [{annotate: () => {}}, {annotate: () => {}}];
-      setup(() => {
-        element.layers = layers;
-        element.showTrailingWhitespace = true;
-        element.setupAnnotationLayers();
-        withLayerCount = element.layersInternal.length;
-      });
-      test('with layers', () => {
-        element.setupAnnotationLayers();
-        assert.equal(element.layersInternal.length, withLayerCount);
-        assert.equal(initialLayersCount + layers.length, withLayerCount);
-      });
-    });
-  });
-
-  suite('trailing whitespace', () => {
-    let layer: DiffLayer;
-    const lineNumberEl = document.createElement('td');
-
-    setup(() => {
-      element.showTrailingWhitespace = true;
-      layer = element.createTrailingWhitespaceLayer();
-    });
-
-    test('does nothing with empty line', () => {
-      const l = line('');
-      const el = document.createElement('div');
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isFalse(annotateElementStub.called);
-    });
-
-    test('does nothing with no trailing whitespace', () => {
-      const str = 'lorem ipsum blah blah';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isFalse(annotateElementStub.called);
-    });
-
-    test('annotates trailing spaces', () => {
-      const str = 'lorem ipsum   ';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isTrue(annotateElementStub.called);
-      assert.equal(annotateElementStub.lastCall.args[1], 11);
-      assert.equal(annotateElementStub.lastCall.args[2], 3);
-    });
-
-    test('annotates trailing tabs', () => {
-      const str = 'lorem ipsum\t\t\t';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isTrue(annotateElementStub.called);
-      assert.equal(annotateElementStub.lastCall.args[1], 11);
-      assert.equal(annotateElementStub.lastCall.args[2], 3);
-    });
-
-    test('annotates mixed trailing whitespace', () => {
-      const str = 'lorem ipsum\t \t';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isTrue(annotateElementStub.called);
-      assert.equal(annotateElementStub.lastCall.args[1], 11);
-      assert.equal(annotateElementStub.lastCall.args[2], 3);
-    });
-
-    test('unicode preceding trailing whitespace', () => {
-      const str = '💢\t';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isTrue(annotateElementStub.called);
-      assert.equal(annotateElementStub.lastCall.args[1], 1);
-      assert.equal(annotateElementStub.lastCall.args[2], 1);
-    });
-
-    test('does not annotate when disabled', () => {
-      element.showTrailingWhitespace = false;
-      const str = 'lorem upsum\t \t ';
-      const l = line(str);
-      const el = document.createElement('div');
-      el.textContent = str;
-      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
-      layer.annotate(el, lineNumberEl, l, Side.LEFT);
-      assert.isFalse(annotateElementStub.called);
-    });
-  });
-
-  suite('rendering text, images and binary files', () => {
-    let keyLocations: KeyLocations;
-    let content: DiffContent[] = [];
-
-    setup(() => {
-      element.viewMode = 'SIDE_BY_SIDE';
-      keyLocations = {left: {}, right: {}};
-      element.prefs = {
-        ...DEFAULT_PREFS,
-        context: -1,
-        syntax_highlighting: true,
-      };
-      content = [
-        {
-          a: ['all work and no play make andybons a dull boy'],
-          b: ['elgoog elgoog elgoog'],
-        },
-        {
-          ab: [
-            'Non eram nescius, Brute, cum, quae summis ingeniis ',
-            'exquisitaque doctrina philosophi Graeco sermone tractavissent',
-          ],
-        },
-      ];
-    });
-
-    test('text', async () => {
-      element.diff = {...createEmptyDiff(), content};
-      element.render(keyLocations);
-      await waitForEventOnce(diffTable, 'render-content');
-      assert.equal(querySelectorAll(diffTable, 'tbody')?.length, 4);
-    });
-
-    test('image', async () => {
-      element.diff = {...createEmptyDiff(), content, binary: true};
-      element.isImageDiff = true;
-      element.render(keyLocations);
-      await waitForEventOnce(diffTable, 'render-content');
-      assert.equal(querySelectorAll(diffTable, 'tbody')?.length, 4);
-    });
-
-    test('binary', async () => {
-      element.diff = {...createEmptyDiff(), content, binary: true};
-      element.render(keyLocations);
-      await waitForEventOnce(diffTable, 'render-content');
-      assert.equal(querySelectorAll(diffTable, 'tbody')?.length, 3);
-    });
-  });
-
-  suite('context hiding and expanding', () => {
-    let dispatchStub: sinon.SinonStub;
-
-    setup(async () => {
-      dispatchStub = sinon.stub(diffTable, 'dispatchEvent');
-      element.diff = {
-        ...createEmptyDiff(),
-        content: [
-          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${i}`)},
-          {a: ['before'], b: ['after']},
-          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${10 + i}`)},
-        ],
-      };
-      element.viewMode = DiffViewMode.SIDE_BY_SIDE;
-
-      const keyLocations: KeyLocations = {left: {}, right: {}};
-      element.prefs = {
-        ...DEFAULT_PREFS,
-        context: 1,
-      };
-      element.render(keyLocations);
-      // Make sure all listeners are installed.
-      await element.untilGroupsRendered();
-    });
-
-    test('hides lines behind two context controls', () => {
-      const contextControls = diffTable.querySelectorAll('gr-context-controls');
-      assert.equal(contextControls.length, 2);
-
-      const diffRows = diffTable.querySelectorAll('.diff-row');
-      // The first two are LOST and FILE line
-      assert.equal(diffRows.length, 2 + 1 + 1 + 1);
-      assert.include(diffRows[2].textContent, 'unchanged 10');
-      assert.include(diffRows[3].textContent, 'before');
-      assert.include(diffRows[3].textContent, 'after');
-      assert.include(diffRows[4].textContent, 'unchanged 11');
-    });
-
-    test('clicking +x common lines expands those lines', async () => {
-      const contextControls = diffTable.querySelectorAll('gr-context-controls');
-      const topExpandCommonButton =
-        contextControls[0].shadowRoot?.querySelectorAll<HTMLElement>(
-          '.showContext'
-        )[0];
-      assert.isOk(topExpandCommonButton);
-      assert.include(topExpandCommonButton!.textContent, '+9 common lines');
-      let diffRows = diffTable.querySelectorAll('.diff-row');
-      // 5 lines:
-      // FILE, LOST, the changed line plus one line of context in each direction
-      assert.equal(diffRows.length, 5);
-
-      topExpandCommonButton!.click();
-
-      await waitUntil(() => {
-        diffRows = diffTable.querySelectorAll<GrDiffRow>('.diff-row');
-        return diffRows.length === 14;
-      });
-      // 14 lines: The 5 above plus the 9 unchanged lines that were expanded
-      assert.equal(diffRows.length, 14);
-      assert.include(diffRows[2].textContent, 'unchanged 1');
-      assert.include(diffRows[3].textContent, 'unchanged 2');
-      assert.include(diffRows[4].textContent, 'unchanged 3');
-      assert.include(diffRows[5].textContent, 'unchanged 4');
-      assert.include(diffRows[6].textContent, 'unchanged 5');
-      assert.include(diffRows[7].textContent, 'unchanged 6');
-      assert.include(diffRows[8].textContent, 'unchanged 7');
-      assert.include(diffRows[9].textContent, 'unchanged 8');
-      assert.include(diffRows[10].textContent, 'unchanged 9');
-      assert.include(diffRows[11].textContent, 'unchanged 10');
-      assert.include(diffRows[12].textContent, 'before');
-      assert.include(diffRows[12].textContent, 'after');
-      assert.include(diffRows[13].textContent, 'unchanged 11');
-    });
-
-    test('unhideLine shows the line with context', async () => {
-      dispatchStub.reset();
-      element.unhideLine(4, Side.LEFT);
-
-      await waitUntil(() => {
-        const rows = diffTable.querySelectorAll<GrDiffRow>('.diff-row');
-        return rows.length === 2 + 5 + 1 + 1 + 1;
-      });
-
-      const diffRows = diffTable.querySelectorAll('.diff-row');
-      // The first two are LOST and FILE line
-      // Lines 3-5 (Line 4 plus 1 context in each direction) will be expanded
-      // Because context expanders do not hide <3 lines, lines 1-2 will also
-      // be shown.
-      // Lines 6-9 continue to be hidden
-      assert.equal(diffRows.length, 2 + 5 + 1 + 1 + 1);
-      assert.include(diffRows[2].textContent, 'unchanged 1');
-      assert.include(diffRows[3].textContent, 'unchanged 2');
-      assert.include(diffRows[4].textContent, 'unchanged 3');
-      assert.include(diffRows[5].textContent, 'unchanged 4');
-      assert.include(diffRows[6].textContent, 'unchanged 5');
-      assert.include(diffRows[7].textContent, 'unchanged 10');
-      assert.include(diffRows[8].textContent, 'before');
-      assert.include(diffRows[8].textContent, 'after');
-      assert.include(diffRows[9].textContent, 'unchanged 11');
-
-      await element.untilGroupsRendered();
-      const firedEventTypes = dispatchStub.getCalls().map(c => c.args[0].type);
-      assert.include(firedEventTypes, 'render-content');
-    });
-  });
-});
diff --git a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
index edd68dc..d87d4d8 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff.ts
@@ -6,7 +6,6 @@
 import '../../../styles/shared-styles';
 import '../../../elements/shared/gr-button/gr-button';
 import '../../../elements/shared/gr-icon/gr-icon';
-import '../gr-diff-builder/gr-diff-builder-element';
 import '../gr-diff-highlight/gr-diff-highlight';
 import '../gr-diff-selection/gr-diff-selection';
 import '../gr-syntax-themes/gr-syntax-theme';
@@ -25,6 +24,7 @@
   getResponsiveMode,
   isResponsive,
   isNewDiff,
+  getSideByLineEl,
 } from '../gr-diff/gr-diff-utils';
 import {BlameInfo, CommentRange, ImageInfo} from '../../../types/common';
 import {DiffInfo, DiffPreferencesInfo} from '../../../types/diff';
@@ -32,18 +32,20 @@
   CreateRangeCommentEventDetail,
   GrDiffHighlight,
 } from '../gr-diff-highlight/gr-diff-highlight';
-import {
-  GrDiffBuilderElement,
-  getLineNumberCellWidth,
-} from '../gr-diff-builder/gr-diff-builder-element';
 import {CoverageRange, DiffLayer} from '../../../types/types';
-import {CommentRangeLayer} from '../gr-ranged-comment-layer/gr-ranged-comment-layer';
+import {
+  CommentRangeLayer,
+  GrRangedCommentLayer,
+} from '../gr-ranged-comment-layer/gr-ranged-comment-layer';
 import {
   createDefaultDiffPrefs,
   DiffViewMode,
   Side,
 } from '../../../constants/constants';
-import {KeyLocations} from '../gr-diff-processor/gr-diff-processor';
+import {
+  GrDiffProcessor,
+  KeyLocations,
+} from '../gr-diff-processor/gr-diff-processor';
 import {fire, fireAlert} from '../../../utils/event-util';
 import {MovedLinkClickedEvent, ValueChangedEvent} from '../../../types/events';
 import {getContentEditableRange} from '../../../utils/safari-selection-util';
@@ -76,6 +78,24 @@
 import {provide} from '../../../models/dependency';
 import {grDiffStyles} from './gr-diff-styles';
 import {getDiffLength} from '../../../utils/diff-util';
+import {GrCoverageLayer} from '../gr-coverage-layer/gr-coverage-layer';
+import {
+  GrDiffBuilder,
+  isImageDiffBuilder,
+  isBinaryDiffBuilder,
+  DiffContextExpandedEventDetail,
+} from '../gr-diff-builder/gr-diff-builder';
+import {GrDiffBuilderBinary} from '../gr-diff-builder/gr-diff-builder-binary';
+import {GrDiffBuilderImage} from '../gr-diff-builder/gr-diff-builder-image';
+import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
+import {
+  GrDiffGroup,
+  GrDiffGroupType,
+  hideInContextControl,
+} from './gr-diff-group';
+import {GrDiffLine} from './gr-diff-line';
+
+const TRAILING_WHITESPACE_PATTERN = /\s+$/;
 
 const NO_NEWLINE_LEFT = 'No newline at end of left file.';
 const NO_NEWLINE_RIGHT = 'No newline at end of right file.';
@@ -264,11 +284,40 @@
   // Private but used in tests.
   highlights = new GrDiffHighlight();
 
-  // Private but used in tests.
-  diffBuilder = new GrDiffBuilderElement();
-
   private diffModel = new DiffModel(undefined);
 
+  // visible for testing
+  builder?: GrDiffBuilder;
+
+  /**
+   * All layers, both from the outside and the default ones. See `layers` for
+   * the property that can be set from the outside.
+   */
+  // visible for testing
+  layersInternal: DiffLayer[] = [];
+
+  // visible for testing
+  showTabs?: boolean;
+
+  // visible for testing
+  showTrailingWhitespace?: boolean;
+
+  private coverageLayerLeft = new GrCoverageLayer(Side.LEFT);
+
+  private coverageLayerRight = new GrCoverageLayer(Side.RIGHT);
+
+  private rangeLayer?: GrRangedCommentLayer;
+
+  // visible for testing
+  processor?: GrDiffProcessor;
+
+  /**
+   * Groups are mostly just passed on to the diff builder (this.builder). But
+   * we also keep track of them here for being able to fire a `render-content`
+   * event when .element of each group has rendered.
+   */
+  private groups: GrDiffGroup[] = [];
+
   static override get styles() {
     return [
       iconStyles,
@@ -301,10 +350,10 @@
     if (this.diff && this.diffTable) {
       this.diffSelection.init(this.diff, this.diffTable);
     }
-    if (this.diffTable && this.diffBuilder) {
-      this.highlights.init(this.diffTable, this.diffBuilder);
+    if (this.diffTable) {
+      this.highlights.init(this.diffTable, this);
     }
-    this.diffBuilder.init();
+    this.diffBuilderInit();
   }
 
   override disconnectedCallback() {
@@ -312,7 +361,7 @@
     this.renderDiffTableTask?.cancel();
     this.diffSelection.cleanup();
     this.highlights.cleanup();
-    this.diffBuilder.cleanup();
+    this.diffBuilderCleanup();
     super.disconnectedCallback();
   }
 
@@ -340,7 +389,7 @@
       }
     }
     if (changedProperties.has('coverageRanges')) {
-      this.diffBuilder.updateCoverageRanges(this.coverageRanges);
+      this.updateCoverageRanges(this.coverageRanges);
     }
     if (changedProperties.has('lineOfInterest')) {
       this.lineOfInterestChanged();
@@ -439,10 +488,6 @@
     document.removeEventListener('mouseup', this.handleMouseUp);
   }
 
-  getLineNumEls(side: Side): HTMLElement[] {
-    return this.diffBuilder.getLineNumEls(side);
-  }
-
   // Private but used in tests.
   showNoChangeMessage() {
     return (
@@ -526,7 +571,7 @@
       });
     }
 
-    this.diffBuilder.updateCommentRanges(this.commentRanges);
+    this.updateCommentRanges(this.commentRanges);
   }
 
   /**
@@ -534,7 +579,8 @@
    * where lines should not be collapsed.
    *
    */
-  private computeKeyLocations() {
+  // visible for testing
+  computeKeyLocations() {
     const keyLocations: KeyLocations = {left: {}, right: {}};
     if (this.lineOfInterest) {
       const side = this.lineOfInterest.side;
@@ -572,7 +618,7 @@
 
   /** Cancel any remaining diff builder rendering work. */
   cancel() {
-    this.diffBuilder.cleanup();
+    this.diffBuilderCleanup();
     this.renderDiffTableTask?.cancel();
   }
 
@@ -580,8 +626,7 @@
     if (this.hidden && this.noAutoRender) return [];
 
     // Get rendered stops.
-    const stops: Array<HTMLElement | AbortStop> =
-      this.diffBuilder.getLineNumberRows();
+    const stops: Array<HTMLElement | AbortStop> = this.getLineNumberRows();
 
     // If we are still loading this diff, abort after the rendered stops to
     // avoid skipping over to e.g. the next file.
@@ -600,7 +645,7 @@
   }
 
   private blameChanged() {
-    this.diffBuilder.setBlame(this.blame);
+    this.setBlame(this.blame);
     if (this.blame) {
       this.classList.add('showBlame');
     } else {
@@ -669,7 +714,7 @@
 
   createCommentForSelection(side: Side, range: CommentRange) {
     const lineNum = range.end_line;
-    const lineEl = this.diffBuilder.getLineElByNumber(lineNum, side);
+    const lineEl = this.getLineElByNumber(lineNum, side);
     if (lineEl) {
       this.createComment(lineEl, lineNum, side, range);
     }
@@ -690,7 +735,7 @@
     side?: Side,
     range?: CommentRange
   ) {
-    const contentEl = this.diffBuilder.getContentTdByLineEl(lineEl);
+    const contentEl = this.getContentTdByLineEl(lineEl);
     if (!contentEl) throw new Error('content el not found for line el');
     side = side ?? this.getCommentSideByLineAndContent(lineEl, contentEl);
     fire(this, 'create-comment', {
@@ -715,7 +760,7 @@
     if (!this.lineOfInterest) return;
     const lineNum = this.lineOfInterest.lineNum;
     if (typeof lineNum !== 'number') return;
-    this.diffBuilder.unhideLine(lineNum, this.lineOfInterest.side);
+    this.unhideLine(lineNum, this.lineOfInterest.side);
   }
 
   private cleanup() {
@@ -815,7 +860,7 @@
     if (this.prefs) {
       this.updatePreferenceStyles();
     }
-    this.diffBuilder.updateRenderPrefs(this.renderPrefs);
+    this.updateRenderPrefs(this.renderPrefs);
   }
 
   private diffChanged() {
@@ -826,7 +871,7 @@
       this.debounceRenderDiffTable();
       assertIsDefined(this.diffTable, 'diffTable');
       this.diffSelection.init(this.diff, this.diffTable);
-      this.highlights.init(this.diffTable, this.diffBuilder);
+      this.highlights.init(this.diffTable, this);
     }
   }
 
@@ -871,7 +916,7 @@
       return;
     }
     if (
-      this.prefs.context === -1 &&
+      this.getBypassPrefs().context === -1 &&
       this.diffLength &&
       this.diffLength >= LARGE_DIFF_THRESHOLD_LINES &&
       this.safetyBypass === null
@@ -883,8 +928,6 @@
 
     this.showWarning = false;
 
-    const keyLocations = this.computeKeyLocations();
-
     this.diffModel.setState({
       diff: this.diff,
       path: this.path,
@@ -892,25 +935,9 @@
       diffPrefs: this.prefs,
     });
 
-    // TODO: Setting tons of public properties like this is obviously a code
-    // smell. We are introducing a diff model for managing all this
-    // data. Then diff builder will only need access to that model.
-    this.diffBuilder.prefs = this.getBypassPrefs();
-    this.diffBuilder.renderPrefs = this.renderPrefs;
-    this.diffBuilder.diff = this.diff;
-    this.diffBuilder.path = this.path;
-    this.diffBuilder.viewMode = this.viewMode;
-    this.diffBuilder.layers = this.layers ?? [];
-    this.diffBuilder.isImageDiff = this.isImageDiff;
-    this.diffBuilder.baseImage = this.baseImage ?? null;
-    this.diffBuilder.revisionImage = this.revisionImage ?? null;
-    this.diffBuilder.useNewImageDiffUi = this.useNewImageDiffUi;
-    this.diffBuilder.diffElement = this.diffTable;
-    // `this.commentRanges` are probably empty here, because they will only be
-    // populated by the node observer, which starts observing *after* rendering.
-    this.diffBuilder.updateCommentRanges(this.commentRanges);
-    this.diffBuilder.updateCoverageRanges(this.coverageRanges);
-    await this.diffBuilder.render(keyLocations);
+    this.updateCommentRanges(this.commentRanges);
+    this.updateCoverageRanges(this.coverageRanges);
+    await this.legacyRender();
   }
 
   private handleRenderContent() {
@@ -959,7 +986,7 @@
       const commentSide = getSide(threadEl);
       const range = getRange(threadEl);
       if (!commentSide) continue;
-      const lineEl = this.diffBuilder.getLineElByNumber(lineNum, commentSide);
+      const lineEl = this.getLineElByNumber(lineNum, commentSide);
       // When the line the comment refers to does not exist, log an error
       // but don't crash. This can happen e.g. if the API does not fully
       // validate e.g. (robot) comments
@@ -972,7 +999,7 @@
         );
         continue;
       }
-      const contentEl = this.diffBuilder.getContentTdByLineEl(lineEl);
+      const contentEl = this.getContentTdByLineEl(lineEl);
       if (!contentEl) continue;
       if (lineNum === LOST) {
         this.insertPortedCommentsWithoutRangeMessage(contentEl);
@@ -1029,7 +1056,8 @@
   /**
    * Get the preferences object including the safety bypass context (if any).
    */
-  private getBypassPrefs() {
+  // visible for testing
+  getBypassPrefs() {
     assertIsDefined(this.prefs, 'prefs');
     if (this.safetyBypass !== null) {
       return {...this.prefs, context: this.safetyBypass};
@@ -1040,9 +1068,7 @@
   clearDiffContent() {
     this.unobserveNodes();
     if (!this.diffTable) return;
-    while (this.diffTable.hasChildNodes()) {
-      this.diffTable.removeChild(this.diffTable.lastChild!);
-    }
+    this.diffTable.innerHTML = '';
   }
 
   // Private but used in tests.
@@ -1099,6 +1125,425 @@
     }
     return messages.join(' \u2014 '); // \u2014 - '—'
   }
+
+  private updateCommentRanges(ranges: CommentRangeLayer[]) {
+    this.rangeLayer?.updateRanges(ranges);
+  }
+
+  private updateCoverageRanges(rs: CoverageRange[]) {
+    this.coverageLayerLeft.setRanges(rs.filter(r => r?.side === Side.LEFT));
+    this.coverageLayerRight.setRanges(rs.filter(r => r?.side === Side.RIGHT));
+  }
+
+  legacyRender(): Promise<void> {
+    assertIsDefined(this.diff, 'diff');
+    assertIsDefined(this.diffTable, 'diff table');
+    assertIsDefined(this.prefs, 'prefs');
+
+    // Setting up annotation layers must happen after plugins are
+    // installed, and |render| satisfies the requirement, however,
+    // |attached| doesn't because in the diff view page, the element is
+    // attached before plugins are installed.
+    this.setupAnnotationLayers();
+
+    this.showTabs = this.prefs.show_tabs;
+    this.showTrailingWhitespace = this.prefs.show_whitespace_errors;
+
+    this.diffBuilderCleanup();
+    this.builder = this.getDiffBuilder();
+    this.diffBuilderInit();
+
+    // TODO: Just pass along the diff model here instead of setting many
+    // individual properties.
+    this.processor = new GrDiffProcessor();
+    this.processor.consumer = this;
+    this.processor.context = this.getBypassPrefs().context;
+    this.processor.keyLocations = this.computeKeyLocations();
+    if (this.renderPrefs?.num_lines_rendered_at_once) {
+      this.processor.asyncThreshold =
+        this.renderPrefs.num_lines_rendered_at_once;
+    }
+
+    this.diffTable.innerHTML = '';
+    this.builder.addColumns(this.diffTable, getLineNumberCellWidth(this.prefs));
+
+    const isBinary = !!(this.isImageDiff || this.diff.binary);
+
+    fire(this.diffTable, 'render-start', {});
+    return (
+      this.processor
+        .process(this.diff.content, isBinary)
+        .then(async () => {
+          if (isImageDiffBuilder(this.builder)) {
+            this.builder.renderImageDiff();
+          } else if (isBinaryDiffBuilder(this.builder)) {
+            this.builder.renderBinaryDiff();
+          }
+          await this.untilGroupsRendered();
+          fire(this.diffTable, 'render-content', {});
+        })
+        // Mocha testing does not like uncaught rejections, so we catch
+        // the cancels which are expected and should not throw errors in
+        // tests.
+        .catch(e => {
+          if (!e.isCanceled) return Promise.reject(e);
+          return;
+        })
+    );
+  }
+
+  // visible for testing
+  async untilGroupsRendered(groups: readonly GrDiffGroup[] = this.groups) {
+    return Promise.all(groups.map(g => g.waitUntilRendered()));
+  }
+
+  private onDiffContextExpanded = (
+    e: CustomEvent<DiffContextExpandedEventDetail>
+  ) => {
+    // Don't stop propagation. The host may listen for reporting or
+    // resizing.
+    this.replaceGroup(e.detail.contextGroup, e.detail.groups);
+  };
+
+  // visible for testing
+  setupAnnotationLayers() {
+    this.rangeLayer = new GrRangedCommentLayer();
+
+    const layers: DiffLayer[] = [
+      this.createTrailingWhitespaceLayer(),
+      this.createIntralineLayer(),
+      this.createTabIndicatorLayer(),
+      this.createSpecialCharacterIndicatorLayer(),
+      this.rangeLayer,
+      this.coverageLayerLeft,
+      this.coverageLayerRight,
+    ];
+
+    if (this.layers) {
+      layers.push(...this.layers);
+    }
+    this.layersInternal = layers;
+  }
+
+  getContentTdByLine(lineNumber: LineNumber, side?: Side) {
+    if (!this.builder) return undefined;
+    return this.builder.getContentTdByLine(lineNumber, side);
+  }
+
+  getContentTdByLineEl(lineEl?: Element): Element | undefined {
+    if (!lineEl) return undefined;
+    const line = getLineNumber(lineEl);
+    if (!line) return undefined;
+    const side = getSideByLineEl(lineEl);
+    return this.getContentTdByLine(line, side);
+  }
+
+  getLineElByNumber(lineNumber: LineNumber, side?: Side) {
+    if (!this.builder) return undefined;
+    return this.builder.getLineElByNumber(lineNumber, side);
+  }
+
+  getLineNumberRows() {
+    if (!this.builder) return [];
+    return this.builder.getLineNumberRows();
+  }
+
+  getLineNumEls(side: Side) {
+    if (!this.builder) return [];
+    return this.builder.getLineNumEls(side);
+  }
+
+  /**
+   * When the line is hidden behind a context expander, expand it.
+   *
+   * @param lineNum A line number to expand. Using number here because other
+   *   special case line numbers are never hidden, so it does not make sense
+   *   to expand them.
+   * @param side The side the line number refer to.
+   */
+  unhideLine(lineNum: number, side: Side) {
+    assertIsDefined(this.prefs, 'prefs');
+    if (!this.builder) return;
+    const group = this.builder.findGroup(side, lineNum);
+    // Cannot unhide a line that is not part of the diff.
+    if (!group) return;
+    // If it's already visible, great!
+    if (group.type !== GrDiffGroupType.CONTEXT_CONTROL) return;
+    const lineRange = group.lineRange[side];
+    const lineOffset = lineNum - lineRange.start_line;
+    const newGroups = [];
+    const groups = hideInContextControl(
+      group.contextGroups,
+      0,
+      lineOffset - 1 - this.prefs.context
+    );
+    // If there is a context group, it will be the first group because we
+    // start hiding from 0 offset
+    if (groups[0].type === GrDiffGroupType.CONTEXT_CONTROL) {
+      newGroups.push(groups.shift()!);
+    }
+    newGroups.push(
+      ...hideInContextControl(
+        groups,
+        lineOffset + 1 + this.prefs.context,
+        // Both ends inclusive, so difference is the offset of the last line.
+        // But we need to pass the first line not to hide, which is the element
+        // after.
+        lineRange.end_line - lineRange.start_line + 1
+      )
+    );
+    this.replaceGroup(group, newGroups);
+  }
+
+  /**
+   * Replace the group of a context control section by rendering the provided
+   * groups instead. This happens in response to expanding a context control
+   * group.
+   *
+   * @param contextGroup The context control group to replace
+   * @param newGroups The groups that are replacing the context control group
+   */
+  private replaceGroup(
+    contextGroup: GrDiffGroup,
+    newGroups: readonly GrDiffGroup[]
+  ) {
+    if (!this.builder) return;
+    fire(this.diffTable, 'render-start', {});
+    this.builder.replaceGroup(contextGroup, newGroups);
+    this.groups = this.groups.filter(g => g !== contextGroup);
+    this.groups.push(...newGroups);
+    this.untilGroupsRendered(newGroups).then(() => {
+      fire(this.diffTable, 'render-content', {});
+    });
+  }
+
+  /**
+   * This is meant to be called when the gr-diff component re-connects, or when
+   * the diff is (re-)rendered.
+   *
+   * Make sure that this method is symmetric with cleanup(), which is called
+   * when gr-diff disconnects.
+   */
+  private diffBuilderInit() {
+    this.cleanup();
+    this.diffTable?.addEventListener(
+      'diff-context-expanded-internal-new',
+      this.onDiffContextExpanded
+    );
+    this.builder?.init();
+  }
+
+  /**
+   * This is meant to be called when the gr-diff component disconnects, or when
+   * the diff is (re-)rendered.
+   *
+   * Make sure that this method is symmetric with init(), which is called when
+   * gr-diff re-connects.
+   */
+  private diffBuilderCleanup() {
+    this.processor?.cancel();
+    this.builder?.cleanup();
+    this.diffTable?.removeEventListener(
+      'diff-context-expanded-internal-new',
+      this.onDiffContextExpanded
+    );
+  }
+
+  // visible for testing
+  handlePreferenceError(pref: string): never {
+    const message =
+      `The value of the '${pref}' user preference is ` +
+      'invalid. Fix in diff preferences';
+    assertIsDefined(this.diffTable, 'diff table');
+    fireAlert(this.diffTable, message);
+    throw Error(`Invalid preference value: ${pref}`);
+  }
+
+  // visible for testing
+  getDiffBuilder(): GrDiffBuilder {
+    assertIsDefined(this.diff, 'diff');
+    assertIsDefined(this.diffTable, 'diff table');
+    assertIsDefined(this.prefs, 'prefs');
+    if (isNaN(this.prefs.tab_size) || this.prefs.tab_size <= 0) {
+      this.handlePreferenceError('tab size');
+    }
+
+    if (isNaN(this.prefs.line_length) || this.prefs.line_length <= 0) {
+      this.handlePreferenceError('diff width');
+    }
+
+    const localPrefs = {...this.prefs};
+    if (this.path === COMMIT_MSG_PATH) {
+      // override line_length for commit msg the same way as
+      // in gr-diff
+      localPrefs.line_length = COMMIT_MSG_LINE_LENGTH;
+    }
+
+    let builder = null;
+    if (this.isImageDiff) {
+      builder = new GrDiffBuilderImage(
+        this.diff,
+        localPrefs,
+        this.diffTable,
+        this.baseImage ?? null,
+        this.revisionImage ?? null,
+        this.renderPrefs,
+        this.useNewImageDiffUi
+      );
+    } else if (this.diff.binary) {
+      return new GrDiffBuilderBinary(this.diff, localPrefs, this.diffTable);
+    } else if (this.viewMode === DiffViewMode.SIDE_BY_SIDE) {
+      this.renderPrefs = {
+        ...this.renderPrefs,
+        view_mode: DiffViewMode.SIDE_BY_SIDE,
+      };
+      builder = new GrDiffBuilder(
+        this.diff,
+        localPrefs,
+        this.diffTable,
+        this.layersInternal,
+        this.renderPrefs
+      );
+    } else if (this.viewMode === DiffViewMode.UNIFIED) {
+      this.renderPrefs = {
+        ...this.renderPrefs,
+        view_mode: DiffViewMode.UNIFIED,
+      };
+      builder = new GrDiffBuilder(
+        this.diff,
+        localPrefs,
+        this.diffTable,
+        this.layersInternal,
+        this.renderPrefs
+      );
+    }
+    if (!builder) {
+      throw Error(`Unsupported diff view mode: ${this.viewMode}`);
+    }
+    return builder;
+  }
+
+  /**
+   * Called when the processor starts converting the diff information from the
+   * server into chunks.
+   */
+  clearGroups() {
+    if (!this.builder) return;
+    this.groups = [];
+    this.builder.clearGroups();
+  }
+
+  /**
+   * Called when the processor is done converting a chunk of the diff.
+   */
+  addGroup(group: GrDiffGroup) {
+    if (!this.builder) return;
+    this.builder.addGroups([group]);
+    this.groups.push(group);
+  }
+
+  // visible for testing
+  createIntralineLayer(): DiffLayer {
+    return {
+      // Take a DIV.contentText element and a line object with intraline
+      // differences to highlight and apply them to the element as
+      // annotations.
+      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
+        const HL_CLASS = 'gr-diff intraline';
+        for (const highlight of line.highlights) {
+          // The start and end indices could be the same if a highlight is
+          // meant to start at the end of a line and continue onto the
+          // next one. Ignore it.
+          if (highlight.startIndex === highlight.endIndex) {
+            continue;
+          }
+
+          // If endIndex isn't present, continue to the end of the line.
+          const endIndex =
+            highlight.endIndex === undefined
+              ? GrAnnotation.getStringLength(line.text)
+              : highlight.endIndex;
+
+          GrAnnotation.annotateElement(
+            contentEl,
+            highlight.startIndex,
+            endIndex - highlight.startIndex,
+            HL_CLASS
+          );
+        }
+      },
+    };
+  }
+
+  // visible for testing
+  createTabIndicatorLayer(): DiffLayer {
+    const show = () => this.showTabs;
+    return {
+      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
+        // If visible tabs are disabled, do nothing.
+        if (!show()) {
+          return;
+        }
+
+        // Find and annotate the locations of tabs.
+        annotateSymbols(contentEl, line, '\t', 'tab-indicator');
+      },
+    };
+  }
+
+  private createSpecialCharacterIndicatorLayer(): DiffLayer {
+    return {
+      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
+        // Find and annotate the locations of soft hyphen (\u00AD)
+        annotateSymbols(contentEl, line, '\u00AD', 'special-char-indicator');
+        // Find and annotate Stateful Unicode directional controls
+        annotateSymbols(
+          contentEl,
+          line,
+          /[\u202A-\u202E\u2066-\u2069]/,
+          'special-char-warning'
+        );
+      },
+    };
+  }
+
+  // visible for testing
+  createTrailingWhitespaceLayer(): DiffLayer {
+    const show = () => this.showTrailingWhitespace;
+
+    return {
+      annotate(contentEl: HTMLElement, _: HTMLElement, line: GrDiffLine) {
+        if (!show()) {
+          return;
+        }
+
+        const match = line.text.match(TRAILING_WHITESPACE_PATTERN);
+        if (match) {
+          // Normalize string positions in case there is unicode before or
+          // within the match.
+          const index = GrAnnotation.getStringLength(
+            line.text.substr(0, match.index)
+          );
+          const length = GrAnnotation.getStringLength(match[0]);
+          GrAnnotation.annotateElement(
+            contentEl,
+            index,
+            length,
+            'gr-diff trailing-whitespace'
+          );
+        }
+      },
+    };
+  }
+
+  setBlame(blame: BlameInfo[] | null) {
+    if (!this.builder) return;
+    this.builder.setBlame(blame ?? []);
+  }
+
+  updateRenderPrefs(renderPrefs: RenderPreferences) {
+    this.builder?.updateRenderPrefs(renderPrefs);
+  }
 }
 
 function extractAddedNodes(mutations: MutationRecord[]) {
@@ -1109,6 +1554,30 @@
   return mutations.flatMap(mutation => [...mutation.removedNodes]);
 }
 
+function getLineNumberCellWidth(prefs: DiffPreferencesInfo) {
+  return prefs.font_size * 4;
+}
+
+function annotateSymbols(
+  contentEl: HTMLElement,
+  line: GrDiffLine,
+  separator: string | RegExp,
+  className: string
+) {
+  const split = line.text.split(separator);
+  if (!split || split.length < 2) {
+    return;
+  }
+  for (let i = 0, pos = 0; i < split.length - 1; i++) {
+    // Skip forward by the length of the content
+    pos += split[i].length;
+
+    GrAnnotation.annotateElement(contentEl, pos, 1, `gr-diff ${className}`);
+
+    pos++;
+  }
+}
+
 // TODO(newdiff-cleanup): Remove once newdiff migration is completed.
 if (isNewDiff()) {
   customElements.define('gr-diff', GrDiff);
@@ -1124,5 +1593,15 @@
     'comment-thread-mouseleave': CustomEvent<{}>;
     'loading-changed': ValueChangedEvent<boolean>;
     'render-required': CustomEvent<{}>;
+    /**
+     * Fired when the diff begins rendering - both for full renders and for
+     * partial rerenders.
+     */
+    'render-start': CustomEvent<{}>;
+    /**
+     * Fired when the diff finishes rendering text content - both for full
+     * renders and for partial rerenders.
+     */
+    'render-content': CustomEvent<{}>;
   }
 }
diff --git a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff_test.ts b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff_test.ts
index f0826ad..d542633 100644
--- a/polygerrit-ui/app/embed/diff/gr-diff/gr-diff_test.ts
+++ b/polygerrit-ui/app/embed/diff/gr-diff/gr-diff_test.ts
@@ -4,15 +4,21 @@
  * SPDX-License-Identifier: Apache-2.0
  */
 import '../../../test/common-test-setup';
-import {createDiff} from '../../../test/test-data-generators';
+import {
+  createConfig,
+  createDiff,
+  createEmptyDiff,
+} from '../../../test/test-data-generators';
 import './gr-diff';
-import {getComputedStyleValue} from '../../../utils/dom-util';
+import {getComputedStyleValue, querySelectorAll} from '../../../utils/dom-util';
 import '@polymer/paper-button/paper-button';
 import {
   DiffContent,
   DiffInfo,
+  DiffLayer,
   DiffPreferencesInfo,
   DiffViewMode,
+  GrDiffLineType,
   IgnoreWhitespaceType,
   Side,
 } from '../../../api/diff';
@@ -22,6 +28,8 @@
   query,
   queryAll,
   queryAndAssert,
+  stubBaseUrl,
+  stubRestApi,
   waitEventLoop,
   waitQueryAndAssert,
   waitUntil,
@@ -33,6 +41,13 @@
 import {GrRangedCommentHint} from '../gr-ranged-comment-hint/gr-ranged-comment-hint';
 import {assertIsDefined} from '../../../utils/common-util';
 import {fixture, html, assert} from '@open-wc/testing';
+import {createDefaultDiffPrefs} from '../../../constants/constants';
+import {GrDiffBuilder} from '../gr-diff-builder/gr-diff-builder';
+import {GrDiffRow} from '../gr-diff-builder/gr-diff-row';
+import {GrAnnotation} from '../gr-diff-highlight/gr-annotation';
+import {GrDiffLine} from './gr-diff-line';
+
+const DEFAULT_PREFS = createDefaultDiffPrefs();
 
 suite('gr-diff a11y test', () => {
   test('audit', async () => {
@@ -3021,12 +3036,6 @@
     });
   });
 
-  test('cancel', () => {
-    const cleanupStub = sinon.stub(element.diffBuilder, 'cleanup');
-    element.cancel();
-    assert.isTrue(cleanupStub.calledOnce);
-  });
-
   test('line limit with line_wrapping', async () => {
     element.prefs = {...MINIMAL_PREFS, line_wrapping: true};
     await element.updateComplete;
@@ -3796,10 +3805,9 @@
     let renderStub: sinon.SinonStub;
 
     setup(async () => {
-      renderStub = sinon.stub(element.diffBuilder, 'render').callsFake(() => {
+      renderStub = sinon.stub(element, 'legacyRender').callsFake(() => {
         assertIsDefined(element.diffTable);
-        const diffTable = element.diffTable;
-        diffTable.dispatchEvent(
+        element.diffTable.dispatchEvent(
           new CustomEvent('render', {bubbles: true, composed: true})
         );
         return Promise.resolve();
@@ -3847,7 +3855,7 @@
 
       assert.equal(element.prefs.context, 3);
       assert.equal(element.safetyBypass, -1);
-      assert.equal(element.diffBuilder.prefs.context, -1);
+      assert.equal(element.getBypassPrefs().context, -1);
     });
 
     test('toggles collapse context from bypass', async () => {
@@ -3860,7 +3868,7 @@
 
       assert.equal(element.prefs.context, 3);
       assert.isNull(element.safetyBypass);
-      assert.equal(element.diffBuilder.prefs.context, 3);
+      assert.equal(element.getBypassPrefs().context, 3);
     });
 
     test('toggles collapse context from pref using default', async () => {
@@ -3872,14 +3880,14 @@
 
       assert.equal(element.prefs.context, -1);
       assert.equal(element.safetyBypass, 10);
-      assert.equal(element.diffBuilder.prefs.context, 10);
+      assert.equal(element.getBypassPrefs().context, 10);
     });
   });
 
   suite('blame', () => {
     test('unsetting', async () => {
       element.blame = [];
-      const setBlameSpy = sinon.spy(element.diffBuilder, 'setBlame');
+      const setBlameSpy = sinon.spy(element, 'setBlame');
       element.classList.add('showBlame');
       element.blame = null;
       await element.updateComplete;
@@ -3957,20 +3965,15 @@
   });
 
   suite('key locations', () => {
-    let renderStub: sinon.SinonStub;
-
     setup(async () => {
       element.prefs = {...MINIMAL_PREFS};
       element.diff = createDiff();
-      renderStub = sinon.stub(element.diffBuilder, 'render');
       await element.updateComplete;
     });
 
     test('lineOfInterest is a key location', () => {
       element.lineOfInterest = {lineNum: 789, side: Side.LEFT};
-      element.renderDiffTable();
-      assert.isTrue(renderStub.called);
-      assert.deepEqual(renderStub.lastCall.args[0], {
+      assert.deepEqual(element.computeKeyLocations(), {
         left: {789: true},
         right: {},
       });
@@ -3984,9 +3987,7 @@
       element.appendChild(threadEl);
       await element.updateComplete;
 
-      element.renderDiffTable();
-      assert.isTrue(renderStub.called);
-      assert.deepEqual(renderStub.lastCall.args[0], {
+      assert.deepEqual(element.computeKeyLocations(), {
         left: {},
         right: {3: true},
       });
@@ -3999,9 +4000,7 @@
       element.appendChild(threadEl);
       await element.updateComplete;
 
-      element.renderDiffTable();
-      assert.isTrue(renderStub.called);
-      assert.deepEqual(renderStub.lastCall.args[0], {
+      assert.deepEqual(element.computeKeyLocations(), {
         left: {FILE: true},
         right: {},
       });
@@ -4057,8 +4056,7 @@
     ];
     function diffTableHasContent() {
       assertIsDefined(element.diffTable);
-      const diffTable = element.diffTable;
-      return diffTable.innerText.includes(content[0].a?.[0] ?? '');
+      return element.diffTable.innerText.includes(content[0].a?.[0] ?? '');
     }
     await setupSampleDiff({content});
     await waitUntil(diffTableHasContent);
@@ -4066,8 +4064,7 @@
     await element.updateComplete;
     // immediately cleaned up
     assertIsDefined(element.diffTable);
-    const diffTable = element.diffTable;
-    assert.equal(diffTable.innerHTML, '');
+    assert.equal(element.diffTable.innerHTML, '');
     element.renderDiffTable();
     await element.updateComplete;
     // rendered again
@@ -4182,3 +4179,598 @@
     assert.equal(element.getDiffLength(diff), 52);
   });
 });
+
+suite('former gr-diff-builder tests', () => {
+  let element: GrDiff;
+  let builder: GrDiffBuilder;
+  let diffTable: HTMLTableElement;
+
+  const setBuilderPrefs = (prefs: Partial<DiffPreferencesInfo>) => {
+    builder = new GrDiffBuilder(
+      createEmptyDiff(),
+      {...createDefaultDiffPrefs(), ...prefs},
+      diffTable
+    );
+  };
+
+  const line = (text: string) => {
+    const line = new GrDiffLine(GrDiffLineType.BOTH);
+    line.text = text;
+    return line;
+  };
+
+  setup(async () => {
+    element = await fixture<GrDiff>(html`<gr-diff></gr-diff>`);
+    element.diff = createEmptyDiff();
+    await element.updateComplete;
+    stubRestApi('getLoggedIn').returns(Promise.resolve(false));
+    stubRestApi('getProjectConfig').returns(Promise.resolve(createConfig()));
+    stubBaseUrl('/r');
+    setBuilderPrefs({});
+  });
+
+  [DiffViewMode.UNIFIED, DiffViewMode.SIDE_BY_SIDE].forEach(mode => {
+    test(`line_length used for regular files under ${mode}`, () => {
+      element.path = '/a.txt';
+      element.viewMode = mode;
+      element.diff = createEmptyDiff();
+      element.prefs = {
+        ...createDefaultDiffPrefs(),
+        tab_size: 4,
+        line_length: 50,
+      };
+      builder = element.getDiffBuilder();
+      assert.equal(builder.prefs.line_length, 50);
+    });
+
+    test(`line_length ignored for commit msg under ${mode}`, () => {
+      element.path = '/COMMIT_MSG';
+      element.viewMode = mode;
+      element.diff = createEmptyDiff();
+      element.prefs = {
+        ...createDefaultDiffPrefs(),
+        tab_size: 4,
+        line_length: 50,
+      };
+      builder = element.getDiffBuilder();
+      assert.equal(builder.prefs.line_length, 72);
+    });
+  });
+
+  test('_handlePreferenceError throws with invalid preference', () => {
+    element.prefs = {...createDefaultDiffPrefs(), tab_size: 0};
+    assert.throws(() => element.getDiffBuilder());
+  });
+
+  test('_handlePreferenceError triggers alert and javascript error', () => {
+    const errorStub = sinon.stub();
+    element.diffTable!.addEventListener('show-alert', errorStub);
+    assert.throws(() => element.handlePreferenceError('tab size'));
+    assert.equal(
+      errorStub.lastCall.args[0].detail.message,
+      "The value of the 'tab size' user preference is invalid. " +
+        'Fix in diff preferences'
+    );
+  });
+
+  suite('intraline differences', () => {
+    let el: HTMLElement;
+    let str: string;
+    let annotateElementSpy: sinon.SinonSpy;
+    let layer: DiffLayer;
+    const lineNumberEl = document.createElement('td');
+
+    function slice(str: string, start: number, end?: number) {
+      return Array.from(str).slice(start, end).join('');
+    }
+
+    setup(async () => {
+      el = await fixture(html`
+        <div>Lorem ipsum dolor sit amet, suspendisse inceptos vehicula</div>
+      `);
+      str = el.textContent ?? '';
+      annotateElementSpy = sinon.spy(GrAnnotation, 'annotateElement');
+      layer = element.createIntralineLayer();
+    });
+
+    test('annotate no highlights', () => {
+      layer.annotate(el, lineNumberEl, line(str), Side.LEFT);
+
+      // The content is unchanged.
+      assert.isFalse(annotateElementSpy.called);
+      assert.equal(el.childNodes.length, 1);
+      assert.instanceOf(el.childNodes[0], Text);
+      assert.equal(str, el.childNodes[0].textContent);
+    });
+
+    test('annotate with highlights', () => {
+      const l = line(str);
+      l.highlights = [
+        {contentIndex: 0, startIndex: 6, endIndex: 12},
+        {contentIndex: 0, startIndex: 18, endIndex: 22},
+      ];
+      const str0 = slice(str, 0, 6);
+      const str1 = slice(str, 6, 12);
+      const str2 = slice(str, 12, 18);
+      const str3 = slice(str, 18, 22);
+      const str4 = slice(str, 22);
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isTrue(annotateElementSpy.called);
+      assert.equal(el.childNodes.length, 5);
+
+      assert.instanceOf(el.childNodes[0], Text);
+      assert.equal(el.childNodes[0].textContent, str0);
+
+      assert.notInstanceOf(el.childNodes[1], Text);
+      assert.equal(el.childNodes[1].textContent, str1);
+
+      assert.instanceOf(el.childNodes[2], Text);
+      assert.equal(el.childNodes[2].textContent, str2);
+
+      assert.notInstanceOf(el.childNodes[3], Text);
+      assert.equal(el.childNodes[3].textContent, str3);
+
+      assert.instanceOf(el.childNodes[4], Text);
+      assert.equal(el.childNodes[4].textContent, str4);
+    });
+
+    test('annotate without endIndex', () => {
+      const l = line(str);
+      l.highlights = [{contentIndex: 0, startIndex: 28}];
+
+      const str0 = slice(str, 0, 28);
+      const str1 = slice(str, 28);
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isTrue(annotateElementSpy.called);
+      assert.equal(el.childNodes.length, 2);
+
+      assert.instanceOf(el.childNodes[0], Text);
+      assert.equal(el.childNodes[0].textContent, str0);
+
+      assert.notInstanceOf(el.childNodes[1], Text);
+      assert.equal(el.childNodes[1].textContent, str1);
+    });
+
+    test('annotate ignores empty highlights', () => {
+      const l = line(str);
+      l.highlights = [{contentIndex: 0, startIndex: 28, endIndex: 28}];
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isFalse(annotateElementSpy.called);
+      assert.equal(el.childNodes.length, 1);
+    });
+
+    test('annotate handles unicode', () => {
+      // Put some unicode into the string:
+      str = str.replace(/\s/g, '💢');
+      el.textContent = str;
+      const l = line(str);
+      l.highlights = [{contentIndex: 0, startIndex: 6, endIndex: 12}];
+
+      const str0 = slice(str, 0, 6);
+      const str1 = slice(str, 6, 12);
+      const str2 = slice(str, 12);
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isTrue(annotateElementSpy.called);
+      assert.equal(el.childNodes.length, 3);
+
+      assert.instanceOf(el.childNodes[0], Text);
+      assert.equal(el.childNodes[0].textContent, str0);
+
+      assert.notInstanceOf(el.childNodes[1], Text);
+      assert.equal(el.childNodes[1].textContent, str1);
+
+      assert.instanceOf(el.childNodes[2], Text);
+      assert.equal(el.childNodes[2].textContent, str2);
+    });
+
+    test('annotate handles unicode w/o endIndex', () => {
+      // Put some unicode into the string:
+      str = str.replace(/\s/g, '💢');
+      el.textContent = str;
+
+      const l = line(str);
+      l.highlights = [{contentIndex: 0, startIndex: 6}];
+
+      const str0 = slice(str, 0, 6);
+      const str1 = slice(str, 6);
+      const numHighlightedChars = GrAnnotation.getStringLength(str1);
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isTrue(annotateElementSpy.calledWith(el, 6, numHighlightedChars));
+      assert.equal(el.childNodes.length, 2);
+
+      assert.instanceOf(el.childNodes[0], Text);
+      assert.equal(el.childNodes[0].textContent, str0);
+
+      assert.notInstanceOf(el.childNodes[1], Text);
+      assert.equal(el.childNodes[1].textContent, str1);
+    });
+  });
+
+  suite('tab indicators', () => {
+    let layer: DiffLayer;
+    const lineNumberEl = document.createElement('td');
+
+    setup(() => {
+      element.showTabs = true;
+      layer = element.createTabIndicatorLayer();
+    });
+
+    test('does nothing with empty line', () => {
+      const l = line('');
+      const el = document.createElement('div');
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isFalse(annotateElementStub.called);
+    });
+
+    test('does nothing with no tabs', () => {
+      const str = 'lorem ipsum no tabs';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isFalse(annotateElementStub.called);
+    });
+
+    test('annotates tab at beginning', () => {
+      const str = '\tlorem upsum';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.equal(annotateElementStub.callCount, 1);
+      const args = annotateElementStub.getCalls()[0].args;
+      assert.equal(args[0], el);
+      assert.equal(args[1], 0, 'offset of tab indicator');
+      assert.equal(args[2], 1, 'length of tab indicator');
+      assert.include(args[3], 'tab-indicator');
+    });
+
+    test('does not annotate when disabled', () => {
+      element.showTabs = false;
+
+      const str = '\tlorem upsum';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.isFalse(annotateElementStub.called);
+    });
+
+    test('annotates multiple in beginning', () => {
+      const str = '\t\tlorem upsum';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.equal(annotateElementStub.callCount, 2);
+
+      let args = annotateElementStub.getCalls()[0].args;
+      assert.equal(args[0], el);
+      assert.equal(args[1], 0, 'offset of tab indicator');
+      assert.equal(args[2], 1, 'length of tab indicator');
+      assert.include(args[3], 'tab-indicator');
+
+      args = annotateElementStub.getCalls()[1].args;
+      assert.equal(args[0], el);
+      assert.equal(args[1], 1, 'offset of tab indicator');
+      assert.equal(args[2], 1, 'length of tab indicator');
+      assert.include(args[3], 'tab-indicator');
+    });
+
+    test('annotates intermediate tabs', () => {
+      const str = 'lorem\tupsum';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+
+      assert.equal(annotateElementStub.callCount, 1);
+      const args = annotateElementStub.getCalls()[0].args;
+      assert.equal(args[0], el);
+      assert.equal(args[1], 5, 'offset of tab indicator');
+      assert.equal(args[2], 1, 'length of tab indicator');
+      assert.include(args[3], 'tab-indicator');
+    });
+  });
+
+  suite('layers', () => {
+    let initialLayersCount = 0;
+    let withLayerCount = 0;
+    setup(() => {
+      const layers: DiffLayer[] = [];
+      element.layers = layers;
+      element.showTrailingWhitespace = true;
+      element.setupAnnotationLayers();
+      initialLayersCount = element.layersInternal.length;
+    });
+
+    test('no layers', () => {
+      element.setupAnnotationLayers();
+      assert.equal(element.layersInternal.length, initialLayersCount);
+    });
+
+    suite('with layers', () => {
+      const layers: DiffLayer[] = [{annotate: () => {}}, {annotate: () => {}}];
+      setup(() => {
+        element.layers = layers;
+        element.showTrailingWhitespace = true;
+        element.setupAnnotationLayers();
+        withLayerCount = element.layersInternal.length;
+      });
+      test('with layers', () => {
+        element.setupAnnotationLayers();
+        assert.equal(element.layersInternal.length, withLayerCount);
+        assert.equal(initialLayersCount + layers.length, withLayerCount);
+      });
+    });
+  });
+
+  suite('trailing whitespace', () => {
+    let layer: DiffLayer;
+    const lineNumberEl = document.createElement('td');
+
+    setup(() => {
+      element.showTrailingWhitespace = true;
+      layer = element.createTrailingWhitespaceLayer();
+    });
+
+    test('does nothing with empty line', () => {
+      const l = line('');
+      const el = document.createElement('div');
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isFalse(annotateElementStub.called);
+    });
+
+    test('does nothing with no trailing whitespace', () => {
+      const str = 'lorem ipsum blah blah';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isFalse(annotateElementStub.called);
+    });
+
+    test('annotates trailing spaces', () => {
+      const str = 'lorem ipsum   ';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isTrue(annotateElementStub.called);
+      assert.equal(annotateElementStub.lastCall.args[1], 11);
+      assert.equal(annotateElementStub.lastCall.args[2], 3);
+    });
+
+    test('annotates trailing tabs', () => {
+      const str = 'lorem ipsum\t\t\t';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isTrue(annotateElementStub.called);
+      assert.equal(annotateElementStub.lastCall.args[1], 11);
+      assert.equal(annotateElementStub.lastCall.args[2], 3);
+    });
+
+    test('annotates mixed trailing whitespace', () => {
+      const str = 'lorem ipsum\t \t';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isTrue(annotateElementStub.called);
+      assert.equal(annotateElementStub.lastCall.args[1], 11);
+      assert.equal(annotateElementStub.lastCall.args[2], 3);
+    });
+
+    test('unicode preceding trailing whitespace', () => {
+      const str = '💢\t';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isTrue(annotateElementStub.called);
+      assert.equal(annotateElementStub.lastCall.args[1], 1);
+      assert.equal(annotateElementStub.lastCall.args[2], 1);
+    });
+
+    test('does not annotate when disabled', () => {
+      element.showTrailingWhitespace = false;
+      const str = 'lorem upsum\t \t ';
+      const l = line(str);
+      const el = document.createElement('div');
+      el.textContent = str;
+      const annotateElementStub = sinon.stub(GrAnnotation, 'annotateElement');
+      layer.annotate(el, lineNumberEl, l, Side.LEFT);
+      assert.isFalse(annotateElementStub.called);
+    });
+  });
+
+  suite('rendering text, images and binary files', () => {
+    let content: DiffContent[] = [];
+
+    setup(() => {
+      element.viewMode = DiffViewMode.SIDE_BY_SIDE;
+      element.prefs = {
+        ...DEFAULT_PREFS,
+        context: -1,
+        syntax_highlighting: true,
+      };
+      content = [
+        {
+          a: ['all work and no play make andybons a dull boy'],
+          b: ['elgoog elgoog elgoog'],
+        },
+        {
+          ab: [
+            'Non eram nescius, Brute, cum, quae summis ingeniis ',
+            'exquisitaque doctrina philosophi Graeco sermone tractavissent',
+          ],
+        },
+      ];
+    });
+
+    test('text', async () => {
+      element.diff = {...createEmptyDiff(), content};
+      await waitForEventOnce(element.diffTable!, 'render-content');
+      assert.equal(querySelectorAll(element.diffTable!, 'tbody')?.length, 4);
+    });
+
+    test('image', async () => {
+      element.diff = {...createEmptyDiff(), content, binary: true};
+      element.isImageDiff = true;
+      await waitForEventOnce(element.diffTable!, 'render-content');
+      assert.equal(querySelectorAll(element.diffTable!, 'tbody')?.length, 4);
+    });
+
+    test('binary', async () => {
+      element.diff = {...createEmptyDiff(), content, binary: true};
+      await waitForEventOnce(element.diffTable!, 'render-content');
+      assert.equal(querySelectorAll(element.diffTable!, 'tbody')?.length, 3);
+    });
+  });
+
+  suite('context hiding and expanding', () => {
+    let dispatchStub: sinon.SinonStub;
+
+    setup(async () => {
+      dispatchStub = sinon.stub(element.diffTable!, 'dispatchEvent');
+      element.diff = {
+        ...createEmptyDiff(),
+        content: [
+          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${i}`)},
+          {a: ['before'], b: ['after']},
+          {ab: [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].map(i => `unchanged ${10 + i}`)},
+        ],
+      };
+      element.viewMode = DiffViewMode.SIDE_BY_SIDE;
+
+      element.prefs = {
+        ...DEFAULT_PREFS,
+        context: 1,
+      };
+      await element.updateComplete;
+      element.legacyRender();
+      // Make sure all listeners are installed.
+      await element.untilGroupsRendered();
+    });
+
+    test('hides lines behind two context controls', () => {
+      const contextControls = element.diffTable!.querySelectorAll(
+        'gr-context-controls'
+      );
+      assert.equal(contextControls.length, 2);
+
+      const diffRows = element.diffTable!.querySelectorAll('.diff-row');
+      // The first two are LOST and FILE line
+      assert.equal(diffRows.length, 2 + 1 + 1 + 1);
+      assert.include(diffRows[2].textContent, 'unchanged 10');
+      assert.include(diffRows[3].textContent, 'before');
+      assert.include(diffRows[3].textContent, 'after');
+      assert.include(diffRows[4].textContent, 'unchanged 11');
+    });
+
+    test('clicking +x common lines expands those lines', async () => {
+      const contextControls = element.diffTable!.querySelectorAll(
+        'gr-context-controls'
+      );
+      const topExpandCommonButton =
+        contextControls[0].shadowRoot?.querySelectorAll<HTMLElement>(
+          '.showContext'
+        )[0];
+      assert.isOk(topExpandCommonButton);
+      assert.include(topExpandCommonButton!.textContent, '+9 common lines');
+      let diffRows = element.diffTable!.querySelectorAll('.diff-row');
+      // 5 lines:
+      // FILE, LOST, the changed line plus one line of context in each direction
+      assert.equal(diffRows.length, 5);
+
+      topExpandCommonButton!.click();
+
+      await waitUntil(() => {
+        diffRows = element.diffTable!.querySelectorAll<GrDiffRow>('.diff-row');
+        return diffRows.length === 14;
+      });
+      // 14 lines: The 5 above plus the 9 unchanged lines that were expanded
+      assert.equal(diffRows.length, 14);
+      assert.include(diffRows[2].textContent, 'unchanged 1');
+      assert.include(diffRows[3].textContent, 'unchanged 2');
+      assert.include(diffRows[4].textContent, 'unchanged 3');
+      assert.include(diffRows[5].textContent, 'unchanged 4');
+      assert.include(diffRows[6].textContent, 'unchanged 5');
+      assert.include(diffRows[7].textContent, 'unchanged 6');
+      assert.include(diffRows[8].textContent, 'unchanged 7');
+      assert.include(diffRows[9].textContent, 'unchanged 8');
+      assert.include(diffRows[10].textContent, 'unchanged 9');
+      assert.include(diffRows[11].textContent, 'unchanged 10');
+      assert.include(diffRows[12].textContent, 'before');
+      assert.include(diffRows[12].textContent, 'after');
+      assert.include(diffRows[13].textContent, 'unchanged 11');
+    });
+
+    test('unhideLine shows the line with context', async () => {
+      dispatchStub.reset();
+      element.unhideLine(4, Side.LEFT);
+
+      await waitUntil(() => {
+        const rows =
+          element.diffTable!.querySelectorAll<GrDiffRow>('.diff-row');
+        return rows.length === 2 + 5 + 1 + 1 + 1;
+      });
+
+      const diffRows = element.diffTable!.querySelectorAll('.diff-row');
+      // The first two are LOST and FILE line
+      // Lines 3-5 (Line 4 plus 1 context in each direction) will be expanded
+      // Because context expanders do not hide <3 lines, lines 1-2 will also
+      // be shown.
+      // Lines 6-9 continue to be hidden
+      assert.equal(diffRows.length, 2 + 5 + 1 + 1 + 1);
+      assert.include(diffRows[2].textContent, 'unchanged 1');
+      assert.include(diffRows[3].textContent, 'unchanged 2');
+      assert.include(diffRows[4].textContent, 'unchanged 3');
+      assert.include(diffRows[5].textContent, 'unchanged 4');
+      assert.include(diffRows[6].textContent, 'unchanged 5');
+      assert.include(diffRows[7].textContent, 'unchanged 10');
+      assert.include(diffRows[8].textContent, 'before');
+      assert.include(diffRows[8].textContent, 'after');
+      assert.include(diffRows[9].textContent, 'unchanged 11');
+
+      await element.untilGroupsRendered();
+      const firedEventTypes = dispatchStub.getCalls().map(c => c.args[0].type);
+      assert.include(firedEventTypes, 'render-content');
+    });
+  });
+});
