private List<PsiElement> _process(final Matcher matcher, final boolean resolve) { final XmlTag root = matcher.getRoot(); if (root == null || myHistory.contains(root)) { return Collections.emptyList(); } myHistory.add(root); final List<PsiElement> found = new ArrayList<PsiElement>(); try { if (matcher.isRecursive()) { root.accept( new XmlRecursiveElementVisitor() { @Override public void visitXmlTag(XmlTag tag) { final Matcher.Result match = matcher.match(tag); if (match != null) { if (match.chain != null) { found.addAll(_process(match.chain, resolve)); } else { assert match.result != null; found.add(match.result); if (resolve) throw Stop.DONE; } } super.visitXmlTag(tag); } }); } else { root.acceptChildren( new XmlElementVisitor() { @Override public void visitXmlTag(XmlTag tag) { final Matcher.Result match = matcher.match(tag); if (match != null) { if (match.chain != null) { found.addAll(_process(match.chain, resolve)); } else { assert match.result != null; found.add(match.result); if (resolve) throw Stop.DONE; } } } }); } } catch (Stop e) { /* processing stopped */ } return found; }