boolean (@NotNull NodeIterator patternNodes, @NotNull NodeIterator matchNodes, @NotNull MatchContext context) { final MatchingStrategy strategy = context.getPattern().getStrategy(); final PsiElement currentPatternNode = patternNodes.current(); final PsiElement currentMatchNode = matchNodes.current(); skipIfNecessary(matchNodes, currentPatternNode, strategy); skipIfNecessary(patternNodes, matchNodes.current(), strategy); if (!patternNodes.hasNext()) { return !matchNodes.hasNext(); } final PsiElement patternElement = patternNodes.current(); final MatchingHandler handler = context.getPattern().getHandler(patternElement); if (!(handler instanceof TopLevelMatchingHandler)) skipComments(matchNodes, currentPatternNode); if (matchNodes.hasNext() && handler.match(patternElement, matchNodes.current(), context)) { patternNodes.advance(); skipIfNecessary(patternNodes, matchNodes.current(), strategy); if (shouldAdvanceTheMatchFor(patternElement, matchNodes.current())) { matchNodes.advance(); skipIfNecessary(matchNodes, patternNodes.current(), strategy); if (patternNodes.hasNext()) skipComments(matchNodes, patternNodes.current()); } if (patternNodes.hasNext()) { final MatchingHandler nextHandler = context.getPattern().getHandler(patternNodes.current()); if (nextHandler.matchSequentially(patternNodes, matchNodes, context)) { return true; } else { patternNodes.rewindTo(currentPatternNode); matchNodes.rewindTo(currentMatchNode); } } else { // match was found return handler.isMatchSequentiallySucceeded(matchNodes); } } return false; }