I killed the PipedState thing and it's now more similar to yours accept it adds a few key things.
- You can go back and forth between buffering and passthrough state. This is important to support the pause/resume scheme of pipe.
- Added flush semantics with flush on resume. In buffer state it buffers everything. When resume is called, the buffer queue is "flushed". It plays back the queue of buffered data in order before going back to passthrough state.
The flush semantics are flawed somehow though. Either that or the test is flawed because it fails. Take a look.