diff --git a/hspec.cabal b/hspec.cabal
--- a/hspec.cabal
+++ b/hspec.cabal
@@ -1,5 +1,5 @@
 name:             hspec
-version:          1.8.3
+version:          1.9.0
 license:          MIT
 license-file:     LICENSE
 copyright:        (c) 2011-2014 Simon Hengel,
@@ -40,14 +40,15 @@
       src
   build-depends:
       base          == 4.*
-    , random        == 1.0.*
+    , random
+    , tf-random
     , setenv
     , ansi-terminal >= 0.5
     , time
     , transformers  >= 0.2.2.0 && < 0.4.0
     , deepseq
     , HUnit         >= 1.2.5
-    , QuickCheck    >= 2.5.1
+    , QuickCheck    >= 2.7
     , quickcheck-io
     , hspec-expectations == 0.5.0.*
   exposed-modules:
@@ -95,7 +96,8 @@
       -Wall -Werror
   build-depends:
       base          == 4.*
-    , random        == 1.0.*
+    , random
+    , tf-random
     , setenv
     , silently      >= 1.2.4
     , ansi-terminal
@@ -107,7 +109,7 @@
     , quickcheck-io
     , hspec-expectations
 
-    , hspec-meta >= 1.8.0
+    , hspec-meta >= 1.9.0
     , process
     , ghc-paths
 
diff --git a/src/Test/Hspec.hs b/src/Test/Hspec.hs
--- a/src/Test/Hspec.hs
+++ b/src/Test/Hspec.hs
@@ -36,7 +36,6 @@
 import           Test.Hspec.Runner
 import           Test.Hspec.HUnit ()
 import           Test.Hspec.Expectations
-import           Test.Hspec.Core (mapSpecItem)
 import qualified Test.Hspec.Core as Core
 
 -- | Combine a list of specs into a larger spec.
diff --git a/src/Test/Hspec/Config.hs b/src/Test/Hspec/Config.hs
--- a/src/Test/Hspec/Config.hs
+++ b/src/Test/Hspec/Config.hs
@@ -3,7 +3,7 @@
 , defaultConfig
 , getConfig
 , configAddFilter
-, configSetSeed
+, configQuickCheckArgs
 ) where
 
 import           Control.Applicative
@@ -12,12 +12,12 @@
 import           System.IO
 import           System.Exit
 import qualified Test.QuickCheck as QC
+import           Test.QuickCheck.Random (mkQCGen)
 import           Test.Hspec.Formatters
 
 import           Test.Hspec.Util
 
--- for Monad (Either e) when base < 4.3
-import           Control.Monad.Trans.Error ()
+import           Control.Monad.Trans.Error () -- for Monad (Either e) when base < 4.3
 
 import           Test.Hspec.Options
 import           Test.Hspec.FailureReport
@@ -31,7 +31,10 @@
 -- A predicate that is used to filter the spec before it is run.  Only examples
 -- that satisfy the predicate are run.
 , configFilterPredicate :: Maybe (Path -> Bool)
-, configQuickCheckArgs  :: QC.Args
+, configQuickCheckSeed :: Maybe Integer
+, configQuickCheckMaxSuccess :: Maybe Int
+, configQuickCheckMaxDiscardRatio :: Maybe Int
+, configQuickCheckMaxSize :: Maybe Int
 , configSmallCheckDepth :: Int
 , configColorMode       :: ColorMode
 , configFormatter       :: Formatter
@@ -40,7 +43,7 @@
 }
 
 defaultConfig :: Config
-defaultConfig = Config False False False Nothing QC.stdArgs 5 ColorAuto specdoc False (Left stdout)
+defaultConfig = Config False False False Nothing Nothing Nothing Nothing Nothing 5 ColorAuto specdoc False (Left stdout)
 
 -- | Add a filter predicate to config.  If there is already a filter predicate,
 -- then combine them with `||`.
@@ -54,16 +57,16 @@
   (Just p1, Just p2) -> Just $ \path -> p1 path || p2 path
   _ -> p1_ <|> p2_
 
-configSetSeed :: Integer -> Config -> Config
-configSetSeed n c = c {configQuickCheckArgs = (configQuickCheckArgs c) {QC.replay = Just (stdGenFromInteger n, 0)}}
-
 mkConfig :: Maybe FailureReport -> Options -> Config
 mkConfig mFailureReport opts = Config {
     configDryRun          = optionsDryRun opts
   , configPrintCpuTime    = optionsPrintCpuTime opts
   , configFastFail        = optionsFastFail opts
   , configFilterPredicate = matchFilter `filterOr` rerunFilter
-  , configQuickCheckArgs  = qcArgs
+  , configQuickCheckSeed = mSeed
+  , configQuickCheckMaxSuccess = mMaxSuccess
+  , configQuickCheckMaxDiscardRatio = mMaxDiscardRatio
+  , configQuickCheckMaxSize = mMaxSize
   , configSmallCheckDepth = fromMaybe (configSmallCheckDepth defaultConfig) (optionsDepth opts)
   , configColorMode       = optionsColorMode opts
   , configFormatter       = optionsFormatter opts
@@ -71,17 +74,27 @@
   , configHandle          = maybe (configHandle defaultConfig) Right (optionsOutputFile opts)
   }
   where
-    qcArgs = (
-        maybe id setSeed mSeed
-      . maybe id setMaxDiscardRatio mMaxDiscardRatio
-      . maybe id setMaxSize mMaxSize
-      . maybe id setMaxSuccess mMaxSuccess) QC.stdArgs
 
     mSeed = optionsSeed opts <|> (failureReportSeed <$> mFailureReport)
     mMaxSuccess = optionsMaxSuccess opts <|> (failureReportMaxSuccess <$> mFailureReport)
     mMaxSize = optionsMaxSize opts <|> (failureReportMaxSize <$> mFailureReport)
     mMaxDiscardRatio = optionsMaxDiscardRatio opts <|> (failureReportMaxDiscardRatio <$> mFailureReport)
 
+    matchFilter = case optionsMatch opts of
+      [] -> Nothing
+      xs -> Just $ foldl1' (\p0 p1 path -> p0 path || p1 path) (map filterPredicate xs)
+
+    rerunFilter = flip elem . failureReportPaths <$> mFailureReport
+
+configQuickCheckArgs :: Config -> QC.Args
+configQuickCheckArgs c = qcArgs
+  where
+    qcArgs = (
+        maybe id setSeed (configQuickCheckSeed c)
+      . maybe id setMaxDiscardRatio (configQuickCheckMaxDiscardRatio c)
+      . maybe id setMaxSize (configQuickCheckMaxSize c)
+      . maybe id setMaxSuccess (configQuickCheckMaxSuccess c)) QC.stdArgs
+
     setMaxSuccess :: Int -> QC.Args -> QC.Args
     setMaxSuccess n args = args {QC.maxSuccess = n}
 
@@ -92,13 +105,7 @@
     setMaxDiscardRatio n args = args {QC.maxDiscardRatio = n}
 
     setSeed :: Integer -> QC.Args -> QC.Args
-    setSeed n args = args {QC.replay = Just (stdGenFromInteger n, 0)}
-
-    matchFilter = case optionsMatch opts of
-      [] -> Nothing
-      xs -> Just $ foldl1' (\p0 p1 path -> p0 path || p1 path) (map filterPredicate xs)
-
-    rerunFilter = flip elem . failureReportPaths <$> mFailureReport
+    setSeed n args = args {QC.replay = Just (mkQCGen (fromIntegral n), 0)}
 
 getConfig :: Options -> String -> [String] -> IO Config
 getConfig opts_ prog args = do
diff --git a/src/Test/Hspec/Core.hs b/src/Test/Hspec/Core.hs
--- a/src/Test/Hspec/Core.hs
+++ b/src/Test/Hspec/Core.hs
@@ -42,14 +42,6 @@
 hspecWith :: Config -> [SpecTree] -> IO Summary
 hspecWith c = Runner.hspecWith c . fromSpecList
 
-mapSpecItem :: (Item -> Item) -> Spec -> Spec
-mapSpecItem f = fromSpecList . map go . runSpecM
-  where
-    go :: SpecTree -> SpecTree
-    go spec = case spec of
-      SpecItem item -> SpecItem (f item)
-      SpecGroup d es -> SpecGroup d (map go es)
-
 modifyParams :: (Params -> Params) -> Spec -> Spec
 modifyParams f = mapSpecItem $ \item -> item {itemExample = \p -> (itemExample item) (f p)}
 
diff --git a/src/Test/Hspec/Core/QuickCheckUtil.hs b/src/Test/Hspec/Core/QuickCheckUtil.hs
--- a/src/Test/Hspec/Core/QuickCheckUtil.hs
+++ b/src/Test/Hspec/Core/QuickCheckUtil.hs
@@ -1,16 +1,19 @@
-{-# LANGUAGE CPP #-}
 module Test.Hspec.Core.QuickCheckUtil where
 
-import Data.IORef
-import Test.QuickCheck hiding (Result(..))
-import Test.QuickCheck as QC
-import Test.QuickCheck.Property hiding (Result(..))
+import           Control.Applicative
+import           Control.Exception
+import           Data.Int
+import           Data.IORef
+import           Test.QuickCheck hiding (Result(..))
+import           Test.QuickCheck as QC
+import           Test.QuickCheck.Property hiding (Result(..))
 import qualified Test.QuickCheck.Property as QCP
-import Test.QuickCheck.IO ()
-import Control.Applicative
+import           Test.QuickCheck.IO ()
+import           Test.QuickCheck.Random
+import           System.Random
 
 aroundProperty :: (IO () -> IO ()) -> Property -> Property
-aroundProperty action p = MkProp . aroundRose action . unProp <$> p
+aroundProperty action (MkProperty p) = MkProperty $ MkProp . aroundRose action . unProp <$> p
 
 aroundRose :: (IO () -> IO ()) -> Rose QCP.Result -> Rose QCP.Result
 aroundRose action r = ioRose $ do
@@ -20,9 +23,8 @@
 
 isUserInterrupt :: QC.Result -> Bool
 isUserInterrupt r = case r of
-#if MIN_VERSION_QuickCheck(2,6,0)
-  QC.Failure {QC.interrupted = x} -> x
-#else
-  QC.Failure {QC.reason = "Exception: 'user interrupt'"} -> True
-#endif
+  QC.Failure {theException = me} -> (me >>= fromException) == Just UserInterrupt
   _ -> False
+
+newSeed :: IO Int
+newSeed = fromIntegral <$> (fst . randomR (0, maxBound) <$> newQCGen :: IO Int32)
diff --git a/src/Test/Hspec/Core/Type.hs b/src/Test/Hspec/Core/Type.hs
--- a/src/Test/Hspec/Core/Type.hs
+++ b/src/Test/Hspec/Core/Type.hs
@@ -6,6 +6,7 @@
 , fromSpecList
 , SpecTree (..)
 , Item (..)
+, mapSpecItem
 , Example (..)
 , Result (..)
 , Params (..)
@@ -60,8 +61,8 @@
 forceResult :: Result -> Result
 forceResult r = case r of
   Success   -> r
-  Pending m -> r `seq` m `deepseq` r
-  Fail    m -> r `seq` m `deepseq` r
+  Pending m -> m `deepseq` r
+  Fail    m -> m `deepseq` r
 
 instance E.Exception Result
 
@@ -83,6 +84,14 @@
 , itemRequirement :: String
 , itemExample :: Params -> (IO () -> IO ()) -> IO Result
 }
+
+mapSpecItem :: (Item -> Item) -> Spec -> Spec
+mapSpecItem f = fromSpecList . map go . runSpecM
+  where
+    go :: SpecTree -> SpecTree
+    go spec = case spec of
+      SpecItem item -> SpecItem (f item)
+      SpecGroup d es -> SpecGroup d (map go es)
 
 -- | The @describe@ function combines a list of specs into a larger spec.
 describe :: String -> [SpecTree] -> SpecTree
diff --git a/src/Test/Hspec/Runner.hs b/src/Test/Hspec/Runner.hs
--- a/src/Test/Hspec/Runner.hs
+++ b/src/Test/Hspec/Runner.hs
@@ -29,16 +29,16 @@
 
 import           System.Console.ANSI (hHideCursor, hShowCursor)
 import qualified Test.QuickCheck as QC
-import           System.Random (newStdGen)
 import           Control.Monad.IO.Class (liftIO)
 
 import           Test.Hspec.Compat (lookupEnv)
-import           Test.Hspec.Util (Path, stdGenToInteger)
+import           Test.Hspec.Util (Path)
 import           Test.Hspec.Core.Type
 import           Test.Hspec.Config
 import           Test.Hspec.Formatters
 import           Test.Hspec.Formatters.Internal
 import           Test.Hspec.FailureReport
+import           Test.Hspec.Core.QuickCheckUtil
 
 import           Test.Hspec.Options (Options(..), ColorMode(..), defaultOptions)
 import           Test.Hspec.Runner.Eval
@@ -71,16 +71,14 @@
   f <- toFormatter formatter
   hspecWithOptions defaultOptions {optionsFormatter = f} spec
 
--- Add a StdGen to configQuickCheckArgs if there is none.  That way the same
--- seed is used for all properties.  This helps with --seed and --rerun.
-ensureStdGen :: Config -> IO Config
-ensureStdGen c = case QC.replay qcArgs of
+-- Add a seed to given config if there is none.  That way the same seed is used
+-- for all properties.  This helps with --seed and --rerun.
+ensureSeed :: Config -> IO Config
+ensureSeed c = case configQuickCheckSeed c of
   Nothing -> do
-    stdGen <- newStdGen
-    return c {configQuickCheckArgs = qcArgs {QC.replay = Just (stdGen, 0)}}
+    seed <- newSeed
+    return c {configQuickCheckSeed = Just (fromIntegral seed)}
   _       -> return c
-  where
-    qcArgs = configQuickCheckArgs c
 
 -- | Run given spec with custom options.
 -- This is similar to `hspec`, but more flexible.
@@ -107,10 +105,14 @@
 -- items.  If you need this, you have to check the `Summary` yourself and act
 -- accordingly.
 hspecWith :: Config -> Spec -> IO Summary
-hspecWith c_ spec = withHandle c_ $ \h -> do
-  c <- ensureStdGen c_
+hspecWith c_ spec_ = withHandle c_ $ \h -> do
+  c <- ensureSeed c_
   let formatter = configFormatter c
-      seed = (stdGenToInteger . fst . fromJust . QC.replay . configQuickCheckArgs) c
+      seed = (fromJust . configQuickCheckSeed) c
+      qcArgs = configQuickCheckArgs c
+      spec
+        | configDryRun c = mapSpecItem markSuccess spec_
+        | otherwise      = spec_
 
   useColor <- doesUseColor h c
 
@@ -125,9 +127,9 @@
       xs <- map failureRecordPath <$> getFailMessages
       liftIO $ writeFailureReport FailureReport {
           failureReportSeed = seed
-        , failureReportMaxSuccess = QC.maxSuccess (configQuickCheckArgs c)
-        , failureReportMaxSize = QC.maxSize (configQuickCheckArgs c)
-        , failureReportMaxDiscardRatio = QC.maxDiscardRatio (configQuickCheckArgs c)
+        , failureReportMaxSuccess = QC.maxSuccess qcArgs
+        , failureReportMaxSize = QC.maxSize qcArgs
+        , failureReportMaxDiscardRatio = QC.maxDiscardRatio qcArgs
         , failureReportPaths = xs
         }
 
@@ -151,6 +153,9 @@
 
 isDumb :: IO Bool
 isDumb = maybe False (== "dumb") <$> lookupEnv "TERM"
+
+markSuccess :: Item -> Item
+markSuccess item = item {itemExample = evaluateExample Success}
 
 -- | Summary of a test run.
 data Summary = Summary {
diff --git a/src/Test/Hspec/Runner/Eval.hs b/src/Test/Hspec/Runner/Eval.hs
--- a/src/Test/Hspec/Runner/Eval.hs
+++ b/src/Test/Hspec/Runner/Eval.hs
@@ -1,5 +1,7 @@
+{-# LANGUAGE DeriveFunctor #-}
 module Test.Hspec.Runner.Eval (runFormatter) where
 
+import           Control.Applicative
 import           Control.Monad
 import qualified Control.Exception as E
 import           Control.Concurrent
@@ -15,111 +17,137 @@
 import           Test.Hspec.Timer
 import           Data.Time.Clock.POSIX
 
+data Tree a
+  = Node String [Tree a]
+  | Leaf String a
+  deriving (Eq, Show, Functor)
+
+toTree :: SpecTree -> Tree Item
+toTree spec = case spec of
+  SpecGroup label specs -> Node label (map toTree specs)
+  SpecItem item -> Leaf (itemRequirement item) item
+
+type EvalTree = Tree (ProgressCallback -> FormatResult -> IO (FormatM ()))
+
 -- | Evaluate all examples of a given spec and produce a report.
 runFormatter :: Bool -> Handle -> Config -> Formatter -> [SpecTree] -> FormatM ()
-runFormatter useColor h c formatter specs = do
+runFormatter useColor h c formatter specs_ = do
   headerFormatter formatter
   chan <- liftIO newChan
-  run chan useColor h c formatter specs
+  reportProgress <- liftIO mkReportProgress
+  run chan reportProgress c formatter specs
+  where
+    mkReportProgress :: IO (Path -> Progress -> IO ())
+    mkReportProgress
+      | useColor = every 0.05 $ exampleProgress formatter h
+      | otherwise = return $ \_ _ -> return ()
 
-data Message = Done | Run (FormatM ())
+    specs = map (fmap (parallelize . fmap (applyNoOpAround . applyQuickCheckArgs) . unwrapItem) . toTree) specs_
 
+    unwrapItem :: Item -> (Bool, Params -> (IO () -> IO ()) -> IO Result)
+    unwrapItem (Item isParallelizable _ e) = (isParallelizable, e)
+
+    applyQuickCheckArgs :: (Params -> a) -> ProgressCallback -> a
+    applyQuickCheckArgs e progressCallback = e $ Params (configQuickCheckArgs c) (configSmallCheckDepth c) progressCallback
+
+    applyNoOpAround :: (a -> (IO () -> IO ()) -> b) -> a -> b
+    applyNoOpAround = fmap ($ id)
+
+-- | Execute given action at most every specified number of seconds.
+every :: POSIXTime -> (a -> b -> IO ()) -> IO (a -> b -> IO ())
+every seconds action = do
+  timer <- newTimer seconds
+  return $ \a b -> do
+    r <- timer
+    when r (action a b)
+
+type ProgressCallback = Progress -> IO ()
+type FormatResult = Either E.SomeException Result -> FormatM ()
+
+parallelize :: (Bool, ProgressCallback -> IO Result) -> ProgressCallback -> FormatResult -> IO (FormatM ())
+parallelize (isParallelizable, e)
+  | isParallelizable = runParallel e
+  | otherwise = runSequentially e
+
+runSequentially :: (ProgressCallback -> IO Result) -> ProgressCallback -> FormatResult -> IO (FormatM ())
+runSequentially e reportProgress formatResult = return $ do
+  result <- liftIO $ evalExample (e reportProgress)
+  formatResult result
+
 data Report = ReportProgress Progress | ReportResult (Either E.SomeException Result)
 
-run :: Chan Message -> Bool -> Handle -> Config -> Formatter -> [SpecTree] -> FormatM ()
-run chan useColor h c formatter specs = do
+runParallel :: (ProgressCallback -> IO Result) -> ProgressCallback -> FormatResult -> IO (FormatM ())
+runParallel e reportProgress formatResult = do
+  mvar <- newEmptyMVar
+  _ <- forkIO $ do
+    let progressCallback = replaceMVar mvar . ReportProgress
+    result <- evalExample (e progressCallback)
+    replaceMVar mvar (ReportResult result)
+  return $ evalReport mvar
+  where
+    evalReport :: MVar Report -> FormatM ()
+    evalReport mvar = do
+      r <- liftIO (takeMVar mvar)
+      case r of
+        ReportProgress p -> do
+          liftIO $ reportProgress p
+          evalReport mvar
+        ReportResult result -> formatResult result
+
+replaceMVar :: MVar a -> a -> IO ()
+replaceMVar mvar p = tryTakeMVar mvar >> putMVar mvar p
+
+evalExample :: IO Result -> IO (Either E.SomeException Result)
+evalExample e = safeTry $ forceResult <$> e
+
+data Message = Done | Run (FormatM ())
+
+run :: Chan Message -> (Path -> ProgressCallback) -> Config -> Formatter -> [EvalTree] -> FormatM ()
+run chan reportProgress_ c formatter specs = do
   liftIO $ do
     forM_ (zip [0..] specs) (queueSpec [])
     writeChan chan Done
-  processChan chan (configFastFail c)
+  processMessages (readChan chan) (configFastFail c)
   where
+    defer :: FormatM () -> IO ()
     defer = writeChan chan . Run
 
-    queueSpec :: [String] -> (Int, SpecTree) -> IO ()
-    queueSpec rGroups (n, SpecGroup group xs) = do
+    queueSpec :: [String] -> (Int, EvalTree) -> IO ()
+    queueSpec rGroups (n, Node group xs) = do
       defer (exampleGroupStarted formatter n (reverse rGroups) group)
       forM_ (zip [0..] xs) (queueSpec (group : rGroups))
       defer (exampleGroupDone formatter)
-    queueSpec rGroups (_, SpecItem (Item isParallelizable requirement e)) =
-      queueExample isParallelizable (reverse rGroups, requirement) (`e` id)
+    queueSpec rGroups (_, Leaf requirement e) =
+      queueExample (reverse rGroups, requirement) e
 
-    queueExample :: Bool -> Path -> (Params -> IO Result) -> IO ()
-    queueExample isParallelizable path e
-      | isParallelizable = runParallel
-      | otherwise = defer runSequentially
+    queueExample :: Path -> (ProgressCallback -> FormatResult -> IO (FormatM ())) -> IO ()
+    queueExample path e = e reportProgress formatResult >>= defer
       where
-        runSequentially :: FormatM ()
-        runSequentially = do
-          progressHandler <- liftIO (mkProgressHandler reportProgress)
-          result <- liftIO (evalExample e progressHandler)
-          formatResult formatter path result
+        reportProgress = reportProgress_ path
 
-        runParallel = do
-          mvar <- newEmptyMVar
-          _ <- forkIO $ do
-            progressHandler <- mkProgressHandler (replaceMVar mvar . ReportProgress)
-            result <- evalExample e progressHandler
-            replaceMVar mvar (ReportResult result)
-          defer (evalReport mvar)
+        formatResult :: Either E.SomeException Result -> FormatM ()
+        formatResult result = do
+          case result of
+            Right Success -> do
+              increaseSuccessCount
+              exampleSucceeded formatter path
+            Right (Pending reason) -> do
+              increasePendingCount
+              examplePending formatter path reason
+            Right (Fail err) -> failed (Right err)
+            Left err         -> failed (Left  err)
           where
-            evalReport :: MVar Report -> FormatM ()
-            evalReport mvar = do
-              r <- liftIO (takeMVar mvar)
-              case r of
-                ReportProgress p -> do
-                  liftIO $ reportProgress p
-                  evalReport mvar
-                ReportResult result -> formatResult formatter path result
-
-        reportProgress :: (Int, Int) -> IO ()
-        reportProgress = exampleProgress formatter h path
-
-    mkProgressHandler :: (a -> IO ()) -> IO (a -> IO ())
-    mkProgressHandler report
-      | useColor = every 0.05 report
-      | otherwise = return . const $ return ()
-
-    evalExample :: (Params -> IO Result) -> (Progress -> IO ()) -> IO (Either E.SomeException Result)
-    evalExample e progressHandler
-      | configDryRun c = return (Right Success)
-      | otherwise      = (safeTry . fmap forceResult) (e $ Params (configQuickCheckArgs c) (configSmallCheckDepth c) progressHandler)
-
-replaceMVar :: MVar a -> a -> IO ()
-replaceMVar mvar p = tryTakeMVar mvar >> putMVar mvar p
-
-processChan :: Chan Message -> Bool -> FormatM ()
-processChan chan fastFail = go
-  where
-    go = do
-      m <- liftIO (readChan chan)
-      case m of
-        Run action -> do
-          action
-          fails <- getFailCount
-          unless (fastFail && fails /= 0) go
-        Done -> return ()
+            failed err = do
+              increaseFailCount
+              addFailMessage path err
+              exampleFailed formatter path err
 
-formatResult :: Formatter -> ([String], String) -> Either E.SomeException Result -> FormatM ()
-formatResult formatter path result = do
-  case result of
-    Right Success -> do
-      increaseSuccessCount
-      exampleSucceeded formatter path
-    Right (Pending reason) -> do
-      increasePendingCount
-      examplePending formatter path reason
-    Right (Fail err) -> failed (Right err)
-    Left e           -> failed (Left  e)
+processMessages :: IO Message -> Bool -> FormatM ()
+processMessages getMessage fastFail = go
   where
-    failed err = do
-      increaseFailCount
-      addFailMessage path err
-      exampleFailed  formatter path err
-
--- | Execute given action at most every specified number of seconds.
-every :: POSIXTime -> (a -> IO ()) -> IO (a -> IO ())
-every seconds action = do
-  timer <- newTimer seconds
-  return $ \a -> do
-    r <- timer
-    when r (action a)
+    go = liftIO getMessage >>= \m -> case m of
+      Run action -> do
+        action
+        fails <- getFailCount
+        unless (fastFail && fails /= 0) go
+      Done -> return ()
diff --git a/src/Test/Hspec/Util.hs b/src/Test/Hspec/Util.hs
--- a/src/Test/Hspec/Util.hs
+++ b/src/Test/Hspec/Util.hs
@@ -6,16 +6,12 @@
 , filterPredicate
 , formatRequirement
 , strip
-, stdGenToInteger
-, stdGenFromInteger
 ) where
 
-import           Data.Int (Int32)
 import           Data.List
 import           Data.Char (isSpace)
 import           Control.Applicative
 import qualified Control.Exception as E
-import           System.Random (StdGen)
 
 -- | Create a more readable display of a quantity of something.
 --
@@ -90,17 +86,3 @@
 
 strip :: String -> String
 strip = dropWhile isSpace . reverse . dropWhile isSpace . reverse
-
--- | Converts a 'StdGen' into an 'Integer'. Assumes
---   StdGens to be encoded as two positive 'Int32's and
---   $show (StdGen a b) = show a ++ " " ++ show b$.
-stdGenToInteger :: StdGen -> Integer
-stdGenToInteger stdGen =
-  let [a, b] = map read . words $ show stdGen
-  in b * fromIntegral (maxBound :: Int32) + a
-
--- | Inverse of 'stdGenToInteger'.
-stdGenFromInteger :: Integer -> StdGen
-stdGenFromInteger n =
-  let (a, b) = quotRem n (fromIntegral (maxBound :: Int32))
-  in read (show b ++ " " ++ show a)
diff --git a/test/Helper.hs b/test/Helper.hs
--- a/test/Helper.hs
+++ b/test/Helper.hs
@@ -33,6 +33,7 @@
 
 import           Test.Hspec.Meta
 import           Test.QuickCheck hiding (Result(..))
+import           Test.QuickCheck.Random
 
 import qualified Test.Hspec as H
 import qualified Test.Hspec.Core as H (Params(..), Item(..), mapSpecItem)
@@ -63,7 +64,7 @@
         | otherwise  = x
 
 defaultParams :: H.Params
-defaultParams = H.Params (H.configQuickCheckArgs H.defaultConfig) (H.configSmallCheckDepth H.defaultConfig) (const $ return ())
+defaultParams = H.Params stdArgs {replay = Just (mkQCGen 23, 0)} (H.configSmallCheckDepth H.defaultConfig) (const $ return ())
 
 sleep :: POSIXTime -> IO ()
 sleep = threadDelay . floor . (* 1000000)
diff --git a/test/Test/Hspec/Core/TypeSpec.hs b/test/Test/Hspec/Core/TypeSpec.hs
--- a/test/Test/Hspec/Core/TypeSpec.hs
+++ b/test/Test/Hspec/Core/TypeSpec.hs
@@ -14,10 +14,10 @@
 main = hspec spec
 
 evaluateExample :: H.Example e => e -> IO H.Result
-evaluateExample e = H.evaluateExample e (defaultParams {H.paramsQuickCheckArgs = (H.paramsQuickCheckArgs defaultParams) {replay = Just (read "", 0)}}) id
+evaluateExample e = H.evaluateExample e defaultParams id
 
 evaluateExampleWith :: H.Example e => (IO () -> IO ()) -> e -> IO H.Result
-evaluateExampleWith action e = H.evaluateExample e (defaultParams {H.paramsQuickCheckArgs = (H.paramsQuickCheckArgs defaultParams) {replay = Just (read "", 0)}}) action
+evaluateExampleWith action e = H.evaluateExample e defaultParams action
 
 spec :: Spec
 spec = do
@@ -72,7 +72,7 @@
       it "shows what falsified it" $ do
         H.Fail r <- evaluateExample $ property $ \x y -> x + y == (x * y :: Int)
         r `shouldBe` intercalate "\n" [
-            "Falsifiable (after 1 test and 2 shrinks): "
+            "Falsifiable (after 2 tests and 2 shrinks): "
           , "0"
           , "1"
           ]
@@ -92,7 +92,7 @@
         it "shows what falsified it" $ do
           H.Fail r <- evaluateExample $ property $ \x y -> x + y `shouldBe` (x * y :: Int)
           r `shouldBe` intercalate "\n" [
-              "Falsifiable (after 1 test and 2 shrinks): "
+              "Falsifiable (after 2 tests and 2 shrinks): "
             , "expected: 0"
             , " but got: 1"
             , "0"
diff --git a/test/Test/Hspec/RunnerSpec.hs b/test/Test/Hspec/RunnerSpec.hs
--- a/test/Test/Hspec/RunnerSpec.hs
+++ b/test/Test/Hspec/RunnerSpec.hs
@@ -88,16 +88,14 @@
       it "reuses the same seed" $ do
         let runSpec_ = (captureLines . ignoreExitCode . H.hspec) $ do
               H.it "foo" $ property $ (/= (26 :: Integer))
-
-        r0 <- withArgs ["--seed", "2413421499272008081"] runSpec_
+        r0 <- withArgs ["--seed", "42"] runSpec_
         r0 `shouldContain` [
-            "Falsifiable (after 66 tests): "
+            "Falsifiable (after 31 tests): "
           , "26"
           ]
-
         r1 <- withArgs ["-r"] runSpec_
         r1 `shouldContain` [
-            "Falsifiable (after 66 tests): "
+            "Falsifiable (after 31 tests): "
           , "26"
           ]
 
@@ -294,11 +292,11 @@
 
     context "with --seed" $ do
       it "uses specified seed" $ do
-        r <- captureLines . ignoreExitCode . withArgs ["--seed", "2413421499272008081"] . H.hspec $ do
+        r <- captureLines . ignoreExitCode . withArgs ["--seed", "42"] . H.hspec $ do
             H.it "foo" $
               property (/= (26 :: Integer))
         r `shouldContain` [
-            "Falsifiable (after 66 tests): "
+            "Falsifiable (after 31 tests): "
           , "26"
           ]
 
@@ -308,13 +306,13 @@
                 H.it "foo" $
                   property $ \n -> ((17 + 31 * n) `mod` 50) /= (23 :: Integer)
           r0 <- runSpec ["--seed", "23"]
-          r0 `shouldContain` "(after 88 tests)"
+          r0 `shouldContain` "(after 27 tests)"
 
           r1 <- runSpec ["--seed", "42"]
-          r1 `shouldContain` "(after 48 tests)"
+          r1 `shouldContain` "(after 31 tests)"
 
           r2 <- runSpec ["--rerun", "--seed", "23"]
-          r2 `shouldContain` "(after 88 tests)"
+          r2 `shouldContain` "(after 27 tests)"
 
       context "when given an invalid argument" $ do
         let run = withArgs ["--seed", "foo"] . H.hspec $ do
diff --git a/test/Test/Hspec/UtilSpec.hs b/test/Test/Hspec/UtilSpec.hs
--- a/test/Test/Hspec/UtilSpec.hs
+++ b/test/Test/Hspec/UtilSpec.hs
@@ -1,9 +1,6 @@
-{-# OPTIONS_GHC -fno-warn-orphans #-}
 module Test.Hspec.UtilSpec (main, spec) where
 
 import           Helper
-import           Data.Int (Int32)
-import           System.Random (StdGen)
 import qualified Control.Exception as E
 
 import           Test.Hspec.Util
@@ -90,19 +87,3 @@
 
     it "properly handles context after a subject that consists of several components" $ do
       formatRequirement (["Data", "List", "reverse", "when applied twice"], "reverses a list") `shouldBe` "Data.List.reverse, when applied twice, reverses a list"
-
-  describe "stdGenToInteger" $ do
-    it "is inverse to stdGenFromInteger" $ property $
-      \(NonNegative i) -> (stdGenToInteger . stdGenFromInteger) i `shouldBe` i
-
-  describe "stdGenFromInteger" $ do
-    it "is inverse to stdGenToInteger" $ property $
-      \stdGen -> (stdGenFromInteger . stdGenToInteger) stdGen `shouldBe` stdGen
-
-instance Eq StdGen where
-  a == b = show a == show b
-
-instance Arbitrary StdGen where
-  arbitrary = do
-    (Positive a, Positive b) <- arbitrary
-    return $ read (show (a :: Int32) ++ " " ++ show (b :: Int32))
