@NotNull
    <T> FactDefinition<T> findFact(DfaValue value, FactExtractor<T> extractor) {
      if (value instanceof DfaVariableValue) {
        for (MemoryStateChange change = this; change != null; change = change.getPrevious()) {
          FactDefinition<T> factPair = factFromChange(extractor, change, change.myChanges.get(value));
          if (factPair != null) return factPair;
          if (!(change.myInstruction instanceof ConditionalGotoInstruction)) {
            factPair = factFromChange(extractor, change, change.myBridgeChanges.get(value));
            if (factPair != null) return factPair;
          }
          if (change.myInstruction instanceof AssignInstruction && change.myTopOfStack == value && change.getPrevious() != null) {
            FactDefinition<T> fact = change.getPrevious().findFact(value, extractor);
            return new FactDefinition<>(change, fact.myFact, fact.myOldFact);
          }
        }
        return new FactDefinition<>(null, extractor.extract(((DfaVariableValue)value).getInherentType()), null);
      }
      if (value instanceof DfaBinOpValue binOp) {
        FactDefinition<T> left = findFact(binOp.getLeft(), extractor);
        FactDefinition<T> right = findFact(binOp.getRight(), extractor);
        if (left.myFact instanceof LongRangeSet && right.myFact instanceof LongRangeSet) {
          LongRangeBinOp op = binOp.getOperation();
          @SuppressWarnings("unchecked")
          T result = (T)op.eval((LongRangeSet)left.myFact, (LongRangeSet)right.myFact, binOp.getDfType().getLongRangeType());
          T oldFact = null;
          if (left.myOldFact != null && right.myOldFact != null) {
            //noinspection unchecked
            oldFact = (T)op.eval((LongRangeSet)left.myOldFact, (LongRangeSet)right.myOldFact, binOp.getDfType().getLongRangeType());
          }
          return new FactDefinition<>(null, Objects.requireNonNull(result), oldFact);
        }
      }
      return new FactDefinition<>(null, extractor.extract(value.getDfType()), null);
    }
@NotNull
    <T> FactDefinition<T> findFact(DfaValue value, FactExtractor<T> extractor)