private static boolean isDeclarationVisible(PsiElement container, Editor editor) {
    Rectangle viewRect = editor.getScrollingModel().getVisibleArea();
    final TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(container);
    if (range == null) {
      return false;
    }

    LogicalPosition pos = editor.offsetToLogicalPosition(range.getStartOffset());
    Point loc = editor.logicalPositionToXY(pos);
    return loc.y >= viewRect.y;
  }
  @Override
  public void invoke(
      @NotNull final Project project, @NotNull final Editor editor, @NotNull PsiFile file) {
    PsiDocumentManager.getInstance(project).commitAllDocuments();

    PsiElement container = null;
    WeakReference<LightweightHint> ref = editor.getUserData(MY_LAST_HINT_KEY);
    if (ref != null) {
      LightweightHint hint = ref.get();
      if (hint != null && hint.isVisible()) {
        hint.hide();
        container = hint.getUserData(CONTAINER_KEY);
        if (container != null && !container.isValid()) {
          container = null;
        }
      }
    }

    StructureViewBuilder builder =
        LanguageStructureViewBuilder.INSTANCE.getStructureViewBuilder(file);
    if (builder instanceof TreeBasedStructureViewBuilder) {
      StructureViewModel model =
          ((TreeBasedStructureViewBuilder) builder).createStructureViewModel();
      boolean goOneLevelUp = true;
      if (container == null) {
        goOneLevelUp = false;
        Object element = model.getCurrentEditorElement();
        if (element instanceof PsiElement) {
          container = (PsiElement) element;
        }
      }
      while (true) {
        if (container == null || container instanceof PsiFile) {
          return;
        }
        if (goOneLevelUp) {
          goOneLevelUp = false;
        } else {
          if (!isDeclarationVisible(container, editor)) {
            break;
          }
        }

        container = container.getParent();
        while (container != null
            && DeclarationRangeUtil.getPossibleDeclarationAtRange(container) == null) {
          container = container.getParent();
          if (container instanceof PsiFile) return;
        }
      }
    }
    if (container == null) {
      return;
    }

    final TextRange range = DeclarationRangeUtil.getPossibleDeclarationAtRange(container);
    if (range == null) {
      return;
    }
    final PsiElement _container = container;
    ApplicationManager.getApplication()
        .invokeLater(
            new Runnable() {
              @Override
              public void run() {
                LightweightHint hint =
                    EditorFragmentComponent.showEditorFragmentHint(editor, range, true, true);
                if (hint != null) {
                  hint.putUserData(CONTAINER_KEY, _container);
                  editor.putUserData(MY_LAST_HINT_KEY, new WeakReference<LightweightHint>(hint));
                }
              }
            });
  }