@Nullable
  static BraceHighlightingAndNavigationContext computeHighlightingAndNavigationContext(@NotNull Editor editor,
                                                                                       @NotNull PsiFile file,
                                                                                       int offset) {
    EditorHighlighter highlighter = BraceHighlightingHandler.getLazyParsableHighlighterIfAny(file.getProject(), editor, file);
    CharSequence text = editor.getDocument().getCharsSequence();

    HighlighterIterator iterator = highlighter.createIterator(offset);
    FileType fileType = iterator.atEnd() ? null : getFileType(file, iterator.getStart());

    boolean isBeforeOrInsideLeftBrace = fileType != null && isLBraceToken(iterator, text, fileType);
    boolean isBeforeOrInsideRightBrace = !isBeforeOrInsideLeftBrace && fileType != null && isRBraceToken(iterator, text, fileType);
    boolean isInsideBrace = (isBeforeOrInsideLeftBrace || isBeforeOrInsideRightBrace) && iterator.getStart() < offset;

    HighlighterIterator preOffsetIterator = offset > 0 && !isInsideBrace ? highlighter.createIterator(offset - 1) : null;
    FileType preOffsetFileType = preOffsetIterator != null ? getFileType(file, preOffsetIterator.getStart()) : null;

    boolean isAfterLeftBrace = preOffsetIterator != null &&
                               isLBraceToken(preOffsetIterator, text, preOffsetFileType);
    boolean isAfterRightBrace = !isAfterLeftBrace && preOffsetIterator != null &&
                                isRBraceToken(preOffsetIterator, text, preOffsetFileType);

    int offsetTokenStart = iterator.atEnd() ? -1 : iterator.getStart();
    int preOffsetTokenStart = preOffsetIterator == null || preOffsetIterator.atEnd() ? -1 : preOffsetIterator.getStart();

    if (editor.getSettings().isBlockCursor()) {
      if (isBeforeOrInsideLeftBrace && matchBrace(text, fileType, iterator, true)) {
        return new BraceHighlightingAndNavigationContext(offsetTokenStart, iterator.getStart(), isInsideBrace);
      }
      else if (isBeforeOrInsideRightBrace && matchBrace(text, fileType, iterator, false)) {
        return new BraceHighlightingAndNavigationContext(offsetTokenStart, iterator.getStart(), isInsideBrace);
      }
      else if (isAfterRightBrace && matchBrace(text, preOffsetFileType, preOffsetIterator, false)) {
        return new BraceHighlightingAndNavigationContext(preOffsetTokenStart, preOffsetIterator.getStart(), true);
      }
      else if (isAfterLeftBrace && matchBrace(text, preOffsetFileType, preOffsetIterator, true)) {
        return new BraceHighlightingAndNavigationContext(preOffsetTokenStart, preOffsetIterator.getStart(), true);
      }
    }
    else {
      if (isAfterRightBrace && matchBrace(text, preOffsetFileType, preOffsetIterator, false)) {
        return new BraceHighlightingAndNavigationContext(preOffsetTokenStart, preOffsetIterator.getStart(), true);
      }
      else if (isBeforeOrInsideLeftBrace && matchBrace(text, fileType, iterator, true)) {
        return new BraceHighlightingAndNavigationContext(offsetTokenStart, iterator.getEnd(), isInsideBrace);
      }
      else if (isAfterLeftBrace && matchBrace(text, preOffsetFileType, preOffsetIterator, true)) {
        return new BraceHighlightingAndNavigationContext(preOffsetTokenStart, preOffsetIterator.getEnd(), true);
      }
      else if (isBeforeOrInsideRightBrace && matchBrace(text, fileType, iterator, false)) {
        return new BraceHighlightingAndNavigationContext(offsetTokenStart, iterator.getStart(), isInsideBrace);
      }
    }
    return null;
  }
@Nullable
  static BraceHighlightingAndNavigationContext computeHighlightingAndNavigationContext(@NotNull Editor editor,
                                                                                       @NotNull PsiFile file,
                                                                                       int offset)