boolean (@NotNull ASTNode node, int @NotNull [] offsetsInNode, @NotNull ProgressIndicator progress, @NotNull NodeTextOccurrenceProcessor processor) { final int scopeStartOffset = node.getStartOffset(); // helps to avoid full tree rescan in subsequent com.intellij.lang.ASTNode#findLeafElementAt calls (O(n) instead of O(n^2)) ASTNode lastElement = null; for (int offset : offsetsInNode) { progress.checkCanceled(); final ASTNode leafNode = findNextLeafElementAt(node, lastElement, offset); if (leafNode == null) { PsiElement psi = node.getPsi(); LOG.error("Cannot find leaf: node=" + node + "; psi= " + psi + "; language=" + (psi==null?null:psi.getLanguage())+ "; offset=" + offset + "; lastElement=" + lastElement); continue; } final int offsetInLeaf = offset - leafNode.getStartOffset() + scopeStartOffset; if (offsetInLeaf < 0) { throw new AssertionError("offset=" + offset + "; scopeStartOffset=" + scopeStartOffset + "; node=" + node); } if (!processor.execute(leafNode, offsetInLeaf)) { return false; } lastElement = leafNode; } return true; }