diff --git a/Documentation/rest-api-changes.txt b/Documentation/rest-api-changes.txt
index 5055007..d6a7092 100644
--- a/Documentation/rest-api-changes.txt
+++ b/Documentation/rest-api-changes.txt
@@ -5356,6 +5356,17 @@
 The `context` parameter can be specified to control the number of lines of surrounding context
 in the diff.  Valid values are `ALL` or number of lines.
 
+[[preview-fix]]
+=== Preview fix
+--
+'GET /changes/<<change-id,\{change-id\}>>/revisions/<<revision-id,\{revision-id\}>>/fixes/<<fix-id,\{fix-id\}>>/preview'
+--
+
+Gets the diffs of all files for a certain <<fix-id,\{fix-id\}>>.
+As response, a map of link:#diff-info[DiffInfo] entities is returned that describes the diffs.
+
+Each link:#diff-info[DiffInfo] is the differences between the patch set indicated by revision-id and a virtual patch set with the applied fix.
+
 [[get-blame]]
 === Get Blame
 --
diff --git a/java/com/google/gerrit/acceptance/BUILD b/java/com/google/gerrit/acceptance/BUILD
index cb3524a..e4a993c 100644
--- a/java/com/google/gerrit/acceptance/BUILD
+++ b/java/com/google/gerrit/acceptance/BUILD
@@ -90,6 +90,7 @@
         "//java/com/google/gerrit/pgm:daemon",
         "//java/com/google/gerrit/pgm/http/jetty",
         "//java/com/google/gerrit/pgm/util",
+        "//java/com/google/gerrit/server/fixes/testing",
         "//java/com/google/gerrit/server/group/testing",
         "//java/com/google/gerrit/server/project/testing:project-test-util",
         "//java/com/google/gerrit/testing:gerrit-test-util",
diff --git a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
index 8853a30..e258134 100644
--- a/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/DiffInfoSubject.java
@@ -18,12 +18,15 @@
 import static com.google.gerrit.extensions.common.testing.FileMetaSubject.fileMetas;
 import static com.google.gerrit.truth.ListSubject.elements;
 
+import com.google.common.truth.BooleanSubject;
 import com.google.common.truth.ComparableSubject;
 import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.IterableSubject;
 import com.google.common.truth.Subject;
 import com.google.gerrit.extensions.common.ChangeType;
 import com.google.gerrit.extensions.common.DiffInfo;
 import com.google.gerrit.extensions.common.DiffInfo.ContentEntry;
+import com.google.gerrit.extensions.common.DiffInfo.IntraLineStatus;
 import com.google.gerrit.truth.ListSubject;
 
 public class DiffInfoSubject extends Subject {
@@ -60,4 +63,24 @@
     isNotNull();
     return check("metaB").about(fileMetas()).that(diffInfo.metaB);
   }
+
+  public ComparableSubject<IntraLineStatus> intralineStatus() {
+    isNotNull();
+    return check("intralineStatus").that(diffInfo.intralineStatus);
+  }
+
+  public IterableSubject webLinks() {
+    isNotNull();
+    return check("webLinks").that(diffInfo.webLinks);
+  }
+
+  public BooleanSubject binary() {
+    isNotNull();
+    return check("binary").that(diffInfo.binary);
+  }
+
+  public IterableSubject diffHeader() {
+    isNotNull();
+    return check("diffHeader").that(diffInfo.diffHeader);
+  }
 }
diff --git a/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java b/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
index fb09a1f..0953bfe 100644
--- a/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
+++ b/java/com/google/gerrit/extensions/common/testing/FileMetaSubject.java
@@ -18,6 +18,8 @@
 
 import com.google.common.truth.FailureMetadata;
 import com.google.common.truth.IntegerSubject;
+import com.google.common.truth.IterableSubject;
+import com.google.common.truth.StringSubject;
 import com.google.common.truth.Subject;
 import com.google.gerrit.extensions.common.DiffInfo.FileMeta;
 
@@ -42,4 +44,24 @@
     isNotNull();
     return check("totalLineCount()").that(fileMeta.lines);
   }
+
+  public StringSubject name() {
+    isNotNull();
+    return check("name").that(fileMeta.name);
+  }
+
+  public StringSubject commitId() {
+    isNotNull();
+    return check("commitId").that(fileMeta.commitId);
+  }
+
+  public StringSubject contentType() {
+    isNotNull();
+    return check("contentType").that(fileMeta.contentType);
+  }
+
+  public IterableSubject webLinks() {
+    isNotNull();
+    return check("webLinks").that(fileMeta.webLinks);
+  }
 }
diff --git a/java/com/google/gerrit/server/config/GerritGlobalModule.java b/java/com/google/gerrit/server/config/GerritGlobalModule.java
index 2a0466f..edf8864 100644
--- a/java/com/google/gerrit/server/config/GerritGlobalModule.java
+++ b/java/com/google/gerrit/server/config/GerritGlobalModule.java
@@ -158,6 +158,7 @@
 import com.google.gerrit.server.notedb.NoteDbModule;
 import com.google.gerrit.server.patch.PatchListCacheImpl;
 import com.google.gerrit.server.patch.PatchScriptFactory;
+import com.google.gerrit.server.patch.PatchScriptFactoryForAutoFix;
 import com.google.gerrit.server.patch.PatchSetInfoFactory;
 import com.google.gerrit.server.permissions.PermissionCollection;
 import com.google.gerrit.server.permissions.SectionSortCache;
@@ -261,6 +262,7 @@
     factory(LabelsJson.Factory.class);
     factory(MergeUtil.Factory.class);
     factory(PatchScriptFactory.Factory.class);
+    factory(PatchScriptFactoryForAutoFix.Factory.class);
     factory(ProjectState.Factory.class);
     factory(RevisionJson.Factory.class);
     factory(InboundEmailRejectionSender.Factory.class);
diff --git a/java/com/google/gerrit/server/fixes/FixCalculator.java b/java/com/google/gerrit/server/fixes/FixCalculator.java
new file mode 100644
index 0000000..5d9d2c2
--- /dev/null
+++ b/java/com/google/gerrit/server/fixes/FixCalculator.java
@@ -0,0 +1,366 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.entities.Comment;
+import com.google.gerrit.entities.FixReplacement;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.jgit.diff.ReplaceEdit;
+import com.google.gerrit.server.patch.Text;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+import org.eclipse.jgit.diff.Edit;
+
+/**
+ * Produces final version of an input content with all fixes applied together with list of edits.
+ */
+public class FixCalculator {
+  private static final Comparator<FixReplacement> ASC_RANGE_FIX_REPLACEMENT_COMPARATOR =
+      Comparator.comparing(fixReplacement -> fixReplacement.range);
+
+  private FixCalculator() {}
+
+  /**
+   * Returns a result of applying fixes to an original content.
+   *
+   * @param originalContent is a text to which fixes must be applied
+   * @param fixReplacements is a list of fixes to be applied
+   * @throws ResourceConflictException if the fixReplacements contains invalid data (for example, if
+   *     an item points to an invalid range or if some ranges are intersected).
+   */
+  public static String getNewFileContent(
+      String originalContent, List<FixReplacement> fixReplacements)
+      throws ResourceConflictException {
+    FixResult fixResult = calculateFix(new Text(originalContent.getBytes(UTF_8)), fixReplacements);
+    return fixResult.text.getString(0, fixResult.text.size(), false);
+  }
+
+  /**
+   * Returns a result of applying fixes to an original content and list of applied edits.
+   *
+   * @param originalText is a text to which fixes must be applied
+   * @param fixReplacements is a list of fixes to be applied
+   * @return {@link FixResult}
+   * @throws ResourceConflictException if the fixReplacements contains invalid data (for example, if
+   *     an item points to an invalid range or if some ranges are intersected).
+   */
+  public static FixResult calculateFix(Text originalText, List<FixReplacement> fixReplacements)
+      throws ResourceConflictException {
+    List<FixReplacement> sortedReplacements = new ArrayList<>(fixReplacements);
+    sortedReplacements.sort(ASC_RANGE_FIX_REPLACEMENT_COMPARATOR);
+    if (!sortedReplacements.isEmpty() && sortedReplacements.get(0).range.startLine <= 0) {
+      throw new ResourceConflictException(
+          String.format(
+              "Cannot calculate fix replacement for range %s",
+              toString(sortedReplacements.get(0).range)));
+    }
+    ContentBuilder builder = new ContentBuilder(originalText);
+    for (FixReplacement fixReplacement : sortedReplacements) {
+      try {
+        builder.addReplacement(fixReplacement);
+      } catch (IndexOutOfBoundsException e) {
+        throw new ResourceConflictException(
+            String.format(
+                "Cannot calculate fix replacement for range %s", toString(fixReplacement.range)),
+            e);
+      }
+    }
+    return builder.build();
+  }
+
+  private static String toString(Comment.Range range) {
+    return String.format(
+        "(%s:%s - %s:%s)", range.startLine, range.startChar, range.endLine, range.endChar);
+  }
+
+  private static class ContentBuilder {
+    private static class FixRegion {
+      int startSrcLine;
+      int startDstLine;
+      int startSrcPos;
+      int startDstPos;
+      List<Edit> internalEdits;
+
+      FixRegion() {
+        this.internalEdits = new ArrayList<>();
+      }
+    }
+
+    private final ContentProcessor contentProcessor;
+    final ImmutableList.Builder<Edit> edits;
+    FixRegion currentRegion;
+
+    ContentBuilder(Text src) {
+      this.contentProcessor = new ContentProcessor(src);
+      this.edits = new ImmutableList.Builder<>();
+    }
+
+    void addReplacement(FixReplacement replacement) {
+      if (shouldStartNewEdit(replacement)) {
+        finishExistingEdit();
+      }
+      // processSrcContent expects that line number is 0-based,
+      // but replacement.range.startLine is 1-based, so subtract 1
+      processSrcContent(replacement.range.startLine - 1, replacement.range.startChar, true);
+      processReplacement(replacement);
+    }
+
+    Text getNewText() {
+      return new Text(contentProcessor.sb.toString().getBytes(UTF_8));
+    }
+
+    void finish() {
+      finishExistingEdit();
+      if (contentProcessor.hasMoreLines()) {
+        contentProcessor.appendLinesToEndOfContent();
+      }
+    }
+
+    public FixResult build() {
+      finish();
+      return new FixResult(edits.build(), this.getNewText());
+    }
+
+    private void finishExistingEdit() {
+      if (contentProcessor.srcPosition.column > 0 || contentProcessor.dstPosition.column > 0) {
+        contentProcessor.processToEndOfLine(true);
+      }
+      if (currentRegion != null) {
+        int endSrc = contentProcessor.srcPosition.line;
+        if (contentProcessor.srcPosition.column > 0) {
+          endSrc++;
+        }
+        int endDst = contentProcessor.dstPosition.line;
+        if (contentProcessor.dstPosition.column > 0) {
+          endDst++;
+        }
+        ReplaceEdit edit =
+            new ReplaceEdit(
+                currentRegion.startSrcLine,
+                endSrc,
+                currentRegion.startDstLine,
+                endDst,
+                currentRegion.internalEdits);
+        currentRegion = null;
+        edits.add(edit);
+      }
+    }
+
+    private boolean shouldStartNewEdit(FixReplacement replacement) {
+      if (currentRegion == null) {
+        return true;
+      }
+      // New edit must be started if there is at least one unchanged line after the last edit
+      // Subtract 1 from replacement.range.startLine because it is a 1-based line number,
+      // and contentProcessor.srcPosition.line is a 0-based line number
+      return replacement.range.startLine - 1 > contentProcessor.srcPosition.line + 1;
+    }
+
+    private void processSrcContent(int toLine, int toColumn, boolean append)
+        throws IndexOutOfBoundsException {
+      // toLine >= currentSrcLineIndex
+      if (toLine == contentProcessor.srcPosition.line) {
+        contentProcessor.processLineToColumn(toColumn, append);
+      } else {
+        contentProcessor.processToEndOfLine(append);
+        contentProcessor.processMultiline(toLine, append);
+        contentProcessor.processLineToColumn(toColumn, append);
+      }
+    }
+
+    private void processReplacement(FixReplacement fix) {
+      if (currentRegion == null) {
+        currentRegion = new FixRegion();
+        currentRegion.startSrcLine = contentProcessor.srcPosition.line;
+        currentRegion.startSrcPos = contentProcessor.srcPosition.getLineStartPos();
+        currentRegion.startDstLine = contentProcessor.dstPosition.line;
+        currentRegion.startDstPos = contentProcessor.dstPosition.getLineStartPos();
+      }
+      int srcStartPos = contentProcessor.srcPosition.textPos;
+      int dstStartPos = contentProcessor.dstPosition.textPos;
+      contentProcessor.appendReplacement(fix.replacement);
+      processSrcContent(fix.range.endLine - 1, fix.range.endChar, false);
+
+      currentRegion.internalEdits.add(
+          new Edit(
+              srcStartPos - currentRegion.startSrcPos,
+              contentProcessor.srcPosition.textPos - currentRegion.startSrcPos,
+              dstStartPos - currentRegion.startDstPos,
+              contentProcessor.dstPosition.textPos - currentRegion.startDstPos));
+    }
+  }
+
+  private static class ContentProcessor {
+    static class ContentPosition {
+      int line;
+      int column;
+      int textPos;
+
+      void appendMultilineContent(int lineCount, int charCount) {
+        line += lineCount;
+        column = 0;
+        textPos += charCount;
+      }
+
+      void appendLineEndedWithEOLMark(int charCount) {
+        textPos += charCount;
+        line++;
+        column = 0;
+      }
+
+      void appendStringWithoutEOLMark(int charCount) {
+        textPos += charCount;
+        column += charCount;
+      }
+
+      int getLineStartPos() {
+        return textPos - column;
+      }
+    }
+
+    private final StringBuilder sb;
+    final ContentPosition srcPosition;
+    final ContentPosition dstPosition;
+    String currentSrcLine;
+    Text src;
+    boolean endOfSource;
+
+    ContentProcessor(Text src) {
+      this.src = src;
+      sb = new StringBuilder(src.size());
+      srcPosition = new ContentPosition();
+      dstPosition = new ContentPosition();
+      endOfSource = src.size() == 0;
+    }
+
+    void processMultiline(int toLine, boolean append) {
+      if (endOfSource || toLine <= srcPosition.line) {
+        return;
+      }
+      int fromLine = srcPosition.line;
+      String lines = src.getString(fromLine, toLine, false);
+      int lineCount = toLine - fromLine;
+      int charCount = lines.length();
+      srcPosition.appendMultilineContent(lineCount, charCount);
+
+      if (append) {
+        sb.append(lines);
+        dstPosition.appendMultilineContent(lineCount, charCount);
+      }
+      currentSrcLine = null;
+      endOfSource = srcPosition.line >= src.size();
+    }
+
+    void processToEndOfLine(boolean append) {
+      if (endOfSource) {
+        return;
+      }
+      String srcLine = getCurrentSrcLine();
+      int from = srcPosition.column;
+      int charCount = srcLine.length() - from;
+      boolean lastLineNoEOLMark = srcPosition.line >= src.size() - 1 && src.isMissingNewlineAtEnd();
+      if (!lastLineNoEOLMark) {
+        srcPosition.appendLineEndedWithEOLMark(charCount);
+        endOfSource = srcPosition.line >= src.size();
+      } else {
+        srcPosition.appendStringWithoutEOLMark(charCount);
+        endOfSource = true;
+      }
+      if (append) {
+        sb.append(srcLine, from, srcLine.length());
+        if (!lastLineNoEOLMark) {
+          dstPosition.appendLineEndedWithEOLMark(charCount);
+        } else {
+          dstPosition.appendStringWithoutEOLMark(charCount);
+        }
+      }
+      currentSrcLine = null;
+    }
+
+    void processLineToColumn(int to, boolean append) throws IndexOutOfBoundsException {
+      if (to == 0) {
+        return;
+      }
+      String srcLine = getCurrentSrcLine();
+      if (to > srcLine.length()) {
+        throw new IndexOutOfBoundsException("Parameter to is out of string");
+      } else if (to == srcLine.length()) {
+        if (srcPosition.line < src.size() - 1 || !src.isMissingNewlineAtEnd()) {
+          throw new IndexOutOfBoundsException("The processLineToColumn shouldn't add end of line");
+        }
+      }
+      int from = srcPosition.column;
+      int charCount = to - from;
+      srcPosition.appendStringWithoutEOLMark(charCount);
+      if (append) {
+        sb.append(srcLine, from, to);
+        dstPosition.appendStringWithoutEOLMark(charCount);
+      }
+    }
+
+    void appendLinesToEndOfContent() {
+      processMultiline(src.size(), true);
+    }
+
+    void appendReplacement(String replacement) {
+      if (replacement.length() == 0) {
+        return;
+      }
+      sb.append(replacement);
+      int lastNewLinePos = -1;
+      int newLineMarkCount = 0;
+      while (true) {
+        int index = replacement.indexOf('\n', lastNewLinePos + 1);
+        if (index < 0) {
+          break;
+        }
+        lastNewLinePos = index;
+        newLineMarkCount++;
+      }
+      if (newLineMarkCount > 0) {
+        dstPosition.appendMultilineContent(newLineMarkCount, lastNewLinePos + 1);
+      }
+      dstPosition.appendStringWithoutEOLMark(replacement.length() - lastNewLinePos - 1);
+    }
+
+    boolean hasMoreLines() {
+      return !endOfSource;
+    }
+
+    private String getCurrentSrcLine() {
+      if (currentSrcLine == null) {
+        currentSrcLine = src.getString(srcPosition.line, srcPosition.line + 1, false);
+      }
+      return currentSrcLine;
+    }
+  }
+
+  /** The result of applying fix to a file content */
+  public static class FixResult {
+    /** List of edits to transform an original text to a final text (with all fixes applied) */
+    public final ImmutableList<Edit> edits;
+    /** Final text with all applied fixes */
+    public final Text text;
+
+    FixResult(ImmutableList<Edit> edits, Text text) {
+      this.edits = edits;
+      this.text = text;
+    }
+  }
+}
diff --git a/java/com/google/gerrit/server/fixes/FixReplacementInterpreter.java b/java/com/google/gerrit/server/fixes/FixReplacementInterpreter.java
index 9d6df7d..32c2450 100644
--- a/java/com/google/gerrit/server/fixes/FixReplacementInterpreter.java
+++ b/java/com/google/gerrit/server/fixes/FixReplacementInterpreter.java
@@ -18,7 +18,6 @@
 import static java.util.stream.Collectors.groupingBy;
 
 import com.google.gerrit.common.RawInputUtil;
-import com.google.gerrit.entities.Comment;
 import com.google.gerrit.entities.FixReplacement;
 import com.google.gerrit.extensions.restapi.BadRequestException;
 import com.google.gerrit.extensions.restapi.BinaryResult;
@@ -96,7 +95,8 @@
       throws BadRequestException, ResourceNotFoundException, IOException,
           ResourceConflictException {
     String fileContent = getFileContent(repository, projectState, patchSetCommitId, filePath);
-    String newFileContent = getNewFileContent(fileContent, fixReplacements);
+    String newFileContent = FixCalculator.getNewFileContent(fileContent, fixReplacements);
+
     return new ChangeFileContentModification(filePath, RawInputUtil.create(newFileContent));
   }
 
@@ -108,48 +108,4 @@
       return fileContent.asString();
     }
   }
-
-  private static String getNewFileContent(String fileContent, List<FixReplacement> fixReplacements)
-      throws ResourceConflictException {
-    List<FixReplacement> sortedReplacements = new ArrayList<>(fixReplacements);
-    sortedReplacements.sort(ASC_RANGE_FIX_REPLACEMENT_COMPARATOR);
-
-    LineIdentifier lineIdentifier = new LineIdentifier(fileContent);
-    StringModifier fileContentModifier = new StringModifier(fileContent);
-    for (FixReplacement fixReplacement : sortedReplacements) {
-      Comment.Range range = fixReplacement.range;
-      try {
-        int startLineIndex = lineIdentifier.getStartIndexOfLine(range.startLine);
-        int startLineLength = lineIdentifier.getLengthOfLine(range.startLine);
-
-        int endLineIndex = lineIdentifier.getStartIndexOfLine(range.endLine);
-        int endLineLength = lineIdentifier.getLengthOfLine(range.endLine);
-
-        if (range.startChar > startLineLength || range.endChar > endLineLength) {
-          throw new ResourceConflictException(
-              String.format(
-                  "Range %s refers to a non-existent offset (start line length: %s,"
-                      + " end line length: %s)",
-                  toString(range), startLineLength, endLineLength));
-        }
-
-        int startIndex = startLineIndex + range.startChar;
-        int endIndex = endLineIndex + range.endChar;
-        fileContentModifier.replace(startIndex, endIndex, fixReplacement.replacement);
-      } catch (StringIndexOutOfBoundsException e) {
-        // Most of the StringIndexOutOfBoundsException should never occur because we reject fix
-        // replacements for invalid ranges. However, we can't cover all cases for efficiency
-        // reasons. For instance, we don't determine the number of lines in a file. That's why we
-        // need to map this exception and thus provide a meaningful error.
-        throw new ResourceConflictException(
-            String.format("Cannot apply fix replacement for range %s", toString(range)), e);
-      }
-    }
-    return fileContentModifier.getResult();
-  }
-
-  private static String toString(Comment.Range range) {
-    return String.format(
-        "(%s:%s - %s:%s)", range.startLine, range.startChar, range.endLine, range.endChar);
-  }
 }
diff --git a/java/com/google/gerrit/server/fixes/LineIdentifier.java b/java/com/google/gerrit/server/fixes/LineIdentifier.java
deleted file mode 100644
index 3d09c34..0000000
--- a/java/com/google/gerrit/server/fixes/LineIdentifier.java
+++ /dev/null
@@ -1,110 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.fixes;
-
-import static java.util.Objects.requireNonNull;
-
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-/**
- * An identifier of lines in a string. Lines are sequences of characters which are separated by any
- * Unicode linebreak sequence as defined by the regular expression {@code \R}. If data for several
- * lines is requested, calls which are ordered according to ascending line numbers are the most
- * efficient.
- */
-class LineIdentifier {
-
-  private static final Pattern LINE_SEPARATOR_PATTERN = Pattern.compile("\\R");
-  private final Matcher lineSeparatorMatcher;
-
-  private int nextLineNumber;
-  private int nextLineStartIndex;
-  private int currentLineStartIndex;
-  private int currentLineEndIndex;
-
-  LineIdentifier(String string) {
-    requireNonNull(string);
-    lineSeparatorMatcher = LINE_SEPARATOR_PATTERN.matcher(string);
-    reset();
-  }
-
-  /**
-   * Returns the start index of the indicated line within the given string. Start indices are
-   * zero-based while line numbers are one-based.
-   *
-   * <p><b>Note:</b> Requesting data for several lines is more efficient if those calls occur with
-   * increasing line number.
-   *
-   * @param lineNumber the line whose start index should be determined
-   * @return the start index of the line
-   * @throws StringIndexOutOfBoundsException if the line number is negative, zero or greater than
-   *     the identified number of lines
-   */
-  public int getStartIndexOfLine(int lineNumber) {
-    findLine(lineNumber);
-    return currentLineStartIndex;
-  }
-
-  /**
-   * Returns the length of the indicated line in the given string. The character(s) used to separate
-   * lines aren't included in the count. Line numbers are one-based.
-   *
-   * <p><b>Note:</b> Requesting data for several lines is more efficient if those calls occur with
-   * increasing line number.
-   *
-   * @param lineNumber the line whose length should be determined
-   * @return the length of the line
-   * @throws StringIndexOutOfBoundsException if the line number is negative, zero or greater than
-   *     the identified number of lines
-   */
-  public int getLengthOfLine(int lineNumber) {
-    findLine(lineNumber);
-    return currentLineEndIndex - currentLineStartIndex;
-  }
-
-  private void findLine(int targetLineNumber) {
-    if (targetLineNumber <= 0) {
-      throw new StringIndexOutOfBoundsException("Line number must be positive");
-    }
-    if (targetLineNumber < nextLineNumber) {
-      reset();
-    }
-    while (nextLineNumber < targetLineNumber + 1 && lineSeparatorMatcher.find()) {
-      currentLineStartIndex = nextLineStartIndex;
-      currentLineEndIndex = lineSeparatorMatcher.start();
-      nextLineStartIndex = lineSeparatorMatcher.end();
-      nextLineNumber++;
-    }
-
-    // End of string
-    if (nextLineNumber == targetLineNumber) {
-      currentLineStartIndex = nextLineStartIndex;
-      currentLineEndIndex = lineSeparatorMatcher.regionEnd();
-    }
-    if (nextLineNumber < targetLineNumber) {
-      throw new StringIndexOutOfBoundsException(
-          String.format("Line %d isn't available", targetLineNumber));
-    }
-  }
-
-  private void reset() {
-    nextLineNumber = 1;
-    nextLineStartIndex = 0;
-    currentLineStartIndex = 0;
-    currentLineEndIndex = 0;
-    lineSeparatorMatcher.reset();
-  }
-}
diff --git a/java/com/google/gerrit/server/fixes/testing/BUILD b/java/com/google/gerrit/server/fixes/testing/BUILD
new file mode 100644
index 0000000..cccf7a5
--- /dev/null
+++ b/java/com/google/gerrit/server/fixes/testing/BUILD
@@ -0,0 +1,19 @@
+load("@rules_java//java:defs.bzl", "java_library")
+
+package(default_visibility = ["//visibility:public"])
+
+java_library(
+    name = "testing",
+    testonly = True,
+    srcs = glob(["*.java"]),
+    deps = [
+        "//java/com/google/gerrit/common:server",
+        "//java/com/google/gerrit/entities",
+        "//java/com/google/gerrit/jgit",
+        "//java/com/google/gerrit/server",
+        "//java/com/google/gerrit/truth",
+        "//lib:guava",
+        "//lib:jgit",
+        "//lib/truth",
+    ],
+)
diff --git a/java/com/google/gerrit/server/fixes/testing/FixResultSubject.java b/java/com/google/gerrit/server/fixes/testing/FixResultSubject.java
new file mode 100644
index 0000000..21f96cd
--- /dev/null
+++ b/java/com/google/gerrit/server/fixes/testing/FixResultSubject.java
@@ -0,0 +1,49 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.testing;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.gitEdits;
+import static com.google.gerrit.truth.ListSubject.elements;
+
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.StringSubject;
+import com.google.common.truth.Subject;
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import com.google.gerrit.truth.ListSubject;
+import org.eclipse.jgit.diff.Edit;
+
+public class FixResultSubject extends Subject {
+  public static FixResultSubject assertThat(FixResult fixResult) {
+    return assertAbout(FixResultSubject::new).that(fixResult);
+  }
+
+  private final FixResult fixResult;
+
+  private FixResultSubject(FailureMetadata failureMetadata, FixResult fixResult) {
+    super(failureMetadata, fixResult);
+    this.fixResult = fixResult;
+  }
+
+  public StringSubject text() {
+    isNotNull();
+    return check("text").that(fixResult.text.getString(0, fixResult.text.size(), false));
+  }
+
+  public ListSubject<GitEditSubject, Edit> edits() {
+    isNotNull();
+    return check("edits").about(elements()).thatCustom(fixResult.edits, gitEdits());
+  }
+}
diff --git a/java/com/google/gerrit/server/fixes/testing/GitEditSubject.java b/java/com/google/gerrit/server/fixes/testing/GitEditSubject.java
new file mode 100644
index 0000000..53b88b1
--- /dev/null
+++ b/java/com/google/gerrit/server/fixes/testing/GitEditSubject.java
@@ -0,0 +1,87 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.testing;
+
+import static com.google.common.truth.Truth.assertAbout;
+import static com.google.gerrit.truth.ListSubject.elements;
+
+import com.google.common.truth.FailureMetadata;
+import com.google.common.truth.Subject;
+import com.google.gerrit.jgit.diff.ReplaceEdit;
+import com.google.gerrit.truth.ListSubject;
+import org.eclipse.jgit.diff.Edit;
+import org.eclipse.jgit.diff.Edit.Type;
+
+public class GitEditSubject extends Subject {
+
+  public static GitEditSubject assertThat(Edit edit) {
+    return assertAbout(gitEdits()).that(edit);
+  }
+
+  public static Subject.Factory<GitEditSubject, Edit> gitEdits() {
+    return GitEditSubject::new;
+  }
+
+  private final Edit edit;
+
+  private GitEditSubject(FailureMetadata failureMetadata, Edit edit) {
+    super(failureMetadata, edit);
+    this.edit = edit;
+  }
+
+  public void hasRegions(int beginA, int endA, int beginB, int endB) {
+    isNotNull();
+    check("beginA").that(edit.getBeginA()).isEqualTo(beginA);
+    check("endA").that(edit.getEndA()).isEqualTo(endA);
+    check("beginB").that(edit.getBeginB()).isEqualTo(beginB);
+    check("endB").that(edit.getEndB()).isEqualTo(endB);
+  }
+
+  public void hasType(Type type) {
+    isNotNull();
+    check("getType").that(edit.getType()).isEqualTo(type);
+  }
+
+  public void isInsert(int insertPos, int beginB, int insertedLength) {
+    isNotNull();
+    hasType(Type.INSERT);
+    hasRegions(insertPos, insertPos, beginB, beginB + insertedLength);
+  }
+
+  public void isDelete(int deletePos, int deletedLength, int posB) {
+    isNotNull();
+    hasType(Type.DELETE);
+    hasRegions(deletePos, deletePos + deletedLength, posB, posB);
+  }
+
+  public void isReplace(int originalPos, int originalLength, int newPos, int newLength) {
+    isNotNull();
+    hasType(Type.REPLACE);
+    hasRegions(originalPos, originalPos + originalLength, newPos, newPos + newLength);
+  }
+
+  public void isEmpty() {
+    isNotNull();
+    hasType(Type.EMPTY);
+  }
+
+  public ListSubject<GitEditSubject, Edit> internalEdits() {
+    isNotNull();
+    isInstanceOf(ReplaceEdit.class);
+    return check("internalEdits")
+        .about(elements())
+        .thatCustom(((ReplaceEdit) edit).getInternalEdits(), gitEdits());
+  }
+}
diff --git a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
index b5842a9..92df794 100644
--- a/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
+++ b/java/com/google/gerrit/server/patch/PatchScriptBuilder.java
@@ -22,9 +22,13 @@
 import com.google.gerrit.common.data.PatchScript;
 import com.google.gerrit.common.data.PatchScript.DisplayMethod;
 import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.FixReplacement;
 import com.google.gerrit.entities.Patch;
 import com.google.gerrit.entities.Patch.ChangeType;
+import com.google.gerrit.entities.Patch.PatchType;
 import com.google.gerrit.extensions.client.DiffPreferencesInfo;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.server.fixes.FixCalculator;
 import com.google.gerrit.server.mime.FileTypeRegistry;
 import com.google.gerrit.server.patch.DiffContentCalculator.DiffCalculatorResult;
 import com.google.gerrit.server.patch.DiffContentCalculator.TextSource;
@@ -32,6 +36,7 @@
 import eu.medsea.mimeutil.MimeType;
 import eu.medsea.mimeutil.MimeUtil2;
 import java.io.IOException;
+import java.util.List;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
@@ -90,9 +95,7 @@
     ResolvedSides sides =
         resolveSides(
             git, sidesResolver, oldName(change), newName(change), list.getOldId(), list.getNewId());
-    PatchSide a = sides.a;
-    PatchSide b = sides.b;
-    return build(a, b, change, comments, history);
+    return build(sides.a, sides.b, change, comments, history);
   }
 
   private ResolvedSides resolveSides(
@@ -111,6 +114,45 @@
     }
   }
 
+  PatchScript toPatchScript(
+      Repository git, ObjectId baseId, String fileName, List<FixReplacement> fixReplacements)
+      throws IOException, ResourceConflictException {
+    SidesResolver sidesResolver = new SidesResolver(git, ComparisonType.againstOtherPatchSet());
+    PatchSide a = resolveSideA(git, sidesResolver, fileName, baseId);
+    FixCalculator.FixResult fixResult = FixCalculator.calculateFix(a.src, fixReplacements);
+    PatchSide b =
+        new PatchSide(
+            null,
+            fileName,
+            ObjectId.zeroId(),
+            a.mode,
+            fixResult.text.getContent(),
+            fixResult.text,
+            a.mimeType,
+            a.displayMethod,
+            a.fileMode);
+
+    PatchFileChange change =
+        new PatchFileChange(
+            fixResult.edits,
+            ImmutableSet.of(),
+            ImmutableList.of(),
+            fileName,
+            fileName,
+            ChangeType.MODIFIED,
+            PatchType.UNIFIED);
+
+    return build(a, b, change, null, null);
+  }
+
+  private PatchSide resolveSideA(
+      Repository git, SidesResolver sidesResolver, String path, ObjectId baseId)
+      throws IOException {
+    try (ObjectReader reader = git.newObjectReader()) {
+      return sidesResolver.resolve(registry, reader, path, null, baseId, true);
+    }
+  }
+
   private PatchScript build(
       PatchSide a,
       PatchSide b,
diff --git a/java/com/google/gerrit/server/patch/PatchScriptFactoryForAutoFix.java b/java/com/google/gerrit/server/patch/PatchScriptFactoryForAutoFix.java
new file mode 100644
index 0000000..cf07190
--- /dev/null
+++ b/java/com/google/gerrit/server/patch/PatchScriptFactoryForAutoFix.java
@@ -0,0 +1,134 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.patch;
+
+import static com.google.common.base.Preconditions.checkState;
+
+import com.google.common.collect.ImmutableList;
+import com.google.common.flogger.FluentLogger;
+import com.google.gerrit.common.data.PatchScript;
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.FixReplacement;
+import com.google.gerrit.entities.PatchSet;
+import com.google.gerrit.extensions.client.DiffPreferencesInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.server.git.LargeObjectException;
+import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.permissions.ChangePermission;
+import com.google.gerrit.server.permissions.PermissionBackend;
+import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.InvalidChangeOperationException;
+import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.inject.Provider;
+import com.google.inject.assistedinject.Assisted;
+import com.google.inject.assistedinject.AssistedInject;
+import java.io.IOException;
+import java.util.concurrent.Callable;
+import org.eclipse.jgit.lib.ObjectId;
+import org.eclipse.jgit.lib.Repository;
+
+public class PatchScriptFactoryForAutoFix implements Callable<PatchScript> {
+
+  private static final FluentLogger logger = FluentLogger.forEnclosingClass();
+
+  public interface Factory {
+
+    PatchScriptFactoryForAutoFix create(
+        Repository git,
+        ChangeNotes notes,
+        String fileName,
+        PatchSet patchSet,
+        ImmutableList<FixReplacement> fixReplacements,
+        DiffPreferencesInfo diffPrefs);
+  }
+
+  private final PermissionBackend permissionBackend;
+  private final ProjectCache projectCache;
+  private final Change.Id changeId;
+  private final ChangeNotes notes;
+  private final Provider<PatchScriptBuilder> builderFactory;
+  private final Repository git;
+  private final PatchSet patchSet;
+  private final String fileName;
+  private final DiffPreferencesInfo diffPrefs;
+  private final ImmutableList<FixReplacement> fixReplacements;
+
+  @AssistedInject
+  PatchScriptFactoryForAutoFix(
+      Provider<PatchScriptBuilder> builderFactory,
+      PermissionBackend permissionBackend,
+      ProjectCache projectCache,
+      @Assisted Repository git,
+      @Assisted ChangeNotes notes,
+      @Assisted String fileName,
+      @Assisted PatchSet patchSet,
+      @Assisted ImmutableList<FixReplacement> fixReplacements,
+      @Assisted DiffPreferencesInfo diffPrefs) {
+    this.notes = notes;
+    this.permissionBackend = permissionBackend;
+    this.projectCache = projectCache;
+    this.changeId = patchSet.id().changeId();
+    this.git = git;
+    this.patchSet = patchSet;
+    this.fileName = fileName;
+    this.fixReplacements = fixReplacements;
+    this.builderFactory = builderFactory;
+    this.diffPrefs = diffPrefs;
+  }
+
+  @Override
+  public PatchScript call()
+      throws LargeObjectException, AuthException, InvalidChangeOperationException, IOException,
+          PermissionBackendException {
+
+    try {
+      permissionBackend.currentUser().change(notes).check(ChangePermission.READ);
+    } catch (AuthException e) {
+      throw new NoSuchChangeException(changeId);
+    }
+
+    if (!projectCache.checkedGet(notes.getProjectName()).statePermitsRead()) {
+      throw new NoSuchChangeException(changeId);
+    }
+
+    return createPatchScript();
+  }
+
+  private PatchScript createPatchScript() throws LargeObjectException {
+    checkState(patchSet.id().get() != 0, "edit not supported for left side");
+    PatchScriptBuilder b = newBuilder();
+    try {
+      ObjectId baseId = patchSet.commitId();
+      return b.toPatchScript(git, baseId, fileName, fixReplacements);
+    } catch (ResourceConflictException e) {
+      logger.atSevere().withCause(e).log("AutoFix replacements is not valid");
+      throw new IllegalStateException("AutoFix replacements is not valid", e);
+    } catch (IOException e) {
+      logger.atSevere().withCause(e).log("File content unavailable");
+      throw new NoSuchChangeException(notes.getChangeId(), e);
+    } catch (org.eclipse.jgit.errors.LargeObjectException err) {
+      throw new LargeObjectException("File content is too large", err);
+    }
+  }
+
+  private PatchScriptBuilder newBuilder() {
+    PatchScriptBuilder b = builderFactory.get();
+    b.setChange(notes.getChange());
+    b.setDiffPrefs(diffPrefs);
+    return b;
+  }
+}
diff --git a/java/com/google/gerrit/server/restapi/change/GetFixPreview.java b/java/com/google/gerrit/server/restapi/change/GetFixPreview.java
index db89819..0666756 100644
--- a/java/com/google/gerrit/server/restapi/change/GetFixPreview.java
+++ b/java/com/google/gerrit/server/restapi/change/GetFixPreview.java
@@ -14,20 +14,129 @@
 
 package com.google.gerrit.server.restapi.change;
 
+import static java.util.stream.Collectors.groupingBy;
+
+import com.google.common.base.MoreObjects;
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.common.data.PatchScript;
+import com.google.gerrit.entities.Change;
+import com.google.gerrit.entities.FixReplacement;
+import com.google.gerrit.entities.PatchSet;
+import com.google.gerrit.extensions.client.DiffPreferencesInfo;
 import com.google.gerrit.extensions.common.DiffInfo;
+import com.google.gerrit.extensions.common.DiffWebLinkInfo;
+import com.google.gerrit.extensions.common.WebLinkInfo;
+import com.google.gerrit.extensions.restapi.AuthException;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.extensions.restapi.ResourceNotFoundException;
 import com.google.gerrit.extensions.restapi.Response;
 import com.google.gerrit.extensions.restapi.RestReadView;
 import com.google.gerrit.server.change.FixResource;
+import com.google.gerrit.server.diff.DiffInfoCreator;
+import com.google.gerrit.server.diff.DiffSide;
+import com.google.gerrit.server.diff.DiffSide.Type;
+import com.google.gerrit.server.diff.DiffWebLinksProvider;
+import com.google.gerrit.server.git.GitRepositoryManager;
+import com.google.gerrit.server.git.LargeObjectException;
+import com.google.gerrit.server.notedb.ChangeNotes;
+import com.google.gerrit.server.patch.PatchScriptFactoryForAutoFix;
+import com.google.gerrit.server.permissions.PermissionBackendException;
+import com.google.gerrit.server.project.InvalidChangeOperationException;
+import com.google.gerrit.server.project.NoSuchChangeException;
+import com.google.gerrit.server.project.ProjectCache;
+import com.google.gerrit.server.project.ProjectState;
+import com.google.inject.Inject;
 import com.google.inject.Singleton;
+import java.io.IOException;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+import org.eclipse.jgit.lib.Repository;
 
 @Singleton
 public class GetFixPreview implements RestReadView<FixResource> {
 
+  private final ProjectCache projectCache;
+  private final GitRepositoryManager repoManager;
+  private final PatchScriptFactoryForAutoFix.Factory patchScriptFactoryFactory;
+
+  @Inject
+  GetFixPreview(
+      ProjectCache projectCache,
+      GitRepositoryManager repoManager,
+      PatchScriptFactoryForAutoFix.Factory patchScriptFactoryFactory) {
+    this.projectCache = projectCache;
+    this.repoManager = repoManager;
+    this.patchScriptFactoryFactory = patchScriptFactoryFactory;
+  }
+
   @Override
-  public Response<Map<String, DiffInfo>> apply(FixResource resource) {
+  public Response<Map<String, DiffInfo>> apply(FixResource resource)
+      throws PermissionBackendException, ResourceNotFoundException, ResourceConflictException,
+          AuthException, IOException, InvalidChangeOperationException {
     Map<String, DiffInfo> result = new HashMap<>();
+    PatchSet patchSet = resource.getRevisionResource().getPatchSet();
+    ChangeNotes notes = resource.getRevisionResource().getNotes();
+    Change change = notes.getChange();
+    ProjectState state = projectCache.get(change.getProject());
+    Map<String, List<FixReplacement>> fixReplacementsPerFilePath =
+        resource.getFixReplacements().stream()
+            .collect(groupingBy(fixReplacement -> fixReplacement.path));
+    try {
+      try (Repository git = repoManager.openRepository(notes.getProjectName())) {
+        for (Map.Entry<String, List<FixReplacement>> entry :
+            fixReplacementsPerFilePath.entrySet()) {
+          String fileName = entry.getKey();
+          DiffInfo diffInfo =
+              getFixPreviewForSingleFile(
+                  git, patchSet, state, notes, fileName, ImmutableList.copyOf(entry.getValue()));
+          result.put(fileName, diffInfo);
+        }
+      }
+    } catch (NoSuchChangeException e) {
+      throw new ResourceNotFoundException(e.getMessage(), e);
+    } catch (LargeObjectException e) {
+      throw new ResourceConflictException(e.getMessage(), e);
+    }
     return Response.ok(result);
   }
+
+  private DiffInfo getFixPreviewForSingleFile(
+      Repository git,
+      PatchSet patchSet,
+      ProjectState state,
+      ChangeNotes notes,
+      String fileName,
+      ImmutableList<FixReplacement> fixReplacements)
+      throws PermissionBackendException, AuthException, LargeObjectException,
+          InvalidChangeOperationException, IOException {
+    PatchScriptFactoryForAutoFix psf =
+        patchScriptFactoryFactory.create(
+            git, notes, fileName, patchSet, fixReplacements, DiffPreferencesInfo.defaults());
+    PatchScript ps = psf.call();
+
+    DiffSide sideA =
+        DiffSide.create(
+            ps.getFileInfoA(),
+            MoreObjects.firstNonNull(ps.getOldName(), ps.getNewName()),
+            Type.SIDE_A);
+    DiffSide sideB = DiffSide.create(ps.getFileInfoB(), ps.getNewName(), DiffSide.Type.SIDE_B);
+
+    DiffInfoCreator diffInfoCreator =
+        new DiffInfoCreator(state, new DiffWebLinksProviderImpl(), true);
+    return diffInfoCreator.create(ps, sideA, sideB);
+  }
+
+  private static class DiffWebLinksProviderImpl implements DiffWebLinksProvider {
+
+    @Override
+    public ImmutableList<DiffWebLinkInfo> getDiffLinks() {
+      return ImmutableList.of();
+    }
+
+    @Override
+    public ImmutableList<WebLinkInfo> getFileWebLinks(Type fileInfoType) {
+      return ImmutableList.of();
+    }
+  }
 }
diff --git a/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java b/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
index db1e99b7..abf0279 100644
--- a/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
+++ b/javatests/com/google/gerrit/acceptance/api/revision/RobotCommentsIT.java
@@ -16,6 +16,7 @@
 
 import static com.google.common.truth.Truth.assertThat;
 import static com.google.gerrit.acceptance.PushOneCommit.SUBJECT;
+import static com.google.gerrit.extensions.common.testing.DiffInfoSubject.assertThat;
 import static com.google.gerrit.extensions.common.testing.EditInfoSubject.assertThat;
 import static com.google.gerrit.extensions.common.testing.RobotCommentInfoSubject.assertThatList;
 import static com.google.gerrit.testing.GerritJUnit.assertThrows;
@@ -31,7 +32,9 @@
 import com.google.gerrit.extensions.api.changes.ReviewInput.RobotCommentInput;
 import com.google.gerrit.extensions.client.Comment;
 import com.google.gerrit.extensions.common.ChangeInfo;
+import com.google.gerrit.extensions.common.ChangeType;
 import com.google.gerrit.extensions.common.DiffInfo;
+import com.google.gerrit.extensions.common.DiffInfo.IntraLineStatus;
 import com.google.gerrit.extensions.common.EditInfo;
 import com.google.gerrit.extensions.common.FixReplacementInfo;
 import com.google.gerrit.extensions.common.FixSuggestionInfo;
@@ -50,9 +53,12 @@
 import java.util.Objects;
 import java.util.Optional;
 import org.junit.Before;
+import org.junit.Ignore;
 import org.junit.Test;
 
 public class RobotCommentsIT extends AbstractDaemonTest {
+  private static final String PLAIN_TEXT_CONTENT_TYPE = "text/plain";
+
   private static final String FILE_NAME = "file_to_fix.txt";
   private static final String FILE_NAME2 = "another_file_to_fix.txt";
   private static final String FILE_CONTENT =
@@ -61,6 +67,7 @@
   private static final String FILE_CONTENT2 = "1st line\n2nd line\n3rd line\n";
 
   private String changeId;
+  private String commitId;
   private FixReplacementInfo fixReplacementInfo;
   private FixSuggestionInfo fixSuggestionInfo;
   private RobotCommentInput withFixRobotCommentInput;
@@ -75,6 +82,7 @@
             ImmutableMap.of(FILE_NAME, FILE_CONTENT, FILE_NAME2, FILE_CONTENT2));
     PushOneCommit.Result changeResult = push.to("refs/for/master");
     changeId = changeResult.getChangeId();
+    commitId = changeResult.getCommit().getName();
 
     fixReplacementInfo = createFixReplacementInfo();
     fixSuggestionInfo = createFixSuggestionInfo(fixReplacementInfo);
@@ -971,15 +979,130 @@
   }
 
   @Test
+  @Ignore
+  public void getFixPreviewForNonExistingFile() throws Exception {
+    // Not implemented yet.
+    fixReplacementInfo.path = "a_non_existent_file.txt";
+    fixReplacementInfo.range = createRange(1, 0, 2, 0);
+    fixReplacementInfo.replacement = "Modified content\n";
+
+    addRobotComment(changeId, withFixRobotCommentInput);
+    List<RobotCommentInfo> robotCommentInfos = getRobotComments();
+    List<String> fixIds = getFixIds(robotCommentInfos);
+    String fixId = Iterables.getOnlyElement(fixIds);
+
+    assertThrows(
+        BadRequestException.class,
+        () -> gApi.changes().id(changeId).current().getFixPreview(fixId));
+  }
+
+  @Test
   public void getFixPreview() throws Exception {
+    FixReplacementInfo fixReplacementInfoFile1 = new FixReplacementInfo();
+    fixReplacementInfoFile1.path = FILE_NAME;
+    fixReplacementInfoFile1.replacement = "some replacement code";
+    fixReplacementInfoFile1.range = createRange(3, 9, 8, 4);
+
+    FixReplacementInfo fixReplacementInfoFile2 = new FixReplacementInfo();
+    fixReplacementInfoFile2.path = FILE_NAME2;
+    fixReplacementInfoFile2.replacement = "New line\n";
+    fixReplacementInfoFile2.range = createRange(2, 0, 2, 0);
+
+    fixSuggestionInfo = createFixSuggestionInfo(fixReplacementInfoFile1, fixReplacementInfoFile2);
+
+    withFixRobotCommentInput = createRobotCommentInput(fixSuggestionInfo);
+
     addRobotComment(changeId, withFixRobotCommentInput);
     List<RobotCommentInfo> robotCommentInfos = getRobotComments();
 
     List<String> fixIds = getFixIds(robotCommentInfos);
     String fixId = Iterables.getOnlyElement(fixIds);
 
-    Map<String, DiffInfo> result = gApi.changes().id(changeId).current().getFixPreview(fixId);
-    assertThat(result).isEmpty();
+    Map<String, DiffInfo> fixPreview = gApi.changes().id(changeId).current().getFixPreview(fixId);
+    assertThat(fixPreview).hasSize(2);
+    assertThat(fixPreview).containsKey(FILE_NAME);
+    assertThat(fixPreview).containsKey(FILE_NAME2);
+
+    DiffInfo diff = fixPreview.get(FILE_NAME);
+    assertThat(diff).intralineStatus().isEqualTo(IntraLineStatus.OK);
+    assertThat(diff).webLinks().isNull();
+    assertThat(diff).binary().isNull();
+    assertThat(diff).diffHeader().isNull();
+    assertThat(diff).changeType().isEqualTo(ChangeType.MODIFIED);
+    assertThat(diff).metaA().totalLineCount().isEqualTo(11);
+    assertThat(diff).metaA().name().isEqualTo(FILE_NAME);
+    assertThat(diff).metaA().commitId().isEqualTo(commitId);
+    assertThat(diff).metaA().contentType().isEqualTo(PLAIN_TEXT_CONTENT_TYPE);
+    assertThat(diff).metaA().webLinks().isNull();
+    assertThat(diff).metaB().totalLineCount().isEqualTo(6);
+    assertThat(diff).metaB().name().isEqualTo(FILE_NAME);
+    assertThat(diff).metaB().commitId().isNull();
+    assertThat(diff).metaB().contentType().isEqualTo(PLAIN_TEXT_CONTENT_TYPE);
+    assertThat(diff).metaB().webLinks().isNull();
+
+    assertThat(diff).content().hasSize(3);
+    assertThat(diff)
+        .content()
+        .element(0)
+        .commonLines()
+        .containsExactly("First line", "Second line");
+    assertThat(diff).content().element(0).linesOfA().isNull();
+    assertThat(diff).content().element(0).linesOfB().isNull();
+
+    assertThat(diff).content().element(1).commonLines().isNull();
+    assertThat(diff)
+        .content()
+        .element(1)
+        .linesOfA()
+        .containsExactly(
+            "Third line", "Fourth line", "Fifth line", "Sixth line", "Seventh line", "Eighth line");
+    assertThat(diff)
+        .content()
+        .element(1)
+        .linesOfB()
+        .containsExactly("Third linsome replacement codeth line");
+
+    assertThat(diff)
+        .content()
+        .element(2)
+        .commonLines()
+        .containsExactly("Ninth line", "Tenth line", "");
+    assertThat(diff).content().element(2).linesOfA().isNull();
+    assertThat(diff).content().element(2).linesOfB().isNull();
+
+    DiffInfo diff2 = fixPreview.get(FILE_NAME2);
+    assertThat(diff2).intralineStatus().isEqualTo(IntraLineStatus.OK);
+    assertThat(diff2).webLinks().isNull();
+    assertThat(diff2).binary().isNull();
+    assertThat(diff2).diffHeader().isNull();
+    assertThat(diff2).changeType().isEqualTo(ChangeType.MODIFIED);
+    assertThat(diff2).metaA().totalLineCount().isEqualTo(4);
+    assertThat(diff2).metaA().name().isEqualTo(FILE_NAME2);
+    assertThat(diff2).metaA().commitId().isEqualTo(commitId);
+    assertThat(diff2).metaA().contentType().isEqualTo(PLAIN_TEXT_CONTENT_TYPE);
+    assertThat(diff2).metaA().webLinks().isNull();
+    assertThat(diff2).metaB().totalLineCount().isEqualTo(5);
+    assertThat(diff2).metaB().name().isEqualTo(FILE_NAME2);
+    assertThat(diff2).metaB().commitId().isNull();
+    assertThat(diff2).metaA().contentType().isEqualTo(PLAIN_TEXT_CONTENT_TYPE);
+    assertThat(diff2).metaB().webLinks().isNull();
+
+    assertThat(diff2).content().hasSize(3);
+    assertThat(diff2).content().element(0).commonLines().containsExactly("1st line");
+    assertThat(diff2).content().element(0).linesOfA().isNull();
+    assertThat(diff2).content().element(0).linesOfB().isNull();
+
+    assertThat(diff2).content().element(1).commonLines().isNull();
+    assertThat(diff2).content().element(1).linesOfA().isNull();
+    assertThat(diff2).content().element(1).linesOfB().containsExactly("New line");
+
+    assertThat(diff2)
+        .content()
+        .element(2)
+        .commonLines()
+        .containsExactly("2nd line", "3rd line", "");
+    assertThat(diff2).content().element(2).linesOfA().isNull();
+    assertThat(diff2).content().element(2).linesOfB().isNull();
   }
 
   private static RobotCommentInput createRobotCommentInputWithMandatoryFields() {
diff --git a/javatests/com/google/gerrit/server/BUILD b/javatests/com/google/gerrit/server/BUILD
index 59ed018..022813b 100644
--- a/javatests/com/google/gerrit/server/BUILD
+++ b/javatests/com/google/gerrit/server/BUILD
@@ -55,6 +55,7 @@
         "//java/com/google/gerrit/server/account/externalids/testing",
         "//java/com/google/gerrit/server/cache/serialize",
         "//java/com/google/gerrit/server/cache/testing",
+        "//java/com/google/gerrit/server/fixes/testing",
         "//java/com/google/gerrit/server/git/receive:ref_cache",
         "//java/com/google/gerrit/server/ioutil",
         "//java/com/google/gerrit/server/logging",
diff --git a/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java b/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java
deleted file mode 100644
index ba80c02..0000000
--- a/javatests/com/google/gerrit/server/fixes/LineIdentifierTest.java
+++ /dev/null
@@ -1,255 +0,0 @@
-// Copyright (C) 2017 The Android Open Source Project
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-package com.google.gerrit.server.fixes;
-
-import static com.google.common.truth.Truth.assertThat;
-import static com.google.gerrit.testing.GerritJUnit.assertThrows;
-
-import org.junit.Test;
-
-public class LineIdentifierTest {
-  @Test
-  public void lineNumberMustBePositive() {
-    LineIdentifier lineIdentifier = new LineIdentifier("First line\nSecond line");
-    StringIndexOutOfBoundsException thrown =
-        assertThrows(
-            StringIndexOutOfBoundsException.class, () -> lineIdentifier.getStartIndexOfLine(0));
-    assertThat(thrown).hasMessageThat().contains("positive");
-  }
-
-  @Test
-  public void lineNumberMustIndicateAnAvailableLine() {
-    LineIdentifier lineIdentifier = new LineIdentifier("First line\nSecond line");
-    StringIndexOutOfBoundsException thrown =
-        assertThrows(
-            StringIndexOutOfBoundsException.class, () -> lineIdentifier.getStartIndexOfLine(3));
-    assertThat(thrown).hasMessageThat().contains("Line 3 isn't available");
-  }
-
-  @Test
-  public void startIndexOfFirstLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(startIndex).isEqualTo(0);
-  }
-
-  @Test
-  public void lengthOfFirstLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int lineLength = lineIdentifier.getLengthOfLine(1);
-    assertThat(lineLength).isEqualTo(8);
-  }
-
-  @Test
-  public void startIndexOfSecondLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void lengthOfSecondLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int lineLength = lineIdentifier.getLengthOfLine(2);
-    assertThat(lineLength).isEqualTo(3);
-  }
-
-  @Test
-  public void startIndexOfLastLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(3);
-    assertThat(startIndex).isEqualTo(13);
-  }
-
-  @Test
-  public void lengthOfLastLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567");
-    int lineLength = lineIdentifier.getLengthOfLine(3);
-    assertThat(lineLength).isEqualTo(7);
-  }
-
-  @Test
-  public void emptyFirstLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("\n123\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(startIndex).isEqualTo(0);
-  }
-
-  @Test
-  public void lengthOfEmptyFirstLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("\n123\n1234567");
-    int lineLength = lineIdentifier.getLengthOfLine(1);
-    assertThat(lineLength).isEqualTo(0);
-  }
-
-  @Test
-  public void emptyIntermediaryLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void lengthOfEmptyIntermediaryLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n\n1234567");
-    int lineLength = lineIdentifier.getLengthOfLine(2);
-    assertThat(lineLength).isEqualTo(0);
-  }
-
-  @Test
-  public void lineAfterIntermediaryLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n\n1234567");
-    int startIndex = lineIdentifier.getStartIndexOfLine(3);
-    assertThat(startIndex).isEqualTo(10);
-  }
-
-  @Test
-  public void emptyLastLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n");
-    int startIndex = lineIdentifier.getStartIndexOfLine(3);
-    assertThat(startIndex).isEqualTo(13);
-  }
-
-  @Test
-  public void lengthOfEmptyLastLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n");
-    int lineLength = lineIdentifier.getLengthOfLine(3);
-    assertThat(lineLength).isEqualTo(0);
-  }
-
-  @Test
-  public void startIndexOfSingleLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678");
-    int startIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(startIndex).isEqualTo(0);
-  }
-
-  @Test
-  public void lengthOfSingleLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678");
-    int lineLength = lineIdentifier.getLengthOfLine(1);
-    assertThat(lineLength).isEqualTo(8);
-  }
-
-  @Test
-  public void startIndexOfSingleEmptyLineIsRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("");
-    int startIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(startIndex).isEqualTo(0);
-  }
-
-  @Test
-  public void lengthOfSingleEmptyLineIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("");
-    int lineLength = lineIdentifier.getLengthOfLine(1);
-    assertThat(lineLength).isEqualTo(0);
-  }
-
-  @Test
-  public void lookingUpSubsequentLinesIsPossible() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567\n12");
-
-    int firstLineStartIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(firstLineStartIndex).isEqualTo(0);
-
-    int secondLineStartIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(secondLineStartIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void lookingUpNotSubsequentLinesInAscendingOrderIsPossible() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567\n12");
-
-    int firstLineStartIndex = lineIdentifier.getStartIndexOfLine(1);
-    assertThat(firstLineStartIndex).isEqualTo(0);
-
-    int fourthLineStartIndex = lineIdentifier.getStartIndexOfLine(4);
-    assertThat(fourthLineStartIndex).isEqualTo(21);
-  }
-
-  @Test
-  public void lookingUpNotSubsequentLinesInDescendingOrderIsPossible() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\n123\n1234567\n12");
-
-    int fourthLineStartIndex = lineIdentifier.getStartIndexOfLine(4);
-    assertThat(fourthLineStartIndex).isEqualTo(21);
-
-    int secondLineStartIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(secondLineStartIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void linesSeparatedByOnlyCarriageReturnAreRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\r123\r12");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void lengthOfLinesSeparatedByOnlyCarriageReturnIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\r123\r12");
-    int lineLength = lineIdentifier.getLengthOfLine(2);
-    assertThat(lineLength).isEqualTo(3);
-  }
-
-  @Test
-  public void linesSeparatedByLineFeedAndCarriageReturnAreRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\r\n123\r\n12");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(10);
-  }
-
-  @Test
-  public void lengthOfLinesSeparatedByLineFeedAndCarriageReturnIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\r\n123\r\n12");
-    int lineLength = lineIdentifier.getLengthOfLine(2);
-    assertThat(lineLength).isEqualTo(3);
-  }
-
-  @Test
-  public void linesSeparatedByMixtureOfCarriageReturnAndLineFeedAreRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\r123\r\n12\n123456\r\n1234");
-    int startIndex = lineIdentifier.getStartIndexOfLine(5);
-    assertThat(startIndex).isEqualTo(25);
-  }
-
-  @Test
-  public void linesSeparatedBySomeUnicodeLinebreakCharacterAreRecognized() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\u2029123\u202912");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(9);
-  }
-
-  @Test
-  public void lengthOfLinesSeparatedBySomeUnicodeLinebreakCharacterIsCorrect() {
-    LineIdentifier lineIdentifier = new LineIdentifier("12345678\u2029123\u202912");
-    int lineLength = lineIdentifier.getLengthOfLine(2);
-    assertThat(lineLength).isEqualTo(3);
-  }
-
-  @Test
-  public void blanksAreNotInterpretedAsLineSeparators() {
-    LineIdentifier lineIdentifier = new LineIdentifier("1 2345678\n123\n12");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(10);
-  }
-
-  @Test
-  public void tabsAreNotInterpretedAsLineSeparators() {
-    LineIdentifier lineIdentifier = new LineIdentifier("123\t45678\n123\n12");
-    int startIndex = lineIdentifier.getStartIndexOfLine(2);
-    assertThat(startIndex).isEqualTo(10);
-  }
-}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/EmptyContentTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/EmptyContentTest.java
new file mode 100644
index 0000000..51fbc67
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/EmptyContentTest.java
@@ -0,0 +1,68 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class EmptyContentTest {
+  @Test
+  public void insertSingleLineNoEOL() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("", 1, 0, 1, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abc");
+    assertThat(fixResult).edits().onlyElement();
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineWithEOL() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("", 1, 0, 1, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\n");
+    assertThat(fixResult).edits().onlyElement();
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertMultilineNoEOL() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("", 1, 0, 1, 0, "Abc\nDEFGH");
+    assertThat(fixResult).text().isEqualTo("Abc\nDEFGH");
+    assertThat(fixResult).edits().onlyElement();
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 9);
+  }
+
+  @Test
+  public void insertMultilineWithEOL() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("", 1, 0, 1, 0, "Abc\nDEFGH\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDEFGH\n");
+    assertThat(fixResult).edits().onlyElement();
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/FixCalculatorVariousTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/FixCalculatorVariousTest.java
new file mode 100644
index 0000000..861af3e
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/FixCalculatorVariousTest.java
@@ -0,0 +1,168 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+import static com.google.gerrit.testing.GerritJUnit.assertThrows;
+import static java.nio.charset.StandardCharsets.UTF_8;
+
+import com.google.common.collect.ImmutableList;
+import com.google.gerrit.entities.Comment.Range;
+import com.google.gerrit.entities.FixReplacement;
+import com.google.gerrit.extensions.restapi.ResourceConflictException;
+import com.google.gerrit.server.fixes.FixCalculator;
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import com.google.gerrit.server.patch.Text;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class FixCalculatorVariousTest {
+  private static final String multilineContentString =
+      "First line\nSecond line\nThird line\nFourth line\nFifth line\n";
+  private static final Text multilineContent = new Text(multilineContentString.getBytes(UTF_8));
+
+  public static FixResult calculateFixSingleReplacement(
+      String content, int startLine, int startChar, int endLine, int endChar, String replacement)
+      throws ResourceConflictException {
+    FixReplacement fixReplacement =
+        new FixReplacement(
+            "AnyPath", new Range(startLine, startChar, endLine, endChar), replacement);
+    return FixCalculator.calculateFix(
+        new Text(content.getBytes(UTF_8)), ImmutableList.of(fixReplacement));
+  }
+
+  @Test
+  public void lineNumberMustBePositive() {
+    assertThrows(
+        ResourceConflictException.class,
+        () -> calculateFixSingleReplacement("First line\nSecond line", 0, 0, 0, 0, "Abc"));
+  }
+
+  @Test
+  public void insertAtTheEndOfSingleLineContentHasEOLMarkInvalidPosition() throws Exception {
+    assertThrows(
+        ResourceConflictException.class,
+        () -> calculateFixSingleReplacement("First line\n", 1, 11, 1, 11, "Abc"));
+  }
+
+  @Test
+  public void severalChangesInTheSameLineNonSorted() throws Exception {
+    FixReplacement replace = new FixReplacement("path", new Range(2, 1, 2, 3), "ABC");
+    FixReplacement insert = new FixReplacement("path", new Range(2, 5, 2, 5), "DEFG");
+    FixReplacement delete = new FixReplacement("path", new Range(2, 7, 2, 9), "");
+    FixResult result =
+        FixCalculator.calculateFix(multilineContent, ImmutableList.of(replace, delete, insert));
+    assertThat(result)
+        .text()
+        .isEqualTo("First line\nSABConDEFGd ne\nThird line\nFourth line\nFifth line\n");
+    assertThat(result).edits().hasSize(1);
+    Edit edit = result.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 1);
+    assertThat(edit).internalEdits().hasSize(3);
+    assertThat(edit).internalEdits().element(0).isReplace(1, 2, 1, 3);
+    assertThat(edit).internalEdits().element(1).isInsert(5, 6, 4);
+    assertThat(edit).internalEdits().element(2).isDelete(7, 2, 12);
+  }
+
+  @Test
+  public void severalChangesInConsecutiveLines() throws Exception {
+    FixReplacement replace = new FixReplacement("path", new Range(2, 1, 2, 3), "ABC");
+    FixReplacement insert = new FixReplacement("path", new Range(3, 5, 3, 5), "DEFG");
+    FixReplacement delete = new FixReplacement("path", new Range(4, 7, 4, 9), "");
+    FixResult result =
+        FixCalculator.calculateFix(multilineContent, ImmutableList.of(replace, insert, delete));
+    assertThat(result)
+        .text()
+        .isEqualTo("First line\nSABCond line\nThirdDEFG line\nFourth ne\nFifth line\n");
+    assertThat(result).edits().hasSize(1);
+    Edit edit = result.edits.get(0);
+    assertThat(edit).isReplace(1, 3, 1, 3);
+    assertThat(edit).internalEdits().hasSize(3);
+    assertThat(edit).internalEdits().element(0).isReplace(1, 2, 1, 3);
+    assertThat(edit).internalEdits().element(1).isInsert(17, 18, 4);
+    assertThat(edit).internalEdits().element(2).isDelete(30, 2, 35);
+  }
+
+  @Test
+  public void severalChangesInNonConsecutiveLines() throws Exception {
+    FixReplacement replace = new FixReplacement("path", new Range(1, 1, 1, 3), "ABC");
+    FixReplacement insert = new FixReplacement("path", new Range(3, 5, 3, 5), "DEFG");
+    FixReplacement delete = new FixReplacement("path", new Range(5, 9, 6, 0), "");
+    FixResult result =
+        FixCalculator.calculateFix(multilineContent, ImmutableList.of(replace, insert, delete));
+    assertThat(result)
+        .text()
+        .isEqualTo("FABCst line\nSecond line\nThirdDEFG line\nFourth line\nFifth lin");
+    assertThat(result).edits().hasSize(3);
+    assertThat(result).edits().element(0).isReplace(0, 1, 0, 1);
+    assertThat(result).edits().element(0).internalEdits().onlyElement().isReplace(1, 2, 1, 3);
+    assertThat(result).edits().element(1).isReplace(2, 1, 2, 1);
+    assertThat(result).edits().element(1).internalEdits().onlyElement().isInsert(5, 5, 4);
+    assertThat(result).edits().element(2).isReplace(4, 1, 4, 1);
+    assertThat(result).edits().element(2).internalEdits().onlyElement().isDelete(9, 2, 9);
+  }
+
+  @Test
+  public void multipleChanges() throws Exception {
+    String str =
+        "First line\nSecond line\nThird line\nFourth line\nFifth line\nSixth line"
+            + "\nSeventh line\nEighth line\nNinth line\nTenth line\n";
+    Text content = new Text(str.getBytes(UTF_8));
+
+    FixReplacement multiLineReplace =
+        new FixReplacement("path", new Range(1, 2, 3, 3), "AB\nC\nDEFG\nQ\n");
+    FixReplacement multiLineDelete = new FixReplacement("path", new Range(4, 8, 5, 8), "");
+    FixReplacement singleLineInsert = new FixReplacement("path", new Range(5, 10, 5, 10), "QWERTY");
+
+    FixReplacement singleLineReplace = new FixReplacement("path", new Range(7, 3, 7, 7), "XY");
+    FixReplacement multiLineInsert =
+        new FixReplacement("path", new Range(8, 7, 8, 7), "KLMNO\nASDF");
+
+    FixReplacement singleLineDelete = new FixReplacement("path", new Range(10, 3, 10, 7), "");
+
+    FixResult result =
+        FixCalculator.calculateFix(
+            content,
+            ImmutableList.of(
+                multiLineReplace,
+                multiLineDelete,
+                singleLineInsert,
+                singleLineReplace,
+                multiLineInsert,
+                singleLineDelete));
+    assertThat(result)
+        .text()
+        .isEqualTo(
+            "FiAB\nC\nDEFG\nQ\nrd line\nFourth lneQWERTY\nSixth line\nSevXY line\nEighth KLMNO\nASDFline\nNinth line\nTenine\n");
+    assertThat(result).edits().hasSize(3);
+    assertThat(result).edits().element(0).isReplace(0, 5, 0, 6);
+    assertThat(result)
+        .edits()
+        .element(0)
+        .internalEdits()
+        .containsExactly(
+            new Edit(2, 26, 2, 14), new Edit(42, 54, 30, 30), new Edit(56, 56, 32, 38));
+
+    assertThat(result).edits().element(1).isReplace(6, 2, 7, 3);
+    assertThat(result)
+        .edits()
+        .element(1)
+        .internalEdits()
+        .containsExactly(new Edit(3, 7, 3, 5), new Edit(20, 20, 18, 28));
+    assertThat(result).edits().element(2).isReplace(9, 1, 11, 1);
+    assertThat(result).edits().element(2).internalEdits().onlyElement().isDelete(3, 4, 3);
+  }
+}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java
new file mode 100644
index 0000000..dd36e3a
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentNoEOLTest.java
@@ -0,0 +1,337 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class MultilineContentNoEOLTest {
+
+  @Test
+  public void insertSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("AbcFirst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 5, 2, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbcd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 10, 3, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird lineAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 3);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nFirst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 5, 2, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbc\nd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 10, 3, 10, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird lineAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 4);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nFirst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 5, 2, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbc\nDefgh\nd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 3);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 10, 3, 10, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird lineAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 10);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 2, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abcrst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 3, 2, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbcd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 8, 3, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird liAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 2, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nrst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 3, 2, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 8, 3, 10, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird liAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 4);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 2, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nrst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 3, 2, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nDefgh\nd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 8, 3, 10, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird liAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 2, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefghrst line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 2, 3, 2, 5, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nDefghd line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 8, 3, 10, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird liAbc\nDefgh");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 9);
+  }
+
+  @Test
+  public void replaceWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 3, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 3, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 33, 0, 3);
+  }
+
+  @Test
+  public void deleteWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 3, 10, "");
+    assertThat(fixResult).text().isEqualTo("");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isDelete(0, 3, 0);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 33, 0);
+  }
+
+  @Test
+  public void deleteAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 0, 1, 4, "");
+    assertThat(fixResult).text().isEqualTo("t line\nSecond line\nThird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 4, 0);
+  }
+
+  @Test
+  public void deleteInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 1, 5, 3, 1, "");
+    assertThat(fixResult).text().isEqualTo("Firsthird line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 3, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(5, 19, 5);
+  }
+
+  @Test
+  public void deleteAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line", 3, 7, 3, 10, "");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird l");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(7, 3, 7);
+  }
+}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentWithEOLTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentWithEOLTest.java
new file mode 100644
index 0000000..a2868c8
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/MultilineContentWithEOLTest.java
@@ -0,0 +1,337 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class MultilineContentWithEOLTest {
+
+  @Test
+  public void insertSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("AbcFirst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 5, 2, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbcd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 4, 0, 4, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird line\nAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(3, 3, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nFirst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 5, 2, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbc\nd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 4, 0, 4, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird line\nAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(3, 3, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nFirst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 5, 2, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSeconAbc\nDefgh\nd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 3);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 4, 0, 4, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird line\nAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(3, 3, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 2, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abcrst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 3, 2, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbcd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 3, 9, 4, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird linAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(9, 2, 9, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 2, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nrst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 3, 2, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 3, 9, 4, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird linAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(9, 2, 9, 4);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 2, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nrst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 3, 2, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nDefgh\nd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 3, 9, 4, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird linAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(9, 2, 9, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 2, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefghrst line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 2, 3, 2, 5, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First line\nSecAbc\nDefghd line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(1, 1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 3, 9, 4, 0, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird linAbc\nDefgh");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(9, 2, 9, 9);
+  }
+
+  @Test
+  public void replaceWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 4, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 3, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 34, 0, 3);
+  }
+
+  @Test
+  public void deleteWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 4, 0, "");
+    assertThat(fixResult).text().isEqualTo("");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isDelete(0, 3, 0);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 34, 0);
+  }
+
+  @Test
+  public void deleteAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 0, 1, 4, "");
+    assertThat(fixResult).text().isEqualTo("t line\nSecond line\nThird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 4, 0);
+  }
+
+  @Test
+  public void deleteInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 1, 5, 3, 1, "");
+    assertThat(fixResult).text().isEqualTo("Firsthird line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 3, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(5, 19, 5);
+  }
+
+  @Test
+  public void deleteAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\nSecond line\nThird line\n", 3, 7, 4, 0, "");
+    assertThat(fixResult).text().isEqualTo("First line\nSecond line\nThird l");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(2, 1, 2, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(7, 4, 7);
+  }
+}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentNoEOLTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentNoEOLTest.java
new file mode 100644
index 0000000..3de4ef7
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentNoEOLTest.java
@@ -0,0 +1,320 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class OneLineContentNoEOLTest {
+
+  @Test
+  public void insertSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("AbcFirst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 5, 1, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("FirstAbc line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 10, 1, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("First lineAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 3);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nFirst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 5, 1, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("FirstAbc\n line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 10, 1, 10, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First lineAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 4);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 0, 1, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nFirst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 5, 1, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("FirstAbc\nDefgh\n line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 10, 1, 10, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First lineAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(10, 10, 10);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 2, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abcrst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 3, 1, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("FirAbc line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 8, 1, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("First liAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 2, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nrst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 3, 1, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("FirAbc\n line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 8, 1, 10, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First liAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 4);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 0, 1, 2, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nrst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 3, 1, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("FirAbc\nDefgh\n line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 8, 1, 10, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First liAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 0, 1, 2, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefghrst line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 3, 1, 5, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("FirAbc\nDefgh line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line", 1, 8, 1, 10, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First liAbc\nDefgh");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 2, 8, 9);
+  }
+
+  @Test
+  public void replaceWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 10, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 10, 0, 3);
+  }
+
+  @Test
+  public void deleteWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 10, "");
+    assertThat(fixResult).text().isEqualTo("");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isDelete(0, 1, 0);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 10, 0);
+  }
+
+  @Test
+  public void deleteAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 0, 1, 4, "");
+    assertThat(fixResult).text().isEqualTo("t line");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 4, 0);
+  }
+
+  @Test
+  public void deleteInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 5, 1, 8, "");
+    assertThat(fixResult).text().isEqualTo("Firstne");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(5, 3, 5);
+  }
+
+  @Test
+  public void deleteAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line", 1, 7, 1, 10, "");
+    assertThat(fixResult).text().isEqualTo("First l");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(7, 3, 7);
+  }
+}
diff --git a/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentWithEOLTest.java b/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentWithEOLTest.java
new file mode 100644
index 0000000..bae714b
--- /dev/null
+++ b/javatests/com/google/gerrit/server/fixes/fixCalculator/OneLineContentWithEOLTest.java
@@ -0,0 +1,320 @@
+// Copyright (C) 2019 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package com.google.gerrit.server.fixes.fixCalculator;
+
+import static com.google.gerrit.server.fixes.testing.FixResultSubject.assertThat;
+import static com.google.gerrit.server.fixes.testing.GitEditSubject.assertThat;
+
+import com.google.gerrit.server.fixes.FixCalculator.FixResult;
+import org.eclipse.jgit.diff.Edit;
+import org.junit.Test;
+
+public class OneLineContentWithEOLTest {
+
+  @Test
+  public void insertSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 1, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("AbcFirst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 5, 1, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("FirstAbc line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 3);
+  }
+
+  @Test
+  public void insertSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 2, 0, 2, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("First line\nAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 3);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 1, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nFirst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 5, 1, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("FirstAbc\n line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 4);
+  }
+
+  @Test
+  public void insertSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 2, 0, 2, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First line\nAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(1, 1, 1);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 4);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 0, 1, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nFirst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(0, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 5, 1, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("FirstAbc\nDefgh\n line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isInsert(5, 5, 10);
+  }
+
+  @Test
+  public void insertMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 2, 0, 2, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First line\nAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isInsert(1, 1, 2);
+    assertThat(edit).internalEdits().onlyElement().isInsert(0, 0, 10);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 1, 2, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abcrst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 3, 1, 5, "Abc");
+    assertThat(fixResult).text().isEqualTo("FirAbc line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 9, 2, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("First linAbc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(9, 2, 9, 3);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 1, 2, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nrst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 3, 1, 5, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("FirAbc\n line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 4);
+  }
+
+  @Test
+  public void replaceWithSingleLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 8, 2, 0, "Abc\n");
+    assertThat(fixResult).text().isEqualTo("First liAbc\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 3, 8, 4);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 0, 1, 2, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefgh\nrst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 3, 1, 5, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("FirAbc\nDefgh\n line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 3);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineWithEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 8, 2, 0, "Abc\nDefgh\n");
+    assertThat(fixResult).text().isEqualTo("First liAbc\nDefgh\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 3, 8, 10);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 0, 1, 2, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("Abc\nDefghrst line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 2, 0, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 3, 1, 5, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("FirAbc\nDefgh line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(3, 2, 3, 9);
+  }
+
+  @Test
+  public void replaceMultilineLineNoEOLAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement(
+            "First line\n", 1, 8, 2, 0, "Abc\nDefgh");
+    assertThat(fixResult).text().isEqualTo("First liAbc\nDefgh");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 2);
+    assertThat(edit).internalEdits().onlyElement().isReplace(8, 3, 8, 9);
+  }
+
+  @Test
+  public void replaceWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 2, 0, "Abc");
+    assertThat(fixResult).text().isEqualTo("Abc");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isReplace(0, 11, 0, 3);
+  }
+
+  @Test
+  public void deleteWholeContent() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 2, 0, "");
+    assertThat(fixResult).text().isEqualTo("");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isDelete(0, 1, 0);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 11, 0);
+  }
+
+  @Test
+  public void deleteAtStart() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 0, 1, 4, "");
+    assertThat(fixResult).text().isEqualTo("t line\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(0, 4, 0);
+  }
+
+  @Test
+  public void deleteInTheMiddle() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 5, 1, 8, "");
+    assertThat(fixResult).text().isEqualTo("Firstne\n");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(5, 3, 5);
+  }
+
+  @Test
+  public void deleteAtEnd() throws Exception {
+    FixResult fixResult =
+        FixCalculatorVariousTest.calculateFixSingleReplacement("First line\n", 1, 7, 2, 0, "");
+    assertThat(fixResult).text().isEqualTo("First l");
+    assertThat(fixResult).edits().hasSize(1);
+    Edit edit = fixResult.edits.get(0);
+    assertThat(edit).isReplace(0, 1, 0, 1);
+    assertThat(edit).internalEdits().onlyElement().isDelete(7, 4, 7);
+  }
+}
