diff --git a/MuCheck.cabal b/MuCheck.cabal
--- a/MuCheck.cabal
+++ b/MuCheck.cabal
@@ -1,5 +1,5 @@
 name:                MuCheck
-version:             0.1.2.1
+version:             0.1.2.2
 synopsis:            Automated Mutation Testing
 description:         This package defines a mutation analysis library for haskell
                      programs. It does this by parsing the haskell source, and
@@ -26,7 +26,7 @@
 source-repository    this
   type:              git
   location:          https://bitbucket.org/osu-testing/mucheck.git
-  tag:               0.1.2.1
+  tag:               0.1.2.2
 
 executable mucheck
   main-is:          Main.hs
@@ -35,7 +35,7 @@
   hs-source-dirs:   src
 
 library
-  exposed-modules:  MuCheck.MuOp, MuCheck.StdArgs, MuCheck.Interpreter, MuCheck.Mutation, MuCheck.Operators, MuCheck.Utils.Syb, MuCheck.Utils.Common, MuCheck.Utils.Print
+  exposed-modules:  MuCheck.MuOp, MuCheck.Config, MuCheck.Interpreter, MuCheck.Mutation, MuCheck.Operators, MuCheck.Utils.Syb, MuCheck.Utils.Common, MuCheck.Utils.Print, MuCheck.Run.Common, MuCheck.Run.QuickCheck, MuCheck.Run.HUnit, MuCheck.Run.Hspec
   -- other-modules:       
   build-depends:    base >=4 && <5, haskell-src-exts >=1.13, syb >= 0.4.0, time >= 1.4.0.1, QuickCheck>=2.6, hint >= 0.3.1.0, mtl>=2.1.2, HUnit >= 1.0, filepath, hspec>= 2.0, hspec-core >= 2.0, random
   default-language: Haskell2010
diff --git a/src/Main.hs b/src/Main.hs
--- a/src/Main.hs
+++ b/src/Main.hs
@@ -3,7 +3,7 @@
 import Control.Monad (void)
 
 import MuCheck.MuOp
-import MuCheck.StdArgs
+import MuCheck.Config
 import MuCheck.Mutation
 import MuCheck.Operators
 import MuCheck.Utils.Common
diff --git a/src/MuCheck/Config.hs b/src/MuCheck/Config.hs
new file mode 100644
--- /dev/null
+++ b/src/MuCheck/Config.hs
@@ -0,0 +1,28 @@
+module MuCheck.Config where
+
+import MuCheck.MuOp
+import MuCheck.Operators
+
+data GenerationMode
+  = FirstOrderOnly
+  | FirstAndHigherOrder
+  deriving (Eq, Show)
+
+data Config = Config { muOps :: [MuOp]
+  , doMutatePatternMatches :: Rational
+  , doMutateValues :: Rational
+  , doNegateIfElse :: Rational
+  , doNegateGuards :: Rational
+  , maxNumMutants :: Int
+  , genMode :: GenerationMode }
+  deriving Show
+
+defaultConfig :: Config
+defaultConfig = Config {muOps = allOps
+  , doMutatePatternMatches = 1.0
+  , doMutateValues = 1.0
+  , doNegateIfElse = 1.0
+  , doNegateGuards = 1.0
+  , maxNumMutants = 300
+  , genMode = FirstOrderOnly }
+
diff --git a/src/MuCheck/Mutation.hs b/src/MuCheck/Mutation.hs
--- a/src/MuCheck/Mutation.hs
+++ b/src/MuCheck/Mutation.hs
@@ -19,27 +19,31 @@
 import MuCheck.Utils.Syb
 import MuCheck.Utils.Common
 import MuCheck.Operators
-import MuCheck.StdArgs
+import MuCheck.Config
 
--- entry point.
-genMutants = genMutantsWith stdArgs
+-- | The `genMutants` function is a wrapper to genMutantsWith with standard
+-- configuraton
+genMutants = genMutantsWith defaultConfig
 
-genMutantsWith :: StdArgs -> String -> FilePath -> IO Int
+-- | The `genMutantsWith` function takes configuration function to mutate,
+-- filename the function is defined in, and produces mutants in the same
+-- directory as the filename, and returns the number of mutants produced.
+genMutantsWith :: Config -> String -> FilePath -> IO Int
 genMutantsWith args funcname filename  = liftM length $ do
     ast <- getASTFromFile filename
-    now <- round `fmap` getPOSIXTime
+    g <- liftM (mkStdGen . round) getPOSIXTime
     let f = func funcname ast
-        g = mkStdGen now
+
+        ops, swapOps, valOps, ifElseNegOps, guardedBoolNegOps :: [MuOp]
         ops = relevantOps f (muOps args ++ valOps ++ ifElseNegOps ++ guardedBoolNegOps)
         swapOps = sampleF g (doMutatePatternMatches args) $ permMatches f ++ removeOnePMatch f
-
         valOps = sampleF g (doMutateValues args) $ selectIntOps f
         ifElseNegOps = sampleF g (doNegateIfElse args) $ selectIfElseBoolNegOps f
         guardedBoolNegOps = sampleF g (doNegateGuards args) $ selectGuardedBoolNegOps f
 
+        patternMatchMutants, ifElseNegMutants, guardedNegMutants, operatorMutants, allMutants :: [Decl]
         allMutants = nub $ patternMatchMutants ++ operatorMutants
 
-        patternMatchMutants, ifElseNegMutants, guardedNegMutants, operatorMutants, allMutants :: [Decl]
         patternMatchMutants = mutatesN swapOps f fstOrder
         ifElseNegMutants = mutatesN ifElseNegOps f fstOrder
         guardedNegMutants = mutatesN guardedBoolNegOps f fstOrder
@@ -58,9 +62,9 @@
   where fstOrder = 1 -- first order
         getASTFromFile filename = liftM parseModuleFromFile $ readFile filename
 
--- Mutating a function's code using a bunch of mutation operators
--- NOTE: In all the three mutate functions, we assume working
--- with functions declaration.
+-- | Mutating a function's code using a bunch of mutation operators
+-- (In all the three mutate functions, we assume working
+-- with functions declaration.)
 mutates :: [MuOp] -> Decl -> [Decl]
 mutates ops m = filter (/= m) $ concatMap (mutatesN ops m) [1..]
 
@@ -69,22 +73,19 @@
 mutatesN ops m 1 = concat [mutate op m | op <- ops ]
 mutatesN ops m c =  concat [mutatesN ops m 1 | m <- mutatesN ops m (c-1)]
 
--- given a function, generate all mutants after applying applying 
--- op once (op might be applied at different places). E.g.:
+-- | Given a function, generate all mutants after applying applying 
+-- op once (op might be applied at different places).E.g.:
 -- op = "<" ==> ">" and there are two instances of "<"
 mutate :: MuOp -> Decl -> [Decl]
 mutate op m = once (mkMp' op) m \\ [m]
 
-isFunction :: Name -> GenericQ Bool
-isFunction (Ident n) = False `mkQ` isFunctionD n
-
 isFunctionD :: String -> Decl -> Bool
 isFunctionD n (FunBind (Match _ (Ident n') _ _ _ _ : _)) = n == n'
 isFunctionD n (FunBind (Match _ (Symbol n') _ _ _ _ : _)) = n == n'
 isFunctionD n (PatBind _ (PVar (Ident n')) _ _)          = n == n'
 isFunctionD _ _                                  = False
 
--- generate all operators for permutating pattern matches in
+-- | Generate all operators for permutating pattern matches in
 -- a function. We don't deal with permutating guards and case for now.
 permMatches :: Decl -> [MuOp]
 permMatches d@(FunBind ms) = d ==>* map FunBind (permutations ms \\ [ms])
@@ -98,13 +99,18 @@
 removeOneElem l = choose l (length l - 1)
 
 -- AST/module-related operations
--- String is the content of the file
+
+-- | Parse a module. Input is the content of the file
 parseModuleFromFile :: String -> Module
 parseModuleFromFile inp = fromParseResult $ parseFileContents inp
 
 getDecls :: Module -> [Decl]
 getDecls (Module _ _ _ _ _ _ decls) = decls
 
+{-
+isFunction :: Name -> GenericQ Bool
+isFunction (Ident n) = False `mkQ` isFunctionD n
+
 extractStrings :: [Match] -> [String] 
 extractStrings [] = []
 extractStrings (Match _ (Symbol name) _ _ _ _:xs) = name : extractStrings xs
@@ -115,12 +121,13 @@
 getFuncNames (FunBind m:xs) = extractStrings m ++ getFuncNames xs
 getFuncNames (_:xs) = getFuncNames xs
   
-putDecls :: Module -> [Decl] -> Module
-putDecls (Module a b c d e f _) decls = Module a b c d e f decls
-
 getName :: Module -> String
 getName (Module _ (ModuleName name) _ _ _ _ _) = name
+-}
 
+putDecls :: Module -> [Decl] -> Module
+putDecls (Module a b c d e f _) decls = Module a b c d e f decls
+
 -- Define all operations on a value
 selectValOps :: (Data a, Eq a, Typeable b, Mutable b, Eq b) => (b -> Bool) -> [b -> b] -> a -> [MuOp]
 selectValOps pred fs m = concatMap (\x -> x ==>* map (\f -> f x) fs) vals
@@ -139,13 +146,13 @@
   where isInt (Int _) = True
         isInt _       = False
 
--- negating boolean in if/else statements
+-- | negating boolean in if/else statements
 selectIfElseBoolNegOps :: (Data a, Eq a) => a -> [MuOp]
 selectIfElseBoolNegOps m = selectValOps isIf [\(If e1 e2 e3) -> If (App (Var (UnQual (Ident "not"))) e1) e2 e3] m
   where isIf If{} = True
         isIf _    = False
 
--- negating boolean in Guards
+-- | negating boolean in Guards
 selectGuardedBoolNegOps :: (Data a, Eq a) => a -> [MuOp]
 selectGuardedBoolNegOps m = selectValOps' isGuardedRhs negateGuardedRhs m
   where isGuardedRhs GuardedRhs{} = True
diff --git a/src/MuCheck/Run/Common.hs b/src/MuCheck/Run/Common.hs
new file mode 100644
--- /dev/null
+++ b/src/MuCheck/Run/Common.hs
@@ -0,0 +1,19 @@
+module MuCheck.Run.Common where
+
+import qualified Language.Haskell.Interpreter as I
+import Data.Typeable
+type InterpreterOutput a = Either I.InterpreterError (String, a)
+
+data TSum = TSum {tsum_numMutants::Int,
+                  tsum_loadError::Int,
+                  tsum_notKilled::Int,
+                  tsum_killed::Int,
+                  tsum_others::Int,
+                  tsum_log::String}
+
+-- Class/Instance declaration
+type MutantFilename = String
+class Typeable s => Summarizable s where
+  testSummary :: [MutantFilename] -> [InterpreterOutput s] -> TSum
+  isSuccess :: s -> Bool
+
diff --git a/src/MuCheck/Run/HUnit.hs b/src/MuCheck/Run/HUnit.hs
new file mode 100644
--- /dev/null
+++ b/src/MuCheck/Run/HUnit.hs
@@ -0,0 +1,38 @@
+{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
+module MuCheck.Run.HUnit where
+import qualified Test.HUnit as HUnit
+import MuCheck.Run.Common
+import MuCheck.Utils.Print (showA, showAS)
+
+import Data.Typeable
+import Data.List((\\))
+import Data.Either (partitionEithers)
+
+deriving instance Typeable HUnit.Counts
+
+instance Summarizable HUnit.Counts where
+  testSummary mutantFiles results = TSum {
+    tsum_numMutants = r,
+    tsum_loadError = le,
+    tsum_notKilled = s,
+    tsum_killed = fl,
+    tsum_others = re + ftc,
+    tsum_log = logMsg}
+    where (loadingErrorCases, executedCases) = partitionEithers results
+          loadingErrorFiles = mutantFiles \\ map fst executedCases
+          successCases = filter (isSuccess . snd) executedCases
+          failuresCases = filter ((>0) . HUnit.failures . snd) executedCases
+          runningErrorCases = filter ((>0) . HUnit.errors . snd) executedCases \\ failuresCases
+          failToFullyTryCases = filter ((\c -> HUnit.cases c > HUnit.tried c) . snd) executedCases
+          r = length results
+          le = length loadingErrorCases
+          [s, fl, re, ftc] = map length [successCases, failuresCases, runningErrorCases, failToFullyTryCases]
+          logMsg = showAS ["Details:",
+                           "Loading error files:",showA loadingErrorFiles,
+                           "Loading error messages:",showA loadingErrorCases,
+                           "Successes:", showA successCases,
+                           "Failures:", showA failuresCases,
+                           "Error while running:", showA runningErrorCases,
+                           "Incompletely tested (may include failures and running errors):",showA failToFullyTryCases]
+  isSuccess c = (HUnit.cases c == HUnit.tried c) && HUnit.failures c == 0 && HUnit.errors c == 0
+
diff --git a/src/MuCheck/Run/Hspec.hs b/src/MuCheck/Run/Hspec.hs
new file mode 100644
--- /dev/null
+++ b/src/MuCheck/Run/Hspec.hs
@@ -0,0 +1,34 @@
+{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
+module MuCheck.Run.Hspec where
+import qualified Test.Hspec.Core.Runner as Hspec
+import MuCheck.Run.Common
+import MuCheck.Utils.Print (showA, showAS)
+
+import Data.Typeable
+import Data.Either (partitionEithers)
+import Data.List((\\))
+
+deriving instance Typeable Hspec.Summary
+
+instance Summarizable Hspec.Summary where
+  testSummary mutantFiles results = TSum {
+    tsum_numMutants = r,
+    tsum_loadError = e,
+    tsum_notKilled = s,
+    tsum_killed = f,
+    tsum_others = 0,
+    tsum_log = logMsg}
+      where (errorCases, executedCases) = partitionEithers results
+            r = length results
+            e = length errorCases
+            [successCases, failureCases] = map (\c -> filter (c . snd) executedCases) [isSuccess, isFailure]
+            [s,f] = map length [successCases, failureCases]
+            errorFiles = mutantFiles \\ map fst executedCases
+            logMsg = showAS ["Details:",
+                             "Loading error files:", showA errorFiles,
+                             "Loading error messages:", showA errorCases,
+                             "Successes:", showA successCases,
+                             "Failure:", showA failureCases]
+            isFailure = not . isSuccess
+  isSuccess (Hspec.Summary { Hspec.summaryExamples = se, Hspec.summaryFailures = sf } ) = sf == 0
+
diff --git a/src/MuCheck/Run/QuickCheck.hs b/src/MuCheck/Run/QuickCheck.hs
new file mode 100644
--- /dev/null
+++ b/src/MuCheck/Run/QuickCheck.hs
@@ -0,0 +1,39 @@
+{-# LANGUAGE StandaloneDeriving, DeriveDataTypeable #-}
+module MuCheck.Run.QuickCheck where
+import qualified Test.QuickCheck.Test as Qc
+import MuCheck.Run.Common
+import MuCheck.Utils.Print (showA, showAS)
+
+import Data.Typeable
+import Data.List((\\))
+import Data.Either (partitionEithers)
+
+deriving instance Typeable Qc.Result
+
+instance Summarizable Qc.Result where
+  testSummary mutantFiles results = TSum {
+    tsum_numMutants = r,
+    tsum_loadError = e,
+    tsum_notKilled = s,
+    tsum_killed = f,
+    tsum_others = g,
+    tsum_log = logMsg}
+    where (errorCases, executedCases) = partitionEithers results
+          [successCases, failureCases, gaveUpCases] = map (\c -> filter (c . snd) executedCases) [isSuccess, isFailure, isGaveUp]
+          r = length results
+          e = length errorCases
+          [s,f,g] = map length [successCases, failureCases, gaveUpCases]
+          errorFiles = mutantFiles \\ map fst executedCases
+          logMsg = showAS ["Details:",
+                           "Loading error files:", showA errorFiles,
+                           "Loading error messages:", showA errorCases,
+                           "Successes:", showA successCases,
+                           "Failure:", showA failureCases,
+                           "Gaveups:", showA gaveUpCases]
+          isFailure :: Qc.Result -> Bool
+          isFailure Qc.Failure{} = True
+          isFailure _         = False
+          isGaveUp :: Qc.Result -> Bool
+          isGaveUp Qc.GaveUp{} = True
+          isGaveUp _        = False
+  isSuccess = Qc.isSuccess
diff --git a/src/MuCheck/StdArgs.hs b/src/MuCheck/StdArgs.hs
deleted file mode 100644
--- a/src/MuCheck/StdArgs.hs
+++ /dev/null
@@ -1,27 +0,0 @@
-module MuCheck.StdArgs where
-
-import MuCheck.MuOp
-import MuCheck.Operators
-
-data GenerationMode = FirstOrderOnly
-                    | FirstAndHigherOrder
-                    deriving (Eq, Show)
-
-data StdArgs = StdArgs {muOps :: [MuOp]
-                      , doMutatePatternMatches :: Rational
-                      , doMutateValues :: Rational
-                      , doNegateIfElse :: Rational
-                      , doNegateGuards :: Rational
-                      , maxNumMutants :: Int
-                      , genMode :: GenerationMode }
-                      deriving Show
-
-stdArgs :: StdArgs
-stdArgs = StdArgs {muOps = allOps
-                 , doMutatePatternMatches = 1.0
-                 , doMutateValues = 1.0
-                 , doNegateIfElse = 1.0
-                 , doNegateGuards = 1.0
-                 , maxNumMutants = 300
-                 , genMode = FirstOrderOnly }
-
