Make TypedPipe immutable

Let's really look carefully at this. This was an attempt at a minimal change that would be source-code compatible.

Some questions:

1. should TypedPipeInst be a case class? It seems like we don't want to pattern match and get the FlowDef back out, as it should never be mutated. Tend to think it should not be a case class (and we can add a custom unapply if needed to match the old cases, which does not expose the flowDef).
2. Should we bite the bullet and make an ImmutableFlowDef, which is just exactly cascading's FlowDef with scala Map/Vector/List? Then have functions to copy between? We could have a Monoid of this class to handle the merging.
3. Be on the lookout for any way to make this change smaller, while keeping the TypedPipe immutable. Verify that despite the fact that FlowDefs are mutable, the TypedPipe is still immutable.
4. Can we move the snapshot/save/toIterator/dump methods from the repl directly on to TypedPipe?

TODO:
- [x] audit the Matrix2 code to remove unneeded FlowDefs from the code.
- [x] consider if we can add implicit Mode to `def toPipe` so that we can remove the Mode bound to IterablePipe, EmptyPipe, LiteralValue, EmptyValue. Seems like a possibly harder case.
Get the joinFunction and inputs out before we use them below to avoid closing over `this`.