private void paintBorderEffect(int startOffset, int endOffset, EffectDescriptor borderDescriptor) {
      startOffset = DocumentUtil.alignToCodePointBoundary(myDocument, startOffset);
      endOffset = DocumentUtil.alignToCodePointBoundary(myDocument, endOffset);

      FoldRegion foldRegion = myEditor.getFoldingModel().getCollapsedRegionAtOffset(startOffset);
      if (foldRegion != null && endOffset <= foldRegion.getEndOffset()) return;

      if (!myClipDetector.rangeCanBeVisible(startOffset, endOffset)) return;

      int startLine = myDocument.getLineNumber(startOffset);
      int endLine = myDocument.getLineNumber(endOffset);
      if (startLine + 1 == endLine &&
          startOffset == myDocument.getLineStartOffset(startLine) &&
          endOffset == myDocument.getLineStartOffset(endLine)) {
        // special case of line highlighters
        endLine--;
        endOffset = myDocument.getLineEndOffset(endLine);
      }

      boolean rounded = borderDescriptor.effectType == EffectType.ROUNDED_BOX;
      int margin = borderDescriptor.effectType == EffectType.SLIGHTLY_WIDER_BOX ? 1 : 0;
      myGraphics.setColor(borderDescriptor.effectColor);
      int startVisualLine = myView.offsetToVisualLine(startOffset, false);
      int endVisualLine = myView.offsetToVisualLine(endOffset, true);
      if (startVisualLine == endVisualLine) {
        int y = myView.visualLineToY(startVisualLine) + myYShift;
        FloatList ranges = adjustedLogicalRangeToVisualRanges(startOffset, endOffset);
        for (int i = 0; i < ranges.size() - 1; i += 2) {
          float startX = myCorrector.singleLineBorderStart(ranges.getFloat(i));
          if (startX - margin >= myCorrector.startX(startVisualLine)) {
            startX -= margin;
          }
          float endX = myCorrector.singleLineBorderEnd(ranges.getFloat(i + 1)) + margin;
          drawSimpleBorder(startX, endX, y, rounded);
        }
      }
      else {
        FloatList leadingRanges = adjustedLogicalRangeToVisualRanges(
          startOffset, myView.visualPositionToOffset(new VisualPosition(startVisualLine, Integer.MAX_VALUE, true)));
        FloatList trailingRanges = adjustedLogicalRangeToVisualRanges(myView.visualLineToOffset(endVisualLine), endOffset);
        if (!leadingRanges.isEmpty() && !trailingRanges.isEmpty()) {
          int minX = Math.min(myCorrector.minX(startVisualLine, endVisualLine), (int)leadingRanges.getFloat(0));
          int maxX = Math.max(myCorrector.maxX(startVisualLine, endVisualLine), (int)trailingRanges.getFloat(trailingRanges.size() - 1));
          boolean containsInnerLines = endVisualLine > startVisualLine + 1;
          int lineHeight = myLineHeight - 1;
          int leadingTopY = myView.visualLineToY(startVisualLine) + myYShift;
          int leadingBottomY = leadingTopY + lineHeight;
          int trailingTopY = myView.visualLineToY(endVisualLine) + myYShift;
          int trailingBottomY = trailingTopY + lineHeight;
          float start = 0;
          float end = 0;
          float leftGap = leadingRanges.getFloat(0) - (containsInnerLines ? minX : trailingRanges.getFloat(0));
          int adjustY = leftGap == 0 ? 2 : leftGap > 0 ? 1 : 0; // avoiding 1-pixel gap between aligned lines
          for (int i = 0; i < leadingRanges.size() - 1; i += 2) {
            start = leadingRanges.getFloat(i);
            end = leadingRanges.getFloat(i + 1);
            if (i > 0) {
              drawLine(leadingRanges.getFloat(i - 1), leadingBottomY, start, leadingBottomY, rounded);
            }
            drawLine(start, leadingBottomY + (i == 0 ? adjustY : 0), start, leadingTopY, rounded);
            if ((i + 2) < leadingRanges.size()) {
              drawLine(start, leadingTopY, end, leadingTopY, rounded);
              drawLine(end, leadingTopY, end, leadingBottomY, rounded);
            }
          }
          end = Math.max(end, maxX);
          drawLine(start, leadingTopY, end, leadingTopY, rounded);
          drawLine(end, leadingTopY, end, trailingTopY - 1, rounded);
          float targetX = trailingRanges.getFloat(trailingRanges.size() - 1);
          drawLine(end, trailingTopY - 1, targetX, trailingTopY - 1, rounded);
          adjustY = end == targetX ? -2 : -1; // for lastX == targetX we need to avoid a gap when rounding is used
          for (int i = trailingRanges.size() - 2; i >= 0; i -= 2) {
            start = trailingRanges.getFloat(i);
            end = trailingRanges.getFloat(i + 1);

            drawLine(end, trailingTopY + (i == 0 ? adjustY : 0), end, trailingBottomY, rounded);
            drawLine(end, trailingBottomY, start, trailingBottomY, rounded);
            drawLine(start, trailingBottomY, start, trailingTopY, rounded);
            if (i > 0) {
              drawLine(start, trailingTopY, trailingRanges.getFloat(i - 1), trailingTopY, rounded);
            }
          }
          float lastX = start;
          if (containsInnerLines) {
            if (start != minX) {
              drawLine(start, trailingTopY, start, trailingTopY - 1, rounded);
              drawLine(start, trailingTopY - 1, minX, trailingTopY - 1, rounded);
              drawLine(minX, trailingTopY - 1, minX, leadingBottomY + 1, rounded);
            }
            else {
              drawLine(minX, trailingTopY, minX, leadingBottomY + 1, rounded);
            }
            lastX = minX;
          }
          targetX = leadingRanges.getFloat(0);
          if (lastX < targetX) {
            drawLine(lastX, leadingBottomY + 1, targetX, leadingBottomY + 1, rounded);
          }
          else {
            drawLine(lastX, leadingBottomY + 1, lastX, leadingBottomY, rounded);
            drawLine(lastX, leadingBottomY, targetX, leadingBottomY, rounded);
          }
        }
      }
    }
private void paintBorderEffect(int startOffset, int endOffset, EffectDescriptor borderDescriptor)