ArrangementEntryMatcher (@NotNull ArrangementMatchCondition condition) { final Ref<ArrangementEntryMatcher> result = new Ref<>(); final Stack<CompositeArrangementEntryMatcher> composites = new Stack<>(); ArrangementMatchConditionVisitor visitor = new ArrangementMatchConditionVisitor() { @Override public void visit(@NotNull ArrangementAtomMatchCondition condition) { ArrangementEntryMatcher matcher = buildMatcher(condition); if (matcher == null) { return; } if (composites.isEmpty()) { result.set(matcher); } else { composites.peek().addMatcher(matcher); } } @Override public void visit(@NotNull ArrangementCompositeMatchCondition condition) { composites.push(new CompositeArrangementEntryMatcher()); try { for (ArrangementMatchCondition operand : condition.getOperands()) { operand.invite(this); } } finally { CompositeArrangementEntryMatcher matcher = composites.pop(); if (composites.isEmpty()) { result.set(matcher); } } } }; condition.invite(visitor); return result.get(); }