Reusable pipelines

Creating the possibility of using the same pipeline more than once. 

This was not previously possible due to the stream objects being closed once the pipeline was used. By adding the possibility of passing tasks as functions that return a stream object, reusable pipelines can be created.