boolean (boolean forward, BiFunction<? super Instruction, ? super BitSet, ? extends BitSet> handleState) { List<Instruction> entryPoints; if (forward) { entryPoints = List.of(myInstructions[0]); } else { entryPoints = StreamEx.of(myInstructions).select(ControlTransferInstruction.class) .filter(cti -> cti.getTransfer().getTarget().getPossibleTargets().length == 0) .collect(Collectors.toList()); } Deque<InstructionState> queue = new ArrayDeque<>(10); for (Instruction i : entryPoints) { queue.addLast(new InstructionState(i, new BitSet())); } int limit = myForwardMap.size() * 100; Map<BitSet, IntSet> processed = new HashMap<>(); int steps = 0; while (!queue.isEmpty()) { if (steps > limit) { return false; } if (steps % 1024 == 0) { ProgressManager.checkCanceled(); } InstructionState state = queue.removeFirst(); Instruction instruction = state.first; Collection<Instruction> nextInstructions = forward ? myForwardMap.get(instruction) : myBackwardMap.get(instruction); BitSet nextVars = handleState.apply(instruction, state.second); for (Instruction next : nextInstructions) { IntSet instructionSet = processed.computeIfAbsent(nextVars, k -> new IntOpenHashSet()); int index = next.getIndex() + 1; if (!instructionSet.contains(index)) { instructionSet.add(index); queue.addLast(new InstructionState(next, nextVars)); steps++; } } } return true; }