diff --git a/LICENSE b/LICENSE
--- a/LICENSE
+++ b/LICENSE
@@ -1,4 +1,4 @@
-Copyright (c) 2012 Timothy Jones
+Copyright (c) 2012-2014 Timothy Jones
 
 Permission is hereby granted, free of charge, to any person obtaining a copy of
 this software and associated documentation files (the "Software"), to deal in
diff --git a/dist/build/test-http-mediaStub/test-http-mediaStub-tmp/test-http-mediaStub.hs b/dist/build/test-http-mediaStub/test-http-mediaStub-tmp/test-http-mediaStub.hs
--- a/dist/build/test-http-mediaStub/test-http-mediaStub-tmp/test-http-mediaStub.hs
+++ b/dist/build/test-http-mediaStub/test-http-mediaStub-tmp/test-http-mediaStub.hs
@@ -1,5 +1,5 @@
 module Main ( main ) where
-import Distribution.Simple.Test ( stubMain )
+import Distribution.Simple.Test.LibV09 ( stubMain )
 import Tests ( tests )
 main :: IO ()
 main = stubMain tests
diff --git a/http-media.cabal b/http-media.cabal
--- a/http-media.cabal
+++ b/http-media.cabal
@@ -1,13 +1,13 @@
 name:          http-media
-version:       0.1.1
+version:       0.2.0
 license:       MIT
 license-file:  LICENSE
 author:        Timothy Jones
-maintainer:    Timothy Jones <git@zimothy.com>
-homepage:      http://github.com/zimothy/http-media
-bug-reports:   http://github.com/zimothy/http-media/issues
+maintainer:    Timothy Jones <git@zmthy.io>
+homepage:      http://github.com/zmthy/http-media
+bug-reports:   http://github.com/zmthy/http-media/issues
 category:      Web
-copyright:     (c) 2013 Timothy Jones
+copyright:     (c) 2012-2014 Timothy Jones
 build-type:    Simple
 cabal-version: >= 1.10
 synopsis:      Processing HTTP Content-Type and Accept headers
@@ -18,7 +18,26 @@
   matching against the other accept headers as well. It encodes MIME parameters
   into a 'MediaType' data, and allows the matching of the final value by
   comparing quality values from the client.
+  .
+  In the following example, the Accept header is parsed, and then matched
+  against a list of server options to serve the appropriate media:
+  .
+  > getHeader >>= maybe send406Error sendResourceWith . mapAcceptMedia
+  >     [ ("text/html",        asHtml)
+  >     , ("application/json", asJson)
+  >     ]
+  .
+  Similarly, the Content-Type header can be used to produce a parser for request
+  bodies based on the given content type:
+  .
+  > getContentType >>= maybe send415Error readRequestBodyWith . mapContentMedia
+  >     [ ("application/json", parseJson)
+  >     , ("text/plain",       parseText)
+  >     ]
+  .
+  The API is agnostic to your choice of server.
 
+
 library
   hs-source-dirs: src
 
@@ -30,7 +49,7 @@
 
   exposed-modules:
     Network.HTTP.Media
-    Network.HTTP.Media.Match
+    Network.HTTP.Media.Accept
     Network.HTTP.Media.MediaType
   other-modules:
     Network.HTTP.Media.MediaType.Internal
@@ -53,9 +72,9 @@
   test-module: Tests
   other-modules:
     Network.HTTP.Media
+    Network.HTTP.Media.Accept
+    Network.HTTP.Media.Accept.Tests
     Network.HTTP.Media.Gen
-    Network.HTTP.Media.Match
-    Network.HTTP.Media.Match.Tests
     Network.HTTP.Media.MediaType
     Network.HTTP.Media.MediaType.Gen
     Network.HTTP.Media.MediaType.Internal
@@ -69,13 +88,13 @@
   build-depends:
     base                  >= 4.6.0  && < 5.0,
     bytestring            >= 0.10.0 && < 0.11,
-    Cabal                 >= 1.18.0 && < 1.19,
+    Cabal                 >= 1.18.0 && < 1.21,
     cabal-test-quickcheck >= 0.1.0  && < 0.2,
     containers            >= 0.5.0  && < 0.6,
-    QuickCheck            >= 2.6    && < 2.7,
+    QuickCheck            >= 2.6    && < 2.9,
     utf8-string           >= 0.3.7  && < 0.4
 
 source-repository head
   type:     git
-  location: git://github.com/zimothy/http-media.git
+  location: git://github.com/zmthy/http-media.git
 
diff --git a/src/Network/HTTP/Media.hs b/src/Network/HTTP/Media.hs
--- a/src/Network/HTTP/Media.hs
+++ b/src/Network/HTTP/Media.hs
@@ -11,81 +11,64 @@
     , parameters
     , (/?)
     , (/.)
-    , Quality
 
-    -- * Parsing
-    , parseAccept
-
     -- * Accept matching
     , matchAccept
     , mapAccept
+    , mapAcceptMedia
+    , mapAcceptBytes
 
     -- * Content matching
     , matchContent
     , mapContent
+    , mapContentMedia
 
-    -- * Match
-    , Match (..)
+    -- * Quality values
+    , Quality
+    , parseQuality
+    , matchQuality
+    , mapQuality
+
+    -- * Accept
+    , Accept (..)
     ) where
 
 ------------------------------------------------------------------------------
 import qualified Data.ByteString as BS
 
 ------------------------------------------------------------------------------
-import Control.Applicative  (pure, (<*>), (<|>))
-import Control.Monad        (guard)
+import Control.Applicative  (pure, (<$>), (<*>), (<|>))
+import Control.Monad        (guard, (>=>))
 import Data.ByteString      (ByteString, split)
 import Data.ByteString.UTF8 (toString)
 
 ------------------------------------------------------------------------------
-import Network.HTTP.Media.Match     as Match
+import Network.HTTP.Media.Accept    as Accept
 import Network.HTTP.Media.MediaType as MediaType
 import Network.HTTP.Media.Quality
 import Network.HTTP.Media.Utils
 
 
 ------------------------------------------------------------------------------
--- | Parses a full Accept header into a list of quality-valued media types.
-parseAccept :: ByteString -> Maybe [Quality MediaType]
-parseAccept = (. split comma) . mapM $ \bs ->
-        let (accept, q) = BS.breakSubstring ";q=" $ BS.filter (/= space) bs
-        in (<*> parse accept) $ if BS.null q
-            then pure maxQuality else fmap (flip Quality) $ readQ
-                (toString $ BS.takeWhile (/= semi) $ BS.drop 3 q)
-
-
-------------------------------------------------------------------------------
 -- | Matches a list of server-side resource options against a quality-marked
 -- list of client-side preferences. A result of 'Nothing' means that nothing
 -- matched (which should indicate a 406 error). If two or more results arise
 -- with the same quality level and specificity, then the first one in the
 -- server list is chosen.
 --
--- The use of the 'Match' type class allows the application of either
+-- The use of the 'Accept' type class allows the application of either
 -- 'MediaType' for the standard Accept header or 'ByteString' for any other
--- Accept header which can be marked with a quality value. The standard
--- application of this function for 'MediaType' should be in conjunction with
--- 'parseAccepts'.
+-- Accept header which can be marked with a quality value.
 --
--- > parseAccepts header >>= matchQuality resourceTypeOptions
+-- > matchAccept ["text/html", "application/json"] <$> getHeader
 --
--- For more information on the matching process see RFC 2616, section 14.
+-- For more information on the matching process see RFC 2616, section 14.1-4.
 matchAccept
-    :: Match a
-    => [a]          -- ^ The server-side options
-    -> [Quality a]  -- ^ The client-side preferences
+    :: Accept a
+    => [a]         -- ^ The server-side options
+    -> ByteString  -- ^ The client-side header value
     -> Maybe a
-matchAccept server clientq = guard (hq /= 0) >> specific qs
-  where
-    merge (Quality c q) = map (`Quality` q) $ filter (`matches` c) server
-    matched = concatMap merge clientq
-    (hq, qs) = foldr qfold (0, []) matched
-    qfold (Quality v q) (mq, vs) = case compare q mq of
-        GT -> (q, [v])
-        EQ -> (mq, v : vs)
-        LT -> (mq, vs)
-    specific (a : ms) = Just $ foldl mostSpecific a ms
-    specific []       = Nothing
+matchAccept = (parseQuality >=>) . matchQuality
 
 
 ------------------------------------------------------------------------------
@@ -93,50 +76,167 @@
 -- mapped to another value. Convenient for specifying how to translate the
 -- resource into each of its available formats.
 --
--- > maybe render406Error renderResource $ parseAccepts header >>= mapQuality
+-- > getHeader >>= maybe render406Error renderResource . mapAccept
+-- >     [ ("text" // "html",        asHtml)
+-- >     , ("application" // "json", asJson)
+-- >     ]
+mapAccept
+    :: Accept a
+    => [(a, b)]    -- ^ The map of server-side preferences to values
+    -> ByteString  -- ^ The client-side header value
+    -> Maybe b
+mapAccept = (parseQuality >=>) . mapQuality
+
+
+------------------------------------------------------------------------------
+-- | A specialisation of 'mapAccept' that only takes MediaType as its input,
+-- to avoid ambiguous-type errors when using string literal overloading.
+--
+-- > getHeader >>= maybe render406Error renderResource . mapAcceptMedia
 -- >     [ ("text/html",        asHtml)
 -- >     , ("application/json", asJson)
 -- >     ]
-mapAccept
-    :: Match a
-    => [(a, b)]     -- ^ The map of server-side preferences to values
-    -> [Quality a]  -- ^ The client-side preferences
+mapAcceptMedia ::
+    [(MediaType, b)]  -- ^ The map of server-side preferences to values
+    -> ByteString     -- ^ The client-side header value
     -> Maybe b
-mapAccept s c = matchAccept (map fst s) c >>= lookupMatches s
+mapAcceptMedia = mapAccept
 
 
 ------------------------------------------------------------------------------
+-- | A specialisation of 'mapAccept' that only takes ByteString as its input,
+-- to avoid ambiguous-type errors when using string literal overloading.
+--
+-- > getHeader >>= maybe render406Error encodeResourceWith . mapAcceptBytes
+-- >     [ ("compress", compress)
+-- >     , ("gzip",     gzip)
+-- >     ]
+mapAcceptBytes ::
+    [(ByteString, b)]  -- ^ The map of server-side preferences to values
+    -> ByteString      -- ^ The client-side header value
+    -> Maybe b
+mapAcceptBytes = mapAccept
+
+
+------------------------------------------------------------------------------
 -- | Matches a list of server-side parsing options against a the client-side
 -- content value. A result of 'Nothing' means that nothing matched (which
 -- should indicate a 415 error).
 --
--- As with the Accept parsing, he use of the 'Match' type class allows the
--- application of either 'MediaType' or 'ByteString'.
+-- > matchContent ["application/json", "text/plain"] <$> getContentType
+--
+-- For more information on the matching process see RFC 2616, section 14.17.
 matchContent
-    :: Match a
-    => a         -- ^ The client's request value
-    -> [a]       -- ^ The server-side response options
+    :: Accept a
+    => [a]         -- ^ The server-side response options
+    -> ByteString  -- ^ The client's request value
     -> Maybe a
-matchContent client = foldl choose Nothing
-  where choose m server = m <|> (guard (matches client server) >> Just server)
+matchContent options ctype = foldl choose Nothing options
+  where
+    choose m server = m <|> do
+        parseAccept ctype >>= guard . (`matches` server)
+        Just server
 
 
 ------------------------------------------------------------------------------
 -- | The equivalent of 'matchContent' above, except the resulting choice is
 -- mapped to another value.
+--
+-- > getContentType >>= maybe send415Error readRequestBodyWith . mapContent
+-- >     [ ("application" // "json", parseJson)
+-- >     , ("text" // "plain",       parseText)
+-- >     ]
 mapContent
-    :: Match a
-    => a         -- ^ The client request's header value
-    -> [(a, b)]  -- ^ The map of server-side responses
+    :: Accept a
+    => [(a, b)]    -- ^ The map of server-side responses
+    -> ByteString  -- ^ The client request's header value
     -> Maybe b
-mapContent c s = matchContent c (map fst s) >>= lookupMatches s
+mapContent options ctype =
+    matchContent (map fst options) ctype >>= lookupMatches options
 
 
 ------------------------------------------------------------------------------
+-- | A specialisation of 'mapContent' that only takes MediaType as its input,
+-- to avoid ambiguous-type errors when using string literal overloading.
+--
+-- > getContentType >>=
+-- >     maybe send415Error readRequestBodyWith . mapContentMedia
+-- >         [ ("application/json", parseJson)
+-- >         , ("text/plain",       parseText)
+-- >         ]
+mapContentMedia
+    :: [(MediaType, b)]  -- ^ The map of server-side responses
+    -> ByteString        -- ^ The client request's header value
+    -> Maybe b
+mapContentMedia = mapContent
+
+
+------------------------------------------------------------------------------
+-- | Parses a full Accept header into a list of quality-valued media types.
+parseQuality :: Accept a => ByteString -> Maybe [Quality a]
+parseQuality = (. split comma) . mapM $ \bs ->
+    let (accept, q) = BS.breakSubstring ";q=" $ BS.filter (/= space) bs
+    in (<*> parseAccept accept) $ if BS.null q
+        then pure maxQuality else flip Quality <$> readQ
+            (toString $ BS.takeWhile (/= semi) $ BS.drop 3 q)
+
+
+------------------------------------------------------------------------------
+-- | Matches a list of server-side resource options against a pre-parsed
+-- quality-marked list of client-side preferences. A result of 'Nothing' means
+-- that nothing matched (which should indicate a 406 error). If two or more
+-- results arise with the same quality level and specificity, then the first
+-- one in the server list is chosen.
+--
+-- The use of the 'Accept' type class allows the application of either
+-- 'MediaType' for the standard Accept header or 'ByteString' for any other
+-- Accept header which can be marked with a quality value.
+--
+-- > matchQuality ["text/html", "application/json"] <$> parseQuality header
+--
+-- For more information on the matching process see RFC 2616, section 14.1-4.
+matchQuality
+    :: Accept a
+    => [a]          -- ^ The server-side options
+    -> [Quality a]  -- ^ The pre-parsed client-side header value
+    -> Maybe a
+matchQuality options acceptq = do
+    let merge (Quality c q) = map (`Quality` q) $ filter (`matches` c) options
+        matched = concatMap merge acceptq
+        (hq, qs) = foldr qfold (0, []) matched
+        qfold (Quality v q) (mq, vs) = case compare q mq of
+            GT -> (q, [v])
+            EQ -> (mq, v : vs)
+            LT -> (mq, vs)
+        specific (a : ms) = Just $ foldl mostSpecific a ms
+        specific []       = Nothing
+    guard (hq /= 0)
+    specific qs
+
+
+------------------------------------------------------------------------------
+-- | The equivalent of 'matchQuality' above, except the resulting choice is
+-- mapped to another value. Convenient for specifying how to translate the
+-- resource into each of its available formats.
+--
+-- > parseQuality header >>= maybe render406Error renderResource . mapQuality
+-- >     [ ("text" // "html",        asHtml)
+-- >     , ("application" // "json", asJson)
+-- >     ]
+mapQuality
+    :: Accept a
+    => [(a, b)]     -- ^ The map of server-side preferences to values
+    -> [Quality a]  -- ^ The client-side header value
+    -> Maybe b
+mapQuality options accept =
+    matchQuality (map fst options) accept >>= lookupMatches options
+
+
+------------------------------------------------------------------------------
 -- | The equivalent of 'lookupBy matches'.
-lookupMatches :: Match a => [(a, b)] -> a -> Maybe b
+lookupMatches :: Accept a => [(a, b)] -> a -> Maybe b
 lookupMatches ((k, v) : r) a
-    | Match.matches k a = Just v
+    | Accept.matches k a = Just v
     | otherwise         = lookupMatches r a
 lookupMatches [] _ = Nothing
 
diff --git a/src/Network/HTTP/Media/Accept.hs b/src/Network/HTTP/Media/Accept.hs
new file mode 100644
--- /dev/null
+++ b/src/Network/HTTP/Media/Accept.hs
@@ -0,0 +1,54 @@
+------------------------------------------------------------------------------
+-- | Defines the 'Accept' type class, designed to unify types on the matching
+-- functions in the Media module.
+module Network.HTTP.Media.Accept
+    ( Accept (..)
+    , mostSpecific
+    ) where
+
+------------------------------------------------------------------------------
+import Data.ByteString
+import Data.ByteString.UTF8 (toString)
+
+
+------------------------------------------------------------------------------
+-- | Defines methods for a type whose values can be matched against each
+-- other in terms of an HTTP Accept-* header.
+--
+-- This allows functions to work on both the standard Accept header and
+-- others such as Accept-Language that still may use quality values.
+class Show a => Accept a where
+
+    -- | Specifies how to parse an Accept-* header after quality has been
+    -- handled.
+    parseAccept :: ByteString -> Maybe a
+
+    -- | Specifies how to show an Accept-* header. Defaults to the standard
+    -- show method.
+    --
+    -- Mostly useful just for avoiding quotes when rendering 'ByteString's
+    -- with accompanying quality.
+    showAccept :: a -> String
+    showAccept = show
+
+    -- | Evaluates whether either the left argument matches the right one
+    -- (order may be important).
+    matches :: a -> a -> Bool
+
+    -- | Evaluates whether the left argument is more specific than the right.
+    moreSpecificThan :: a -> a -> Bool
+
+instance Accept ByteString where
+    parseAccept = Just
+    showAccept = toString
+    matches = (==)
+    moreSpecificThan _ _ = False
+
+
+------------------------------------------------------------------------------
+-- | Evaluates to whichever argument is more specific. Left biased.
+mostSpecific :: Accept a => a -> a -> a
+mostSpecific a b
+    | b `moreSpecificThan` a = b
+    | otherwise              = a
+
diff --git a/src/Network/HTTP/Media/Match.hs b/src/Network/HTTP/Media/Match.hs
deleted file mode 100644
--- a/src/Network/HTTP/Media/Match.hs
+++ /dev/null
@@ -1,39 +0,0 @@
-------------------------------------------------------------------------------
--- | Defines the 'Match' type class, designed to unify types on the
--- matching functions in the Media module.
-module Network.HTTP.Media.Match
-    ( Match (..)
-    , mostSpecific
-    ) where
-
-------------------------------------------------------------------------------
-import Data.ByteString
-
-
-------------------------------------------------------------------------------
--- | Defines methods for a type whose values can be matched against each
--- other in terms of a HTTP media header.
---
--- This allows functions to work on both the standard Accept header and
--- others such as Accept-Language that still may use quality values.
-class Match a where
-
-    -- | Evaluates whether either the left argument matches the right one
-    -- (order may be important).
-    matches :: a -> a -> Bool
-
-    -- | Evaluates whether the left argument is more specific than the right.
-    moreSpecificThan :: a -> a -> Bool
-
-instance Match ByteString where
-    matches = (==)
-    moreSpecificThan _ _ = False
-
-
-------------------------------------------------------------------------------
--- | Evaluates to whichever argument is more specific. Left biased.
-mostSpecific :: Match a => a -> a -> a
-mostSpecific a b
-    | b `moreSpecificThan` a = b
-    | otherwise              = a
-
diff --git a/src/Network/HTTP/Media/MediaType.hs b/src/Network/HTTP/Media/MediaType.hs
--- a/src/Network/HTTP/Media/MediaType.hs
+++ b/src/Network/HTTP/Media/MediaType.hs
@@ -7,7 +7,6 @@
     , Parameters
     , (//)
     , (/:)
-    , parse
     , toByteString
 
     -- * Querying
diff --git a/src/Network/HTTP/Media/MediaType/Internal.hs b/src/Network/HTTP/Media/MediaType/Internal.hs
--- a/src/Network/HTTP/Media/MediaType/Internal.hs
+++ b/src/Network/HTTP/Media/MediaType/Internal.hs
@@ -4,7 +4,6 @@
     ( MediaType (..)
     , Parameters
     , toByteString
-    , parse
     ) where
 
 ------------------------------------------------------------------------------
@@ -22,7 +21,7 @@
 import Data.Monoid          ((<>))
 
 ------------------------------------------------------------------------------
-import Network.HTTP.Media.Match (Match (..))
+import Network.HTTP.Media.Accept (Accept (..))
 import Network.HTTP.Media.Utils
 
 
@@ -41,10 +40,19 @@
         f k v = (++ ';' : toString k ++ '=' : toString v)
 
 instance IsString MediaType where
-    fromString str = flip fromMaybe (parse $ BS.fromString str) $
+    fromString str = flip fromMaybe (parseAccept $ BS.fromString str) $
         error $ "Invalid media type literal " ++ str
 
-instance Match MediaType where
+instance Accept MediaType where
+    parseAccept bs = do
+        let pieces = BS.split semi bs
+        guard $ not (null pieces)
+        let (m : ps) = pieces
+            (a, b)   = breakByte slash m
+        guard $ BS.elem slash m && (a /= "*" || b == "*")
+        return $ MediaType a b $
+            foldr (uncurry Map.insert . breakByte equal) Map.empty ps
+
     matches a b
         | mainType b == "*" = params
         | subType b == "*"  = mainType a == mainType b && params
@@ -67,19 +75,6 @@
 ------------------------------------------------------------------------------
 -- | 'MediaType' parameters.
 type Parameters = Map ByteString ByteString
-
-
-------------------------------------------------------------------------------
--- | Parses a media type header into a 'MediaType'.
-parse :: ByteString -> Maybe MediaType
-parse bs = do
-    let pieces = BS.split semi bs
-    guard $ not (null pieces)
-    let (m : ps) = pieces
-        (a, b)   = breakByte slash m
-    guard $ BS.elem slash m && (a /= "*" || b == "*")
-    return $ MediaType a b $
-        foldr (uncurry Map.insert . breakByte equal) Map.empty ps
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Network/HTTP/Media/Quality.hs b/src/Network/HTTP/Media/Quality.hs
--- a/src/Network/HTTP/Media/Quality.hs
+++ b/src/Network/HTTP/Media/Quality.hs
@@ -11,6 +11,8 @@
 import Data.Maybe (listToMaybe)
 import Data.Word  (Word16)
 
+------------------------------------------------------------------------------
+import Network.HTTP.Media.Accept
 
 ------------------------------------------------------------------------------
 -- | Attaches a quality value to data.
@@ -19,8 +21,8 @@
     , qualityValue :: Word16
     } deriving (Eq)
 
-instance Show a => Show (Quality a) where
-    show (Quality a q) = show a ++ ";q=" ++ showQ q
+instance Accept a => Show (Quality a) where
+    show (Quality a q) = showAccept a ++ ";q=" ++ showQ q
 
 
 ------------------------------------------------------------------------------
diff --git a/test/Network/HTTP/Media/Accept/Tests.hs b/test/Network/HTTP/Media/Accept/Tests.hs
new file mode 100644
--- /dev/null
+++ b/test/Network/HTTP/Media/Accept/Tests.hs
@@ -0,0 +1,48 @@
+------------------------------------------------------------------------------
+module Network.HTTP.Media.Accept.Tests (tests) where
+
+------------------------------------------------------------------------------
+import Control.Monad                     (join, liftM, liftM2)
+import Distribution.TestSuite.QuickCheck
+
+------------------------------------------------------------------------------
+import Network.HTTP.Media.Accept
+import Network.HTTP.Media.Gen
+
+
+------------------------------------------------------------------------------
+tests :: [Test]
+tests =
+    [ testMatches
+    , testMoreSpecificThan
+    , testMostSpecific
+    ]
+
+
+------------------------------------------------------------------------------
+testMatches :: Test
+testMatches = testGroup "matches"
+    [ testProperty "Does match" $ do
+        string <- genByteString
+        return $ matches string string
+    , testProperty "Doesn't match" $ do
+        string  <- genByteString
+        string' <- genDiffByteString string
+        return . not $ matches string string'
+    ]
+
+
+------------------------------------------------------------------------------
+-- | Note that this test never actually generates any strings, as they are not
+-- required for the 'moreSpecificThan' test.
+testMoreSpecificThan :: Test
+testMoreSpecificThan = testProperty "moreSpecificThan" $
+    join (liftM2 ((not .) . moreSpecificThan)) genByteString
+
+
+------------------------------------------------------------------------------
+testMostSpecific :: Test
+testMostSpecific = testProperty "mostSpecific" $ do
+    string <- genByteString
+    liftM ((== string) . mostSpecific string) genByteString
+
diff --git a/test/Network/HTTP/Media/Gen.hs b/test/Network/HTTP/Media/Gen.hs
--- a/test/Network/HTTP/Media/Gen.hs
+++ b/test/Network/HTTP/Media/Gen.hs
@@ -26,4 +26,3 @@
     bs' <- genByteString
     if bs == bs' then genDiffByteString bs else return bs'
 
-
diff --git a/test/Network/HTTP/Media/Match/Tests.hs b/test/Network/HTTP/Media/Match/Tests.hs
deleted file mode 100644
--- a/test/Network/HTTP/Media/Match/Tests.hs
+++ /dev/null
@@ -1,48 +0,0 @@
-------------------------------------------------------------------------------
-module Network.HTTP.Media.Match.Tests (tests) where
-
-------------------------------------------------------------------------------
-import Control.Monad                     (join, liftM, liftM2)
-import Distribution.TestSuite.QuickCheck
-
-------------------------------------------------------------------------------
-import Network.HTTP.Media.Gen
-import Network.HTTP.Media.Match
-
-
-------------------------------------------------------------------------------
-tests :: [Test]
-tests =
-    [ testMatches
-    , testMoreSpecificThan
-    , testMostSpecific
-    ]
-
-
-------------------------------------------------------------------------------
-testMatches :: Test
-testMatches = testGroup "matches"
-    [ testProperty "Does match" $ do
-        string <- genByteString
-        return $ matches string string
-    , testProperty "Doesn't match" $ do
-        string  <- genByteString
-        string' <- genDiffByteString string
-        return . not $ matches string string'
-    ]
-
-
-------------------------------------------------------------------------------
--- | Note that this test never actually generates any strings, as they are not
--- required for the 'moreSpecificThan' test.
-testMoreSpecificThan :: Test
-testMoreSpecificThan = testProperty "moreSpecificThan" $
-    join (liftM2 ((not .) . moreSpecificThan)) genByteString
-
-
-------------------------------------------------------------------------------
-testMostSpecific :: Test
-testMostSpecific = testProperty "mostSpecific" $ do
-    string <- genByteString
-    liftM ((== string) . mostSpecific string) genByteString
-
diff --git a/test/Network/HTTP/Media/MediaType/Tests.hs b/test/Network/HTTP/Media/MediaType/Tests.hs
--- a/test/Network/HTTP/Media/MediaType/Tests.hs
+++ b/test/Network/HTTP/Media/MediaType/Tests.hs
@@ -13,7 +13,7 @@
 import Distribution.TestSuite.QuickCheck
 
 ------------------------------------------------------------------------------
-import Network.HTTP.Media.Match
+import Network.HTTP.Media.Accept
 import Network.HTTP.Media.MediaType          ((/?), (/.))
 import Network.HTTP.Media.MediaType.Internal
 import Network.HTTP.Media.MediaType.Gen
@@ -30,7 +30,7 @@
     , testMatches
     , testMoreSpecificThan
     , testMostSpecific
-    , testParse
+    , testParseAccept
     ]
 
 
@@ -52,7 +52,7 @@
 testShow :: Test
 testShow = testProperty "show" $ do
     media <- genMediaType
-    return $ parse (BS.fromString $ show media) == Just media
+    return $ parseAccept (BS.fromString $ show media) == Just media
 
 
 ------------------------------------------------------------------------------
@@ -186,13 +186,13 @@
 
 
 ------------------------------------------------------------------------------
-testParse :: Test
-testParse = testProperty "parse" $ do
+testParseAccept :: Test
+testParseAccept = testProperty "parseAccept" $ do
     media <- genMediaType
     let main   = mainType media
         sub    = subType media
         params = parameters media
-    let (Just parsed) = parse $ main <> "/" <> sub <> mconcat
+    let (Just parsed) = parseAccept $ main <> "/" <> sub <> mconcat
             (map (uncurry ((<>) . (<> "=") . (";" <>))) $ Map.toList params)
     return $ parsed == media
 
diff --git a/test/Network/HTTP/Media/Tests.hs b/test/Network/HTTP/Media/Tests.hs
--- a/test/Network/HTTP/Media/Tests.hs
+++ b/test/Network/HTTP/Media/Tests.hs
@@ -3,10 +3,11 @@
 
 ------------------------------------------------------------------------------
 import Control.Monad                     (replicateM)
+import Data.ByteString                   (ByteString)
 import Data.ByteString.UTF8              (fromString)
 import Data.List                         (intercalate)
 import Data.Map                          (empty)
-import Data.Maybe                        (isNothing)
+import Data.Maybe                        (isNothing, listToMaybe)
 import Data.Word                         (Word16)
 import Distribution.TestSuite.QuickCheck
 import Test.QuickCheck
@@ -22,21 +23,25 @@
 tests :: [Test]
 tests =
     [ testParse
-    , testMatch
-    , testMap
+    , testMatchAccept
+    , testMapAccept
+    , testMatchContent
+    , testMapContent
+    , testMatchQuality
+    , testMapQuality
     ]
 
 
 ------------------------------------------------------------------------------
 testParse :: Test
-testParse = testGroup "parseAccept"
+testParse = testGroup "parseQuality"
     [ testProperty "Without quality" $ do
         media <- medias
         return $
-            parseAccept (group media) == Just (map maxQuality media)
+            parseQuality (group media) == Just (map maxQuality media)
     , testProperty "With quality" $ do
         media <- medias >>= mapM (flip fmap (choose (0, 1000)) . Quality)
-        return $ parseAccept (group media) == Just media
+        return $ parseQuality (group media) == Just media
     ]
   where
     medias = listOf1 genMediaType
@@ -44,66 +49,160 @@
 
 
 ------------------------------------------------------------------------------
-testMatch :: Test
-testMatch = testGroup "match"
+testMatchAccept :: Test
+testMatchAccept = testMatch "Accept" matchAccept qToBS
+
+
+------------------------------------------------------------------------------
+testMapAccept :: Test
+testMapAccept = testMap "Accept" mapAccept qToBS
+
+
+------------------------------------------------------------------------------
+testMatchContent :: Test
+testMatchContent = testGroup "matchContent"
+    [ testProperty "Most specific" $ do
+        media <- genConcreteMediaType
+        let client = toBS
+                [ MediaType "*" "*" empty
+                , media { subType = "*" }
+                , media { parameters = empty }
+                , media
+                ]
+        return $ matchAccept [media] client == Just media
+    , testProperty "Nothing" $ do
+        (server, client) <- genServerAndClient
+        let client' = filter (not . flip any server . matches) client
+        return . isNothing $ matchAccept server (toBS client')
+    , testProperty "Left biased" $ do
+        server <- genServer
+        return $ matchAccept server (toBS server) == Just (head server)
+    , testProperty "Against */*" $ do
+        server <- genServer
+        let stars = "*/*" :: ByteString
+        return $ matchAccept server (toBS [stars]) == Just (head server)
+    , testProperty "Against type/*" $ do
+        server <- genServer
+        let client = toBS [subStarOf $ head server]
+        return $ matchAccept server client == Just (head server)
+    ]
+
+
+------------------------------------------------------------------------------
+testMapContent :: Test
+testMapContent = testGroup "mapContent"
+    [ testProperty "Matches" $ do
+        server <- genServer
+        let zipped = zip server server
+        return $ mapAccept zipped (toBS server) == listToMaybe server
+    , testProperty "Nothing" $ do
+        server <- genServer
+        client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server
+        let zipped = zip server $ repeat ()
+        return . isNothing $ mapAccept zipped (toBS client)
+    ]
+
+
+------------------------------------------------------------------------------
+testMatchQuality :: Test
+testMatchQuality = testMatch "Quality" matchQuality id
+
+
+------------------------------------------------------------------------------
+testMapQuality :: Test
+testMapQuality = testMap "Quality" mapQuality id
+
+
+------------------------------------------------------------------------------
+testMatch
+    :: String
+    -> ([MediaType] -> a -> Maybe MediaType)
+    -> ([Quality MediaType] -> a)
+    -> Test
+testMatch name match qToI = testGroup ("match" ++ name)
     [ testProperty "Highest quality" $ do
         server <- genServer
         qs     <- replicateM (length server) $ choose (1, 1000)
         let client = zipWith Quality server qs
             qmax v q = if qualityValue q > qualityValue v then q else v
-        return $ matchAccept server client ==
+        return $ match server (qToI client) ==
             Just (qualityData $ foldr1 qmax client)
     , testProperty "Most specific" $ do
         media <- genConcreteMediaType
-        let client = map maxQuality
+        let client = qToI $ map maxQuality
                 [ MediaType "*" "*" empty
                 , media { subType = "*" }
                 , media { parameters = empty }
                 , media
                 ]
-        return $ matchAccept [media] client == Just media
+        return $ match [media] client == Just media
     , testProperty "Nothing" $ do
         server <- genServer
         client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server
         let client' = filter (not . flip any server . matches) client
-        return . isNothing $ matchAccept server (map maxQuality client')
+        return . isNothing $ match server
+            (qToI $ map maxQuality client')
     , testProperty "Never chooses q=0" $ do
         server <- genServer
-        return . isNothing $ matchAccept server (map minQuality server)
+        return . isNothing $
+            match server (qToI $ map minQuality server)
     , testProperty "Left biased" $ do
         server <- genServer
-        let client = map maxQuality server
-        return $ matchAccept server client == Just (head server)
+        let client = qToI $ map maxQuality server
+        return $ match server client == Just (head server)
     , testProperty "Against */*" $ do
         server <- genServer
-        return $ matchAccept server [maxQuality "*/*"] == Just (head server)
+        let stars = "*/*" :: MediaType
+        return $ match server (qToI [maxQuality stars]) ==
+            Just (head server)
     , testProperty "Against type/*" $ do
         server <- genServer
-        let client = [maxQuality (subStarOf $ head server)]
-        return $ matchAccept server client == Just (head server)
+        let client = qToI [maxQuality (subStarOf $ head server)]
+        return $ match server client == Just (head server)
     ]
 
 
 ------------------------------------------------------------------------------
-testMap :: Test
-testMap = testGroup "map"
+testMap
+    :: String
+    -> ([(MediaType, MediaType)] -> a -> Maybe MediaType)
+    -> ([Quality MediaType] -> a)
+    -> Test
+testMap name mapf qToI = testGroup ("map" ++ name)
     [ testProperty "Matches" $ do
         server <- genServer
         qs     <- replicateM (length server) $ choose (1, 1000 :: Word16)
         let client = zipWith Quality server qs
             qmax q v = if qualityValue q >= qualityValue v then q else v
             zipped = zip server server
-        return $ mapAccept zipped client ==
+        return $ mapf zipped (qToI client) ==
             Just (qualityData $ foldr1 qmax client)
     , testProperty "Nothing" $ do
-        server <- genServer
-        client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server
-        let zipped = zip server $ repeat ()
-        return . isNothing $ mapAccept zipped (map maxQuality client)
+        (server, client) <- genServerAndClient
+        let zipped = zip server $ repeat "*/*"
+        return . isNothing $ mapf zipped (qToI $ map maxQuality client)
     ]
 
 
 ------------------------------------------------------------------------------
 genServer :: Gen [MediaType]
 genServer = listOf1 genConcreteMediaType
+
+
+------------------------------------------------------------------------------
+genServerAndClient :: Gen ([MediaType], [MediaType])
+genServerAndClient = do
+    server <- genServer
+    client <- listOf1 $ genDiffMediaTypesWith genConcreteMediaType server
+    return (server, client)
+
+
+------------------------------------------------------------------------------
+toBS :: Accept a => [a] -> ByteString
+toBS = fromString . intercalate "," . map showAccept
+
+
+------------------------------------------------------------------------------
+qToBS :: Accept a => [Quality a] -> ByteString
+qToBS = fromString . intercalate "," . map show
 
diff --git a/test/Tests.hs b/test/Tests.hs
--- a/test/Tests.hs
+++ b/test/Tests.hs
@@ -6,7 +6,7 @@
 
 ------------------------------------------------------------------------------
 import qualified Network.HTTP.Media.Tests           as Media
-import qualified Network.HTTP.Media.Match.Tests     as Match
+import qualified Network.HTTP.Media.Accept.Tests    as Accept
 import qualified Network.HTTP.Media.MediaType.Tests as MediaType
 
 
@@ -14,7 +14,7 @@
 tests :: IO [Test]
 tests = return
     [ testGroup "MediaType" MediaType.tests
-    , testGroup "Match"     Match.tests
+    , testGroup "Accept"    Accept.tests
     , testGroup "Media"     Media.tests
     ]
 
