docs: @Override
      public void edgeTransfer(Edge edge, TypeQualifierValueSet fact) throws DataflowAnalysisException {
          if (!fact.isValid()) {
              return;
          }
  
          // Propagate flow values and source information across phi nodes.
  
          ValueNumberFrame targetVnaFrame = vnaDataflow.getStartFact(edge.getTarget());
          ValueNumberFrame sourceVnaFrame = vnaDataflow.getResultFact(edge.getSource());
  
          if (!targetVnaFrame.isValid() || !sourceVnaFrame.isValid()) {
              return;
          }
  
          // The source and target frames can have different numbers of slots
          // if the target is an exception handler.
          // So, merge the minimum number of slots in either frame.
          int numSlotsToMerge = Math.min(sourceVnaFrame.getNumSlots(), targetVnaFrame.getNumSlots());
  
          for (int i = 0; i < numSlotsToMerge; i++) {
              ValueNumber targetVN = targetVnaFrame.getValue(i);
              ValueNumber sourceVN = sourceVnaFrame.getValue(i);
  
              if (!targetVN.equals(sourceVN) && targetVN.hasFlag(ValueNumber.PHI_NODE)) {
                  // targetVN is a phi result
                  if (DEBUG_VERBOSE) {
                      System.out.println("Phi node: " + fact.valueNumberToString(sourceVN) + " -> "
                              + fact.valueNumberToString(targetVN));
                  }
                  propagateAcrossPhiNode(fact, sourceVN, targetVN);
                  if (DEBUG_VERBOSE) {
                      String dir = isForwards() ? "forwards" : "backwards";
                      System.out.println("After propagating phi node " + dir + ": " + fact.toString());
                  }
              }
          }
      }