diff --git a/Text/Trifecta/Parser/Char.hs b/Text/Trifecta/Parser/Char.hs
--- a/Text/Trifecta/Parser/Char.hs
+++ b/Text/Trifecta/Parser/Char.hs
@@ -152,8 +152,8 @@
   | otherwise                 = satisfy (c ==) <?> show [c]
 {-# INLINE char #-}
 
--- | @char c@ parses a single character @c@. Returns the parsed
--- character (i.e. @c@).
+-- | @notChar c@ parses any single character other than @c@. Returns the parsed
+-- character.
 --
 -- >  semiColon  = char ';'
 notChar :: MonadParser m => Char -> m Char
diff --git a/Text/Trifecta/Parser/Combinators.hs b/Text/Trifecta/Parser/Combinators.hs
--- a/Text/Trifecta/Parser/Combinators.hs
+++ b/Text/Trifecta/Parser/Combinators.hs
@@ -180,7 +180,6 @@
 --
 --    Note the overlapping parsers @anyChar@ and @string \"-->\"@, and
 --    therefore the use of the 'try' combinator.
--- manyTill :: Alternative m => m a -> m end -> m [a]
 manyTill :: (Alternative m, MonadPlus m) => m a -> m end -> m [a]
 {-
 manyTill p end = scan
diff --git a/Text/Trifecta/Parser/Perm.hs b/Text/Trifecta/Parser/Perm.hs
new file mode 100644
--- /dev/null
+++ b/Text/Trifecta/Parser/Perm.hs
@@ -0,0 +1,141 @@
+-----------------------------------------------------------------------------
+-- |
+-- Module      :  Text.Trifecta.Parser.Perm
+-- Copyright   :  (c) Edward Kmett 2011
+--                (c) Paolo Martini 2007
+--                (c) Daan Leijen 1999-2001
+-- License     :  BSD-style
+-- 
+-- Maintainer  :  ekmett@gmail.com
+-- Stability   :  provisional
+-- Portability :  non-portable
+-- 
+-- This module implements permutation parsers. The algorithm is described in:
+-- 
+-- /Parsing Permutation Phrases,/
+-- by Arthur Baars, Andres Loh and Doaitse Swierstra.
+-- Published as a functional pearl at the Haskell Workshop 2001.
+-- 
+-----------------------------------------------------------------------------
+
+{-# LANGUAGE ExistentialQuantification #-}
+
+module Text.Trifecta.Parser.Perm
+    ( Perm
+    , permute
+    , (<||>), (<$$>)
+    , (<|?>), (<$?>)
+    ) where
+
+import Control.Applicative
+import Text.Trifecta.Parser.Combinators (choice)
+
+infixl 1 <||>, <|?>
+infixl 2 <$$>, <$?>
+
+{---------------------------------------------------------------
+  Building a permutation parser
+---------------------------------------------------------------}
+
+-- | The expression @perm \<||> p@ adds parser @p@ to the permutation
+-- parser @perm@. The parser @p@ is not allowed to accept empty input -
+-- use the optional combinator ('<|?>') instead. Returns a
+-- new permutation parser that includes @p@. 
+
+(<||>) :: Functor m => Perm m (a -> b) -> m a -> Perm m b
+(<||>) perm p = add perm p
+
+-- | The expression @f \<$$> p@ creates a fresh permutation parser
+-- consisting of parser @p@. The the final result of the permutation
+-- parser is the function @f@ applied to the return value of @p@. The
+-- parser @p@ is not allowed to accept empty input - use the optional
+-- combinator ('<$?>') instead.
+--
+-- If the function @f@ takes more than one parameter, the type variable
+-- @b@ is instantiated to a functional type which combines nicely with
+-- the adds parser @p@ to the ('<||>') combinator. This
+-- results in stylized code where a permutation parser starts with a
+-- combining function @f@ followed by the parsers. The function @f@
+-- gets its parameters in the order in which the parsers are specified,
+-- but actual input can be in any order.
+
+(<$$>) :: Functor m => (a -> b) -> m a -> Perm m b
+(<$$>) f p = newPerm f <||> p
+
+-- | The expression @perm \<||> (x,p)@ adds parser @p@ to the
+-- permutation parser @perm@. The parser @p@ is optional - if it can
+-- not be applied, the default value @x@ will be used instead. Returns
+-- a new permutation parser that includes the optional parser @p@. 
+
+(<|?>) :: Functor m => Perm m (a -> b) -> (a, m a) -> Perm m b
+(<|?>) perm (x,p) = addOpt perm x p
+
+-- | The expression @f \<$?> (x,p)@ creates a fresh permutation parser
+-- consisting of parser @p@. The the final result of the permutation
+-- parser is the function @f@ applied to the return value of @p@. The
+-- parser @p@ is optional - if it can not be applied, the default value
+-- @x@ will be used instead. 
+
+(<$?>) :: Functor m => (a -> b) -> (a, m a) -> Perm m b
+(<$?>) f (x,p) = newPerm f <|?> (x,p)
+
+{---------------------------------------------------------------
+  The permutation tree
+---------------------------------------------------------------}
+
+-- | The type @Perm m a@ denotes a permutation parser that,
+-- when converted by the 'permute' function, parses 
+-- using the base parsing monad @m@ and returns a value of
+-- type @a@ on success.
+--
+-- Normally, a permutation parser is first build with special operators
+-- like ('<||>') and than transformed into a normal parser
+-- using 'permute'.
+
+data Perm m a = Perm (Maybe a) [Branch m a]
+
+instance Functor m => Functor (Perm m) where
+  fmap f (Perm x xs) = Perm (fmap f x) (fmap f <$> xs)
+
+data Branch m a = forall b. Branch (Perm m (b -> a)) (m b)
+
+instance Functor m => Functor (Branch m) where
+  fmap f (Branch perm p) = Branch (fmap (f.) perm) p
+
+-- | The parser @permute perm@ parses a permutation of parser described
+-- by @perm@. For example, suppose we want to parse a permutation of:
+-- an optional string of @a@'s, the character @b@ and an optional @c@.
+-- This can be described by:
+--
+-- >  test  = permute (tuple <$?> ("",some (char 'a'))
+-- >                         <||> char 'b' 
+-- >                         <|?> ('_',char 'c'))
+-- >        where
+-- >          tuple a b c  = (a,b,c)
+
+-- transform a permutation tree into a normal parser
+permute :: Alternative m => Perm m a -> m a
+permute (Perm def xs)
+  = choice (map branch xs ++ e)
+  where
+    e = maybe [] (pure . pure) def
+    branch (Branch perm p) = flip id <$> p <*> permute perm
+           
+-- build permutation trees
+newPerm :: (a -> b) -> Perm m (a -> b)
+newPerm f = Perm (Just f) []
+
+add :: Functor m => Perm m (a -> b) -> m a -> Perm m b
+add perm@(Perm _mf fs) p
+  = Perm Nothing (first:map insert fs)
+  where
+    first = Branch perm p
+    insert (Branch perm' p')
+            = Branch (add (fmap flip perm') p) p'
+
+addOpt :: Functor m => Perm m (a -> b) -> a -> m a -> Perm m b
+addOpt perm@(Perm mf fs) x p
+  = Perm (fmap ($ x) mf) (first:map insert fs)
+  where
+    first = Branch perm p
+    insert (Branch perm' p') = Branch (addOpt (fmap flip perm') x p) p'
diff --git a/Text/Trifecta/Parser/Token/Identifier.hs b/Text/Trifecta/Parser/Token/Identifier.hs
--- a/Text/Trifecta/Parser/Token/Identifier.hs
+++ b/Text/Trifecta/Parser/Token/Identifier.hs
@@ -8,12 +8,16 @@
 -- Stability   :  provisional
 -- Portability :  non-portable
 -- 
+-- idStyle = haskellIdentifierStyle { styleReserved = ... } 
+-- identifier = ident haskellIdentifierStyle
+-- reserved   = reserve haskellIdentifierStyle
+--
 -----------------------------------------------------------------------------
 module Text.Trifecta.Parser.Token.Identifier
   ( IdentifierStyle(..)
   , ident
-  , reserved
-  , reservedByteString
+  , reserve
+  , reserveByteString
   ) where
 
 import Data.ByteString as Strict hiding (map, zip, foldl, foldr)
@@ -35,13 +39,13 @@
   , styleReservedHighlight :: TokenHighlight
   }
 
--- | parse a reserved operator or identifier
-reserved :: MonadTokenParser m => IdentifierStyle m -> String -> m ()
-reserved s name = reservedByteString s $! UTF8.fromString name
+-- | parse a reserved operator or identifier using a given style
+reserve :: MonadTokenParser m => IdentifierStyle m -> String -> m ()
+reserve s name = reserveByteString s $! UTF8.fromString name
 
--- | parse a reserved operator or identifier specified by bytestring
-reservedByteString :: MonadTokenParser m => IdentifierStyle m -> ByteString -> m ()
-reservedByteString s name = lexeme $ try $ do
+-- | parse a reserved operator or identifier using a given style specified by bytestring
+reserveByteString :: MonadTokenParser m => IdentifierStyle m -> ByteString -> m ()
+reserveByteString s name = lexeme $ try $ do
    _ <- highlightToken (styleReservedHighlight s) $ byteString name 
    notFollowedBy (styleLetter s) <?> "end of " ++ show name
 
diff --git a/Text/Trifecta/Parser/Token/Prim.hs b/Text/Trifecta/Parser/Token/Prim.hs
--- a/Text/Trifecta/Parser/Token/Prim.hs
+++ b/Text/Trifecta/Parser/Token/Prim.hs
@@ -100,7 +100,7 @@
            ,'\SYN','\ETB','\CAN','\SUB','\ESC','\DEL']
   
 
--- | This lexeme parser parses a natural number (a positive whole
+-- | This parser parses a natural number (a positive whole
 -- number). Returns the value of the number. The number can be
 -- specified in 'decimal', 'hexadecimal' or
 -- 'octal'. The number is parsed according to the grammar
@@ -115,7 +115,7 @@
   digits <- some baseDigit
   return $! foldl' (\x d -> base*x + toInteger (digitToInt d)) 0 digits
 
--- | This lexeme parser parses an integer (a whole number). This parser
+-- | This parser parses an integer (a whole number). This parser
 -- is like 'natural' except that it can be prefixed with
 -- sign (i.e. \'-\' or \'+\'). Returns the value of the number. The
 -- number can be specified in 'decimal', 'hexadecimal'
diff --git a/trifecta.cabal b/trifecta.cabal
--- a/trifecta.cabal
+++ b/trifecta.cabal
@@ -1,6 +1,6 @@
 name:          trifecta
 category:      Text, Parsing, Diagnostics, Pretty Printer, Logging
-version:       0.32.1
+version:       0.34
 license:       BSD3
 cabal-version: >= 1.6
 license-file:  LICENSE
@@ -60,6 +60,7 @@
     Text.Trifecta.Parser.Combinators
     Text.Trifecta.Parser.Expr
     Text.Trifecta.Parser.It
+    Text.Trifecta.Parser.Perm
     Text.Trifecta.Parser.Prim
     Text.Trifecta.Parser.Result
     Text.Trifecta.Parser.Step
