@Nullable
  PsiElement findMatchingElement(PsiFile file, Editor editor) {
    if (!file.getViewProvider().getLanguages().contains(GroovyLanguage.INSTANCE)) {
      return null;
    }

    SelectionModel selectionModel = editor.getSelectionModel();
    if (selectionModel.hasSelection()) {
      int start = selectionModel.getSelectionStart();
      int end = selectionModel.getSelectionEnd();

      if (0 <= start && start <= end) {
        TextRange selectionRange = new TextRange(start, end);
        PsiElement element = PsiImplUtil.findElementInRange(file, start, end, PsiElement.class);
        while (element != null && element.getTextRange() != null && selectionRange.contains(element.getTextRange())) {
          if (predicate.getValue().satisfiedBy(element)) return element;
          element = element.getParent();
        }
      }
    }

    final int position = editor.getCaretModel().getOffset();
    PsiElement element = file.findElementAt(position);
    while (element != null) {
      if (predicate.getValue().satisfiedBy(element)) return element;
      if (isStopElement(element)) break;
      element = element.getParent();
    }

    element = file.findElementAt(position - 1);
    while (element != null) {
      if (predicate.getValue().satisfiedBy(element)) return element;
      if (isStopElement(element)) return null;
      element = element.getParent();
    }

    return null;
  }
@Nullable
  PsiElement findMatchingElement(PsiFile file, Editor editor)