public void testRangeHighlighterLinesInRangeForLongLinePerformance() throws Exception {
    final int N = 50000;
    Document document =
        EditorFactory.getInstance().createDocument(StringUtil.repeatSymbol('x', 2 * N));

    final MarkupModelEx markupModel =
        (MarkupModelEx) DocumentMarkupModel.forDocument(document, ourProject, true);
    for (int i = 0; i < N - 1; i++) {
      markupModel.addRangeHighlighter(2 * i, 2 * i + 1, 0, null, HighlighterTargetArea.EXACT_RANGE);
    }
    markupModel.addRangeHighlighter(
        N / 2, N / 2 + 1, 0, null, HighlighterTargetArea.LINES_IN_RANGE);

    PlatformTestUtil.startPerformanceTest(
            "slow highlighters lookup",
            (int) (N * Math.log(N) / 1000),
            new ThrowableRunnable() {
              @Override
              public void run() {
                List<RangeHighlighterEx> list = new ArrayList<RangeHighlighterEx>();
                CommonProcessors.CollectProcessor<RangeHighlighterEx> coll =
                    new CommonProcessors.CollectProcessor<RangeHighlighterEx>(list);
                for (int i = 0; i < N - 1; i++) {
                  list.clear();
                  markupModel.processRangeHighlightersOverlappingWith(2 * i, 2 * i + 1, coll);
                  assertEquals(2, list.size()); // 1 line plus one exact range marker
                }
              }
            })
        .assertTiming();
  }
  public void testRangeHighlighterDisposeVsRemoveAllConflict() throws Exception {
    Document document = EditorFactory.getInstance().createDocument("[xxxxxxxxxxxxxx]");

    MarkupModel markupModel = DocumentMarkupModel.forDocument(document, ourProject, true);
    RangeMarker m =
        markupModel.addRangeHighlighter(1, 6, 0, null, HighlighterTargetArea.EXACT_RANGE);
    assertTrue(m.isValid());
    markupModel.removeAllHighlighters();
    assertFalse(m.isValid());
    assertEmpty(markupModel.getAllHighlighters());
    m.dispose();
    assertFalse(m.isValid());
  }
  public void testRangeHighlighterIteratorOrder() throws Exception {
    Document document = EditorFactory.getInstance().createDocument("1234567890");

    final MarkupModelEx markupModel =
        (MarkupModelEx) DocumentMarkupModel.forDocument(document, ourProject, true);
    RangeHighlighter exact =
        markupModel.addRangeHighlighter(3, 6, 0, null, HighlighterTargetArea.EXACT_RANGE);
    RangeHighlighter line =
        markupModel.addRangeHighlighter(4, 5, 0, null, HighlighterTargetArea.LINES_IN_RANGE);
    List<RangeHighlighter> list = new ArrayList<RangeHighlighter>();
    markupModel.processRangeHighlightersOverlappingWith(
        2, 9, new CommonProcessors.CollectProcessor<RangeHighlighter>(list));
    assertEquals(Arrays.asList(line, exact), list);
  }
  public void testRangeHighlightersRecreateBug() throws Exception {
    Document document = EditorFactory.getInstance().createDocument("[xxxxxxxxxxxxxx]");

    MarkupModel markupModel = DocumentMarkupModel.forDocument(document, ourProject, true);
    for (int i = 0; i < 2; i++) {
      RangeMarker m =
          markupModel.addRangeHighlighter(1, 6, 0, null, HighlighterTargetArea.EXACT_RANGE);
      RangeMarker m2 =
          markupModel.addRangeHighlighter(2, 7, 0, null, HighlighterTargetArea.EXACT_RANGE);
      RangeMarker m3 =
          markupModel.addRangeHighlighter(1, 6, 0, null, HighlighterTargetArea.EXACT_RANGE);
      markupModel.removeAllHighlighters();
    }
  }
  void paint(Graphics2D g) {
    Rectangle clip = g.getClipBounds();

    if (myEditor.getContentComponent().isOpaque()) {
      g.setColor(myEditor.getBackgroundColor());
      g.fillRect(clip.x, clip.y, clip.width, clip.height);
    }

    if (paintPlaceholderText(g)) {
      paintCaret(g);
      return;
    }

    int startLine = myView.yToVisualLine(Math.max(clip.y, 0));
    int endLine = myView.yToVisualLine(Math.max(clip.y + clip.height, 0));
    int startOffset = myView.visualPositionToOffset(new VisualPosition(startLine, 0));
    int endOffset = myView.visualPositionToOffset(new VisualPosition(endLine + 1, 0, true));
    ClipDetector clipDetector = new ClipDetector(myEditor, clip);

    paintBackground(g, clip, startLine, endLine);
    paintRightMargin(g, clip);
    paintCustomRenderers(g, startOffset, endOffset);
    MarkupModelEx docMarkup =
        (MarkupModelEx) DocumentMarkupModel.forDocument(myDocument, myEditor.getProject(), true);
    paintLineMarkersSeparators(g, clip, docMarkup, startOffset, endOffset);
    paintLineMarkersSeparators(g, clip, myEditor.getMarkupModel(), startOffset, endOffset);
    paintTextWithEffects(g, clip, startLine, endLine);
    paintHighlightersAfterEndOfLine(g, docMarkup, startOffset, endOffset);
    paintHighlightersAfterEndOfLine(g, myEditor.getMarkupModel(), startOffset, endOffset);
    paintBorderEffect(g, clipDetector, myEditor.getHighlighter(), startOffset, endOffset);
    paintBorderEffect(g, clipDetector, docMarkup, startOffset, endOffset);
    paintBorderEffect(g, clipDetector, myEditor.getMarkupModel(), startOffset, endOffset);

    paintCaret(g);

    paintComposedTextDecoration(g);
  }