diff --git a/Data/Monoid/Cancellative.hs b/Data/Monoid/Cancellative.hs
--- a/Data/Monoid/Cancellative.hs
+++ b/Data/Monoid/Cancellative.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2011-2013 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -32,7 +32,7 @@
 -- 
 -- * 'RightGCDMonoid'
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, Trustworthy #-}
 
 module Data.Monoid.Cancellative (
    -- * Symmetric, commutative monoid classes
diff --git a/Data/Monoid/Factorial.hs b/Data/Monoid/Factorial.hs
--- a/Data/Monoid/Factorial.hs
+++ b/Data/Monoid/Factorial.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2011-2014 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -7,7 +7,7 @@
 -- | This module defines the 'FactorialMonoid' class and some of its instances.
 -- 
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, Trustworthy #-}
 
 module Data.Monoid.Factorial (
    -- * Classes
diff --git a/Data/Monoid/Instances/ByteString/UTF8.hs b/Data/Monoid/Instances/ByteString/UTF8.hs
--- a/Data/Monoid/Instances/ByteString/UTF8.hs
+++ b/Data/Monoid/Instances/ByteString/UTF8.hs
@@ -1,12 +1,36 @@
 {- 
-    Copyright 2013 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
 
 -- | This module defines the 'ByteStringUTF8' newtype wrapper around 'ByteString', together with its 'TextualMonoid'
--- instance.
+-- instance. The 'FactorialMonoid' instance of a wrapped 'ByteStringUTF8' value differs from the original 'ByteString':
+-- the prime 'factors' of the original value are bytes, while UTF8 character byte sequences make up the wrapped value's
+-- prime 'factors'. The following example session demonstrates the relationship:
 -- 
+-- >> let utf8@(ByteStringUTF8 bs) = fromString "E=mc\xb2"
+-- >> bs
+-- >"E=mc\194\178"
+-- >> factors bs
+-- >["E","=","m","c","\194","\178"]
+-- >> utf8
+-- >"E=mc²"
+-- >> factors utf8
+-- >["E","=","m","c","²"]
+--
+-- The 'TextualMonoid' instance follows the same logic, but it also decodes all valid UTF8 sequences into
+-- characters. Any invalid UTF8 byte sequence from the original 'ByteString' is preserved as a single prime factor:
+--
+-- >> let utf8'@(ByteStringUTF8 bs') = ByteStringUTF8 (Data.ByteString.map pred bs)
+-- >> bs'
+-- >"D<lb\193\177"
+-- >> factors bs'
+-- >["D","<","l","b","\193","\177"]
+-- >> utf8'
+-- >"D<lb\[193,177]"
+-- >> factors utf8'
+-- >["D","<","l","b","\[193,177]"]
 
 {-# LANGUAGE Haskell2010 #-}
 
@@ -15,16 +39,16 @@
    )
 where
 
-import Prelude hiding (drop, dropWhile, foldl, foldl1, foldr, foldr1, scanl, scanr, scanl1, scanr1,
+import Prelude hiding (any, drop, dropWhile, foldl, foldl1, foldr, foldr1, scanl, scanr, scanl1, scanr1,
                        map, concatMap, break, span)
 
 import Control.Exception (assert)
 import Data.Bits ((.&.), (.|.), shiftL, shiftR)
-import Data.Char (chr, ord)
+import Data.Char (chr, ord, isDigit, isPrint)
 import qualified Data.Foldable as Foldable
 import qualified Data.List as List
 import Data.Functor ((<$>))
-import Data.Maybe (fromJust, fromMaybe)
+import Data.Maybe (fromJust, fromMaybe, isJust, isNothing)
 import Data.String (IsString(fromString))
 import Data.Word (Word8)
 import Data.ByteString (ByteString)
@@ -82,8 +106,12 @@
    {-# INLINE stripCommonPrefix #-}
 
 instance Show ByteStringUTF8 where
-   showsPrec _ bs s = '"' : Textual.foldr showsBytes (:) ('"' : s) bs
+   showsPrec _ bs s = '"' : Textual.foldr showsBytes showsChar ('"' : s) bs
       where showsBytes (ByteStringUTF8 b) s = '\\' : shows (ByteString.unpack b) s
+            showsChar c s
+              | isPrint c = c : s
+              | h:_ <- s, isDigit h = "\\" ++ show (ord c) ++ "\\&" ++ s
+              | otherwise = "\\" ++ show (ord c) ++ s
 
 instance IsString ByteStringUTF8 where
    fromString = ByteStringUTF8 . Foldable.foldMap fromChar
@@ -245,17 +273,17 @@
                          | c < '\xC0' = (a, fromIntegral (ord c) : acc)
                          | otherwise = let a' = multiByte a acc in seq a' (a', [fromIntegral $ ord c])
             multiByte a acc = reverseBytesToChar (ft a . ByteStringUTF8) (fc a) acc
-                                                                  
    {-# INLINE foldl' #-}
    foldr ft fc a0 (ByteStringUTF8 bs) = case ByteString.Char8.foldr f (a0, []) bs
                                         of (a, []) -> a
                                            (a, acc) -> multiByte a acc
       where f c (a, []) | c < '\x80' = (fc c a, [])
-                        | otherwise = (a, [fromIntegral $ ord c])
-            f c (a, acc) | c < '\x80' = (fc c (multiByte a acc), [])
+                        | c < '\xC0' = (a, [fromIntegral $ ord c])
+                        | otherwise = (ft (ByteStringUTF8 $ ByteString.Char8.singleton c) a, [])
+            f c (a, acc) | c < '\x80' = (fc c (ft (ByteStringUTF8 $ ByteString.pack acc) a), [])
                          | c < '\xC0' = (a, fromIntegral (ord c) : acc)
-                         | otherwise = (multiByte a acc, [fromIntegral $ ord c])
-            multiByte a acc = reverseBytesToChar ((`ft` a) . ByteStringUTF8) (`fc` a) acc
+                         | otherwise = (multiByte a (fromIntegral (ord c) : acc), [])
+            multiByte a acc = bytesToChar ((`ft` a) . ByteStringUTF8) (`fc` a) acc
    {-# INLINE foldr #-}
    dropWhile pb pc (ByteStringUTF8 bs) = ByteStringUTF8 $ dropASCII bs
       where dropASCII rest = case ByteString.Char8.findIndex (\c-> c > '\x7f' || not (pc c)) rest
@@ -334,12 +362,20 @@
                                                                             | otherwise -> loop rest
                                               Nothing -> loop (ByteString.dropWhile (not . byteStartsCharacter) bs')
    {-# INLINE find #-}
+   any p utf8 = isJust (find p utf8)
+   {-# INLINE any #-}
+   all p utf8 = isNothing (find (not . p) utf8)
+   {-# INLINE all #-}
+   elem c utf8@(ByteStringUTF8 bs)
+     | c < '\x80' = ByteString.Char8.elem c bs
+     | otherwise = any (== c) utf8
+   {-# INLINE elem #-}
 
 reverseBytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
 reverseBytesToChar ft fc [w] = if w < 0x80 then fc (w2c w) else ft (ByteString.singleton w)
 reverseBytesToChar ft fc [b0, b1] =
   assert (0x80 <= b0 && b0 < 0xC0 && 0xC0 <= b1) $
-  if b1 < 0xE0
+  if 0xC2 <= b1 && b1 < 0xE0
   then fc (chr (shiftL (fromIntegral b1 .&. 0x1F) 6 .|. fromIntegral b0 .&. 0x3F))
   else ft (ByteString.pack [b1, b0])
 reverseBytesToChar ft fc [b0, b1, b2] =
@@ -357,6 +393,31 @@
                 .|. shiftL (fromIntegral b1 .&. 0x3F) 6
                 .|. fromIntegral b0 .&. 0x3F))
   else ft (ByteString.pack [b3, b2, b1, b0])
+reverseBytesToChar ft fc bytes = ft (ByteString.reverse $ ByteString.pack bytes)
+
+bytesToChar :: (ByteString -> a) -> (Char -> a) -> [Word8] -> a
+bytesToChar ft fc [w] = if w < 0x80 then fc (w2c w) else ft (ByteString.singleton w)
+bytesToChar ft fc bytes@[b1, b0] =
+  assert (0x80 <= b0 && b0 < 0xC0) $
+  if 0xC2 <= b1 && b1 < 0xE0
+  then fc (chr (shiftL (fromIntegral b1 .&. 0x1F) 6 .|. fromIntegral b0 .&. 0x3F))
+  else ft (ByteString.pack bytes)
+bytesToChar ft fc bytes@[b2, b1, b0] =
+  assert (0x80 <= b0 && b0 < 0xC0 && 0x80 <= b1 && b1 < 0xC0) $
+  if (0xE0 < b2 || 0xE0 == b2 && 0xA0 <= b1) && 0xC0 <= b2 && b2 < 0xF0
+  then fc (chr (shiftL (fromIntegral b2 .&. 0xF) 12
+                .|. shiftL (fromIntegral b1 .&. 0x3F) 6
+                .|. fromIntegral b0 .&. 0x3F))
+  else ft (ByteString.pack bytes)
+bytesToChar ft fc bytes@[b3, b2, b1, b0] =
+  assert (0x80 <= b0 && b0 < 0xC0 && 0x80 <= b1 && b1 < 0xC0 && 0x80 <= b2 && b2 < 0xC0) $
+  if (0xF0 < b3 || 0xF0 == b3 && 0xA0 <= b2) && 0xC0 <= b3 && b3 < 0xF4
+  then fc (chr (shiftL (fromIntegral b3 .&. 0x7) 18
+                .|. shiftL (fromIntegral b2 .&. 0x3F) 12
+                .|. shiftL (fromIntegral b1 .&. 0x3F) 6
+                .|. fromIntegral b0 .&. 0x3F))
+  else ft (ByteString.pack bytes)
+bytesToChar ft fc bytes = ft (ByteString.pack bytes)
 
 wrapPair (bs1, bs2) = (ByteStringUTF8 bs1, ByteStringUTF8 bs2)
 {-# INLINE wrapPair #-}
diff --git a/Data/Monoid/Instances/Concat.hs b/Data/Monoid/Instances/Concat.hs
--- a/Data/Monoid/Instances/Concat.hs
+++ b/Data/Monoid/Instances/Concat.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2011-2014 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -10,12 +10,13 @@
 {-# LANGUAGE Haskell2010 #-}
 
 module Data.Monoid.Instances.Concat (
-   Concat, concatenate, inject, extract 
+   Concat, concatenate, extract
    )
 where
 
 import Prelude hiding (all, any, break, filter, foldl, foldl1, foldr, foldr1, map, concatMap, 
                        length, null, reverse, scanl, scanr, scanl1, scanr1, span, splitAt)
+import Control.Applicative (Applicative(..))
 import Data.Foldable (Foldable)
 import Data.Traversable (Traversable, traverse)
 import qualified Data.Foldable as Foldable
@@ -34,7 +35,7 @@
 import qualified Data.Sequence as Seq
 
 -- | @'Concat' a@ is a @newtype@ wrapper around @'Seq' a@. The behaviour of the @'Concat' a@ instances of monoid
--- subclasses is identical to the behaviour of their @a@ instances, up to the @'inject' . 'singleton'@ isomorphism.
+-- subclasses is identical to the behaviour of their @a@ instances, up to the 'pure' isomorphism.
 --
 -- The only purpose of 'Concat' then is to change the performance characteristics of various operations. Most
 -- importantly, injecting a monoid into a 'Concat' has the effect of making 'mappend' a constant-time operation.
@@ -50,6 +51,14 @@
 instance (Ord a, Monoid a) => Ord (Concat a) where
    compare (Concat x) (Concat y) = compare (Foldable.foldMap id x) (Foldable.foldMap id y)
 
+instance Functor Concat where
+   fmap f (Concat x) = Concat (fmap f x)
+
+instance Applicative Concat where
+   pure a = Concat (Seq.singleton a)
+   Concat x <*> Concat y = Concat (x <*> y)
+   Concat x *> Concat y = Concat (x *> y)
+
 instance Monoid (Concat a) where
    mempty = Concat Seq.empty
    mappend (Concat a) (Concat b) = Concat (mappend a b)
@@ -207,10 +216,6 @@
    break pt pc = Textual.span (not . pt) (not . pc)
 
    find p (Concat x) = getFirst $ Foldable.foldMap (First . find p) x
-
-inject :: (MonoidNull a, PositiveMonoid a) => Seq a -> Concat a
-inject = concatenate
-{-# DEPRECATED inject "Use concatenate instead." #-}
 
 injectSingleton :: (MonoidNull a, PositiveMonoid a) => a -> Concat a
 injectSingleton a | null a = mempty
diff --git a/Data/Monoid/Instances/Measured.hs b/Data/Monoid/Instances/Measured.hs
--- a/Data/Monoid/Instances/Measured.hs
+++ b/Data/Monoid/Instances/Measured.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013-2014 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -10,7 +10,7 @@
 {-# LANGUAGE Haskell2010 #-}
 
 module Data.Monoid.Instances.Measured (
-   Measured, inject, measure, extract
+   Measured, measure, extract
    )
 where
 
@@ -38,10 +38,6 @@
 measure :: FactorialMonoid a => a -> Measured a
 measure x = Measured (length x) x
 
-inject :: FactorialMonoid a => a -> Measured a
-inject = measure
-{-# DEPRECATED inject "Use measure instead." #-}
-
 instance Ord a => Ord (Measured a) where
    compare (Measured _ x) (Measured _ y) = compare x y
 
@@ -61,10 +57,10 @@
    stripSuffix (Measured m x) (Measured n y) = fmap (Measured (n - m)) (stripSuffix x y)
 
 instance (LeftGCDMonoid a, StableFactorialMonoid a) => LeftGCDMonoid (Measured a) where
-   commonPrefix (Measured _ x) (Measured _ y) = inject (commonPrefix x y)
+   commonPrefix (Measured _ x) (Measured _ y) = measure (commonPrefix x y)
 
 instance (RightGCDMonoid a, StableFactorialMonoid a) => RightGCDMonoid (Measured a) where
-   commonSuffix (Measured _ x) (Measured _ y) = inject (commonSuffix x y)
+   commonSuffix (Measured _ x) (Measured _ y) = measure (commonSuffix x y)
 
 instance StableFactorialMonoid a => FactorialMonoid (Measured a) where
    factors (Measured _ x) = List.map (Measured 1) (factors x)
@@ -86,9 +82,9 @@
    foldMap f (Measured _ x) = Factorial.foldMap (f . Measured 1) x
    span p (Measured n x) = (xp', xs')
       where (xp, xs) = Factorial.span (p . Measured 1) x
-            xp' = inject xp
+            xp' = measure xp
             xs' = Measured (n - length xp') xs
-   split p (Measured _ x) = inject <$> Factorial.split (p . Measured 1) x
+   split p (Measured _ x) = measure <$> Factorial.split (p . Measured 1) x
    splitAt m (Measured n x) | m <= 0 = (mempty, Measured n x)
                             | m >= n = (Measured n x, mempty)
                             | otherwise = (Measured m xp, Measured (n - m) xs)
@@ -98,10 +94,10 @@
 instance StableFactorialMonoid a => StableFactorialMonoid (Measured a)
 
 instance (FactorialMonoid a, IsString a) => IsString (Measured a) where
-   fromString = inject . fromString
+   fromString = measure . fromString
 
 instance (Eq a, TextualMonoid a, StableFactorialMonoid a) => TextualMonoid (Measured a) where
-   fromText = inject . fromText
+   fromText = measure . fromText
    singleton = Measured 1 . singleton
    splitCharacterPrefix (Measured n x) = (Measured (n - 1) <$>) <$> splitCharacterPrefix x
    characterPrefix (Measured _ x) = characterPrefix x
@@ -115,7 +111,7 @@
 
    span pt pc (Measured n x) = (xp', xs')
       where (xp, xs) = Textual.span (pt . Measured 1) pc x
-            xp' = inject xp
+            xp' = measure xp
             xs' = Measured (n - length xp') xs
    break pt pc = Textual.span (not . pt) (not . pc)
 
diff --git a/Data/Monoid/Instances/Positioned.hs b/Data/Monoid/Instances/Positioned.hs
--- a/Data/Monoid/Instances/Positioned.hs
+++ b/Data/Monoid/Instances/Positioned.hs
@@ -1,5 +1,5 @@
 {-
-    Copyright 2014 Mario Blazevic
+    Copyright 2014-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -10,26 +10,29 @@
 -- base monoid of 'LinePositioned' must be a 'TextualMonoid', but for the price it will keep track of the current line
 -- and column numbers as well.
 --
+-- All positions are zero-based:
+--
+-- >> let p = pure "abcd\nefgh\nijkl\nmnop\n" :: LinePositioned String
+-- >> p
+-- >Line 0, column 0: "abcd\nefgh\nijkl\nmnop\n"
+-- >> Data.Monoid.Factorial.drop 13 p
+-- >Line 2, column 3: "l\nmnop\n"
 
 {-# LANGUAGE Haskell2010 #-}
 
 module Data.Monoid.Instances.Positioned (
-   OffsetPositioned, LinePositioned, extract, position, line, column, findIndex, findPosition
+   OffsetPositioned, LinePositioned, extract, position, line, column
    )
 where
 
-import Prelude hiding (all, any, break, filter, foldl, foldl1, foldr, foldr1, map, concatMap,
+import Prelude hiding (all, any, break, filter, foldl, foldl1, foldr, foldr1, lines, map, concatMap,
                        length, null, reverse, scanl, scanr, scanl1, scanr1, span, splitAt)
 import Control.Applicative (Applicative(..))
-import Data.Functor ((<$>))
 import qualified Data.List as List
 import Data.String (IsString(..))
-import Data.Sequence (Seq, filter, (<|), (|>), ViewL((:<)), ViewR((:>)))
-import qualified Data.Sequence as Seq
 
-import Data.Monoid (Monoid(..), (<>), Endo(..), First(..), Sum(..))
-import Data.Monoid.Cancellative (LeftReductiveMonoid(..), RightReductiveMonoid(..), ReductiveMonoid(..),
-                                 LeftGCDMonoid(..), RightGCDMonoid(..), GCDMonoid(..))
+import Data.Monoid (Monoid(..), (<>), Endo(..))
+import Data.Monoid.Cancellative (LeftReductiveMonoid(..), RightReductiveMonoid(..), LeftGCDMonoid(..), RightGCDMonoid(..))
 import Data.Monoid.Null (MonoidNull(null), PositiveMonoid)
 import Data.Monoid.Factorial (FactorialMonoid(..), StableFactorialMonoid)
 import Data.Monoid.Textual (TextualMonoid(..))
@@ -65,7 +68,7 @@
    OffsetPositioned _ f <*> OffsetPositioned p c = OffsetPositioned p (f c)
 
 instance Applicative LinePositioned where
-   pure = LinePositioned 1 1 0
+   pure = LinePositioned 0 0 0
    LinePositioned _ _ _ f <*> LinePositioned p l lp c = LinePositioned p l lp (f c)
 
 instance Positioned OffsetPositioned where
@@ -98,24 +101,32 @@
 instance StableFactorialMonoid m => Monoid (OffsetPositioned m) where
    mempty = pure mempty
    mappend (OffsetPositioned p1 c1) (OffsetPositioned p2 c2) =
-      OffsetPositioned (max p1 (p2 - length c1)) (mappend c1 c2)
+      OffsetPositioned (if p1 /= 0 || p2 == 0 then p1 else max 0 $ p2 - length c1) (mappend c1 c2)
+   {-# INLINE mempty #-}
+   {-# INLINE mappend #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m) => Monoid (LinePositioned m) where
    mempty = pure mempty
-   mappend (LinePositioned p1 l1 lp1 c1) (LinePositioned p2 l2 lp2 c2) =
-      let p2' = p2 - length c1
-          l2' = l2 - lines
-          (lines, _) = linesColumns c1
-          c = mappend c1 c2
-      in if p1 >= p2' || l1 > l2' || lp1 > lp2
-         then LinePositioned p1 l1 lp1 c
-         else LinePositioned p2' l2' (if lines == 0 then lp2 else lp1) c
+   mappend (LinePositioned p1 l1 lp1 c1) (LinePositioned p2 l2 lp2 c2)
+     | p1 /= 0 || p2 == 0 = LinePositioned p1 l1 lp1 c
+     | otherwise = LinePositioned p2' l2' lp2' c
+     where c = mappend c1 c2
+           p2' = max 0 $ p2 - length c1
+           lp2' = min p2' lp2
+           l2' = if l2 == 0 then 0 else max 0 $ l2 - Textual.foldl_' countLines 0 c1
+           countLines :: Int -> Char -> Int
+           countLines n '\n' = succ n
+           countLines n _ = n
+   {-# INLINE mempty #-}
+   {-# INLINE mappend #-}
 
 instance (StableFactorialMonoid m, MonoidNull m) => MonoidNull (OffsetPositioned m) where
    null = null . extractOffset
+   {-# INLINE null #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m, MonoidNull m) => MonoidNull (LinePositioned m) where
    null = null . extractLines
+   {-# INLINE null #-}
 
 instance (StableFactorialMonoid m, PositiveMonoid m) => PositiveMonoid (OffsetPositioned m)
 
@@ -124,14 +135,18 @@
 instance (StableFactorialMonoid m, LeftReductiveMonoid m) => LeftReductiveMonoid (OffsetPositioned m) where
    isPrefixOf (OffsetPositioned _ c1) (OffsetPositioned _ c2) = isPrefixOf c1 c2
    stripPrefix (OffsetPositioned _ c1) (OffsetPositioned p c2) = fmap (OffsetPositioned (p + length c1)) (stripPrefix c1 c2)
+   {-# INLINE isPrefixOf #-}
+   {-# INLINE stripPrefix #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m, LeftReductiveMonoid m) => 
          LeftReductiveMonoid (LinePositioned m) where
    isPrefixOf a b = isPrefixOf (extractLines a) (extractLines b)
    stripPrefix LinePositioned{extractLines= c1} (LinePositioned p l lpos c2) =
-      let (lines, columns) = linesColumns c1
+      let (lines, columns) = linesColumns' c1
           len = length c1
       in fmap (LinePositioned (p + len) (l + lines) (lpos + len - columns)) (stripPrefix c1 c2)
+   {-# INLINE isPrefixOf #-}
+   {-# INLINE stripPrefix #-}
 
 instance (StableFactorialMonoid m, LeftGCDMonoid m) => LeftGCDMonoid (OffsetPositioned m) where
    commonPrefix (OffsetPositioned p1 c1) (OffsetPositioned p2 c2) = OffsetPositioned (min p1 p2) (commonPrefix c1 c2)
@@ -139,6 +154,8 @@
       (OffsetPositioned (min p1 p2) prefix, OffsetPositioned (p1 + l) c1', OffsetPositioned (p2 + l) c2')
       where (prefix, c1', c2') = stripCommonPrefix c1 c2
             l = length prefix
+   {-# INLINE commonPrefix #-}
+   {-# INLINE stripCommonPrefix #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m, LeftGCDMonoid m) => LeftGCDMonoid (LinePositioned m) where
    commonPrefix (LinePositioned p1 l1 lp1 c1) (LinePositioned p2 l2 lp2 c2) =
@@ -147,21 +164,27 @@
       else LinePositioned p2 l2 lp2 (commonPrefix c1 c2)
    stripCommonPrefix (LinePositioned p1 l1 lp1 c1) (LinePositioned p2 l2 lp2 c2) =
       let (prefix, c1', c2') = stripCommonPrefix c1 c2
-          (lines, columns) = linesColumns prefix
+          (lines, columns) = linesColumns' prefix
           len = length prefix
       in (if p1 <= p2 then LinePositioned p1 l1 lp1 prefix else LinePositioned p2 l2 lp2 prefix, 
           LinePositioned (p1 + len) (l1 + lines) (lp1 + len - columns) c1', 
           LinePositioned (p2 + len) (l2 + lines) (lp2 + len - columns) c2')
+   {-# INLINE commonPrefix #-}
+   {-# INLINE stripCommonPrefix #-}
 
 instance (StableFactorialMonoid m, RightReductiveMonoid m) => RightReductiveMonoid (OffsetPositioned m) where
    isSuffixOf (OffsetPositioned _ c1) (OffsetPositioned _ c2) = isSuffixOf c1 c2
    stripSuffix (OffsetPositioned _ c1) (OffsetPositioned p c2) = fmap (OffsetPositioned p) (stripSuffix c1 c2)
+   {-# INLINE isSuffixOf #-}
+   {-# INLINE stripSuffix #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m, RightReductiveMonoid m) =>
          RightReductiveMonoid (LinePositioned m) where
    isSuffixOf LinePositioned{extractLines=c1} LinePositioned{extractLines=c2} = isSuffixOf c1 c2
    stripSuffix (LinePositioned p l lp c1) LinePositioned{extractLines=c2} = 
       fmap (LinePositioned p l lp) (stripSuffix c1 c2)
+   {-# INLINE isSuffixOf #-}
+   {-# INLINE stripSuffix #-}
 
 instance (StableFactorialMonoid m, RightGCDMonoid m) => RightGCDMonoid (OffsetPositioned m) where
    commonSuffix (OffsetPositioned p1 c1) (OffsetPositioned p2 c2) = 
@@ -171,6 +194,8 @@
       (OffsetPositioned p1 c1', OffsetPositioned p2 c2', 
        OffsetPositioned (min (p1 + length c1') (p2 + length c2')) suffix)
       where (c1', c2', suffix) = stripCommonSuffix c1 c2
+   {-# INLINE commonSuffix #-}
+   {-# INLINE stripCommonSuffix #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m, RightGCDMonoid m) => RightGCDMonoid (LinePositioned m) where
    stripCommonSuffix (LinePositioned p1 l1 lp1 c1) (LinePositioned p2 l2 lp2 c2) =
@@ -181,17 +206,17 @@
       where (c1', c2', suffix) = stripCommonSuffix c1 c2
             len1 = length c1'
             len2 = length c2'
-            (lines1, columns1) = linesColumns c1'
-            (lines2, columns2) = linesColumns c2'
+            (lines1, columns1) = linesColumns' c1'
+            (lines2, columns2) = linesColumns' c2'
 
 instance StableFactorialMonoid m => FactorialMonoid (OffsetPositioned m) where
    factors (OffsetPositioned p c) = snd $ List.mapAccumL next p (factors c)
       where next p1 c1 = (succ p1, OffsetPositioned p1 c1)
    primePrefix (OffsetPositioned p c) = OffsetPositioned p (primePrefix c)
-   splitPrimePrefix (OffsetPositioned p c) = fmap position (splitPrimePrefix c)
-      where position (cp, cs) = (OffsetPositioned p cp, OffsetPositioned (succ p) cs)
-   splitPrimeSuffix (OffsetPositioned p c) = fmap position (splitPrimeSuffix c)
-      where position (cp, cs) = (OffsetPositioned p cp, OffsetPositioned (p + length cp) cs)
+   splitPrimePrefix (OffsetPositioned p c) = fmap rewrap (splitPrimePrefix c)
+      where rewrap (cp, cs) = (OffsetPositioned p cp, OffsetPositioned (succ p) cs)
+   splitPrimeSuffix (OffsetPositioned p c) = fmap rewrap (splitPrimeSuffix c)
+      where rewrap (cp, cs) = (OffsetPositioned p cp, OffsetPositioned (p + length cp) cs)
    foldl f a0 (OffsetPositioned p0 c0) = fst $ Factorial.foldl f' (a0, p0) c0
       where f' (a, p) c = (f a (OffsetPositioned p c), succ p)
    foldl' f a0 (OffsetPositioned p0 c0) = fst $ Factorial.foldl' f' (a0, p0) c0
@@ -202,10 +227,22 @@
    foldMap f (OffsetPositioned p c) = appEndo (Factorial.foldMap f' c) (const mempty) p
       where -- f' :: m -> Endo (Int -> m)
             f' prime = Endo (\cont pos-> f (OffsetPositioned pos prime) <> cont (succ pos))
-   span f m = Factorial.splitAt (findIndex (not . f) m) m
-   break f m = Factorial.splitAt (findIndex f m) m
-   takeWhile f m = Factorial.take (findIndex (not . f) m) m
-   dropWhile f m = Factorial.drop (findIndex (not . f) m) m
+
+   spanMaybe s0 f (OffsetPositioned p0 t) = rewrap $ Factorial.spanMaybe (s0, p0) f' t
+      where f' (s, p) prime = do s' <- f s (OffsetPositioned p prime)
+                                 let p' = succ p
+                                 Just $! seq p' (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   spanMaybe' s0 f (OffsetPositioned p0 t) = rewrap $! Factorial.spanMaybe' (s0, p0) f' t
+      where f' (s, p) prime = do s' <- f s (OffsetPositioned p prime)
+                                 let p' = succ p
+                                 Just $! s' `seq` p' `seq` (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   span f (OffsetPositioned p0 t) = rewrap $ Factorial.spanMaybe' p0 f' t
+      where f' p prime = if f (OffsetPositioned p prime)
+                         then Just $! succ p
+                         else Nothing
+            rewrap (prefix, suffix, p) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix)
    splitAt n m@(OffsetPositioned p c) | n <= 0 = (mempty, m)
                                       | n >= length c = (m, mempty)
                                       | otherwise = (OffsetPositioned p prefix, OffsetPositioned (p + n) suffix)
@@ -213,55 +250,103 @@
    drop n (OffsetPositioned p c) = OffsetPositioned (p + n) (Factorial.drop n c)
    take n (OffsetPositioned p c) = OffsetPositioned p (Factorial.take n c)
    reverse (OffsetPositioned p c) = OffsetPositioned p (Factorial.reverse c)
+   {-# INLINE primePrefix #-}
+   {-# INLINE splitPrimePrefix #-}
+   {-# INLINE splitPrimeSuffix #-}
+   {-# INLINE foldl #-}
+   {-# INLINE foldl' #-}
+   {-# INLINE foldr #-}
+   {-# INLINE foldMap #-}
+   {-# INLINE length #-}
+   {-# INLINE span #-}
+   {-# INLINE splitAt #-}
+   {-# INLINE take #-}
+   {-# INLINE drop #-}
+   {-# INLINE reverse #-}
 
 instance (StableFactorialMonoid m, TextualMonoid m) => FactorialMonoid (LinePositioned m) where
    factors (LinePositioned p0 l0 lp0 c) = snd $ List.mapAccumL next (p0, l0, lp0) (factors c)
       where next (p, l, lp) c1 | characterPrefix c1 == Just '\n' = ((succ p, succ l, p), LinePositioned p l lp c1)
                                | otherwise = ((succ p, l, lp), LinePositioned p l lp c1)
    primePrefix (LinePositioned p l lp c) = LinePositioned p l lp (primePrefix c)
-   splitPrimePrefix (LinePositioned p l lp c) = fmap position (splitPrimePrefix c)
-      where position (cp, cs) = (LinePositioned p l lp cp, 
-                                 if characterPrefix cp == Just '\n'
-                                 then LinePositioned (succ p) (succ l) p cs
-                                 else LinePositioned (succ p) l lp cs)
-   splitPrimeSuffix (LinePositioned p l lp c) = fmap position (splitPrimeSuffix c)
-      where position (cp, cs) = (LinePositioned p l lp cp, LinePositioned (p + len) (l + lines) (lp + len - columns) cs)
+   splitPrimePrefix (LinePositioned p l lp c) = fmap rewrap (splitPrimePrefix c)
+      where rewrap (cp, cs) = (LinePositioned p l lp cp,
+                               if characterPrefix cp == Just '\n'
+                               then LinePositioned (succ p) (succ l) p cs
+                               else LinePositioned (succ p) l lp cs)
+   splitPrimeSuffix (LinePositioned p l lp c) = fmap rewrap (splitPrimeSuffix c)
+      where rewrap (cp, cs) = (LinePositioned p l lp cp, LinePositioned p' (l + lines) (p' - columns) cs)
                where len = length cp
                      (lines, columns) = linesColumns cp
-   foldl f a0 (LinePositioned p0 l0 lp0 c0) = fst $ Factorial.foldl f' (a0, p0, l0, lp0) c0
+                     p' = p + len
+   foldl f a0 (LinePositioned p0 l0 lp0 c0) = fstOf4 $! Factorial.foldl f' (a0, p0, l0, lp0) c0
       where f' (a, p, l, lp) c | characterPrefix c == Just '\n' = (f a (LinePositioned p l lp c), succ p, succ l, p)
                                | otherwise = (f a (LinePositioned p l lp c), succ p, l, lp)
-            fst (a, _, _, _) = a
-   foldl' f a0 (LinePositioned p0 l0 lp0 c0) = fst $ Factorial.foldl' f' (a0, p0, l0, lp0) c0
+   foldl' f a0 (LinePositioned p0 l0 lp0 c0) = fstOf4 $! Factorial.foldl' f' (a0, p0, l0, lp0) c0
       where f' (a, p, l, lp) c = let a' = f a (LinePositioned p l lp c) 
                                  in seq a' (if characterPrefix c == Just '\n' 
                                             then (a', succ p, succ l, p)
                                             else (a', succ p, l, lp))
-            fst (a, _, _, _) = a
    foldr f a0 (LinePositioned p0 l0 lp0 c0) = Factorial.foldr f' (const3 a0) c0 p0 l0 lp0
       where f' c cont p l lp
                | characterPrefix c == Just '\n' = f (LinePositioned p l lp c) $ ((cont $! succ p) $! succ l) p
                | otherwise = f (LinePositioned p l lp c) $ (cont $! succ p) l lp
    length = length . extractLines
-   foldMap f (LinePositioned p l lp c) = appEndo (Factorial.foldMap f' c) (const mempty) p l lp
+   foldMap f (LinePositioned p0 l0 lp0 c) = appEndo (Factorial.foldMap f' c) (const mempty) p0 l0 lp0
       where -- f' :: m -> Endo (Int -> Int -> Int -> m)
             f' prime = Endo (\cont p l lp-> f (LinePositioned p l lp prime) 
                                             <> if characterPrefix prime == Just '\n'
                                                then cont (succ p) (succ l) p
                                                else cont (succ p) l lp)
-   
-   span f m = Factorial.splitAt (findLineIndex (not . f) m) m
-   break f m = Factorial.splitAt (findLineIndex f m) m
-   takeWhile f m = Factorial.take (findLineIndex (not . f) m) m
-   dropWhile f m = Factorial.drop (findLineIndex (not . f) m) m
+
+   spanMaybe s0 f (LinePositioned p0 l0 lp0 c) = rewrap $ Factorial.spanMaybe (s0, p0, l0, lp0) f' c
+      where f' (s, p, l, lp) prime = do s' <- f s (LinePositioned p l lp prime)
+                                        let p' = succ p
+                                            l' = succ l
+                                        Just $! p' `seq` if characterPrefix prime == Just '\n'
+                                                         then l' `seq` (s', p', l', p)
+                                                         else (s', p', l, lp)
+            rewrap (prefix, suffix, (s, p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix, s)
+   spanMaybe' s0 f (LinePositioned p0 l0 lp0 c) = rewrap $! Factorial.spanMaybe' (s0, p0, l0, lp0) f' c
+      where f' (s, p, l, lp) prime = do s' <- f s (LinePositioned p l lp prime)
+                                        let p' = succ p
+                                            l' = succ l
+                                        Just $! s' `seq` p' `seq` if characterPrefix prime == Just '\n'
+                                                                  then l' `seq` (s', p', l', p)
+                                                                  else (s', p', l, lp)
+            rewrap (prefix, suffix, (s, p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix, s)
+
+   span f (LinePositioned p0 l0 lp0 t) = rewrap $ Factorial.spanMaybe' (p0, l0, lp0) f' t
+      where f' (p, l, lp) prime = if f (LinePositioned p l lp prime)
+                                  then let p' = succ p
+                                           l' = succ l
+                                       in Just $! p' `seq` if characterPrefix prime == Just '\n'
+                                                           then l' `seq` (p', l', p)
+                                                           else (p', l, lp)
+                                  else Nothing
+            rewrap (prefix, suffix, (p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix)
    splitAt n m@(LinePositioned p l lp c) | n <= 0 = (mempty, m)
                                          | n >= length c = (m, mempty)
                                          | otherwise = (LinePositioned p l lp prefix, 
-                                                        LinePositioned (p + n) (l + lines) (lp + n - columns) suffix)
+                                                        LinePositioned p' (l + lines) (p' - columns) suffix)
       where (prefix, suffix) = splitAt n c
             (lines, columns) = linesColumns prefix
+            p' = p + n
    take n (LinePositioned p l lp c) = LinePositioned p l lp (Factorial.take n c)
    reverse (LinePositioned p l lp c) = LinePositioned p l lp (Factorial.reverse c)
+   {-# INLINE primePrefix #-}
+   {-# INLINE splitPrimePrefix #-}
+   {-# INLINE splitPrimeSuffix #-}
+   {-# INLINE foldl #-}
+   {-# INLINE foldl' #-}
+   {-# INLINE foldr #-}
+   {-# INLINE foldMap #-}
+   {-# INLINE length #-}
+   {-# INLINE span #-}
+   {-# INLINE splitAt #-}
+   {-# INLINE take #-}
+   {-# INLINE drop #-}
+   {-# INLINE reverse #-}
 
 instance StableFactorialMonoid m => StableFactorialMonoid (OffsetPositioned m)
 
@@ -290,8 +375,8 @@
       where ft' (a, p) c = (ft a (OffsetPositioned p c), succ p)
             fc' (a, p) c = (fc a c, succ p)
    foldl' ft fc a0 (OffsetPositioned p0 c0) = fst $ Textual.foldl' ft' fc' (a0, p0) c0
-      where ft' (a, p) c = let a' = ft a (OffsetPositioned p c) in seq a' (a', succ p)
-            fc' (a, p) c = let a' = fc a c in seq a' (a', succ p)
+      where ft' (a, p) c = ((,) $! ft a (OffsetPositioned p c)) $! succ p
+            fc' (a, p) c = ((,) $! fc a c) $! succ p
    foldr ft fc a0 (OffsetPositioned p0 c0) = snd $ Textual.foldr ft' fc' (p0, a0) c0
       where ft' c (p, a) = (succ p, ft (OffsetPositioned p c) a)
             fc' c (p, a) = (succ p, fc c a)
@@ -303,27 +388,75 @@
    mapAccumL f a0 (OffsetPositioned p c) = fmap (OffsetPositioned p) (Textual.mapAccumL f a0 c)
    mapAccumR f a0 (OffsetPositioned p c) = fmap (OffsetPositioned p) (Textual.mapAccumR f a0 c)
 
-   span pt pc (OffsetPositioned p c) = 
-      case (splitCharacterPrefix cs, splitPrimePrefix cs)
-      of (Nothing, Just (csp, css)) | pt (OffsetPositioned p' csp) ->
-            let (OffsetPositioned _ cssp, ms) = Textual.span pt pc (OffsetPositioned (succ p') css)
-            in (OffsetPositioned p (cp <> csp <> cssp), ms)
-         _ -> (OffsetPositioned p cp, OffsetPositioned p' cs)
-      where (cp, cs) = Textual.span (const False) pc c
-            p' = p + length cp
-   break pt pc (OffsetPositioned p c) =
-      case (splitCharacterPrefix cs, splitPrimePrefix cs)
-      of (Nothing, Just (csp, css)) | not (pt (OffsetPositioned p' csp)) ->
-            let (OffsetPositioned _ cssp, ms) = Textual.break pt pc (OffsetPositioned (succ p') css)
-            in (OffsetPositioned p (cp <> csp <> cssp), ms)
-         _ -> (OffsetPositioned p cp, OffsetPositioned p' cs)
-      where (cp, cs) = Textual.break (const True) pc c
-            p' = p + length cp
+   spanMaybe s0 ft fc (OffsetPositioned p0 t) = rewrap $ Textual.spanMaybe (s0, p0) ft' fc' t
+      where ft' (s, p) prime = do s' <- ft s (OffsetPositioned p prime)
+                                  let p' = succ p
+                                  Just $! seq p' (s', p')
+            fc' (s, p) c = do s' <- fc s c
+                              let p' = succ p
+                              Just $! seq p' (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   spanMaybe' s0 ft fc (OffsetPositioned p0 t) = rewrap $! Textual.spanMaybe' (s0, p0) ft' fc' t
+      where ft' (s, p) prime = do s' <- ft s (OffsetPositioned p prime)
+                                  let p' = succ p
+                                  Just $! s' `seq` p' `seq` (s', p')
+            fc' (s, p) c = do s' <- fc s c
+                              let p' = succ p
+                              Just $! s' `seq` p' `seq` (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   span ft fc (OffsetPositioned p0 t) = rewrap $ Textual.spanMaybe' p0 ft' fc' t
+      where ft' p prime = if ft (OffsetPositioned p prime)
+                          then Just $! succ p
+                          else Nothing
+            fc' p c = if fc c
+                      then Just $! succ p
+                      else Nothing
+            rewrap (prefix, suffix, p) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix)
+
    split f (OffsetPositioned p0 c0) = rewrap p0 (Textual.split f c0)
-      where rewrap p [] = []
+      where rewrap _ [] = []
             rewrap p (c:rest) = OffsetPositioned p c : rewrap (p + length c) rest
    find p = find p . extractOffset
 
+   foldl_ fc a0 (OffsetPositioned _ c) = Textual.foldl_ fc a0 c
+   foldl_' fc a0 (OffsetPositioned _ c) = Textual.foldl_' fc a0 c
+   foldr_ fc a0 (OffsetPositioned _ c) = Textual.foldr_ fc a0 c
+
+   spanMaybe_ s0 fc (OffsetPositioned p0 t) = rewrap $ Textual.spanMaybe_' (s0, p0) fc' t
+      where fc' (s, p) c = do s' <- fc s c
+                              let p' = succ p
+                              Just $! seq p' (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   spanMaybe_' s0 fc (OffsetPositioned p0 t) = rewrap $! Textual.spanMaybe_' (s0, p0) fc' t
+      where fc' (s, p) c = do s' <- fc s c
+                              let p' = succ p
+                              Just $! s' `seq` p' `seq` (s', p')
+            rewrap (prefix, suffix, (s, p)) = (OffsetPositioned p0 prefix, OffsetPositioned p suffix, s)
+   span_ bt fc (OffsetPositioned p0 t) = rewrap $ Textual.span_ bt fc t
+      where rewrap (prefix, suffix) = (OffsetPositioned p0 prefix, OffsetPositioned (p0 + length prefix) suffix)
+   break_ bt fc (OffsetPositioned p0 t) = rewrap $ Textual.break_ bt fc t
+      where rewrap (prefix, suffix) = (OffsetPositioned p0 prefix, OffsetPositioned (p0 + length prefix) suffix)
+   dropWhile_ bt fc t = snd (span_ bt fc t)
+   takeWhile_ bt fc (OffsetPositioned p t) = OffsetPositioned p (takeWhile_ bt fc t)
+
+   {-# INLINE characterPrefix #-}
+   {-# INLINE splitCharacterPrefix #-}
+   {-# INLINE map #-}
+   {-# INLINE concatMap #-}
+   {-# INLINE foldl' #-}
+   {-# INLINE foldr #-}
+   {-# INLINE spanMaybe' #-}
+   {-# INLINE span #-}
+   {-# INLINE foldl_' #-}
+   {-# INLINE foldr_ #-}
+   {-# INLINE spanMaybe_' #-}
+   {-# INLINE span_ #-}
+   {-# INLINE break_ #-}
+   {-# INLINE dropWhile_ #-}
+   {-# INLINE takeWhile_ #-}
+   {-# INLINE split #-}
+   {-# INLINE find #-}
+
 instance (StableFactorialMonoid m, TextualMonoid m) => TextualMonoid (LinePositioned m) where
    splitCharacterPrefix (LinePositioned p l lp c) = 
       case splitCharacterPrefix c
@@ -343,9 +476,8 @@
 
    foldl ft fc a0 (LinePositioned p0 l0 lp0 c0) = fstOf4 $ Textual.foldl ft' fc' (a0, p0, l0, lp0) c0
       where ft' (a, p, l, lp) c = (ft a (LinePositioned p l lp c), succ p, l, lp)
-            fc' (a, p, l, lp) '\n' = (fc a '\n', succ p, succ l, p)
+            fc' (a, p, l, _lp) '\n' = (fc a '\n', succ p, succ l, p)
             fc' (a, p, l, lp) c = (fc a c, succ p, l, lp)
-            fstOf4 (a, _, _, _) = a
    foldl' ft fc a0 (LinePositioned p0 l0 lp0 c0) = fstOf4 $ Textual.foldl' ft' fc' (a0, p0, l0, lp0) c0
       where ft' (a, p, l, lp) c = let a' = ft a (LinePositioned p l lp c) 
                                       p' = succ p
@@ -353,16 +485,44 @@
             fc' (a, p, l, lp) c = let a' = fc a c 
                                       p' = succ p
                                       l' = succ l
-                                  in if c == '\n'
-                                     then a' `seq` p' `seq` l' `seq` (a', p', l', p)
-                                     else a' `seq` p' `seq` (a', p', l, lp)
-            fstOf4 (a, _, _, _) = a
+                                  in a' `seq` p' `seq` if c == '\n'
+                                                       then l' `seq` (a', p', l', p)
+                                                       else (a', p', l, lp)
    foldr ft fc a0 (LinePositioned p0 l0 lp0 c0) = Textual.foldr ft' fc' (const3 a0) c0 p0 l0 lp0
       where ft' c cont p l lp = ft (LinePositioned p l lp c) $ (cont $! succ p) l lp
             fc' c cont p l lp
                | c == '\n' = fc c $ ((cont $! succ p) $! succ l) p
                | otherwise = fc c $ (cont $! succ p) l lp
 
+   spanMaybe s0 ft fc (LinePositioned p0 l0 lp0 t) = rewrap $ Textual.spanMaybe (s0, p0, l0, lp0) ft' fc' t
+      where ft' (s, p, l, lp) prime = do s' <- ft s (LinePositioned p l lp prime)
+                                         let p' = succ p
+                                         Just $! seq p' (s', p', l, lp)
+            fc' (s, p, l, lp) c = fc s c
+                                  >>= \s'-> Just $! seq p' (if c == '\n' then seq l' (s', p', l', p) else (s', p', l, lp))
+               where p' = succ p
+                     l' = succ l
+            rewrap (prefix, suffix, (s, p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix, s)
+   spanMaybe' s0 ft fc (LinePositioned p0 l0 lp0 t) = rewrap $! Textual.spanMaybe' (s0, p0, l0, lp0) ft' fc' t
+      where ft' (s, p, l, lp) prime = do s' <- ft s (LinePositioned p l lp prime)
+                                         let p' = succ p
+                                         Just $! s' `seq` p' `seq` (s', p', l, lp)
+            fc' (s, p, l, lp) c = do s' <- fc s c
+                                     let p' = succ p
+                                         l' = succ l
+                                     Just $! s' `seq` p' `seq` (if c == '\n' then seq l' (s', p', l', p) else (s', p', l, lp))
+            rewrap (prefix, suffix, (s, p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix, s)
+   span ft fc (LinePositioned p0 l0 lp0 t) = rewrap $ Textual.spanMaybe' (p0, l0, lp0) ft' fc' t
+      where ft' (p, l, lp) prime = if ft (LinePositioned p l lp prime)
+                                   then let p' = succ p
+                                        in p' `seq` Just (p', l, lp)
+                                   else Nothing
+            fc' (p, l, lp) c | fc c = Just $! seq p' (if c == '\n' then seq l' (p', l', p) else (p', l, lp))
+                             | otherwise = Nothing
+               where p' = succ p
+                     l' = succ l
+            rewrap (prefix, suffix, (p, l, lp)) = (LinePositioned p0 l0 lp0 prefix, LinePositioned p l lp suffix)
+
    scanl f ch (LinePositioned p l lp c) = LinePositioned p l lp (Textual.scanl f ch c)
    scanl1 f (LinePositioned p l lp c) = LinePositioned p l lp (Textual.scanl1 f c)
    scanr f ch (LinePositioned p l lp c) = LinePositioned p l lp (Textual.scanr f ch c)
@@ -370,28 +530,6 @@
    mapAccumL f a0 (LinePositioned p l lp c) = fmap (LinePositioned p l lp) (Textual.mapAccumL f a0 c)
    mapAccumR f a0 (LinePositioned p l lp c) = fmap (LinePositioned p l lp) (Textual.mapAccumR f a0 c)
 
-   span pt pc (LinePositioned p l lp c) = 
-      case (splitCharacterPrefix cs, splitPrimePrefix cs)
-      of (Nothing, Just (csp, css)) | pt (LinePositioned p' l' lp' csp) ->
-            let (LinePositioned{extractLines= cssp}, ms) = Textual.span pt pc (LinePositioned (succ p') l' lp' css)
-            in (LinePositioned p l lp (cp <> csp <> cssp), ms)
-         _ -> (LinePositioned p l lp cp, LinePositioned p' l' lp' cs)
-      where (cp, cs) = Textual.span (const False) pc c
-            p' = p + length cp
-            l' = l + lines
-            lp' = if lines == 0 then lp else p' - columns
-            (lines, columns) = linesColumns cp
-   break pt pc (LinePositioned p l lp c) =
-      case (splitCharacterPrefix cs, splitPrimePrefix cs)
-      of (Nothing, Just (csp, css)) | not (pt (LinePositioned p' l' lp' csp)) ->
-            let (LinePositioned{extractLines= cssp}, ms) = Textual.break pt pc (LinePositioned (succ p') l' lp' css)
-            in (LinePositioned p l lp (cp <> csp <> cssp), ms)
-         _ -> (LinePositioned p l lp cp, LinePositioned p' l' lp' cs)
-      where (cp, cs) = Textual.break (const True) pc c
-            p' = p + length cp
-            l' = l + lines
-            lp' = if lines == 0 then lp else p' - columns
-            (lines, columns) = linesColumns cp
    split f (LinePositioned p0 l0 lp0 c0) = rewrap p0 l0 lp0 (Textual.split f c0)
       where rewrap _ _ _ [] = []
             rewrap p l lp (c:rest) = LinePositioned p l lp c 
@@ -400,26 +538,65 @@
                      (lines, columns) = linesColumns c
    find p = find p . extractLines
 
-findIndex f m = findPosition f m - position m
-
-findPosition :: FactorialMonoid m => (OffsetPositioned m -> Bool) -> OffsetPositioned m -> Int
-findPosition f (OffsetPositioned p c) = appEndo (foldMap f' c) id p
-   where -- f' :: m -> Endo ((Int -> Int) -> Int -> Int)
-         f' prime = Endo (\cont pos-> if f (OffsetPositioned pos prime) then pos else cont (succ pos))
+   foldl_ fc a0 (LinePositioned _ _ _ t) = Textual.foldl_ fc a0 t
+   foldl_' fc a0 (LinePositioned _ _ _ t) = Textual.foldl_' fc a0 t
+   foldr_ fc a0 (LinePositioned _ _ _ t) = Textual.foldr_ fc a0 t
 
-findLineIndex f m = findLinePosition f m - position m
+   spanMaybe_ s0 fc (LinePositioned p0 l0 lp0 t) = rewrap $ Textual.spanMaybe_ s0 fc t
+      where rewrap (prefix, suffix, s) = (LinePositioned p0 l0 lp0 prefix,
+                                          LinePositioned p1 (l0 + l) (if l == 0 then lp0 else p1 - col) suffix,
+                                          s)
+              where (l, col) = linesColumns prefix
+                    p1 = p0 + length prefix
+   spanMaybe_' s0 fc (LinePositioned p0 l0 lp0 t) = rewrap $ Textual.spanMaybe_' s0 fc t
+      where rewrap (prefix, suffix, s) = p1 `seq` l1 `seq` lp1 `seq`
+                                         (LinePositioned p0 l0 lp0 prefix, LinePositioned p1 l1 lp1 suffix, s)
+              where (l, col) = linesColumns' prefix
+                    p1 = p0 + length prefix
+                    l1 = l0 + l
+                    lp1 = if l == 0 then lp0 else p1 - col
+   span_ bt fc (LinePositioned p0 l0 lp0 t) = rewrap $ Textual.span_ bt fc t
+      where rewrap (prefix, suffix) = (LinePositioned p0 l0 lp0 prefix,
+                                       LinePositioned p1 (l0 + l) (if l == 0 then lp0 else p1 - col) suffix)
+              where (l, col) = linesColumns' prefix
+                    p1 = p0 + length prefix
+   break_ bt fc t = span_ (not bt) (not . fc) t
+   dropWhile_ bt fc t = snd (span_ bt fc t)
+   takeWhile_ bt fc (LinePositioned p l lp t) = LinePositioned p l lp (takeWhile_ bt fc t)
 
-findLinePosition :: TextualMonoid m => (LinePositioned m -> Bool) -> LinePositioned m -> Int
-findLinePosition f (LinePositioned p l lp c) = Factorial.foldr f' const2 c p l lp
-   where -- f' :: m -> (Int -> Int -> Int -> Int) -> Int -> Int -> Int -> Int
-         f' t cont p l lp | f (LinePositioned p l lp t) = p 
-                          | characterPrefix t == Just '\n' = cont (succ p) (succ l) p
-                          | otherwise = cont (succ p) l lp
-         const2 p _l _lp = p
+   {-# INLINE characterPrefix #-}
+   {-# INLINE splitCharacterPrefix #-}
+   {-# INLINE map #-}
+   {-# INLINE concatMap #-}
+   {-# INLINE foldl' #-}
+   {-# INLINE foldr #-}
+   {-# INLINE spanMaybe' #-}
+   {-# INLINE span #-}
+   {-# INLINE split #-}
+   {-# INLINE find #-}
+   {-# INLINE foldl_' #-}
+   {-# INLINE foldr_ #-}
+   {-# INLINE spanMaybe_' #-}
+   {-# INLINE span_ #-}
+   {-# INLINE break_ #-}
+   {-# INLINE dropWhile_ #-}
+   {-# INLINE takeWhile_ #-}
 
 linesColumns :: TextualMonoid m => m -> (Int, Int)
-linesColumns t = Textual.foldl' (const . fmap succ) fc (0, 0) t
-   where fc (l, c) '\n' = (succ l, 0)
+linesColumns t = Textual.foldl (const . fmap succ) fc (0, 0) t
+   where fc (l, _) '\n' = (succ l, 0)
          fc (l, c) _ = (l, succ c)
+linesColumns' :: TextualMonoid m => m -> (Int, Int)
+linesColumns' t = Textual.foldl' (const . fmap succ) fc (0, 0) t
+   where fc (l, _) '\n' = let l' = succ l in seq l' (l', 0)
+         fc (l, c) _ = let c' = succ c in seq c' (l, c)
+{-# INLINE linesColumns #-}
+{-# INLINE linesColumns' #-}
 
+const3 :: a -> b -> c -> d -> a
 const3 a _p _l _lp = a
+{-# INLINE const3 #-}
+
+fstOf4 :: (a, b, c, d) -> a
+fstOf4 (a, _, _, _) = a
+{-# INLINE fstOf4  #-}
diff --git a/Data/Monoid/Instances/Stateful.hs b/Data/Monoid/Instances/Stateful.hs
--- a/Data/Monoid/Instances/Stateful.hs
+++ b/Data/Monoid/Instances/Stateful.hs
@@ -1,20 +1,25 @@
 {-
-    Copyright 2013-2014 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
 
 -- | This module defines the monoid transformer data type 'Stateful'.
 --
+-- >> let s = setState [4] $ pure "data" :: Stateful [Int] String
+-- >> s
+-- >Stateful ("data",[4])
+-- >> factors s
+-- >[Stateful ("d",[]),Stateful ("a",[]),Stateful ("t",[]),Stateful ("a",[]),Stateful ("",[4])]
 
 {-# LANGUAGE Haskell2010 #-}
 
 module Data.Monoid.Instances.Stateful (
-   Stateful(Stateful), inject, extract, state, setState
+   Stateful(Stateful), extract, state, setState
    )
 where
 
-import Prelude hiding (all, any, break, filter, foldl, foldl1, foldr, foldr1, map, concatMap,
+import Prelude hiding (all, any, break, elem, filter, foldl, foldl1, foldr, foldr1, map, concatMap,
                        length, null, reverse, scanl, scanr, scanl1, scanr1, span, splitAt)
 import Control.Applicative (Applicative(..))
 import Data.Functor ((<$>))
@@ -34,10 +39,6 @@
 -- monoid @b@ has the priority and the state @a@ is left for the end.
 newtype Stateful a b = Stateful (b, a) deriving (Eq, Ord, Show)
 
-inject :: Monoid a => b -> Stateful a b
-inject = pure
-{-# DEPRECATED inject "Use pure instead." #-}
-
 extract :: Stateful a b -> b
 extract (Stateful (t, _)) = t
 
@@ -100,7 +101,7 @@
 instance (StableFactorialMonoid a, StableFactorialMonoid b) => StableFactorialMonoid (Stateful a b)
 
 instance (Monoid a, IsString b) => IsString (Stateful a b) where
-   fromString = inject . fromString
+   fromString = pure . fromString
 
 instance (LeftGCDMonoid a, FactorialMonoid a, TextualMonoid b) => TextualMonoid (Stateful a b) where
    fromText t = Stateful (fromText t, mempty)
@@ -145,6 +146,7 @@
             restore f [t] = f [Stateful (t, x)]
             restore f (hd:tl) = restore (f . (Stateful (hd, mempty):)) tl
    find p = find p . extract
+   elem c = elem c . extract
 
 {-# INLINE fromFst #-}
 fromFst :: Monoid b => a -> Stateful b a
diff --git a/Data/Monoid/Null.hs b/Data/Monoid/Null.hs
--- a/Data/Monoid/Null.hs
+++ b/Data/Monoid/Null.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2011-2013 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -7,7 +7,7 @@
 -- | This module defines the MonoidNull class and some of its instances.
 -- 
 
-{-# LANGUAGE Haskell2010 #-}
+{-# LANGUAGE Haskell2010, Trustworthy #-}
 
 module Data.Monoid.Null (
    MonoidNull(..), PositiveMonoid
diff --git a/Data/Monoid/Textual.hs b/Data/Monoid/Textual.hs
--- a/Data/Monoid/Textual.hs
+++ b/Data/Monoid/Textual.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -7,14 +7,15 @@
 -- | This module defines the 'TextualMonoid' class and its most important instances for 'String' and 'Text'.
 -- 
 
-{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE Haskell2010, FlexibleInstances, Trustworthy #-}
 
 module Data.Monoid.Textual (
    TextualMonoid(..)
    )
 where
 
-import Prelude hiding (foldl, foldl1, foldr, foldr1, scanl, scanr, scanl1, scanr1, map, concatMap, break, span)
+import Prelude hiding (all, any, break, concatMap, dropWhile, foldl, foldl1, foldr, foldr1, map, scanl, scanl1, scanr, scanr1,
+                       span, takeWhile)
 
 import qualified Data.Foldable as Foldable
 import qualified Data.Traversable as Traversable
@@ -59,11 +60,16 @@
 -- >
 -- > mconcat . intersperse (singleton c) . split (== c) == id
 -- > find p . fromString == List.find p
+-- > elem c . fromString == List.elem c
 --
 -- A 'TextualMonoid' may contain non-character data insterspersed between its characters. Every class method that
--- returns a modified 'TextualMonoid' instance generally preserves this non-character data. All of the following
--- expressions are identities:
+-- returns a modified 'TextualMonoid' instance generally preserves this non-character data. Methods like 'foldr' can
+-- access both the non-character and character data and expect two arguments for the two purposes. For each of these
+-- methods there is also a simplified version with underscore in name (like 'foldr_') that ignores the non-character
+-- data.
 --
+-- All of the following expressions are identities:
+--
 -- > map id
 -- > concatMap singleton
 -- > foldl  (<>) (\a c-> a <> singleton c) mempty
@@ -156,7 +162,26 @@
    split :: (Char -> Bool) -> t -> [t]
    -- | Like 'List.find' from "Data.List" when applied to a 'String'. Ignores non-character data.
    find :: (Char -> Bool) -> t -> Maybe Char
+   -- | Like 'List.elem' from "Data.List" when applied to a 'String'. Ignores non-character data.
+   elem :: Char -> t -> Bool
 
+   -- | > foldl_ = foldl const
+   foldl_   :: (a -> Char -> a) -> a -> t -> a
+   foldl_'  :: (a -> Char -> a) -> a -> t -> a
+   foldr_   :: (Char -> a -> a) -> a -> t -> a
+   -- | > takeWhile_ = takeWhile . const
+   takeWhile_ :: Bool -> (Char -> Bool) -> t -> t
+   -- | > dropWhile_ = dropWhile . const
+   dropWhile_ :: Bool -> (Char -> Bool) -> t -> t
+   -- | > break_ = break . const
+   break_ :: Bool -> (Char -> Bool) -> t -> (t, t)
+   -- | > span_ = span . const
+   span_ :: Bool -> (Char -> Bool) -> t -> (t, t)
+   -- | > spanMaybe_ s = spanMaybe s (const . Just)
+   spanMaybe_ :: s -> (s -> Char -> Maybe s) -> t -> (t, t, s)
+   spanMaybe_' :: s -> (s -> Char -> Maybe s) -> t -> (t, t, s)
+
+
    fromText = fromString . Text.unpack
    singleton = fromString . (:[])
 
@@ -170,6 +195,9 @@
    foldl ft fc = Factorial.foldl (\a prime-> maybe (ft a prime) (fc a) (characterPrefix prime))
    foldr ft fc = Factorial.foldr (\prime-> maybe (ft prime) fc (characterPrefix prime))
    foldl' ft fc = Factorial.foldl' (\a prime-> maybe (ft a prime) (fc a) (characterPrefix prime))
+   foldl_ = foldl const
+   foldr_ = foldr (const id)
+   foldl_' = foldl' const
 
    scanl f c = mappend (singleton c) . fst . foldl foldlOther (foldlChars f) (mempty, c)
    scanl1 f t = case (Factorial.splitPrimePrefix t, splitCharacterPrefix t)
@@ -207,16 +235,24 @@
                                                         spanAfter (g . mappend prime) s' rest
                                                     | otherwise -> (g mempty, t, s)
                                  Nothing -> (t0, t, s)
+   takeWhile_ = takeWhile . const
+   dropWhile_ = dropWhile . const
+   break_ = break . const
+   span_ = span . const
+   spanMaybe_ s = spanMaybe s (const . Just)
+   spanMaybe_' s = spanMaybe' s (const . Just)
+
    split p m = prefix : splitRest
       where (prefix, rest) = break (const False) p m
             splitRest = case splitCharacterPrefix rest
                         of Nothing -> []
                            Just (_, tail) -> split p tail
    find p = foldr (const id) (\c r-> if p c then Just c else r) Nothing
+   elem c = any (== c)
+
    {-# INLINE characterPrefix #-}
    {-# INLINE concatMap #-}
    {-# INLINE dropWhile #-}
-   {-# INLINE find #-}
    {-# INLINE fromText #-}
    {-# INLINE map #-}
    {-# INLINE mapAccumL #-}
@@ -230,6 +266,15 @@
    {-# INLINE spanMaybe' #-}
    {-# INLINE split #-}
    {-# INLINE takeWhile #-}
+   {-# INLINE foldl_ #-}
+   {-# INLINE foldl_' #-}
+   {-# INLINE foldr_ #-}
+   {-# INLINE spanMaybe_ #-}
+   {-# INLINE spanMaybe_' #-}
+   {-# INLINE span_ #-}
+   {-# INLINE break_ #-}
+   {-# INLINE takeWhile_ #-}
+   {-# INLINE dropWhile_ #-}
 
 foldlChars f (t, c1) c2 = (mappend t (singleton c'), c')
    where c' = f c1 c2
@@ -265,21 +310,24 @@
    dropWhile _ = List.dropWhile
    break _ = List.break
    span _ = List.span
-   spanMaybe s0 ft fc l = (prefix' [], suffix' [], s')
+   spanMaybe s0 _ft fc l = (prefix' [], suffix' [], s')
       where (prefix', suffix', s', live') = List.foldl' g (id, id, s0, True) l
             g (prefix, suffix, s, live) c | live, Just s' <- fc s c = (prefix . (c:), id, s', True)
                                           | otherwise = (prefix, suffix . (c:), s, False)
-   spanMaybe' s0 ft fc l = (prefix' [], suffix' [], s')
+   spanMaybe' s0 _ft fc l = (prefix' [], suffix' [], s')
       where (prefix', suffix', s', live') = List.foldl' g (id, id, s0, True) l
             g (prefix, suffix, s, live) c | live, Just s' <- fc s c = seq s' (prefix . (c:), id, s', True)
                                           | otherwise = (prefix, suffix . (c:), s, False)
    find = List.find
+   elem = List.elem
+
    {-# INLINE all #-}
    {-# INLINE any #-}
    {-# INLINE break #-}
    {-# INLINE characterPrefix #-}
    {-# INLINE concatMap #-}
    {-# INLINE dropWhile #-}
+   {-# INLINE elem #-}
    {-# INLINE find #-}
    {-# INLINE foldl   #-}
    {-# INLINE foldl'  #-}
@@ -325,16 +373,17 @@
    dropWhile _ = Text.dropWhile
    break _ = Text.break
    span _ = Text.span
-   spanMaybe s0 ft fc t = case Text.foldr g id t (0, s0)
-                          of (i, s') | (prefix, suffix) <- Text.splitAt i t -> (prefix, suffix, s')
+   spanMaybe s0 _ft fc t = case Text.foldr g id t (0, s0)
+                           of (i, s') | (prefix, suffix) <- Text.splitAt i t -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int in seq i' $ cont (i', s')
                             | otherwise = (i, s)
-   spanMaybe' s0 ft fc t = case Text.foldr g id t (0, s0)
-                           of (i, s') | (prefix, suffix) <- Text.splitAt i t -> (prefix, suffix, s')
+   spanMaybe' s0 _ft fc t = case Text.foldr g id t (0, s0)
+                            of (i, s') | (prefix, suffix) <- Text.splitAt i t -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int in seq i' $ seq s' $ cont (i', s')
                             | otherwise = (i, s)
    split = Text.split
    find = Text.find
+
    {-# INLINE all #-}
    {-# INLINE any #-}
    {-# INLINE break #-}
@@ -386,12 +435,12 @@
    dropWhile _ = LazyText.dropWhile
    break _ = LazyText.break
    span _ = LazyText.span
-   spanMaybe s0 ft fc t = case LazyText.foldr g id t (0, s0)
-                          of (i, s') | (prefix, suffix) <- LazyText.splitAt i t -> (prefix, suffix, s')
+   spanMaybe s0 _ft fc t = case LazyText.foldr g id t (0, s0)
+                           of (i, s') | (prefix, suffix) <- LazyText.splitAt i t -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int64 in seq i' $ cont (i', s')
                             | otherwise = (i, s)
-   spanMaybe' s0 ft fc t = case LazyText.foldr g id t (0, s0)
-                           of (i, s') | (prefix, suffix) <- LazyText.splitAt i t -> (prefix, suffix, s')
+   spanMaybe' s0 _ft fc t = case LazyText.foldr g id t (0, s0)
+                            of (i, s') | (prefix, suffix) <- LazyText.splitAt i t -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int64 in seq i' $ seq s' $ cont (i', s')
                             | otherwise = (i, s)
    split = LazyText.split
@@ -453,21 +502,24 @@
    dropWhile _ = Sequence.dropWhileL
    break _ = Sequence.breakl
    span _ = Sequence.spanl
-   spanMaybe s0 ft fc b = case Foldable.foldr g id b (0, s0)
-                          of (i, s') | (prefix, suffix) <- Sequence.splitAt i b -> (prefix, suffix, s')
+   spanMaybe s0 _ft fc b = case Foldable.foldr g id b (0, s0)
+                           of (i, s') | (prefix, suffix) <- Sequence.splitAt i b -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int in seq i' $ cont (i', s')
                             | otherwise = (i, s)
-   spanMaybe' s0 ft fc b = case Foldable.foldr g id b (0, s0)
-                           of (i, s') | (prefix, suffix) <- Sequence.splitAt i b -> (prefix, suffix, s')
+   spanMaybe' s0 _ft fc b = case Foldable.foldr g id b (0, s0)
+                            of (i, s') | (prefix, suffix) <- Sequence.splitAt i b -> (prefix, suffix, s')
       where g c cont (i, s) | Just s' <- fc s c = let i' = succ i :: Int in seq i' $ seq s' $ cont (i', s')
                             | otherwise = (i, s)
    find = Foldable.find
+   elem = Foldable.elem
+
    {-# INLINE all #-}
    {-# INLINE any #-}
    {-# INLINE break #-}
    {-# INLINE characterPrefix #-}
    {-# INLINE concatMap #-}
    {-# INLINE dropWhile #-}
+   {-# INLINE elem #-}
    {-# INLINE find #-}
    {-# INLINE foldl   #-}
    {-# INLINE foldl'  #-}
@@ -523,23 +575,26 @@
    dropWhile _ = Vector.dropWhile
    break _ = Vector.break
    span _ = Vector.span
-   spanMaybe s0 ft fc v = case Vector.ifoldr g Left v s0
-                          of Left s' -> (v, Vector.empty, s')
-                             Right (i, s') | (prefix, suffix) <- Vector.splitAt i v -> (prefix, suffix, s')
-      where g i c cont s | Just s' <- fc s c = cont s'
-                         | otherwise = Right (i, s)
-   spanMaybe' s0 ft fc v = case Vector.ifoldr' g Left v s0
+   spanMaybe s0 _ft fc v = case Vector.ifoldr g Left v s0
                            of Left s' -> (v, Vector.empty, s')
                               Right (i, s') | (prefix, suffix) <- Vector.splitAt i v -> (prefix, suffix, s')
+      where g i c cont s | Just s' <- fc s c = cont s'
+                         | otherwise = Right (i, s)
+   spanMaybe' s0 _ft fc v = case Vector.ifoldr' g Left v s0
+                            of Left s' -> (v, Vector.empty, s')
+                               Right (i, s') | (prefix, suffix) <- Vector.splitAt i v -> (prefix, suffix, s')
       where g i c cont s | Just s' <- fc s c = seq s' (cont s')
                          | otherwise = Right (i, s)
    find = Vector.find
+   elem = Vector.elem
+
    {-# INLINE all #-}
    {-# INLINE any #-}
    {-# INLINE break #-}
    {-# INLINE characterPrefix #-}
    {-# INLINE concatMap #-}
    {-# INLINE dropWhile #-}
+   {-# INLINE elem #-}
    {-# INLINE find #-}
    {-# INLINE foldl   #-}
    {-# INLINE foldl'  #-}
diff --git a/Test/TestMonoidSubclasses.hs b/Test/TestMonoidSubclasses.hs
--- a/Test/TestMonoidSubclasses.hs
+++ b/Test/TestMonoidSubclasses.hs
@@ -1,5 +1,5 @@
 {- 
-    Copyright 2013 Mario Blazevic
+    Copyright 2013-2015 Mario Blazevic
 
     License: BSD3 (see BSD3-LICENSE.txt file)
 -}
@@ -11,8 +11,9 @@
 
 import Prelude hiding (foldl, foldr, gcd, length, null, reverse, span, splitAt, takeWhile)
 
-import Test.QuickCheck (Arbitrary, CoArbitrary, Property, Gen,
-                        quickCheck, arbitrary, coarbitrary, property, label, forAll, mapSize, variant, whenFail, (.&&.))
+import Test.Tasty (defaultMain, testGroup)
+import Test.Tasty.QuickCheck (Arbitrary, CoArbitrary, Property, Gen,
+                              arbitrary, coarbitrary, property, label, forAll, mapSize, testProperty, variant, whenFail, (.&&.))
 import Test.QuickCheck.Instances ()
 
 import Control.Applicative (Applicative(..), liftA2)
@@ -310,29 +311,26 @@
                             CancellativeGCDMonoidInstance (mempty :: Dual (Sum Integer)),
                             CancellativeGCDMonoidInstance (mempty :: (Sum Integer, Sum Int))]
 
-main = mapM_ (quickCheck . uncurry checkInstances) tests
+main = defaultMain (testGroup "MonoidSubclasses" $ map expand tests)
+  where expand (name, test) = testProperty name (foldr1 (.&&.) $ checkInstances test)
 
-checkInstances :: String -> Test -> Property
-checkInstances name (CommutativeTest checkType) = label name $ foldr1 (.&&.) (map checkType commutativeInstances)
-checkInstances name (NullTest checkType) = label name $ foldr1 (.&&.) (map checkType nullInstances)
-checkInstances name (PositiveTest checkType) = label name $ foldr1 (.&&.) (map checkType positiveInstances)
-checkInstances name (FactorialTest checkType) = label name $ foldr1 (.&&.) (map checkType factorialInstances)
-checkInstances name (StableFactorialTest checkType) =
-   label name $ foldr1 (.&&.) (map checkType stableFactorialInstances)
-checkInstances name (TextualTest checkType) = label name $ foldr1 (.&&.) (map checkType textualInstances)
-checkInstances name (LeftReductiveTest checkType) = label name $ foldr1 (.&&.) (map checkType leftReductiveInstances)
-checkInstances name (RightReductiveTest checkType) = label name $ foldr1 (.&&.) (map checkType rightReductiveInstances)
-checkInstances name (ReductiveTest checkType) = label name $ foldr1 (.&&.) (map checkType reductiveInstances)
-checkInstances name (LeftCancellativeTest checkType) =
-   label name $ foldr1 (.&&.) (map checkType leftCancellativeInstances) 
-checkInstances name (RightCancellativeTest checkType) =
-   label name $ foldr1 (.&&.) (map checkType rightCancellativeInstances) 
-checkInstances name (CancellativeTest checkType) = label name $ foldr1 (.&&.) (map checkType cancellativeInstances) 
-checkInstances name (LeftGCDTest checkType) = label name $ foldr1 (.&&.) (map checkType leftGCDInstances) 
-checkInstances name (RightGCDTest checkType) = label name $ foldr1 (.&&.) (map checkType rightGCDInstances) 
-checkInstances name (GCDTest checkType) = label name $ foldr1 (.&&.) (map checkType gcdInstances)  
-checkInstances name (CancellativeGCDTest checkType) = 
-   label name $ foldr1 (.&&.) (map checkType cancellativeGCDInstances) 
+checkInstances :: Test -> [Property]
+checkInstances (CommutativeTest checkType) = (map checkType commutativeInstances)
+checkInstances (NullTest checkType) = (map checkType nullInstances)
+checkInstances (PositiveTest checkType) = (map checkType positiveInstances)
+checkInstances (FactorialTest checkType) = (map checkType factorialInstances)
+checkInstances (StableFactorialTest checkType) = (map checkType stableFactorialInstances)
+checkInstances (TextualTest checkType) = (map checkType textualInstances)
+checkInstances (LeftReductiveTest checkType) = (map checkType leftReductiveInstances)
+checkInstances (RightReductiveTest checkType) = (map checkType rightReductiveInstances)
+checkInstances (ReductiveTest checkType) = (map checkType reductiveInstances)
+checkInstances (LeftCancellativeTest checkType) = (map checkType leftCancellativeInstances) 
+checkInstances (RightCancellativeTest checkType) = (map checkType rightCancellativeInstances) 
+checkInstances (CancellativeTest checkType) = (map checkType cancellativeInstances) 
+checkInstances (LeftGCDTest checkType) = (map checkType leftGCDInstances) 
+checkInstances (RightGCDTest checkType) = (map checkType rightGCDInstances) 
+checkInstances (GCDTest checkType) = (map checkType gcdInstances)  
+checkInstances (CancellativeGCDTest checkType) = (map checkType cancellativeGCDInstances) 
 
 tests :: [(String, Test)]
 tests = [("CommutativeMonoid", CommutativeTest checkCommutative),
@@ -521,7 +519,7 @@
    forAll (arbitrary :: Gen a) check1 .&&. forAll (arbitrary :: Gen String) check2
    where check1 a = Textual.foldr (\a l-> Left a : l) (\c l-> Right c : l) [] a == textualFactors a
                     && Textual.foldr (<>) ((<>) . Textual.singleton) mempty a == a
-         check2 s = Textual.foldr undefined (:) [] s == s
+         check2 s = Textual.foldr undefined (:) [] (fromString s :: a) == s
 
 checkTextualFoldl' (TextualMonoidInstance (_ :: a)) = 
    forAll (arbitrary :: Gen a) check1 .&&. forAll (arbitrary :: Gen String) check2
diff --git a/monoid-subclasses.cabal b/monoid-subclasses.cabal
--- a/monoid-subclasses.cabal
+++ b/monoid-subclasses.cabal
@@ -1,5 +1,5 @@
 Name:                monoid-subclasses
-Version:             0.3.6.2
+Version:             0.4
 Cabal-Version:       >= 1.10
 Build-Type:          Simple
 Synopsis:            Subclasses of Monoid
@@ -11,7 +11,7 @@
   
 License:             BSD3
 License-file:        BSD3-LICENSE.txt
-Copyright:           (c) 2013-2014 Mario Blazevic
+Copyright:           (c) 2013-2015 Mario Blazevic
 Author:              Mario Blazevic
 Maintainer:          Mario Blazevic <blamario@yahoo.com>
 Homepage:            https://github.com/blamario/monoid-subclasses/
@@ -24,20 +24,16 @@
   Exposed-Modules:   Data.Monoid.Cancellative, Data.Monoid.Factorial, Data.Monoid.Null, Data.Monoid.Textual,
                      Data.Monoid.Instances.ByteString.UTF8, Data.Monoid.Instances.Concat,
                      Data.Monoid.Instances.Measured, Data.Monoid.Instances.Positioned, Data.Monoid.Instances.Stateful
-  Build-Depends:     base < 5, bytestring >= 0.9 && < 1.0, containers == 0.5.*, text >= 0.11 && < 1.3,
+  Build-Depends:     base >= 4 && < 5, bytestring >= 0.9 && < 1.0, containers == 0.5.*, text >= 0.11 && < 1.3,
                      primes == 0.2.*, vector >= 0.9 && < 0.11
   GHC-prof-options:  -auto-all
-  if impl(ghc >= 7.0.0)
-     default-language: Haskell2010
+  default-language:  Haskell2010
 
 test-suite Main
   Type:              exitcode-stdio-1.0
-  x-uses-tf:         true
-  Build-Depends:     base < 5, bytestring >= 0.9 && < 1.0, containers == 0.5.*, text >= 0.11 && < 1.3,
-                     primes == 0.2.*, vector >= 0.9 && < 0.11, QuickCheck == 2.*, quickcheck-instances == 0.3.*,
-                     test-framework >= 0.4.1, test-framework-quickcheck2
+  Build-Depends:     base >= 4 && < 5, bytestring >= 0.9 && < 1.0, containers == 0.5.*, text >= 0.11 && < 1.3,
+                     vector >= 0.9 && < 0.11, primes == 0.2.*,
+                     QuickCheck == 2.*, quickcheck-instances == 0.3.*, tasty >= 0.7, tasty-quickcheck >= 0.7,
+                     monoid-subclasses
   Main-is:           Test/TestMonoidSubclasses.hs
-  Other-Modules:     Data.Monoid.Cancellative, Data.Monoid.Factorial, Data.Monoid.Null, Data.Monoid.Textual,
-                     Data.Monoid.Instances.ByteString.UTF8, Data.Monoid.Instances.Concat,
-                     Data.Monoid.Instances.Measured, Data.Monoid.Instances.Positioned, Data.Monoid.Instances.Stateful
   default-language:  Haskell2010
