@Override
  protected @NotNull StandardDataFlowInterpreter createInterpreter(@NotNull DfaListener listener,
                                                                   @NotNull ControlFlow flow) {
    return new StandardDataFlowInterpreter(flow, listener, true) {
      @Override
      protected void beforeInstruction(Instruction instruction) {
        afterStates.clear();
        killedStates.clear();
      }

      @Override
      protected DfaInstructionState @NotNull [] acceptInstruction(@NotNull DfaInstructionState instructionState) {
        Instruction instruction = instructionState.getInstruction();
        TrackingDfaMemoryState memState = (TrackingDfaMemoryState)instructionState.getMemoryState().createCopy();
        DfaInstructionState[] states = super.acceptInstruction(instructionState);
        for (DfaInstructionState state : states) {
          afterStates.add(state);
          ((TrackingDfaMemoryState)state.getMemoryState()).recordChange(instruction, memState);
        }
        if (states.length == 0) {
          killedStates.add(memState);
        }
        if (instruction instanceof ExpressionPushingInstruction pushing && pushing.getDfaAnchor() instanceof JavaExpressionAnchor anchor &&
            anchor.getExpression() == myExpression) {
          for (DfaInstructionState state : states) {
            MemoryStateChange history = ((TrackingDfaMemoryState)state.getMemoryState()).getHistory();
            myHistoryForContext = myHistoryForContext == null ? history : myHistoryForContext.merge(history);
          }
        }
        return states;
      }

      @Override
      protected void afterInstruction(Instruction instruction) {
        if (afterStates.size() <= 1 && killedStates.isEmpty()) return;
        Map<Instruction, List<TrackingDfaMemoryState>> instructionToState =
          StreamEx.of(afterStates).mapToEntry(s -> s.getInstruction(), s -> (TrackingDfaMemoryState)s.getMemoryState()).grouping();
        if (instructionToState.size() <= 1 && killedStates.isEmpty()) return;
        instructionToState.forEach((target, memStates) -> {
          List<TrackingDfaMemoryState> bridgeChanges =
            StreamEx.of(afterStates).filter(s -> s.getInstruction() != target)
              .map(s -> ((TrackingDfaMemoryState)s.getMemoryState()))
              .append(killedStates)
              .toList();
          for (TrackingDfaMemoryState state : memStates) {
            state.addBridge(instruction, bridgeChanges);
          }
        });
      }
    };
  }
@Override
  protected @NotNull StandardDataFlowInterpreter createInterpreter(@NotNull DfaListener listener,
                                                                   @NotNull ControlFlow flow)