private void processTokens(@NotNull CharSequence chars, int start, int end, @NotNull TokenHighlightProcessor tokenHighlightProcessor) {
    Lexer lexer = myHighlighter.getHighlightingLexer();
    SyntaxHighlighterOverEditorHighlighter highlighter = myHighlighter;

    LOG.assertTrue(start <= end);

    int i = StringUtil.indexOf(chars, '\n', start, end);
    if (i != -1) end = i;

    if (myDocumentStamp != myDocument.getModificationStamp()) {
      highlighter.restart(chars);
      myDocumentStamp = myDocument.getModificationStamp();
    }
    else if (lexer.getTokenType() == null || lexer.getTokenStart() > start) {
      highlighter.resetPosition(0);  // todo restart from nearest position with initial state
    }

    boolean isBeginning = true;

    for (; lexer.getTokenType() != null; lexer.advance()) {
      int hiStart = lexer.getTokenStart();
      int hiEnd = lexer.getTokenEnd();
      if (hiStart >= end) {
        break;
      }
      hiStart = Math.max(hiStart, start);
      hiEnd = Math.min(hiEnd, end);
      if (hiStart >= hiEnd) {
        continue;
      }
      if (isBeginning) {
        String text = chars.subSequence(hiStart, hiEnd).toString();
        if (text.trim().isEmpty()) {
          continue;
        }
      }
      isBeginning = false;
      IElementType tokenType = lexer.getTokenType();
      TextAttributesKey[] tokenHighlights = highlighter.getTokenHighlights(tokenType);
      if (!tokenHighlightProcessor.process(hiStart, hiEnd, tokenHighlights)) {
        return;
      }
    }
  }
private void processTokens(@NotNull CharSequence chars, int start, int end, @NotNull TokenHighlightProcessor tokenHighlightProcessor)