void (Set<PsiExpression> conditions) { final List<PsiExpression> conditionList = new ArrayList<>(conditions); if (ignoreSideEffectConditions) { conditionList.replaceAll(cond -> SideEffectChecker.mayHaveSideEffects(cond) ? null : cond); // Every condition having side-effect separates non-side-effect conditions into independent groups // like: // if(!readToken() || token == X || token == Y) ... // else if(!readToken() || token == X || token == Y) ... // here we analyze independently first ['token == X', 'token == Y'] and second ['token == X', 'token == Y'] // thus no warning is issued. Such constructs often appear in parsers. StreamEx.of(conditionList).groupRuns((a, b) -> a != null && b != null) .filter(list -> list.size() >= 2).forEach(this::findDuplicates); } else { findDuplicates(conditionList); } }