diff --git a/CHANGELOG b/CHANGELOG
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,7 @@
+0.7.1.0
+-------
+- contramapFoldable, contramapEnumerable.
+
 0.7.0.2
 -------
 - Bumped conceit dependency to make it work with GHC 7.10.
diff --git a/process-streaming.cabal b/process-streaming.cabal
--- a/process-streaming.cabal
+++ b/process-streaming.cabal
@@ -1,5 +1,5 @@
 name:          process-streaming
-version:       0.7.0.2
+version:       0.7.1.0
 license:       BSD3
 license-file:  LICENSE
 data-files:    
diff --git a/src/System/Process/Streaming.hs b/src/System/Process/Streaming.hs
--- a/src/System/Process/Streaming.hs
+++ b/src/System/Process/Streaming.hs
@@ -74,6 +74,8 @@
         , DecodingFunction
         , encoded
         , SiphonOp (..)
+        , contramapFoldable
+        , contramapEnumerable
         -- * Handling lines
         , Lines
         , toLines
@@ -351,14 +353,13 @@
     Collects incoming 'BS.ByteString' values into a lazy 'BL.ByteString'.
 -}
 intoLazyBytes :: Siphon ByteString e BL.ByteString 
-intoLazyBytes = fromFold toLazyM  
-
+intoLazyBytes = fromFoldl (fmap BL.fromChunks L.list)
 
 {-| 
     Collects incoming 'Data.Text' values into a lazy 'TL.Text'.
 -}
 intoLazyText :: Siphon Text e TL.Text
-intoLazyText = fromFold T.toLazyM  
+intoLazyText = fromFoldl (fmap TL.fromChunks L.list)
 
 {-| 
    Builds a 'Siphon' out of a computation that does something with
@@ -564,6 +565,10 @@
         pure (f a,r)
 
 
+{-|
+    A newtype wrapper with functions for working on the inputs of
+    a 'Siphon', instead of the outputs. 
+ -}
 newtype SiphonOp e a b = SiphonOp { getSiphonOp :: Siphon b e a } 
 
 -- | 'contramap' carn turn a 'SiphonOp' for bytes into a 'SiphonOp' for text.
@@ -625,6 +630,16 @@
             Right (b,_) -> Right (absurd (f b))
 
 {-|
+    Useful to weed out unwanted inputs to a 'Siphon', by returning @[]@.
+-}
+contramapFoldable :: Foldable f => (a -> f b) -> SiphonOp e r b -> SiphonOp e r a
+contramapFoldable unwinder = contramapEnumerable (Select . each . unwinder)
+
+contramapEnumerable :: Enumerable t => (a -> t IO b) -> SiphonOp e r b -> SiphonOp e r a
+contramapEnumerable unwinder (getSiphonOp -> s) = SiphonOp $
+    siphon' $ runSiphon s . flip for (enumerate . toListT . unwinder) 
+
+{-|
     Specifies a transformation that will be applied to each line of text,
     represented as a 'Producer'.
 -}
@@ -664,7 +679,7 @@
 
 {-|
   A simplified version of 'executePipelineFallibly' for when the error type
-  unified with `Void`.  Note however that this function may still throw
+  unifies with `Void`.  Note however that this function may still throw
   exceptions.
  -}
 executePipeline :: Piping Void a -> Tree (Stage Void) -> IO a 
diff --git a/src/System/Process/Streaming/Extended.hs b/src/System/Process/Streaming/Extended.hs
--- a/src/System/Process/Streaming/Extended.hs
+++ b/src/System/Process/Streaming/Extended.hs
@@ -1,4 +1,3 @@
-
 {-|
 -}
 
@@ -26,12 +25,19 @@
     ) where
 
 import Data.Text 
+import Data.Void
+import Data.Monoid
 import Control.Applicative
 import Control.Exception
 import Control.Concurrent.Conceit
+import Control.Monad
+import Control.Monad.Trans.Except
 import Pipes.ByteString
 import System.IO
 
+import Pipes
+import Pipes.Core
+import qualified Pipes.Prelude as P
 import System.Process.Streaming
 import System.Process.Streaming.Internal
 
@@ -129,3 +135,27 @@
 
 siphonToHandle :: Handle -> Siphon ByteString e ()
 siphonToHandle = fromConsumer . toHandle
+
+
+--{-|
+--    More general than '_nestEnumerable' in that the 'Siphon's that consume each
+--    stream of @b@s can depend on the @a@s.
+---}
+--nestEnumerable :: Enumerable t => (a -> t IO b) -> (a -> Client (SiphonOp e () b) a (ExceptT e IO) Void) -> SiphonOp e () a
+--nestEnumerable unwinder siphonClient = SiphonOp $ siphon' $ \producer -> runExceptT . runEffect $ fmap ((,) ()) $
+--    hoist lift producer >>~ (retag >~> (fmap absurd . siphonClient))
+--  where
+--    retag a = do
+--        s <- respond a
+--        _ <- lift . ExceptT $ runSiphonDumb (getSiphonOp s) (enumerate . toListT . unwinder $ a) 
+--        request () >>= retag
+--
+--
+--{-|
+--    For each incoming @a@, use a different 'Siphon' to consume the
+--    corresponding stream of @b@s. 
+---}
+--_nestEnumerable :: Enumerable t => (a -> t IO b) -> Producer (SiphonOp e () b) (ExceptT e IO) Void -> SiphonOp e () a 
+--_nestEnumerable unwinder siphonProducer = SiphonOp $ siphon' $ \producer -> runExceptT . runEffect $ fmap ((,) ()) $
+--    for (P.zip (hoist lift producer) (fmap absurd siphonProducer)) $ \(a, siph) ->
+--       lift . ExceptT $ runSiphonDumb (getSiphonOp siph) (enumerate . toListT . unwinder $ a) 
diff --git a/src/System/Process/Streaming/Internal.hs b/src/System/Process/Streaming/Internal.hs
--- a/src/System/Process/Streaming/Internal.hs
+++ b/src/System/Process/Streaming/Internal.hs
@@ -119,6 +119,9 @@
             fmap (fmap (bimap f g)) action
 
 
+{-| 
+    'Pump's are actions that write data into a process' @stdin@. 
+ -}
 newtype Pump b e a = Pump { runPump :: Consumer b IO () -> IO (Either e a) } deriving Functor
 
 {-| 
@@ -127,6 +130,12 @@
 instance Bifunctor (Pump b) where
   bimap f g (Pump x) = Pump $ fmap (liftM  (bimap f g)) x
 
+
+{-| 
+    'pure' writes nothing to @stdin@.
+
+    '<*>' sequences the writes to @stdin@.
+-}
 instance Applicative (Pump b e) where
   pure = Pump . pure . pure . pure
   Pump fs <*> Pump as = 
@@ -238,9 +247,8 @@
 
 
 {-| 
-    A 'Siphon' represents a computation that completely drains a producer, but
-may fail early with an error of type @e@. 
-
+    A 'Siphon' represents a computation that completely drains
+    a 'Producer', but which may fail early with an error of type @e@. 
  -}
 newtype Siphon b e a = Siphon (Lift (Siphon_ b e) a) deriving (Functor)
 
