diff --git a/Data/Monoid/Cancellative.hs b/Data/Monoid/Cancellative.hs
deleted file mode 100644
--- a/Data/Monoid/Cancellative.hs
+++ /dev/null
@@ -1,132 +0,0 @@
-{- 
-    Copyright 2011 Mario Blazevic
-
-    This file is part of the Streaming Component Combinators (SCC) project.
-
-    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
-    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
-    version.
-
-    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along with SCC.  If not, see
-    <http://www.gnu.org/licenses/>.
--}
-
--- | This module defines the 'Monoid' => 'CancellativeMonoid' => 'GCDMonoid' class hierarchy.
--- 
-
-module Data.Monoid.Cancellative (
-   -- * Classes
-   CancellativeMonoid, GCDMonoid,
-   LeftCancellativeMonoid(..), RightCancellativeMonoid(..),
-   LeftGCDMonoid(..), RightGCDMonoid(..)
-   ) where
-
-import Data.Monoid (Monoid (mappend))
-import qualified Data.List as List
-import qualified Data.ByteString as ByteString
-import qualified Data.Text as Text
-import Data.ByteString (ByteString)
-import Data.Text (Text)
-
--- | Class of monoids with a left inverse of 'mappend', satisfying the following law:
--- 
--- > mstripPrefix a (a `mappend` b) == Just b
--- > maybe b (a `mappend`) (mstripPrefix a b) == b
-class Monoid m => LeftCancellativeMonoid m where
-   mstripPrefix :: m -> m -> Maybe m
-
--- | Class of monoids with a right inverse of 'mappend', satisfying the following law:
--- 
--- > mstripSuffix b (a `mappend` b) == Just a
--- > maybe b (`mappend` a) (mstripSuffix a b) == b
-class Monoid m => RightCancellativeMonoid m where
-   mstripSuffix :: m -> m -> Maybe m
-
-class LeftCancellativeMonoid m => LeftGCDMonoid m where
-   commonPrefix :: m -> m -> m
-
-class RightCancellativeMonoid m => RightGCDMonoid m where
-   commonSuffix :: m -> m -> m
-
--- | Class of monoids for which the 'mappend' operation can be reverted while satisfying the following laws:
--- 
--- > mstripPrefix a (a `mappend` b) == Just b
--- > mstripSuffix b (a `mappend` b) == Just a
--- > maybe b (a `mappend`) (mstripPrefix a b) == b
--- > maybe b (`mappend` a) (mstripSuffix a b) == b
-class (LeftCancellativeMonoid m, RightCancellativeMonoid m) => CancellativeMonoid m
-
--- | Class of monoids that allow the greatest common denominator to be found for any two given values. The operations
--- must satisfy the following laws:
--- 
--- > commonPrefix (a `mappend` b) (a `mappend` c) == a `mappend` commonPrefix b c
--- > commonSuffix (a `mappend` c) (b `mappend` c) == commonSuffix a b `mappend` c
-class (CancellativeMonoid m, LeftGCDMonoid m, RightGCDMonoid m) => GCDMonoid m
-
--- List instances
-
-instance Eq x => LeftCancellativeMonoid [x] where
-   mstripPrefix = List.stripPrefix
-
-instance Eq x => LeftGCDMonoid [x] where
-   commonPrefix (x:xs) (y:ys) | x == y = x : commonPrefix xs ys
-   commonPrefix _ _ = []
-
-instance Eq x => RightCancellativeMonoid [x] where
-   mstripSuffix s l = fmap List.reverse (mstripPrefix (List.reverse s) (List.reverse l))
-
-instance Eq x => RightGCDMonoid [x] where
-   commonSuffix xs ys = List.reverse (commonPrefix (List.reverse xs) (List.reverse ys))
-
-instance Eq x => CancellativeMonoid [x]
-
-instance Eq x => GCDMonoid [x]
-
--- ByteString instances
-
-instance LeftCancellativeMonoid ByteString where
-   mstripPrefix p l = if ByteString.isPrefixOf p l
-                      then Just (ByteString.drop (ByteString.length p) l)
-                      else Nothing
-
-instance RightCancellativeMonoid ByteString where
-   mstripSuffix s l = if ByteString.isSuffixOf s l
-                      then Just (ByteString.take (ByteString.length l - ByteString.length s) l)
-                      else Nothing
-
-instance CancellativeMonoid ByteString
-
-instance LeftGCDMonoid ByteString where
-   commonPrefix x y = ByteString.take maxPrefixLength x
-      where maxPrefixLength = prefixLength 0
-            prefixLength n | ByteString.index x 0 == ByteString.index y 0 = prefixLength (succ n) 
-            prefixLength n = n
-
-instance RightGCDMonoid ByteString where
-   commonSuffix x y = ByteString.drop minNonSuffixLength x
-      where minNonSuffixLength = nonSuffixLength (ByteString.length x - 1) (ByteString.length y - 1)
-            nonSuffixLength m n | ByteString.index x m == ByteString.index y n = nonSuffixLength (pred m) (pred n) 
-            nonSuffixLength m n = m + 1
-
-instance GCDMonoid ByteString
-
--- Text instances
-
-instance LeftCancellativeMonoid Text where
-   mstripPrefix p t = Text.stripPrefix p t
-
-instance RightCancellativeMonoid Text where
-   mstripSuffix s t = Text.stripSuffix s t
-
-instance CancellativeMonoid Text
-
-instance LeftGCDMonoid Text where
-   commonPrefix x y = maybe Text.empty (\(p, _, _)-> p) (Text.commonPrefixes x y)
-
-instance RightGCDMonoid Text where
-   commonSuffix x y = Text.reverse $ commonPrefix (Text.reverse x) (Text.reverse y)
-
-instance GCDMonoid Text
diff --git a/Data/Monoid/Factorial.hs b/Data/Monoid/Factorial.hs
deleted file mode 100644
--- a/Data/Monoid/Factorial.hs
+++ /dev/null
@@ -1,152 +0,0 @@
-{- 
-    Copyright 2011 Mario Blazevic
-
-    This file is part of the Streaming Component Combinators (SCC) project.
-
-    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
-    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
-    version.
-
-    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along with SCC.  If not, see
-    <http://www.gnu.org/licenses/>.
--}
-
--- | This module defines the 'FactorialMonoid' class.
--- 
-
-module Data.Monoid.Factorial (
-   -- * Classes
-   FactorialMonoid(..),
-   -- * Functions
-   mbreak, mlength, mmap, mreverse, mtakeWhile, mdropWhile
-   )
-where
-
-import Data.Monoid (Monoid (..))
-import qualified Data.List as List
-import qualified Data.ByteString as ByteString
-import qualified Data.Text as Text
-import Data.ByteString (ByteString)
-import Data.Text (Text)
-
--- | Class of monoids that can be split into irreducible factors, /i.e./, atoms or primes. The methods of this class
--- satisfy the following laws:
--- 
--- > mconcat . factors == id
--- > factors mempty == []
--- > all (\f-> factors f == [f]) (factors m)
--- > factors == unfoldr splitPrimePrefix == reverse . unfoldr (fmap swap . splitPrimeSuffix)
--- > primePrefix == maybe mempty fst . splitPrimePrefix
--- > primeSuffix == maybe mempty snd . splitPrimeSuffix
--- > mfoldl f f0 == foldl f f0 . factors
--- > mfoldr f f0 == foldr f f0 . factors
--- > mspan p m == (mconcat l, mconcat r) where (l, r) = span p (factors m)
--- 
--- A minimal instance definition must implement 'factors' or 'splitPrimePrefix'.
-class Monoid m => FactorialMonoid m where
-   -- | Returns a list of all prime factors; inverse of mconcat.
-   factors :: m -> [m]
-   -- | The prime prefix, 'mempty' if none.
-   primePrefix :: m -> m
-   -- | The prime suffix, 'mempty' if none.
-   primeSuffix :: m -> m
-   -- | Splits the argument into its prime prefix and the remaining suffix. Returns 'Nothing' for 'mempty'.
-   splitPrimePrefix :: m -> Maybe (m, m)
-   -- | Splits the argument into its prime suffix and the remaining prefix. Returns 'Nothing' for 'mempty'.
-   splitPrimeSuffix :: m -> Maybe (m, m)
-   -- | Like 'foldl' on the list of primes.
-   mfoldl :: (a -> m -> a) -> a -> m -> a
-   -- | Like 'foldr' on the list of primes.
-   mfoldr :: (m -> a -> a) -> a -> m -> a
-   -- | Like 'span' on the list of primes.
-   mspan :: (m -> Bool) -> m -> (m, m)
-
-   factors = List.unfoldr splitPrimePrefix
-   primePrefix = maybe mempty fst . splitPrimePrefix
-   primeSuffix = maybe mempty snd . splitPrimeSuffix
-   splitPrimePrefix x = case factors x
-                        of [] -> Nothing
-                           prefix : rest -> Just (prefix, mconcat rest)
-   splitPrimeSuffix x = case factors x
-                        of [] -> Nothing
-                           fs -> Just (mconcat (List.init fs), List.last fs)
-   mfoldl f f0 = List.foldl f f0 . factors
-   mfoldr f f0 = List.foldr f f0 . factors
-   mspan p = mfoldr f (mempty, mempty)
-      where f s (prefix, suffix) = if p s 
-                                   then (mappend s prefix, suffix) 
-                                   else (mempty, mappend s (mappend prefix suffix))
-
-instance FactorialMonoid [x] where
-   factors xs = List.map (:[]) xs
-   primePrefix [] = []
-   primePrefix (x:xs) = [x]
-   primeSuffix [] = []
-   primeSuffix xs = [List.last xs]
-   splitPrimePrefix [] = Nothing
-   splitPrimePrefix (x:xs) = Just ([x], xs)
-   splitPrimeSuffix [] = Nothing
-   splitPrimeSuffix xs = Just (split id xs)
-      where split f last@[x] = (f [], last)
-            split f (x:xs) = split (f . (x:)) xs
-   mfoldl _ acc [] = acc
-   mfoldl f acc (x:xs) = mfoldl f (f acc [x]) xs
-   mfoldr _ f0 [] = f0
-   mfoldr f f0 (x:xs) = f [x] (mfoldr f f0 xs)
-   mspan f = List.span (f . (:[]))
-
-instance FactorialMonoid ByteString where
-   factors x = factorize (ByteString.length x) x
-      where factorize 0 xs = []
-            factorize n xs = x : factorize (pred n) xs'
-              where (x, xs') = ByteString.splitAt 1 xs
-   primePrefix = ByteString.take 1
-   primeSuffix x = ByteString.drop (ByteString.length x - 1) x
-   splitPrimePrefix x = if ByteString.null x then Nothing else Just (ByteString.splitAt 1 x)
-   splitPrimeSuffix x = if ByteString.null x then Nothing else Just (ByteString.splitAt (ByteString.length x - 1) x)
-   mfoldl f = ByteString.foldl f'
-      where f' a byte = f a (ByteString.singleton byte)
-   mfoldr f = ByteString.foldr f'
-      where f' byte a = f (ByteString.singleton byte) a
-   mspan f x = ByteString.splitAt (findIndex 0 x) x
-      where findIndex i x | ByteString.null x = i
-            findIndex i x = if f (ByteString.take 1 x) then findIndex (succ i) (ByteString.drop 1 x) else i
-
-instance FactorialMonoid Text where
-   factors = Text.chunksOf 1
-   primePrefix = Text.take 1
-   primeSuffix x = if Text.null x then Text.empty else Text.singleton (Text.last x)
-   splitPrimePrefix x = if Text.null x then Nothing else Just (Text.splitAt 1 x)
-   splitPrimeSuffix x = if Text.null x then Nothing else Just (Text.splitAt (Text.length x - 1) x)
-   mfoldl f = Text.foldl f'
-      where f' a char = f a (Text.singleton char)
-   mfoldr f = Text.foldr f'
-      where f' char a = f (Text.singleton char) a
-   mspan f = Text.span (f . Text.singleton)
-
--- | A 'List.break' equivalent.
-mbreak :: FactorialMonoid m => (m -> Bool) -> m -> (m, m)
-mbreak = mspan . (not .)
-
--- | A 'List.length' equivalent.
-mlength :: FactorialMonoid m => m -> Int
-mlength = List.length . factors
-
--- | A 'List.map' equivalent.
-mmap :: FactorialMonoid m => (m -> m) -> m -> m
-mmap f = mconcat . List.map f . factors
-
--- | A 'List.reverse' equivalent.
-mreverse :: FactorialMonoid m => m -> m
-mreverse = mconcat . List.reverse . factors
-
--- | A 'List.takeWhile' equivalent.
-mtakeWhile :: FactorialMonoid m => (m -> Bool) -> m -> m
-mtakeWhile p = fst . mspan p
-
--- | A 'List.dropWhile' equivalent.
-mdropWhile :: FactorialMonoid m => (m -> Bool) -> m -> m
-mdropWhile p = snd . mspan p
diff --git a/Data/Monoid/Null.hs b/Data/Monoid/Null.hs
deleted file mode 100644
--- a/Data/Monoid/Null.hs
+++ /dev/null
@@ -1,61 +0,0 @@
-{- 
-    Copyright 2011 Mario Blazevic
-
-    This file is part of the Streaming Component Combinators (SCC) project.
-
-    The SCC project is free software: you can redistribute it and/or modify it under the terms of the GNU General Public
-    License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later
-    version.
-
-    SCC is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
-    of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
-
-    You should have received a copy of the GNU General Public License along with SCC.  If not, see
-    <http://www.gnu.org/licenses/>.
--}
-
--- | This module defines the MonoidNull class.
--- 
-
-module Data.Monoid.Null (
-   -- * Classes
-   MonoidNull(..)
-   )
-where
-   
-import Data.Monoid (Monoid(mempty), First(..), Last(..))
-import qualified Data.List as List
-import qualified Data.ByteString as ByteString
-import qualified Data.Text as Text
-import Data.ByteString (ByteString)
-import Data.Text (Text)
-   
--- | Extension of 'Monoid' that allows testing a value for equality with 'mempty'. The following law must hold:
--- 
--- > mnull == (== mempty)
-class Monoid m => MonoidNull m where
-   mnull :: m -> Bool
-
-instance MonoidNull [x] where
-   mnull = List.null
-
-instance MonoidNull ByteString where
-   mnull = ByteString.null
-
-instance MonoidNull Text where
-   mnull = Text.null
-
-instance (MonoidNull a, MonoidNull b) => MonoidNull (a, b) where
-   mnull (a, b) = mnull a && mnull b
-   
-instance Monoid a => MonoidNull (Maybe a) where
-   mnull Nothing = True
-   mnull _ = False
-
-instance MonoidNull (First a) where
-   mnull (First Nothing) = True
-   mnull _ = False
-
-instance MonoidNull (Last a) where
-   mnull (Last Nothing) = True
-   mnull _ = False
diff --git a/Text/ParserCombinators/Incremental.hs b/Text/ParserCombinators/Incremental.hs
--- a/Text/ParserCombinators/Incremental.hs
+++ b/Text/ParserCombinators/Incremental.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2010-2011 Mario Blazevic
+    Copyright 2010-2012 Mario Blazevic
 
     This file is part of the Streaming Component Combinators (SCC) project.
 
@@ -28,9 +28,11 @@
    -- * The Parser type
    Parser,
    -- * Using a Parser
-   feed, feedEof, results, completeResults, resultPrefix,
+   feed, feedEof, inspect, results, completeResults, resultPrefix,
    -- * Parser primitives
    failure, more, eof, anyToken, token, satisfy, acceptAll, string, takeWhile, takeWhile1,
+   -- ** Character primitives
+   satisfyChar, takeCharsWhile, takeCharsWhile1,
    -- * Parser combinators
    count, skip, moptional, concatMany, concatSome, manyTill,
    mapType, mapIncremental, (<||>), (<<|>), (><), lookAhead, notFollowedBy, and, andThen,
@@ -39,14 +41,17 @@
    )
 where
 
-import Prelude hiding (and, takeWhile)
+import Prelude hiding (and, null, span, takeWhile)
 import Control.Applicative (Applicative (pure, (<*>), (*>), (<*)), Alternative ((<|>)))
 import Control.Applicative.Monoid(MonoidApplicative(..), MonoidAlternative(..))
 import Control.Monad (ap)
+import Data.Maybe (fromMaybe)
 import Data.Monoid (Monoid, mempty, mappend, (<>))
-import Data.Monoid.Cancellative (LeftCancellativeMonoid (mstripPrefix))
-import Data.Monoid.Factorial (FactorialMonoid (splitPrimePrefix), mspan)
-import Data.Monoid.Null (MonoidNull(mnull))
+import Data.Monoid.Cancellative (LeftReductiveMonoid (stripPrefix))
+import Data.Monoid.Factorial (FactorialMonoid (splitPrimePrefix), span)
+import Data.Monoid.Null (MonoidNull(null))
+import Data.Monoid.Textual (TextualMonoid)
+import qualified Data.Monoid.Textual as Textual
 
 -- | The central parser type. Its first parameter is the input monoid, the second the output.
 data Parser a s r = Failure
@@ -71,20 +76,25 @@
 feedEof (Choice p1 p2) = feedEof p1 <||> feedEof p2
 feedEof (Delay e _) = feedEof e
 
--- | Extracts all available parsing results. The first component of the result pair is a list of complete results
--- together with the unconsumed remainder of the input. If the parsing can continue further, the second component of the
--- pair provides the partial result prefix together with the parser for the rest of the input.
+-- | Extracts all available parsing results from a 'Parser'. The first component of the result pair is a list of
+-- complete results together with the unconsumed remainder of the input. If the parsing can continue further, the second
+-- component of the pair provides the partial result prefix together with the parser for the rest of the input.
 results :: Monoid r => Parser a s r -> ([(r, s)], Maybe (r, Parser a s r))
-results Failure = ([], Nothing)
-results (Result t r) = ([(r, t)], Nothing)
-results (ResultPart r e f) = ([], Just (r mempty, ResultPart id e f))
-results (Choice p1 p2) | isInfallible p1 = (results1 ++ results2, combine rest1 rest2)
-   where (results1, rest1) = results p1
-         (results2, rest2) = results p2
+results = fmap (fmap (\(mf, p)-> (fromMaybe id mf mempty, p))) . inspect
+
+-- | Like 'results', but more general: doesn't assume that the result type is a 'Monoid'.
+inspect :: Parser a s r -> ([(r, s)], Maybe (Maybe (r -> r), Parser a s r))
+inspect Failure = ([], Nothing)
+inspect (Result t r) = ([(r, t)], Nothing)
+inspect (ResultPart r e f) = ([], Just (Just r, ResultPart id e f))
+inspect (Choice p1 p2) | isInfallible p1 = (results1 ++ results2, combine rest1 rest2)
+   where (results1, rest1) = inspect p1
+         (results2, rest2) = inspect p2
          combine Nothing rest = rest
          combine rest Nothing = rest
-         combine (Just (r1, p1')) (Just (r2, p2')) = Just (mempty, Choice (prepend (r1 <>) p1') (prepend (r2 <>) p2'))
-results p = ([], Just (mempty, p))
+         combine (Just (r1, p1')) (Just (r2, p2')) = 
+            Just (Just id, Choice (prepend (fromMaybe id r1) p1') (prepend (fromMaybe id r2) p2'))
+inspect p = ([], Just (Nothing, p))
 
 -- | Like 'results', but returns only the complete results with the corresponding unconsumed inputs.
 completeResults :: Parser a s r -> [(r, s)]
@@ -260,7 +270,7 @@
 
 -- | A parser that fails on any input and succeeds at its end.
 eof :: (MonoidNull s, Monoid r) => Parser a s r
-eof = Delay mempty (\s-> if mnull s then eof else Failure)
+eof = Delay mempty (\s-> if null s then eof else Failure)
 
 -- | A parser that accepts any single input atom.
 anyToken :: FactorialMonoid s => Parser a s s
@@ -281,10 +291,21 @@
                of Just (first, rest) -> if predicate first then Result rest first else Failure
                   Nothing -> p
 
+-- | Specialization of 'satisfy' on 'TextualMonoid' inputs, accepting an input character only if it satisfies the given
+-- predicate.
+satisfyChar :: TextualMonoid s => (Char -> Bool) -> Parser a s s
+satisfyChar predicate = p
+   where p = more f
+         f s = case splitPrimePrefix s
+               of Just (first, rest) -> case Textual.characterPrefix first
+                                        of Just c -> if predicate c then Result rest first else Failure
+                                           Nothing -> if null rest then p else Failure
+                  Nothing -> p
+
 -- | A parser that consumes and returns the given prefix of the input.
-string :: (LeftCancellativeMonoid s, MonoidNull s) => s -> Parser a s s
-string x | mnull x = mempty
-string x = more (\y-> case (mstripPrefix x y, mstripPrefix y x)
+string :: (LeftReductiveMonoid s, MonoidNull s) => s -> Parser a s s
+string x | null x = mempty
+string x = more (\y-> case (stripPrefix x y, stripPrefix y x)
                       of (Just y', _) -> Result y' x
                          (Nothing, Nothing) -> Failure
                          (Nothing, Just x') -> string x' >> return x)
@@ -294,19 +315,45 @@
 takeWhile :: (FactorialMonoid s, MonoidNull s) => (s -> Bool) -> Parser a s s
 takeWhile pred = while
    where while = ResultPart id (return mempty) f
-         f s = let (prefix, suffix) = mspan pred s 
-               in if mnull suffix then resultPart (mappend prefix) while
+         f s = let (prefix, suffix) = span pred s
+               in if null suffix then resultPart (mappend prefix) while
                   else Result suffix prefix
 
 -- | A parser accepting the longest non-empty sequence of input atoms that match the given predicate; an optimized
 -- version of 'concatSome . satisfy'.
 takeWhile1 :: (FactorialMonoid s, MonoidNull s) => (s -> Bool) -> Parser a s s
 takeWhile1 pred = more f
-   where f s | mnull s = takeWhile1 pred
-             | otherwise = let (prefix, suffix) = mspan pred s 
-                           in if mnull prefix then Failure
-                              else if mnull suffix then resultPart (mappend prefix) (takeWhile pred)
+   where f s | null s = takeWhile1 pred
+             | otherwise = let (prefix, suffix) = span pred s
+                           in if null prefix then Failure
+                              else if null suffix then resultPart (mappend prefix) (takeWhile pred)
                                    else Result suffix prefix
+
+-- | Specialization of 'takeWhile' on 'TextualMonoid' inputs, accepting the longest sequence of input characters that
+-- match the given predicate; an optimized version of 'concatMany . satisfyChar'.
+takeCharsWhile :: (TextualMonoid s, MonoidNull s) => (Char -> Bool) -> Parser a s s
+takeCharsWhile pred = while
+   where while = ResultPart id (return mempty) f
+         f s = let (prefix, suffix) = Textual.span (const False) pred s
+               in if null suffix then resultPart (mappend prefix) while
+                  else let (prefix', suffix') = Textual.span (const True) (const False) suffix
+                       in if null prefix' then Result suffix prefix
+                          else resultPart (mappend prefix . mappend prefix') (f suffix')
+
+-- | Specialization of 'takeWhile1' on 'TextualMonoid' inputs, accepting the longest non-empty sequence of input atoms
+-- that match the given predicate; an optimized version of 'concatSome . satisfyChar'.
+takeCharsWhile1 :: (TextualMonoid s, MonoidNull s) => (Char -> Bool) -> Parser a s s
+takeCharsWhile1 pred = more f
+   where f s | null s = takeCharsWhile1 pred
+             | otherwise = let (prefix, suffix) = Textual.span (const False) pred s
+                               (prefix', suffix') = Textual.span (const True) (const False) suffix
+                           in if null prefix
+                              then if null prefix' then Failure
+                                   else prepend (mappend prefix') (f suffix')
+                              else if null suffix then resultPart (mappend prefix) (takeCharsWhile pred)
+                                   else if null prefix' then Result suffix prefix
+                                        else resultPart (mappend prefix . mappend prefix')
+                                                        (feed suffix' $ takeCharsWhile pred)
 
 -- | Accepts the given number of occurrences of the argument parser.
 count :: (Monoid s, Monoid r) => Int -> Parser a s r -> Parser a s r
diff --git a/incremental-parser.cabal b/incremental-parser.cabal
--- a/incremental-parser.cabal
+++ b/incremental-parser.cabal
@@ -1,5 +1,5 @@
 Name:                incremental-parser
-Version:             0.2.1
+Version:             0.2.2
 Cabal-Version:       >= 1.10
 Build-Type:          Simple
 Synopsis:            Generic parser library capable of providing partial results from partial input.
@@ -7,12 +7,13 @@
 Tested-with:         GHC
 Description:
   This package defines yet another parser library. This one is implemented using the concept of Brzozowski derivatives,
-  tweaked and optimized to work with any monoidal input type. Lists, ByteString, and Text are supported out of the box.
+  tweaked and optimized to work with any monoidal input type. Lists, ByteString, and Text are supported out of the box,
+  as well as any other data type for which the monoid-subclasses package defines instances.
   If the parser result is also a monoid, the parser can provide it incrementally, before the complete input is parsed.
   
 License:             GPL
 License-file:        LICENSE.txt
-Copyright:           (c) 2011 Mario Blazevic
+Copyright:           (c) 2011-2013 Mario Blazevic
 Author:              Mario Blazevic
 Maintainer:          blamario@yahoo.com
 Homepage:            http://patch-tag.com/r/blamario/incremental-parser/wiki/
@@ -22,10 +23,9 @@
 
 Library
   Exposed-Modules:   Text.ParserCombinators.Incremental,
-                     Text.ParserCombinators.Incremental.LeftBiasedLocal, Text.ParserCombinators.Incremental.Symmetric
-                     Control.Applicative.Monoid,
-                     Data.Monoid.Cancellative, Data.Monoid.Factorial, Data.Monoid.Null
-  Build-Depends:     base < 5, bytestring >= 0.9 && < 1.0, text >= 0.11.0.1 && < 0.12
+                     Text.ParserCombinators.Incremental.LeftBiasedLocal, Text.ParserCombinators.Incremental.Symmetric,
+                     Control.Applicative.Monoid
+  Build-Depends:     base < 5, monoid-subclasses < 0.2
   GHC-prof-options:  -auto-all
   if impl(ghc >= 7.0.0)
      default-language: Haskell2010
@@ -33,12 +33,11 @@
 test-suite Main
   Type:            exitcode-stdio-1.0
   x-uses-tf:       true
-  Build-Depends:     base < 5, bytestring >= 0.9 && < 1.0, text >= 0.11.0.1 && < 0.12,
+  Build-Depends:     base < 5, monoid-subclasses < 0.2,
                      QuickCheck >= 2 && < 3, checkers >= 0.2 && < 0.3,
                      test-framework >= 0.4.1, test-framework-quickcheck2
   Main-is:           Test/TestIncrementalParser.hs
   Other-Modules:     Text.ParserCombinators.Incremental,
-                     Text.ParserCombinators.Incremental.LeftBiasedLocal, Text.ParserCombinators.Incremental.Symmetric
-                     Control.Applicative.Monoid,
-                     Data.Monoid.Cancellative, Data.Monoid.Factorial, Data.Monoid.Null
+                     Text.ParserCombinators.Incremental.LeftBiasedLocal, Text.ParserCombinators.Incremental.Symmetric,
+                     Control.Applicative.Monoid
   default-language:  Haskell2010
