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.
actually, I spent some time on this. This does not work in a very clean way. Look at the AlsoPullUp rule. We want to leave Alsos alone. Not matching the case does not work, because there is a catch all case below. For that catch-all, we really want all BUT AlsoProducer. I don't know how to implement such a case match in scala (if it is indeed possible).

I don't like the verbosity of the Some/None in the return, but some kinds of rules are not easy to express without them. Instead, what about adding a PartialRule that hase applyWhere that returns a PartialFunction, and then calls lift on it. In that way, we can use the most convenient option for each case.