@Nullable
  private List<@Nullable E> performDFA(boolean timeout) {
    final int n = myFlow.length;
    final List<Optional<E>> info = getEmptyInfo(n);
    final CallEnvironment env = new MyCallEnvironment(n);

    final WorkList workList = new WorkList(n, getFlowOrder());

    while (!workList.isEmpty()) {
      ProgressManager.checkCanceled();
      if (timeout && checkCounter()) return null;
      final int num = workList.next();
      final Instruction curr = myFlow[num];
      final Optional<E> oldE = info.get(num);                        // saved outbound state
      final List<E> ins = getPrevInfos(curr, info, env);             // states from all inbound edges
      final E jointE = mySemilattice.join(ins);                      // inbound state
      final E newE = myDfa.fun(jointE, curr);                        // new outbound state
      if (oldE.isEmpty() || !mySemilattice.eq(newE, oldE.get())) {   // if outbound state changed
        info.set(num, Optional.of(newE));                            // save new state
        for (Instruction next : getNext(curr, env)) {
          workList.offer(next.num());
        }
      }
    }
    return ContainerUtil.map(info, e -> e.orElse(null));
  }
@Nullable
  private List<@Nullable E> performDFA(boolean timeout)