String (@NotNull Collection<? extends LineMarkerInfo> markerInfos) { StringBuilder result = new StringBuilder(); int index = 0; List<Pair<LineMarkerInfo, Integer>> lineMarkerInfos = new ArrayList<>(markerInfos.size() * 2); for (LineMarkerInfo info : markerInfos) lineMarkerInfos.add(Pair.create(info, info.startOffset)); for (LineMarkerInfo info : markerInfos) lineMarkerInfos.add(Pair.create(info, info.endOffset)); Collections.reverse(lineMarkerInfos.subList(markerInfos.size(), lineMarkerInfos.size())); lineMarkerInfos.sort(comparingInt(o -> o.second)); String documentText = myDocument.getText(); for (Pair<LineMarkerInfo, Integer> info : lineMarkerInfos) { LineMarkerInfo expectedLineMarker = info.first; result.append(documentText, index, info.second); if (info.second == expectedLineMarker.startOffset) { result .append("<lineMarker descr=\"") .append(sanitizedLineMarkerTooltip(expectedLineMarker)) .append("\">"); } else { result.append("</lineMarker>"); } index = info.second; } result.append(documentText, index, myDocument.getTextLength()); return result.toString(); }