@Nullable
  public static <T> List<Cmd> createDiffCmds(@NotNull Model<T> listModel, T @NotNull [] oldElements, T @NotNull [] newElements) {
    Diff.Change change = null;
    try {
      change = Diff.buildChanges(oldElements, newElements);
    }
    catch (FilesTooBigForDiffException e) {
      // should not occur
    }

    if (change == null) {
      return null;
    }

    List<Cmd> commands = new ArrayList<>();
    int inserted = 0;
    int deleted = 0;
    while (change != null) {
      if (change.deleted > 0) {
        final int start = change.line0 + inserted - deleted;
        commands.add(new RemoveCmd<>(listModel, start, start + change.deleted - 1));
      }

      if (change.inserted > 0) {
        List<T> elements = new ArrayList<>(Arrays.asList(newElements).subList(change.line1, change.line1 + change.inserted));
        commands.add(new InsertCmd<>(listModel, change.line0 + inserted - deleted, elements));
      }

      deleted += change.deleted;
      inserted += change.inserted;
      change = change.link;
    }
    return commands;
  }
@Nullable
  public static <T> List<Cmd> createDiffCmds(@NotNull Model<T> listModel, T @NotNull [] oldElements, T @NotNull [] newElements)