public static boolean matchInAnyOrder(@NotNull NodeIterator patternNodes, @NotNull NodeIterator matchedNodes, @NotNull MatchContext context) {
    if (patternNodes.hasNext() && !matchedNodes.hasNext()) {
      return validateSatisfactionOfHandlers(patternNodes, context);
    }

    Set<PsiElement> matchedElements = null;
    while (patternNodes.hasNext()) {
      final PsiElement patternNode = patternNodes.current();
      patternNodes.advance();
      final CompiledPattern pattern = context.getPattern();
      final MatchingHandler handler = pattern.getHandler(patternNode);

      matchedNodes.reset();
      boolean allElementsMatched = true;
      int matchedOccurs = 0;
      do {
        final PsiElement pinnedNode = handler.getPinnedNode();
        final PsiElement matchedNode = (pinnedNode != null) ? pinnedNode : matchedNodes.current();
        if (pinnedNode == null) matchedNodes.advance();

        if (matchedElements == null || !matchedElements.contains(matchedNode)) {
          allElementsMatched = false;
          if (handler.match(patternNode, matchedNode, context)) {
            matchedOccurs++;
            if (matchedElements == null) matchedElements = new HashSet<>();
            matchedElements.add(matchedNode);
            if (handler.shouldAdvanceThePatternFor(patternNode, matchedNode)) {
              break;
            }
          } else if (pinnedNode != null) {
            return false;
          }

          // clear state of dependent objects
          clearingVisitor.clearState(pattern, patternNode);
        }

        if (!matchedNodes.hasNext() || pinnedNode != null) {
          if (!handler.validate(context, matchedOccurs)) return false;
          if (allElementsMatched || !patternNodes.hasNext()) {
            final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
            if (result && matchedElements != null) {
              context.notifyMatchedElements(matchedElements);
            }
            return result;
          }
          break;
        }
      } while(true);

      if (!handler.validate(context, matchedOccurs)) return false;
    }

    final boolean result = validateSatisfactionOfHandlers(patternNodes, context);
    if (result && matchedElements != null) {
      context.notifyMatchedElements(matchedElements);
    }
    return result;
  }
public static boolean matchInAnyOrder(@NotNull NodeIterator patternNodes, @NotNull NodeIterator matchedNodes, @NotNull MatchContext context)