class ConstantPropagatorAndFolder extends BodyTransformer {
  private static final Logger logger = LoggerFactory.getLogger(ConstantPropagatorAndFolder.class);

  public ConstantPropagatorAndFolder(Singletons.Global g) {
  }

  public static ConstantPropagatorAndFolder v() {
    return G.v().soot_jimple_toolkits_scalar_ConstantPropagatorAndFolder();
  }

  @Override
  protected void internalTransform(Body b, String phaseName, Map<String, String> options) {<FILL_FUNCTION_BODY>}
}

    int numFolded = 0;
    int numPropagated = 0;

    if (Options.v().verbose()) {
      logger.debug("[" + b.getMethod().getName() + "] Propagating and folding constants...");
    }

    UnitGraph g = ExceptionalUnitGraphFactory.createExceptionalUnitGraph(b);
    LocalDefs localDefs = G.v().soot_toolkits_scalar_LocalDefsFactory().newLocalDefs(g);

    // Perform a constant/local propagation pass.
    // go through each use box in each statement
    for (Unit u : (new PseudoTopologicalOrderer<Unit>()).newList(g, false)) {
      // propagation pass
      for (ValueBox useBox : u.getUseBoxes()) {
        Value value = useBox.getValue();
        if (value instanceof Local) {
          Local local = (Local) value;
          List<Unit> defsOfUse = localDefs.getDefsOfAt(local, u);
          if (defsOfUse.size() == 1) {
            DefinitionStmt defStmt = (DefinitionStmt) defsOfUse.get(0);
            Value rhs = defStmt.getRightOp();
            if (rhs instanceof NumericConstant || rhs instanceof StringConstant || rhs instanceof NullConstant) {
              if (useBox.canContainValue(rhs)) {
                useBox.setValue(rhs);
                numPropagated++;
              }
            } else if (rhs instanceof CastExpr) {
              CastExpr ce = (CastExpr) rhs;
              if (ce.getCastType() instanceof RefType && ce.getOp() instanceof NullConstant) {
                defStmt.getRightOpBox().setValue(NullConstant.v());
                numPropagated++;
              }
            }
          }
        }
      }

      // folding pass
      for (ValueBox useBox : u.getUseBoxes()) {
        Value value = useBox.getValue();
        if (!(value instanceof Constant)) {
          if (Evaluator.isValueConstantValued(value)) {
            Value constValue = Evaluator.getConstantValueOf(value);
            if (useBox.canContainValue(constValue)) {
              useBox.setValue(constValue);
              numFolded++;
            }
          }
        }
      }
    }

    if (Options.v().verbose()) {
      logger.debug("[" + b.getMethod().getName() + "]     Propagated: " + numPropagated + ", Folded:  " + numFolded);
    }
  
<methods>public non-sealed void <init>() ,public final void transform(soot.Body, java.lang.String, Map<java.lang.String,java.lang.String>) ,public final void transform(soot.Body, java.lang.String) ,public final void transform(soot.Body) <variables>private static final Map<java.lang.String,java.lang.String> enabledOnlyMap