@NotNull
  public List<MatchResult> matchByDownUp(PsiElement element) throws MalformedPatternException, UnsupportedPatternException {
    final MatchContext matchContext = getMatchContext();
    matchContext.clear();
    final CollectingMatchResultSink sink = new CollectingMatchResultSink();
    matchContext.setSink(new DuplicateFilteringResultSink(sink));
    final CompiledPattern compiledPattern = matchContext.getPattern();
    matchContext.setShouldRecursivelyMatch(false);

    PsiElement targetNode = compiledPattern.getTargetNode();
    PsiElement elementToStartMatching = null;

    if (targetNode == null) {
      targetNode = compiledPattern.getNodes().current();
      if (targetNode != null) {
        compiledPattern.getNodes().advance();
        assert !compiledPattern.getNodes().hasNext();
        compiledPattern.getNodes().rewind();

        element = element.getParent();
        if (element == null) {
          return Collections.emptyList();
        }
        while (element.getClass() != targetNode.getClass()) {
          element = element.getParent();
          if (element == null) return Collections.emptyList();
        }

        elementToStartMatching = element;
      }
    }
    else {
      final StructuralSearchProfile profile = StructuralSearchUtil.getProfileByPsiElement(element);
      if (profile == null) return Collections.emptyList();
      targetNode = profile.extendMatchedByDownUp(targetNode);

      final MatchOptions options = matchContext.getOptions();
      MatchingHandler handler = null;
      while (element.getClass() == targetNode.getClass() ||
             compiledPattern.isTypedVar(targetNode) && compiledPattern.getHandler(targetNode).canMatch(targetNode, element, matchContext)) {
        handler = compiledPattern.getHandler(targetNode);
        handler.setPinnedElement(element);
        elementToStartMatching = element;
        if (handler instanceof TopLevelMatchingHandler) break;
        element = element.getParent();
        targetNode = targetNode.getParent();

        if (options.isLooseMatching()) {
          element = profile.updateCurrentNode(element);
          targetNode = profile.updateCurrentNode(targetNode);
        }
      }

      if (!(handler instanceof TopLevelMatchingHandler)) return Collections.emptyList();
    }

    assert targetNode != null : "Could not match down up when no target node";

    visitor.matchContext(SingleNodeIterator.create(elementToStartMatching));
    matchContext.getSink().matchingFinished();
    return sink.getMatches();
  }
@NotNull
  public List<MatchResult> matchByDownUp(PsiElement element)