public static @NotNull List<LineMarkerInfo<?>> merge(@NotNull List<? extends MergeableLineMarkerInfo<?>> sameLineMarkers, int passId) {
    // must maintain the order of sameLineMarkers, to show icons in consistent order
    List<LineMarkerInfo<?>> result = new ArrayList<>(sameLineMarkers.size());
    boolean[] alreadyMerged = new boolean[sameLineMarkers.size()]; // [i]=true means the `sameLineMarkers[i]` was merged with some other marker from this array, and should not be tried to merge again
    for (int i = 0; i < sameLineMarkers.size(); i++) {
      MergeableLineMarkerInfo<?> prev = sameLineMarkers.get(i);
      if (alreadyMerged[i]) continue;
      List<MergeableLineMarkerInfo<?>> toMerge = new SmartList<>();
      for (int k = i + 1; k < sameLineMarkers.size(); k++) {
        MergeableLineMarkerInfo<?> next = sameLineMarkers.get(k);
        if (alreadyMerged[k]) continue;
        boolean canMergeWith = prev.canMergeWith(next);
        if (ApplicationManager.getApplication().isUnitTestMode() && !canMergeWith && next.canMergeWith(prev)) {
          LOG.error("inconsistent canMergeWith():" + next.getClass() + "[" + next.getLineMarkerTooltip() + "] can merge " +
                    prev.getClass() + "[" + prev.getLineMarkerTooltip() + "], but not vice versa");
        }
        if (canMergeWith) {
          alreadyMerged[k] = true; // mark as merged to avoid counting it twice
          if (toMerge.isEmpty()) {
            toMerge.add(prev);
          }
          toMerge.add(next);
        }
      }
      if (toMerge.isEmpty()) {
        result.add(prev);
      }
      else {
        result.add(new MyLineMarkerInfo(toMerge, passId));
      }
    }
    return result;
  }
public static @NotNull List<LineMarkerInfo<?>> merge(@NotNull List<? extends MergeableLineMarkerInfo<?>> sameLineMarkers, int passId)