public void transform(final FlowGraph cfg) {

		final File dir = new File("ValueFoldingOutdir");
		if (ValueFolding.DUMP) {
			// System.out.println(" Dumping Value Folding in directory: " +
			// dir);

			// try {
			// cfgFile = new File(dir, "cfg.txt");

			// cfg.print(new PrintWriter(new FileWriter(cfgFile), true));

			// dotFile = new File(dir, "cfg.dot");
			// cfg.printGraph(new PrintWriter(new FileWriter(dotFile),
			// true));

			// vnFile = new File(dir, "value.numbers");
			// vn = new PrintWriter(new FileWriter(vnFile), true);

			// dumpFile = new File(dir, "vn.dump");
			// dump = new PrintWriter(new FileWriter(dumpFile), true);

			// } catch (IOException ex) {

			// }

			vn = new PrintWriter(System.out, true);
			dump = new PrintWriter(System.out, true);
		}

		final EditorContext context = cfg.method().declaringClass().context();

		sideEffects = new SideEffectChecker(context);

		folder = new ValueFolder(true, context);

		final SSAGraph ssaGraph = new SSAGraph(cfg);

		ssaGraph.visitComponents(new ComponentVisitor() {
			public void visitComponent(final List scc) {
				// Maps Nodes in the SCC to their folded value
				final HashMap map = new HashMap(scc.size() * 2 + 1);

				boolean changed = true;

				while (changed) {
					changed = false;

					final Iterator iter = scc.iterator();

					int x = 0;
					while (iter.hasNext()) {
						final Node node = (Node) iter.next();

						if (ValueFolding.DUMP) {
							x++;
							dump.println("Folding SCC Node " + node + " (" + x
									+ " of " + scc.size() + ")");
						}

						if (fold(map, node)) {
							changed = true;
						}
					}

					if (ValueFolding.DUMP) {
						dump.println("");
					}

					if (scc.size() == 1) {
						break;
					}
				}
			}
		});

		cfg.removeUnreachable();

		folder = null;
		sideEffects = null;

		// Okay, we've successfully value folded, remove debugging files
		if (ValueFolding.DUMP && !ValueFolding.SAVEDUMP) {
			// cfgFile.delete();
			// dotFile.delete();
			// dumpFile.delete();
			// vnFile.delete();
			// dir.delete();
		}
	}