Initial add of the generic optimizer code

Before digging into this code, look at the Rules implemented at the bottom of DagOptimizer.

There are several TODOS here:

- [x] After I split the code into separate files, I started hitting a scala 2.9 compiler bug, that I don't hit in 2.10. I'll try to work around, or possibly hope that Twitter finally gets on 2.9 before we need this.

- [x] Tests tests tests. I played around at the repl, but clearly we need super hardcore tests for any optimization framework.

- [ ] Actually call this code from an existing platform.
That is a good question. Originally we thought of names applying to nodes. With this patch I realized they should rightly apply to the items contained in the nodes (what I call the irreducibles): functions, stores, services, sources, sinks. So, in the original graph, you build a `Map[Any, List[String]]` for the names of each of the above items (function, store, etc...). Then at plan time, though they may have been moved around or combined, you can still get the names for any irreducible value.