diff --git a/hspec-expectations.cabal b/hspec-expectations.cabal
--- a/hspec-expectations.cabal
+++ b/hspec-expectations.cabal
@@ -1,5 +1,5 @@
 name:             hspec-expectations
-version:          0.4.0
+version:          0.5.0
 synopsis:         Catchy combinators for HUnit
 description:      Catchy combinators for HUnit: <https://github.com/sol/hspec-expectations#readme>
 license:          MIT
@@ -27,7 +27,6 @@
       src
   exposed-modules:
       Test.Hspec.Expectations
-    , Test.Hspec.Expectations.Lifted
     , Test.Hspec.Expectations.Contrib
 
 test-suite spec
diff --git a/src/Test/Hspec/Expectations.hs b/src/Test/Hspec/Expectations.hs
--- a/src/Test/Hspec/Expectations.hs
+++ b/src/Test/Hspec/Expectations.hs
@@ -8,6 +8,7 @@
 , shouldBe
 , shouldSatisfy
 , shouldContain
+, shouldMatchList
 , shouldReturn
 
 -- * Expecting exceptions
@@ -39,7 +40,7 @@
 import           Test.HUnit (Assertion, (@?=), assertBool, assertFailure)
 import           Control.Exception
 import           Data.Typeable
-import           Data.List (isInfixOf)
+import           Data.List ((\\), isInfixOf)
 
 type Expectation = Assertion
 
@@ -47,7 +48,7 @@
 expectationFailure :: String -> Expectation
 expectationFailure = assertFailure
 
-infix 1 `shouldBe`, `shouldSatisfy`, `shouldContain`, `shouldReturn`, `shouldThrow`
+infix 1 `shouldBe`, `shouldSatisfy`, `shouldContain`, `shouldMatchList`, `shouldReturn`, `shouldThrow`
 
 -- |
 -- @actual \`shouldBe\` expected@ sets the expectation that @actual@ is equal
@@ -67,6 +68,14 @@
 list `shouldContain` sublist = assertBool errorMsg (sublist `isInfixOf` list)
   where
     errorMsg = show list ++ " doesn't contain " ++ show sublist
+
+-- |
+-- @xs \`shouldMatchList\` ys@ sets the expectation that @xs@ has the same
+-- elements that @ys@ has, possibly in another order
+shouldMatchList :: (Show a, Eq a) => [a] -> [a] -> Expectation
+xs `shouldMatchList` ys = assertBool errorMsg (all null [xs \\ ys, ys \\ xs])
+  where
+    errorMsg = show ys ++ " is not a permutation of " ++ show xs
 
 -- |
 -- @action \`shouldReturn\` expected@ sets the expectation that @action@
diff --git a/src/Test/Hspec/Expectations/Lifted.hs b/src/Test/Hspec/Expectations/Lifted.hs
deleted file mode 100644
--- a/src/Test/Hspec/Expectations/Lifted.hs
+++ /dev/null
@@ -1,81 +0,0 @@
--- |
--- Introductory documentation: <https://github.com/sol/hspec-expectations#readme>
-module Test.Hspec.Expectations.Lifted (
-
--- * Setting expectations
-  Expectation
-, expectationFailure
-, shouldBe
-, shouldSatisfy
-, shouldContain
-, shouldReturn
-
--- * Expecting exceptions
-, shouldThrow
-
--- ** Selecting exceptions
-, Selector
-
--- ** Predefined type-based selectors
--- |
--- There are predefined selectors for some standard exceptions.  Each selector
--- is just @const True@ with an appropriate type.
-, anyException
-, anyErrorCall
-, anyIOException
-, anyArithException
-
--- ** Combinators for defining value-based selectors
--- |
--- Some exceptions (most prominently `ErrorCall`) have no `Eq` instance.
--- Selecting a specific value would require pattern matching.
---
--- For such exceptions, combinators that construct selectors are provided.
--- Each combinator corresponds to a constructor; it takes the same arguments,
--- and has the same name (but starting with a lower-case letter).
-, errorCall
-) where
-
-import           Control.Exception
-import           Control.Monad.IO.Class
-import           Test.Hspec.Expectations hiding (expectationFailure, shouldBe, shouldSatisfy, shouldContain, shouldReturn, shouldThrow)
-import qualified Test.Hspec.Expectations as E
-
-infix 1 `shouldBe`, `shouldSatisfy`, `shouldContain`, `shouldReturn`, `shouldThrow`
-
-liftIO2 :: MonadIO m => (a -> b -> IO r) -> a -> b -> m r
-liftIO2 action a = liftIO . action a
-
--- | This is just an alias for HUnit's `assertFailure`.
-expectationFailure :: MonadIO m => String -> m ()
-expectationFailure = liftIO . E.expectationFailure
-
--- |
--- @actual \`shouldBe\` expected@ sets the expectation that @actual@ is equal
--- to @expected@ (this is just an alias for `@?=`).
-shouldBe :: (Show a, Eq a, MonadIO m) => a -> a -> m ()
-shouldBe = liftIO2 E.shouldBe
-
--- |
--- @v \`shouldSatisfy\` p@ sets the expectation that @p v@ is @True@.
-shouldSatisfy :: (Show a, MonadIO m) => a -> (a -> Bool) -> m ()
-shouldSatisfy = liftIO2 E.shouldSatisfy
-
--- |
--- @list \`shouldContain\` sublist@ sets the expectation that @sublist@ is contained,
--- wholly and intact, anywhere in the second.
-shouldContain :: (Show a, Eq a, MonadIO m) => [a] -> [a] -> m ()
-shouldContain = liftIO2 E.shouldContain
-
--- |
--- @action \`shouldReturn\` expected@ sets the expectation that @action@
--- returns @expected@.
-shouldReturn :: (Show a, Eq a, MonadIO m) => IO a -> a -> m ()
-shouldReturn = liftIO2 E.shouldReturn
-
--- |
--- @action \`shouldThrow\` selector@ sets the expectation that @action@ throws
--- an exception.  The precise nature of the expected exception is described
--- with a 'Selector'.
-shouldThrow :: (Exception e, MonadIO m) => IO a -> Selector e -> m ()
-shouldThrow = liftIO2 E.shouldThrow
