diff --git a/Data/Attoparsec/Text.hs b/Data/Attoparsec/Text.hs
--- a/Data/Attoparsec/Text.hs
+++ b/Data/Attoparsec/Text.hs
@@ -15,6 +15,9 @@
     -- * Differences from Parsec
     -- $parsec
 
+    -- * Incremental input
+    -- $incremental
+
     -- * Performance considerations
     -- $performance
 
@@ -27,9 +30,10 @@
 
     -- * Running parsers
     , parse
-    , parseTest
-    , parseWith
     , feed
+    , I.parseOnly
+    , parseWith
+    , parseTest
 
     -- ** Result conversion
     , maybeResult
@@ -63,10 +67,15 @@
     , I.skipSpace
     , I.skipWhile
     , I.take
+    , I.scan
     , I.takeWhile
     , I.takeWhile1
     , I.takeTill
 
+    -- ** Consume all remaining input
+    , I.takeText
+    , I.takeLazyText
+
     -- * Text parsing
     , I.endOfLine
 
@@ -79,7 +88,7 @@
 
     -- * State observation and manipulation functions
     , I.endOfInput
-    , I.ensure
+    , I.atEnd
 
     -- * Applicative specializations
     -- $applicative
@@ -91,6 +100,7 @@
 import Data.Attoparsec.Combinator
 import qualified Data.Attoparsec.Text.Internal as I
 import qualified Data.Text as T
+import Data.Attoparsec.Text.Internal (Result(..), parse)
 
 -- $parsec
 --
@@ -107,12 +117,11 @@
 -- * Much of the performance advantage of @attoparsec-text@ is
 --   gained via high-performance parsers such as 'I.takeWhile'
 --   and 'I.string'.  If you use complicated combinators that
---   return lists of characters, there really isn't much
---   performance difference the two libraries.
+--   return lists of characters, there is less performance
+--   difference between the two libraries.
 --
 -- * Unlike Parsec 3, @attoparsec-text@ does not support being
---   used as a monad transformer.  This is mostly a matter of the
---   implementor not having needed that functionality.
+--   used as a monad transformer.
 --
 -- * @attoparsec-text@ is specialised to deal only with strict
 --   'T.Text' input.  Efficiency concernts rule out both lists
@@ -120,13 +129,39 @@
 --   allow consumption of very large input without a large
 --   footprint.  For this need, @attoparsec-text@'s incremental
 --   input provides an excellent substitute, with much more
---   control over when input takes place.
+--   control over when input takes place.  If you must use lazy
+--   texts, see the 'Lazy' module, which feeds lazy chunks to a
+--   regular parser.
 --
 -- * Parsec parsers can produce more helpful error messages than
 --   @attoparsec-text@ parsers.  This is a matter of focus:
 --   @attoparsec-text@ avoids the extra book-keeping in favour of
 --   higher performance.
 
+-- $incremental
+--
+-- @attoparsec-text@ supports incremental input, meaning that you
+-- can feed it a text that represents only part of the
+-- expected total amount of data to parse. If your parser reaches
+-- the end of a fragment of input and could consume more input,
+-- it will suspend parsing and return a 'Partial' continuation.
+--
+-- Supplying the 'Partial' continuation with another text will
+-- resume parsing at the point where it was suspended. You must be
+-- prepared for the result of the resumed parse to be another
+-- 'Partial' continuation.
+--
+-- To indicate that you have no more input, supply the 'Partial'
+-- continuation with an empty text.
+--
+-- Remember that some parsing combinators will not return a result
+-- until they reach the end of input.  They may thus cause 'Partial'
+-- results to be returned.
+--
+-- If you do not need support for incremental input, consider using
+-- the 'I.parseOnly' function to run your parser.  It will never
+-- prompt for more input.
+
 -- $performance
 --
 -- To actually achieve high performance, there are a few guidelines
@@ -166,57 +201,18 @@
 -- The 'Result' type is an instance of 'Functor', where 'fmap'
 -- transforms the value in a 'Done' result.
 
--- | The result of a parse.
-data Result r = Fail !T.Text [String] String
-              -- ^ The parse failed.  The 'T.Text' is the input
-              -- that had not yet been consumed when the failure
-              -- occurred.  The @[@'String'@]@ is a list of contexts
-              -- in which the error occurred.  The 'String' is the
-              -- message describing the error, if any.
-              | Partial (T.Text -> Result r)
-              -- ^ Supply this continuation with more input so that
-              -- the parser can resume.  To indicate that no more
-              -- input is available, use an 'T.empty' string.
-              | Done !T.Text r
-              -- ^ The parse succeeded.  The 'T.Text' is the
-              -- input that had not yet been consumed (if any) when
-              -- the parse succeeded.
-
-instance Show r => Show (Result r) where
-    show (Fail bs stk msg) =
-        "Fail " ++ show bs ++ " " ++ show stk ++ " " ++ show msg
-    show (Partial _)       = "Partial _"
-    show (Done bs r)       = "Done " ++ show bs ++ " " ++ show r
-
 -- | If a parser has returned a 'Partial' result, supply it with more
 -- input.
 feed :: Result r -> T.Text -> Result r
 feed f@(Fail _ _ _) _ = f
 feed (Partial k) d    = k d
 feed (Done bs r) d    = Done (T.append bs d) r
-
-fmapR :: (a -> b) -> Result a -> Result b
-fmapR _ (Fail st stk msg) = Fail st stk msg
-fmapR f (Partial k)       = Partial (fmapR f . k)
-fmapR f (Done bs r)       = Done bs (f r)
-
-instance Functor Result where
-    fmap = fmapR
+{-# INLINE feed #-}
 
 -- | Run a parser and print its result to standard output.
 parseTest :: (Show a) => I.Parser a -> T.Text -> IO ()
 parseTest p s = print (parse p s)
 
-translate :: I.Result a -> Result a
-translate (I.Fail st stk msg) = Fail (I.input st) stk msg
-translate (I.Partial k)       = Partial (translate . k)
-translate (I.Done st r)       = Done (I.input st) r
-
--- | Run a parser and return its result.
-parse :: I.Parser a -> T.Text -> Result a
-parse m s = translate (I.parse m s)
-{-# INLINE parse #-}
-
 -- | Run a parser with an initial input string, and a monadic action
 -- that can supply more input if needed.
 parseWith :: Monad m =>
@@ -228,10 +224,9 @@
           -> T.Text
           -- ^ Initial input for the parser.
           -> m (Result a)
-parseWith refill p s = step $ I.parse p s
-  where step (I.Fail st stk msg) = return $! Fail (I.input st) stk msg
-        step (I.Partial k)       = (step . k) =<< refill
-        step (I.Done st r)       = return $! Done (I.input st) r
+parseWith refill p s = step $ parse p s
+  where step (Partial k) = (step . k) =<< refill
+        step r           = return r
 
 -- | Convert a 'Result' value to a 'Maybe' value. A 'Partial' result
 -- is treated as failure.
diff --git a/Data/Attoparsec/Text/Internal.hs b/Data/Attoparsec/Text/Internal.hs
--- a/Data/Attoparsec/Text/Internal.hs
+++ b/Data/Attoparsec/Text/Internal.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE Rank2Types, RecordWildCards, FlexibleInstances #-}
+{-# LANGUAGE BangPatterns, Rank2Types, RecordWildCards, FlexibleInstances #-}
 -- |
 -- Module      :  Data.Attoparsec.Text.Internal
 -- Copyright   :  Felipe Lessa 2010-2011, Bryan O'Sullivan 2007-2010
@@ -16,10 +16,10 @@
     -- * Parser types
       Parser
     , Result(..)
-    , S(input)
 
     -- * Running parsers
     , parse
+    , parseOnly
 
     -- * Combinators
     , (<?>)
@@ -49,10 +49,15 @@
     , string
     , stringTransform
     , take
+    , scan
     , takeWhile
     , takeWhile1
     , takeTill
 
+    -- ** Consume all remaining input
+    , takeText
+    , takeLazyText
+
     -- * Numeric parsers
     , decimal
     , hexadecimal
@@ -62,6 +67,7 @@
 
     -- * State observation and manipulation functions
     , endOfInput
+    , atEnd
     , ensure
 
     -- * Utilities
@@ -78,21 +84,51 @@
 import Data.String (IsString(..))
 import Prelude hiding (getChar, take, takeWhile)
 import qualified Data.Text as T
+import qualified Data.Text.Lazy as TL
 
-data Result r = Fail S [String] String
+-- | The result of a parse.
+data Result r = Fail T.Text [String] String
+              -- ^ The parse failed.  The 'T.Text' is the input
+              -- that had not yet been consumed when the failure
+              -- occurred.  The @[@'String'@]@ is a list of contexts
+              -- in which the error occurred.  The 'String' is the
+              -- message describing the error, if any.
               | Partial (T.Text -> Result r)
-              | Done S r
+              -- ^ Supply this continuation with more input so that
+              -- the parser can resume.  To indicate that no more
+              -- input is available, use an 'T.empty' string.
+              | Done T.Text r
+              -- ^ The parse succeeded.  The 'T.Text' is the
+              -- input that had not yet been consumed (if any) when
+              -- the parse succeeded.
 
+instance Show r => Show (Result r) where
+    show (Fail bs stk msg) =
+        "Fail " ++ show bs ++ " " ++ show stk ++ " " ++ show msg
+    show (Partial _)       = "Partial _"
+    show (Done bs r)       = "Done " ++ show bs ++ " " ++ show r
+
+fmapR :: (a -> b) -> Result a -> Result b
+fmapR _ (Fail st stk msg) = Fail st stk msg
+fmapR f (Partial k)       = Partial (fmapR f . k)
+fmapR f (Done bs r)       = Done bs (f r)
+
+instance Functor Result where
+    fmap = fmapR
+
+newtype Input = I {unI :: T.Text}
+newtype Added = A {unA :: T.Text}
+
 -- | The 'Parser' type is a monad.
 newtype Parser a = Parser {
-      runParser :: forall r. S
+      runParser :: forall r. Input -> Added -> More
                 -> Failure   r
                 -> Success a r
                 -> Result r
     }
 
-type Failure   r = S -> [String] -> String -> Result r
-type Success a r = S -> a -> Result r
+type Failure   r = Input -> Added -> More -> [String] -> String -> Result r
+type Success a r = Input -> Added -> More -> a -> Result r
 
 instance IsString (Parser T.Text) where
     fromString = string . T.pack
@@ -101,42 +137,28 @@
 data More = Complete | Incomplete
             deriving (Eq, Show)
 
-plusMore :: More -> More -> More
-plusMore Complete _ = Complete
-plusMore _ Complete = Complete
-plusMore _ _        = Incomplete
-{-# INLINE plusMore #-}
-
-instance Monoid More where
-    mempty  = Incomplete
-    mappend = plusMore
-
-data S = S {
-      input  :: !T.Text
-    , _added :: !T.Text
-    , more  :: !More
-    } deriving (Show)
-
-instance Show r => Show (Result r) where
-    show (Fail _ stack msg) = "Fail " ++ show stack ++ " " ++ show msg
-    show (Partial _) = "Partial _"
-    show (Done bs r) = "Done " ++ show bs ++ " " ++ show r
-
-addS :: S -> S -> S
-addS (S s0 a0 c0) (S _s1 a1 c1) = S (s0 +++ a1) (a0 +++ a1) (mappend c0 c1)
+addS :: Input -> Added -> More
+     -> Input -> Added -> More
+     -> (Input -> Added -> More -> r) -> r
+addS i0 a0 m0 _i1 a1 m1 f =
+    let !i = I (unI i0 +++ unA a1)
+        a  = A (unA a0 +++ unA a1)
+        !m = m0 <> m1
+    in f i a m
+  where
+    Complete <> _ = Complete
+    _ <> Complete = Complete
+    _ <> _        = Incomplete
 {-# INLINE addS #-}
 
-instance Monoid S where
-    mempty  = S T.empty T.empty Incomplete
-    mappend = addS
-
 bindP :: Parser a -> (a -> Parser b) -> Parser b
 bindP m g =
-    Parser (\st0 kf ks -> runParser m st0 kf (\s a -> runParser (g a) s kf ks))
+    Parser $ \i0 a0 m0 kf ks -> runParser m i0 a0 m0 kf $
+                                \i1 a1 m1 a -> runParser (g a) i1 a1 m1 kf ks
 {-# INLINE bindP #-}
 
 returnP :: a -> Parser a
-returnP a = Parser (\st0 _kf ks -> ks st0 a)
+returnP a = Parser (\i0 a0 m0 _kf ks -> ks i0 a0 m0 a)
 {-# INLINE returnP #-}
 
 instance Monad Parser where
@@ -144,23 +166,26 @@
     (>>=)  = bindP
     fail   = failDesc
 
-noAdds :: S -> S
-noAdds (S s0 _a0 c0) = S s0 T.empty c0
+noAdds :: Input -> Added -> More
+       -> (Input -> Added -> More -> r) -> r
+noAdds i0 _a0 m0 f = f i0 (A T.empty) m0
 {-# INLINE noAdds #-}
 
 plus :: Parser a -> Parser a -> Parser a
-plus a b = Parser $ \st0 kf ks ->
-           let kf' st1 _ _ = runParser b (mappend st0 st1) kf ks
-               !st2 = noAdds st0
-           in  runParser a st2 kf' ks
+plus a b = Parser $ \i0 a0 m0 kf ks ->
+           let kf' i1 a1 m1 _ _ = addS i0 a0 m0 i1 a1 m1 $
+                                  \ i2 a2 m2 -> runParser b i2 a2 m2 kf ks
+           in  noAdds i0 a0 m0 $ \i2 a2 m2 -> runParser a i2 a2 m2 kf' ks
 {-# INLINE plus #-}
 
 instance MonadPlus Parser where
     mzero = failDesc "mzero"
+    {-# INLINE mzero #-}
     mplus = plus
 
 fmapP :: (a -> b) -> Parser a -> Parser b
-fmapP p m = Parser (\st0 f k -> runParser m st0 f (\s a -> k s (p a)))
+fmapP p m = Parser $ \i0 a0 m0 f k ->
+            runParser m i0 a0 m0 f $ \i1 a1 s1 a -> k i1 a1 s1 (p a)
 {-# INLINE fmapP #-}
 
 instance Functor Parser where
@@ -183,53 +208,67 @@
     (*>)   = (>>)
     x <* y = x >>= \a -> y >> return a
 
+instance Monoid (Parser a) where
+    mempty  = failDesc "mempty"
+    {-# INLINE mempty #-}
+    mappend = plus
+
 instance Alternative Parser where
     empty = failDesc "empty"
+    {-# INLINE empty #-}
     (<|>) = plus
 
 failDesc :: String -> Parser a
-failDesc err = Parser (\st0 kf _ks -> kf st0 [] msg)
+failDesc err = Parser (\i0 a0 m0 kf _ks -> kf i0 a0 m0 [] msg)
     where msg = "Failed reading: " ++ err
 {-# INLINE failDesc #-}
 
--- | Succeed only if at least @n@ characters of input are available.
-ensure :: Int -> Parser ()
-ensure n = Parser $ \st0@(S s0 _a0 _c0) kf ks ->
-    if T.length s0 >= n
-    then ks st0 ()
-    else runParser (demandInput >> ensure n) st0 kf ks
+-- | If at least @n@ bytes of input are available, return the current
+-- input, otherwise fail.
+ensure :: Int -> Parser T.Text
+ensure !n = Parser $ \i0 a0 m0 kf ks ->
+    if T.length (unI i0) >= n
+    then ks i0 a0 m0 (unI i0)
+    else runParser (demandInput >> ensure n) i0 a0 m0 kf ks
 
 -- | Ask for input.  If we receive any, pass it to a success
 -- continuation, otherwise to a failure continuation.
-prompt :: S -> (S -> Result r) -> (S -> Result r) -> Result r
-prompt (S s0 a0 _c0) kf ks = Partial $ \s ->
+prompt :: Input -> Added -> More
+       -> (Input -> Added -> More -> Result r)
+       -> (Input -> Added -> More -> Result r)
+       -> Result r
+prompt i0 a0 _m0 kf ks = Partial $ \s ->
     if T.null s
-    then kf $! S s0 a0 Complete
-    else ks $! S (s0 +++ s) (a0 +++ s) Incomplete
+    then kf i0 a0 Complete
+    else ks (I (unI i0 +++ s)) (A (unA a0 +++ s)) Incomplete
 
 -- | Immediately demand more input via a 'Partial' continuation
 -- result.
 demandInput :: Parser ()
-demandInput = Parser $ \st0 kf ks ->
-    if more st0 == Complete
-    then kf st0 ["demandInput"] "not enough characters"
-    else prompt st0 (\st -> kf st ["demandInput"] "not enough characters") (`ks` ())
+demandInput = Parser $ \i0 a0 m0 kf ks ->
+    if m0 == Complete
+    then kf i0 a0 m0 ["demandInput"] "not enough characters"
+    else let kf' i a m = kf i a m ["demandInput"] "not enough characters"
+             ks' i a m = ks i a m ()
+         in prompt i0 a0 m0 kf' ks'
 
 -- | This parser always succeeds.  It returns 'True' if any input is
 -- available either immediately or on demand, and 'False' if the end
 -- of all input has been reached.
 wantInput :: Parser Bool
-wantInput = Parser $ \st0@(S s0 _a0 c0) _kf ks ->
+wantInput = Parser $ \i0 a0 m0 _kf ks ->
   case () of
-    _ | not (T.null s0) -> ks st0 True
-      | c0 == Complete  -> ks st0 False
-      | otherwise       -> prompt st0 (`ks` False) (`ks` True)
+    _ | not (T.null (unI i0)) -> ks i0 a0 m0 True
+      | m0 == Complete        -> ks i0 a0 m0 False
+      | otherwise             -> let kf' i a m = ks i a m False
+                                     ks' i a m = ks i a m True
+                                 in prompt i0 a0 m0 kf' ks'
 
 get :: Parser T.Text
-get  = Parser (\st0 _kf ks -> ks st0 (input st0))
+get  = Parser $ \i0 a0 m0 _kf ks -> ks i0 a0 m0 (unI i0)
 
 put :: T.Text -> Parser ()
-put s = Parser (\(S _s0 a0 c0) _kf ks -> ks (S s a0 c0) ())
+put s = Parser $ \_i0 a0 m0 _kf ks -> ks (I s) a0 m0 ()
 
 (+++) :: T.Text -> T.Text -> T.Text
 (+++) = T.append
@@ -243,8 +282,10 @@
 -- lookahead.  The downside to using this combinator is that it can
 -- retain input for longer than is desirable.
 try :: Parser a -> Parser a
-try p = Parser $ \st0 kf ks ->
-        runParser p (noAdds st0) (kf . mappend st0) ks
+try p = Parser $ \i0 a0 m0 kf ks ->
+        noAdds i0 a0 m0 $ \i1 a1 m1 ->
+            let kf' i2 a2 m2 = addS i0 a0 m0 i2 a2 m2 kf
+            in runParser p i1 a1 m1 kf' ks
 
 -- | The parser @satisfy p@ succeeds for any character for which
 -- the predicate @p@ returns 'True'. Returns the character that
@@ -254,8 +295,7 @@
 -- >digit = satisfy isDigit
 satisfy :: (Char -> Bool) -> Parser Char
 satisfy p = do
-  ensure 1
-  s <- get
+  s <- ensure 1
   case T.uncons s of
     Just (h,t) | p h       -> put t >> return h
                | otherwise -> fail "satisfy"
@@ -268,8 +308,7 @@
 -- >digit = satisfy isDigit
 skip :: (Char -> Bool) -> Parser ()
 skip p = do
-  ensure 1
-  s <- get
+  s <- ensure 1
   case T.uncons s of
     Just (h,t) | p h       -> put t
                | otherwise -> fail "skip"
@@ -282,8 +321,7 @@
 -- character that was parsed.
 satisfyWith :: (Char -> a) -> (a -> Bool) -> Parser a
 satisfyWith f p = do
-  ensure 1
-  s <- get
+  s <- ensure 1
   let Just (h,t) = T.uncons s
       c = f h
   if p c
@@ -309,8 +347,7 @@
 -- predicate returns 'True'.
 takeWith :: Int -> (T.Text -> Bool) -> Parser T.Text
 takeWith n p = do
-  ensure n
-  s <- get
+  s <- ensure n
   let (h,t) = T.splitAt n s
   if p h
     then put t >> return h
@@ -352,11 +389,12 @@
 skipWhile p = go
  where
   go = do
-    input <- wantInput
-    when input $ do
-      t <- T.dropWhile p <$> get
-      put t
-      when (T.null t) go
+    t <- T.dropWhile p <$> get
+    put t
+    when (T.null t) $ do
+      input <- wantInput
+      when input go
+{-# INLINE skipWhile #-}
 
 -- | Skip over white space.
 skipSpace :: Parser ()
@@ -386,26 +424,80 @@
 -- combinators such as 'many', because such parsers loop until a
 -- failure occurs.  Careless use will thus result in an infinite loop.
 takeWhile :: (Char -> Bool) -> Parser T.Text
-takeWhile p = go []
+takeWhile p = (T.concat . reverse) `fmap` go []
  where
   go acc = do
-    input <- wantInput
-    if input
-      then do
 #if MIN_VERSION_text(0,11,0)
-        (h,t) <- T.span p <$> get
+    (h,t) <- T.span p <$> get
 #else
-        (h,t) <- T.spanBy p <$> get
+    (h,t) <- T.spanBy p <$> get
 #endif
-        put t
-        if T.null t
+    put t
+    if T.null t
+      then do
+        input <- wantInput
+        if input
           then go (h:acc)
-          else return $ if null acc then h else T.concat $ reverse (h:acc)
-      else return $ case acc of
-                      []  -> T.empty
-                      [x] -> x
-                      _   -> T.concat $ reverse acc
+          else return (h:acc)
+      else return (h:acc)
 
+takeRest :: Parser [T.Text]
+takeRest = go []
+ where
+  go acc = do
+    input <- wantInput
+    if input
+      then do
+        s <- get
+        put T.empty
+        go (s:acc)
+      else return (reverse acc)
+
+-- | Consume all remaining input and return it as a single string.
+takeText :: Parser T.Text
+takeText = T.concat `fmap` takeRest
+
+-- | Consume all remaining input and return it as a single string.
+takeLazyText :: Parser TL.Text
+takeLazyText = TL.fromChunks `fmap` takeRest
+
+-- | A stateful scanner.  The predicate consumes and transforms a
+-- state argument, and each transformed state is passed to successive
+-- invocations of the predicate on each character of the input until one
+-- returns 'Nothing' or the input ends.
+--
+-- This parser does not fail.  It will return an empty string if the
+-- predicate returns 'Nothing' on the first character of input.
+--
+-- /Note/: Because this parser does not fail, do not use it with
+-- combinators such as 'many', because such parsers loop until a
+-- failure occurs.  Careless use will thus result in an infinite loop.
+scan :: s -> (s -> Char -> Maybe s) -> Parser T.Text
+scan s0 p = do
+  chunks <- go [] s0
+  case chunks of
+    [x] -> return x
+    xs  -> return . T.concat . reverse $ xs
+ where
+  scanner s !n t =
+    case T.uncons t of
+      Nothing     -> Continue s
+      Just (c,t') -> case p s c of
+                       Just s' -> scanner s' (n+1) t'
+                       Nothing -> Finished n t
+  go acc s = do
+    input <- get
+    case scanner s 0 input of
+      Continue s'  -> do put T.empty
+                         more <- wantInput
+                         if more
+                           then go (input : acc) s'
+                           else return (input : acc)
+      Finished n t -> put t >> return (T.take n input : acc)
+{-# INLINE scan #-}
+
+data ScannnerResult s = Continue s | Finished !Int !T.Text
+
 -- | Consume input as long as the predicate returns 'True', and return
 -- the consumed input.
 --
@@ -576,15 +668,24 @@
 
 -- | Match only if all input has been consumed.
 endOfInput :: Parser ()
-endOfInput = Parser $ \st0@S{..} kf ks ->
-             if T.null input
-             then if more == Complete
-                  then ks st0 ()
-                  else let kf' st1 _ _ = ks (mappend st0 st1) ()
-                           ks' st1 _   = kf (mappend st0 st1) [] "endOfInput"
-                       in  runParser demandInput st0 kf' ks'
-             else kf st0 [] "endOfInput"
+endOfInput = Parser $ \i0 a0 m0 kf ks ->
+             if T.null (unI i0)
+             then if m0 == Complete
+                  then ks i0 a0 m0 ()
+                  else let kf' i1 a1 m1 _ _ = addS i0 a0 m0 i1 a1 m1 $
+                                              \ i2 a2 m2 -> ks i2 a2 m2 ()
+                           ks' i1 a1 m1 _   = addS i0 a0 m0 i1 a1 m1 $
+                                              \ i2 a2 m2 -> kf i2 a2 m2 []
+                                                            "endOfInput"
+                       in  runParser demandInput i0 a0 m0 kf' ks'
+             else kf i0 a0 m0 [] "endOfInput"
 
+-- | Return an indication of whether the end of input has been
+-- reached.
+atEnd :: Parser Bool
+atEnd = not <$> wantInput
+{-# INLINE atEnd #-}
+
 -- | Match either a single newline character @\'\\n\'@, or a carriage
 -- return followed by a newline character @\"\\r\\n\"@.
 endOfLine :: Parser ()
@@ -594,19 +695,31 @@
 (<?>) :: Parser a
       -> String                 -- ^ the name to use if parsing fails
       -> Parser a
-p <?> msg = Parser $ \s kf ks -> runParser p s (\s' strs m -> kf s' (msg:strs) m) ks
+p <?> msg0 = Parser $ \i0 a0 m0 kf ks ->
+             let kf' i a m strs msg = kf i a m (msg0:strs) msg
+             in runParser p i0 a0 m0 kf' ks
 {-# INLINE (<?>) #-}
 infix 0 <?>
 
 -- | Terminal failure continuation.
 failK :: Failure a
-failK st0 stack msg = Fail st0 stack msg
+failK i0 _a0 _m0 stack msg = Fail (unI i0) stack msg
+{-# INLINE failK #-}
 
 -- | Terminal success continuation.
 successK :: Success a a
-successK state a = Done state a
+successK i0 _a0 _m0 a = Done (unI i0) a
+{-# INLINE successK #-}
 
 -- | Run a parser.
 parse :: Parser a -> T.Text -> Result a
-parse m s = runParser m (S s T.empty Incomplete) failK successK
+parse m s = runParser m (I s) (A T.empty) Incomplete failK successK
 {-# INLINE parse #-}
+
+-- | Run a parser that cannot be resupplied via a 'Partial' result.
+parseOnly :: Parser a -> T.Text -> Either String a
+parseOnly m s = case runParser m (I s) (A T.empty) Complete failK successK of
+                  Fail _ _ err -> Left err
+                  Done _ a     -> Right a
+                  _            -> error "parseOnly: impossible error!"
+{-# INLINE parseOnly #-}
diff --git a/attoparsec-text.cabal b/attoparsec-text.cabal
--- a/attoparsec-text.cabal
+++ b/attoparsec-text.cabal
@@ -1,5 +1,5 @@
 name:            attoparsec-text
-version:         0.8.2.1
+version:         0.8.5.0
 license:         BSD3
 license-file:    LICENSE
 category:        Text, Parsing
@@ -10,7 +10,6 @@
 synopsis:        Fast combinator parsing for texts
 cabal-version:   >= 1.6
 homepage:        http://patch-tag.com/r/felipe/attoparsec-text/home
--- bug-reports:     http://bitbucket.org/bos/attoparsec/issues
 build-type:      Simple
 description:
     A fast parser combinator library, aimed particularly at dealing
@@ -20,6 +19,10 @@
     This library is basically a translation of the original
     attoparsec library to use text instead of bytestrings.
     .
+    Changes in version 0.8.5.0:
+    .
+    * Ported changes from attoparsec 0.8.5.0.
+    .
     Changes in version 0.8.2.1:
     .
     * Permit newer version of containers for GHC 7.0.
@@ -49,6 +52,10 @@
 --    examples/RFC2616.hs
 --    examples/TestRFC2616.hs
 --    examples/rfc2616.c
+
+source-repository head
+  type: darcs
+  location: http://patch-tag.com/r/felipe/attoparsec-text
 
 library
   build-depends: base       >= 3       && < 5,
diff --git a/benchmarks/Double.hs b/benchmarks/Double.hs
--- a/benchmarks/Double.hs
+++ b/benchmarks/Double.hs
@@ -3,12 +3,25 @@
 import Data.Char (isDigit, isLetter)
 import Data.List (foldl')
 import System.Environment (getArgs)
+import qualified Data.Attoparsec.Char8 as AB
 import qualified Data.Attoparsec.Text as A
+import qualified Data.ByteString.Char8 as B
 import qualified Data.Text as T
 import qualified Data.Text.IO as T
 import qualified Data.Text.Read as TR
 import qualified Text.ParserCombinators.Parsec as P
 
+attoparsec_builtin args = do
+  forM_ args $ \arg -> do
+    input <- B.readFile arg
+    case AB.parse (AB.many1 (AB.char '#' >> p)) input `AB.feed` B.empty of
+      AB.Done _ xs -> print (sum xs :: Double)
+      what        -> print what
+ where
+  p = AB.double
+
+----------------------------------------------------------------------
+
 attoparsec_text_builtin args = do
   forM_ args $ \arg -> do
     input <- T.readFile arg
@@ -85,6 +98,7 @@
 main = do
   args <- getArgs
   case args of
+    ("attoparsec_builtin":xs) -> attoparsec_builtin xs
     ("attoparsec_text_builtin":xs) -> attoparsec_text_builtin xs
     ("attoparsec_text_laforge":xs) -> attoparsec_text_laforge xs
     ("attoparsec_text_laforge_discarding":xs) -> attoparsec_text_laforge_discarding xs
