@RequiresWriteLock
  public LineRange replaceChange(@NotNull TextMergeChange change,
                                 @NotNull Side side,
                                 boolean resolveChange) {
    if (change.isResolved(side)) return null;
    if (!change.isChange(side)) {
      markChangeResolved(change);
      return null;
    }

    ThreeSide sourceSide = side.select(ThreeSide.LEFT, ThreeSide.RIGHT);
    ThreeSide oppositeSide = side.select(ThreeSide.RIGHT, ThreeSide.LEFT);

    Document sourceDocument = getContent(sourceSide).getDocument();
    int sourceStartLine = change.getStartLine(sourceSide);
    int sourceEndLine = change.getEndLine(sourceSide);
    List<String> newContent = DiffUtil.getLines(sourceDocument, sourceStartLine, sourceEndLine);

    int newLineStart;
    if (change.isConflict()) {
      boolean append = change.isOnesideAppliedConflict();
      if (append) {
        newLineStart = myModel.getLineEnd(change.getIndex());
        myModel.appendChange(change.getIndex(), newContent);
      }
      else {
        myModel.replaceChange(change.getIndex(), newContent);
        newLineStart = myModel.getLineStart(change.getIndex());
      }

      if (resolveChange || change.getStartLine(oppositeSide) == change.getEndLine(oppositeSide)) {
        markChangeResolved(change);
      }
      else {
        change.markOnesideAppliedConflict();
        markChangeResolved(change, side);
      }
    }
    else {
      myModel.replaceChange(change.getIndex(), newContent);
      newLineStart = myModel.getLineStart(change.getIndex());
      markChangeResolved(change);
    }
    int newLineEnd = myModel.getLineEnd(change.getIndex());
    return new LineRange(newLineStart, newLineEnd);
  }
@RequiresWriteLock
  public LineRange replaceChange(@NotNull TextMergeChange change,
                                 @NotNull Side side,
                                 boolean resolveChange)