diff --git a/TODO b/TODO
--- a/TODO
+++ b/TODO
@@ -1,18 +1,25 @@
 TODO : 
+  Refactor tests
+  configure quickcheck to be faster (less tests)
+  integrate a quickcheck driver
   Big refactoring : Better model for information representation, better separations!
-  Make action take parameters from command line
-  Implement QuickCheck Action
   Optimisation possible by saving the files to listen
   Clean module export
   Cabal Integration : 
     Propose which composant (Library? Executable?) to build
   Trap ctrl+c
+  Trap ctrl+d
   Correct import module (only import necessary functions)
   Create action command
   Use a monad writer for cabal information extraction
+  Correct alignement when launching test
+  command case insensitive
+  Test changes are not taken loaded when using ~QuickCheck
 
 Done : 
-  bug : ~Compile launche two fork the first time
+  Make action take parameters from command line
+  Implement QuickCheck Action
+  bug : ~Compile launch two fork the first time
   Convert InputShaker parameter to Monad
   Support multi action
   Implement Clean
@@ -28,4 +35,6 @@
   Exclude main methods from fullCompile 
   If no source dir is specified, an error is throwed
   correct fullcompile. Concat source dir from all artifacts (currently only use the first)
+  Make tests action take pattern as parameters
+  Change parse result if there is invalid action
 
diff --git a/prog/Shaker.hs b/prog/Shaker.hs
--- a/prog/Shaker.hs
+++ b/prog/Shaker.hs
@@ -1,20 +1,30 @@
 module Main
  where
 
+import Shaker.Type
 import Shaker.Conductor
-import Shaker.Config
 import Shaker.Parser
 import Shaker.Cabal.CabalInfo
 import Control.Monad.Reader
 import System( getArgs )
 
-
 main :: IO()
 main = do
   args <- getArgs
-  inputState <- defaultInputState
   cab <- defaultCabalInput 
   if null args 
-    then runReaderT (initThread inputState) cab
-    else runReaderT ( executeCommand . parseCommand cab $ concat args)  cab 
+    then runReaderT initThread cab
+    else 
+         runReaderT ( runArgumentAction $ concat args) cab >> return ()
   
+runArgumentAction :: String -> Shaker IO ()
+runArgumentAction args = do 
+  shIn <- ask 
+  let either_command = parseCommand args shIn
+  either errAction okAction either_command 
+  return () 
+  where 
+        errAction = lift . putStrLn . show 
+        okAction :: Command -> Shaker IO()
+        okAction command = executeCommand (Just command) >> return ()
+
diff --git a/shaker.cabal b/shaker.cabal
--- a/shaker.cabal
+++ b/shaker.cabal
@@ -1,5 +1,5 @@
 name: shaker
-version: 0.3.1
+version: 0.4
 cabal-version: >= 1.8
 build-type: Custom
 license: BSD3
@@ -10,58 +10,77 @@
 homepage: http://github.com/bonnefoa/Shaker
 bug-reports: http://github.com/bonnefoa/Shaker/issues 
 Stability:alpha
-Tested-With:GHC == 6.12.1
+Tested-With:GHC == 6.12.3
 category: Development
 synopsis: simple and interactive command-line build tool
 description: 
-  Shaker is a build tool which allow to compile an haskell project with some features like continuous action similar to SBT.
+  Shaker is a build tool which allow to simply compile or launch test on an haskell project and provides some interesting features like continuous action. With continuous action, an action (compile or test) will be automatically executed when a source modification is detected.
   .
-  For the moment, all configuration are made via cabal. Shaker will read cabal configuration to discover source directories, compilation options and targets to compile.
+  All configuration are made via cabal; Shaker will read cabal configuration to discover source directories, compilation options and targets to compile.
   .
   /Usage/
   .
-  The cabal configuration file should be generated beforehand with /runhaskell Setup.hs configure/. If you change your cabal configuration, you need to recreate the configuration file. 
+  The cabal configuration file should be generated beforehand with /cabal configure/. If you change your cabal configuration, you will need to recreate the configuration file.
   .
-  /Execution/
+  /Launch interactive prompt/
   .
-  In the root of your haskell project, launch shaker. An interactive prompt will allow you to execute differents action.
+  In the root of your haskell project, launch shaker. An interactive prompt will allow you to execute different actions. 
   .
+  /Launch a shaker action from command-line/
+  .
+  In the root of your haskell project, launch shaker with your action as a command argument; shaker will execute the given action and exit. See examples for more details.
+  .
   /Action execution/
   .
-  [@Simple Execution@] An action can be launched normally, by entering the action name 
+  [@Simple Execution@] An action can be launched normally, by entering the action name. 
   .
   [@Multiple action execution@] You can specify multiple action to execute simply by separating action by spaces.
   .
-  [@Continuous Action@] A continuous action will execute the action when a changement on files has been detected.
-  Every action are elligible to continuous action, you simply need to prefix them with '~'
+  [@Continuous Action@] A continuous action will execute the action when a file modification has been detected.
+  Every action are elligible to continuous action, you simply need to prefix them with '~'. To stop a continuous action, simply use ^C.
   .
   /Available actions/
   .
-  [@Compile@] Compile the project. Targets of the compilation are main file (in case of executable) or exposed modules (in case of library).
-  .
-  [@FullCompile@] Compile all hs files found in source directory. It is usefull to compile test sources.
+  [@compile@] Compile the project. Targets of the compilation are main files (in case of executable) and exposed modules (in case of library).
   .
-  [@Clean@] Clean the directory containing .o and .hi files.
+  [@fullcompile@] Compile all hs files found in source directory. It is usefull to compile test sources. Since it is not possible to compile multiple modules with main, all modules with a main function are excluded.
   .
-  [@QuickCheck@] Launch all QuickCheck properties of the project.
+  [@help@] Print all available action.
   .
-  [@IQuickCheck@] Intelligent QuickCheck launch. Only launch necessary properties (beta). 
+  [@clean@] Clean the directory containing .o and .hi files.
   .
-  [@HUnit@] Launch all HUnit tests of the project.
+  [@test@] Launch all quickcheck properties and hunit tests of the project using test-framework. You can provide a regexp as argument and shaker will execute all tests located in modules matching the regexp. Quickcheck properties and HUnit tests are automatically discovered using GHC Api. All functions begining with “prop_” are considered as quickcheck properties and all functions of type Test.HUnit.Lang.Assertion are considered as HUnit tests. 
   .
-  [@IHUnit@] Intelligent HUnit launch. Only launch necessary tests (beta).
+  [@itest@] Launch all quickcheck properties and hunit tests using test-framework on compiled modules. Same as test, you can give a regexp as argument. This action is only useful when used with continuous action. 
   .
-  [@Quit@] Exit the application.
+  [@quit@] Exit the application. You can also use ^C or ^D to exit shaker.
   . 
-  /Examples/
+  /Examples with interactive prompt/
   .
-  [@% Compile@] Simply compile the project
+  [@% compile@] Simply compile the project
   .
-  [@% Clean Compile@] Clean and compile the project
+  [@% clean compile@] Clean and compile the project
   .
-  [@% ~Compile@] Switch to continuous mode and will compile the project when sources are modified.
+  [@% ~compile@] Switch to continuous mode and will compile the project when sources are modified.
   .
-  [@% ~Clean Compile@] Switch to continuous mode and will clean and compile the project when sources are modified.
+  [@% ~clean compile@] Switch to continuous mode and will clean and compile the project when sources are modified.
+  .
+  [@% test@] Execute all tests in the project
+  .
+  [@% ~itest@] Switch to continuous mode and execute tests on compiled modules.
+  .
+  [@% test Regex@] Launch all tests in modules containing Regex
+  .
+  [@% ~itest Regex@] Launch all tests in modules containing Regex only when Regex is build.
+  . 
+  /Examples with command-line/
+  .
+  [@% shaker fullcompile@] Launch shaker, execute the fullcompile action and give back the control.
+  . 
+  [@% shaker \"~fullcompile\" @] Launch shaker, continuously execute the fullcompile action until shaker is interrupted.
+  . 
+
+
 extra-source-files: README TODO testsuite/tests/resources/invalidMain/dist/setup-config
     testsuite/tests/resources/invalidMain/src/Main.hs
     testsuite/tests/resources/invalidMain/tests/Dummy.hs
@@ -81,7 +100,7 @@
 source-repository this
   type:     git
   location: git://github.com/bonnefoa/Shaker.git 
-  tag:      0.3.1
+  tag:      0.4
 
 Library 
   ghc-options: -Wall -fno-warn-orphans 
@@ -104,52 +123,58 @@
     Shaker.Cabal.CabalInfo
     Shaker.Type
     Shaker.Listener
-  build-depends: base >= 4.1,
-                 Cabal >= 1.8.0.6,
-                 containers >= 0.3,
-                 haskeline >= 0.6.2.2 
-                 ,directory >= 1.0.1.0,
-                 filepath >= 1.1,
-                 ghc >= 6,
-                 ghc-paths >= 0.1,
-                 haskell98 >= 1.0,
-                 mtl >= 1.0,
-                 parsec >= 3.0,
-                 regex-posix >= 0.94.1,
-                 old-time >= 1.0.0
+  build-depends: base == 4.*
+                 ,Cabal >= 1.8.0.6
+                 ,containers == 0.3.*
+                 ,haskeline == 0.6.*
+                 ,directory == 1.0.*
+                 ,filepath == 1.1.*
+                 ,ghc == 6.*
+                 ,ghc-paths == 0.1.*
+                 ,haskell98 == 1.0.*
+                 ,mtl == 1.1.*
+                 ,parsec == 3.*
+                 ,regex-posix == 0.94.*
+                 ,old-time >= 1.0.0
                  ,bytestring >= 0.9.1.5
-                 ,HUnit >= 1.2.2.1
-                 ,QuickCheck >= 2.1.1.1
+                 ,HUnit == 1.2.*
+                 ,QuickCheck == 2.*
                  ,template-haskell >= 2.4.0.0
+                 ,test-framework == 0.3.*
+                 ,test-framework-hunit == 0.2.*
+                 ,test-framework-quickcheck2 == 0.2.*
 
 Executable shaker
   Main-Is: Shaker.hs
   ghc-options: -Wall -fno-warn-orphans 
-  hs-source-dirs: prog
-  build-depends: base >= 4.1 && < 5 ,
-                 shaker
-                 ,Cabal >= 1.8.0.6,
-                 containers >= 0.3,
-                 haskeline >= 0.6.2.2 
-                 ,directory >= 1.0.1.0,
-                 filepath >= 1.1,
-                 ghc >= 6,
-                 ghc-paths >= 0.1,
-                 haskell98 >= 1.0,
-                 mtl >= 1.0,
-                 parsec >= 3.0,
-                 regex-posix >= 0.94.1,
-                 old-time >= 1.0.0
+  hs-source-dirs: prog src
+  build-depends: base == 4.*
+                 ,Cabal >= 1.8.0.6
+                 ,containers == 0.3.*
+                 ,haskeline == 0.6.*
+                 ,directory == 1.0.*
+                 ,filepath == 1.1.*
+                 ,ghc == 6.*
+                 ,ghc-paths == 0.1.*
+                 ,haskell98 == 1.0.*
+                 ,mtl == 1.1.*
+                 ,parsec == 3.*
+                 ,regex-posix == 0.94.*
+                 ,old-time >= 1.0.0
                  ,bytestring >= 0.9.1.5
-                 ,HUnit >= 1.2.2.1
-                 ,QuickCheck >= 2.1.1.1
+                 ,HUnit == 1.2.*
+                 ,QuickCheck == 2.*
                  ,template-haskell >= 2.4.0.0
+                 ,test-framework == 0.3.*
+                 ,test-framework-hunit == 0.2.*
+                 ,test-framework-quickcheck2 == 0.2.*
+
 flag test
   description: Build test program.
   default:     False
 
 Executable test
-  hs-source-dirs:  testsuite/tests 
+  hs-source-dirs:  testsuite/tests src 
   main-is:         RunTestTH.hs
   ghc-options: -Wall -fno-warn-orphans
   other-modules: 
@@ -166,23 +191,25 @@
     Shaker.ListenerTest
     Shaker.ReflexiviteTest
     Shaker.ConductorTest
-  build-depends: base >= 4.1,
-                 shaker
-                 ,Cabal >= 1.8.0.6,
-                 containers >= 0.3,
-                 haskeline >= 0.6.2.2 
-                 ,directory >= 1.0.1.0,
-                 filepath >= 1.1,
-                 ghc >= 6,
-                 ghc-paths >= 0.1,
-                 haskell98 >= 1.0,
-                 mtl >= 1.0,
-                 parsec >= 3.0,
-                 regex-posix >= 0.94.1,
-                 old-time >= 1.0.0
+  build-depends: base == 4.*
+                 ,Cabal >= 1.8.0.6
+                 ,containers == 0.3.*
+                 ,haskeline == 0.6.*
+                 ,directory == 1.0.*
+                 ,filepath == 1.1.*
+                 ,ghc == 6.*
+                 ,ghc-paths == 0.1.*
+                 ,haskell98 == 1.0.*
+                 ,mtl == 1.1.*
+                 ,parsec == 3.*
+                 ,regex-posix == 0.94.*
+                 ,old-time >= 1.0.0
                  ,bytestring >= 0.9.1.5
-                 ,HUnit >= 1.2.2.1
-                 ,QuickCheck >= 2.1.1.1
+                 ,HUnit == 1.2.*
+                 ,QuickCheck == 2.*
                  ,template-haskell >= 2.4.0.0
+                 ,test-framework == 0.3.*
+                 ,test-framework-hunit == 0.2.*
+                 ,test-framework-quickcheck2 == 0.2.*
   if !flag(test)
     buildable:     False
diff --git a/src/Shaker/Action/Standard.hs b/src/Shaker/Action/Standard.hs
--- a/src/Shaker/Action/Standard.hs
+++ b/src/Shaker/Action/Standard.hs
@@ -7,6 +7,7 @@
 import Control.Monad.Trans
 import Control.Monad.Reader
 import System.Directory
+import Control.Concurrent
 
 -- | Print the list of available actions
 runHelp ::  Plugin
@@ -19,13 +20,19 @@
  
 -- | Print exit. The real exit management is made in conductor
 runExit :: Plugin
-runExit = lift $ putStrLn "Exiting"
+runExit = do
+  lift $ putStrLn "Exiting"
+  quit_token <- asks (quitToken . threadData)
+  lift $ putMVar quit_token 42
 
 -- | Print a begin action notification
 runStartAction :: Plugin
 runStartAction = lift $ 
   putStrLn "---------- Begin action -------------------------"
 
+runEmpty :: Plugin
+runEmpty = return ()
+
 -- | Print an end action notification
 runEndAction :: Plugin
 runEndAction = lift $ 
@@ -40,3 +47,7 @@
                  ex <- doesDirectoryExist toClean
                  if ex then removeDirectoryRecursive toClean  
                        else putStrLn "" 
+
+runInvalidAction :: Plugin 
+runInvalidAction = lift $ putStrLn "Invalid action,  use help to display available actions"
+
diff --git a/src/Shaker/Action/Test.hs b/src/Shaker/Action/Test.hs
--- a/src/Shaker/Action/Test.hs
+++ b/src/Shaker/Action/Test.hs
@@ -3,42 +3,24 @@
 
 import Shaker.Type
 import Shaker.Reflexivite
-import Control.Monad.Trans
+import Control.Monad.Reader
 import Language.Haskell.TH
 
--- | Discover all quickcheck properties in the project 
--- and execute them
-runQuickCheck :: Plugin
-runQuickCheck = collectAllModulesForTest >>= runQuickCheck'
-
--- | Discover all Hunit test in the project and execute them
-runHUnit :: Plugin
-runHUnit = collectAllModulesForTest >>= runHUnit'
-
-runIntelligentHunit :: Plugin
-runIntelligentHunit = collectChangedModulesForTest >>= runHUnit'
-
-runIntelligentQuickCheck :: Plugin
-runIntelligentQuickCheck = collectChangedModulesForTest >>= runQuickCheck'
- 
-runQuickCheck' :: [ModuleMapping] -> Plugin
-runQuickCheck' modMap  
- | null filteredModMap = lift $ putStrLn "No tests to run"
- | otherwise = do
-     resolvedExp <- lift $ runQ (listProperties filteredModMap)
-     let function =  filter (/= '\n') $ pprint resolvedExp
-     let fullFunction = "sequence_ " ++ function ++ " >> return () "
-     lift $ putStrLn fullFunction
-     runFunction $ RunnableFunction modules fullFunction  
- where filteredModMap = filter (not . null . cfPropName) modMap
-       modules = ["Test.QuickCheck","Prelude" ] ++ map cfModuleName filteredModMap 
+runTestFramework :: Plugin 
+runTestFramework = collectAllModulesForTest  >>= runTestFramework'
+        
+runIntelligentTestFramework :: Plugin
+runIntelligentTestFramework = collectChangedModulesForTest >>= runTestFramework'
 
-runHUnit' :: [ModuleMapping] -> Plugin
-runHUnit' modMap = do 
-  let filteredModMap = filter (not . null . cfHunitName) modMap
-  let modules = ["Test.HUnit","Prelude" ] ++ map cfModuleName filteredModMap 
-  resolvedExp <- lift $ runQ (listHunit filteredModMap)
+runTestFramework' :: [ModuleMapping] -> Plugin
+runTestFramework' modules = do
+  arg <- asks argument 
+  let filtered_mod = (filterModulesWithPattern arg . removeNonTestModule) modules 
+  let import_modules = base_modules ++ map cfModuleName filtered_mod
+  resolvedExp <- lift $ runQ (listTestFrameworkGroupList filtered_mod)
   let function =  filter (/= '\n') $ pprint resolvedExp
   lift $ putStrLn function
-  runFunction $ RunnableFunction modules ("runTestTT  $ TestList $ " ++ function) 
+  runFunction $ RunnableFunction import_modules ("defaultMain $ " ++ function) 
+  return () 
+  where base_modules =["Test.Framework", "Test.Framework.Providers.HUnit", "Test.Framework.Providers.QuickCheck2", "Test.QuickCheck", "Test.HUnit", "Prelude" ] 
 
diff --git a/src/Shaker/Cabal/CabalInfo.hs b/src/Shaker/Cabal/CabalInfo.hs
--- a/src/Shaker/Cabal/CabalInfo.hs
+++ b/src/Shaker/Cabal/CabalInfo.hs
@@ -29,15 +29,16 @@
 
 -- | Read the build information from cabal and output a shakerInput from it
 defaultCabalInput :: IO ShakerInput
-defaultCabalInput = readConf >>=
- checkInvalidMain . localBuildInfoToShakerInput
+defaultCabalInput = readConf >>= localBuildInfoToShakerInput >>= checkInvalidMain 
 
 readConf :: IO LocalBuildInfo
 readConf = getPersistBuildConfig "dist"
 
 -- | Extract useful information from localBuildInfo to a ShakerInput
-localBuildInfoToShakerInput :: LocalBuildInfo -> ShakerInput
-localBuildInfoToShakerInput lbi = defaultInput {
+localBuildInfoToShakerInput :: LocalBuildInfo -> IO ShakerInput
+localBuildInfoToShakerInput lbi = do 
+  defInput <- defaultInputInitialized 
+  return defInput {
     compileInputs = cplInputs
     ,listenerInput = compileInputsToListenerInput cplInputs
   }
diff --git a/src/Shaker/Cli.hs b/src/Shaker/Cli.hs
--- a/src/Shaker/Cli.hs
+++ b/src/Shaker/Cli.hs
@@ -9,40 +9,35 @@
 )
  where
 
+import Data.Char
+import Data.List
 import Shaker.Parser
 import Shaker.Type
 import Control.Concurrent
 import Control.Monad.Trans
 import System.Console.Haskeline
 import qualified Data.Map as M
-import Data.List
 import Control.Monad.Reader
- 
--- | The input mvar is used to push the parsed command
-type Input = MVar Command
--- | Token is used to manage the token between action executor and command-line listener
-type Token = MVar Int
 
-data InputState = InputState {  
-  input :: Input,
-  token :: Token
-}
-
 -- | Listen to keyboard input and parse command
-getInput :: InputState -> Shaker IO()
-getInput inSt = do
-        shIn <- ask 
-        lift $ runInputT (myDefaultSettings shIn) $ processInput shIn inSt
+getInput :: Shaker IO( IO() )
+getInput = do
+  shIn <- ask 
+  return $ runInputT (myDefaultSettings shIn) $ withInterrupt $ processInput shIn 
 
 -- | Execute the entered command 
-processInput :: ShakerInput ->  InputState -> InputT IO()
-processInput shIn (InputState inputMv tokenMv) = do
+processInput :: ShakerInput -> InputT IO()
+processInput shIn  = do
+  let (InputState inputMv tokenMv) = inputState shIn
   _ <- lift $ takeMVar tokenMv 
-  minput <- getInputLine "% "
+  minput <-  handleInterrupt (return (Just "quit"))
+               $ getInputLine "% "
   case minput of 
-     Nothing -> return()
-     Just str -> lift $ tryPutMVar inputMv (parseCommand shIn str) >> return() 
-
+     Nothing -> lift $ tryPutMVar inputMv (Just exitCommand ) >> return () 
+     Just str -> either error_action normal_action (parseCommand str shIn)
+                 where error_action err = lift $ print err >> tryPutMVar inputMv Nothing >> return()
+                       normal_action val = lift $ tryPutMVar inputMv (Just val) >> return()
+       
 -- * Auto-completion management 
 
 -- | Settings for haskeline
@@ -62,7 +57,7 @@
 autocompleteFunction :: CommandMap  -> String -> [Completion]
 autocompleteFunction cmdMap [] = map simpleCompletion $ M.keys cmdMap
 autocompleteFunction cmdMap cliInput = map simpleCompletion  compleListProp
-  where inpWords = words cliInput
+  where inpWords = (words . map toLower) cliInput
         lastWord = last inpWords 
         listProp = filter (lastWord `isPrefixOf`) $ M.keys cmdMap
         commonPref = unwords (init inpWords)
diff --git a/src/Shaker/Conductor.hs b/src/Shaker/Conductor.hs
--- a/src/Shaker/Conductor.hs
+++ b/src/Shaker/Conductor.hs
@@ -17,87 +17,102 @@
 import qualified Control.Exception as C
  
 -- | Initialize the master thread 
--- Once the master thread is finished, all input threads are killed
-initThread :: InputState -> Shaker IO()
-initThread inputState = do
-  act <- asks $ runReaderT (getInput inputState) 
-  procId <- lift $ forkIO $ forever act
-  mainThread inputState 
-  lift $ killThread procId
+-- Once quit is called, all threads are killed
+initThread :: Shaker IO()
+initThread = do
+  shIn <- ask
+  input_action <- getInput 
+  lift ( forkIO ( forever input_action) ) >>= addThreadIdToQuitMVar 
+  let main_loop = runReaderT mainThread shIn 
+  lift ( forkIO (forever main_loop) ) >>= addThreadIdToQuitMVar
+  quit_token <- asks (quitToken . threadData)
+  _ <- lift $ takeMVar quit_token
+  cleanAllThreads 
  
 -- | The main thread. 
--- Loop until a Quit action is called
-mainThread :: InputState -> Shaker IO()
-mainThread st@(InputState inputMv tokenMv) = do
+mainThread :: Shaker IO()
+mainThread = do
+  (InputState inputMv tokenMv) <- asks inputState
   _ <- lift $ tryPutMVar tokenMv 42
-  cmd <- lift $ takeMVar inputMv
-  executeCommand cmd  
-  case cmd of
-       Command _ [Action Quit] -> return ()
-       _ ->  mainThread st
-
-data ConductorData = ConductorData {
-  coKillChannel :: MVar [ThreadId]
-  ,coEndToken :: MVar Char
-  ,coEndProcess :: MVar Int
-  ,coListenState :: ListenState
-  ,coFun :: [FileInfo] -> IO ()
- }
+  maybe_cmd <- lift $ takeMVar inputMv 
+  executeCommand maybe_cmd
 
--- | Continuously execute the given action until a keyboard input is done
-listenManager :: Shaker IO() -> Shaker IO()
-listenManager fun = do
-  conductorData <- initializeConductorData fun 
-  lift $ action conductorData
-  where action conductorData = do
-         -- Setup keyboard listener
-         forkIO (getChar >>= putMVar (coEndToken conductorData) ) >>= addThreadIdToMVar conductorData
-         -- Run the action
-         forkIO (forever $ threadExecutor conductorData) >>= addThreadIdToMVar conductorData
-         _ <- readMVar (coEndToken conductorData)
-         cleanThreads conductorData
+data ConductorData = ConductorData ListenState ([FileInfo] -> IO () )
 
 initializeConductorData :: Shaker IO () -> Shaker IO ConductorData 
 initializeConductorData fun = do
   shIn <- ask
   lstState <- initializeListener 
-  killChannel <- lift $ newMVar [] 
-  endToken <- lift newEmptyMVar 
-  endProcess <- lift ( newMVar 42 :: IO ( MVar Int ) )
+  mapM_ addThreadIdToListenMVar $ threadIds lstState 
   let theFun = \a -> runReaderT fun shIn {modifiedInfoFiles = a}
-  return $ ConductorData killChannel endToken endProcess lstState theFun
+  return $ ConductorData lstState theFun
   
-cleanThreads :: ConductorData -> IO()
-cleanThreads (ConductorData chan _ _ lsState _) = do 
-  lstChan <- readMVar chan
-  mapM_ killThread $ lstChan ++ threadIds lsState
+cleanAllThreads :: Shaker IO ()
+cleanAllThreads = do 
+  asks ( threadIdListenList . threadData ) >>= cleanThreads
+  asks ( threadIdQuitList . threadData ) >>= cleanThreads
 
-addThreadIdToMVar :: ConductorData -> ThreadId -> IO ()
-addThreadIdToMVar conductorData thrId = modifyMVar_ (coKillChannel conductorData) (\b -> return $ thrId:b) 
+cleanThreads :: ThreadIdList -> Shaker IO()
+cleanThreads thrdList = lift (readMVar thrdList)  >>= lift . mapM_ killThread 
 
 -- | Execute the given action when the modified MVar is filled
-threadExecutor :: ConductorData -> IO ()
-threadExecutor cdtData@(ConductorData _ _ endProcess listenState fun) = do 
-  modFiles <- takeMVar (mvModifiedFiles listenState)
-  _ <- takeMVar endProcess
-  forkIO (fun modFiles `C.finally` putMVar endProcess 42) >>= addThreadIdToMVar cdtData
+threadExecutor :: ConductorData -> Shaker IO ()  
+threadExecutor conductorData = do 
+  shIn <- ask
+  res <- lift $  handleContinuousInterrupt $ runReaderT (threadExecutor' conductorData) shIn
+  when res $ threadExecutor conductorData
   
+threadExecutor' :: ConductorData -> Shaker IO Bool
+threadExecutor' (ConductorData listenState fun) = lift $ takeMVar (mvModifiedFiles listenState) >>= fun >> return True
+
 -- | Execute Given Command in a new thread
-executeCommand :: Command -> Shaker IO()
-executeCommand (Command OneShot act) = executeAction act 
-executeCommand (Command Continuous act) = listenManager ( executeAction act ) >> return () 
+executeCommand :: Maybe Command -> Shaker IO ()
+executeCommand Nothing = executeAction [Action InvalidAction] 
+executeCommand (Just (Command OneShot act_list)) = executeAction act_list 
+executeCommand (Just (Command Continuous act)) = initializeConductorData ( executeAction act )  >>= threadExecutor 
 
 -- | Execute given action
 executeAction :: [Action] -> Shaker IO()
-executeAction acts = do
-   mapM_ executeAction' acts 
-   return () 
+executeAction acts = do 
+  shIn <- ask
+  let allActs = runReaderT (mapM_ executeAction'  acts) shIn
+  lift $ handleActionInterrupt allActs
+  return () 
 
+-- | Execute a single action with argument
 executeAction' :: Action -> Shaker IO()
-executeAction' (ActionWithArg act arg) = do 
-  plMap<- asks pluginMap 
-  local (\shIn -> shIn {argument = Just arg} ) $ fromJust $ act `M.lookup` plMap
-executeAction' (Action act) = do
+executeAction' (ActionWithArg actKey arg) = do 
   plMap <- asks pluginMap 
-  fromJust $ act `M.lookup` plMap
+  local (\shIn -> shIn {argument = Just arg} ) $ fromJust $ actKey `M.lookup` plMap
+
+-- | Execute a single action without argument
+executeAction' (Action actKey) = do
+  plMap <- asks pluginMap 
+  fromJust $ actKey `M.lookup` plMap
+
+-- * Handlers 
+
+handleContinuousInterrupt :: IO Bool -> IO Bool
+handleContinuousInterrupt = C.handle catchAll 
+  where catchAll :: C.SomeException -> IO Bool
+        catchAll e = putStrLn ("Shaker caught " ++ show e ) >>  return False
+
+handleActionInterrupt :: IO() -> IO()
+handleActionInterrupt =  C.handle catchAll
+  where catchAll :: C.SomeException -> IO ()
+        catchAll e = putStrLn ("Shaker caught " ++ show e ) >>  return ()
+
+-- * Mvar with threadId list management
+
+-- | Add the given threadId to the listener thread list
+addThreadIdToListenMVar :: ThreadId -> Shaker IO()
+addThreadIdToListenMVar thrdId = asks (threadIdListenList . threadData) >>= flip addThreadIdToMVar thrdId
+
+-- | Add the given threadId to the quit thread list
+addThreadIdToQuitMVar :: ThreadId -> Shaker IO()
+addThreadIdToQuitMVar thrdId = asks (threadIdQuitList . threadData) >>= flip addThreadIdToMVar thrdId
+
+-- | Add the given threadId to the mvar list
+addThreadIdToMVar :: ThreadIdList -> ThreadId -> Shaker IO ()
+addThreadIdToMVar thrdList thrId = lift $ modifyMVar_ thrdList (\b -> return $ thrId:b) 
 
diff --git a/src/Shaker/Config.hs b/src/Shaker/Config.hs
--- a/src/Shaker/Config.hs
+++ b/src/Shaker/Config.hs
@@ -17,6 +17,28 @@
   ,modifiedInfoFiles = []
   }
 
+defaultInputInitialized :: IO ShakerInput 
+defaultInputInitialized = do 
+  defThrdData <- defaultThreadData
+  input_state <- defaultInputState 
+  return defaultInput { 
+    threadData = defThrdData 
+    ,inputState = input_state 
+ }
+
+defaultThreadData :: IO ThreadData 
+defaultThreadData = do 
+  thread_listen <- newMVar [] :: IO  ThreadIdList 
+  thread_quit <- newMVar [] :: IO ThreadIdList 
+  listen_token <- newEmptyMVar 
+  quit_token <- newEmptyMVar  
+  return ThreadData {
+      listenToken = listen_token
+      ,quitToken = quit_token
+      ,threadIdListenList = thread_listen
+      ,threadIdQuitList = thread_quit
+    } 
+
 defaultInputState :: IO InputState
 defaultInputState = do
   inputMv <- newEmptyMVar 
diff --git a/src/Shaker/Io.hs b/src/Shaker/Io.hs
--- a/src/Shaker/Io.hs
+++ b/src/Shaker/Io.hs
@@ -1,15 +1,16 @@
 -- | Manage all file operations like listing files with includes and exclude patterns
 -- and file filtering
 module Shaker.Io(
+  -- * List files functions
   listModifiedAndCreatedFiles
+  ,listFiles
   ,getCurrentFpCl
   ,recurseMultipleListFiles
-  ,listFiles
   ,recurseListFiles 
-  ,FileInfo(FileInfo)
-  ,FileListenInfo(..)
+  -- * Test file property
   ,isFileContainingMain
   ,isFileContainingTH
+  -- * Default patterns
   ,defaultHaskellPatterns
   ,defaultExclude
 )
diff --git a/src/Shaker/Parser.hs b/src/Shaker/Parser.hs
--- a/src/Shaker/Parser.hs
+++ b/src/Shaker/Parser.hs
@@ -4,28 +4,34 @@
 )
  where
 
+import Data.Char
+
 import Text.ParserCombinators.Parsec
 import Shaker.Type
 import qualified Data.Map as M
 
 -- | Parse the given string to a Command
-parseCommand :: ShakerInput -> String -> Command
-parseCommand shIn str = 
-  case (parse (typeCommand $ commandMap shIn) "parseCommand" str) of
-    Left _ -> Command OneShot [Action Help] 
-    Right val -> val
+parseCommand :: String -> ShakerInput -> Either ParseError Command
+parseCommand str shIn = parse (typeCommand cmd_map) "parseCommand" process_input
+  where cmd_map = commandMap shIn
+        process_input = map toLower str
 
 -- | Parse a Command
 typeCommand :: CommandMap -> GenParser Char st Command
-typeCommand cmMap = typeDuration >>= \dur ->
+typeCommand cmMap = choice [try typeEmpty, typeCommandNonEmpty cmMap] 
+
+typeCommandNonEmpty :: CommandMap -> GenParser Char st Command 
+typeCommandNonEmpty cmMap = typeDuration >>= \dur ->
   typeMultipleAction cmMap >>= \acts ->
   return (Command dur acts)
 
+typeEmpty :: GenParser Char st Command
+typeEmpty = spaces >> 
+  notFollowedBy anyChar >>
+  return emptyCommand
+
 typeMultipleAction :: CommandMap -> GenParser Char st [Action]
-typeMultipleAction cmMap = many (typeAction cmMap) >>= \res ->
-  case res of 
-       [] -> return [Action Help]
-       _ -> return res
+typeMultipleAction cmMap = many1 (typeAction cmMap)
 
 -- | Parse to an action
 typeAction :: CommandMap -> GenParser Char st Action
diff --git a/src/Shaker/PluginConfig.hs b/src/Shaker/PluginConfig.hs
--- a/src/Shaker/PluginConfig.hs
+++ b/src/Shaker/PluginConfig.hs
@@ -15,11 +15,11 @@
                 (Compile,runCompile ),
                 (FullCompile,runFullCompile ),
                 (Help,runHelp),
+                (InvalidAction,runInvalidAction),
 --                (Execute,runExecute),
-                (QuickCheck,runQuickCheck),
-                (IntelligentQuickCheck,runIntelligentQuickCheck),
-                (IntelligentHunit ,runIntelligentHunit),
-                (HUnit,runHUnit),
+                (TestFramework , runTestFramework),
+                (IntelligentTestFramework , runIntelligentTestFramework),
+                (Empty,runEmpty),
                 (Clean,runClean),
                 (Quit,runExit)
               ]
@@ -27,16 +27,13 @@
 defaultCommandMap :: CommandMap 
 defaultCommandMap = M.fromList list
   where list = [
-            ("Compile",Compile),
-            ("FullCompile",FullCompile),
-            ("Help", Help),
+            ("compile",Compile),
+            ("fullcompile",FullCompile),
+            ("help", Help),
 --            ("Execute", Execute),
-            ("QuickCheck",QuickCheck),
-            ("IQuickCheck",IntelligentQuickCheck),
-            ("IHUnit",IntelligentHunit),
-            ("HUnit",HUnit),
-            ("Clean",Clean),
-            ("q",Quit),
-            ("Quit",Quit)
+            ("test", TestFramework ),
+            ("itest", IntelligentTestFramework ),
+            ("clean",Clean),
+            ("quit",Quit)
           ]
 
diff --git a/src/Shaker/Reflexivite.hs b/src/Shaker/Reflexivite.hs
--- a/src/Shaker/Reflexivite.hs
+++ b/src/Shaker/Reflexivite.hs
@@ -1,16 +1,17 @@
 module Shaker.Reflexivite(
   ModuleMapping(..)
   ,RunnableFunction(..)
+  -- * Collect module information functions
   ,collectAllModulesForTest
   ,collectAllModules
   ,collectChangedModules
   ,collectChangedModulesForTest 
   ,runFunction
+  ,removeNonTestModule
   -- * Template haskell generator
-  ,listHunit
-  ,listProperties
-  ,listAllProperties
-  ,listAllHunit
+  ,listAllTestFrameworkGroupList
+  ,filterModulesWithPattern
+  ,listTestFrameworkGroupList 
 )
  where
 
@@ -19,9 +20,11 @@
 import Shaker.Type 
 import Shaker.Action.Compile
 import Shaker.SourceHelper
+import Shaker.Regex
 
 import Control.Monad.Reader(runReader,runReaderT,asks, Reader, lift, filterM)
 import Control.Arrow
+import Control.Exception as C
 
 import Digraph
 import Language.Haskell.TH
@@ -39,7 +42,7 @@
   ,cfHunitName :: [String] -- ^ Hunit test function names
   ,cfPropName :: [String] -- ^ QuickCheck test function names
  }
- deriving Show
+ deriving (Show,Eq)
 
 data RunnableFunction = RunnableFunction {
   cfModule :: [String]
@@ -60,7 +63,7 @@
   (cpIn, cfFlList) <- initializeFilesForCompilation 
   lift $ runGhc (Just libdir) $ do 
         _ <- ghcCompile $ runReader (fillCompileInputWithStandardTarget cpIn) cfFlList
-        collectAllModulesForTest' 
+        collectAllModules' >>= mapM getModuleMapping 
 
 -- | Collect all non-main modules 
 collectAllModules :: Shaker IO [ModSummary]
@@ -97,8 +100,6 @@
   let sort_mss = flattenSCCs $ topSortModuleGraph True mss Nothing
   return sort_mss
          
-collectAllModulesForTest' :: GhcMonad m => m [ModuleMapping] 
-collectAllModulesForTest' = collectAllModules' >>= mapM getModuleMapping 
 
 collectChangedModules' :: GhcMonad m => [FilePath] -> m [ModSummary] 
 collectChangedModules' modFilePaths = collectAllModules' >>= filterM (isModuleNeedCompilation modFilePaths) 
@@ -114,20 +115,25 @@
 
 -- | Compile, load and run the given function
 runFunction :: RunnableFunction -> Shaker IO()
-runFunction (RunnableFunction funModuleName fun) = do
+runFunction (RunnableFunction importModuleList fun) = do
   (cpIn, cfFlList) <- initializeFilesForCompilation 
   dynFun <- lift $ runGhc (Just libdir) $ do
          _ <- ghcCompile $ runReader (setAllHsFilesAsTargets cpIn >>= removeFileWithMain ) cfFlList
-         configureContext funModuleName
+         configureContext importModuleList
          value <- compileExpr fun
          do let value' = unsafeCoerce value :: a
             return value'
-  _ <- lift dynFun
-  return () 
+  _ <- lift $ handleActionInterrupt dynFun
+  return ()
   where 
         configureContext [] = getModuleGraph >>= \mGraph ->  setContext [] $ map ms_mod mGraph
         configureContext imports = mapM (\a -> findModule (mkModuleName a)  Nothing ) imports >>= \m -> setContext [] m
 
+handleActionInterrupt :: IO() -> IO()
+handleActionInterrupt =  C.handle catchAll
+  where catchAll :: C.SomeException -> IO ()
+        catchAll e = putStrLn ("Shaker caught " ++ show e ) >>  return () 
+
 -- | Collect module name and tests name for the given module
 getModuleMapping :: (GhcMonad m) => ModSummary -> m ModuleMapping
 getModuleMapping  modSum = do 
@@ -141,7 +147,7 @@
 getQuickCheckFunction = getFunctionNameWithPredicate ("prop_" `isPrefixOf`) 
 
 getHunitFunctions :: Maybe ModuleInfo -> [String]
-getHunitFunctions = getFunctionTypeWithPredicate (== "Test.HUnit.Base.Test") 
+getHunitFunctions = getFunctionTypeWithPredicate (== "Test.HUnit.Lang.Assertion") 
 
 getFunctionTypeWithPredicate :: (String -> Bool) -> Maybe ModuleInfo -> [String]
 getFunctionTypeWithPredicate _ Nothing = []
@@ -164,37 +170,49 @@
 tyThingToId :: TyThing -> Maybe Id
 tyThingToId (AnId tyId) = Just tyId
 tyThingToId _ = Nothing
- 
-getQuickCheckProperty :: [ModuleMapping] -> [Exp]
-getQuickCheckProperty = concatMap getQuickCheckProperty'
 
-getQuickCheckProperty' :: ModuleMapping -> [Exp]
-getQuickCheckProperty' modMap = map getSingleQuickCheck $ cfPropName modMap
+-- | List all test group of the project.
+-- see "Shaker.TestTH" 
+listAllTestFrameworkGroupList :: ShakerInput -> ExpQ
+listAllTestFrameworkGroupList shIn = runIO (runReaderT collectAllModulesForTest shIn) >>= listTestFrameworkGroupList . removeNonTestModule
 
-getSingleQuickCheck :: String -> Exp
-getSingleQuickCheck propName = InfixE (Just printName) (VarE $ mkName ">>") (Just quickCall)
-  where quickCall = (AppE (VarE $ mkName "quickCheck" ) . VarE . mkName) propName
-        printName = AppE (VarE $ mkName "putStrLn") (LitE (StringL propName)) 
+-- | List all test group for test-framework from the list of modules
+listTestFrameworkGroupList :: [ModuleMapping] -> ExpQ
+listTestFrameworkGroupList = return . ListE . map getSingleTestFrameworkGroup
 
-getHunit :: [ModuleMapping] -> [Exp]
-getHunit = concatMap getHunit'
+-- | Remove all modules which does not contain test
+removeNonTestModule :: [ModuleMapping] -> [ModuleMapping]
+removeNonTestModule = filter (\modMap -> notEmpty (cfHunitName modMap) || notEmpty (cfPropName modMap) )
+  where notEmpty = not.null
 
-getHunit' :: ModuleMapping -> [Exp]
-getHunit' modMap = map (VarE . mkName) $ cfHunitName modMap
+-- * Test framework integration 
 
-listProperties :: [ModuleMapping] -> ExpQ
-listProperties modMaps = return $ ListE $ getQuickCheckProperty modMaps
+-- | Generate a test group for a given module
+getSingleTestFrameworkGroup :: ModuleMapping -> Exp
+getSingleTestFrameworkGroup modMap = AppE first_arg second_arg
+  where first_arg = AppE (VarE .mkName $ "testGroup") (LitE (StringL $ cfModuleName modMap))
+        second_arg = ListE $ list_prop ++ list_hunit 
+        list_prop = map getSingleFrameworkQuickCheck $ cfPropName modMap
+        list_hunit = map getSingleFrameworkHunit $ cfHunitName modMap
 
--- | List the quickeck properties of the project.
--- see "Shaker.TestTH"
-listAllProperties :: ShakerInput -> ExpQ
-listAllProperties shIn = runIO (runReaderT collectAllModulesForTest shIn) >>= listProperties
+-- | Generate an expression for a single hunit test
+getSingleFrameworkHunit :: String -> Exp 
+getSingleFrameworkHunit hunitName = AppE first_arg second_arg 
+  where first_arg = AppE ( VarE $ mkName "testCase") (LitE $ StringL hunitName)
+        second_arg = VarE . mkName $ hunitName
 
--- | List all test case of the project.
--- see "Shaker.TestTH"
-listHunit :: [ModuleMapping] -> ExpQ
-listHunit modMaps = return $ ListE $ getHunit modMaps
+-- | Generate an expression for a single quickcheck property
+getSingleFrameworkQuickCheck :: String -> Exp
+getSingleFrameworkQuickCheck propName = AppE first_arg second_arg 
+  where canonical_name = tail . dropWhile (/= '_') $ propName 
+        first_arg = AppE ( VarE $ mkName "testProperty") (LitE $ StringL canonical_name)
+        second_arg = VarE . mkName $ propName
 
-listAllHunit :: ShakerInput -> ExpQ
-listAllHunit shIn = runIO ( runReaderT collectAllModulesForTest shIn ) >>= listHunit
+-- * utility functions 
 
+-- | Include only module matching the given pattern
+filterModulesWithPattern :: Maybe String -> [ModuleMapping] -> [ModuleMapping]
+filterModulesWithPattern Nothing mod_map = mod_map
+filterModulesWithPattern (Just pattern) mod_map = filter (\a -> cfModuleName a `elem` filtered_mod_list) mod_map
+  where mod_list = map cfModuleName mod_map
+        filtered_mod_list = processListWithRegexp mod_list [] [pattern]
diff --git a/src/Shaker/Regex.hs b/src/Shaker/Regex.hs
--- a/src/Shaker/Regex.hs
+++ b/src/Shaker/Regex.hs
@@ -14,8 +14,8 @@
 -- If no exclude pattern is given, all elements matching include patterns are taken.
 processListWithRegexp :: 
   [String] -- ^ Initial list to filter
-  -> [String] -- ^ include patterns (regex)
   -> [String] -- ^ exclude patterns (regex)
+  -> [String] -- ^ include patterns (regex)
   -> [String] -- ^ List with all elements matching include patterns minus all elements matching exclude patterns
 processListWithRegexp list [] [] = list
 processListWithRegexp list ignore [] = nub $ list \\ getExcluded list ignore 
@@ -25,8 +25,13 @@
 
 getExcluded :: [String] -> [String] -> [String]
 getExcluded list patterns = filter funExclude list
- where funExclude el = any (el =~) patterns
+ where funExclude el = any (\a -> el =~+ (a,compIgnoreCase, execBlank) ) patterns
 
 getIncluded :: [String] -> [String] -> [String]
 getIncluded list patterns = filter funInclude list
-  where funInclude el = any (el =~) patterns
+  where funInclude el = any (\a -> el =~+ (a,compIgnoreCase, execBlank) ) patterns
+
+(=~+) :: ( RegexMaker regex compOpt execOpt source, RegexContext regex source1 target ) => source1 -> (source, compOpt, execOpt) -> target
+source1 =~+ (source, compOpt, execOpt) = match (makeRegexOpts compOpt execOpt source) source1
+
+
diff --git a/src/Shaker/SourceHelper.hs b/src/Shaker/SourceHelper.hs
--- a/src/Shaker/SourceHelper.hs
+++ b/src/Shaker/SourceHelper.hs
@@ -28,6 +28,7 @@
 import LazyUniqFM
 import MkIface 
 import HscTypes
+import Linker
 
 import System.Directory
 
@@ -39,7 +40,6 @@
   ,cfHasTH :: Bool
  } deriving Show
 
-
 -- | Build the list of haskell source files located in 
 -- CompileInput source dirs
 constructCompileFileList :: CompileInput -> IO [CompileFile] 
@@ -48,6 +48,7 @@
   mapM constructCompileFile files
   where fli = getFileListenInfoForCompileInput cpIn
   
+-- | Build an individual CompileFile. 
 constructCompileFile :: FilePath -> IO CompileFile      
 constructCompileFile fp = do
   hasMain <- isFileContainingMain fp
@@ -60,7 +61,7 @@
 mergeCompileInputsSources [] = defaultCompileInput 
 mergeCompileInputsSources cplInps@(cpIn:_) = do 
   let srcDirs = nub $ concatMap cfSourceDirs cplInps
-  cpIn {cfSourceDirs = srcDirs, cfDescription ="Full compilation"  } 
+  cpIn {cfSourceDirs = srcDirs, cfDescription ="Full compilation"} 
 
 -- | Configure the CompileInput with all haskell files configured as targets
 setAllHsFilesAsTargets :: CompileInput -> CompileR CompileInput
@@ -106,6 +107,8 @@
 ghcCompile :: GhcMonad m => CompileInput -> m SuccessFlag
 ghcCompile cpIn = do   
      initializeGhc cpIn
+     dflags <- getSessionDynFlags
+     liftIO $ unload dflags []
      load LoadAllTargets
 
 initializeGhc :: GhcMonad m => CompileInput -> m ()
diff --git a/src/Shaker/TestTH.hs b/src/Shaker/TestTH.hs
--- a/src/Shaker/TestTH.hs
+++ b/src/Shaker/TestTH.hs
@@ -7,21 +7,11 @@
 import Language.Haskell.TH
 import Shaker.Cabal.CabalInfo
 
--- | Template for the list of quickcheck properties.
--- Currently generate a list of type [IO()] containing
---
--- /[putStrLn "prop_1" >> quickCheck prop_1, ...]/
-thListProperties :: ExpQ 
-thListProperties = do
-  shIn <-runIO defaultCabalInput
-  listAllProperties shIn
-
--- | Template for the list of hunit tests.
--- Currently generate a list of type [Test] containing
+-- | Template for the test group.
+-- Currently generate a list of type [Test] with a test group per module
 --
--- /[test1, test2]/
-thListHunit :: ExpQ 
-thListHunit = do 
-  shIn <-runIO defaultCabalInput
-  listAllHunit shIn
+thListTestFramework :: ExpQ 
+thListTestFramework = do
+  shIn <- runIO defaultCabalInput 
+  listAllTestFrameworkGroupList shIn
 
diff --git a/src/Shaker/Type.hs b/src/Shaker/Type.hs
--- a/src/Shaker/Type.hs
+++ b/src/Shaker/Type.hs
@@ -2,14 +2,21 @@
 module Shaker.Type
  where
 
-import DynFlags
+import DynFlags hiding (OneShot)
 import qualified Data.Map as M
 import Control.Monad.Reader
 import System.Time(ClockTime)
+import Control.Concurrent.MVar
+import Control.Concurrent
 
 -- | Environnement containing the project configuration.
 -- It is generated at startup and won't change
 type Shaker  = ReaderT ShakerInput 
+type ShakerR  = Reader ShakerInput 
+
+type ThreadIdList = MVar [ThreadId]
+type Token = MVar Int
+
 -- | Environnement for the project compilation
 -- This environnement can change depending on the compile 
 -- action called
@@ -26,17 +33,25 @@
   Action ShakerAction
   | ActionWithArg ShakerAction String
   deriving (Show,Eq,Ord)
+ 
+-- | The input mvar is used to push the parsed command
+type Input = MVar (Maybe Command)
 
+data InputState = InputState {  
+  input :: Input,
+  token :: Token -- ^ Token is used to manage the token between action executor and command-line listener
+}
+
 -- | ShakerAction represents the differents actions realisable by shaker
 data ShakerAction = 
 	Compile -- ^ Compile sources with ghc
 	| FullCompile -- ^ Compile all hs sources with ghc
-	| QuickCheck -- ^ Execute quickcheck properties
-	| IntelligentQuickCheck -- ^ Execute quickcheck properties only on necessary properties
-	| HUnit -- ^ Execute hunit tests
-	| IntelligentHunit -- ^ Execute changed hunit tests 
+        | TestFramework -- ^ Execute both quickcheck and hunit using test framework
+        | IntelligentTestFramework -- ^ Execute both quickcheck and hunit using test framework on recompiled modules
+        | InvalidAction -- ^ Display an error when invalid action is inputed
 	| Help -- ^ Display the help
         | Execute -- ^ Execute a command
+        | Empty -- ^ Nothing to execute 
 	| Quit -- ^ Exit shaker
 	| Clean -- ^ Delete generated 
   deriving (Show,Eq,Ord)
@@ -53,7 +68,20 @@
   ,commandMap :: CommandMap
   ,argument :: Maybe String
   ,modifiedInfoFiles :: [FileInfo]
-}
+  ,threadData :: ThreadData 
+  ,inputState :: InputState 
+ }  
+ 
+data ThreadData = ThreadData {
+    -- processToken :: Token
+    listenToken :: Token 
+    ,quitToken :: Token 
+    ,threadIdListenList :: ThreadIdList
+    ,threadIdQuitList :: ThreadIdList
+ }
+     
+getListenThreadList :: ShakerInput -> ThreadIdList 
+getListenThreadList = threadIdListenList . threadData
   
 -- | Configuration flags to pass to the ghc compiler
 data CompileInput = CompileInput{
@@ -133,8 +161,15 @@
 
 -- | Default haskell file pattern : *.hs
 defaultHaskellPatterns :: [String]
-defaultHaskellPatterns = [".*\\.hs$"]
+defaultHaskellPatterns = [".*\\.hs$", ".*\\.lhs"]
 
 -- | Default exclude pattern : Setup.hs
 defaultExclude :: [String]
 defaultExclude =  [".*Setup\\.hs$"]
+
+exitCommand :: Command
+exitCommand = Command OneShot [Action Quit]
+
+emptyCommand :: Command 
+emptyCommand = Command OneShot [Action Empty] 
+
diff --git a/testsuite/tests/RunTestTH.hs b/testsuite/tests/RunTestTH.hs
--- a/testsuite/tests/RunTestTH.hs
+++ b/testsuite/tests/RunTestTH.hs
@@ -2,10 +2,7 @@
 module Main
  where
 
-import Test.HUnit
-import Control.Monad.Trans
 import Shaker.TestTH
-import Test.QuickCheck
 import Shaker.Cabal.CabalInfoTest
 import Shaker.Action.CompileTest
 import Shaker.CliTest
@@ -15,17 +12,10 @@
 import Shaker.IoTest
 import Shaker.ReflexiviteTest
 import Shaker.SourceHelperTest
+import Test.Framework
+import Test.Framework.Providers.HUnit
+import Test.Framework.Providers.QuickCheck2
 
 main :: IO()
-main = do 
-  mapM_ liftIO propLists
-  _ <- testLists
-  return () 
-
-propLists :: [IO()]
-propLists = $(thListProperties)
-
-testLists :: IO Counts
-testLists = runTestTT  $ TestList $(thListHunit)
-
+main = defaultMain $(thListTestFramework)
 
diff --git a/testsuite/tests/Shaker/Action/CompileTest.hs b/testsuite/tests/Shaker/Action/CompileTest.hs
--- a/testsuite/tests/Shaker/Action/CompileTest.hs
+++ b/testsuite/tests/Shaker/Action/CompileTest.hs
@@ -7,16 +7,16 @@
 import Control.Monad.Reader
 import Shaker.CommonTest 
   
-testRunCompileProject :: Test
-testRunCompileProject = TestCase $ 
+testRunCompileProject :: Assertion
+testRunCompileProject = 
   runReaderT runCompile  testShakerInput >> 
   getDirectoryContents "target/Shaker" >>= \cont ->
   doesFileExist "target/Shaker/Action/CompileTest.o" >>= \ex ->
   doesFileExist "target/Shaker/Action/CompileTest.hi" >>= \ex2 ->
   assertBool ("File .o and hi should exists "++ show cont) (ex && ex2)
 
-testRunFullCompile :: Test 
-testRunFullCompile = TestCase $ do
+testRunFullCompile :: Assertion
+testRunFullCompile = do
   runReaderT runFullCompile testShakerInput
   cont <- getDirectoryContents "target/Shaker" 
   ex <- doesFileExist "target/Shaker/Conductor.o" 
diff --git a/testsuite/tests/Shaker/Cabal/CabalInfoTest.hs b/testsuite/tests/Shaker/Cabal/CabalInfoTest.hs
--- a/testsuite/tests/Shaker/Cabal/CabalInfoTest.hs
+++ b/testsuite/tests/Shaker/Cabal/CabalInfoTest.hs
@@ -12,8 +12,8 @@
 import DynFlags( DynFlags, packageFlags, importPaths ,PackageFlag (ExposePackage) , defaultDynFlags
         )
 
-testParseCabalConfig :: Test
-testParseCabalConfig = TestCase $ runTestOnDirectory "testsuite/tests/resources/cabalTest" $ do  
+testParseCabalConfig :: Assertion
+testParseCabalConfig =  runTestOnDirectory "testsuite/tests/resources/cabalTest" $ do  
   shIn <- defaultCabalInput
   let cplInps@(cplLib:cplExe:[]) = compileInputs shIn
   length cplInps == 2 @? "Should have two compile input, one executable and one library, got "++ show ( length cplInps)
@@ -27,14 +27,14 @@
   let (ListenerInput (flLib:[]) _) = listenerInput shIn
   dir flLib == "src" @? "Expected : src, got " ++ show  flLib
 
-testInvalidMainShouldBeExcluded :: Test
-testInvalidMainShouldBeExcluded = TestCase $ runTestOnDirectory "testsuite/tests/resources/invalidMain" $ do
+testInvalidMainShouldBeExcluded :: Assertion
+testInvalidMainShouldBeExcluded =  runTestOnDirectory "testsuite/tests/resources/invalidMain" $ do
  shIn <- defaultCabalInput
  let (cplExe:[]) = compileInputs shIn
  cfTargetFiles cplExe == ["src/Main.hs"] @? "since tests/Main.hs is invalid, should have only src/Main.hs, got " ++ show (cfTargetFiles cplExe)
 
-testCompileWithLocalSource :: Test
-testCompileWithLocalSource = TestCase $ runTestOnDirectory "testsuite/tests/resources/noSourceConfig" $ do
+testCompileWithLocalSource :: Assertion
+testCompileWithLocalSource =  runTestOnDirectory "testsuite/tests/resources/noSourceConfig" $ do
  shIn <- defaultCabalInput
  runReaderT runCompile shIn
  ex <- doesFileExist "target/Main.o" 
@@ -43,8 +43,8 @@
  ex && not ex2 @? "file main should exist and be cleaned"
 
 
-testProjectCabalContentWithLocalSource :: Test
-testProjectCabalContentWithLocalSource = TestCase $
+testProjectCabalContentWithLocalSource :: Assertion
+testProjectCabalContentWithLocalSource = 
     runTestOnDirectory "testsuite/tests/resources/noSourceConfig" $ do
     shIn <- defaultCabalInput
     let cplInps@(cplInp:_) = compileInputs shIn
diff --git a/testsuite/tests/Shaker/CliTest.hs b/testsuite/tests/Shaker/CliTest.hs
--- a/testsuite/tests/Shaker/CliTest.hs
+++ b/testsuite/tests/Shaker/CliTest.hs
@@ -1,6 +1,8 @@
 module Shaker.CliTest
  where
 
+import Data.Char
+
 import Control.Monad
 import Test.QuickCheck 
 import Test.QuickCheck.Monadic
@@ -25,7 +27,7 @@
 checkRes :: Monad m => String -> String -> PropertyM m ()
 checkRes incomplete expected = do
   proposedActions <- listActions defaultInput incomplete
-  assert $ any (\a -> replacement a == expected) proposedActions
+  assert $ any (\a -> replacement a == map toLower expected ) proposedActions
 
 prop_completeWord :: Action -> Property
 prop_completeWord act = monadicIO $ checkRes str str 
diff --git a/testsuite/tests/Shaker/IoTest.hs b/testsuite/tests/Shaker/IoTest.hs
--- a/testsuite/tests/Shaker/IoTest.hs
+++ b/testsuite/tests/Shaker/IoTest.hs
@@ -2,10 +2,9 @@
  where
 
 import Shaker.Io
+import Shaker.Type
 import System.Time
 import Data.List
-import Test.QuickCheck 
-import Test.QuickCheck.Monadic 
 import Test.HUnit hiding (assert)
 
 aTimeDiff :: TimeDiff
@@ -14,75 +13,84 @@
 modifyFileInfoClock :: FileInfo -> FileInfo
 modifyFileInfoClock (FileInfo fp cl) = FileInfo fp (addToClockTime aTimeDiff cl)
 
-abstractTestListFiles :: FileListenInfo -> ([FilePath] -> [FilePath] -> Bool) -> Property
-abstractTestListFiles fli predicat = monadicIO action
-  where action = do
-               lstFile <- run $ listFiles fli{ignore= []}
-               r <- run $ listFiles fli
-               assert $ predicat lstFile r 
+defaultFileListenInfo :: FileListenInfo
+defaultFileListenInfo = FileListenInfo "src" [] [] 
 
-prop_listFiles :: FileListenInfo -> Property
-prop_listFiles fli = abstractTestListFiles fli{ignore=[]} (\_ b -> length b>2)
+type ExpectedFiles = [FilePath]
+type PresentFiles = [FilePath]
 
-prop_listFilesWithIgnoreAll :: FileListenInfo -> Property
-prop_listFilesWithIgnoreAll fli = abstractTestListFiles fli{ignore= [".*"], include=[]} (\_ b -> b==[])
+abstractHunitTestListFiles :: FileListenInfo -> (PresentFiles -> ExpectedFiles -> Bool) -> IO Bool
+abstractHunitTestListFiles fli predicat = do 
+  normal_list <- listFiles fli{ignore= []}
+  res <- listFiles fli
+  return $ predicat normal_list res
 
-prop_listFilesWithIgnore :: FileListenInfo -> Property
-prop_listFilesWithIgnore fli = abstractTestListFiles fli{ignore= ["\\.$"], include=[]} (\a b-> length a == length b + 2)
+type ModifyFileInfo = [FileInfo] -> [FileInfo]
+type Predicat = [FileInfo] -> [FileInfo] ->Bool
 
-prop_listFilesWithIncludeAll :: FileListenInfo -> Property
-prop_listFilesWithIncludeAll fli = abstractTestListFiles fli{include=[".*"]} (\a b->length a >= length b)
+abstractTestModifiedFiles :: FileListenInfo -> ModifyFileInfo -> Predicat -> IO Bool
+abstractTestModifiedFiles fli proc predicat= do
+     curList <- getCurrentFpCl fli 
+     (_,newList) <- listModifiedAndCreatedFiles [fli] (proc curList)
+     return $ predicat curList newList 
 
-testModifiedFiles :: FileListenInfo -> ([FileInfo] -> [FileInfo]) -> ([FileInfo] -> [FileInfo] ->Bool) -> Property
-testModifiedFiles fli proc predicat= monadicIO action
-  where action = do 
-               curList <- run $ getCurrentFpCl fli 
-               (_,newList) <- run $ listModifiedAndCreatedFiles [fli] (proc curList)
-               assert $ predicat curList newList 
+testListFiles :: Assertion
+testListFiles =  do 
+  res <- abstractHunitTestListFiles defaultFileListenInfo (\_ b -> length b > 2 )
+  res  @? "should have more than 2 files in src/"
 
-prop_listModifiedFiles :: FileListenInfo -> Property
-prop_listModifiedFiles fli = 
-  testModifiedFiles fli (map modifyFileInfoClock) (\a b -> length a == length b)
+testListFilesWithIgnoreAll :: Assertion
+testListFilesWithIgnoreAll =  do 
+  res <- abstractHunitTestListFiles defaultFileListenInfo {ignore=[".*"]} (\_ b -> b == [] )
+  res  @? "List with ignore all should return an empty list"
 
-prop_listCreatedFiles :: FileListenInfo -> Property
-prop_listCreatedFiles fli = 
-  testModifiedFiles fli init (\_ b -> length b==1)
+testListFilesWithIgnore :: Assertion
+testListFilesWithIgnore =  do
+  res <-  abstractHunitTestListFiles defaultFileListenInfo {ignore=["\\.$"]} (\a b -> length a  ==length b + 2)
+  res @? "ignore of \\.$ should exclude only . and .."
 
-prop_listModifiedAndCreatedFiles :: FileListenInfo -> Property
-prop_listModifiedAndCreatedFiles fli = 
-  testModifiedFiles fli (map modifyFileInfoClock . init) (\a b -> length a == length b)
+testListFilesWithIncludeAll :: Assertion
+testListFilesWithIncludeAll =  do 
+  res <- abstractHunitTestListFiles defaultFileListenInfo {include=[".*"]} (\a b->length a == length b)
+  res @? "inclue of .* should should list all files"
 
-testRecurseListFiles :: Test
-testRecurseListFiles = TestCase $ 
+testListModifiedFiles :: Assertion
+testListModifiedFiles =  do
+  res <- abstractTestModifiedFiles defaultFileListenInfo (map modifyFileInfoClock) (\a b -> length a == length b)
+  res @? "all modified files should be listed "
+
+testListCreatedFiles :: Assertion
+testListCreatedFiles =  do
+  res <- abstractTestModifiedFiles defaultFileListenInfo init (\_ b -> length b==1)
+  res @? "a created file should be listed "
+
+testListModifiedAndCreatedFiles :: Assertion
+testListModifiedAndCreatedFiles =  do
+  res <- abstractTestModifiedFiles defaultFileListenInfo (map modifyFileInfoClock . init) (\a b -> length a == length b)
+  res @? "should list modified and created files"
+
+testRecurseListFiles :: Assertion
+testRecurseListFiles =  
   recurseListFiles (FileListenInfo "." ["\\.$"] []) >>= \res ->
-  assertBool ("Should contains IoTest.hs file "++show res) $
-    any ("IoTest.hs" `isSuffixOf`) res
-  
-testListFiles :: Test
-testListFiles = TestCase $ 
-  listFiles (FileListenInfo "." [] []) >>= \res ->
-  assertBool ("Should contains src dir"++show res) $
-    any ("src" `isSuffixOf`) res
+  any ("IoTest.hs" `isSuffixOf`) res @? "Should contains IoTest.hs file "++show res
   
-testListHsFiles :: Test
-testListHsFiles = TestCase $
+testListHsFiles :: Assertion
+testListHsFiles = 
   recurseListFiles (FileListenInfo "." [] [".*\\.hs$"]) >>= \res ->
-  assertBool ("Should only contains hs files " ++ show res) $
-    all (".hs" `isSuffixOf`) res
-
-testIsFileContainingMain :: Test
-testIsFileContainingMain = TestCase $ do
+  all (".hs" `isSuffixOf`) res @?  "Should only contains hs files " ++ show res
+    
+testIsFileContainingMain :: Assertion
+testIsFileContainingMain =  do
   res <- isFileContainingMain "prog/Shaker.hs" 
-  assertBool "File Shaker.hs should contain main methods" res
+  res @? "File Shaker.hs should contain main methods" 
 
-testIsFileNotContainingMain :: Test
-testIsFileNotContainingMain = TestCase $ do
+testIsFileNotContainingMain :: Assertion
+testIsFileNotContainingMain =  do
   res <- isFileContainingMain "src/Shaker/Config.hs"
-  assertBool "File Config.hs should not contain main methods" $ not res
+  not res @? "File Config.hs should not contain main methods" 
 
-testIsFileConductorNotContainingMain :: Test
-testIsFileConductorNotContainingMain = TestCase $ do
+testIsFileConductorNotContainingMain :: Assertion
+testIsFileConductorNotContainingMain =  do
   res <- isFileContainingMain "src/Shaker/Conductor.hs"
-  assertBool "File Config.hs should not contain main methods" $ not res
+  not res @?  "File Config.hs should not contain main methods" 
 
- 
diff --git a/testsuite/tests/Shaker/ListenerTest.hs b/testsuite/tests/Shaker/ListenerTest.hs
--- a/testsuite/tests/Shaker/ListenerTest.hs
+++ b/testsuite/tests/Shaker/ListenerTest.hs
@@ -3,36 +3,38 @@
 
 import Control.Concurrent
 import Shaker.Listener
-import Shaker.Properties()
-import Test.QuickCheck 
-import Test.QuickCheck.Monadic 
+import Test.HUnit 
 import Shaker.Type
 import Shaker.Io
-
-prop_updateFileStat :: [FileInfo] ->[FileInfo] -> Property
-prop_updateFileStat curF curM = not (null curM) ==>
-  monadicIO $ do
-          mC <- run $ newMVar []
-          mM <- run newEmptyMVar 
-          run (updateFileStat mC mM curF curM) 
-          mCurF <- run $ readMVar mC
-          assert $  curF == mCurF
+import System.Time
 
-prop_schedule :: FileListenInfo -> Property
-prop_schedule fli = monadicIO $ do 
-                   mJ <- run newEmptyMVar 
-  		   run $ schedule (ListenerInput [fli] 0) mJ
-  		   res <- run (tryTakeMVar mJ)
-		   assert $ res == Just [fli]
+testUpdateFileStat :: Assertion
+testUpdateFileStat = do
+  let clockTime = TOD 100 100
+  let curF = [FileInfo "." clockTime]
+  let curM = [FileInfo ".." clockTime]
+  mC <- newMVar []
+  mM <- newEmptyMVar 
+  (updateFileStat mC mM curF curM) 
+  mCurF <- readMVar mC
+  curF == mCurF @? "current file should be equal to the file in mvar"
 
-prop_listen :: FileListenInfo -> Property
-prop_listen fli = monadicIO $ do
-        expected <- run $ getCurrentFpCl fli
-	mC <- run $ newMVar []
-	mM <- run newEmptyMVar 
-	mJ <- run $ newMVar [fli]
-	run $ listen mC mM mJ
-	Just res <- run $ tryTakeMVar mC
-	assert $ expected == res
+testSchedule :: Assertion
+testSchedule = do
+  let fli = FileListenInfo "." [] []
+  mJ <- newEmptyMVar 
+  schedule (ListenerInput [fli] 0) mJ
+  res <- (tryTakeMVar mJ)
+  res == Just [fli] @? "scheduled fileListenInfo should be put in the job mvar"
 
+testListen :: Assertion
+testListen = do 
+  let fli = FileListenInfo "." [] []
+  expected <- getCurrentFpCl fli
+  mC <- newMVar []
+  mM <- newEmptyMVar 
+  mJ <- newMVar [fli]
+  listen mC mM mJ
+  Just res <- tryTakeMVar mC
+  expected == res @? "listen should processe the FileListenInfo in the job box"
 
diff --git a/testsuite/tests/Shaker/ParserTest.hs b/testsuite/tests/Shaker/ParserTest.hs
--- a/testsuite/tests/Shaker/ParserTest.hs
+++ b/testsuite/tests/Shaker/ParserTest.hs
@@ -1,6 +1,8 @@
 module Shaker.ParserTest
  where
 
+import Control.Arrow 
+
 import Test.QuickCheck
 import Shaker.Type
 import Shaker.Parser
@@ -10,12 +12,12 @@
 import Data.Char
  
 prop_parseDefaultAction :: String -> Bool
-prop_parseDefaultAction act = res == Command OneShot [Action Help]
-  where res = parseCommand defaultInput ('x' :act )
+prop_parseDefaultAction act = either (\_ -> True) (\_ -> False) res
+  where res = parseCommand ('x' :act) defaultInput 
 
 prop_parseCommand :: CommandString -> Bool
-prop_parseCommand (CommandString str expCom) = parsed == expCom 
-  where parsed = parseCommand defaultInput str
+prop_parseCommand (CommandString str expCom) = either (\_ -> False) (== expCom) res
+  where res = parseCommand str defaultInput
 
 -- * Arbitrary instances 
 
@@ -31,12 +33,22 @@
        ,cfAction :: Action
 } deriving (Show)
 
+constructActionString :: (String, ShakerAction) -> ActionString
+constructActionString (key, value) = ActionString key (Action value)
+
 instance Arbitrary ActionString where
   arbitrary = do 
-        str <- listOf $ elements ['a'..'p'] 
+        str <- listOf $ elements ['a'..'z'] 
         proc str 
-        where proc "" = elements $ map (\(key,value) -> ActionString key (Action value)) (toList defaultCommandMap)
-              proc str = elements $ map (\(key,value) -> ActionString (key ++ " " ++ trim str) (ActionWithArg value str)  ) (toList defaultCommandMap)
+        where 
+              -- Build action string without arg
+              proc "" = oneof [
+                         elements $ map (constructActionString . first (map toUpper)) listCommandMap 
+                         ,elements $ map constructActionString listCommandMap
+                        ]
+              -- build action string with args
+              proc str = elements $ map (\(key,value) -> ActionString (key ++ " " ++ trim str) (ActionWithArg value str)  ) listCommandMap 
+              listCommandMap = toList defaultCommandMap 
 
 trim :: String -> String
 trim = reverse . dropWhile isSpace . reverse
@@ -44,11 +56,13 @@
 instance Arbitrary CommandString where
   arbitrary = do 
     dur <- elements [Continuous,OneShot]
-    actionStrings <- listOf1 arbitrary
-    return CommandString {
-        comStr = getStringFromDurationAndAction dur actionStrings
-        ,command = Command dur (map cfAction actionStrings) 
-    }
+    spaces <- listOf $ elements " "
+    actionString_list <- listOf1 arbitrary
+    elements [
+        CommandString { comStr = getStringFromDurationAndAction dur actionString_list
+          ,command = Command dur (map cfAction actionString_list) }
+        , CommandString spaces $ Command OneShot [Action Empty]
+        ]
 
 getStringFromDurationAndAction :: Duration -> [ActionString] -> String
 getStringFromDurationAndAction dur acts  =
diff --git a/testsuite/tests/Shaker/Properties.hs b/testsuite/tests/Shaker/Properties.hs
--- a/testsuite/tests/Shaker/Properties.hs
+++ b/testsuite/tests/Shaker/Properties.hs
@@ -3,30 +3,54 @@
 
 import Control.Monad
 import Test.QuickCheck 
+import Shaker.Type
 import System.Time
-import Shaker.Io
+import Shaker.Reflexivite
 
 instance Arbitrary TimeDiff where
-   arbitrary =  TimeDiff `liftM` elements tab
-			 `ap` elements tab
-			 `ap` elements tab
-			 `ap` elements tab
-			 `ap` elements tab
-			 `ap` elements tab
-			 `ap` elements (map fromIntegral tab)
-     where tab = [1..10] 
+   arbitrary =  TimeDiff `liftM` genSmallNumber
+			 `ap` genSmallNumber 
+			 `ap` genSmallNumber 
+			 `ap` genSmallNumber 
+			 `ap` genSmallNumber 
+			 `ap` genSmallNumber 
+			 `ap` elements [1..10] 
 
 instance Arbitrary ClockTime where
    arbitrary = TOD `liftM` elements [1..1000]
 		   `ap` elements [1..1000]
 
 instance Arbitrary FileListenInfo where 
-   arbitrary = FileListenInfo `liftM` elements ["src","testsuite"]
-			      `ap` listOf (elements ["\\.$","ab"])
-			      `ap` elements [[],[".*"]]
+   arbitrary = do
+     gen_dir <- elements ["src","testsuite"]
+     sizeIgnore <- genSmallNumber
+     gen_ignore <- vectorOf sizeIgnore $ elements ["\\.$","ab"]
+     gen_include <- elements [[],[".*"]]
+     return $ FileListenInfo gen_dir gen_ignore gen_include
 
 instance Arbitrary FileInfo where
    arbitrary = arbitrary >>= \cl ->
                elements [".",".."] >>= \ele ->
                return $ FileInfo ele cl
+
+instance Arbitrary ModuleMapping where 
+  arbitrary = do 
+              name <- createShortName
+              listHunitName <- listOf createShortName 
+              listPropName <- listOf createShortName 
+              return $ ModuleMapping name listHunitName listPropName
+
+genSmallNumber :: Gen Int
+genSmallNumber = elements [0..10]
+
+createListName :: Gen [String]
+createListName = do 
+ sizeList <- genSmallNumber
+ vectorOf sizeList createShortName
+
+createShortName :: Gen String
+createShortName = do
+ sizeName <- genSmallNumber
+ vectorOf sizeName letters
+ where letters = elements $ '.' : ['a'..'z'] 
 
diff --git a/testsuite/tests/Shaker/ReflexiviteTest.hs b/testsuite/tests/Shaker/ReflexiviteTest.hs
--- a/testsuite/tests/Shaker/ReflexiviteTest.hs
+++ b/testsuite/tests/Shaker/ReflexiviteTest.hs
@@ -2,18 +2,21 @@
  where
 
 import Test.HUnit
+import Test.QuickCheck 
+
 import Data.List
 import Control.Monad.Reader(runReaderT)
 import Shaker.Reflexivite
 import Shaker.Type
 import Shaker.CommonTest
+import Shaker.Properties()
 
 import System.Time
 import System.Directory
 import System.FilePath 
 
-testRunReflexivite ::Test
-testRunReflexivite = TestCase $ do
+testRunReflexivite :: Assertion
+testRunReflexivite =  do
   modMapLst <- runReaderT collectAllModulesForTest testShakerInput
   length modMapLst > 1 @? "Should have more than one module, got : "++ show (length modMapLst)
   any ( \(ModuleMapping nm _ _) -> nm == "Shaker.ReflexiviteTest") modMapLst @? 
@@ -35,21 +38,21 @@
   where proc True fp = removeDirectory fp >> createDirectory fp
         proc _ fp = createDirectory fp
 
-testRunFunction :: Test
+testRunFunction :: Assertion
 testRunFunction = templateTestRunFunction ["Shaker.ReflexiviteTest"]
 
-testRunFunctionWithEmptyModule :: Test
+testRunFunctionWithEmptyModule :: Assertion
 testRunFunctionWithEmptyModule = templateTestRunFunction [] 
 
-templateTestRunFunction :: [String] -> Test 
-templateTestRunFunction modules= TestCase $ do 
+templateTestRunFunction :: [String] -> Assertion
+templateTestRunFunction modules=  do 
   tempFp <- getTemporaryDirectory >>= \a -> return $ a++"/testSha"
   let run = RunnableFunction modules $ "aFun " ++ show tempFp
   runReaderT (runFunction run) testShakerInput 
   doesDirectoryExist tempFp @? "Directory /tmp/testSha should have been created"
   
-testCollectChangedModules :: Test
-testCollectChangedModules = TestCase $ do
+testCollectChangedModules :: Assertion
+testCollectChangedModules =  do
   (cpIn,_) <- compileProject
   exp_no_modules <- runReaderT collectChangedModules testShakerInput 
   length exp_no_modules == 0 @? "There should be no modules to recompile"
@@ -59,13 +62,13 @@
   exp_one_modules <- runReaderT collectChangedModules testShakerInput 
   length exp_one_modules == 1 @? "One module (SourceHelperTest) should need compilation"
 
-testCollectChangedModulesForTestNoRecomp :: Test
-testCollectChangedModulesForTestNoRecomp = TestCase $ do
+testCollectChangedModulesForTestNoRecomp :: Assertion
+testCollectChangedModulesForTestNoRecomp =  do
   exp_no_modules <- runReaderT collectChangedModulesForTest testShakerInput 
   length exp_no_modules == 0 @? "There should be no modules to recompile"
 
-testCollectChangedModulesForTestHunit:: Test
-testCollectChangedModulesForTestHunit = TestCase $ do
+testCollectChangedModulesForTestHunit:: Assertion
+testCollectChangedModulesForTestHunit =  do
   (cpIn,_) <- compileProject
   let target = cfCompileTarget cpIn </> "Shaker" </> "SourceHelperTest.hi"
   removeFile target
@@ -75,8 +78,8 @@
   cfModuleName module_mapping == "Shaker.SourceHelperTest" @? "module SourceHelperTest should need recompilation, got " ++ cfModuleName module_mapping 
   length (cfHunitName module_mapping) >2  @? "module SourceHelperTest should have hunit test" 
   
-testCollectChangedModulesForTestQuickCheck :: Test
-testCollectChangedModulesForTestQuickCheck = TestCase $ do
+testCollectChangedModulesForTestQuickCheck :: Assertion
+testCollectChangedModulesForTestQuickCheck =  do
   (cpIn,_) <- compileProject
   let target = cfCompileTarget cpIn </> "Shaker" </> "RegexTest.hi"
   removeFile target
@@ -86,11 +89,20 @@
   cfModuleName module_mapping == "Shaker.RegexTest" @? "module RegexTest should need recompilation, got " ++ cfModuleName module_mapping 
   length (cfPropName module_mapping) >2  @? "module RegexTest should have properties" 
 
-testCollectChangedModulesWithModifiedFiles :: Test
-testCollectChangedModulesWithModifiedFiles = TestCase $ do
+testCollectChangedModulesWithModifiedFiles :: Assertion
+testCollectChangedModulesWithModifiedFiles =  do
   (cpIn,_) <- compileProject
   let sources = map (</> "Shaker" </> "SourceHelperTest.hs") (cfSourceDirs cpIn)
   let modFileInfo = map (\a -> FileInfo a (TOD 0 0) ) sources
   exp_one_modules <- runReaderT collectChangedModulesForTest testShakerInput {modifiedInfoFiles = modFileInfo }
   length exp_one_modules == 1 @? "One module should need compilation"
   
+prop_filterModMap_include_all :: [ModuleMapping] -> Bool
+prop_filterModMap_include_all modMap = modMap == res
+  where res = filterModulesWithPattern (Just ".*") modMap 
+        
+prop_filterModMap_include_some :: [ModuleMapping] -> Property
+prop_filterModMap_include_some modMap = (not . null) modMap ==> head res == head modMap
+  where module_name = (cfModuleName . head) modMap
+        res = filterModulesWithPattern (Just module_name) modMap 
+
diff --git a/testsuite/tests/Shaker/SourceHelperTest.hs b/testsuite/tests/Shaker/SourceHelperTest.hs
--- a/testsuite/tests/Shaker/SourceHelperTest.hs
+++ b/testsuite/tests/Shaker/SourceHelperTest.hs
@@ -16,27 +16,27 @@
 
 import System.FilePath 
 
-testConstructCompileFileList :: Test
-testConstructCompileFileList = TestCase $ runTestOnDirectory "testsuite/tests/resources/cabalTest" $ do 
+testConstructCompileFileList :: Assertion
+testConstructCompileFileList =  runTestOnDirectory "testsuite/tests/resources/cabalTest" $ do 
   let cpIn = initializeEmptyCompileInput {cfSourceDirs = ["src"]}
   fileList <- constructCompileFileList cpIn 
   any (\cpFl -> "Main.hs" `isSuffixOf` cfFp cpFl && cfHasMain cpFl) fileList @? "Should have one main file, got " ++ show fileList
   any (\cpFl -> "CabalTest.hs" `isSuffixOf` cfFp cpFl && (not . cfHasMain) cpFl) fileList @? "Should have one main file, got " ++ show fileList
 
-testConstructConductorCompileFileList :: Test
-testConstructConductorCompileFileList = TestCase $ do
+testConstructConductorCompileFileList :: Assertion
+testConstructConductorCompileFileList =  do
   list <- constructCompileFileList defaultCompileInput 
   let (Just cpFile) = find (\a ->  "Conductor.hs" `isSuffixOf` cfFp a ) list
   not (cfHasMain cpFile) && not (cfHasTH cpFile) @? "Should have conductor in list, got " ++ show cpFile
 
-testCompileInputConstruction :: Test
-testCompileInputConstruction = TestCase $ do
+testCompileInputConstruction :: Assertion
+testCompileInputConstruction =  do
   list <- constructCompileFileList defaultCompileInput 
   let newCpIn = runReader (fillCompileInputWithStandardTarget defaultCompileInput) list 
   any (\a -> "Conductor.hs" `isSuffixOf` a) (cfTargetFiles newCpIn) @?"Should have conductor in list, got " ++ show (cfTargetFiles newCpIn)
 
-testCheckUnchangedSources :: Test
-testCheckUnchangedSources = TestCase $ do
+testCheckUnchangedSources :: Assertion
+testCheckUnchangedSources =  do
   cfFlList <- constructCompileFileList cpIn
   mss <- runGhc (Just libdir) $ do 
             _ <- initializeGhc $ runReader (fillCompileInputWithStandardTarget cpIn) cfFlList
@@ -52,8 +52,8 @@
   length exp_one_false == length hsSrcs - 1 @? "partial checkUnchangedSources should have only one false"
  where cpIn = head . compileInputs $ testShakerInput 
 
-testModuleNeedCompilation :: Test
-testModuleNeedCompilation = TestCase $ do 
+testModuleNeedCompilation :: Assertion
+testModuleNeedCompilation =  do 
  (cpIn, cfFlList) <- compileProject
  let targets = map (</> "Shaker" </> "SourceHelperTest.hs") (cfSourceDirs cpIn)
  runGhc (Just libdir) $ do 
