diff --git a/hspec2.cabal b/hspec2.cabal
--- a/hspec2.cabal
+++ b/hspec2.cabal
@@ -1,5 +1,5 @@
 name:             hspec2
-version:          0.3.0
+version:          0.3.1
 license:          MIT
 license-file:     LICENSE
 copyright:        (c) 2011-2014 Simon Hengel,
@@ -50,7 +50,6 @@
     , quickcheck-io
     , hspec-expectations == 0.5.0.*
     , async >= 2
-    , io-memoize
   exposed-modules:
       Test.Hspec
       Test.Hspec.Core
@@ -60,6 +59,7 @@
       Test.Hspec.QuickCheck
   other-modules:
       Test.Hspec.Util
+      Test.Hspec.Memoize
       Test.Hspec.Compat
       Test.Hspec.Core.Type
       Test.Hspec.Core.QuickCheckUtil
@@ -110,7 +110,6 @@
     , quickcheck-io
     , hspec-expectations
     , async
-    , io-memoize
 
     , hspec-meta >= 1.9.1
     , process
diff --git a/src/Test/Hspec.hs b/src/Test/Hspec.hs
--- a/src/Test/Hspec.hs
+++ b/src/Test/Hspec.hs
@@ -27,6 +27,7 @@
 , before
 , beforeWith
 , beforeAll
+, beforeAllWith
 , after
 , after_
 , around
@@ -38,6 +39,7 @@
 , hspec
 ) where
 
+import           Control.Applicative
 import           Control.Exception (finally)
 
 import           Test.Hspec.Core.Type hiding (describe, it)
@@ -45,7 +47,7 @@
 import           Test.Hspec.HUnit ()
 import           Test.Hspec.Expectations
 import qualified Test.Hspec.Core as Core
-import           System.IO.Memoize
+import           Test.Hspec.Memoize
 
 -- | Combine a list of specs into a larger spec.
 describe :: String -> SpecWith a -> SpecWith a
@@ -98,11 +100,19 @@
 
 -- | Run a custom action before all spec items.
 beforeAll :: IO a -> SpecWith a -> SpecWith ()
-beforeAll action = fromSpecList . return . BuildSpecs . go .  runSpecM
+beforeAll action = fromSpecList . return . BuildSpecs . go
   where
-    go xs = do
+    go spec = do
       action_ <- ioMemo action
-      return . runSpecM $ before action_ (fromSpecList xs)
+      return . runSpecM $ before action_ spec
+
+-- | Run a custom action before all spec items.
+beforeAllWith :: (b -> IO a) -> SpecWith a -> SpecWith b
+beforeAllWith action = fromSpecList . return . BuildSpecs . go
+  where
+    go spec = do
+      action_ <- (. action) <$> newIOMemoizer
+      return . runSpecM $ aroundWith (\e x -> action_ x >>= e) spec
 
 -- | Run a custom action after every spec item.
 after :: ActionWith a -> SpecWith a -> SpecWith a
diff --git a/src/Test/Hspec/Memoize.hs b/src/Test/Hspec/Memoize.hs
new file mode 100644
--- /dev/null
+++ b/src/Test/Hspec/Memoize.hs
@@ -0,0 +1,84 @@
+-- Taken from:
+--
+-- * https://github.com/DanBurton/io-memoize/
+-- * http://hackage.haskell.org/package/io-memoize
+--
+-- Copyright (c) 2012, Dan Burton
+--
+-- All rights reserved.
+--
+-- Redistribution and use in source and binary forms, with or without
+-- modification, are permitted provided that the following conditions are met:
+--
+--     * Redistributions of source code must retain the above copyright
+--       notice, this list of conditions and the following disclaimer.
+--
+--     * Redistributions in binary form must reproduce the above
+--       copyright notice, this list of conditions and the following
+--       disclaimer in the documentation and/or other materials provided
+--       with the distribution.
+--
+--     * Neither the name of Dan Burton nor the names of other
+--       contributors may be used to endorse or promote products derived
+--       from this software without specific prior written permission.
+--
+-- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+-- "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+-- LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+-- A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+-- OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+-- SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+-- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+-- DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+-- THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+-- OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+module Test.Hspec.Memoize (ioMemo, newIOMemoizer) where
+
+import Control.Concurrent.MVar
+import Data.IORef
+
+-- | Memoize an IO action.
+-- The action will be performed
+-- the first time that it its value is demanded;
+-- all subsequent invocations
+-- will simply recall the value acquired
+-- from the first call.
+-- If the value is never demanded,
+-- then the action will never be performed.
+--
+-- This is basically a safe version of
+-- 'System.IO.Unsafe.unsafeInterleaveIO'.
+-- This function is also thread-safe:
+-- it is guaranteed that the action passed in
+-- will be performed exactly 0 or 1 times
+-- by this code. Exceptions will be propagated
+-- to the caller.
+--
+-- Example usage:
+--
+-- >>> getLine' <- ioMemo getLine
+--
+-- >>> replicateM 3 getLine'
+-- Hello
+-- ["Hello", "Hello", "Hello"]
+ioMemo :: IO a -> IO (IO a)
+ioMemo action = do
+  memo <- newIOMemoizer
+  return (memo action)
+
+newIOMemoizer :: IO (IO a -> IO a)
+newIOMemoizer = do
+  b <- newMVar True
+  r <- newIORef undefined
+  return (ioMemoizer b r)
+
+ioMemoizer :: MVar Bool -> IORef a -> IO a -> IO a
+ioMemoizer b r action = do
+  modifyMVar_ b $ \isEmpty ->
+    if isEmpty
+      then do v <- action
+              writeIORef r v
+              return False
+      else return False
+  readIORef r
