diff --git a/AUTHORS.md b/AUTHORS.md
--- a/AUTHORS.md
+++ b/AUTHORS.md
@@ -37,6 +37,7 @@
 * Dennis Gosnell
 * Derek Elkins
 * Emil Sköldberg
+* Herbert Valerio Riedel
 * Joel Williamson
 * Mark Karpov
 * Paolo Martini
diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,18 @@
+## Megaparsec 4.3.0
+
+* Canonicalized `Applicative`/`Monad` instances. Thanks to Herbert Valerio
+  Riedel.
+
+* Custom messages in `ParseError` are printed each on its own line.
+
+* Now accumulated hints are not used with `ParseError` records that have
+  only custom messages in them (created with `Message` constructor, as
+  opposed to `Unexpected` or `Expected`). This strips “expected” line from
+  custom error messages where it's unlikely to be relevant anyway.
+
+* Added higher-level combinators for indentation-sensitive grammars:
+  `indentLevel`, `nonIndented`, and `indentBlock`.
+
 ## Megaparsec 4.2.0
 
 * Made `newPos` constructor and other functions in `Text.Megaparsec.Pos`
diff --git a/LICENSE.md b/LICENSE.md
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -1,4 +1,4 @@
-Copyright © 2015 Megaparsec contributors<br>
+Copyright © 2015–2016 Megaparsec contributors<br>
 Copyright © 2007 Paolo Martini<br>
 Copyright © 1999–2000 Daan Leijen
 
diff --git a/README.md b/README.md
--- a/README.md
+++ b/README.md
@@ -84,7 +84,7 @@
 
 * `updateParserState` applies given function on parser state.
 
-This list of core function is longer than in some other libraries. Our goal
+This list of core functions is longer than in some other libraries. Our goal
 was easy and readable implementation of functionality provided by every such
 primitive, not minimal number of them. You can read the comprehensive
 description of every primitive function in [Megaparsec documentation](https://hackage.haskell.org/package/megaparsec/docs/Text-Megaparsec-Prim.html).
@@ -153,7 +153,7 @@
 and indentation.
 
 The design of the module allows you quickly solve simple tasks and doesn't
-get in your way when you want to implemented something less standard.
+get in your way when you want to implement something less standard.
 
 ## Documentation
 
@@ -165,9 +165,9 @@
 ## Tutorials
 
 You can visit [site of the project](https://mrkkrp.github.io/megaparsec/)
-which has several tutorials that should help you to start with your parsing
-tasks. The site also has instructions and tips for Parsec users who decide
-to switch.
+which has [several tutorials](https://mrkkrp.github.io/megaparsec/tutorials.html) that
+should help you to start with your parsing tasks. The site also has
+instructions and tips for Parsec users who decide to switch.
 
 ## Comparison with other solutions
 
@@ -181,7 +181,7 @@
 usually easy to decide which you will need in particular project:
 
 * *Attoparsec* is much faster but not that feature-rich. It should be used
-  when you want to process large amounts of data where performance matter
+  when you want to process large amounts of data where performance matters
   more than quality of error messages.
 
 * *Megaparsec* is good for parsing of source code or other human-readable
@@ -246,7 +246,7 @@
 
 * It currently has a bug in definition of `lookAhead` for various monad
   transformers like `StateT`, etc. which is visible when you create
-  backtracking state via monad stack, not via built-in features. See #27.
+  backtracking state via monad stack, not via built-in features.
 
 We intended to use Parsers library in Megaparsec at some point, but aside
 from already mentioned flaws the library has different conventions for
@@ -275,7 +275,7 @@
 
 ## License
 
-Copyright © 2015 Megaparsec contributors<br>
+Copyright © 2015–2016 Megaparsec contributors<br>
 Copyright © 2007 Paolo Martini<br>
 Copyright © 1999–2000 Daan Leijen
 
diff --git a/Text/Megaparsec.hs b/Text/Megaparsec.hs
--- a/Text/Megaparsec.hs
+++ b/Text/Megaparsec.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
diff --git a/Text/Megaparsec/ByteString.hs b/Text/Megaparsec/ByteString.hs
--- a/Text/Megaparsec/ByteString.hs
+++ b/Text/Megaparsec/ByteString.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.ByteString
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 -- License     :  FreeBSD
 --
diff --git a/Text/Megaparsec/ByteString/Lazy.hs b/Text/Megaparsec/ByteString/Lazy.hs
--- a/Text/Megaparsec/ByteString/Lazy.hs
+++ b/Text/Megaparsec/ByteString/Lazy.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.ByteString.Lazy
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 -- License     :  FreeBSD
 --
diff --git a/Text/Megaparsec/Char.hs b/Text/Megaparsec/Char.hs
--- a/Text/Megaparsec/Char.hs
+++ b/Text/Megaparsec/Char.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Char
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
diff --git a/Text/Megaparsec/Combinator.hs b/Text/Megaparsec/Combinator.hs
--- a/Text/Megaparsec/Combinator.hs
+++ b/Text/Megaparsec/Combinator.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Combinator
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -107,7 +107,7 @@
 -- \"-->\"@ overlap and @string \"-->\"@ could consume input before failing.
 
 manyTill :: Alternative m => m a -> m end -> m [a]
-manyTill p end = (end *> pure []) <|> someTill p end
+manyTill p end = ([] <$ end) <|> someTill p end
 {-# INLINE manyTill #-}
 
 -- | @someTill p end@ works similarly to @manyTill p end@, but @p@ should
@@ -115,7 +115,6 @@
 
 someTill :: Alternative m => m a -> m end -> m [a]
 someTill p end = (:) <$> p <*> manyTill p end
-{-# INLINE someTill #-}
 
 -- | @option x p@ tries to apply parser @p@. If @p@ fails without
 -- consuming input, it returns the value @x@, otherwise the value returned
@@ -157,7 +156,6 @@
 
 sepEndBy1 :: Alternative m => m a -> m sep -> m [a]
 sepEndBy1 p sep = (:) <$> p <*> ((sep *> sepEndBy p sep) <|> pure [])
-{-# INLINE sepEndBy1 #-}
 
 -- | @skipMany p@ applies the parser @p@ /zero/ or more times, skipping
 -- its result.
diff --git a/Text/Megaparsec/Error.hs b/Text/Megaparsec/Error.hs
--- a/Text/Megaparsec/Error.hs
+++ b/Text/Megaparsec/Error.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Error
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -54,9 +54,9 @@
 -- system to generate quite good error messages for the user.
 
 data Message
-  = Unexpected !String
-  | Expected   !String
-  | Message    !String
+  = Unexpected !String -- ^ Parser ran into an unexpected token
+  | Expected   !String -- ^ What is expected instead
+  | Message    !String -- ^ General-purpose error message component
   deriving (Show, Eq)
 
 instance Enum Message where
@@ -121,6 +121,8 @@
 
 -- | @newErrorMessages ms pos@ creates 'ParseError' with messages @ms@ and
 -- associated position @pos@.
+--
+-- @since 4.2.0
 
 newErrorMessages :: [Message] -> SourcePos -> ParseError
 newErrorMessages ms pos = addErrorMessages ms $ newErrorUnknown pos
@@ -143,6 +145,8 @@
 
 -- | @addErrorMessages ms err@ returns @err@ with messages @ms@ added. The
 -- function is defined in terms of 'addErrorMessage'.
+--
+-- @since 4.2.0
 
 addErrorMessages :: [Message] -> ParseError -> ParseError
 addErrorMessages ms err = foldr addErrorMessage err ms
@@ -188,15 +192,19 @@
         (expected, messages) = span ((== 1) . fromEnum) ms'
         f prefix m = (prefix ++) <$> m
         ns = ["\nunexpected ","\nexpecting ","\n"]
-        rs = renderMsgs <$> [unexpected, expected, messages]
+        rs = (renderMsgs orList <$> [unexpected, expected]) ++
+             [renderMsgs (intercalate "\n") messages]
 
 -- | Render collection of messages. If the collection is empty, return
--- 'Nothing', else return textual representation of the messages inside
+-- 'Nothing', otherwise return textual representation of the messages inside
 -- 'Just'.
 
-renderMsgs :: [Message] -> Maybe String
-renderMsgs [] = Nothing
-renderMsgs ms = Just . orList $ messageString <$> ms
+renderMsgs
+  :: ([String] -> String) -- ^ Function to combine results
+  -> [Message]         -- ^ Collection of messages to render
+  -> Maybe String      -- ^ Result, if any
+renderMsgs _ [] = Nothing
+renderMsgs f ms = Just . f $ messageString <$> ms
 
 -- | Print a pretty list where items are separated with commas and the word
 -- “or” according to rules of English punctuation.
diff --git a/Text/Megaparsec/Expr.hs b/Text/Megaparsec/Expr.hs
--- a/Text/Megaparsec/Expr.hs
+++ b/Text/Megaparsec/Expr.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Expr
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -27,11 +27,11 @@
 -- operator has also an associated associativity.
 
 data Operator m a
-  = InfixN  (m (a -> a -> a)) -- ^ non-associative infix
-  | InfixL  (m (a -> a -> a)) -- ^ left-associative infix
-  | InfixR  (m (a -> a -> a)) -- ^ right-associative infix
-  | Prefix  (m (a -> a))      -- ^ prefix
-  | Postfix (m (a -> a))      -- ^ postfix
+  = InfixN  (m (a -> a -> a)) -- ^ Non-associative infix
+  | InfixL  (m (a -> a -> a)) -- ^ Left-associative infix
+  | InfixR  (m (a -> a -> a)) -- ^ Right-associative infix
+  | Prefix  (m (a -> a))      -- ^ Prefix
+  | Postfix (m (a -> a))      -- ^ Postfix
 
 -- | @makeExprParser term table@ builds an expression parser for terms
 -- @term@ with operators from @table@, taking the associativity and
diff --git a/Text/Megaparsec/Lexer.hs b/Text/Megaparsec/Lexer.hs
--- a/Text/Megaparsec/Lexer.hs
+++ b/Text/Megaparsec/Lexer.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Lexer
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -19,14 +19,19 @@
 -- > import qualified Text.Megaparsec.Lexer as L
 
 module Text.Megaparsec.Lexer
-  ( -- * White space and indentation
+  ( -- * White space
     space
   , lexeme
   , symbol
   , symbol'
-  , indentGuard
   , skipLineComment
   , skipBlockComment
+    -- * Indentation
+  , indentLevel
+  , indentGuard
+  , nonIndented
+  , IndentOpt (..)
+  , indentBlock
     -- * Character and string literals
   , charLiteral
     -- * Numbers
@@ -40,10 +45,10 @@
   , signed )
 where
 
-import Control.Applicative ((<|>), some)
+import Control.Applicative ((<|>), some, optional)
 import Control.Monad (void)
 import Data.Char (readLitChar)
-import Data.Maybe (listToMaybe)
+import Data.Maybe (listToMaybe, fromMaybe, isJust)
 import Prelude hiding (negate)
 import qualified Prelude
 
@@ -85,10 +90,10 @@
 -- of the file).
 
 space :: MonadParsec s m Char
-      => m () -- ^ A parser for a space character (e.g. 'C.spaceChar')
-      -> m () -- ^ A parser for a line comment (e.g. 'skipLineComment')
-      -> m () -- ^ A parser for a block comment (e.g. 'skipBlockComment')
-      -> m ()
+  => m () -- ^ A parser for a space character (e.g. 'C.spaceChar')
+  -> m () -- ^ A parser for a line comment (e.g. 'skipLineComment')
+  -> m () -- ^ A parser for a block comment (e.g. 'skipBlockComment')
+  -> m ()
 space ch line block = hidden . skipMany $ choice [ch, line, block]
 
 -- | This is wrapper for lexemes. Typical usage is to supply first argument
@@ -98,7 +103,10 @@
 -- > lexeme  = L.lexeme spaceConsumer
 -- > integer = lexeme L.integer
 
-lexeme :: MonadParsec s m Char => m () -> m a -> m a
+lexeme :: MonadParsec s m Char
+  => m ()              -- ^ How to consume white space after lexeme
+  -> m a               -- ^ How to parse actual lexeme
+  -> m a
 lexeme spc p = p <* spc
 
 -- | This is a helper to parse symbols, i.e. verbatim strings. You pass the
@@ -116,15 +124,57 @@
 -- > colon     = symbol ":"
 -- > dot       = symbol "."
 
-symbol :: MonadParsec s m Char => m () -> String -> m String
+symbol :: MonadParsec s m Char
+  => m ()              -- ^ How to consume white space after lexeme
+  -> String            -- ^ String to parse
+  -> m String
 symbol spc = lexeme spc . C.string
 
 -- | Case-insensitive version of 'symbol'. This may be helpful if you're
 -- working with case-insensitive languages.
 
-symbol' :: MonadParsec s m Char => m () -> String -> m String
+symbol' :: MonadParsec s m Char
+  => m ()              -- ^ How to consume white space after lexeme
+  -> String            -- ^ String to parse (case-insensitive)
+  -> m String
 symbol' spc = lexeme spc . C.string'
 
+-- | Given comment prefix this function returns parser that skips line
+-- comments. Note that it stops just before newline character but doesn't
+-- consume the newline. Newline is either supposed to be consumed by 'space'
+-- parser or picked up manually.
+
+skipLineComment :: MonadParsec s m Char
+  => String            -- ^ Line comment prefix
+  -> m ()
+skipLineComment prefix = p >> void (manyTill C.anyChar n)
+  where p = try (C.string prefix)
+        n = lookAhead C.newline
+
+-- | @skipBlockComment start end@ skips non-nested block comment starting
+-- with @start@ and ending with @end@.
+
+skipBlockComment :: MonadParsec s m Char
+  => String            -- ^ Start of block comment
+  -> String            -- ^ End of block comment
+  -> m ()
+skipBlockComment start end = p >> void (manyTill C.anyChar n)
+  where p = try (C.string start)
+        n = try (C.string end)
+
+-- Indentation
+
+-- | Return current indentation level.
+--
+-- The function is a simple shortcut defined as:
+--
+-- > indentLevel = sourceColumn <$> getPosition
+--
+-- @since 4.3.0
+
+indentLevel :: MonadParsec s m t => m Int
+indentLevel = sourceColumn <$> getPosition
+
 -- | @indentGuard spaceConsumer test@ first consumes all white space
 -- (indentation) with @spaceConsumer@ parser, then it checks column
 -- position. It should satisfy supplied predicate @test@, otherwise the
@@ -136,32 +186,99 @@
 -- indentation. Use returned value to check indentation on every subsequent
 -- line according to syntax of your language.
 
-indentGuard :: MonadParsec s m Char => m () -> (Int -> Bool) -> m Int
+indentGuard :: MonadParsec s m Char
+  => m ()              -- ^ How to consume indentation (white space)
+  -> (Int -> Bool)     -- ^ Predicate checking indentation level
+  -> m Int             -- ^ Current column (indentation level)
 indentGuard spc p = do
   spc
-  pos <- sourceColumn <$> getPosition
-  if p pos
-  then return pos
-  else fail "incorrect indentation"
+  lvl <- indentLevel
+  if p lvl
+    then return lvl
+    else fail ii
 
--- | Given comment prefix this function returns parser that skips line
--- comments. Note that it stops just before newline character but doesn't
--- consume the newline. Newline is either supposed to be consumed by 'space'
--- parser or picked up manually.
+-- | Parse non-indented construction. This ensures that there is no
+-- indentation before actual data. Useful, for example, as a wrapper for
+-- top-level function definitions.
+--
+-- @since 4.3.0
 
-skipLineComment :: MonadParsec s m Char => String -> m ()
-skipLineComment prefix = p >> void (manyTill C.anyChar n)
-  where p = try $ C.string prefix
-        n = lookAhead C.newline
+nonIndented :: MonadParsec s m Char
+  => m ()              -- ^ How to consume indentation (white space)
+  -> m a               -- ^ How to parse actual data
+  -> m a
+nonIndented sc p = indentGuard sc (== 1) *> p
 
--- | @skipBlockComment start end@ skips non-nested block comment starting
--- with @start@ and ending with @end@.
+-- | The data type represents available behaviors for parsing of indented
+-- tokens. This is used in 'indentBlock', which see.
+--
+-- @since 4.3.0
 
-skipBlockComment :: MonadParsec s m Char => String -> String -> m ()
-skipBlockComment start end = p >> void (manyTill C.anyChar n)
-  where p = try $ C.string start
-        n = try $ C.string end
+data IndentOpt m a b
+  = IndentNone a
+    -- ^ Parse no indented tokens, just return the value
+  | IndentMany (Maybe Int) ([b] -> m a) (m b)
+    -- ^ Parse many indented tokens (possibly zero), use given indentation
+    -- level (if 'Nothing', use level of the first indented token); the
+    -- second argument tells how to get final result, and third argument
+    -- describes how to parse indented token
+  | IndentSome (Maybe Int) ([b] -> m a) (m b)
+    -- ^ Just like 'ManyIndent', but requires at least one indented token to
+    -- be present
 
+-- | Parse a “reference” token and a number of other tokens that have
+-- greater (but the same) level of indentation than that of “reference”
+-- token. Reference token can influence parsing, see 'IndentOpt' for more
+-- information.
+--
+-- Tokens /must not/ consume newlines after them. On the other hand, the
+-- first argument of this function /must/ consume newlines among other white
+-- space characters.
+--
+-- @since 4.3.0
+
+indentBlock :: MonadParsec s m Char
+  => m ()              -- ^ How to consume indentation (white space)
+  -> m (IndentOpt m a b) -- ^ How to parse “reference” token
+  -> m a
+indentBlock sc r = do
+  ref <- indentGuard sc (const True)
+  a   <- r
+  case a of
+    IndentNone x -> return x
+    IndentMany indent f p -> do
+      mlvl <- optional . try $ C.eol *> indentGuard sc (> ref)
+      case mlvl of
+        Nothing  -> sc *> f []
+        Just lvl -> indentedItems ref (fromMaybe lvl indent) sc p >>= f
+    IndentSome indent f p -> do
+      lvl <- C.eol *> indentGuard sc (> ref)
+      indentedItems ref (fromMaybe lvl indent) sc p >>= f
+
+-- | Grab indented items. This is a helper for 'indentBlock', it's not a
+-- part of public API.
+
+indentedItems :: MonadParsec s m Char
+  => Int               -- ^ Reference indentation level
+  -> Int               -- ^ Level of the first indented item ('lookAhead'ed)
+  -> m ()              -- ^ How to consume indentation (white space)
+  -> m b               -- ^ How to parse indented tokens
+  -> m [b]
+indentedItems ref lvl sc p = go
+  where
+    go = (sc *> indentLevel) >>= re
+    re pos
+      | pos <= ref = return []
+      | pos == lvl = (:) <$> p <*> go
+      | otherwise  = do
+          done <- isJust <$> optional eof
+          if done
+            then return []
+            else fail ii
+
+ii :: String
+ii = "incorrect indentation"
+
 -- Character and string literals
 
 -- | The lexeme parser parses a single literal character without
@@ -256,21 +373,18 @@
 -- If you need to parse signed floats, see 'signed'.
 
 float :: MonadParsec s m Char => m Double
-float = label "float" $ read <$> f
-  where f = do
-          d    <- some C.digitChar
-          rest <- fraction <|> fExp
-          return $ d ++ rest
+float = label "float" (read <$> f)
+  where f = (++) <$> some C.digitChar <*> (fraction <|> fExp)
 
 -- | This is a helper for 'float' parser. It parses fractional part of
 -- floating point number, that is, dot and everything after it.
 
 fraction :: MonadParsec s m Char => m String
 fraction = do
-  void $ C.char '.'
+  void (C.char '.')
   d <- some C.digitChar
   e <- option "" fExp
-  return $ '.' : d ++ e
+  return ('.' : d ++ e)
 
 -- | This helper parses exponent of floating point numbers.
 
@@ -279,7 +393,7 @@
   expChar <- C.char' 'e'
   signStr <- option "" (pure <$> choice (C.char <$> "+-"))
   d       <- some C.digitChar
-  return $ expChar : signStr ++ d
+  return (expChar : signStr ++ d)
 
 -- | Parse a number: either integer or floating point. The parser can handle
 -- overlapping grammars graciously.
diff --git a/Text/Megaparsec/Perm.hs b/Text/Megaparsec/Perm.hs
--- a/Text/Megaparsec/Perm.hs
+++ b/Text/Megaparsec/Perm.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Perm
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
diff --git a/Text/Megaparsec/Pos.hs b/Text/Megaparsec/Pos.hs
--- a/Text/Megaparsec/Pos.hs
+++ b/Text/Megaparsec/Pos.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Pos
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -40,7 +40,7 @@
 
 data SourcePos = SourcePos
   { -- | Extract the name of the source from a source position.
-    sourceName   :: String
+    sourceName   :: !String
     -- | Extract the line number from a source position.
   , sourceLine   :: !Int
     -- | Extract the column number from a source position.
@@ -117,7 +117,7 @@
 -- positive, 'InvalidTextualPosition' will be thrown.
 
 setSourceColumn :: SourcePos -> Int -> SourcePos
-setSourceColumn (SourcePos n l _) c = newPos n l c
+setSourceColumn (SourcePos n l _) = newPos n l
 
 -- | Update a source position given a character. The first argument
 -- specifies tab width. If the character is a newline (\'\\n\') the line
diff --git a/Text/Megaparsec/Prim.hs b/Text/Megaparsec/Prim.hs
--- a/Text/Megaparsec/Prim.hs
+++ b/Text/Megaparsec/Prim.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Prim
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 --                © 1999–2001 Daan Leijen
 -- License     :  FreeBSD
@@ -91,24 +91,22 @@
 data Reply s a = Reply !(State s) Consumption (Result a)
 
 -- | This data structure represents an aspect of result of parser's
--- work. The two constructors have the following meaning:
---
---     * @Consumed@ means that some part of input stream was consumed.
---     * @Virgin@ means that no input was consumed.
+-- work.
 --
 -- See also: 'Result', 'Reply'.
 
-data Consumption = Consumed | Virgin
+data Consumption
+  = Consumed -- ^ Some part of input stream was consumed
+  | Virgin   -- ^ No input was consumed
 
 -- | This data structure represents an aspect of result of parser's
--- work. The two constructors have the following meaning:
---
---     * @OK@ means that parser succeeded.
---     * @Error@ means that parser failed.
+-- work.
 --
 -- See also: 'Consumption', 'Reply'.
 
-data Result a = OK a | Error ParseError
+data Result a
+  = OK a             -- ^ Parser succeeded
+  | Error ParseError -- ^ Parser failed
 
 -- | 'Hints' represent collection of strings to be included into 'ParserError'
 -- as “expected” messages when a parser fails without consuming input right
@@ -138,9 +136,18 @@
         msgs  = filter ((== 1) . fromEnum) $ errorMessages err
 
 -- | @withHints hs c@ makes “error” continuation @c@ use given hints @hs@.
+--
+-- Note that if resulting continuation gets 'ParseError' where all messages
+-- are created with 'Message' constructor, hints are ignored.
 
 withHints :: Hints -> (ParseError -> m b) -> ParseError -> m b
-withHints (Hints xs) c = c . addErrorMessages (Expected <$> concat xs)
+withHints (Hints xs) c e =
+  let isMessage (Message _) = True
+      isMessage _           = False
+  in (if all isMessage (errorMessages e)
+      then c
+      else c . addErrorMessages (Expected <$> concat xs))
+     e
 
 -- | @accHints hs c@ results in “OK” continuation that will add given hints
 -- @hs@ to third argument of original continuation @c@.
@@ -185,7 +192,7 @@
   {-# INLINE uncons #-}
 
 -- | @StorableStream@ abstracts ability of some streams to be stored in a
--- file. This is used by polymorphic function 'readFromFile'.
+-- file. This is used by the polymorphic function 'parseFromFile'.
 
 class Stream s t => StorableStream s t where
 
@@ -265,9 +272,9 @@
 {-# INLINE pMap #-}
 
 instance A.Applicative (ParsecT s m) where
-  pure     = return
+  pure     = pPure
   (<*>)    = ap
-  (*>)     = (>>)
+  p1 *> p2 = p1 `pBind` const p2
   p1 <* p2 = do { x1 <- p1 ; void p2 ; return x1 }
 
 instance A.Alternative (ParsecT s m) where
@@ -287,18 +294,18 @@
   in unParser p s (walk []) cerr manyErr (errToHints $ eok [] s)
 
 manyErr :: a
-manyErr = error $ concat
-  [ "Text.Megaparsec.Prim.many: combinator 'many' is applied to a parser"
-  , " that accepts an empty string." ]
+manyErr = error $
+  "Text.Megaparsec.Prim.many: combinator 'many' is applied to a parser"
+  ++ " that accepts an empty string."
 
 instance Monad (ParsecT s m) where
-  return = pReturn
+  return = pure
   (>>=)  = pBind
   fail   = pFail
 
-pReturn :: a -> ParsecT s m a
-pReturn x = ParsecT $ \s _ _ eok _ -> eok x s mempty
-{-# INLINE pReturn #-}
+pPure :: a -> ParsecT s m a
+pPure x = ParsecT $ \s _ _ eok _ -> eok x s mempty
+{-# INLINE pPure #-}
 
 pBind :: ParsecT s m a -> (a -> ParsecT s m b) -> ParsecT s m b
 pBind m k = ParsecT $ \s cok cerr eok eerr ->
@@ -320,11 +327,11 @@
 mkPT k = ParsecT $ \s cok cerr eok eerr -> do
   (Reply s' consumption result) <- k s
   case consumption of
-    Consumed -> do
+    Consumed ->
       case result of
         OK    x -> cok x s' mempty
         Error e -> cerr e
-    Virgin -> do
+    Virgin ->
       case result of
         OK    x -> eok x s' mempty
         Error e -> eerr e
@@ -384,6 +391,8 @@
   -- 'unexpected' is defined in terms of the function:
   --
   -- > unexpected = failure . pure . Unexpected
+  --
+  -- @since 4.2.0
 
   failure :: [Message] -> m a
 
@@ -718,6 +727,8 @@
 -- accepts and returns parser state. This allows to specify arbitrary
 -- textual position at the beginning of parsing, for example. This is the
 -- most general way to run a parser over the 'Identity' monad.
+--
+-- @since 4.2.0
 
 runParser' :: Stream s t
            => Parsec s a -- ^ Parser to run
@@ -738,6 +749,8 @@
 -- | This function is similar to 'runParserT', but like 'runParser'' it
 -- accepts and returns parser state. This is thus the most general way to
 -- run a parser.
+--
+-- @since 4.2.0
 
 runParserT' :: (Monad m, Stream s t)
             => ParsecT s m a -- ^ Parser to run
@@ -746,8 +759,8 @@
 runParserT' p s = do
   (Reply s' _ result) <- runParsecT p s
   case result of
-    OK    x -> return $ (s', Right x)
-    Error e -> return $ (s', Left  e)
+    OK    x -> return (s', Right x)
+    Error e -> return (s', Left  e)
 
 -- | Given name of source file and input construct initial state for parser.
 
diff --git a/Text/Megaparsec/ShowToken.hs b/Text/Megaparsec/ShowToken.hs
--- a/Text/Megaparsec/ShowToken.hs
+++ b/Text/Megaparsec/ShowToken.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.ShowToken
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 -- License     :  FreeBSD
 --
 -- Maintainer  :  Mark Karpov <markkarpov@opmbx.org>
diff --git a/Text/Megaparsec/String.hs b/Text/Megaparsec/String.hs
--- a/Text/Megaparsec/String.hs
+++ b/Text/Megaparsec/String.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.String
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2007 Paolo Martini
 -- License     :  FreeBSD
 --
diff --git a/Text/Megaparsec/Text.hs b/Text/Megaparsec/Text.hs
--- a/Text/Megaparsec/Text.hs
+++ b/Text/Megaparsec/Text.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Text
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2011 Antoine Latter
 -- License     :  FreeBSD
 --
diff --git a/Text/Megaparsec/Text/Lazy.hs b/Text/Megaparsec/Text/Lazy.hs
--- a/Text/Megaparsec/Text/Lazy.hs
+++ b/Text/Megaparsec/Text/Lazy.hs
@@ -1,6 +1,6 @@
 -- |
 -- Module      :  Text.Megaparsec.Text.Lazy
--- Copyright   :  © 2015 Megaparsec contributors
+-- Copyright   :  © 2015–2016 Megaparsec contributors
 --                © 2011 Antoine Latter
 -- License     :  FreeBSD
 --
diff --git a/benchmarks/Main.hs b/benchmarks/Main.hs
--- a/benchmarks/Main.hs
+++ b/benchmarks/Main.hs
@@ -2,7 +2,7 @@
 --
 -- Criterion benchmarks for Megaparsec.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/megaparsec.cabal b/megaparsec.cabal
--- a/megaparsec.cabal
+++ b/megaparsec.cabal
@@ -2,7 +2,7 @@
 --
 -- Cabal config for Megaparsec.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
@@ -28,7 +28,7 @@
 -- POSSIBILITY OF SUCH DAMAGE.
 
 name:                megaparsec
-version:             4.2.0
+version:             4.3.0
 cabal-version:       >= 1.10
 license:             BSD2
 license-file:        LICENSE.md
@@ -51,6 +51,11 @@
                    , CHANGELOG.md
                    , README.md
 
+flag dev
+  description:       Turn on development settings.
+  manual:            True
+  default:           False
+
 library
   build-depends:     base                   >= 4.6 && < 5
                    , mtl                    == 2.*
@@ -83,14 +88,20 @@
                    , Text.Megaparsec.String
                    , Text.Megaparsec.Text
                    , Text.Megaparsec.Text.Lazy
-  ghc-options:       -O2 -Wall
+  if flag(dev)
+    ghc-options:     -Wall -Werror
+  else
+    ghc-options:     -O2 -Wall
   default-language:  Haskell2010
 
 test-suite old-tests
   main-is:           Main.hs
   hs-source-dirs:    old-tests
   type:              exitcode-stdio-1.0
-  ghc-options:       -O2 -Wall
+  if flag(dev)
+    ghc-options:     -Wall -Werror
+  else
+    ghc-options:     -O2 -Wall
   other-modules:     Bugs
                    , Bugs.Bug2
                    , Bugs.Bug6
@@ -99,7 +110,7 @@
                    , Bugs.Bug39
                    , Util
   build-depends:     base                   >= 4.6 && < 5
-                   , megaparsec             >= 4.2
+                   , megaparsec             >= 4.3
                    , HUnit                  >= 1.2 && < 1.4
                    , test-framework         >= 0.6 && < 1
                    , test-framework-hunit   >= 0.2 && < 0.4
@@ -112,7 +123,10 @@
   main-is:           Main.hs
   hs-source-dirs:    tests
   type:              exitcode-stdio-1.0
-  ghc-options:       -O2 -Wall
+  if flag(dev)
+    ghc-options:     -Wall -Werror
+  else
+    ghc-options:     -O2 -Wall
   other-modules:     Char
                    , Combinator
                    , Error
@@ -123,7 +137,7 @@
                    , Prim
                    , Util
   build-depends:     base                   >= 4.6 && < 5
-                   , megaparsec             >= 4.2
+                   , megaparsec             >= 4.3
                    , mtl                    == 2.*
                    , transformers           == 0.4.*
                    , QuickCheck             >= 2.4 && < 3
@@ -139,9 +153,12 @@
   main-is:           Main.hs
   hs-source-dirs:    benchmarks
   type:              exitcode-stdio-1.0
-  ghc-options:       -O2 -Wall
+  if flag(dev)
+    ghc-options:     -O2 -Wall -Werror
+  else
+    ghc-options:     -O2 -Wall
   build-depends:     base                   >= 4.6 && < 5
-                   , megaparsec             >= 4.2
+                   , megaparsec             >= 4.3
                    , criterion              >= 0.6.2.1 && < 1.2
                    , text                   >= 1.2 && < 2
                    , bytestring             >= 0.10 && < 2
diff --git a/tests/Char.hs b/tests/Char.hs
--- a/tests/Char.hs
+++ b/tests/Char.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's character parsers.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Combinator.hs b/tests/Combinator.hs
--- a/tests/Combinator.hs
+++ b/tests/Combinator.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's generic parser combinators.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Error.hs b/tests/Error.hs
--- a/tests/Error.hs
+++ b/tests/Error.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's parse errors.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Expr.hs b/tests/Expr.hs
--- a/tests/Expr.hs
+++ b/tests/Expr.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's expression parsers.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
@@ -182,5 +182,5 @@
         c = s !! n
         n = succ $ length a'
         r | c == '-'  = Right $ Sub a b
-          | otherwise = posErr n s $ [uneCh c, exEof, exSpec "operator"]
+          | otherwise = posErr n s [uneCh c, exEof, exSpec "operator"]
         s = a' ++ " " ++ inParens b
diff --git a/tests/Lexer.hs b/tests/Lexer.hs
--- a/tests/Lexer.hs
+++ b/tests/Lexer.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's lexer.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
@@ -27,6 +27,8 @@
 -- ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 -- POSSIBILITY OF SUCH DAMAGE.
 
+{-# LANGUAGE TupleSections #-}
+
 module Lexer (tests) where
 
 import Control.Applicative (empty)
@@ -39,7 +41,7 @@
   , isSpace
   , toLower )
 import Data.List (findIndices, isInfixOf, find)
-import Data.Maybe (listToMaybe, maybeToList, isNothing, fromJust)
+import Data.Maybe
 import Numeric (showInt, showHex, showOct, showSigned)
 
 import Test.Framework
@@ -53,10 +55,11 @@
 import Text.Megaparsec.String
 import qualified Text.Megaparsec.Char as C
 
+import Prim () -- 'Arbitrary' instance for 'SourcePos'
 import Util
 
 #if !MIN_VERSION_base(4,8,0)
-import Control.Applicative ((<$>), (<*), (<*>))
+import Control.Applicative ((<$>), (<*), (<*>), (<$))
 #endif
 
 tests :: Test
@@ -64,7 +67,11 @@
         [ testProperty "space combinator"       prop_space
         , testProperty "symbol combinator"      prop_symbol
         , testProperty "symbol' combinator"     prop_symbol'
+        , testProperty "indentLevel"            prop_indentLevel
         , testProperty "indentGuard combinator" prop_indentGuard
+        , testProperty "nonIndented combinator" prop_nonIndented
+        , testProperty "indentBlock combinator" prop_indentBlock
+        , testProperty "indentBlock (many)"     prop_indentMany
         , testProperty "charLiteral"            prop_charLiteral
         , testProperty "integer"                prop_integer
         , testProperty "decimal"                prop_decimal
@@ -77,25 +84,28 @@
         , testProperty "number 2 (signed)"      prop_number_2
         , testProperty "signed"                 prop_signed ]
 
-newtype WhiteSpace = WhiteSpace
-  { getWhiteSpace :: String }
-  deriving (Show, Eq)
+-- White space
 
-instance Arbitrary WhiteSpace where
-  arbitrary = WhiteSpace . concat <$> listOf whiteUnit
+mkWhiteSpace :: Gen String
+mkWhiteSpace = concat <$> listOf whiteUnit
+  where whiteUnit = oneof [whiteChars, whiteLine, whiteBlock]
 
-newtype Symbol = Symbol
-  { getSymbol :: String }
-  deriving (Show, Eq)
+mkSymbol :: Gen String
+mkSymbol = (++) <$> symbolName <*> whiteChars
 
-instance Arbitrary Symbol where
-  arbitrary = Symbol <$> ((++) <$> symbolName <*> whiteChars)
+mkIndent :: String -> Int -> Gen String
+mkIndent x n = (++) <$> mkIndent' x n <*> eol
+  where eol = frequency [(5, return "\n"), (1, listOf1 (return '\n'))]
 
-whiteUnit :: Gen String
-whiteUnit = oneof [whiteChars, whiteLine, whiteBlock]
+mkIndent' :: String -> Int -> Gen String
+mkIndent' x n = concat <$> sequence [spc, sym, tra]
+  where spc = frequency [(5, vectorOf n itm), (1, listOf itm)]
+        tra = listOf itm
+        itm = elements " \t"
+        sym = return x
 
 whiteChars :: Gen String
-whiteChars = listOf $ elements "\t\n "
+whiteChars = listOf (elements "\t\n ")
 
 whiteLine :: Gen String
 whiteLine = commentOut <$> arbitrary `suchThat` goodEnough
@@ -118,53 +128,125 @@
 sc' :: Parser ()
 sc' = space (void $ C.oneOf " \t") empty empty
 
-prop_space :: WhiteSpace -> Property
-prop_space w = checkParser p r s
+prop_space :: Property
+prop_space = forAll mkWhiteSpace (checkParser p r)
   where p = sc
         r = Right ()
-        s = getWhiteSpace w
 
-prop_symbol :: Symbol -> Maybe Char -> Property
-prop_symbol = parseSymbol (symbol sc) id
+prop_symbol :: Maybe Char -> Property
+prop_symbol t = forAll mkSymbol $ \s ->
+  parseSymbol (symbol sc) id s t
 
-prop_symbol' :: Symbol -> Maybe Char -> Property
-prop_symbol' = parseSymbol (symbol' sc) (fmap toLower)
+prop_symbol' :: Maybe Char -> Property
+prop_symbol' t = forAll mkSymbol $ \s ->
+  parseSymbol (symbol' sc) (fmap toLower) s t
 
-parseSymbol :: (String -> Parser String) -> (String -> String)
-            -> Symbol -> Maybe Char -> Property
+parseSymbol
+  :: (String -> Parser String)
+  -> (String -> String)
+  -> String
+  -> Maybe Char
+  -> Property
 parseSymbol p' f s' t = checkParser p r s
   where p = p' (f g)
         r | g == s || isSpace (last s) = Right g
           | otherwise = posErr (length s - 1) s [uneCh (last s), exEof]
         g = takeWhile (not . isSpace) s
-        s = getSymbol s' ++ maybeToList t
+        s = s' ++ maybeToList t
 
-newtype IndLine = IndLine
-  { getIndLine :: String }
-  deriving (Show, Eq)
+-- Indentation
 
-instance Arbitrary IndLine where
-  arbitrary = IndLine . concat <$> sequence [spc, sym, spc, eol]
-    where spc = listOf (elements " \t")
-          sym = return "xxx"
-          eol = return "\n"
+prop_indentLevel :: SourcePos -> Property
+prop_indentLevel pos = p /=\ sourceColumn pos
+  where p = setPosition pos >> indentLevel
 
-prop_indentGuard :: IndLine -> IndLine -> IndLine -> Property
-prop_indentGuard l0 l1 l2 = checkParser p r s
-  where p  = ip (> 1) >>= \x -> sp >> ip (== x) >> sp >> ip (> x) >> sp
-        ip = indentGuard sc'
-        sp = void $ symbol sc' "xxx" <* C.eol
-        r | f' l0 <= 1     = posErr 0 s msg'
-          | f' l1 /= f' l0 = posErr (f l1 + g [l0]) s msg'
-          | f' l2 <= f' l0 = posErr (f l2 + g [l0, l1]) s msg'
+prop_indentGuard :: NonNegative Int -> Property
+prop_indentGuard n =
+  forAll ((,,) <$> mki <*> mki <*> mki) $ \(l0,l1,l2) ->
+    let r | getCol l0 <= 1         = posErr 0 s ii
+          | getCol l1 /= getCol l0 = posErr (getIndent l1 + g 1) s ii
+          | getCol l2 <= getCol l0 = posErr (getIndent l2 + g 2) s ii
           | otherwise = Right ()
-        msg' = [msg "incorrect indentation"]
-        f    = length . takeWhile isSpace . getIndLine
-        f' x = sourceColumn $ updatePosString defaultTabWidth (initialPos "") $
-               take (f x) (getIndLine x)
-        g xs = sum $ length . getIndLine <$> xs
-        s    = concat $ getIndLine <$> [l0, l1, l2]
+        fragments = [l0,l1,l2]
+        g x = sum (length <$> take x fragments)
+        s = concat fragments
+    in checkParser p r s
+  where mki = mkIndent sbla (getNonNegative n)
+        p  = ip (> 1) >>= \x -> sp >> ip (== x) >> sp >> ip (> x) >> sp >> sc
+        ip = indentGuard sc
+        sp = void (symbol sc' sbla <* C.eol)
 
+prop_nonIndented :: Property
+prop_nonIndented = forAll (mkIndent sbla 0) $ \s ->
+  let i = getIndent s
+      r | i == 0    = Right sbla
+        | otherwise = posErr i s ii
+  in checkParser p r s
+  where p = nonIndented sc (symbol sc sbla)
+
+prop_indentBlock :: Maybe (Positive Int) -> Property
+prop_indentBlock mn' = forAll mkBlock $ \(l0,l1,l2,l3,l4) ->
+  let r | getCol l1 <= getCol l0 =
+          posErr (getIndent l1 + g 1) s [uneCh (head sblb), exEof]
+        | isJust mn && getCol l1 /= ib =
+          posErr (getIndent l1 + g 1) s ii
+        | getCol l2 <= getCol l1 =
+          posErr (getIndent l2 + g 2) s ii
+        | getCol l3 == getCol l2 =
+          posErr (getIndent l3 + g 3) s [uneCh (head sblb), exStr sblc]
+        | getCol l3 <= getCol l0 =
+          posErr (getIndent l3 + g 3) s [uneCh (head sblb), exEof]
+        | getCol l3 /= getCol l1 =
+          posErr (getIndent l3 + g 3) s ii
+        | getCol l4 <= getCol l3 =
+          posErr (getIndent l4 + g 4) s ii
+        | otherwise = Right (sbla, [(sblb, [sblc]), (sblb, [sblc])])
+      fragments = [l0,l1,l2,l3,l4]
+      g x = sum (length <$> take x fragments)
+      s = concat fragments
+  in checkParser p r s
+  where mkBlock = do
+          l0 <- mkIndent sbla 0
+          l1 <- mkIndent sblb ib
+          l2 <- mkIndent sblc (ib + 2)
+          l3 <- mkIndent sblb ib
+          l4 <- mkIndent' sblc (ib + 2)
+          return (l0,l1,l2,l3,l4)
+        p = lvla
+        lvla = indentBlock sc $ IndentMany mn      (l sbla) lvlb <$ b sbla
+        lvlb = indentBlock sc $ IndentSome Nothing (l sblb) lvlc <$ b sblb
+        lvlc = indentBlock sc $ IndentNone                  sblc <$ b sblc
+        b    = symbol sc'
+        l x  = return . (x,)
+        mn   = getPositive <$> mn'
+        ib   = fromMaybe 2 mn
+
+prop_indentMany :: Property
+prop_indentMany = forAll (mkIndent sbla 0) (checkParser p r)
+  where r = Right (sbla, [])
+        p = lvla
+        lvla = indentBlock sc $ IndentMany Nothing (l sbla) lvlb <$ b sbla
+        lvlb = b sblb
+        b    = symbol sc'
+        l x  = return . (x,)
+
+getIndent :: String -> Int
+getIndent = length . takeWhile isSpace
+
+getCol :: String -> Int
+getCol x = sourceColumn $
+  updatePosString defaultTabWidth (initialPos "") $ take (getIndent x) x
+
+sbla, sblb, sblc :: String
+sbla = "xxx"
+sblb = "yyy"
+sblc = "zzz"
+
+ii :: [Message]
+ii = [msg "incorrect indentation"]
+
+-- Character and string literals
+
 prop_charLiteral :: String -> Bool -> Property
 prop_charLiteral t i = checkParser charLiteral r s
   where b = listToMaybe $ readLitChar s
@@ -176,6 +258,8 @@
         l = length s - length g
         s = if null t || i then t else showLitChar (head t) (tail t)
 
+-- Numbers
+
 prop_integer :: NonNegative Integer -> Int -> Property
 prop_integer n' i = checkParser integer r s
   where (r, s) = quasiCorrupted n' i showInt "integer"
@@ -227,11 +311,11 @@
   where p = signed (hidden C.space) integer
         r | i > length z = Right n
           | otherwise = posErr i s $ uneCh '?' :
-                        (if i <= 0 then [exCh '+', exCh '-'] else []) ++
-                        [exSpec $ if isNothing . find isDigit $ take i s
-                                  then "integer"
-                                  else "rest of integer"]
-                        ++ [exEof | i > head (findIndices isDigit s)]
+            (if i <= 0 then [exCh '+', exCh '-'] else []) ++
+            [exSpec $ if isNothing . find isDigit $ take i s
+                      then "integer"
+                      else "rest of integer"] ++
+            [exEof | i > head (findIndices isDigit s)]
         z = let bar = showSigned showInt 0 n ""
             in if n < 0 || plus then bar else '+' : bar
         s = if i <= length z then take i z ++ "?" ++ drop i z else z
@@ -243,9 +327,9 @@
   where n = getNonNegative n'
         r | i > length z = Right n
           | otherwise    = posErr i s $ uneCh '?' :
-                           [ exEof | i > 0 ] ++
-                           [if i <= 0 || null l
-                            then exSpec l
-                            else exSpec $ "rest of " ++ l]
+            [ exEof | i > 0 ] ++
+            [if i <= 0 || null l
+             then exSpec l
+             else exSpec $ "rest of " ++ l]
         z = shower n ""
         s = if i <= length z then take i z ++ "?" ++ drop i z else z
diff --git a/tests/Main.hs b/tests/Main.hs
--- a/tests/Main.hs
+++ b/tests/Main.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec, main module.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Perm.hs b/tests/Perm.hs
--- a/tests/Perm.hs
+++ b/tests/Perm.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's permutation phrases parsers.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Pos.hs b/tests/Pos.hs
--- a/tests/Pos.hs
+++ b/tests/Pos.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's textual source positions.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
diff --git a/tests/Prim.hs b/tests/Prim.hs
--- a/tests/Prim.hs
+++ b/tests/Prim.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec's primitive parser combinators.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
@@ -228,7 +228,7 @@
         s = ""
 
 prop_monad_left_id :: Integer -> Integer -> Property
-prop_monad_left_id a b = (return a >>= f) !=! (f a)
+prop_monad_left_id a b = (return a >>= f) !=! f a
   where f x = return $ x + b
 
 prop_monad_right_id :: Integer -> Property
diff --git a/tests/Util.hs b/tests/Util.hs
--- a/tests/Util.hs
+++ b/tests/Util.hs
@@ -2,7 +2,7 @@
 --
 -- QuickCheck tests for Megaparsec, utility functions for parser testing.
 --
--- Copyright © 2015 Megaparsec contributors
+-- Copyright © 2015–2016 Megaparsec contributors
 --
 -- Redistribution and use in source and binary forms, with or without
 -- modification, are permitted provided that the following conditions are
