diff --git a/CHANGELOG.markdown b/CHANGELOG.markdown
--- a/CHANGELOG.markdown
+++ b/CHANGELOG.markdown
@@ -1,3 +1,13 @@
+2.2.2
+-----
+* `Control.Monad.Identity` now re-exports `Control.Monad.Trans.Identity`
+* Fix a bug in which `Control.Monad.State.Class.modify'` was not as strict in
+  the new state as its counterparts in `transformers`
+* Add a `MonadError () Maybe` instance
+* Add `liftEither :: MonadError e m => Either e a -> m a` to
+  `Control.Monad.Except{.Class}`
+* Add a `MonadWriter w ((,) w)` instance (when built against `base-4.9` or later)
+
 2.2.1
 -------
 * Provide MINIMAL pragmas for `MonadState`, `MonadWriter`, `MonadReader`
diff --git a/Control/Monad/Cont/Class.hs b/Control/Monad/Cont/Class.hs
--- a/Control/Monad/Cont/Class.hs
+++ b/Control/Monad/Cont/Class.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 {- |
 Module      :  Control.Monad.Cont.Class
 Copyright   :  (c) The University of Glasgow 2001,
@@ -90,6 +91,9 @@
     even if it is many layers deep within nested computations.
     -}
     callCC :: ((a -> m b) -> m a) -> m a
+#if __GLASGOW_HASKELL__ >= 707
+    {-# MINIMAL callCC #-}
+#endif
 
 instance MonadCont (ContT r m) where
     callCC = ContT.callCC
@@ -100,6 +104,7 @@
 instance (Error e, MonadCont m) => MonadCont (ErrorT e m) where
     callCC = Error.liftCallCC callCC
 
+{- | @since 2.2 -}
 instance MonadCont m => MonadCont (ExceptT e m) where
     callCC = Except.liftCallCC callCC
 
diff --git a/Control/Monad/Error.hs b/Control/Monad/Error.hs
--- a/Control/Monad/Error.hs
+++ b/Control/Monad/Error.hs
@@ -22,7 +22,7 @@
 [Zero and plus:] Zero is represented by an empty error and the plus operation
 executes its second argument if the first fails.
 
-[Example type:] @'Data.Either' String a@
+[Example type:] @'Either' String a@
 
 The Error monad (also called the Exception monad).
 -}
@@ -33,7 +33,7 @@
     Andy Gill (<http://web.cecs.pdx.edu/~andy/>)
 -}
 module Control.Monad.Error
-  {-# DEPRECATED "Use Control.Monad.Except instead" #-} (
+  {-# DEPRECATED "Use \"Control.Monad.Except\" instead" #-} (
     -- * Monads with error handling
     MonadError(..),
     Error(..),
diff --git a/Control/Monad/Error/Class.hs b/Control/Monad/Error/Class.hs
--- a/Control/Monad/Error/Class.hs
+++ b/Control/Monad/Error/Class.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 
 {- |
@@ -38,6 +41,7 @@
 module Control.Monad.Error.Class (
     Error(..),
     MonadError(..),
+    liftEither,
   ) where
 
 import Control.Monad.Trans.Except (Except, ExceptT)
@@ -64,7 +68,7 @@
 #endif
 
 import Data.Monoid
-import Prelude (Either(..), (.), IO)
+import Prelude (Either(..), Maybe(..), either, (.), IO)
 
 {- |
 The strategy of combining computations that can throw exceptions
@@ -73,14 +77,16 @@
 
 Is parameterized over the type of error information and
 the monad type constructor.
-It is common to use @'Data.Either' String@ as the monad type constructor
+It is common to use @'Either' String@ as the monad type constructor
 for an error monad in which error descriptions take the form of strings.
 In that case and many other common cases the resulting monad is already defined
 as an instance of the 'MonadError' class.
 You can also define your own error type and\/or use a monad type constructor
 other than @'Either' 'String'@ or @'Either' 'IOError'@.
-In these cases you will have to explicitly define instances of the 'Error'
-and\/or 'MonadError' classes.
+In these cases you will have to explicitly define instances of the 'MonadError'
+class.
+(If you are using the deprecated "Control.Monad.Error" or
+"Control.Monad.Trans.Error", you may also have to define an 'Error' instance.)
 -}
 class (Monad m) => MonadError e m | m -> e where
     -- | Is used within a monadic computation to begin exception processing.
@@ -96,11 +102,32 @@
     Note that @handler@ and the do-block must have the same return type.
     -}
     catchError :: m a -> (e -> m a) -> m a
+#if __GLASGOW_HASKELL__ >= 707
+    {-# MINIMAL throwError, catchError #-}
+#endif
 
+{- |
+Lifts an @'Either' e@ into any @'MonadError' e@.
+
+> do { val <- liftEither =<< action1; action2 }
+
+where @action1@ returns an 'Either' to represent errors.
+
+@since 2.2.2
+-}
+liftEither :: MonadError e m => Either e a -> m a
+liftEither = either throwError return
+
 instance MonadError IOException IO where
     throwError = ioError
     catchError = catch
 
+{- | @since 2.2.2 -}
+instance MonadError () Maybe where
+    throwError ()        = Nothing
+    catchError Nothing f = f ()
+    catchError x       _ = x
+
 -- ---------------------------------------------------------------------------
 -- Our parameterizable error monad
 
@@ -113,6 +140,7 @@
     throwError = ErrorT.throwError
     catchError = ErrorT.catchError
 
+{- | @since 2.2 -}
 instance Monad m => MonadError e (ExceptT e m) where
     throwError = ExceptT.throwE
     catchError = ExceptT.catchE
diff --git a/Control/Monad/Except.hs b/Control/Monad/Except.hs
--- a/Control/Monad/Except.hs
+++ b/Control/Monad/Except.hs
@@ -1,6 +1,6 @@
 {-# LANGUAGE CPP #-}
 {- |
-Module      :  Control.Monad.Error
+Module      :  Control.Monad.Except
 Copyright   :  (c) Michael Weber <michael.weber@post.rwth-aachen.de> 2001,
                (c) Jeff Newbern 2003-2006,
                (c) Andriy Palamarchuk 2006
@@ -19,9 +19,11 @@
 [Useful for:] Building computations from sequences of functions that may fail
 or using exception handling to structure error handling.
 
-[Example type:] @'Data.Either' String a@
+[Example type:] @'Either' String a@
 
 The Error monad (also called the Exception monad).
+
+@since 2.2.1
 -}
 
 {-
@@ -31,9 +33,12 @@
 -}
 module Control.Monad.Except
   (
+    -- * Warning
+    -- $warning
     -- * Monads with error handling
     MonadError(..),
-    -- * The ErrorT monad transformer
+    liftEither,
+    -- * The ExceptT monad transformer
     ExceptT(ExceptT),
     Except,
 
@@ -70,6 +75,18 @@
 import Control.Monad.Instances ()
 #endif
 
+{- $warning
+Please do not confuse 'ExceptT' and 'throwError' with 'Control.Exception.Exception' /
+'Control.Exception.SomeException' and 'Control.Exception.catch', respectively. The latter
+are for exceptions built into GHC, by default, and are mostly used from within the IO monad.
+They do not interact with the \"exceptions\" in this package at all. This package allows you
+to define a new kind of exception control mechanism which does not necessarily need your code to
+be placed in the IO monad.
+
+In short, all \"catching\" mechanisms in this library will be unable to catch exceptions thrown
+by functions in the "Control.Exception" module, and vice-versa.
+-}
+
 {- $customErrorExample
 Here is an example that demonstrates the use of a custom error data type with
 the 'throwError' and 'catchError' exception mechanism from 'MonadError'.
@@ -99,18 +116,13 @@
 >  s <- getLine
 >  reportResult (calculateLength s)
 >
->-- Wraps length calculation to catch the errors.
->-- Returns either length of the string or an error.
->calculateLength :: String -> LengthMonad Int
->calculateLength s = (calculateLengthOrFail s) `catchError` Left
->
 >-- Attempts to calculate length and throws an error if the provided string is
 >-- empty or longer than 5 characters.
->-- The processing is done in Either monad.
->calculateLengthOrFail :: String -> LengthMonad Int
->calculateLengthOrFail [] = throwError EmptyString
->calculateLengthOrFail s | len > 5 = throwError (StringTooLong len)
->                        | otherwise = return len
+>-- (Throwing an error in this monad means returning a 'Left'.)
+>calculateLength :: String -> LengthMonad Int
+>calculateLength [] = throwError EmptyString
+>calculateLength s | len > 5 = throwError (StringTooLong len)
+>                  | otherwise = return len
 >  where len = length s
 >
 >-- Prints result of the string length calculation.
diff --git a/Control/Monad/Identity.hs b/Control/Monad/Identity.hs
--- a/Control/Monad/Identity.hs
+++ b/Control/Monad/Identity.hs
@@ -13,7 +13,7 @@
 [Computation type:] Simple function application.
 
 [Binding strategy:] The bound function is applied to the input value.
-@'Identity' x >>= f == 'Identity' (f x)@
+@'Identity' x >>= f == f x@
 
 [Useful for:] Monads can be derived from monad transformers applied to the
 'Identity' monad.
@@ -34,11 +34,14 @@
 
 module Control.Monad.Identity (
     module Data.Functor.Identity,
+    module Control.Monad.Trans.Identity,
 
     module Control.Monad,
     module Control.Monad.Fix,
    ) where
 
+import Data.Functor.Identity
+import Control.Monad.Trans.Identity
+
 import Control.Monad
 import Control.Monad.Fix
-import Data.Functor.Identity
diff --git a/Control/Monad/RWS/Class.hs b/Control/Monad/RWS/Class.hs
--- a/Control/Monad/RWS/Class.hs
+++ b/Control/Monad/RWS/Class.hs
@@ -1,3 +1,6 @@
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- Search for UndecidableInstances to see why this is needed
 
@@ -54,6 +57,7 @@
 -- All of these instances need UndecidableInstances,
 -- because they do not satisfy the coverage condition.
 
+-- | @since 2.2
 instance MonadRWS r w s m => MonadRWS r w s (ExceptT e m)
 instance (Error e, MonadRWS r w s m) => MonadRWS r w s (ErrorT e m)
 instance MonadRWS r w s m => MonadRWS r w s (IdentityT m)
diff --git a/Control/Monad/Reader.hs b/Control/Monad/Reader.hs
--- a/Control/Monad/Reader.hs
+++ b/Control/Monad/Reader.hs
@@ -96,7 +96,7 @@
 >-- The selector function to  use with 'asks'.
 >-- Returns value of the variable with specified name.
 >lookupVar :: String -> Bindings -> Int
->lookupVar name bindings = fromJust (Map.lookup name bindings)
+>lookupVar name bindings = maybe 0 id (Map.lookup name bindings)
 >
 >sampleBindings = Map.fromList [("count",3), ("1",1), ("b",2)]
 >
@@ -130,7 +130,7 @@
 
 Now you are thinking: 'Wow, what a great monad! I wish I could use
 Reader functionality in MyFavoriteComplexMonad!'. Don't worry.
-This can be easy done with the 'ReaderT' monad transformer.
+This can be easily done with the 'ReaderT' monad transformer.
 This example shows how to combine @ReaderT@ with the IO monad.
 
 >-- The Reader/IO combined monad, where Reader stores a string.
diff --git a/Control/Monad/Reader/Class.hs b/Control/Monad/Reader/Class.hs
--- a/Control/Monad/Reader/Class.hs
+++ b/Control/Monad/Reader/Class.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- Search for UndecidableInstances to see why this is needed
 {- |
@@ -70,7 +73,7 @@
 -- Note, the partially applied function type @(->) r@ is a simple reader monad.
 -- See the @instance@ declaration below.
 class Monad m => MonadReader r m | m -> r where
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707
+#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL (ask | reader), local #-}
 #endif
     -- | Retrieves the monad environment.
@@ -134,6 +137,7 @@
     local = mapErrorT . local
     reader = lift . reader
 
+{- | @since 2.2 -}
 instance MonadReader r m => MonadReader r (ExceptT e m) where
     ask   = lift ask
     local = mapExceptT . local
diff --git a/Control/Monad/State/Class.hs b/Control/Monad/State/Class.hs
--- a/Control/Monad/State/Class.hs
+++ b/Control/Monad/State/Class.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- Search for UndecidableInstances to see why this is needed
 
@@ -66,7 +69,7 @@
       let ~(a, s') = f s
       put s'
       return a
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707
+#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL state | get, put #-}
 #endif
 
@@ -86,8 +89,12 @@
 
 -- | A variant of 'modify' in which the computation is strict in the
 -- new state.
+--
+-- @since 2.2
 modify' :: MonadState s m => (s -> s) -> m ()
-modify' f = state (\s -> let s' = f s in s' `seq` ((), s'))
+modify' f = do
+  s' <- get
+  put $! f s'
 
 -- | Gets specific component of the state, using a projection function
 -- supplied.
@@ -132,6 +139,7 @@
     put = lift . put
     state = lift . state
 
+-- | @since 2.2
 instance MonadState s m => MonadState s (ExceptT e m) where
     get = lift get
     put = lift . put
diff --git a/Control/Monad/State/Lazy.hs b/Control/Monad/State/Lazy.hs
--- a/Control/Monad/State/Lazy.hs
+++ b/Control/Monad/State/Lazy.hs
@@ -59,7 +59,7 @@
 -- $examples
 -- A function to increment a counter.  Taken from the paper
 -- /Generalising Monads to Arrows/, John
--- Hughes (<http://www.math.chalmers.se/~rjmh/>), November 1998:
+-- Hughes (<http://www.cse.chalmers.se/~rjmh/Papers/arrows.pdf>), November 1998:
 --
 -- > tick :: State Int Int
 -- > tick = do n <- get
diff --git a/Control/Monad/Writer/Class.hs b/Control/Monad/Writer/Class.hs
--- a/Control/Monad/Writer/Class.hs
+++ b/Control/Monad/Writer/Class.hs
@@ -1,4 +1,7 @@
 {-# LANGUAGE CPP #-}
+{-# LANGUAGE FlexibleInstances #-}
+{-# LANGUAGE FunctionalDependencies #-}
+{-# LANGUAGE MultiParamTypeClasses #-}
 {-# LANGUAGE UndecidableInstances #-}
 -- Search for UndecidableInstances to see why this is needed
 
@@ -60,7 +63,7 @@
 -- the written object.
 
 class (Monoid w, Monad m) => MonadWriter w m | m -> w where
-#if defined(__GLASGOW_HASKELL__) && __GLASGOW_HASKELL__ >= 707
+#if __GLASGOW_HASKELL__ >= 707
     {-# MINIMAL (writer | tell), listen, pass #-}
 #endif
     -- | @'writer' (a,w)@ embeds a simple writer action.
@@ -100,6 +103,17 @@
     a <- m
     return (a, f)
 
+#if MIN_VERSION_base(4,9,0)
+-- | __NOTE__: This instance is only defined for @base >= 4.9.0@.
+--
+-- @since 2.2.2
+instance (Monoid w) => MonadWriter w ((,) w) where
+  writer ~(a, w) = (w, a)
+  tell w = (w, ())
+  listen ~(w, a) = (w, (a, w))
+  pass ~(w, (a, f)) = (f w, a)
+#endif
+
 instance (Monoid w, Monad m) => MonadWriter w (Lazy.WriterT w m) where
     writer = Lazy.writer
     tell   = Lazy.tell
@@ -136,6 +150,7 @@
     listen = Error.liftListen listen
     pass   = Error.liftPass pass
 
+-- | @since 2.2
 instance MonadWriter w m => MonadWriter w (ExceptT e m) where
     writer = lift . writer
     tell   = lift . tell
diff --git a/README.markdown b/README.markdown
new file mode 100644
--- /dev/null
+++ b/README.markdown
@@ -0,0 +1,4 @@
+The `mtl` Package  [![Hackage](https://img.shields.io/hackage/v/mtl.svg)](https://hackage.haskell.org/package/mtl) [![Build Status](https://travis-ci.org/haskell/mtl.svg)](https://travis-ci.org/haskell/mtl)
+=====================
+
+See [`mtl` on Hackage](http://hackage.haskell.org/package/mtl) for more information.
diff --git a/mtl.cabal b/mtl.cabal
--- a/mtl.cabal
+++ b/mtl.cabal
@@ -1,14 +1,14 @@
 name:         mtl
-version:      2.2.1
-cabal-version: >= 1.6
+version:      2.2.2
+cabal-version: >= 1.10
 license:      BSD3
 license-file: LICENSE
 author:       Andy Gill
 maintainer:   Edward Kmett <ekmett@gmail.com>
 category:     Control
 synopsis:     Monad classes, using functional dependencies
-homepage:     http://github.com/ekmett/mtl
-bug-reports:  http://github.com/ekmett/mtl/issues
+homepage:     http://github.com/haskell/mtl
+bug-reports:  http://github.com/haskell/mtl/issues
 description:
     Monad classes using functional dependencies, with instances
     for various monad transformers, inspired by the paper
@@ -16,11 +16,21 @@
     by Mark P Jones, in /Advanced School of Functional Programming/, 1995
     (<http://web.cecs.pdx.edu/~mpj/pubs/springschool.html>).
 build-type: Simple
-extra-source-files: CHANGELOG.markdown
+extra-source-files: CHANGELOG.markdown, README.markdown
+tested-with:
+  GHC==7.0.4,
+  GHC==7.2.2,
+  GHC==7.4.2,
+  GHC==7.6.3,
+  GHC==7.8.4,
+  GHC==7.10.3,
+  GHC==8.0.2,
+  GHC==8.2.2,
+  GHC==8.4.1
 
 source-repository head
   type: git
-  location: git://github.com/ekmett/mtl.git
+  location: https://github.com/haskell/mtl.git
 
 Library
   exposed-modules:
@@ -46,9 +56,22 @@
     Control.Monad.Writer.Class
     Control.Monad.Writer.Lazy
     Control.Monad.Writer.Strict
-  build-depends: base < 6, transformers == 0.4.*
-  extensions:
+  build-depends: base < 5, transformers >= 0.4 && <0.6
+
+  default-language: Haskell2010
+  other-extensions:
+    CPP
     MultiParamTypeClasses
     FunctionalDependencies
     FlexibleInstances
+    UndecidableInstances
+
+  -- This is a SafeHaskell safeguard (pun intended) to explicitly declare the API contract of `mtl`
+  -- GHC versions before 7.4 were hopelessly broken or incapable of SafeHaskell
+  if impl(ghc >= 7.4)
+    default-extensions: Safe
+
   ghc-options: -Wall -fno-warn-unused-imports -fno-warn-warnings-deprecations
+
+  if impl(ghc >= 8.0)
+    ghc-options: -Wcompat -Wnoncanonical-monad-instances -Wnoncanonical-monadfail-instances
