PsiElementVisitor (@NotNull GlobalMatchingVisitor globalVisitor) { return new PsiElementVisitor() { @Override public void visitElement(@NotNull PsiElement element) { if (element instanceof Property) { Property other = globalVisitor.getElement(Property.class); final PsiElement key = element.getFirstChild(); if (globalVisitor.setResult(globalVisitor.match(key, other.getFirstChild()))) { final PsiElement value = element.getLastChild(); if (value instanceof PropertyValueImpl) { final PsiElement otherValue = other.getLastChild(); globalVisitor.setResult(globalVisitor.matchOptionally(value, otherValue instanceof PropertyValueImpl ? otherValue : null)); } } } else if (element instanceof PropertyKeyImpl) { final PropertyKeyImpl other = globalVisitor.getElement(PropertyKeyImpl.class); final MatchContext context = globalVisitor.getMatchContext(); final MatchingHandler handler = context.getPattern().getHandler(element); if (handler instanceof SubstitutionHandler) { globalVisitor.setResult(((SubstitutionHandler)handler).handle(other, context)); } else { globalVisitor.setResult(globalVisitor.matchText(element, other)); } } else if (element instanceof PropertyValueImpl) { final PropertyValueImpl other = globalVisitor.getElement(PropertyValueImpl.class); final MatchContext context = globalVisitor.getMatchContext(); final MatchingHandler handler = element.getUserData(CompiledPattern.HANDLER_KEY); if (handler instanceof LiteralWithSubstitutionHandler) { globalVisitor.setResult(handler.match(element, other, context)); } else if (handler instanceof SubstitutionHandler) { globalVisitor.setResult(((SubstitutionHandler)handler).handle(other, context)); } else { globalVisitor.setResult(globalVisitor.matchText(element, other)); } } } @Override public void visitComment(@NotNull PsiComment comment) { final PsiElement other = globalVisitor.getElement(); final MatchingHandler handler = comment.getUserData(CompiledPattern.HANDLER_KEY); globalVisitor.setResult(handler instanceof LiteralWithSubstitutionHandler ? handler.match(comment, other, globalVisitor.getMatchContext()) : globalVisitor.matchText(comment, other)); } }; }