diff --git a/CONTRIBUTORS b/CONTRIBUTORS
--- a/CONTRIBUTORS
+++ b/CONTRIBUTORS
@@ -5,5 +5,7 @@
 John Lato
 Echo Nolan
 Paulo Tanimoto
+Magnus Therning
 Johan Tibell
 Bas van Dijk
+Valery Vorotyntsev
diff --git a/Setup.hs b/Setup.hs
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,3 +1,5 @@
+#! /usr/bin/runhaskell
+
 module Main (main) where
 
 import Distribution.Simple (defaultMain)
diff --git a/iteratee.cabal b/iteratee.cabal
--- a/iteratee.cabal
+++ b/iteratee.cabal
@@ -1,5 +1,5 @@
 name:          iteratee
-version:       0.3.1
+version:       0.3.4
 synopsis:      Iteratee-based I/O
 description:
   The IterateeGM monad provides strict, safe, and functional I/O. In addition
@@ -30,6 +30,10 @@
   description: Build test executables.
   default:     False
 
+flag includeCodecs
+  description: Build Tiff and Wave codec modules
+  default:     False
+
 library
   hs-source-dirs:
     src
@@ -68,12 +72,15 @@
     Data.Iteratee.Base.LooseMap
     Data.Iteratee.Binary
     Data.Iteratee.Char
-    Data.Iteratee.Codecs.Tiff
-    Data.Iteratee.Codecs.Wave
     Data.Iteratee.IO
     Data.Iteratee.IO.Handle
     Data.Iteratee.WrappedByteString
 
+  if flag(includeCodecs)
+    exposed-modules:
+      Data.Iteratee.Codecs.Tiff
+      Data.Iteratee.Codecs.Wave
+
   other-modules:
     Data.Iteratee.IO.Base
 
@@ -109,4 +116,4 @@
 
 source-repository head
   type:     darcs
-  location: http://inmachina.net/~jwlato/haskell/iteratee
+  location: http://tanimoto.us/~jwlato/haskell/iteratee
diff --git a/src/Data/Iteratee/Base.hs b/src/Data/Iteratee/Base.hs
--- a/src/Data/Iteratee/Base.hs
+++ b/src/Data/Iteratee/Base.hs
@@ -444,10 +444,9 @@
 length = length' 0
   where
   length' = IterateeG . step
-  step i (Chunk xs) = return $ Cont
-                               (length' $! i + fromIntegral (LL.length xs))
-                               Nothing
-  step i stream     = return $ Done i stream
+  step i (Chunk xs) = let a = i + (LL.length xs)
+                      in a `seq` return $ Cont (length' a) Nothing
+  step i stream     = return $ Done (fromIntegral i) stream
 
 
 -- ---------------------------------------------------
@@ -466,21 +465,20 @@
 -- stream of the read elements. Unless the stream is terminated early, we
 -- read exactly n elements (even if the iteratee has accepted fewer).
 take :: (SC.StreamChunk s el, Monad m) =>
-  Int ->
-  EnumeratorN s el s el m a
+  Int -> EnumeratorN s el s el m a
 take 0 iter = return iter
-take n' iter = IterateeG (step n')
+take n iter = IterateeG step
   where
-  step n chk@(Chunk str)
-    | SC.null str = return $ Cont (take n iter) Nothing
-    | SC.length str < n = liftM (flip Cont Nothing) inner
-      where inner = liftM (check (n - SC.length str)) (runIter iter chk)
-  step n (Chunk str) = done (Chunk s1) (Chunk s2)
-    where (s1, s2) = SC.splitAt n str
-  step _n stream            = done stream stream
-  check n (Done x _)        = drop n >> return (return x)
-  check n (Cont x Nothing)  = take n x
-  check n (Cont _ (Just e)) = drop n >> throwErr e
+  step s@(Chunk str)
+    | LL.null str       = return $ Cont (take n iter) Nothing
+    | LL.length str < n = liftM (flip Cont Nothing) inner
+      where inner = check (n - LL.length str) `liftM` runIter iter s
+  step (Chunk str) = done (Chunk s1) (Chunk s2)
+    where (s1, s2) = LL.splitAt n str
+  step str = done str str
+  check n' (Done x _)        = drop n' >> return (return x)
+  check n' (Cont x Nothing)  = take n' x
+  check n' (Cont _ (Just e)) = drop n' >> throwErr e
   done s1 s2 = liftM (flip Done s2) (runIter iter s1 >>= checkIfDone return)
 
 
@@ -491,23 +489,24 @@
 -- of processing of the outer stream once the processing of the inner stream
 -- finished early.
 takeR :: (SC.StreamChunk s el, Monad m) =>
-  Int ->
-  IterateeG s el m a ->
-  IterateeG s el m (IterateeG s el m a)
+  Int -> EnumeratorN s el s el m a
 takeR 0 iter = return iter
-takeR n iter = IterateeG (step n)
+takeR n iter = IterateeG step
   where
-  step n' s@(Chunk str)
+  step s@(Chunk str)
     | LL.null str        = return $ Cont (takeR n iter) Nothing
     | LL.length str <= n = runIter iter s >>= check (n - LL.length str)
     | otherwise          = done (Chunk str1) (Chunk str2)
-      where (str1, str2) = LL.splitAt n' str
-  step _n str            = done str str
-  check _n' (Done a str)   = return $ Done (return a) str
-  check n'  (Cont k mErr)  = return $ Cont (takeR n' k) mErr
+      where (str1, str2) = LL.splitAt n str
+  step str = done str str
+  check _ (Done a str)  = return $ Done (return a) str
+  check n' (Cont k mErr) = return $ Cont (takeR n' k) mErr
   done s1 s2 = liftM (flip Done s2) (runIter iter s1 >>= checkIfDone return)
 
+{-# SPECIALIZE takeR :: Int -> IterateeG [] el IO a -> IterateeG [] el IO (IterateeG [] el IO a) #-}
+{-# SPECIALIZE takeR :: Monad m => Int -> IterateeG [] el m a -> IterateeG [] el m (IterateeG [] el m a) #-}
 
+
 -- |Map the stream: yet another iteratee transformer
 -- Given the stream of elements of the type el and the function el->el',
 -- build a nested stream of elements of the type el' and apply the
@@ -517,11 +516,11 @@
 mapStream :: (SC.StreamChunk s el, SC.StreamChunk s el', Monad m) =>
  (el -> el')
   -> EnumeratorN s el s el' m a
-mapStream f i = IterateeG ((check <=< runIter i) . strMap (SC.cMap f))
+mapStream f i = step i
   where
-    go iter = IterateeG ((check <=< runIter iter) . strMap (SC.cMap f))
+    step iter = IterateeG ((check <=< runIter iter) . strMap (SC.cMap f))
     check (Done a _)    = return $ Done (return a) (Chunk LL.empty)
-    check (Cont k mErr) = return $ Cont (go k) mErr
+    check (Cont k mErr) = return $ Cont (step k) mErr
 
 -- |Map a stream without changing the element type.  For StreamChunks
 -- with limited element types (e.g. bytestrings)
@@ -529,11 +528,11 @@
 rigidMapStream :: (SC.StreamChunk s el, Monad m) =>
   (el -> el)
   -> EnumeratorN s el s el m a
-rigidMapStream f i =  go i
+rigidMapStream f i = step i
   where
-    go iter = IterateeG ((check <=< runIter iter) . strMap (LL.rigidMap f))
+    step iter = IterateeG ((check <=< runIter iter) . strMap (LL.rigidMap f))
     check (Done a _)    = return $ Done (return a) (Chunk LL.empty)
-    check (Cont k mErr) = return $ Cont (go k) mErr
+    check (Cont k mErr) = return $ Cont (step k) mErr
 
 -- |Yet another stream mapping function.  For container instances with
 -- class contexts, such as uvector or storablevector, this allows
@@ -545,11 +544,11 @@
     Monad m) =>
   (el -> el')
   -> EnumeratorN s el s el' m a
-looseMapStream f i =  go i
+looseMapStream f i = step i
   where
-    go iter = IterateeG ((check <=< runIter iter) . strMap (looseMap f))
+    step iter = IterateeG ((check <=< runIter iter) . strMap (looseMap f))
     check (Done a _)    = return $ Done (return a) (Chunk LL.empty)
-    check (Cont k mErr) = return $ Cont (go k) mErr
+    check (Cont x mErr) = return $ Cont (step x) mErr
 
 
 -- |Convert one stream into another, not necessarily in `lockstep'
diff --git a/src/Data/Iteratee/WrappedByteString.hs b/src/Data/Iteratee/WrappedByteString.hs
--- a/src/Data/Iteratee/WrappedByteString.hs
+++ b/src/Data/Iteratee/WrappedByteString.hs
@@ -90,6 +90,12 @@
   toList        = BC.unpack . unWrap
   rigidMap f    = WrapBS . BC.map f . unWrap
 
+instance LL.StringLike (WrappedByteString Char) where
+  toString = BC.unpack . unWrap
+  fromString = WrapBS . BC.pack
+  lines      = LL.fromList . map WrapBS . BC.lines . unWrap
+  words      = LL.fromList . map WrapBS . BC.words . unWrap
+
 instance SC.StreamChunk WrappedByteString Char where
   cMap          = bcmap
 
