diff --git a/hlint.cabal b/hlint.cabal
--- a/hlint.cabal
+++ b/hlint.cabal
@@ -1,7 +1,7 @@
 cabal-version:      >= 1.6
 build-type:         Simple
 name:               hlint
-version:            1.8.3
+version:            1.8.4
 -- license is GPL v2 only
 license:            GPL
 license-file:       LICENSE
@@ -38,7 +38,7 @@
         transformers == 0.2.*,
         hscolour == 1.17.*,
         cpphs == 1.11.*,
-        haskell-src-exts == 1.9.* && >= 1.9.6,
+        haskell-src-exts >= 1.9.6 && < 1.11,
         uniplate >= 1.5 && < 1.7
 
     hs-source-dirs:     src
diff --git a/hlint.htm b/hlint.htm
--- a/hlint.htm
+++ b/hlint.htm
@@ -85,6 +85,7 @@
 <ul>
 	<li>The presence of <tt>seq</tt> may cause some hints (i.e. eta-reduction) to change the semantics of a program.</li>
 	<li>Either the monomorphism restriction, or rank-2 types, may cause transformed programs to require type signatures to be manually inserted.</li>
+	<li>HLint operates on each module at a time in isolation, as a result HLint does not know about types or which names are in scope.</li>
 </ul>
 
 <h2 id="installation">Installing and running HLint</h2>
diff --git a/src/Hint/Extensions.hs b/src/Hint/Extensions.hs
--- a/src/Hint/Extensions.hs
+++ b/src/Hint/Extensions.hs
@@ -25,6 +25,8 @@
 data Set (cxt :: * -> *) a = Set [a]
 {-# LANGUAGE RecordWildCards #-} \
 record field = Record{..}
+{-# LANGUAGE RecordWildCards #-} \
+record = 1 -- {-# LANGUAGE DisambiguateRecordFields #-}
 </TEST>
 -}
 
@@ -33,17 +35,32 @@
 
 import Hint.Type
 import Data.Maybe
+import Data.List
 import Util
 
 
 extensionsHint :: ModuHint
 extensionsHint _ x = [rawIdea Error "Unused LANGUAGE pragma" (toSrcLoc sl)
-          (prettyPrint o) (if null new then "" else prettyPrint $ LanguagePragma sl new)
+          (prettyPrint o) (if null new then "" else prettyPrint $ LanguagePragma sl $ map (toNamed . showExt) new)
     | not $ used TemplateHaskell x -- if TH is on, can use all other extensions programmatically
-    , o@(LanguagePragma sl old) <- modulePragmas x
-    , let new = filter (flip used x . classifyExtension . prettyPrint) old
-    , length new /= length old]
+    , o@(LanguagePragma sl exts) <- modulePragmas x
+    , let old = map (classifyExtension . prettyPrint) exts
+    , let new = minimalExtensions x old
+    , sort new /= sort old]
+    where
+        showExt (UnknownExtension x) = x
+        showExt x = show x
 
+
+minimalExtensions :: Module_ -> [Extension] -> [Extension]
+minimalExtensions x es = nub $ concatMap f es
+    where f e = if used e x then [e] else concatMap f $ implies e
+
+
+-- sometimes one extension implies others, this captures that
+implies :: Extension -> [Extension]
+implies RecordWildCards = [DisambiguateRecordFields]
+implies _ = []
 
 used :: Extension -> Module_ -> Bool
 used RecursiveDo = hasS isMDo
diff --git a/src/Hint/Import.hs b/src/Hint/Import.hs
--- a/src/Hint/Import.hs
+++ b/src/Hint/Import.hs
@@ -26,7 +26,10 @@
 import B; import A; import A -- import A
 import A hiding(Foo); import A hiding(Bar)
 import List -- import Data.List
-import IO(foo) -- import System.IO(foo)
+import qualified List -- import qualified Data.List as List
+import Char(foo) -- import Data.Char(foo)
+import IO(foo)
+import IO as X -- import System.IO as X; import System.IO.Error as X; import Control.Exception  as X (bracket,bracket_)
 </TEST>
 -}
 
@@ -64,14 +67,6 @@
     Just xy -> Just $ xy : ys
 
 
--- Useful fields in import are:
--- importModule :: ModuleName [same]
--- importPkg :: Maybe String [same]
--- importQualified :: Bool
--- importSrc :: Bool [False]
--- importAs :: Maybe ModuleName
--- importSpecs :: Maybe (Bool, [ImportSpec])
-
 reduce :: ImportDecl S -> ImportDecl S -> Maybe (ImportDecl S)
 reduce x y | qual, as, specs = Just x
            | qual, as, Just (ImportSpecList _ False xs) <- importSpecs x, Just (ImportSpecList _ False ys) <- importSpecs y =
@@ -95,13 +90,33 @@
     ,"Data" * "Maybe"
     ,"Data" * "Ratio"
     ,"System" * "Directory"
-    ,"System" * "IO"
+
+    -- Special, see bug #393
+    -- ,"System" * "IO"
+
     -- Do not encourage use of old-locale/old-time over haskell98
     -- ,"System" * "Locale"
     -- ,"System" * "Time"
     ]
 
+
 hierarchy :: ImportDecl S -> [Idea]
-hierarchy i@ImportDecl{importModule=ModuleName _ x} | Just y <- lookup x newNames
-    = [warn "Use hierarchical imports" i i{importModule=ModuleName an $ y ++ "." ++ x}]
+hierarchy i@ImportDecl{importModule=ModuleName _ x,importPkg=Nothing} | Just y <- lookup x newNames
+    = [warn "Use hierarchical imports" i (desugarQual i){importModule=ModuleName an $ y ++ "." ++ x}]
+
+-- import IO is equivalent to
+-- import System.IO, import System.IO.Error, import Control.Exception(bracket, bracket_)
+hierarchy i@ImportDecl{importModule=ModuleName _ "IO", importSpecs=Nothing,importPkg=Nothing}
+    = [rawIdea Warning "Use hierarchical imports" (toSrcLoc $ ann i) (ltrim $ prettyPrint i) $
+          unlines $ map (ltrim . prettyPrint)
+          [f "System.IO" Nothing, f "System.IO.Error" Nothing
+          ,f "Control.Exception" $ Just $ ImportSpecList an False [IVar an $ toNamed x | x <- ["bracket","bracket_"]]]]
+    where f a b = (desugarQual i){importModule=ModuleName an a, importSpecs=b}
+
 hierarchy _ = []
+
+
+-- import qualified X ==> import qualified X as X
+desugarQual :: ImportDecl S -> ImportDecl S
+desugarQual x | importQualified x && isNothing (importAs x) = x{importAs=Just (importModule x)}
+              | otherwise = x
