diff --git a/Web/Twitter/Conduit.hs b/Web/Twitter/Conduit.hs
--- a/Web/Twitter/Conduit.hs
+++ b/Web/Twitter/Conduit.hs
@@ -17,15 +17,16 @@
        -- $howto
 
        -- * Re-exports
-         module Web.Twitter.Conduit.Base
-       , module Web.Twitter.Conduit.Api
-       , module Web.Twitter.Conduit.Status
+         module Web.Twitter.Conduit.Api
+       , module Web.Twitter.Conduit.Base
+       , module Web.Twitter.Conduit.Cursor
        , module Web.Twitter.Conduit.Monad
-       , module Web.Twitter.Conduit.Stream
-       , module Web.Twitter.Conduit.Request
        , module Web.Twitter.Conduit.Parameters
+       , module Web.Twitter.Conduit.Request
+       , module Web.Twitter.Conduit.Response
+       , module Web.Twitter.Conduit.Status
+       , module Web.Twitter.Conduit.Stream
 
-       , MediaData (..)
 #if !MIN_VERSION_twitter_types(0,5,0)
        , UploadedMedia
        , mediaId
@@ -38,14 +39,15 @@
 #endif
        ) where
 
-import Web.Twitter.Conduit.Types
-import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Api
-import Web.Twitter.Conduit.Status
+import Web.Twitter.Conduit.Base
+import Web.Twitter.Conduit.Cursor
 import Web.Twitter.Conduit.Monad
-import Web.Twitter.Conduit.Stream
-import Web.Twitter.Conduit.Request
 import Web.Twitter.Conduit.Parameters
+import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Response
+import Web.Twitter.Conduit.Status
+import Web.Twitter.Conduit.Stream
 
 -- for haddock
 import Web.Authenticate.OAuth
@@ -72,6 +74,7 @@
 -- > {-# LANGUAGE OverloadedStrings #-}
 -- >
 -- > import Web.Twitter.Conduit
+-- > import Web.Twitter.Types
 -- > import Web.Authenticate.OAuth
 -- > import Data.Conduit
 -- > import qualified Data.Conduit.List as CL
diff --git a/Web/Twitter/Conduit/Api.hs b/Web/Twitter/Conduit/Api.hs
--- a/Web/Twitter/Conduit/Api.hs
+++ b/Web/Twitter/Conduit/Api.hs
@@ -2,11 +2,7 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 704
-{-# LANGUAGE ConstraintKinds #-}
-#endif
 
 module Web.Twitter.Conduit.Api
        (
@@ -95,25 +91,36 @@
 
        -- * Lists
        -- , listsList
-       -- , listsStatuses
-       -- , listsMembersDestroy
-       -- , listsMemberships
-       -- , listsSubscribers
+       , ListsStatuses
+       , listsStatuses
+       , ListsMembersDestroy
+       , listsMembersDestroy
+       , ListsMemberships
+       , listsMemberships
+       , ListsSubscribers
+       , listsSubscribers
        -- , listsSubscribersCreate
        -- , listsSubscribersShow
        -- , listsSubscribersDestroy
-       -- , listsSubscribersCreateAll
+       -- , listsMembersCreateAll
        -- , listsMembersShow
        , ListsMembers
        , listsMembers
-       -- , listsMembersCreate
-       -- , listsDestroy
-       -- , listsUpdate
-       -- , listsCreate
-       -- , listsShow
-       -- , listsSubscriptions
+       , ListsMembersCreate
+       , listsMembersCreate
+       , ListsDestroy
+       , listsDestroy
+       , ListsUpdate
+       , listsUpdate
+       , ListsCreate
+       , listsCreate
+       , ListsShow
+       , listsShow
+       , ListsSubscriptions
+       , listsSubscriptions
        -- , listsMembersDestroyAll
-       -- , listsOwnerships
+       , ListsOwnerships
+       , listsOwnerships
 
        -- * Saved Searches
        -- savedSearchesList
@@ -134,15 +141,14 @@
        ) where
 
 import Web.Twitter.Types
-import Web.Twitter.Conduit.Types
 import Web.Twitter.Conduit.Parameters
 import Web.Twitter.Conduit.Parameters.TH
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Cursor
 
 import Network.HTTP.Client.MultipartFormData
 import qualified Data.Text as T
-import qualified Data.Text.Encoding as T
 import Data.Default
 
 -- $setup
@@ -165,7 +171,7 @@
 -- APIRequestGet "https://api.twitter.com/1.1/search/tweets.json" [("count","100"),("lang","ja"),("q","search text")]
 searchTweets :: T.Text -- ^ search string
              -> APIRequest SearchTweets (SearchResult [SearchStatus])
-searchTweets q = APIRequestGet (endpoint ++ "search/tweets.json") [("q", T.encodeUtf8 q)]
+searchTweets q = APIRequestGet (endpoint ++ "search/tweets.json") [("q", PVString q)]
 deriveHasParamInstances ''SearchTweets
     [ "lang"
     , "locale"
@@ -242,7 +248,7 @@
 -- >>> directMessagesShow 1234567890
 -- APIRequestGet "https://api.twitter.com/1.1/direct_messages/show.json" [("id","1234567890")]
 directMessagesShow :: StatusId -> APIRequest DirectMessagesShow DirectMessage
-directMessagesShow sId = APIRequestGet (endpoint ++ "direct_messages/show.json") [("id", showBS sId)]
+directMessagesShow sId = APIRequestGet (endpoint ++ "direct_messages/show.json") [("id", PVInteger sId)]
 
 data DirectMessagesDestroy
 -- | Returns post data which destroys the direct message specified in the required ID parameter.
@@ -256,7 +262,7 @@
 -- >>> directMessagesDestroy 1234567890
 -- APIRequestPost "https://api.twitter.com/1.1/direct_messages/destroy.json" [("id","1234567890")]
 directMessagesDestroy :: StatusId -> APIRequest DirectMessagesDestroy DirectMessage
-directMessagesDestroy sId = APIRequestPost (endpoint ++ "direct_messages/destroy.json") [("id", showBS sId)]
+directMessagesDestroy sId = APIRequestPost (endpoint ++ "direct_messages/destroy.json") [("id", PVInteger sId)]
 deriveHasParamInstances ''DirectMessagesDestroy
     [ "include_entities"
     ]
@@ -275,7 +281,7 @@
 -- >>> directMessagesNew (UserIdParam 69179963) "Hello thimura! by UserId"
 -- APIRequestPost "https://api.twitter.com/1.1/direct_messages/new.json" [("text","Hello thimura! by UserId"),("user_id","69179963")]
 directMessagesNew :: UserParam -> T.Text -> APIRequest DirectMessagesNew DirectMessage
-directMessagesNew q msg = APIRequestPost (endpoint ++ "direct_messages/new.json") (("text", T.encodeUtf8 msg):mkUserParam q)
+directMessagesNew q msg = APIRequestPost (endpoint ++ "direct_messages/new.json") (("text", PVString msg):mkUserParam q)
 
 data FriendshipsNoRetweetsIds
 -- | Returns a collection of user_ids that the currently authenticated user does not want to receive retweets from.
@@ -575,7 +581,7 @@
 -- >>> favoritesCreate 1234567890
 -- APIRequestPost "https://api.twitter.com/1.1/favorites/create.json" [("id","1234567890")]
 favoritesCreate :: StatusId -> APIRequest FavoritesCreate Status
-favoritesCreate sid = APIRequestPost (endpoint ++ "favorites/create.json") [("id", showBS sid)]
+favoritesCreate sid = APIRequestPost (endpoint ++ "favorites/create.json") [("id", PVInteger sid)]
 deriveHasParamInstances ''FavoritesCreate
     [ "include_entities"
     ]
@@ -592,11 +598,143 @@
 -- >>> favoritesDestroy 1234567890
 -- APIRequestPost "https://api.twitter.com/1.1/favorites/destroy.json" [("id","1234567890")]
 favoritesDestroy :: StatusId -> APIRequest FavoritesDestroy Status
-favoritesDestroy sid = APIRequestPost (endpoint ++ "favorites/destroy.json") [("id", showBS sid)]
+favoritesDestroy sid = APIRequestPost (endpoint ++ "favorites/destroy.json") [("id", PVInteger sid)]
 deriveHasParamInstances ''FavoritesDestroy
     [ "include_entities"
     ]
 
+data ListsStatuses
+-- | Returns the query parameter which fetches a timeline of tweets authored by members of the specified list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsStatuses' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- If you need more statuses, you can obtain those by using 'sourceWithMaxId':
+-- @
+-- res <- sourceWithMaxId ('listsStatuses' ('ListNameParam' "thimura/haskell") & count ?~ 200) $$ CL.take 1000
+-- @
+--
+-- >>> listsStatuses (ListNameParam "thimura/haskell")
+-- APIRequestGet "https://api.twitter.com/1.1/lists/statuses.json" [("slug","haskell"),("owner_screen_name","thimura")]
+-- >>> listsStatuses (ListIdParam 20849097)
+-- APIRequestGet "https://api.twitter.com/1.1/lists/statuses.json" [("list_id","20849097")]
+listsStatuses :: ListParam -> APIRequest ListsStatuses [Status]
+listsStatuses q = APIRequestGet (endpoint ++ "lists/statuses.json") (mkListParam q)
+deriveHasParamInstances ''ListsStatuses
+    [ "since_id"
+    , "max_id"
+    , "count"
+    , "include_entities"
+    , "include_rts"
+    ]
+
+data ListsMembersDestroy
+-- | Returns the post parameter which removes the specified member from the list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsMembersDestroy' ('ListNameParam' "thimura/haskell") ('ScreenNameParam' "thimura")
+-- @
+--
+-- >>> listsMembersDestroy (ListNameParam "thimura/haskell") (ScreenNameParam "thimura")
+-- APIRequestPost "https://api.twitter.com/1.1/lists/members/destroy.json" [("slug","haskell"),("owner_screen_name","thimura"),("screen_name","thimura")]
+-- >>> listsMembersDestroy (ListIdParam 20849097) (UserIdParam 69179963)
+-- APIRequestPost "https://api.twitter.com/1.1/lists/members/destroy.json" [("list_id","20849097"),("user_id","69179963")]
+listsMembersDestroy :: ListParam -> UserParam -> APIRequest ListsMembersDestroy List
+listsMembersDestroy list user = APIRequestPost (endpoint ++ "lists/members/destroy.json") (mkListParam list ++ mkUserParam user)
+
+data ListsMemberships
+-- | Returns the request parameters which asks the lists the specified user has been added to.
+-- If 'UserParam' are not provided, the memberships for the authenticating user are returned.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsMemberships' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsMemberships Nothing
+-- APIRequestGet "https://api.twitter.com/1.1/lists/memberships.json" []
+-- >>> listsMemberships (Just (ScreenNameParam "thimura"))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/memberships.json" [("screen_name","thimura")]
+-- >>> listsMemberships (Just (UserIdParam 69179963))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/memberships.json" [("user_id","69179963")]
+listsMemberships :: Maybe UserParam -> APIRequest ListsMemberships (WithCursor ListsCursorKey List)
+listsMemberships q = APIRequestGet (endpoint ++ "lists/memberships.json") $ maybe [] mkUserParam q
+deriveHasParamInstances ''ListsMemberships
+    [ "cursor"
+    , "count"
+    ]
+
+data ListsSubscribers
+-- | Returns the request parameter which asks the subscribers of the specified list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsSubscribers' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsSubscribers (ListNameParam "thimura/haskell")
+-- APIRequestGet "https://api.twitter.com/1.1/lists/subscribers.json" [("slug","haskell"),("owner_screen_name","thimura")]
+-- >>> listsSubscribers (ListIdParam 20849097)
+-- APIRequestGet "https://api.twitter.com/1.1/lists/subscribers.json" [("list_id","20849097")]
+listsSubscribers :: ListParam -> APIRequest ListsSubscribers (WithCursor UsersCursorKey User)
+listsSubscribers q = APIRequestGet (endpoint ++ "lists/subscribers.json") (mkListParam q)
+deriveHasParamInstances ''ListsSubscribers
+    [ "cursor"
+    , "count"
+    , "skip_status"
+    ]
+
+data ListsSubscriptions
+-- | Returns the request parameter which obtains a collection of the lists the specified user is subscribed to.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsSubscriptions' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsSubscriptions Nothing
+-- APIRequestGet "https://api.twitter.com/1.1/lists/subscriptions.json" []
+-- >>> listsSubscriptions (Just (ScreenNameParam "thimura"))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/subscriptions.json" [("screen_name","thimura")]
+-- >>> listsSubscriptions (Just (UserIdParam 69179963))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/subscriptions.json" [("user_id","69179963")]
+listsSubscriptions :: Maybe UserParam -> APIRequest ListsSubscriptions (WithCursor ListsCursorKey List)
+listsSubscriptions q = APIRequestGet (endpoint ++ "lists/subscriptions.json") $ maybe [] mkUserParam q
+deriveHasParamInstances ''ListsSubscriptions
+    [ "cursor"
+    , "count"
+    ]
+
+data ListsOwnerships
+-- | Returns the request parameter which asks the lists owned by the specified Twitter user.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsOwnerships' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsOwnerships Nothing
+-- APIRequestGet "https://api.twitter.com/1.1/lists/ownerships.json" []
+-- >>> listsOwnerships (Just (ScreenNameParam "thimura"))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/ownerships.json" [("screen_name","thimura")]
+-- >>> listsOwnerships (Just (UserIdParam 69179963))
+-- APIRequestGet "https://api.twitter.com/1.1/lists/ownerships.json" [("user_id","69179963")]
+listsOwnerships :: Maybe UserParam -> APIRequest ListsOwnerships (WithCursor ListsCursorKey List)
+listsOwnerships q = APIRequestGet (endpoint ++ "lists/ownerships.json") $ maybe [] mkUserParam q
+deriveHasParamInstances ''ListsOwnerships
+    [ "cursor"
+    , "count"
+    ]
+
 data ListsMembers
 -- | Returns query data asks the members of the specified list.
 --
@@ -616,6 +754,102 @@
     [ "cursor"
     , "skip_status"
     ]
+
+data ListsMembersCreate
+-- | Returns the post parameter which adds a member to a list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsMembersCreate' ('ListNameParam' "thimura/haskell") ('ScreenNameParam' "thimura")
+-- @
+--
+-- >>> listsMembersCreate (ListNameParam "thimura/haskell") (ScreenNameParam "thimura")
+-- APIRequestPost "https://api.twitter.com/1.1/lists/members/create.json" [("slug","haskell"),("owner_screen_name","thimura"),("screen_name","thimura")]
+-- >>> listsMembersCreate (ListIdParam 20849097) (UserIdParam 69179963)
+-- APIRequestPost "https://api.twitter.com/1.1/lists/members/create.json" [("list_id","20849097"),("user_id","69179963")]
+listsMembersCreate :: ListParam -> UserParam -> APIRequest ListsMembersCreate List
+listsMembersCreate list user = APIRequestPost (endpoint ++ "lists/members/create.json") (mkListParam list ++ mkUserParam user)
+
+data ListsDestroy
+-- | Returns the post parameter which deletes the specified list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsDestroy' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsDestroy (ListNameParam "thimura/haskell")
+-- APIRequestPost "https://api.twitter.com/1.1/lists/destroy.json" [("slug","haskell"),("owner_screen_name","thimura")]
+-- >>> listsDestroy (ListIdParam 20849097)
+-- APIRequestPost "https://api.twitter.com/1.1/lists/destroy.json" [("list_id","20849097")]
+listsDestroy :: ListParam -> APIRequest ListsDestroy List
+listsDestroy list = APIRequestPost (endpoint ++ "lists/destroy.json") (mkListParam list)
+
+data ListsUpdate
+-- | Returns the post parameter which updates the specified list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsUpdate' ('ListNameParam' "thimura/haskell") True (Just "Haskellers")
+-- @
+--
+-- >>> listsUpdate (ListNameParam "thimura/haskell") True (Just "Haskellers")
+-- APIRequestPost "https://api.twitter.com/1.1/lists/update.json" [("slug","haskell"),("owner_screen_name","thimura"),("description","Haskellers"),("mode","public")]
+listsUpdate :: ListParam
+            -> Bool -- ^ is public
+            -> Maybe T.Text -- ^ description
+            -> APIRequest ListsUpdate List
+listsUpdate list isPublic description = APIRequestPost (endpoint ++ "lists/update.json") (mkListParam list ++ p')
+  where
+    p = [("mode", PVString . mode $ isPublic)]
+    p' = maybe id (\d -> (("description", PVString d):)) description p
+    mode True = "public"
+    mode False = "private"
+
+data ListsCreate
+-- | Returns the post parameter which creates a new list for the authenticated user.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsCreate' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsCreate "haskell" True Nothing
+-- APIRequestPost "https://api.twitter.com/1.1/lists/create.json" [("name","haskell"),("mode","public")]
+-- >>> listsCreate "haskell" False Nothing
+-- APIRequestPost "https://api.twitter.com/1.1/lists/create.json" [("name","haskell"),("mode","private")]
+-- >>> listsCreate "haskell" True (Just "Haskellers")
+-- APIRequestPost "https://api.twitter.com/1.1/lists/create.json" [("description","Haskellers"),("name","haskell"),("mode","public")]
+listsCreate :: T.Text -- ^ list name
+            -> Bool -- ^ whether public(True) or private(False)
+            -> Maybe T.Text -- ^ the description to give the list
+            -> APIRequest ListsCreate List
+listsCreate name isPublic description = APIRequestPost (endpoint ++ "lists/create.json") p'
+  where
+    p = [("name", PVString name), ("mode", PVString . mode $ isPublic)]
+    p' = maybe id (\d -> (("description", PVString d):)) description p
+    mode True = "public"
+    mode False = "private"
+
+data ListsShow
+-- | Returns the request parameter which asks the specified list.
+--
+-- You can perform request by using 'call':
+--
+-- @
+-- res <- 'call' '$' 'listsShow' ('ListNameParam' "thimura/haskell")
+-- @
+--
+-- >>> listsShow (ListNameParam "thimura/haskell")
+-- APIRequestGet "https://api.twitter.com/1.1/lists/show.json" [("slug","haskell"),("owner_screen_name","thimura")]
+-- >>> listsShow (ListIdParam 20849097)
+-- APIRequestGet "https://api.twitter.com/1.1/lists/show.json" [("list_id","20849097")]
+listsShow :: ListParam -> APIRequest ListsShow List
+listsShow q = APIRequestGet (endpoint ++ "lists/show.json") (mkListParam q)
 
 data MediaUpload
 -- | Upload media and returns the media data.
diff --git a/Web/Twitter/Conduit/Base.hs b/Web/Twitter/Conduit/Base.hs
--- a/Web/Twitter/Conduit/Base.hs
+++ b/Web/Twitter/Conduit/Base.hs
@@ -1,8 +1,6 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
 {-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE ConstraintKinds #-}
 {-# LANGUAGE RecordWildCards #-}
 
@@ -25,9 +23,10 @@
        ) where
 
 import Web.Twitter.Conduit.Monad
-import Web.Twitter.Conduit.Types
 import Web.Twitter.Conduit.Parameters
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Response
+import Web.Twitter.Conduit.Cursor
 import Web.Twitter.Types.Lens
 
 import qualified Network.HTTP.Conduit as HTTP
@@ -57,13 +56,13 @@
 makeRequest :: (MonadThrow m, MonadIO m)
             => APIRequest apiName responseType
             -> m HTTP.Request
-makeRequest (APIRequestGet u pa) = makeRequest' "GET" u pa
-makeRequest (APIRequestPost u pa) = makeRequest' "POST" u pa
+makeRequest (APIRequestGet u pa) = makeRequest' "GET" u (makeSimpleQuery pa)
+makeRequest (APIRequestPost u pa) = makeRequest' "POST" u (makeSimpleQuery pa)
 makeRequest (APIRequestPostMultipart u param prt) =
     formDataBody body =<< makeRequest' "POST" u []
   where
     body = prt ++ partParam
-    partParam = Prelude.map (uncurry partBS . over _1 T.decodeUtf8) param
+    partParam = Prelude.map (uncurry partBS . over _1 T.decodeUtf8) (makeSimpleQuery param)
 
 makeRequest' :: MonadThrow m
              => HT.Method -- ^ HTTP request method (GET or POST)
diff --git a/Web/Twitter/Conduit/Cursor.hs b/Web/Twitter/Conduit/Cursor.hs
new file mode 100644
--- /dev/null
+++ b/Web/Twitter/Conduit/Cursor.hs
@@ -0,0 +1,70 @@
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE EmptyDataDecls #-}
+{-# LANGUAGE ScopedTypeVariables #-}
+{-# LANGUAGE CPP #-}
+
+module Web.Twitter.Conduit.Cursor
+       ( CursorKey (..)
+       , IdsCursorKey
+       , UsersCursorKey
+       , ListsCursorKey
+       , WithCursor (..)
+       ) where
+
+import Control.Applicative
+import Data.Aeson
+import Data.Monoid
+import Data.Text (Text)
+import Web.Twitter.Types (checkError)
+
+-- $setup
+-- >>> type UserId = Integer
+
+class CursorKey a where
+    cursorKey :: a -> Text
+
+-- | Phantom type to specify the key which point out the content in the response.
+data IdsCursorKey
+instance CursorKey IdsCursorKey where
+    cursorKey = const "ids"
+
+-- | Phantom type to specify the key which point out the content in the response.
+data UsersCursorKey
+instance CursorKey UsersCursorKey where
+    cursorKey = const "users"
+
+-- | Phantom type to specify the key which point out the content in the response.
+data ListsCursorKey
+instance CursorKey ListsCursorKey where
+    cursorKey = const "lists"
+
+#if __GLASGOW_HASKELL__ >= 706
+-- | A wrapper for API responses which have "next_cursor" field.
+--
+-- The first type parameter of 'WithCursor' specifies the field name of contents.
+--
+-- >>> let Just res = decode "{\"previous_cursor\": 0, \"next_cursor\": 1234567890, \"ids\": [1111111111]}" :: Maybe (WithCursor IdsCursorKey UserId)
+-- >>> nextCursor res
+-- 1234567890
+-- >>> contents res
+-- [1111111111]
+--
+-- >>> let Just res = decode "{\"previous_cursor\": 0, \"next_cursor\": 0, \"users\": [1000]}" :: Maybe (WithCursor UsersCursorKey UserId)
+-- >>> nextCursor res
+-- 0
+-- >>> contents res
+-- [1000]
+#endif
+data WithCursor cursorKey wrapped = WithCursor
+    { previousCursor :: Integer
+    , nextCursor :: Integer
+    , contents :: [wrapped]
+    } deriving Show
+
+instance (FromJSON wrapped, CursorKey c) =>
+         FromJSON (WithCursor c wrapped) where
+    parseJSON (Object o) = checkError o >>
+      WithCursor <$> o .:  "previous_cursor"
+                 <*> o .:  "next_cursor"
+                 <*> o .:  cursorKey (undefined :: c)
+    parseJSON _ = mempty
diff --git a/Web/Twitter/Conduit/Lens.hs b/Web/Twitter/Conduit/Lens.hs
new file mode 100644
--- /dev/null
+++ b/Web/Twitter/Conduit/Lens.hs
@@ -0,0 +1,62 @@
+{-# LANGUAGE RankNTypes #-}
+
+module Web.Twitter.Conduit.Lens
+       (
+       -- * 'TT.Response'
+         TT.Response
+       , responseStatus
+       , responseBody
+       , responseHeaders
+       -- * 'TT.TwitterErrorMessage'
+       , TT.TwitterErrorMessage
+       , twitterErrorMessage
+       , twitterErrorCode
+
+       -- * 'TT.WithCursor'
+       , TT.WithCursor
+       , previousCursor
+       , nextCursor
+       , contents
+
+       -- * Re-exports
+       , TT.TwitterError(..)
+       , TT.CursorKey (..)
+       , TT.IdsCursorKey
+       , TT.UsersCursorKey
+       , TT.ListsCursorKey
+       ) where
+
+import Control.Applicative
+import Control.Lens
+import Data.Text (Text)
+import Network.HTTP.Types (Status, ResponseHeaders)
+import qualified Web.Twitter.Conduit.Cursor as TT
+import qualified Web.Twitter.Conduit.Response as TT
+
+-- * Lenses for 'TT.Response'
+responseStatus :: forall responseType. Lens' (TT.Response responseType) Status
+responseStatus afb s = (\b -> s { TT.responseStatus = b }) <$> afb (TT.responseStatus s)
+
+responseHeaders :: forall responseType. Lens' (TT.Response responseType) ResponseHeaders
+responseHeaders afb s = (\b -> s {TT.responseHeaders = b }) <$> afb (TT.responseHeaders s)
+
+responseBody :: forall a b. Lens (TT.Response a) (TT.Response b) a b
+responseBody afb s = (\b -> s { TT.responseBody = b }) <$> afb (TT.responseBody s)
+
+-- * Lenses for 'TT.TwitterErrorMessage'
+
+twitterErrorCode :: Lens' TT.TwitterErrorMessage Int
+twitterErrorCode afb s = (\b -> s { TT.twitterErrorCode = b }) <$> afb (TT.twitterErrorCode s)
+
+twitterErrorMessage :: Lens' TT.TwitterErrorMessage Text
+twitterErrorMessage afb s = (\b -> s { TT.twitterErrorMessage = b }) <$> afb (TT.twitterErrorMessage s)
+
+-- * Lenses for 'TT.WithCursor'
+previousCursor :: forall cursorKey wrapped. Lens' (TT.WithCursor cursorKey wrapped) Integer
+previousCursor afb s = (\b -> s { TT.previousCursor = b }) <$> afb (TT.previousCursor s)
+
+nextCursor :: forall cursorKey wrapped. Lens' (TT.WithCursor cursorKey wrapped) Integer
+nextCursor afb s = (\b -> s { TT.nextCursor = b }) <$> afb (TT.nextCursor s)
+
+contents :: forall cursorKey a b. Lens (TT.WithCursor cursorKey a) (TT.WithCursor cursorKey b) [a] [b]
+contents afb s = (\b -> s { TT.contents = b }) <$> afb (TT.contents s)
diff --git a/Web/Twitter/Conduit/Monad.hs b/Web/Twitter/Conduit/Monad.hs
--- a/Web/Twitter/Conduit/Monad.hs
+++ b/Web/Twitter/Conduit/Monad.hs
@@ -1,7 +1,4 @@
-{-# LANGUAGE GADTs #-}
-{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE FlexibleContexts #-}
-{-# LANGUAGE CPP #-}
 
 module Web.Twitter.Conduit.Monad
        ( TW
diff --git a/Web/Twitter/Conduit/Parameters.hs b/Web/Twitter/Conduit/Parameters.hs
--- a/Web/Twitter/Conduit/Parameters.hs
+++ b/Web/Twitter/Conduit/Parameters.hs
@@ -2,7 +2,12 @@
 {-# LANGUAGE TemplateHaskell #-}
 
 module Web.Twitter.Conduit.Parameters
-       ( Parameters (..)
+       ( Parameters(..)
+       , PV(..)
+       , APIQuery
+       , APIQueryItem
+       , makeSimpleQuery
+
        , HasSinceIdParam (..)
        , HasCountParam (..)
        , HasMaxIdParam (..)
@@ -29,87 +34,83 @@
        , UserParam(..)
        , UserListParam(..)
        , ListParam(..)
+       , MediaData(..)
        , mkUserParam
        , mkUserListParam
        , mkListParam
        ) where
 
-import Prelude as P
-import Web.Twitter.Conduit.Parameters.Internal
+import qualified Data.Text as T
+import Network.HTTP.Client (RequestBody)
 import Web.Twitter.Conduit.Parameters.TH
+import Web.Twitter.Conduit.Request
 import Web.Twitter.Types
-import Data.Time.Calendar (Day)
-import Data.Text.Strict.Lens
-import Data.Text (Text)
-import Control.Lens
 
-import qualified Network.HTTP.Types as HT
-import qualified Data.ByteString.Char8 as S8
-
 data UserParam = UserIdParam UserId | ScreenNameParam String
                deriving (Show, Eq)
 data UserListParam = UserIdListParam [UserId] | ScreenNameListParam [String]
                    deriving (Show, Eq)
 data ListParam = ListIdParam Integer | ListNameParam String
                deriving (Show, Eq)
+data MediaData = MediaFromFile FilePath
+               | MediaRequestBody FilePath RequestBody
 
-defineHasParamClass "count" ''Integer 'readShow
-defineHasParamClass "since_id" ''Integer 'readShow
-defineHasParamClass "max_id" ''Integer 'readShow
-defineHasParamClass "page" ''Integer 'readShow
-defineHasParamClass "cursor" ''Integer 'readShow
-defineHasParamClass "trim_user" ''Bool 'booleanQuery
-defineHasParamClass "exclude_replies" ''Bool 'booleanQuery
-defineHasParamClass "contributor_details" ''Bool 'booleanQuery
-defineHasParamClass "include_entities" ''Bool 'booleanQuery
-defineHasParamClass "include_user_entities" ''Bool 'booleanQuery
-defineHasParamClass "include_rts" ''Bool 'booleanQuery
-defineHasParamClass "include_my_retweet" ''Bool 'booleanQuery
-defineHasParamClass "in_reply_to_status_id" ''StatusId 'readShow
-defineHasParamClass "display_coordinates" ''Bool 'booleanQuery
-defineHasParamClass "possibly_sensitive" ''Bool 'booleanQuery
-defineHasParamClass "lang" ''Text 'utf8
-defineHasParamClass "locale" ''Text 'utf8
-defineHasParamClass "until" ''Day 'readShow
-defineHasParamClass "skip_status" ''Bool 'booleanQuery
-defineHasParamClass "follow" ''Bool 'booleanQuery
-defineHasParamClass "map" ''Bool 'booleanQuery
-defineHasParamClass' "media_ids" [t|[Integer]|] 'integerArrayQuery
+defineHasParamClassInteger "count"
+defineHasParamClassInteger "since_id"
+defineHasParamClassInteger "max_id"
+defineHasParamClassInteger "page"
+defineHasParamClassInteger "cursor"
+defineHasParamClassBool "trim_user"
+defineHasParamClassBool "exclude_replies"
+defineHasParamClassBool "contributor_details"
+defineHasParamClassBool "include_entities"
+defineHasParamClassBool "include_user_entities"
+defineHasParamClassBool "include_rts"
+defineHasParamClassBool "include_my_retweet"
+defineHasParamClassInteger "in_reply_to_status_id"
+defineHasParamClassBool "display_coordinates"
+defineHasParamClassBool "possibly_sensitive"
+defineHasParamClassString "lang"
+defineHasParamClassString "locale"
+defineHasParamClassDay "until"
+defineHasParamClassBool "skip_status"
+defineHasParamClassBool "follow"
+defineHasParamClassBool "map"
+defineHasParamClassIntegerArray "media_ids"
 
 -- | converts 'UserParam' to 'HT.SimpleQuery'.
 --
--- >>> mkUserParam $ UserIdParam 123456
+-- >>> makeSimpleQuery . mkUserParam $ UserIdParam 123456
 -- [("user_id","123456")]
--- >>> mkUserParam $ ScreenNameParam "thimura"
+-- >>> makeSimpleQuery . mkUserParam $ ScreenNameParam "thimura"
 -- [("screen_name","thimura")]
-mkUserParam :: UserParam -> HT.SimpleQuery
-mkUserParam (UserIdParam uid) =  [("user_id", readShow # uid)]
-mkUserParam (ScreenNameParam sn) = [("screen_name", S8.pack sn)]
+mkUserParam :: UserParam -> APIQuery
+mkUserParam (UserIdParam uid) =  [("user_id", PVInteger uid)]
+mkUserParam (ScreenNameParam sn) = [("screen_name", PVString . T.pack $ sn)]
 
 -- | converts 'UserListParam' to 'HT.SimpleQuery'.
 --
--- >>> mkUserListParam $ UserIdListParam [123456]
+-- >>> makeSimpleQuery . mkUserListParam $ UserIdListParam [123456]
 -- [("user_id","123456")]
--- >>> mkUserListParam $ UserIdListParam [123456, 654321]
+-- >>> makeSimpleQuery . mkUserListParam $ UserIdListParam [123456, 654321]
 -- [("user_id","123456,654321")]
--- >>> mkUserListParam $ ScreenNameListParam ["thimura", "NikaidouShinku"]
+-- >>> makeSimpleQuery . mkUserListParam $ ScreenNameListParam ["thimura", "NikaidouShinku"]
 -- [("screen_name","thimura,NikaidouShinku")]
-mkUserListParam :: UserListParam -> HT.SimpleQuery
-mkUserListParam (UserIdListParam uids) =  [("user_id", uids ^.. traversed . re readShow & S8.intercalate ",")]
-mkUserListParam (ScreenNameListParam sns) = [("screen_name", S8.intercalate "," . P.map S8.pack $ sns)]
+mkUserListParam :: UserListParam -> APIQuery
+mkUserListParam (UserIdListParam uids) =  [("user_id", PVIntegerArray uids)]
+mkUserListParam (ScreenNameListParam sns) = [("screen_name", PVStringArray (Prelude.map T.pack sns))]
 
 -- | converts 'ListParam' to 'HT.SimpleQuery'.
 --
--- >>> mkListParam $ ListIdParam 123123
+-- >>> makeSimpleQuery . mkListParam $ ListIdParam 123123
 -- [("list_id","123123")]
--- >>> mkListParam $ ListNameParam "thimura/haskell"
+-- >>> makeSimpleQuery . mkListParam $ ListNameParam "thimura/haskell"
 -- [("slug","haskell"),("owner_screen_name","thimura")]
-mkListParam :: ListParam -> HT.SimpleQuery
-mkListParam (ListIdParam lid) =  [("list_id", readShow # lid)]
+mkListParam :: ListParam -> APIQuery
+mkListParam (ListIdParam lid) =  [("list_id", PVInteger lid)]
 mkListParam (ListNameParam listname) =
-    [("slug", S8.pack lstName),
-     ("owner_screen_name", S8.pack screenName)]
+    [("slug", PVString (T.pack lstName)),
+     ("owner_screen_name", PVString (T.pack screenName))]
   where
     (screenName, ln) = span (/= '/') listname
     lstName = drop 1 ln
-
diff --git a/Web/Twitter/Conduit/Parameters/Internal.hs b/Web/Twitter/Conduit/Parameters/Internal.hs
deleted file mode 100644
--- a/Web/Twitter/Conduit/Parameters/Internal.hs
+++ /dev/null
@@ -1,94 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE Rank2Types #-}
-
-module Web.Twitter.Conduit.Parameters.Internal
-       ( Parameters(..)
-       , readShow
-       , booleanQuery
-       , integerArrayQuery
-       , wrappedParam
-       ) where
-
-import qualified Network.HTTP.Types as HT
-import qualified Data.ByteString as S
-import qualified Data.ByteString.Char8 as S8
-import Data.Maybe
-import Control.Lens
-
-class Parameters a where
-    params :: Lens' a HT.SimpleQuery
-
--- | This 'Prism' convert from a 'ByteString' to some value based on 'Read' and 'Show'
---
--- >>> readShow # 2
--- "2"
--- >>> "1024" ^? readShow :: Maybe Integer
--- Just 1024
-readShow :: (Read a, Show a) => Prism' S.ByteString a
-readShow = prism' (S8.pack . show) (readMaybe . S8.unpack)
-  where
-    readMaybe str = case [x | (x, t) <- reads str, ("", "") <- lex t] of
-        [x] -> Just x
-        _ -> Nothing
-
--- | This 'Prism' convert from a 'ByteString' to 'Bool' value.
---
--- >>> booleanQuery # True
--- "true"
--- >>> booleanQuery # False
--- "false"
--- >>> "true" ^? booleanQuery
--- Just True
--- >>> "1" ^? booleanQuery
--- Just True
--- >>> "t" ^? booleanQuery
--- Just True
--- >>> "test" ^? booleanQuery
--- Just False
-booleanQuery :: Prism' S.ByteString Bool
-booleanQuery = prism' bs sb
-  where
-    bs True = "true"
-    bs False = "false"
-    sb "true" = Just True
-    sb "1" = Just True
-    sb "t" = Just True
-    sb _ = Just False
-
--- | This 'Prism' convert from a 'ByteString' to the array of 'Integer' value.
---
--- This is not a valid Prism, for example:
---
--- @
--- "1, 2" ^? integerArrayQuery == Just [1,2]
--- integerArrayQuery # [1,2] != "1, 2"
--- @
---
--- >>> integerArrayQuery # [1]
--- "1"
--- >>> integerArrayQuery # [1,2234,3]
--- "1,2234,3"
--- >>> "1,2234,3" ^? integerArrayQuery
--- Just [1,2234,3]
--- >>> "" ^? integerArrayQuery
--- Just []
--- >>> "hoge,2" ^? integerArrayQuery
--- Nothing
-integerArrayQuery :: Prism' S.ByteString [Integer]
-integerArrayQuery = prism' bs_arr arr_bs
-  where
-    bs_arr xs = S8.intercalate "," $ xs ^.. traversed . re readShow
-    arr_bs str = chkValid $ map (^? readShow) $ S8.split ',' str
-    chkValid arr =
-        if all isJust arr
-        then Just (catMaybes arr)
-        else Nothing
-
-wrappedParam :: Parameters p => S.ByteString -> Prism' S.ByteString a -> Lens' p (Maybe a)
-wrappedParam key aSBS = lens getter setter
-   where
-     getter = preview $ params . to (lookup key) . _Just . aSBS
-     setter = flip (over params . replace key)
-     replace k (Just v) = ((k, aSBS # v):) . dropAssoc k
-     replace k Nothing = dropAssoc k
-     dropAssoc k = filter ((/= k) . fst)
diff --git a/Web/Twitter/Conduit/Parameters/TH.hs b/Web/Twitter/Conduit/Parameters/TH.hs
--- a/Web/Twitter/Conduit/Parameters/TH.hs
+++ b/Web/Twitter/Conduit/Parameters/TH.hs
@@ -4,10 +4,13 @@
 
 module Web.Twitter.Conduit.Parameters.TH where
 
-import Web.Twitter.Conduit.Parameters.Internal
+import Web.Twitter.Conduit.Request
 import Language.Haskell.TH
 import Control.Lens
+import qualified Data.ByteString as S
 import Data.Char
+import Data.Text (Text)
+import Data.Time.Calendar (Day)
 
 snakeToLowerCamel :: String -> String
 snakeToLowerCamel [] = []
@@ -25,28 +28,38 @@
 paramNameToClassName :: String -> String
 paramNameToClassName paramName = "Has" ++ snakeToUpperCamel paramName ++ "Param"
 
-defineHasParamClass :: String -- ^ parameter name
-                    -> Name -- ^ parameter type
-                    -> Name -- ^ a Prism
-                    -> Q [Dec]
-defineHasParamClass paramName typeN =
-    defineHasParamClass' paramName (conT typeN)
+wrappedParam :: Parameters p
+             => S.ByteString
+             -> (a -> PV)
+             -> (PV -> a)
+             -> Lens' p (Maybe a)
+wrappedParam key wrap unwrap = lens getter setter
+   where
+     getter = preview $ params . to (lookup key) . _Just . to unwrap
+     setter = flip (over params . replace key)
+     replace k (Just v) = ((k, wrap v):) . dropAssoc k
+     replace k Nothing = dropAssoc k
+     dropAssoc k = filter ((/= k) . fst)
 
-defineHasParamClass' :: String -> TypeQ -> Name -> Q [Dec]
-defineHasParamClass' paramName typeQ =
-    defineHasParamClass'' cNameS fNameS paramName typeQ
+defineHasParamClass :: Name -- wrap function
+                    -> Name -- unwrap function
+                    -> TypeQ -- wrapped type
+                    -> String -- ^ parameter name
+                    -> Q [Dec]
+defineHasParamClass wrap unwrap typ paramName =
+    defineHasParamClass' cNameS fNameS wrap unwrap typ paramName 
   where
     cNameS = paramNameToClassName paramName
     fNameS = snakeToLowerCamel paramName
 
-defineHasParamClass'' :: String -> String -> String -> TypeQ -> Name -> Q [Dec]
-defineHasParamClass'' cNameS fNameS paramName typeQ prismN = do
+defineHasParamClass' :: String -> String -> Name -> Name -> TypeQ -> String -> Q [Dec]
+defineHasParamClass' cNameS fNameS wrap unwrap typ paramName = do
     a <- newName "a"
     cName <- newName cNameS
     fName <- newName fNameS
     let cCxt = cxt [classP ''Parameters [varT a]]
-        tySig = sigD fName (appT (appT (conT ''Lens') (varT a)) (appT (conT ''Maybe) typeQ))
-        valDef = valD (varP fName) (normalB (appE (appE (varE 'wrappedParam) (litE (stringL paramName))) (varE prismN))) []
+        tySig = sigD fName (appT (appT (conT ''Lens') (varT a)) (appT (conT ''Maybe) typ))
+        valDef = valD (varP fName) (normalB (appE (appE (appE (varE 'wrappedParam) (litE (stringL paramName))) (conE wrap)) (varE unwrap))) []
     dec <- classD cCxt cName [PlainTV a] [] [tySig, valDef]
     return [dec]
 
@@ -61,3 +74,27 @@
     targetType = do
         a <- newName "a"
         appT (appT (conT (mkName "APIRequest")) (conT typName)) (varT a)
+
+defineHasParamClassInteger :: String -> Q [Dec]
+defineHasParamClassInteger =
+    defineHasParamClass 'PVInteger 'unPVInteger [t|Integer|]
+
+defineHasParamClassBool :: String -> Q [Dec]
+defineHasParamClassBool =
+    defineHasParamClass 'PVBool 'unPVBool [t|Bool|]
+
+defineHasParamClassString :: String -> Q [Dec]
+defineHasParamClassString =
+    defineHasParamClass 'PVString 'unPVString [t|Text|]
+
+defineHasParamClassIntegerArray :: String -> Q [Dec]
+defineHasParamClassIntegerArray =
+    defineHasParamClass 'PVIntegerArray 'unPVIntegerArray [t|[Integer]|]
+
+defineHasParamClassStringArray :: String -> Q [Dec]
+defineHasParamClassStringArray =
+    defineHasParamClass 'PVStringArray 'unPVStringArray [t|[Text]|]
+
+defineHasParamClassDay :: String -> Q [Dec]
+defineHasParamClassDay =
+    defineHasParamClass 'PVDay 'unPVDay [t|Day|]
diff --git a/Web/Twitter/Conduit/Request.hs b/Web/Twitter/Conduit/Request.hs
--- a/Web/Twitter/Conduit/Request.hs
+++ b/Web/Twitter/Conduit/Request.hs
@@ -1,18 +1,30 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE Rank2Types #-}
-{-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE CPP #-}
 
 module Web.Twitter.Conduit.Request
-       ( APIRequest(..)
+       ( Parameters(..)
+       , APIRequest(..)
+       , APIQuery
+       , APIQueryItem
+       , PV(..)
+       , makeSimpleQuery
+       , paramValueBS
        ) where
 
-import Web.Twitter.Conduit.Parameters
-
+import Control.Applicative
+import Control.Lens
+import Data.ByteString (ByteString)
+import qualified Data.ByteString.Char8 as S8
+import Data.Text (Text)
+import qualified Data.Text.Encoding as T
+import Data.Time.Calendar (Day)
 import Network.HTTP.Client.MultipartFormData
 import qualified Network.HTTP.Types as HT
-import Control.Applicative
 
+class Parameters a where
+    params :: Lens' a APIQuery
+
 -- In GHC 7.4.2, the following test fails with Overlapping instances error.
 -- It may be caused by #5820 "defining instance in GHCi leads to duplicated instances".
 -- So, we bypass below tests when GHC version older than 7.6.
@@ -22,6 +34,7 @@
 -- >>> :set -XOverloadedStrings -XRank2Types -XEmptyDataDecls -XFlexibleInstances -XOverlappingInstances -XIncoherentInstances
 -- >>> import Control.Lens
 -- >>> import Data.Default
+-- >>> import Web.Twitter.Conduit.Parameters
 -- >>> data SampleApi
 -- >>> type SampleId = Integer
 -- >>> instance HasCountParam (APIRequest SampleApi [SampleId])
@@ -50,22 +63,22 @@
 -- And update request parameters.
 --
 -- >>> (sampleApiRequest & count ?~ 100 & maxId ?~ 1234567890) ^. params
--- [("max_id","1234567890"),("count","100")]
+-- [("max_id",PVInteger {unPVInteger = 1234567890}),("count",PVInteger {unPVInteger = 100})]
 -- >>> (sampleApiRequest & count ?~ 100 & maxId ?~ 1234567890 & count .~ Nothing) ^. params
--- [("max_id","1234567890")]
+-- [("max_id",PVInteger {unPVInteger = 1234567890})]
 #endif
 data APIRequest apiName responseType
     = APIRequestGet
       { _url :: String
-      , _params :: HT.SimpleQuery
+      , _params :: APIQuery
       }
     | APIRequestPost
       { _url :: String
-      , _params :: HT.SimpleQuery
+      , _params :: APIQuery
       }
     | APIRequestPostMultipart
       { _url :: String
-      , _params :: HT.SimpleQuery
+      , _params :: APIQuery
       , _part :: [Part]
       }
 instance Parameters (APIRequest apiName responseType) where
@@ -74,6 +87,30 @@
     params f (APIRequestPostMultipart u pa prt) =
         (\p -> APIRequestPostMultipart u p prt) <$> f pa
 instance Show (APIRequest apiName responseType) where
-    show (APIRequestGet u p) = "APIRequestGet " ++ show u ++ " " ++ show p
-    show (APIRequestPost u p) = "APIRequestPost " ++ show u ++ " " ++ show p
-    show (APIRequestPostMultipart u p _) = "APIRequestPostMultipart " ++ show u ++ " " ++ show p
+    show (APIRequestGet u p) = "APIRequestGet " ++ show u ++ " " ++ show (makeSimpleQuery p)
+    show (APIRequestPost u p) = "APIRequestPost " ++ show u ++ " " ++ show (makeSimpleQuery p)
+    show (APIRequestPostMultipart u p _) = "APIRequestPostMultipart " ++ show u ++ " " ++ show (makeSimpleQuery p)
+
+type APIQuery = [APIQueryItem]
+type APIQueryItem = (ByteString, PV)
+
+data PV
+    = PVInteger { unPVInteger :: Integer }
+    | PVBool { unPVBool :: Bool }
+    | PVString { unPVString :: Text }
+    | PVIntegerArray { unPVIntegerArray :: [Integer] }
+    | PVStringArray { unPVStringArray :: [Text] }
+    | PVDay { unPVDay :: Day }
+    deriving (Show, Eq)
+
+makeSimpleQuery :: APIQuery -> HT.SimpleQuery
+makeSimpleQuery = traversed . _2 %~ paramValueBS
+
+paramValueBS :: PV -> ByteString
+paramValueBS (PVInteger i) = S8.pack . show $ i
+paramValueBS (PVBool True) = "true"
+paramValueBS (PVBool False) = "false"
+paramValueBS (PVString txt) = T.encodeUtf8 txt
+paramValueBS (PVIntegerArray iarr) = S8.intercalate "," $ map (S8.pack . show) iarr
+paramValueBS (PVStringArray iarr) = S8.intercalate "," $ map T.encodeUtf8 iarr
+paramValueBS (PVDay day) = S8.pack . show $ day
diff --git a/Web/Twitter/Conduit/Response.hs b/Web/Twitter/Conduit/Response.hs
new file mode 100644
--- /dev/null
+++ b/Web/Twitter/Conduit/Response.hs
@@ -0,0 +1,61 @@
+{-# LANGUAGE DeriveDataTypeable #-}
+{-# LANGUAGE DeriveFoldable #-}
+{-# LANGUAGE DeriveFunctor #-}
+{-# LANGUAGE DeriveTraversable #-}
+{-# LANGUAGE OverloadedStrings #-}
+
+module Web.Twitter.Conduit.Response
+       ( Response (..)
+       , TwitterError (..)
+       , TwitterErrorMessage (..)
+       ) where
+
+import Control.Applicative
+import Control.Exception
+import Data.Aeson
+import Data.Data
+import Data.Foldable (Foldable)
+import qualified Data.Text as T
+import Data.Traversable (Traversable)
+import Network.HTTP.Types (Status, ResponseHeaders, Status, ResponseHeaders)
+
+data Response responseType = Response
+    { responseStatus :: Status
+    , responseHeaders :: ResponseHeaders
+    , responseBody :: responseType
+    } deriving (Show, Eq, Typeable, Functor, Foldable, Traversable)
+
+data TwitterError
+    = FromJSONError String
+    | TwitterErrorResponse Status ResponseHeaders [TwitterErrorMessage]
+    | TwitterStatusError Status ResponseHeaders Value
+    deriving (Show, Typeable, Eq)
+
+instance Exception TwitterError
+
+-- | Twitter Error Messages
+--
+-- see detail: <https://dev.twitter.com/docs/error-codes-responses>
+data TwitterErrorMessage = TwitterErrorMessage
+    { twitterErrorCode :: Int
+    , twitterErrorMessage :: T.Text
+    } deriving (Show, Data, Typeable)
+
+instance Eq TwitterErrorMessage where
+    TwitterErrorMessage { twitterErrorCode = a } == TwitterErrorMessage { twitterErrorCode = b }
+        = a == b
+
+instance Ord TwitterErrorMessage where
+    compare TwitterErrorMessage { twitterErrorCode = a } TwitterErrorMessage { twitterErrorCode = b }
+        = a `compare` b
+
+instance Enum TwitterErrorMessage where
+    fromEnum = twitterErrorCode
+    toEnum a = TwitterErrorMessage a T.empty
+
+instance FromJSON TwitterErrorMessage where
+    parseJSON (Object o) =
+        TwitterErrorMessage
+        <$> o .:  "code"
+        <*> o .:  "message"
+    parseJSON v = fail $ "unexpected: " ++ show v
diff --git a/Web/Twitter/Conduit/Status.hs b/Web/Twitter/Conduit/Status.hs
--- a/Web/Twitter/Conduit/Status.hs
+++ b/Web/Twitter/Conduit/Status.hs
@@ -1,13 +1,8 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE CPP #-}
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE QuasiQuotes #-}
 {-# LANGUAGE EmptyDataDecls #-}
-#if __GLASGOW_HASKELL__ >= 704
-{-# LANGUAGE ConstraintKinds #-}
-#endif
 
 module Web.Twitter.Conduit.Status
        (
@@ -43,14 +38,11 @@
 import Prelude hiding ( lookup )
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Request
-import Web.Twitter.Conduit.Types
 import Web.Twitter.Conduit.Parameters
 import Web.Twitter.Conduit.Parameters.TH
 import Web.Twitter.Types
 
-import qualified Data.ByteString as S
 import qualified Data.Text as T
-import qualified Data.Text.Encoding as T
 import Network.HTTP.Client.MultipartFormData
 import Data.Default
 
@@ -234,7 +226,7 @@
 -- >>> update "Hello World" & inReplyToStatusId ?~ 1234567890
 -- APIRequestPost "https://api.twitter.com/1.1/statuses/update.json" [("in_reply_to_status_id","1234567890"),("status","Hello World")]
 update :: T.Text -> APIRequest StatusesUpdate Status
-update status = APIRequestPost uri [("status", T.encodeUtf8 status)]
+update status = APIRequestPost uri [("status", PVString status)]
   where uri = endpoint ++ "statuses/update.json"
 deriveHasParamInstances ''StatusesUpdate
     [ "in_reply_to_status_id"
@@ -278,7 +270,7 @@
                 -> MediaData
                 -> APIRequest StatusesUpdateWithMedia Status
 updateWithMedia tweet mediaData =
-    APIRequestPostMultipart uri [("status", T.encodeUtf8 tweet)] [mediaBody mediaData]
+    APIRequestPostMultipart uri [("status", PVString tweet)] [mediaBody mediaData]
   where
     uri = endpoint ++ "statuses/update_with_media.json"
     mediaBody (MediaFromFile fp) = partFileSource "media[]" fp
@@ -306,8 +298,8 @@
 -- APIRequestGet "https://api.twitter.com/1.1/statuses/lookup.json" [("id","10,432656548536401920")]
 -- >>> lookup [10, 432656548536401920] & includeEntities ?~ True
 -- APIRequestGet "https://api.twitter.com/1.1/statuses/lookup.json" [("include_entities","true"),("id","10,432656548536401920")]
-lookup :: [ StatusId ] -> APIRequest StatusesLookup [Status]
-lookup ids = APIRequestGet (endpoint ++ "statuses/lookup.json") [("id", S.intercalate "," . Prelude.map showBS $ ids)]
+lookup :: [StatusId] -> APIRequest StatusesLookup [Status]
+lookup ids = APIRequestGet (endpoint ++ "statuses/lookup.json") [("id", PVIntegerArray ids)]
 deriveHasParamInstances ''StatusesLookup
     [ "include_entities"
     , "trim_user"
diff --git a/Web/Twitter/Conduit/Stream.hs b/Web/Twitter/Conduit/Stream.hs
--- a/Web/Twitter/Conduit/Stream.hs
+++ b/Web/Twitter/Conduit/Stream.hs
@@ -1,10 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE FlexibleContexts #-}
 {-# LANGUAGE EmptyDataDecls #-}
 {-# LANGUAGE CPP #-}
-#if __GLASGOW_HASKELL__ >= 704
 {-# LANGUAGE ConstraintKinds #-}
-#endif
 
 module Web.Twitter.Conduit.Stream
        (
@@ -23,18 +20,17 @@
        , stream'
   ) where
 
-import Web.Twitter.Conduit.Types
 import Web.Twitter.Conduit.Base
 import Web.Twitter.Conduit.Monad
 import Web.Twitter.Types
+import Web.Twitter.Conduit.Parameters
 import Web.Twitter.Conduit.Request
+import Web.Twitter.Conduit.Response
 
 import qualified Data.Conduit as C
 import qualified Data.Conduit.List as CL
 import qualified Data.Conduit.Internal as CI
 import qualified Data.Text as T
-import qualified Data.Text.Encoding as T
-import qualified Data.ByteString as S
 import Control.Monad.IO.Class
 import Data.Aeson
 
@@ -72,9 +68,9 @@
 data StatusesFilter
 statusesFilterByFollow :: [UserId] -> APIRequest StatusesFilter StreamingAPI
 statusesFilterByFollow userIds =
-    APIRequestPost statusesFilterEndpoint [("follow", S.intercalate "," . map showBS $ userIds)]
+    APIRequestPost statusesFilterEndpoint [("follow", PVIntegerArray userIds)]
 
 statusesFilterByTrack :: T.Text -- ^ keyword
                       -> APIRequest StatusesFilter StreamingAPI
 statusesFilterByTrack keyword =
-    APIRequestPost statusesFilterEndpoint [("track", T.encodeUtf8 keyword)]
+    APIRequestPost statusesFilterEndpoint [("track", PVString keyword)]
diff --git a/Web/Twitter/Conduit/Types.hs b/Web/Twitter/Conduit/Types.hs
deleted file mode 100644
--- a/Web/Twitter/Conduit/Types.hs
+++ /dev/null
@@ -1,154 +0,0 @@
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE DeriveDataTypeable #-}
-{-# LANGUAGE DeriveFoldable #-}
-{-# LANGUAGE DeriveFunctor #-}
-{-# LANGUAGE DeriveTraversable #-}
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE ScopedTypeVariables #-}
-{-# LANGUAGE CPP #-}
-
-module Web.Twitter.Conduit.Types
-       ( Response (..)
-       , TwitterError (..)
-       , TwitterErrorMessage (..)
-       , CursorKey (..)
-       , IdsCursorKey
-       , UsersCursorKey
-       , WithCursor (..)
-       , MediaData (..)
-#if !MIN_VERSION_twitter_types(0,5,0)
-       , UploadedMedia (..)
-       , ImageSizeType (..)
-#endif
-       ) where
-
-
-import Control.Applicative
-import Control.Exception
-import Data.Aeson
-import Data.Data
-import Data.Foldable (Foldable)
-import Data.Monoid
-import qualified Data.Text as T
-import Data.Traversable (Traversable)
-import Network.HTTP.Client (RequestBody)
-import Network.HTTP.Types (Status, ResponseHeaders)
-import Web.Twitter.Types (checkError)
-
--- $setup
--- >>> type UserId = Integer
-
-
-class CursorKey a where
-    cursorKey :: a -> T.Text
-
--- | Phantom type to specify the key which point out the content in the response.
-data IdsCursorKey
-instance CursorKey IdsCursorKey where
-    cursorKey = const "ids"
-
--- | Phantom type to specify the key which point out the content in the response.
-data UsersCursorKey
-instance CursorKey UsersCursorKey where
-    cursorKey = const "users"
-
-#if __GLASGOW_HASKELL__ >= 706
--- | A wrapper for API responses which have "next_cursor" field.
---
--- The first type parameter of 'WithCursor' specifies the field name of contents.
---
--- >>> let Just res = decode "{\"previous_cursor\": 0, \"next_cursor\": 1234567890, \"ids\": [1111111111]}" :: Maybe (WithCursor IdsCursorKey UserId)
--- >>> nextCursor res
--- 1234567890
--- >>> contents res
--- [1111111111]
---
--- >>> let Just res = decode "{\"previous_cursor\": 0, \"next_cursor\": 0, \"users\": [1000]}" :: Maybe (WithCursor UsersCursorKey UserId)
--- >>> nextCursor res
--- 0
--- >>> contents res
--- [1000]
-#endif
-data WithCursor cursorKey wrapped = WithCursor
-    { previousCursor :: Integer
-    , nextCursor :: Integer
-    , contents :: [wrapped]
-    } deriving Show
-
-instance (FromJSON wrapped, CursorKey c) =>
-         FromJSON (WithCursor c wrapped) where
-    parseJSON (Object o) = checkError o >>
-      WithCursor <$> o .:  "previous_cursor"
-                 <*> o .:  "next_cursor"
-                 <*> o .:  cursorKey (undefined :: c)
-    parseJSON _ = mempty
-
-data MediaData = MediaFromFile FilePath
-               | MediaRequestBody FilePath RequestBody
-
-#if !MIN_VERSION_twitter_types(0,5,0)
-data ImageSizeType = ImageSizeType
-    { imageWidth :: Int
-    , imageHeight :: Int
-    , imageType :: T.Text
-    } deriving Show
-instance FromJSON ImageSizeType where
-    parseJSON (Object o) =
-        ImageSizeType <$> o .:  "w"
-                      <*> o .:  "h"
-                      <*> o .:  "image_type"
-    parseJSON v = fail $ "unknown value: " ++ show v
-
-data UploadedMedia = UploadedMedia
-    { mediaId :: Integer
-    , mediaSize :: Integer
-    , mediaImage :: ImageSizeType
-    } deriving Show
-instance FromJSON UploadedMedia where
-    parseJSON (Object o) =
-        UploadedMedia <$> o .:  "media_id"
-                      <*> o .:  "size"
-                      <*> o .:  "image"
-    parseJSON v = fail $ "unknown value: " ++ show v
-#endif
-
-data Response responseType = Response
-    { responseStatus :: Status
-    , responseHeaders :: ResponseHeaders
-    , responseBody :: responseType
-    } deriving (Show, Eq, Typeable, Functor, Foldable, Traversable)
-
-data TwitterError
-    = FromJSONError String
-    | TwitterErrorResponse Status ResponseHeaders [TwitterErrorMessage]
-    | TwitterStatusError Status ResponseHeaders Value
-    deriving (Show, Typeable, Eq)
-
-instance Exception TwitterError
-
--- | Twitter Error Messages
---
--- see detail: <https://dev.twitter.com/docs/error-codes-responses>
-data TwitterErrorMessage = TwitterErrorMessage
-    { twitterErrorCode :: Int
-    , twitterErrorMessage :: T.Text
-    } deriving (Show, Data, Typeable)
-
-instance Eq TwitterErrorMessage where
-    TwitterErrorMessage { twitterErrorCode = a } == TwitterErrorMessage { twitterErrorCode = b }
-        = a == b
-
-instance Ord TwitterErrorMessage where
-    compare TwitterErrorMessage { twitterErrorCode = a } TwitterErrorMessage { twitterErrorCode = b }
-        = a `compare` b
-
-instance Enum TwitterErrorMessage where
-    fromEnum = twitterErrorCode
-    toEnum a = TwitterErrorMessage a T.empty
-
-instance FromJSON TwitterErrorMessage where
-    parseJSON (Object o) =
-        TwitterErrorMessage
-        <$> o .:  "code"
-        <*> o .:  "message"
-    parseJSON v = fail $ "unexpected: " ++ show v
diff --git a/Web/Twitter/Conduit/Types/Lens.hs b/Web/Twitter/Conduit/Types/Lens.hs
deleted file mode 100644
--- a/Web/Twitter/Conduit/Types/Lens.hs
+++ /dev/null
@@ -1,37 +0,0 @@
-{-# LANGUAGE TemplateHaskell #-}
-{-# LANGUAGE CPP #-}
-
-module Web.Twitter.Conduit.Types.Lens
-       ( TT.Response
-       , responseStatus
-       , responseBody
-       , responseHeaders
-       , TT.WithCursor
-       , previousCursor
-       , nextCursor
-       , contents
-#if !MIN_VERSION_twitter_types(0,5,0)
-       , TT.ImageSizeType
-       , imageWidth
-       , imageHeight
-       , imageType
-       , TT.UploadedMedia
-       , mediaId
-       , mediaSize
-       , mediaImage
-#endif
-       , TT.TwitterErrorMessage
-       , twitterErrorMessage
-       , twitterErrorCode
-       ) where
-
-import qualified Web.Twitter.Conduit.Types as TT
-import Web.Twitter.Conduit.Types.TH
-
-makeLenses ''TT.WithCursor
-#if !MIN_VERSION_twitter_types(0,5,0)
-makeLenses ''TT.ImageSizeType
-makeLenses ''TT.UploadedMedia
-#endif
-makeLenses ''TT.Response
-makeLenses ''TT.TwitterErrorMessage
diff --git a/Web/Twitter/Conduit/Types/TH.hs b/Web/Twitter/Conduit/Types/TH.hs
deleted file mode 100644
--- a/Web/Twitter/Conduit/Types/TH.hs
+++ /dev/null
@@ -1,18 +0,0 @@
-{-# LANGUAGE CPP #-}
-
-module Web.Twitter.Conduit.Types.TH
-       ( makeLenses
-       ) where
-
-import Control.Lens hiding (makeLenses)
-import Language.Haskell.TH
-
-#if MIN_VERSION_lens(4,4,0)
-makeLenses :: Name -> Q [Dec]
-makeLenses = makeLensesWith (lensRules & lensField .~ myFieldToDef)
-  where
-    myFieldToDef _ n = [TopName (mkName (nameBase n))]
-#else
-makeLenses :: Name -> Q [Dec]
-makeLenses = makeLensesWith (defaultRules & lensField .~ Just)
-#endif
diff --git a/sample/Common.hs b/sample/Common.hs
--- a/sample/Common.hs
+++ b/sample/Common.hs
diff --git a/sample/userstream.hs b/sample/userstream.hs
--- a/sample/userstream.hs
+++ b/sample/userstream.hs
@@ -14,7 +14,7 @@
 import System.Directory
 import Data.Conduit
 import qualified Data.Conduit.Binary as CB
-import Network.HTTP.Conduit
+import Network.HTTP.Conduit as HTTP
 
 import Web.Twitter.Conduit
 import Web.Twitter.Types.Lens
@@ -79,5 +79,5 @@
     unless exists $ withManager $ \mgr -> do
         req <- liftIO $ parseUrl url
         body <- http req mgr
-        responseBody body $$+- CB.sinkFile fname
+        HTTP.responseBody body $$+- CB.sinkFile fname
     return fname
diff --git a/tests/ApiSpec.hs b/tests/ApiSpec.hs
--- a/tests/ApiSpec.hs
+++ b/tests/ApiSpec.hs
@@ -7,7 +7,7 @@
 import qualified Data.Conduit.List as CL
 import Web.Twitter.Conduit (call, sourceWithCursor)
 import Web.Twitter.Conduit.Api
-import Web.Twitter.Conduit.Types.Lens
+import Web.Twitter.Conduit.Lens
 import qualified Web.Twitter.Conduit.Parameters as Param
 import Web.Twitter.Types.Lens
 import Control.Lens
diff --git a/twitter-conduit.cabal b/twitter-conduit.cabal
--- a/twitter-conduit.cabal
+++ b/twitter-conduit.cabal
@@ -1,5 +1,5 @@
 name:              twitter-conduit
-version:           0.0.5.8
+version:           0.0.6
 license:           BSD3
 license-file:      LICENSE
 author:            HATTORI Hiroki, Hideyuki Tanaka, Takahiro HIMURA
@@ -58,7 +58,6 @@
       base >= 4.5 && < 5
     , transformers >= 0.2.2
     , template-haskell
-    , lens >= 4.0 && < 4.5
     , authenticate-oauth >= 1.3
     , resourcet >= 1.0
     , conduit >= 1.1
@@ -74,28 +73,30 @@
     , text >= 0.11
     , containers
     , time
-    , twitter-types >= 0.2
+    , twitter-types >= 0.5
 
   if flag(lens-aeson)
-    build-depends: lens-aeson >= 1
+    build-depends:
+        lens-aeson >= 1
+      , lens >= 4.4 && < 4.5
+  else
+    build-depends:
+        lens >= 4.0 && < 4.4
 
   exposed-modules:
     Web.Twitter.Conduit
-    Web.Twitter.Conduit.Types
-    Web.Twitter.Conduit.Types.Lens
-    Web.Twitter.Conduit.Types.TH
-    Web.Twitter.Conduit.Base
+    Web.Twitter.Conduit.Lens
     Web.Twitter.Conduit.Api
-    Web.Twitter.Conduit.Monad
     Web.Twitter.Conduit.Stream
     Web.Twitter.Conduit.Status
+    Web.Twitter.Conduit.Base
+    Web.Twitter.Conduit.Monad
     Web.Twitter.Conduit.Request
+    Web.Twitter.Conduit.Response
+    Web.Twitter.Conduit.Cursor
     Web.Twitter.Conduit.Parameters
-    Web.Twitter.Conduit.Parameters.Internal
     Web.Twitter.Conduit.Parameters.TH
 
-  other-modules:
-
 test-suite hlint
   type: exitcode-stdio-1.0
   main-is: hlint.hs
@@ -187,6 +188,7 @@
       , http-conduit
       , monad-logger
       , authenticate-oauth
+      , twitter-types
       , twitter-conduit
       , twitter-types
 
