diff --git a/selftest/Makefile b/selftest/Makefile
index b849076..6a33442 100644
--- a/selftest/Makefile
+++ b/selftest/Makefile
@@ -1,12 +1,21 @@
 INC= -i -i../drift_processed -i../src
-GHCOPTS= -fallow-overlapping-instances -fallow-undecidable-instances -fglasgow-exts \
-	 -XBangPatterns $(INC) -XTypeFamilies -XViewPatterns -XRecordWildCards \
-	 -O -package QuickCheck -ignore-package lang  -optc-std=c99 -optc-g \
+GHCOPTS= -XBangPatterns $(INC) \
+	-O -package QuickCheck -ignore-package lang  -optc-std=c99 \
 	-XTypeFamilies -XViewPatterns -XUndecidableInstances -XOverlappingInstances \
 	-XRecordWildCards -XRecursiveDo -XTupleSections -XParallelListComp \
 	-XGeneralizedNewtypeDeriving -XScopedTypeVariables -XFlexibleInstances \
 	-XTypeSynonymInstances -XMultiParamTypeClasses -XDeriveDataTypeable \
-	-fglasgow-exts -XNoMonoLocalBinds -XNamedFieldPuns  -I../src
+	-XForeignFunctionInterface -XUnliftedFFITypes -XImplicitParams \
+	-XScopedTypeVariables -XUnboxedTuples -XTypeSynonymInstances -XStandaloneDeriving \
+	-XDeriveDataTypeable -XDeriveFunctor -XDeriveFoldable -XDeriveTraversable \
+	-XDeriveGeneric -XFlexibleContexts -XFlexibleInstances -XConstrainedClassMethods \
+	-XMultiParamTypeClasses -XFunctionalDependencies -XMagicHash -XPolymorphicComponents \
+	-XExistentialQuantification -XUnicodeSyntax -XPostfixOperators -XPatternGuards \
+	-XLiberalTypeSynonyms -XRankNTypes -XTypeOperators \
+	-XParallelListComp -XEmptyDataDecls -XKindSignatures -XGeneralizedNewtypeDeriving \
+	-XNoMonoLocalBinds -XNamedFieldPuns  -I../src
+# Setting -optc-g occur link error on gcc. (on GHC 7.4.1)
+# Error: can't resolve `.debug-ghc-link-info' {.debug-ghc-link-info section} - `.Ltext0' {.text section}
 
 HC= ghc
 
@@ -20,5 +29,8 @@ TempDir: TempDir.hs ../src/Support/TempDir.hs
 %: %.hs
 	$(HC) $(GHCOPTS) --make $< -o $@  -I../src/cbits ../src/cbits/md5sum.c ../src/StringTable/StringTable_cbits.c ../src/cbits/lookup3.c
 
+test: all
+	./SelfTest
+
 clean:
-	rm -f -- md5 sha1 TestParse cff SelfTest
+	rm -f -- md5 sha1 TestParse cff SelfTest TempDir UnionSolve
diff --git a/selftest/SelfTest.hs b/selftest/SelfTest.hs
index 0818543..30be187 100644
--- a/selftest/SelfTest.hs
+++ b/selftest/SelfTest.hs
@@ -1,10 +1,15 @@
+{-# LANGUAGE TemplateHaskell #-}
 import Data.Monoid
-import List(sort,nub)
-import Monad
+import Data.List(sort,nub)
+import Control.Monad
 import System.IO
+import Test.Framework.TH
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
 import Test.QuickCheck
+import Test.HUnit
 import qualified Data.Set as Set
-import qualified List
+import qualified Data.List
 
 import Data.Binary
 import E.Arbitrary
@@ -26,40 +31,24 @@ import qualified Info.Info as Info
 
 {-# NOINLINE main #-}
 main :: IO ()
-main = do
-    testAtom
-    testProperties
-    testPackedString
-    testHasSize
-    testName
-    testInfo
-    testBinary
-
-qc s p = quickCheck $ label s p
-
-testAtom = do
-    let prop_atomneq xs ys = (xs /= ys) == (a1 /= a2) where
-            a1 = toAtom xs
-            a2 = toAtom (ys :: String)
-        prop_atomIndex (xs :: String) = intToAtom (fromAtom a) == Just a where
-            a = toAtom xs
-        prop_atomneq' xs ys = (xs `compare` ys) == (fromAtom a1 `compare` (fromAtom a2 :: BS.ByteString)) where
-            a1 = toAtom xs
-            a2 = toAtom (ys :: String)
-        prop_atomint xs = an > 0 && odd an where
-            an = fromAtom $ toAtom (xs :: String) :: Int
-        prop_atomii xs = Just xs == fromAtom `fmap` (intToAtom an) where
-            an = fromAtom $ toAtom (xs :: String) :: Int
-        prop_aappend (xs,ys) = (toAtom xs `mappend` toAtom ys) == toAtom ((xs::String) ++ ys)
-        prop_aappend' (xs,ys) = fromAtom (toAtom xs `mappend` toAtom ys) == ((xs::String) ++ ys)
-    qc "atom.id" $ \xs -> fromAtom (toAtom xs) == (xs::String)
-    qc "atom.eq" $ \xs -> (toAtom xs) == toAtom (xs::String)
-    qc "atom.index" prop_atomIndex
-    qc "atom.neq" prop_atomneq
-    qc "atom.eq'" prop_atomneq'
-    qc "atom.int" prop_atomint
-    qc "atom.ii" prop_atomii
-    qc "atom.aapend" prop_aappend
+main = $(defaultMainGenerator)
+
+prop_atom_id xs = fromAtom (toAtom xs) == (xs::String)
+prop_atom_eq xs = (toAtom xs) == toAtom (xs::String)
+prop_atom_index (xs :: String) = intToAtom (fromAtom a) == Just a where
+  a = toAtom xs
+prop_atom_neq xs ys = (xs /= ys) == (a1 /= a2) where
+  a1 = toAtom xs
+  a2 = toAtom (ys :: String)
+prop_atom_neq' xs ys = (xs `compare` ys) == (fromAtom a1 `compare` (fromAtom a2 :: BS.ByteString)) where
+  a1 = toAtom xs
+  a2 = toAtom (ys :: String)
+prop_atom_int xs = an > 0 && odd an where
+  an = fromAtom $ toAtom (xs :: String) :: Int
+prop_atom_ii xs = Just xs == fromAtom `fmap` (intToAtom an) where
+  an = fromAtom $ toAtom (xs :: String) :: Int
+prop_atom_aappend (xs,ys) = (toAtom xs `mappend` toAtom ys) == toAtom ((xs::String) ++ ys)
+prop_atom_aappend' (xs,ys) = fromAtom (toAtom xs `mappend` toAtom ys) == ((xs::String) ++ ys) -- xxx need?
 
 --strings = [ "foo", "foobar", "baz", "", "bob"]
 strings =  ["h","n\206^um\198(","\186","yOw\246$\187x#",";\221x<n","\201\209\236\213J\244\233","\189eW\176v\175\209"]
@@ -67,16 +56,11 @@ strings =  ["h","n\206^um\198(","\186","yOw\246$\187x#",";\221x<n","\201\209\236
 appendPS :: PackedString -> PackedString -> PackedString
 appendPS = mappend
 
-testPackedString = do
-    let prop_psid xs = unpackPS (packString xs) == (xs::String)
+prop_PackedString_psid xs = unpackPS (packString xs) == (xs::String)
 --        prop_pslen xs = lengthPS (packString xs) == length (xs::String)
-        prop_psappend (xs,ys) = (packString xs `appendPS` packString ys) == packString ((xs::String) ++ ys)
-        prop_psappend' (xs,ys) = unpackPS (packString xs `appendPS` packString ys) == ((xs::String) ++ ys)
-        prop_sort xs = sort (map packString xs) == map packString (sort xs)
-    qc "PackedString.psid" prop_psid
-    qc "PackedString.sort"  prop_sort
-    qc "PackedString.psappend"  prop_psappend
-    qc "PackedString.psappend'"  prop_psappend'
+prop_PackedString_sort xs = sort (map packString xs) == map packString (sort xs)
+prop_PackedString_psappend (xs,ys) = (packString xs `appendPS` packString ys) == packString ((xs::String) ++ ys)
+prop_PackedString_psappend' (xs,ys) = unpackPS (packString xs `appendPS` packString ys) == ((xs::String) ++ ys)
 --    quickCheck prop_pslen
 --    print $ map packString strings
 --    print $ sort $ map packString strings
@@ -90,51 +74,43 @@ testPackedString = do
 
 --pshash xs = putStrLn $ xs ++ ": " ++ show (hashPS (packString xs ))
 
-testName = do
-    let nn x = (not (null x)) && ';' `notElem` x
-        prop_acc t a b = nn a && nn b ==> let
-            n = toName t (a::String,b::String)
-            un = toUnqualified n
-            in  nameType n == t && getModule n == Just (toModule a) && getModule un == Nothing && show un == b && show n == (a ++ "." ++ b)
-    qc "name.tofrom" $ \t a b -> nn a && nn b ==> fromName (toName t (a::String,b::String)) == (t,(a,b))
-    qc "name.nameparts" $ \t a b -> nn b ==> nameParts (toName t (a,b)) == (t,a,b)
-    qc "name.nameparts2" $ \t a b ->  nn b ==> nameParts (toName t (a,b)) == (t,Just a,b)
-    qc "name.toUnqualified" $ \t a b -> nn a && nn b ==> toUnqualified (toName t (a,b)) == toName t b
-    qc "name.getModule" $ \ t a b -> nn a && nn b ==> getModule (toName t (a,b)) == Just (toModule a)
-    qc "name.getModule2" $ \ t b -> nn b ==> getModule (toName t b) == Nothing
-    qc "name.getIdent" $ \t a b ->  nn b ==> getIdent (toName t (a :: Maybe Module,b)) == b
-    qc "name.setModule" $ \t a b c ->  nn b && nn c ==> setModule (toModule c) (toName t (a :: Maybe Module,b)) == toName t (c,b)
-    qc "name.show" $ \ t a b -> nn a && nn b ==> show (toName t (a,b)) == a ++ "." ++ b
-    qc "name.quote" $ \ t a b -> nn a && nn b ==> let n = toName t (a,b) in fromQuotedName (quoteName n) == Just n
-    qc "name.noquote" $ \ t a b -> t /= QuotedName && nn b ==> collect t $ fromQuotedName (toName t (a :: Maybe Module,b)) == Nothing
-    qc "name.acc" prop_acc
-    qc "name.tup" $ \n -> n >= 0 ==> fromUnboxedNameTuple (unboxedNameTuple RawType n) == Just n
-    qc "name.overlap" $ \t -> (isTypeNamespace t,isValNamespace t) /= (True,True)
-
-testProperties = do
-    let prop_list x xs = sort (List.delete x $ nub xs) == toList p where
-            p = unsetProperty x ((fromList xs) :: Properties)
-        prop_enum :: Info.Types.Property -> Info.Types.Property -> Bool
-        prop_enum x y = (fromEnum x `compare` fromEnum y) == (x `compare` y)
-    qc "prop.list" prop_list
-    qc "prop.enum" prop_enum
-
-testHasSize = do
-    let prop_gt (xs,n) = sizeGT n (xs::[Int]) == (length xs > n)
-        prop_gte (xs,n) = sizeGTE n (xs::[Int]) == (length xs >= n)
-        prop_lte (xs,n) = sizeLTE n (xs::[Int]) == (length xs <= n)
-    qc "hasSize.gt" prop_gt
-    qc "hasSize.gte" prop_gte
-    qc "hasSize.lte" prop_lte
-
-
-testInfo = do
-    putStrLn "Testing Info"
+nn x = (not (null x)) && ';' `notElem` x
+
+prop_name_tofrom t a b = nn a && nn b ==> fromName (toName t (a::String,b::String)) == (t,(a,b))
+prop_name_nameparts t a b = nn b ==> nameParts (toName t (a,b)) == (t,a,b)
+prop_name_nameparts2 t a b =  nn b ==> nameParts (toName t (a,b)) == (t,Just a,b)
+prop_name_toUnqualified t a b = nn a && nn b ==> toUnqualified (toName t (a,b)) == toName t b
+prop_name_getModule  t a b = nn a && nn b ==> getModule (toName t (a,b)) == Just (toModule a)
+prop_name_getModule2  t b = nn b ==> getModule (toName t b) == Nothing
+prop_name_getIdent t a b =  nn b ==> getIdent (toName t (a :: Maybe Module,b)) == b
+prop_name_setModule t a b c =  nn b && nn c ==> setModule (toModule c) (toName t (a :: Maybe Module,b)) == toName t (c,b)
+prop_name_show  t a b = nn a && nn b ==> show (toName t (a,b)) == a ++ "." ++ b
+prop_name_quote  t a b = nn a && nn b ==> let n = toName t (a,b) in fromQuotedName (quoteName n) == Just n
+prop_name_noquote  t a b = t /= QuotedName && nn b ==> collect t $ fromQuotedName (toName t (a :: Maybe Module,b)) == Nothing
+prop_name_acc t a b = nn a && nn b ==> let
+  n = toName t (a::String,b::String)
+  un = toUnqualified n
+  in  nameType n == t && getModule n == Just (toModule a) && getModule un == Nothing && show n == (a ++ "." ++ b) && case t of
+    QuotedName -> show un == '`':b
+    _          -> show un == b
+prop_name_tup n = n >= 0 ==> fromUnboxedNameTuple (unboxedNameTuple RawType n) == Just n
+prop_name_overlap t = (isTypeNamespace t,isValNamespace t) /= (True,True)
+
+prop_prop_list x xs = sort (Data.List.delete x $ nub xs) == toList p where
+    p = unsetProperty x ((fromList xs) :: Properties)
+prop_prop_enum :: Info.Types.Property -> Info.Types.Property -> Bool
+prop_prop_enum x y = (fromEnum x `compare` fromEnum y) == (x `compare` y)
+
+prop_hasSize_gt (xs,n) = sizeGT n (xs::[Int]) == (length xs > n)
+prop_hasSize_gte (xs,n) = sizeGTE n (xs::[Int]) == (length xs >= n)
+prop_hasSize_lte (xs,n) = sizeLTE n (xs::[Int]) == (length xs <= n)
+
+case_testInfo = do
     i <- return mempty
-    unless (Info.lookup i == (Nothing :: Maybe Int)) $ fail "test failed..."
+    Info.lookup i @=? (Nothing :: Maybe Int)
     i <- return $ Info.insert (3 :: Int) i
-    unless (Info.lookup i == (Just 3 :: Maybe Int)) $ fail "test failed..."
-    unless (Info.fetch (Info.insert (5 :: Int) i) == ([] :: [Int])) $ fail "test failed..."
+    Info.lookup i @=? (Just 3 :: Maybe Int)
+    Info.fetch (Info.insert (5 :: Int) i) @=? ([] :: [Int])
 
     let x = Properties mempty
         x' = setProperty prop_METHOD $ setProperty prop_INLINE x
@@ -149,14 +125,12 @@ testInfo = do
     print (x'',getProperty prop_METHOD x'', getProperty prop_INSTANCE x'')
     print (getProperties x')
 
-
-testBinary = do
+case_testBinary = do
     let test = ("hello",3::Int,toAtom "Up and Atom!")
         fn = "/tmp/jhc.test.bin"
-    putStrLn "Testing Binary"
     encodeFile fn test
     x <- decodeFile fn
-    if (x /= test) then fail "Test Failed" else return ()
+    x @=? test
     print x
     let fn = "/tmp/jhc.info.bin"
         t = (singleton prop_INLINE) `mappend` fromList [prop_WORKER,prop_SPECIALIZATION]
@@ -168,7 +142,7 @@ testBinary = do
     x@(nfo,_,_) <- decodeFile fn
     print $ x `asTypeOf` nf
     z <- Info.lookup nfo
-    if (z /= t) then fail "Info Test Failed" else return ()
+    z @=? t
 
 
 deriving instance Bounded NameType
@@ -198,6 +172,8 @@ instance Arbitrary Module where
         f "" = f "X"
         f s = toModule s
 
+{--
 instance Arbitrary Char where
     arbitrary     = Test.QuickCheck.choose ('\32', '\128')
-    coarbitrary c = variant (fromEnum c `rem` 4)
+--    coarbitrary c = variant (fromEnum c `rem` 4)
+--}
diff --git a/selftest/cff.hs b/selftest/cff.hs
index e3a5aaf..c54a8a6 100644
--- a/selftest/cff.hs
+++ b/selftest/cff.hs
@@ -3,7 +3,7 @@
 import System.IO
 import Support.CFF
 import qualified Data.ByteString as BS
-import System
+import System.Environment
 
 main = do
     xs <- getArgs
diff --git a/selftest/md5.hs b/selftest/md5.hs
index c34f899..b12cd9e 100644
--- a/selftest/md5.hs
+++ b/selftest/md5.hs
@@ -1,6 +1,6 @@
 
 
-import System
+import System.Environment
 
 import Support.MD5
 
diff --git a/selftest/sha1.hs b/selftest/sha1.hs
index a88ac75..3ef572b 100644
--- a/selftest/sha1.hs
+++ b/selftest/sha1.hs
@@ -1,5 +1,5 @@
 
-import System
+import System.Environment
 
 import Util.SHA1
 
diff --git a/src/E/Arbitrary.hs b/src/E/Arbitrary.hs
index c9848db..0b1ba7e 100644
--- a/src/E/Arbitrary.hs
+++ b/src/E/Arbitrary.hs
@@ -11,7 +11,7 @@ import E.TypeCheck()
 import GenUtil
 import Name.Id
 import Name.VConsts
-import Random
+import System.Random
 import Support.CanType
 import Support.FreeVars
 import qualified Data.Map as Map
diff --git a/src/GenUtil.hs b/src/GenUtil.hs
index eae8e81..218a40a 100644
--- a/src/GenUtil.hs
+++ b/src/GenUtil.hs
@@ -130,7 +130,7 @@ import System.Random(StdGen, newStdGen, Random(randomR))
 import System.Time
 import System.CPUTime
 import System.Exit
-import System.Environment
+import System.Environment (getArgs, getEnv)
 
 {-# SPECIALIZE snub :: [String] -> [String] #-}
 {-# SPECIALIZE snub :: [Int] -> [Int] #-}
diff --git a/src/Options.hs b/src/Options.hs
index 3ba9404..c822365 100644
--- a/src/Options.hs
+++ b/src/Options.hs
@@ -37,7 +37,7 @@ import Data.Maybe
 import System.Console.GetOpt
 import System.Directory
 import System.IO.Unsafe
-import System.Environment
+import System.Environment (getArgs, getProgName, getEnv)
 import System.Exit
 import qualified Data.ByteString.UTF8 as BS
 import qualified Data.Map as M
diff --git a/src/Util/SHA1.hs b/src/Util/SHA1.hs
index e647698..d618b70 100644
--- a/src/Util/SHA1.hs
+++ b/src/Util/SHA1.hs
@@ -23,7 +23,7 @@ Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
 
 -}
 
-{-# OPTIONS -funbox-strict-fields -fglasgow-exts -fno-warn-name-shadowing -O2 #-}
+{-# OPTIONS -funbox-strict-fields -fno-warn-name-shadowing -O2 #-}
 
 module Util.SHA1 (sha1String,sha1file,sha1Bytes,hashToBytes,sha1Handle,ABCDE(..),Hash,emptyHash) where
 
@@ -59,7 +59,7 @@ sha1String ss = sha1Bytes (toUTF ss) where
 
 
 sha1Bytes :: [Word8] -> Hash
-sha1Bytes ss = unsafePerformIO $ do
+sha1Bytes ss = System.IO.Unsafe.unsafePerformIO $ do
     let len = length ss
         plen = sha1_step_1_2_plength len
     allocaBytes plen $ \ptr -> do
@@ -100,7 +100,7 @@ sha1file fp = do
     hClose h
     return hash
 
-big_endian = unsafePerformIO $ do
+big_endian = System.IO.Unsafe.unsafePerformIO $ do
     let x :: Word32
         x = 0x12345678
     s <- with x $ \ptr -> peekCStringLen (castPtr ptr,4)
