public void matchContext(@NotNull NodeIterator elements) {
    final CompiledPattern pattern = matchContext.getPattern();
    final NodeIterator patternNodes = pattern.getNodes().clone();
    final MatchResultImpl saveResult = matchContext.hasResult() ? matchContext.getResult() : null;
    matchContext.saveMatchedNodes();

    try {
      if (!patternNodes.hasNext()) return;
      final MatchingHandler firstMatchingHandler = pattern.getHandler(patternNodes.current());

      for (; elements.hasNext(); elements.advance()) {
        matchContext.setResult(null);
        matchContext.clearMatchedNodes();
        final PsiElement elementNode = elements.current();

        final boolean patternMatched = firstMatchingHandler.matchSequentially(patternNodes, elements, matchContext);
        final boolean contextMatched;
        if (patternMatched) {
          final MatchingHandler matchingHandler = pattern.getHandler(Configuration.CONTEXT_VAR_NAME);
          contextMatched = matchingHandler == null || ((SubstitutionHandler)matchingHandler).handle(elementNode, matchContext);
        }
        else {
          contextMatched = false;
        }

        if (contextMatched) matchContext.dispatchMatched();

        patternNodes.reset();
        if (patternMatched) {
          elements.rewind();
        }
      }
    }
    finally {
      matchContext.setResult(saveResult);
      matchContext.restoreMatchedNodes();
    }
  }
public void matchContext(@NotNull NodeIterator elements)