LoopReduceResult (@NotNull PsiType selectorType, @NotNull PsiElement context, @NotNull Set<? extends PatternDescription> patterns, @NotNull BiPredicate<Set<? extends PatternDescription>, PsiType> stopAt, @NotNull Map<ReduceResultCacheContext, ReduceResult> cache) { boolean changed = false; int currentIteration = 0; Set<? extends PatternDescription> currentPatterns = new HashSet<>(patterns); while (currentIteration < MAX_ITERATION_COVERAGE) { currentIteration++; if (stopAt.test(currentPatterns, selectorType)) { return new LoopReduceResult(currentPatterns, true, true); } ReduceResult reduceResult = reduce(selectorType, context, currentPatterns, cache); changed |= reduceResult.changed(); currentPatterns = reduceResult.patterns(); if (!reduceResult.changed()) { return new LoopReduceResult(currentPatterns, changed, false); } } LOG.error("The number of iteration is exceeded, length of set patterns: " + patterns.size() + "max length deconstruction: " + patterns.stream() .filter(t->t instanceof PatternDeconstructionDescription) .map(t->((PatternDeconstructionDescription)t).list.size()) .max(Comparator.naturalOrder()) ); return new LoopReduceResult(currentPatterns, changed, false); }