diff --git a/C2HS.hs b/C2HS.hs
new file mode 100644
--- /dev/null
+++ b/C2HS.hs
@@ -0,0 +1,220 @@
+--  C->Haskell Compiler: Marshalling library
+--
+--  Copyright (c) [1999...2005] Manuel M T Chakravarty
+--
+--  Redistribution and use in source and binary forms, with or without
+--  modification, are permitted provided that the following conditions are met:
+-- 
+--  1. Redistributions of source code must retain the above copyright notice,
+--     this list of conditions and the following disclaimer. 
+--  2. Redistributions in binary form must reproduce the above copyright
+--     notice, this list of conditions and the following disclaimer in the
+--     documentation and/or other materials provided with the distribution. 
+--  3. The name of the author may not be used to endorse or promote products
+--     derived from this software without specific prior written permission. 
+--
+--  THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+--  IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+--  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
+--  NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+--  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
+--  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+--  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+--  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+--  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+--  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+--
+--- Description ---------------------------------------------------------------
+--
+--  Language: Haskell 98
+--
+--  This module provides the marshaling routines for Haskell files produced by 
+--  C->Haskell for binding to C library interfaces.  It exports all of the
+--  low-level FFI (language-independent plus the C-specific parts) together
+--  with the C->HS-specific higher-level marshalling routines.
+--
+
+module C2HS (
+
+  -- * Re-export the language-independent component of the FFI 
+  module Foreign,
+
+  -- * Re-export the C language component of the FFI
+  module CForeign,
+
+  -- * Composite marshalling functions
+  withCStringLenIntConv, peekCStringLenIntConv, withIntConv, withFloatConv,
+  peekIntConv, peekFloatConv, withBool, peekBool, withEnum, peekEnum,
+
+  -- * Conditional results using 'Maybe'
+  nothingIf, nothingIfNull,
+
+  -- * Bit masks
+  combineBitMasks, containsBitMask, extractBitMasks,
+
+  -- * Conversion between C and Haskell types
+  cIntConv, cFloatConv, cToBool, cFromBool, cToEnum, cFromEnum
+) where 
+
+
+import Foreign
+       hiding       (Word)
+		    -- Should also hide the Foreign.Marshal.Pool exports in
+		    -- compilers that export them
+import CForeign
+
+import Monad        (when, liftM)
+
+
+-- Composite marshalling functions
+-- -------------------------------
+
+-- Strings with explicit length
+--
+withCStringLenIntConv s f    = withCStringLen s $ \(p, n) -> f (p, cIntConv n)
+peekCStringLenIntConv (s, n) = peekCStringLen (s, cIntConv n)
+
+-- Marshalling of numerals
+--
+
+withIntConv   :: (Storable b, Integral a, Integral b) 
+	      => a -> (Ptr b -> IO c) -> IO c
+withIntConv    = with . cIntConv
+
+withFloatConv :: (Storable b, RealFloat a, RealFloat b) 
+	      => a -> (Ptr b -> IO c) -> IO c
+withFloatConv  = with . cFloatConv
+
+peekIntConv   :: (Storable a, Integral a, Integral b) 
+	      => Ptr a -> IO b
+peekIntConv    = liftM cIntConv . peek
+
+peekFloatConv :: (Storable a, RealFloat a, RealFloat b) 
+	      => Ptr a -> IO b
+peekFloatConv  = liftM cFloatConv . peek
+
+-- Passing Booleans by reference
+--
+
+withBool :: (Integral a, Storable a) => Bool -> (Ptr a -> IO b) -> IO b
+withBool  = with . fromBool
+
+peekBool :: (Integral a, Storable a) => Ptr a -> IO Bool
+peekBool  = liftM toBool . peek
+
+
+-- Passing enums by reference
+--
+
+withEnum :: (Enum a, Integral b, Storable b) => a -> (Ptr b -> IO c) -> IO c
+withEnum  = with . cFromEnum
+
+peekEnum :: (Enum a, Integral b, Storable b) => Ptr b -> IO a
+peekEnum  = liftM cToEnum . peek
+
+
+-- Storing of 'Maybe' values
+-- -------------------------
+
+instance Storable a => Storable (Maybe a) where
+  sizeOf    _ = sizeOf    (undefined :: Ptr ())
+  alignment _ = alignment (undefined :: Ptr ())
+
+  peek p = do
+	     ptr <- peek (castPtr p)
+	     if ptr == nullPtr
+	       then return Nothing
+	       else liftM Just $ peek ptr
+
+  poke p v = do
+	       ptr <- case v of
+		        Nothing -> return nullPtr
+			Just v' -> new v'
+               poke (castPtr p) ptr
+
+
+-- Conditional results using 'Maybe'
+-- ---------------------------------
+
+-- Wrap the result into a 'Maybe' type.
+--
+-- * the predicate determines when the result is considered to be non-existing,
+--   ie, it is represented by `Nothing'
+--
+-- * the second argument allows to map a result wrapped into `Just' to some
+--   other domain
+--
+nothingIf       :: (a -> Bool) -> (a -> b) -> a -> Maybe b
+nothingIf p f x  = if p x then Nothing else Just $ f x
+
+-- |Instance for special casing null pointers.
+--
+nothingIfNull :: (Ptr a -> b) -> Ptr a -> Maybe b
+nothingIfNull  = nothingIf (== nullPtr)
+
+
+-- Support for bit masks
+-- ---------------------
+
+-- Given a list of enumeration values that represent bit masks, combine these
+-- masks using bitwise disjunction.
+--
+combineBitMasks :: (Enum a, Bits b) => [a] -> b
+combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum)
+
+-- Tests whether the given bit mask is contained in the given bit pattern
+-- (i.e., all bits set in the mask are also set in the pattern).
+--
+containsBitMask :: (Bits a, Enum b) => a -> b -> Bool
+bits `containsBitMask` bm = let bm' = fromIntegral . fromEnum $ bm
+			    in
+			    bm' .&. bits == bm'
+
+-- |Given a bit pattern, yield all bit masks that it contains.
+--
+-- * This does *not* attempt to compute a minimal set of bit masks that when
+--   combined yield the bit pattern, instead all contained bit masks are
+--   produced.
+--
+extractBitMasks :: (Bits a, Enum b, Bounded b) => a -> [b]
+extractBitMasks bits = 
+  [bm | bm <- [minBound..maxBound], bits `containsBitMask` bm]
+
+
+-- Conversion routines
+-- -------------------
+
+-- |Integral conversion
+--
+cIntConv :: (Integral a, Integral b) => a -> b
+cIntConv  = fromIntegral
+
+-- |Floating conversion
+--
+cFloatConv :: (RealFloat a, RealFloat b) => a -> b
+cFloatConv  = realToFrac
+-- As this conversion by default goes via `Rational', it can be very slow...
+{-# RULES 
+  "cFloatConv/Float->Float"   forall (x::Float).  cFloatConv x = x;
+  "cFloatConv/Double->Double" forall (x::Double). cFloatConv x = x
+ #-}
+
+-- |Obtain C value from Haskell 'Bool'.
+--
+cFromBool :: Num a => Bool -> a
+cFromBool  = fromBool
+
+-- |Obtain Haskell 'Bool' from C value.
+--
+cToBool :: Num a => a -> Bool
+cToBool  = toBool
+
+-- |Convert a C enumeration to Haskell.
+--
+cToEnum :: (Integral i, Enum e) => i -> e
+cToEnum  = toEnum . cIntConv
+
+-- |Convert a Haskell enumeration to C.
+--
+cFromEnum :: (Enum e, Integral i) => e -> i
+cFromEnum  = cIntConv . fromEnum
diff --git a/COPYING b/COPYING
new file mode 100644
--- /dev/null
+++ b/COPYING
@@ -0,0 +1,165 @@
+		   GNU LESSER GENERAL PUBLIC LICENSE
+                       Version 3, 29 June 2007
+
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+
+  This version of the GNU Lesser General Public License incorporates
+the terms and conditions of version 3 of the GNU General Public
+License, supplemented by the additional permissions listed below.
+
+  0. Additional Definitions. 
+
+  As used herein, "this License" refers to version 3 of the GNU Lesser
+General Public License, and the "GNU GPL" refers to version 3 of the GNU
+General Public License.
+
+  "The Library" refers to a covered work governed by this License,
+other than an Application or a Combined Work as defined below.
+
+  An "Application" is any work that makes use of an interface provided
+by the Library, but which is not otherwise based on the Library.
+Defining a subclass of a class defined by the Library is deemed a mode
+of using an interface provided by the Library.
+
+  A "Combined Work" is a work produced by combining or linking an
+Application with the Library.  The particular version of the Library
+with which the Combined Work was made is also called the "Linked
+Version".
+
+  The "Minimal Corresponding Source" for a Combined Work means the
+Corresponding Source for the Combined Work, excluding any source code
+for portions of the Combined Work that, considered in isolation, are
+based on the Application, and not on the Linked Version.
+
+  The "Corresponding Application Code" for a Combined Work means the
+object code and/or source code for the Application, including any data
+and utility programs needed for reproducing the Combined Work from the
+Application, but excluding the System Libraries of the Combined Work.
+
+  1. Exception to Section 3 of the GNU GPL.
+
+  You may convey a covered work under sections 3 and 4 of this License
+without being bound by section 3 of the GNU GPL.
+
+  2. Conveying Modified Versions.
+
+  If you modify a copy of the Library, and, in your modifications, a
+facility refers to a function or data to be supplied by an Application
+that uses the facility (other than as an argument passed when the
+facility is invoked), then you may convey a copy of the modified
+version:
+
+   a) under this License, provided that you make a good faith effort to
+   ensure that, in the event an Application does not supply the
+   function or data, the facility still operates, and performs
+   whatever part of its purpose remains meaningful, or
+
+   b) under the GNU GPL, with none of the additional permissions of
+   this License applicable to that copy.
+
+  3. Object Code Incorporating Material from Library Header Files.
+
+  The object code form of an Application may incorporate material from
+a header file that is part of the Library.  You may convey such object
+code under terms of your choice, provided that, if the incorporated
+material is not limited to numerical parameters, data structure
+layouts and accessors, or small macros, inline functions and templates
+(ten or fewer lines in length), you do both of the following:
+
+   a) Give prominent notice with each copy of the object code that the
+   Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the object code with a copy of the GNU GPL and this license
+   document.
+
+  4. Combined Works.
+
+  You may convey a Combined Work under terms of your choice that,
+taken together, effectively do not restrict modification of the
+portions of the Library contained in the Combined Work and reverse
+engineering for debugging such modifications, if you also do each of
+the following:
+
+   a) Give prominent notice with each copy of the Combined Work that
+   the Library is used in it and that the Library and its use are
+   covered by this License.
+
+   b) Accompany the Combined Work with a copy of the GNU GPL and this license
+   document.
+
+   c) For a Combined Work that displays copyright notices during
+   execution, include the copyright notice for the Library among
+   these notices, as well as a reference directing the user to the
+   copies of the GNU GPL and this license document.
+
+   d) Do one of the following:
+
+       0) Convey the Minimal Corresponding Source under the terms of this
+       License, and the Corresponding Application Code in a form
+       suitable for, and under terms that permit, the user to
+       recombine or relink the Application with a modified version of
+       the Linked Version to produce a modified Combined Work, in the
+       manner specified by section 6 of the GNU GPL for conveying
+       Corresponding Source.
+
+       1) Use a suitable shared library mechanism for linking with the
+       Library.  A suitable mechanism is one that (a) uses at run time
+       a copy of the Library already present on the user's computer
+       system, and (b) will operate properly with a modified version
+       of the Library that is interface-compatible with the Linked
+       Version. 
+
+   e) Provide Installation Information, but only if you would otherwise
+   be required to provide such information under section 6 of the
+   GNU GPL, and only to the extent that such information is
+   necessary to install and execute a modified version of the
+   Combined Work produced by recombining or relinking the
+   Application with a modified version of the Linked Version. (If
+   you use option 4d0, the Installation Information must accompany
+   the Minimal Corresponding Source and Corresponding Application
+   Code. If you use option 4d1, you must provide the Installation
+   Information in the manner specified by section 6 of the GNU GPL
+   for conveying Corresponding Source.)
+
+  5. Combined Libraries.
+
+  You may place library facilities that are a work based on the
+Library side by side in a single library together with other library
+facilities that are not Applications and are not covered by this
+License, and convey such a combined library under terms of your
+choice, if you do both of the following:
+
+   a) Accompany the combined library with a copy of the same work based
+   on the Library, uncombined with any other library facilities,
+   conveyed under the terms of this License.
+
+   b) Give prominent notice with the combined library that part of it
+   is a work based on the Library, and explaining where to find the
+   accompanying uncombined form of the same work.
+
+  6. Revised Versions of the GNU Lesser General Public License.
+
+  The Free Software Foundation may publish revised and/or new versions
+of the GNU Lesser General Public License from time to time. Such new
+versions will be similar in spirit to the present version, but may
+differ in detail to address new problems or concerns.
+
+  Each version is given a distinguishing version number. If the
+Library as you received it specifies that a certain numbered version
+of the GNU Lesser General Public License "or any later version"
+applies to it, you have the option of following the terms and
+conditions either of that published version or of any later version
+published by the Free Software Foundation. If the Library as you
+received it does not specify a version number of the GNU Lesser
+General Public License, you may choose any version of the GNU Lesser
+General Public License ever published by the Free Software Foundation.
+
+  If the Library as you received it specifies that a proxy can decide
+whether future versions of the GNU Lesser General Public License shall
+apply, that proxy's public statement of acceptance of any version is
+permanent authorization for you to choose that version for the
+Library.
diff --git a/Setup.hs b/Setup.hs
new file mode 100644
--- /dev/null
+++ b/Setup.hs
@@ -0,0 +1,4 @@
+#! /usr/bin/env runhaskell
+import Distribution.Simple
+main = defaultMainWithHooks autoconfUserHooks
+       
diff --git a/src/Control/Monad/ToIO.hs b/src/Control/Monad/ToIO.hs
new file mode 100644
--- /dev/null
+++ b/src/Control/Monad/ToIO.hs
@@ -0,0 +1,38 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 14 Jan. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module Control.Monad.ToIO
+  ( MonadToIO (..)
+  ) where
+
+import Control.Monad.Reader
+
+
+class Monad m => MonadToIO m where
+  toIO :: m (m a -> IO a)
+          
+
+instance MonadToIO IO where
+  toIO = return id
+
+instance MonadToIO m => MonadToIO (ReaderT r m) where
+  toIO = do
+    r <- ask
+    w <- lift toIO
+    return $ w . flip runReaderT r
diff --git a/src/XMMS2/Client.hs b/src/XMMS2/Client.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client.hs
@@ -0,0 +1,40 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client
+  ( module XMMS2.Client.Exception
+  , module XMMS2.Client.Types
+  , module XMMS2.Client.Connection
+  , module XMMS2.Client.Coll
+  , module XMMS2.Client.Medialib
+  , module XMMS2.Client.Playback
+  , module XMMS2.Client.Playlist
+  , module XMMS2.Client.Result
+  , module XMMS2.Client.Stats
+  ) where
+
+import XMMS2.Client.Exception
+import XMMS2.Client.Types
+import XMMS2.Client.Connection
+import XMMS2.Client.Coll
+import XMMS2.Client.Medialib
+import XMMS2.Client.Playback
+import XMMS2.Client.Playlist
+import XMMS2.Client.Result hiding (liftResult)
+import XMMS2.Client.Stats
diff --git a/src/XMMS2/Client/Bindings.hs b/src/XMMS2/Client/Bindings.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings.hs
@@ -0,0 +1,38 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 17 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings
+  ( module XMMS2.Client.Exception
+  , module XMMS2.Client.Bindings.Types
+  , module XMMS2.Client.Bindings.Connection
+  , module XMMS2.Client.Bindings.Medialib
+  , module XMMS2.Client.Bindings.Playback
+  , module XMMS2.Client.Bindings.Playlist
+  , module XMMS2.Client.Bindings.Result
+  , module XMMS2.Client.Bindings.Stats
+  ) where
+
+import XMMS2.Client.Exception
+import XMMS2.Client.Bindings.Types
+import XMMS2.Client.Bindings.Connection
+import XMMS2.Client.Bindings.Medialib
+import XMMS2.Client.Bindings.Playback
+import XMMS2.Client.Bindings.Playlist
+import XMMS2.Client.Bindings.Result hiding (ResultPtr)
+import XMMS2.Client.Bindings.Stats
diff --git a/src/XMMS2/Client/Bindings/Coll.chs b/src/XMMS2/Client/Bindings/Coll.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Coll.chs
@@ -0,0 +1,102 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 17 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Coll
+  ( CollectionChangedActions (..)
+  , collGet
+  , collList
+  , collSave
+  , collRemove
+  , collRename
+  , collIdlistFromPlaylistFile
+  , collSync
+  , collQueryIds
+  , broadcastCollectionChanged
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsc" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Connection #}
+{# import XMMS2.Client.Bindings.Result #}
+{# import XMMS2.Client.Bindings.Types.Value #}
+{# import XMMS2.Client.Bindings.Types.Coll #}
+
+
+{# enum xmms_collection_changed_actions_t as CollectionChangedActions
+ { underscoreToCase
+ } with prefix = "XMMS_"
+ deriving (Eq, Show) #}
+
+
+{# fun coll_get as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_list as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_save as ^
+ { withConnection* `Connection'
+ , withColl*       `Coll'
+ , withCString*    `String'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_remove as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_rename as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ , withCString*    `String'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_idlist_from_playlist_file as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun coll_sync as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun coll_query_ids as ^
+ { withConnection* `Connection'
+ , withColl*       `Coll'
+ , withValue*      `Value'
+ , cIntConv        `Int'
+ , cIntConv        `Int'
+ } -> `Result' takeResult* #}
+
+
+{# fun broadcast_collection_changed as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
diff --git a/src/XMMS2/Client/Bindings/Connection.chs b/src/XMMS2/Client/Bindings/Connection.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Connection.chs
@@ -0,0 +1,75 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 1 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Connection
+  ( Connection
+  , withConnection
+  , init
+  , connect
+  , disconnectCallbackSet
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+#include <xmms2hs-client.h>
+
+{# context prefix = "xmmsc" #}
+
+import Prelude hiding (init)
+
+import Control.Applicative
+import Control.Monad
+
+import XMMS2.Utils
+
+import XMMS2.Client.Exception
+
+
+{# pointer *xmmsc_connection_t as Connection foreign newtype #}
+
+takeConnection p
+  | p == nullPtr = throwIO ConnectionInitFailed
+  | otherwise    = takePtr Connection xmmsc_unref p
+
+foreign import ccall unsafe "&xmmsc_unref"
+  xmmsc_unref :: FunPtr (Ptr Connection -> IO ())
+
+
+{# fun init as ^
+ { withCString* `String'
+ } -> `Connection' takeConnection* #}
+
+{# fun xmmsc_connect as connect
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ } -> `Bool' #}
+
+disconnectCallbackSet xmmsc fun = do
+  ptr <- mkDisconnectPtr $ const fun
+  disconnect_callback_set xmmsc ptr
+
+type DisconnectFun = Ptr () -> IO ()
+type DisconnectPtr = FunPtr DisconnectFun
+
+{# fun xmms2hs_disconnect_callback_set as disconnect_callback_set
+ { withConnection* `Connection'
+ , id              `DisconnectPtr'
+ } -> `()' #}
+
+foreign import ccall "wrapper"
+  mkDisconnectPtr :: DisconnectFun -> IO DisconnectPtr
diff --git a/src/XMMS2/Client/Bindings/Medialib.chs b/src/XMMS2/Client/Bindings/Medialib.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Medialib.chs
@@ -0,0 +1,131 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 4 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Medialib
+  ( medialibAddEntry
+  , medialibAddEntryFull
+  , medialibAddEntryEncoded
+  , medialibGetInfo
+  , medialibGetId
+  , medialibGetIdEncoded
+  , medialibEntryPropertySetInt
+  , medialibEntryPropertySetIntWithSource
+  , medialibEntryPropertySetStr
+  , medialibEntryPropertySetStrWithSource
+  , medialibEntryPropertyRemove
+  , medialibEntryPropertyRemoveWithSource
+  , xformMediaBrowse
+  , broadcastMedialibEntryChanged
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsc" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+{# import XMMS2.Client.Bindings.Connection #}
+{# import XMMS2.Client.Bindings.Result #}
+
+
+{# fun medialib_add_entry as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_add_entry_full as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ , withValue*      `Value'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_add_entry_encoded as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_get_info as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_get_id as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_get_id_encoded as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ } -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_set_int as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'     ,
+   cIntConv        `Int32'
+ }  -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_set_int_with_source as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'     ,
+   withCString*    `String'     ,
+   cIntConv        `Int32'
+ }  -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_set_str as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'     ,
+   withCString*    `String'
+ }  -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_set_str_with_source as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'     ,
+   withCString*    `String'     ,
+   withCString*    `String'
+ }  -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_remove as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'
+ }  -> `Result' takeResult* #}
+
+{# fun medialib_entry_property_remove_with_source as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'      ,
+   withCString*    `String'     ,
+   withCString*    `String'
+ }  -> `Result' takeResult* #}
+
+{# fun xform_media_browse as ^
+ { withConnection* `Connection' ,
+   withCString*    `String'
+ }  -> `Result' takeResult* #}
+
+
+{# fun broadcast_medialib_entry_changed as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
diff --git a/src/XMMS2/Client/Bindings/Playback.chs b/src/XMMS2/Client/Bindings/Playback.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Playback.chs
@@ -0,0 +1,127 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 1 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Playback
+  ( PlaybackStatus (..)
+  , SeekMode (..)
+  , playbackStop
+  , playbackTickle
+  , playbackStart
+  , playbackPause
+  , playbackCurrentId
+  , playbackSeekMs
+  , playbackSeekSamples
+  , playbackPlaytime
+  , playbackStatus
+  , playbackVolumeSet
+  , playbackVolumeGet
+  , broadcastPlaybackVolumeChanged
+  , broadcastPlaybackStatus
+  , broadcastPlaybackCurrentId
+  , signalPlaybackPlaytime
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsc" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Connection #}
+{# import XMMS2.Client.Bindings.Result #}
+
+
+{# enum xmms_playback_status_t as PlaybackStatus
+ { underscoreToCase }
+ with prefix = "XMMS_PLAYBACK_"
+ deriving (Eq, Show) #}
+
+{# enum xmms_playback_seek_mode_t as SeekMode
+ { underscoreToCase }
+ with prefix = "XMMS_PLAYBACK_"
+ deriving (Eq, Show) #}
+
+
+{# fun playback_stop as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_tickle as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_start as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_pause as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_current_id as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_seek_ms as ^
+ { withConnection* `Connection'
+ , cIntConv        `Int32'
+ , cFromEnum       `SeekMode'
+ } -> `Result' takeResult* #}
+
+{# fun playback_seek_samples as ^
+ { withConnection* `Connection'
+ , cIntConv        `Int32'
+ , cFromEnum       `SeekMode'
+ } -> `Result' takeResult* #}
+
+{# fun playback_playtime as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_status as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playback_volume_set as ^
+ { withConnection* `Connection'
+ , withCString*    `String'
+ , cIntConv        `Int'
+ } -> `Result' takeResult* #}
+
+{# fun playback_volume_get as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+
+{# fun broadcast_playback_volume_changed as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun broadcast_playback_status as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun broadcast_playback_current_id as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
+
+
+{# fun signal_playback_playtime as ^
+ { withConnection* `Connection'
+ } -> `Result' takeResult* #}
diff --git a/src/XMMS2/Client/Bindings/Playlist.chs b/src/XMMS2/Client/Bindings/Playlist.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Playlist.chs
@@ -0,0 +1,165 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 3 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Playlist
+  ( PlaylistChangedActions (..)
+  , playlistAddURL
+  , playlistAddId
+  , playlistAddEncoded
+  , playlistAddIdlist
+  , playlistAddCollection
+  , playlistRemoveEntry
+  , playlistClear
+  , playlistListEntries
+  , playlistSetNext
+  , playlistSetNextRel
+  , playlistMoveEntry
+  , playlistCurrentPos
+  , playlistCurrentActive
+  , playlistInsertId
+  , playlistRAdd
+  , playlistRAddEncoded
+  , broadcastPlaylistChanged
+  , broadcastPlaylistCurrentPos
+  , broadcastPlaylistLoaded
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsc" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+{# import XMMS2.Client.Bindings.Types.Coll #}
+{# import XMMS2.Client.Bindings.Connection #}
+{# import XMMS2.Client.Bindings.Result #}
+{# import XMMS2.Client.Bindings.Coll #}
+
+
+{# enum xmms_playlist_changed_actions_t as PlaylistChangedActions
+ { underscoreToCase
+ } with prefix = "XMMS_"
+ deriving (Eq, Show) #}
+
+
+{# fun playlist_add_url as playlistAddURL
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String' ,
+   withCString*      `String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_add_id as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , cIntConv          `Int32'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_add_encoded as ^
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String' ,
+   withCString*      `String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_add_idlist as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , withColl*         `Coll'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_add_collection as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , withColl*         `Coll'
+ , withValue*        `Value'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_remove_entry as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , cIntConv          `Int'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_clear as ^
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_list_entries as ^
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_set_next as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_set_next_rel as ^
+ { withConnection* `Connection' ,
+   cIntConv        `Int32'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_move_entry as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , cIntConv          `Int'
+ , cIntConv          `Int'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_current_pos as ^
+ { withConnection*   `Connection' ,
+   withMaybeCString* `Maybe String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_current_active as ^
+ { withConnection*   `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_insert_id as ^
+ { withConnection*   `Connection'
+ , withMaybeCString* `Maybe String'
+ , cIntConv          `Int'
+ , cIntConv          `Int32'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_radd as playlistRAdd
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String' ,
+   withCString*      `String'
+ } -> `Result' takeResult* #}
+
+{# fun playlist_radd_encoded as playlistRAddEncoded
+ { withConnection*   `Connection'   ,
+   withMaybeCString* `Maybe String' ,
+   withCString*      `String'
+ } -> `Result' takeResult* #}
+
+
+{# fun broadcast_playlist_changed as ^
+ { withConnection*   `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun broadcast_playlist_current_pos as ^
+ { withConnection*   `Connection'
+ } -> `Result' takeResult* #}
+
+{# fun broadcast_playlist_loaded as ^
+ { withConnection*   `Connection'
+ } -> `Result' takeResult* #}
diff --git a/src/XMMS2/Client/Bindings/Result.chs b/src/XMMS2/Client/Bindings/Result.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Result.chs
@@ -0,0 +1,84 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 1 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Result
+  ( Result
+  , ResultPtr
+  , withResult
+  , takeResult
+  , resultWait
+  , resultGetValue
+  , resultNotifierSet
+  , resultCallbackSet
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+#include <xmms2hs-client.h>
+
+{# context prefix = "xmmsc" #}
+
+import Control.Applicative
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+
+
+data T = T
+{# pointer *result_t as ResultPtr -> T #}
+data Result = Result (ForeignPtr T)
+
+withResult (Result p) = withForeignPtr p
+
+takeResult = takePtr Result xmmsc_result_unref
+
+foreign import ccall unsafe "&xmmsc_result_unref"
+  xmmsc_result_unref :: FunPtr (ResultPtr -> IO ())
+
+
+resultGetValue :: Result -> IO Value
+resultGetValue r = result_get_value r >>= takeValue True
+{# fun result_get_value as result_get_value
+ { withResult* `Result'
+ } -> `ValuePtr' id #}
+
+{# fun result_wait as ^
+ { withResult* `Result'
+ } -> `()' #}
+
+resultNotifierSet :: Result -> (Value -> IO Bool) -> IO ()
+resultNotifierSet r f =
+  xmms2hs_result_notifier_set r
+    =<< (mkNotifierPtr $ \p _ ->
+          fromBool <$> (f =<< takeValue True p))
+
+resultCallbackSet :: IO Result -> (Value -> IO Bool) -> IO ()
+resultCallbackSet r f =
+  (flip resultNotifierSet) f =<< r
+
+type NotifierFun = ValuePtr -> Ptr () -> IO CInt
+type NotifierPtr = FunPtr NotifierFun
+
+{# fun xmms2hs_result_notifier_set as xmms2hs_result_notifier_set
+ { withResult* `Result'
+ , id          `NotifierPtr'
+ } -> `()' #}
+
+foreign import ccall "wrapper"
+  mkNotifierPtr :: NotifierFun -> IO NotifierPtr
diff --git a/src/XMMS2/Client/Bindings/Stats.chs b/src/XMMS2/Client/Bindings/Stats.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Stats.chs
@@ -0,0 +1,48 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 18 Oct. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Stats
+  ( PluginType (..)
+  , pluginList
+  , mainListPlugins
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsc" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Connection #}
+{# import XMMS2.Client.Bindings.Result #}
+
+
+{# enum xmms_plugin_type_t as PluginType
+ { underscoreToCase }
+ with prefix = "XMMS_"
+ deriving (Show) #}
+
+
+{-# DEPRECATED pluginList "Use mainListPlugins" #-}
+pluginList = mainListPlugins
+
+{# fun main_list_plugins as ^
+ { withConnection* `Connection'
+ , cFromEnum       `PluginType'
+ } -> `Result' takeResult* #}
diff --git a/src/XMMS2/Client/Bindings/Types.hs b/src/XMMS2/Client/Bindings/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types.hs
@@ -0,0 +1,33 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 14 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Types
+  ( module XMMS2.Client.Bindings.Types.Value
+  , module XMMS2.Client.Bindings.Types.Coll
+  , module XMMS2.Client.Bindings.Types.Bin
+  , module XMMS2.Client.Bindings.Types.List
+  , module XMMS2.Client.Bindings.Types.Dict
+  ) where
+
+import XMMS2.Client.Bindings.Types.Value hiding (ValuePtr, get, raiseGetError)
+import XMMS2.Client.Bindings.Types.Coll hiding (CollPtr)
+import XMMS2.Client.Bindings.Types.Bin
+import XMMS2.Client.Bindings.Types.List
+import XMMS2.Client.Bindings.Types.Dict
+
diff --git a/src/XMMS2/Client/Bindings/Types/Bin.chs b/src/XMMS2/Client/Bindings/Types/Bin.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types/Bin.chs
@@ -0,0 +1,62 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Types.Bin
+  ( Bin
+  , withBin
+  , makeBin
+  , getBin
+  , newBin
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsv" #}
+
+import XMMS2.Utils
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+
+
+data Bin = Bin (Maybe Value) CUInt (ForeignPtr CUChar)
+
+withBin (Bin _ len ptr) f =
+  withForeignPtr ptr $ (flip f) len . castPtr
+
+makeBin len =
+  takePtr (Bin Nothing len) finalizerFree
+    =<< mallocArray (fromIntegral len)
+
+
+getBin v = do
+  (ok, ptr, len) <- get_bin v
+  if ok
+     then takePtr_ (Bin (Just v) len) ptr
+     else raiseGetError TypeBin v
+{# fun get_bin as get_bin
+ { withValue* `Value'
+ , alloca-    `Ptr CUChar' peek*
+ , alloca-    `CUInt'      peek*
+ } -> `Bool' #}
+
+newBin = (flip withBin) (\ptr len -> new_bin ptr len >>= takeValue True)
+{# fun new_bin as new_bin
+ { id `Ptr CUChar'
+ , id `CUInt'
+ } -> `ValuePtr' id #}
diff --git a/src/XMMS2/Client/Bindings/Types/Coll.chs b/src/XMMS2/Client/Bindings/Types/Coll.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types/Coll.chs
@@ -0,0 +1,144 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 14 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+{-# OPTIONS_GHC -fno-warn-overlapping-patterns #-}
+
+module XMMS2.Client.Bindings.Types.Coll
+  ( CollPtr
+  , Coll
+  , withColl
+  , takeColl
+  , getColl
+  , newColl
+  , CollType
+    ( TypeReference
+    , TypeUnion
+    , TypeIntersection
+    , TypeComplement
+    , TypeHas
+    , TypeEquals
+    , TypeMatch
+    , TypeSmaller
+    , TypeGreater
+    , TypeIdlist
+    , TypeQueue
+    , TypePartyshuffle )
+  , collNew
+  , collSetIdlist
+  , collAddOperand
+  , collIdlistAppend
+  , collUniverse
+  , collParse
+  , collNewIdlist
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsv" #}
+
+import XMMS2.Utils
+import XMMS2.Client.Exception
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+
+
+data T = T
+{# pointer *coll_t as CollPtr -> T #}
+data Coll = Coll (ForeignPtr T)
+
+withColl (Coll p) = withForeignPtr p
+
+takeColl ref p = do
+  p' <- if ref then coll_ref p else return p
+  takePtr Coll coll_unref p'
+
+{# fun coll_ref as coll_ref
+ { id `CollPtr'
+ } -> `CollPtr' id #}
+
+foreign import ccall unsafe "&xmmsv_coll_unref"
+  coll_unref :: FinalizerPtr T
+
+
+getColl v = get TypeColl get_coll (takeColl True) v
+{# fun get_coll as get_coll
+ { withValue* `Value'
+ , alloca-    `CollPtr' peek*
+ } -> `Bool' #}
+
+newColl v = new_coll v >>= takeValue False
+{# fun new_coll as new_coll
+ { withColl* `Coll'
+ } -> `ValuePtr' id #}
+
+
+{# enum coll_type_t as CollType
+ { underscoreToCase }
+ with prefix = "XMMS_COLLECTION"
+ deriving (Show) #}
+
+
+collNew :: CollType -> IO Coll
+collNew t = coll_new t >>= takeColl False
+{# fun coll_new as coll_new
+ { cFromEnum `CollType'
+ } -> `CollPtr' id #}
+
+collSetIdlist :: Coll -> [Int32] -> IO ()
+collSetIdlist c i = coll_set_idlist c $ map fromIntegral i
+{# fun coll_set_idlist as coll_set_idlist
+ { withColl*    `Coll'
+ , withZTArray* `[CUInt]'
+ } -> `()' #}
+
+{# fun coll_add_operand as ^
+ { withColl* `Coll'
+ , withColl* `Coll'
+ } -> `()' #}
+
+collIdlistAppend :: Coll -> Int32 -> IO ()
+collIdlistAppend coll id = coll_idlist_append coll $ fromIntegral id
+{# fun coll_idlist_append as coll_idlist_append
+ { withColl* `Coll'
+ , cIntConv  `CUInt'
+ } -> `()' #}
+
+collUniverse :: IO Coll
+collUniverse = coll_universe >>= takeColl True
+{# fun coll_universe as coll_universe
+ {} -> `CollPtr' id #}
+
+
+collParse :: String -> IO Coll
+collParse s = do
+  (ok, coll) <- coll_parse s
+  if ok
+    then takeColl False coll
+    else throwIO ParseError
+{# fun coll_parse as coll_parse
+ { withCString* `String'
+ , alloca-      `CollPtr' peek*
+ } -> `Bool' #}
+
+
+
+collNewIdlist list = do
+  c <- collNew TypeIdlist
+  collSetIdlist c list
+  return c
diff --git a/src/XMMS2/Client/Bindings/Types/Dict.chs b/src/XMMS2/Client/Bindings/Types/Dict.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types/Dict.chs
@@ -0,0 +1,122 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 14 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Types.Dict
+  ( newDict
+  , dictSet
+  , DictIter
+  , getDictIter
+  , dictIterValid
+  , dictIterPair
+  , dictIterNext
+  , dictForeach
+  , propdictToDict
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+#include <xmms2hs-client.h>
+
+{# context prefix = "xmmsv" #}
+
+import Control.Applicative
+import Control.Monad
+
+import XMMS2.Utils
+import XMMS2.Client.Exception
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+
+
+newDict = new_dict >>= takeValue False
+{# fun new_dict as new_dict
+ {} -> `ValuePtr' id #}
+
+{# fun dict_set as ^
+ { withValue*   `Value'
+ , withCString* `String'
+ , withValue*   `Value'
+ } -> `Int' #}
+
+
+data T = T
+{# pointer *xmms2hs_dict_iter_t as DictIterPtr -> T #}
+data DictIter = DictIter (ForeignPtr T)
+
+withDictIter (DictIter p) f =
+  withForeignPtr p $ \p -> {# get xmms2hs_dict_iter_t->iter #} p >>= f
+
+getDictIter :: Value -> IO DictIter
+getDictIter = get TypeDict get_dict_iter (takePtr DictIter finalize_dict_iter)
+{# fun xmms2hs_get_dict_iter as get_dict_iter
+ { withValue* `Value'
+ , alloca-    `DictIterPtr' peek*
+ } -> `Bool' #}
+
+foreign import ccall unsafe "&xmms2hs_finalize_dict_iter"
+  finalize_dict_iter :: FinalizerPtr T
+
+
+dictIterPair :: DictIter -> IO (String, Value)
+dictIterPair iter = do
+  (ok, key, val) <- dict_iter_pair iter
+  unless ok $ throwIO $ InvalidIter
+  (,) <$> peekCString key <*> takeValue True val
+{# fun dict_iter_pair as dict_iter_pair
+ { withDictIter* `DictIter'
+ , alloca-       `CString'  peek*
+ , alloca-       `ValuePtr' peek*
+ } -> `Bool' #}
+
+{# fun dict_iter_valid as ^
+ { withDictIter* `DictIter'
+ } -> `Bool' #}
+
+{# fun dict_iter_next as ^
+ { withDictIter* `DictIter'
+ } -> `()' #}
+
+
+type DictForeachFun a = CString -> ValuePtr -> Ptr () -> IO ()
+type DictForeachPtr a = FunPtr (DictForeachFun a)
+
+dictForeach :: (String -> Value -> IO ()) -> Value -> IO ()
+dictForeach f d = do
+  f' <- mkDictForeachPtr $
+        \s v _ -> do
+          s' <- peekCString s
+          v' <- takeValue True v
+          f s' v'
+  dict_foreach d f' nullPtr
+  freeHaskellFunPtr f'
+{# fun dict_foreach as dict_foreach
+ { withValue* `Value'
+ , id         `DictForeachPtr a'
+ , id         `Ptr ()'
+ } -> `()' #}
+
+foreign import ccall "wrapper"
+  mkDictForeachPtr :: DictForeachFun a -> IO (DictForeachPtr a)
+
+
+propdictToDict :: Value -> [String] -> IO Value
+propdictToDict v p = propdict_to_dict v p >>= takeValue False
+{# fun propdict_to_dict as propdict_to_dict
+ { withValue*         `Value'
+ , withCStringArray0* `[String]'
+ } -> `ValuePtr' id #}
diff --git a/src/XMMS2/Client/Bindings/Types/List.chs b/src/XMMS2/Client/Bindings/Types/List.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types/List.chs
@@ -0,0 +1,98 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 14 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Types.List
+  ( newList
+  , listGetSize
+  , listGet
+  , listAppend
+  , ListIter
+  , getListIter
+  , listIterValid
+  , listIterEntry
+  , listIterNext
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+#include <xmms2hs-client.h>
+
+{# context prefix = "xmmsv" #}
+
+import Control.Monad
+
+import XMMS2.Utils
+import XMMS2.Client.Exception
+
+{# import XMMS2.Client.Bindings.Types.Value #}
+
+
+newList = new_list >>= takeValue False
+{# fun new_list as new_list
+ {} -> `ValuePtr' id #}
+
+{# fun list_get_size as ^
+ { withValue* `Value'
+ } -> `Integer' cIntConv #}
+
+listGet l p = get TypeList ((flip list_get) p) (takeValue True) l
+{# fun list_get as list_get
+ { withValue* `Value'
+ , cIntConv   `Integer'
+ , alloca-    `ValuePtr' peek*
+ } -> `Bool' #}
+
+{#fun list_append as ^
+ { withValue* `Value'
+ , withValue* `Value'
+ } -> `Int' #}
+
+
+data T = T
+{# pointer *list_iter_t as ListIterPtr -> T #}
+data ListIter = ListIter (ForeignPtr T)
+
+withListIter (ListIter p) = withForeignPtr p
+
+getListIter :: Value -> IO ListIter
+getListIter = get TypeList get_list_iter (takePtr ListIter finalize_list_iter)
+{# fun xmms2hs_get_list_iter as get_list_iter
+ { withValue* `Value'
+ , alloca-    `ListIterPtr' peek*
+ } -> `Bool' #}
+
+foreign import ccall unsafe "&xmms2hs_finalize_list_iter"
+  finalize_list_iter :: FinalizerPtr T
+
+
+listIterEntry iter = do
+  (ok, v') <- list_iter_entry iter
+  unless ok $ throwIO InvalidIter
+  takeValue True v'
+{# fun list_iter_entry as list_iter_entry
+ { withListIter* `ListIter'
+ , alloca-       `ValuePtr' peek*
+ } -> `Bool' #}
+
+{# fun list_iter_valid as ^
+ { withListIter* `ListIter'
+ } -> `Bool' #}
+
+{# fun list_iter_next as ^
+ { withListIter* `ListIter'
+ } -> `()' #}
diff --git a/src/XMMS2/Client/Bindings/Types/Value.chs b/src/XMMS2/Client/Bindings/Types/Value.chs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Bindings/Types/Value.chs
@@ -0,0 +1,141 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 5 Oct. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Bindings.Types.Value
+  ( ValueType
+    ( TypeNone
+    , TypeError
+    , TypeInt32
+    , TypeString
+    , TypeColl
+    , TypeBin
+    , TypeList
+    , TypeDict )
+  , ValuePtr
+  , Value
+  , Int32
+  , withValue
+  , takeValue
+  , refValue
+  , getType
+  , getError
+  , getNone
+  , newNone
+  , getInt
+  , newInt
+  , getString
+  , newString
+  , get
+  , raiseGetError
+  ) where
+
+#include <xmmsclient/xmmsclient.h>
+
+{# context prefix = "xmmsv" #}
+
+import Control.Applicative
+
+import Data.Maybe
+
+import XMMS2.Utils
+import XMMS2.Client.Exception
+
+
+data T = T
+{# pointer *t as ValuePtr -> T #}
+data Value = Value (ForeignPtr T)
+
+withValue (Value p) = withForeignPtr p
+
+takeValue ref p = do
+  p' <- if ref then xmmsv_ref p else return p
+  takePtr Value xmmsv_unref p'
+
+{# fun xmmsv_ref as xmmsv_ref
+ { id `ValuePtr'
+ } -> `ValuePtr' id #}
+
+foreign import ccall unsafe "&xmmsv_unref"
+  xmmsv_unref :: FunPtr (ValuePtr -> IO ())
+
+refValue :: Value -> IO Value
+refValue val = withValue val $ takeValue True
+
+
+{# enum type_t as ValueType
+ { underscoreToCase }
+ deriving (Show) #}
+
+{# fun get_type as ^
+ { withValue* `Value'
+ } -> `ValueType' cToEnum #}
+
+
+getError value = do
+  (ok, err) <- get_error value
+  if ok
+    then Just <$> peekCString err
+    else return Nothing
+{# fun get_error as get_error
+ { withValue* `Value'
+ , alloca-    `CString' peek*
+ } -> `Bool' #}
+
+getNone = get TypeNone (const $ return (True, ())) return
+
+newNone = new_none >>= takeValue False
+{# fun new_none as new_none
+ {} -> `ValuePtr' id #}
+
+getInt = get TypeInt32 get_int return
+{# fun get_int as get_int
+ { withValue* `Value'
+ , alloca-    `Int32' peekIntConv*
+ } -> `Bool' #}
+
+newInt val = new_int val >>= takeValue False
+{# fun new_int as new_int
+ { cIntConv `Int32'
+ } -> `ValuePtr' id #}
+
+getString = get TypeString get_string peekCString
+{# fun get_string as get_string
+ { withValue* `Value'
+ , alloca-    `CString' peek*
+ } -> `Bool' #}
+
+newString val = new_string val >>= takeValue False
+{# fun new_string as new_string
+ { withCString* `String'
+ } -> `ValuePtr' id #}
+
+
+get t f c v = do
+  (ok, v') <- f v
+  if ok
+    then c v'
+    else raiseGetError t v
+
+raiseGetError t v = do
+  t' <- getType v
+  case t' of
+    TypeError -> do
+      throwIO . XMMSError . fromJust =<< getError v
+    _         ->
+      fail $ "type mismatch: want " ++ show t ++ ", got " ++ show t'
diff --git a/src/XMMS2/Client/Coll.hs b/src/XMMS2/Client/Coll.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Coll.hs
@@ -0,0 +1,125 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Coll
+  ( CollectionChangedActions (..)
+  , CollectionChange (..)
+  , collGet
+  , collList
+  , collSave
+  , collRemove
+  , collRename
+  , collIdlistFromPlaylistFile
+  , collSync
+  , collQueryIds
+  , broadcastCollectionChanged
+  ) where
+
+import Control.Applicative
+
+import XMMS2.Client.Types
+import XMMS2.Client.Result
+
+import XMMS2.Client.Bindings.Connection
+import XMMS2.Client.Bindings.Coll (CollectionChangedActions (..))
+import qualified XMMS2.Client.Bindings.Coll as B
+
+
+data CollectionChange
+  = CollectionAdd
+    { namespace :: String
+    , name      :: String }
+  | CollectionUpdate
+    { namespace :: String
+    , name      :: String }
+  | CollectionRename
+    { namespace :: String
+    , name      :: String
+    , newName   :: String }
+  | CollectionRemove
+    { namespace :: String
+    , name      :: String }
+  deriving (Show)
+
+instance ValueGet CollectionChange where
+  valueGet v = do
+    dict <- valueGet v
+    maybe (fail "not a collection change notification") return $ do
+      namespace <- lookupString "namespace" dict
+      name      <- lookupString "name" dict
+      action    <- (toEnum . fromIntegral) <$> lookupInt32 "type" dict
+      case action of
+        CollectionChangedAdd    ->
+          return CollectionAdd { namespace = namespace
+                               , name      = name }
+        CollectionChangedUpdate ->
+          return CollectionUpdate { namespace = namespace
+                                  , name      = name }
+        CollectionChangedRename -> do
+          newName <- lookupString "newname" dict
+          return CollectionRename { namespace = namespace
+                                  , name      = name
+                                  , newName   = newName }
+        CollectionChangedRemove ->
+          return CollectionRemove { namespace = namespace
+                                  , name      = name }
+
+
+collGet :: Connection -> String -> String -> IO (Result Coll)
+collGet xmmsc name ns =
+  liftResult $ B.collGet xmmsc name ns
+
+collList :: Connection -> String -> IO (Result [String])
+collList xmmsc ns =
+  liftResult $ B.collList xmmsc ns
+
+collSave :: Connection -> Coll -> String -> String -> IO (Result ())
+collSave xmmsc coll name ns =
+  liftResult $ B.collSave xmmsc coll name ns
+
+collRemove :: Connection -> String -> String -> IO (Result ())
+collRemove xmmsc name ns =
+  liftResult $ B.collRemove xmmsc name ns
+
+collRename :: Connection -> String -> String -> String -> IO (Result ())
+collRename xmmsc from to ns =
+  liftResult $ B.collRename xmmsc from to ns
+
+collIdlistFromPlaylistFile :: Connection -> String -> IO (Result Coll)
+collIdlistFromPlaylistFile xmmsc file =
+  liftResult $ B.collIdlistFromPlaylistFile xmmsc file
+
+collSync :: Connection -> IO (Result ())
+collSync xmmsc =
+  liftResult $ B.collSync xmmsc
+
+collQueryIds ::
+  Connection ->
+  Coll       ->
+  [String]   ->
+  Int        ->
+  Int        ->
+  IO (Result [Int32])
+collQueryIds xmmsc coll order start len = do
+  order' <- valueNew order
+  liftResult $ B.collQueryIds xmmsc coll order' start len
+
+
+broadcastCollectionChanged :: Connection -> IO (Result CollectionChange)
+broadcastCollectionChanged = liftResult . B.broadcastCollectionChanged
diff --git a/src/XMMS2/Client/Connection.hs b/src/XMMS2/Client/Connection.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Connection.hs
@@ -0,0 +1,24 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Connection
+  ( module XMMS2.Client.Bindings.Connection
+  ) where
+
+import XMMS2.Client.Bindings.Connection
diff --git a/src/XMMS2/Client/Exception.hs b/src/XMMS2/Client/Exception.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Exception.hs
@@ -0,0 +1,37 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 5 Oct. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Exception
+  ( XMMSException (..)
+  , throwIO
+  ) where
+
+import Control.Exception
+import Data.Typeable
+
+
+data XMMSException
+  = XMMSError String
+  | ConnectionInitFailed
+  | InvalidIter
+  | ParseError
+    deriving (Typeable, Show)
+
+instance Exception XMMSException
+
diff --git a/src/XMMS2/Client/Medialib.hs b/src/XMMS2/Client/Medialib.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Medialib.hs
@@ -0,0 +1,115 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Medialib
+  ( BrowseEntry (..)
+  , medialibAddEntry
+  , medialibAddEntryFull
+  , medialibAddEntryEncoded
+  , medialibGetInfo
+  , medialibGetId
+  , medialibGetIdEncoded
+  , medialibEntryPropertySet
+  , medialibEntryPropertyRemove
+  , xformMediaBrowse
+  , broadcastMedialibEntryChanged
+  ) where
+
+import Control.Applicative
+import Control.Monad
+
+import XMMS2.Client.Types
+import XMMS2.Client.Result
+
+import XMMS2.Client.Bindings.Connection
+import qualified XMMS2.Client.Bindings.Medialib as B
+
+
+data BrowseEntry
+  = BrowseEntry { entryPath  :: String
+                , entryIsDir :: Bool }
+
+instance ValueGet BrowseEntry where
+  valueGet v = do
+    dict <- valueGet v
+    maybe (fail "not a browse entry") return $ do
+      path <- lookupString "realpath" dict `mplus` lookupString "path" dict
+      dirp <- (1 ==) <$> lookupInt32 "isdir" dict
+      return BrowseEntry { entryPath = path, entryIsDir = dirp }
+
+
+medialibAddEntry :: Connection -> String -> IO (Result ())
+medialibAddEntry xmmsc url =
+  liftResult $ B.medialibAddEntry xmmsc url
+
+medialibAddEntryFull :: Connection -> String -> [String] -> IO (Result ())
+medialibAddEntryFull xmmsc url args =
+  liftResult $ B.medialibAddEntryFull xmmsc url =<< valueNew args
+
+medialibAddEntryEncoded :: Connection -> String -> IO (Result ())
+medialibAddEntryEncoded xmmsc url =
+  liftResult $ B.medialibAddEntryEncoded xmmsc url
+
+medialibGetInfo :: Connection -> Int32 -> IO (Result PropDict)
+medialibGetInfo xmmsc id =
+  liftResult $ B.medialibGetInfo xmmsc id
+
+medialibGetId :: Connection -> String -> IO (Result Int32)
+medialibGetId xmmsc url =
+  liftResult $ B.medialibGetId xmmsc url
+
+medialibGetIdEncoded :: Connection -> String -> IO (Result Int32)
+medialibGetIdEncoded xmmsc url =
+  liftResult $ B.medialibGetIdEncoded xmmsc url
+
+medialibEntryPropertySet ::
+  Connection             ->
+  Int32                  ->
+  Maybe String           ->
+  String                 ->
+  Property               ->
+  IO (Result ())
+medialibEntryPropertySet xmmsc id (Just src) key (PropInt32 val) =
+  liftResult $ B.medialibEntryPropertySetIntWithSource xmmsc id src key val
+medialibEntryPropertySet xmmsc id Nothing key (PropInt32 val) =
+  liftResult $ B.medialibEntryPropertySetInt xmmsc id key val
+medialibEntryPropertySet xmmsc id (Just src) key (PropString val) =
+  liftResult $ B.medialibEntryPropertySetStrWithSource xmmsc id src key val
+medialibEntryPropertySet xmmsc id Nothing key (PropString val) =
+  liftResult $ B.medialibEntryPropertySetStr xmmsc id key val
+
+medialibEntryPropertyRemove ::
+  Connection                ->
+  Int32                     ->
+  Maybe String              ->
+  String                    ->
+  IO (Result ())
+medialibEntryPropertyRemove xmmsc id (Just src) key =
+  liftResult $ B.medialibEntryPropertyRemoveWithSource xmmsc id src key
+medialibEntryPropertyRemove xmmsc id Nothing key =
+  liftResult $ B.medialibEntryPropertyRemove xmmsc id key
+
+xformMediaBrowse :: Connection -> String -> IO (Result [BrowseEntry])
+xformMediaBrowse xmmsc url =
+  liftResult $ B.xformMediaBrowse xmmsc url
+
+
+broadcastMedialibEntryChanged :: Connection -> IO (Result Int32)
+broadcastMedialibEntryChanged =
+  liftResult . B.broadcastMedialibEntryChanged
diff --git a/src/XMMS2/Client/Playback.hs b/src/XMMS2/Client/Playback.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Playback.hs
@@ -0,0 +1,114 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Playback
+  ( PlaybackStatus (..)
+  , SeekMode (..)
+  , playbackStop
+  , playbackTickle
+  , playbackStart
+  , playbackPause
+  , playbackCurrentId
+  , playbackSeekMs
+  , playbackSeekSamples
+  , playbackPlaytime
+  , playbackStatus
+  , playbackVolumeSet
+  , playbackVolumeGet
+  , broadcastPlaybackVolumeChanged
+  , broadcastPlaybackStatus
+  , broadcastPlaybackCurrentId
+  , signalPlaybackPlaytime
+  ) where
+
+import Control.Applicative
+
+import XMMS2.Client.Types
+import XMMS2.Client.Result
+
+import XMMS2.Client.Bindings.Connection
+import XMMS2.Client.Bindings.Playback (PlaybackStatus (..), SeekMode (..))
+import qualified XMMS2.Client.Bindings.Playback as B
+
+
+instance ValueGet PlaybackStatus where
+  valueGet v = (toEnum . fromIntegral) <$> getInt v
+
+
+playbackStop :: Connection -> IO (Result ())
+playbackStop xmmsc =
+  liftResult $ B.playbackStop xmmsc
+
+playbackTickle :: Connection -> IO (Result ())
+playbackTickle xmmsc =
+  liftResult $ B.playbackTickle xmmsc
+
+playbackStart :: Connection -> IO (Result ())
+playbackStart xmmsc =
+  liftResult $ B.playbackStart xmmsc
+
+playbackPause :: Connection -> IO (Result ())
+playbackPause xmmsc =
+  liftResult $ B.playbackPause xmmsc
+
+playbackCurrentId :: Connection -> IO (Result Int32)
+playbackCurrentId xmmsc =
+  liftResult $ B.playbackCurrentId xmmsc
+
+playbackSeekMs :: Connection -> Int32 -> SeekMode -> IO (Result ())
+playbackSeekMs xmmsc pos whence
+  = liftResult $ B.playbackSeekMs xmmsc pos whence
+
+playbackSeekSamples :: Connection -> Int32 -> SeekMode -> IO (Result ())
+playbackSeekSamples xmmsc pos whence =
+  liftResult $ B.playbackSeekSamples xmmsc pos whence
+
+playbackPlaytime :: Connection -> IO (Result Int32)
+playbackPlaytime xmmsc =
+  liftResult $ B.playbackPlaytime xmmsc
+
+playbackStatus :: Connection -> IO (Result PlaybackStatus)
+playbackStatus xmmsc =
+  liftResult $ B.playbackStatus xmmsc
+
+playbackVolumeSet :: Connection -> String -> Int -> IO (Result ())
+playbackVolumeSet xmmsc chan vol =
+  liftResult $ B.playbackVolumeSet xmmsc chan vol
+
+playbackVolumeGet :: Connection -> IO (Result (Dict Int32))
+playbackVolumeGet xmmsc =
+  liftResult $ B.playbackVolumeGet xmmsc
+
+
+broadcastPlaybackVolumeChanged :: Connection -> IO (Result (Dict Int32))
+broadcastPlaybackVolumeChanged =
+  liftResult . B.broadcastPlaybackVolumeChanged
+
+broadcastPlaybackStatus :: Connection -> IO (Result PlaybackStatus)
+broadcastPlaybackStatus =
+  liftResult . B.broadcastPlaybackStatus
+
+broadcastPlaybackCurrentId :: Connection -> IO (Result Int32)
+broadcastPlaybackCurrentId =
+  liftResult . B.broadcastPlaybackCurrentId
+
+
+signalPlaybackPlaytime :: Connection -> IO (Result Int32)
+signalPlaybackPlaytime =
+  liftResult . B.signalPlaybackPlaytime
diff --git a/src/XMMS2/Client/Playlist.hs b/src/XMMS2/Client/Playlist.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Playlist.hs
@@ -0,0 +1,293 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Playlist
+  ( -- * Types
+    PlaylistChangedActions (..)
+  , PlaylistChange (..)
+  , PlaylistPosition
+
+    -- * Commands
+  , playlistAddURL
+  , playlistAddId
+  , playlistAddEncoded
+  , playlistAddIdlist
+  , playlistAddCollection
+  , playlistRemoveEntry
+  , playlistClear
+  , playlistListEntries
+  , playlistSetNext
+  , playlistSetNextRel
+  , playlistMoveEntry
+  , playlistCurrentPos
+  , playlistCurrentActive
+  , playlistInsertId
+  , playlistRAdd
+  , playlistRAddEncoded
+
+    -- * Broadcasts
+  , broadcastPlaylistChanged
+  , broadcastPlaylistCurrentPos
+  , broadcastPlaylistLoaded
+  ) where
+
+import Control.Applicative
+
+import XMMS2.Client.Types
+import XMMS2.Client.Result
+
+import XMMS2.Client.Bindings.Connection
+import XMMS2.Client.Bindings.Playlist (PlaylistChangedActions (..))
+import qualified XMMS2.Client.Bindings.Playlist as B
+
+
+--------
+-- Types
+
+data PlaylistChange
+  = PlaylistAdd
+    { playlist    :: String
+    , mlibId      :: MediaId
+    , position    :: Int }
+  | PlaylistInsert
+    { playlist    :: String
+    , mlibId      :: MediaId
+    , position    :: Int }
+  | PlaylistShuffle
+    { playlist    :: String }
+  | PlaylistRemove
+    { playlist    :: String
+    , position    :: Int }
+  | PlaylistClear
+    { playlist    :: String }
+  | PlaylistMove
+    { playlist    :: String
+    , mlibId      :: MediaId
+    , position    :: Int
+    , newPosition :: Int }
+  | PlaylistSort
+    { playlist    :: String }
+  | PlaylistUpdate
+    { playlist    :: String }
+  deriving (Show)
+
+instance ValueGet PlaylistChange where
+  valueGet v = do
+    dict <- valueGet v
+    let getMlibId      = lookupInt32 "id" dict
+        getPosition    = fromIntegral <$> lookupInt32 "position" dict
+        getNewPosition = fromIntegral <$> lookupInt32 "newposition" dict
+    maybe (fail "not a playlist change notification") return $ do
+      playlist <- lookupString "name" dict
+      action   <- (toEnum . fromIntegral) <$> lookupInt32 "type" dict
+      case action of
+        PlaylistChangedAdd -> do
+          mlibId   <- getMlibId
+          position <- getPosition
+          return PlaylistAdd { playlist = playlist
+                             , mlibId   = mlibId
+                             , position = position }
+        PlaylistChangedInsert -> do
+          mlibId   <- getMlibId
+          position <- getPosition
+          return PlaylistInsert { playlist = playlist
+                                , mlibId   = mlibId
+                                , position = position }
+        PlaylistChangedShuffle ->
+          return PlaylistShuffle { playlist = playlist }
+        PlaylistChangedRemove -> do
+          position <- getPosition
+          return PlaylistRemove { playlist = playlist
+                                , position = position }
+        PlaylistChangedClear ->
+          return PlaylistClear { playlist = playlist }
+        PlaylistChangedMove -> do
+          mlibId      <- getMlibId
+          position    <- getPosition
+          newPosition <- getNewPosition
+          return PlaylistMove { playlist    = playlist
+                              , mlibId      = mlibId
+                              , position    = position
+                              , newPosition = newPosition }
+        PlaylistChangedSort ->
+          return PlaylistSort { playlist = playlist }
+        PlaylistChangedUpdate ->
+          return PlaylistUpdate { playlist = playlist }
+
+
+type PlaylistPosition = (Int32, String)
+
+instance ValueGet PlaylistPosition where
+  valueGet v = do
+    dict <- valueGet v
+    maybe (fail "not a playlist position") return $
+      (,) <$> lookupInt32 "position" dict <*> lookupString "name" dict
+
+
+-----------
+-- Commands
+
+playlistAddURL
+  :: Connection
+  -> Maybe String
+  -> URL
+  -> IO (Result ())
+playlistAddURL xmmsc name url =
+  liftResult $ B.playlistAddURL xmmsc name url
+
+playlistAddId  ::
+  Connection   ->
+  Maybe String ->
+  MediaId      ->
+  IO (Result ())
+playlistAddId xmmsc name id =
+  liftResult $ B.playlistAddId xmmsc name id
+
+playlistAddEncoded ::
+  Connection       ->
+  Maybe String     ->
+  EncodedURL       ->
+  IO (Result ())
+playlistAddEncoded xmmsc name url =
+  liftResult $ B.playlistAddEncoded xmmsc name url
+
+playlistAddIdlist ::
+  Connection      ->
+  Maybe String    ->
+  Coll            ->
+  IO (Result ())
+playlistAddIdlist xmmsc name idlist =
+  liftResult $ B.playlistAddIdlist xmmsc name idlist
+
+playlistAddCollection ::
+  Connection          ->
+  Maybe String        ->
+  Coll                ->
+  [String]            ->
+  IO (Result ())
+playlistAddCollection xmmsc name coll order =
+  liftResult $ B.playlistAddCollection xmmsc name coll =<< newList order
+
+playlistRemoveEntry ::
+  Connection        ->
+  Maybe String      ->
+  Int               ->
+  IO (Result ())
+playlistRemoveEntry xmmsc name num =
+  liftResult $ B.playlistRemoveEntry xmmsc name num
+
+playlistClear  ::
+  Connection   ->
+  Maybe String ->
+  IO (Result ())
+playlistClear xmmsc name =
+  liftResult $ B.playlistClear xmmsc name
+
+playlistListEntries ::
+  Connection        ->
+  Maybe String      ->
+  IO (Result [MediaId])
+playlistListEntries xmmsc name =
+  liftResult $ B.playlistListEntries xmmsc name
+
+playlistSetNext ::
+  Connection    ->
+  Int32         ->
+  IO (Result ())
+playlistSetNext xmmsc num =
+  liftResult $ B.playlistSetNext xmmsc num
+
+playlistSetNextRel ::
+  Connection       ->
+  Int32            ->
+  IO (Result ())
+playlistSetNextRel xmmsc num =
+  liftResult $ B.playlistSetNextRel xmmsc num
+
+-- | Move a playlist entry to a new position. Both positions are
+-- absolute.
+playlistMoveEntry
+  :: Connection
+  -> Maybe String
+  -> Int
+  -> Int
+  -> IO (Result ())
+playlistMoveEntry xmmsc name from to =
+  liftResult $ B.playlistMoveEntry xmmsc name from to
+
+playlistCurrentPos ::
+  Connection       ->
+  Maybe String     ->
+  IO (Result PlaylistPosition)
+playlistCurrentPos xmmsc name =
+  liftResult $ B.playlistCurrentPos xmmsc name
+
+-- | Retrieve the name of the active playlist.
+playlistCurrentActive ::
+  Connection          ->
+  IO (Result String)
+playlistCurrentActive xmmsc =
+  liftResult $ B.playlistCurrentActive xmmsc
+
+playlistInsertId ::
+  Connection     ->
+  Maybe String   ->
+  Int            ->
+  MediaId        ->
+  IO (Result ())
+playlistInsertId xmmsc name pos id =
+  liftResult $ B.playlistInsertId xmmsc name pos id
+
+playlistRAdd   ::
+  Connection   ->
+  Maybe String ->
+  URL          ->
+  IO (Result ())
+playlistRAdd xmmsc name url =
+  liftResult $ B.playlistRAdd xmmsc name url
+
+playlistRAddEncoded ::
+  Connection        ->
+  Maybe String      ->
+  EncodedURL        ->
+  IO (Result ())
+playlistRAddEncoded xmmsc name url =
+  liftResult $ B.playlistRAddEncoded xmmsc name url
+
+
+-------------
+-- Broadcasts
+
+broadcastPlaylistChanged ::
+  Connection             ->
+  IO (Result PlaylistChange)
+broadcastPlaylistChanged =
+  liftResult . B.broadcastPlaylistChanged
+
+broadcastPlaylistCurrentPos ::
+  Connection                ->
+  IO (Result ())
+broadcastPlaylistCurrentPos =
+  liftResult . B.broadcastPlaylistCurrentPos
+
+broadcastPlaylistLoaded ::
+  Connection            ->
+  IO (Result String)
+broadcastPlaylistLoaded =
+  liftResult . B.broadcastPlaylistLoaded
diff --git a/src/XMMS2/Client/Result.hs b/src/XMMS2/Client/Result.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Result.hs
@@ -0,0 +1,75 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Result
+  ( Result
+  , liftResult
+  , resultWait
+  , resultGetValue
+  , ResultM
+  , resultRawValue
+  , result
+  , resultLength
+  , (>>*)
+  ) where
+
+import Control.Applicative
+import Control.Monad.Trans
+import Control.Monad.Reader
+import Control.Monad.ToIO
+
+import XMMS2.Client.Types
+
+import XMMS2.Client.Bindings.Types
+import qualified XMMS2.Client.Bindings.Result as B
+
+
+newtype Result a = Result B.Result
+
+liftResult = (return . Result =<<)
+
+
+resultWait (Result r) = B.resultWait r
+
+resultGetValue (Result r) = B.resultGetValue r
+
+
+newtype RVC a = RVC { value :: Value }
+
+type ResultM m a b = ReaderT (RVC a) m b
+
+runResultM :: (MonadIO m, MonadToIO m) => ResultM m a b -> Value -> m b
+runResultM f v = runReaderT f $ RVC v
+
+
+resultRawValue :: (ValueGet a, MonadIO m, MonadToIO m) => ResultM m a Value
+resultRawValue = value <$> ask
+
+result :: (ValueGet a, MonadIO m, MonadToIO m) => ResultM m a a
+result = resultRawValue >>= liftIO . valueGet
+
+resultLength :: (ValueGet a, ValueGet [a], MonadIO m, MonadToIO m) => ResultM m [a] Integer
+resultLength = resultRawValue >>= liftIO . listGetSize
+
+
+(>>*) :: (ValueGet a, MonadIO m, MonadToIO m) => m (Result a) -> ResultM m a Bool -> m ()
+f >>* h = do
+  (Result result)  <- f
+  wrapper          <- toIO
+  liftIO $ B.resultNotifierSet result $ \v -> wrapper (runResultM h v)
diff --git a/src/XMMS2/Client/Stats.hs b/src/XMMS2/Client/Stats.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Stats.hs
@@ -0,0 +1,39 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Stats
+  ( PluginType (..)
+  , pluginList
+  , mainListPlugins
+  ) where
+
+import XMMS2.Client.Types
+import XMMS2.Client.Result
+
+import XMMS2.Client.Bindings.Connection
+import XMMS2.Client.Bindings.Stats (PluginType (..))
+import qualified XMMS2.Client.Bindings.Stats as B
+
+
+{-# DEPRECATED pluginList "Use mainListPlugins" #-}
+pluginList = mainListPlugins
+
+mainListPlugins :: Connection -> PluginType -> IO (Result [Dict Data])
+mainListPlugins xmmsc ptype =
+  liftResult $ B.mainListPlugins xmmsc ptype
diff --git a/src/XMMS2/Client/Types.hs b/src/XMMS2/Client/Types.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types.hs
@@ -0,0 +1,54 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types
+  ( module XMMS2.Client.Types.Value
+  , module XMMS2.Client.Types.List
+  , module XMMS2.Client.Types.Coll
+  , module XMMS2.Client.Types.Bin
+  , module XMMS2.Client.Types.Dict
+  , module XMMS2.Client.Types.Property
+  , module XMMS2.Client.Types.Data
+    -- * Types
+  , MediaId
+  , URL
+  , EncodedURL
+  ) where
+
+import XMMS2.Client.Types.Value
+import XMMS2.Client.Types.Coll
+import XMMS2.Client.Types.Bin
+import XMMS2.Client.Types.List
+import XMMS2.Client.Types.Dict
+import XMMS2.Client.Types.Property
+import XMMS2.Client.Types.Data
+
+
+--------
+-- Types
+
+-- | A Medialib entry identifier.
+type MediaId = Int32
+
+-- | A 'String' identifying a resource (media file, playlist etc.)
+-- from XMMS2 daemon's point of view.
+type URL = String
+
+-- | Same as 'URL', but encoded in XMMS2 specific format.
+type EncodedURL = String
diff --git a/src/XMMS2/Client/Types/Bin.hs b/src/XMMS2/Client/Types/Bin.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Bin.hs
@@ -0,0 +1,38 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.Bin
+  ( module XMMS2.Client.Bindings.Types.Bin
+  ) where
+
+import XMMS2.Client.Types.Value
+
+import XMMS2.Client.Bindings.Types.Bin
+  ( Bin
+  , withBin
+  , makeBin
+  , getBin
+  , newBin )
+
+
+instance ValueGet Bin where
+  valueGet = getBin
+
+instance ValueNew Bin where
+  valueNew = newBin
diff --git a/src/XMMS2/Client/Types/Coll.hs b/src/XMMS2/Client/Types/Coll.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Coll.hs
@@ -0,0 +1,44 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.Coll
+  ( module XMMS2.Client.Bindings.Types.Coll
+  ) where
+
+import XMMS2.Client.Types.Value
+
+import XMMS2.Client.Bindings.Types.Coll
+  ( Coll
+  , CollType (..)
+  , getColl
+  , newColl
+  , collNew
+  , collSetIdlist
+  , collAddOperand
+  , collIdlistAppend
+  , collUniverse
+  , collParse
+  , collNewIdlist )
+
+
+instance ValueGet Coll where
+  valueGet = getColl
+
+instance ValueNew Coll where
+  valueNew = newColl
diff --git a/src/XMMS2/Client/Types/Data.hs b/src/XMMS2/Client/Types/Data.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Data.hs
@@ -0,0 +1,122 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.Data
+  ( Data
+  , mkData
+  , dataInt32
+  , dataString
+  , dataColl
+  , dataBin
+  , dataList
+  , dataDict
+  , lookupInt32
+  , lookupString
+  , lookupColl
+  , lookupBin
+  , lookupList
+  , lookupDict
+  ) where
+
+import Control.Applicative
+--import Control.Monad.Trans
+
+import Data.Maybe
+import qualified Data.Map as Map
+
+import XMMS2.Client.Exception
+
+import XMMS2.Client.Types.Value
+import XMMS2.Client.Types.Coll
+import XMMS2.Client.Types.Bin
+import XMMS2.Client.Types.List
+import XMMS2.Client.Types.Dict
+
+
+class (ValueGet a, ValueNew a) => ValuePrim a where
+  primInt32  :: a -> Maybe Int32
+  primInt32  = const Nothing
+  primString :: a -> Maybe String
+  primString = const Nothing
+  primColl   :: a -> Maybe Coll
+  primColl   = const Nothing
+  primBin    :: a -> Maybe Bin
+  primBin    = const Nothing
+  primList   :: a -> Maybe [Data]
+  primList   = const Nothing
+  primDict   :: a -> Maybe (Dict Data)
+  primDict   = const Nothing
+
+
+instance ValuePrim ()
+
+instance ValuePrim Int32 where
+  primInt32 = Just
+
+instance ValuePrim String where
+  primString = Just
+
+instance ValuePrim Coll where
+  primColl = Just
+
+instance ValuePrim Bin where
+  primBin = Just
+
+instance ValuePrim [Data] where
+  primList = Just
+
+instance ValuePrim (Dict Data) where
+  primDict = Just
+
+
+data Data = forall a. ValuePrim a => Data a
+
+instance ValueGet Data where
+  valueGet v = do
+    t <- getType v
+    case t of
+      TypeNone   -> Data <$> getNone v
+      TypeInt32  -> Data <$> getInt v
+      TypeString -> Data <$> getString v
+      TypeColl   -> Data <$> getColl v
+      TypeBin    -> Data <$> getBin v
+      TypeList   -> Data <$> (getList v :: IO [Data])
+      TypeDict   -> Data <$> (getDict v :: IO (Dict Data))
+      TypeError  -> throwIO . XMMSError . fromJust =<< getError v
+
+instance ValueNew Data where
+  valueNew (Data a) = valueNew a
+
+
+mkData = Data
+
+dataInt32  (Data a) = primInt32 a
+dataString (Data a) = primString a
+dataColl   (Data a) = primColl a
+dataBin    (Data a) = primBin a
+dataList   (Data a) = primList a
+dataDict   (Data a) = primDict a
+
+
+lookupInt32  k d = dataInt32  =<< Map.lookup k d
+lookupString k d = dataString =<< Map.lookup k d
+lookupColl   k d = dataColl   =<< Map.lookup k d
+lookupBin    k d = dataBin    =<< Map.lookup k d
+lookupList   k d = dataList   =<< Map.lookup k d
+lookupDict   k d = dataDict   =<< Map.lookup k d
diff --git a/src/XMMS2/Client/Types/Dict.hs b/src/XMMS2/Client/Types/Dict.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Dict.hs
@@ -0,0 +1,62 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+{-# LANGUAGE TupleSections #-}
+
+module XMMS2.Client.Types.Dict
+  ( Dict
+  , getDict
+  , getAssocs
+  , newDict
+  ) where
+
+import Control.Applicative
+
+import Data.Map (Map)
+import qualified Data.Map as Map
+
+import XMMS2.Utils
+
+import XMMS2.Client.Types.Value
+import qualified XMMS2.Client.Bindings.Types as B
+
+
+type Dict a = Map String a
+
+instance ValueGet a => ValueGet (Dict a) where
+  valueGet = getDict
+
+instance ValueNew a => ValueNew (Dict a) where
+  valueNew = newDict
+
+getDict :: ValueGet a => Value -> IO (Dict a)
+getDict val = Map.fromList <$> getAssocs val
+
+getAssocs :: ValueGet a => Value -> IO [(String, a)]
+getAssocs val = do
+  iter <- B.getDictIter val
+  while (B.dictIterValid iter) $ do
+    (key, val) <- B.dictIterPair iter
+    B.dictIterNext iter
+    (key, ) <$> valueGet val
+
+newDict dict = do
+  val <- B.newDict
+  mapM_ (\(k, v) -> valueNew v >>= B.dictSet val k) $ Map.toList dict
+  return val
diff --git a/src/XMMS2/Client/Types/List.hs b/src/XMMS2/Client/Types/List.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/List.hs
@@ -0,0 +1,54 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.List
+  ( getList
+  , newList
+  , strictGetList
+  ) where
+
+import XMMS2.Utils
+
+import XMMS2.Client.Types.Value
+import qualified XMMS2.Client.Bindings.Types as B
+
+
+instance ValueGet a => ValueGet [a] where
+  valueGet = getList
+
+instance ValueNew a => ValueNew [a] where
+  valueNew = newList
+
+getList :: ValueGet a => Value -> IO [a]
+getList = getList' lazyWhile
+
+strictGetList :: ValueGet a => Value -> IO [a]
+strictGetList = getList' while
+
+getList' while val = do
+  iter <- B.getListIter val
+  while (B.listIterValid iter) $ do
+    entry <- B.listIterEntry iter
+    B.listIterNext iter
+    valueGet entry
+
+newList list = do
+  val <- B.newList
+  mapM_ (\v -> valueNew v >>= B.listAppend val) list
+  return val
diff --git a/src/XMMS2/Client/Types/Property.hs b/src/XMMS2/Client/Types/Property.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Property.hs
@@ -0,0 +1,50 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 15 Feb. 2010
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.Property
+  ( Property (..)
+  , PropDict
+  ) where
+
+import Control.Applicative
+
+import XMMS2.Utils
+
+import XMMS2.Client.Types.Value
+import XMMS2.Client.Types.Dict
+
+
+data Property
+  = PropInt32 Int32
+  | PropString String
+    deriving (Eq, Show, Read)
+
+instance ValueGet Property where
+  valueGet v = do
+    t <- getType v
+    case t of
+      TypeInt32  -> PropInt32  <$> getInt v
+      TypeString -> PropString <$> getString v
+      _          -> fail $ "Property.valueGet: bad type " ++ show t
+
+
+type PropDict = Dict [(String, Property)]
+
+instance ValueGet [(String, Property)] where
+  valueGet v = valueGet v >>= getAssocs
diff --git a/src/XMMS2/Client/Types/Value.hs b/src/XMMS2/Client/Types/Value.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Client/Types/Value.hs
@@ -0,0 +1,72 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 1 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Client.Types.Value
+  ( module XMMS2.Client.Bindings.Types.Value
+  , ValueGet (..)
+  , ValueNew (..)
+  ) where
+
+import XMMS2.Client.Bindings.Types.Value
+  ( Value
+  , ValueType (..)
+  , Int32
+  , getType
+  , getError
+  , getNone
+  , newNone
+  , getInt
+  , newInt
+  , getString
+  , newString )
+
+
+class ValueGet a where
+  valueGet :: Value -> IO a
+
+class ValueNew a where
+  valueNew :: a -> IO Value
+
+
+instance ValueGet Value where
+  valueGet = return
+
+instance ValueNew Value where
+  valueNew = return
+
+
+instance ValueGet () where
+  valueGet = getNone
+
+instance ValueNew () where
+  valueNew = const newNone
+
+
+instance ValueGet Int32 where
+  valueGet = getInt
+
+instance ValueNew Int32 where
+  valueNew = newInt
+
+
+instance ValueGet String where
+  valueGet = getString
+
+instance ValueNew String where
+  valueNew = newString
diff --git a/src/XMMS2/Utils.hs b/src/XMMS2/Utils.hs
new file mode 100644
--- /dev/null
+++ b/src/XMMS2/Utils.hs
@@ -0,0 +1,78 @@
+-- -*-haskell-*-
+--  XMMS2 client library.
+--
+--  Author:  Oleg Belozeorov
+--  Created: 3 Sep. 2009
+--
+--  Copyright (C) 2009-2010 Oleg Belozeorov
+--
+--  This library is free software; you can redistribute it and/or
+--  modify it under the terms of the GNU Lesser General Public
+--  License as published by the Free Software Foundation; either
+--  version 3 of the License, or (at your option) any later version.
+--
+--  This library is distributed in the hope that it will be useful,
+--  but WITHOUT ANY WARRANTY; without even the implied warranty of
+--  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+--  Lesser General Public License for more details.
+--
+
+module XMMS2.Utils
+  ( module C2HS
+  , withCString
+  , withMaybeCString
+  , withCStringArray0
+  , peekCString
+  , withZTArray
+  , while
+  , lazyWhile
+  , takePtr
+  , takePtr_
+  ) where
+
+import Control.Applicative
+import Control.Monad
+
+import System.IO.Unsafe
+
+import Foreign.Ptr
+import qualified Foreign.C.String as CS
+
+import Codec.Binary.UTF8.String
+
+import C2HS hiding (withCString, peekCString)
+
+
+withMaybeCString (Just s) f = withCString s f
+withMaybeCString Nothing f  = f nullPtr
+
+withCString = CS.withCString . encodeString
+
+withCStringArray0 [] f =
+  f nullPtr
+withCStringArray0 sl f =
+  allocaArray0 (length sl) (\p -> doIt sl p (f p))
+  where
+    doIt [] p f =
+      poke p nullPtr >> f
+    doIt (x:xs) p f =
+      withCString x $ \s -> poke p s >> doIt xs (advancePtr p 1) f
+
+
+peekCString = liftM decodeString . CS.peekCString
+
+while = while' id
+lazyWhile = while' unsafeInterleaveIO
+
+while' w c a = w $ do
+  continue <- c
+  if continue
+     then (:) <$> a <*> while' w c a
+     else return []
+
+
+withZTArray = withArray0 0
+
+
+takePtr  con fin = liftM con . newForeignPtr fin
+takePtr_ con     = liftM con . newForeignPtr_
diff --git a/src/c/xmms2hs-client.c b/src/c/xmms2hs-client.c
new file mode 100644
--- /dev/null
+++ b/src/c/xmms2hs-client.c
@@ -0,0 +1,92 @@
+/* XMMS2 client library.
+
+   Author:  Oleg Belozeorov
+   Created: 2 Sep. 2009
+
+   Copyright (C) 2009-2010 Oleg Belozeorov
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details. */
+
+#include <HsFFI.h>
+#include <stdlib.h>
+#include <xmmsc/xmmsc_util.h>
+#include <xmms2hs-client.h>
+
+
+static void
+xmms2hs_finalize_callback (void *notifier)
+{
+  hs_free_fun_ptr ((HsFunPtr) notifier);
+}
+
+void
+xmms2hs_disconnect_callback_set (xmmsc_connection_t *xmmsc,
+								 xmmsc_disconnect_func_t func)
+{
+  xmmsc_disconnect_callback_set_full (xmmsc, func, (void *) func, xmms2hs_finalize_callback);
+}
+
+void
+xmms2hs_result_notifier_set (xmmsc_result_t *res,
+							 xmmsc_result_notifier_t func)
+{
+  xmmsc_result_notifier_set_full (res, func, (void *) func, xmms2hs_finalize_callback);
+}
+
+
+extern int
+xmms2hs_get_list_iter (xmmsv_t *value, xmmsv_list_iter_t **iter)
+{
+  int res = xmmsv_get_list_iter (value, iter);
+  
+  if (res)
+	xmmsv_ref (value);
+  
+  return res;
+}
+
+extern void
+xmms2hs_finalize_list_iter (xmmsv_list_iter_t *iter)
+{
+  xmmsv_t *parent = xmmsv_list_iter_get_parent (iter);
+
+  xmmsv_list_iter_explicit_destroy (iter);
+  xmmsv_unref (parent);
+}
+
+extern int
+xmms2hs_get_dict_iter (xmmsv_t *value, xmms2hs_dict_iter_t **iter)
+{
+  xmms2hs_dict_iter_t *result;
+  xmmsv_dict_iter_t *xi;
+  
+  if (xmmsv_get_dict_iter (value, &xi)) {
+	*iter = x_malloc (sizeof (xmms2hs_dict_iter_t));
+	if (!*iter)
+	  x_oom ();
+
+	(*iter)->parent = value;
+	(*iter)->iter = xi;
+	xmmsv_ref (value);
+
+	return 1;
+  }
+  
+  return 0;
+}
+
+extern void
+xmms2hs_finalize_dict_iter (xmms2hs_dict_iter_t *iter)
+{
+  xmmsv_dict_iter_explicit_destroy (iter->iter);
+  xmmsv_unref (iter->parent);
+  free (iter);
+}
diff --git a/src/c/xmms2hs-client.h b/src/c/xmms2hs-client.h
new file mode 100644
--- /dev/null
+++ b/src/c/xmms2hs-client.h
@@ -0,0 +1,40 @@
+/* XMMS2 client library.
+
+   Author:  Oleg Belozeorov
+   Created: 2 Sep. 2009
+
+   Copyright (C) 2009-2010 Oleg Belozeorov
+
+   This library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 3 of the License, or (at your option) any later version.
+
+   This library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details. */
+
+#ifndef XMMS2HS_CLIENT_H
+#define XMMS2HS_CLIENT_H
+
+#include <xmmsclient/xmmsclient.h>
+
+
+extern void xmms2hs_disconnect_callback_set (xmmsc_connection_t *, xmmsc_disconnect_func_t);
+
+extern void xmms2hs_result_notifier_set (xmmsc_result_t *, xmmsc_result_notifier_t);
+
+extern int xmms2hs_get_list_iter (xmmsv_t *, xmmsv_list_iter_t **);
+extern void xmms2hs_finalize_list_iter (xmmsv_list_iter_t *);
+
+typedef struct {
+  xmmsv_t *parent;
+  xmmsv_dict_iter_t *iter;
+} xmms2hs_dict_iter_t;
+
+extern int xmms2hs_get_dict_iter (xmmsv_t *, xmms2hs_dict_iter_t **);
+extern void xmms2hs_finalize_dict_iter (xmms2hs_dict_iter_t *);
+
+
+#endif /* XMMS2HS_CLIENT_H */
diff --git a/xmms2-client.cabal b/xmms2-client.cabal
new file mode 100644
--- /dev/null
+++ b/xmms2-client.cabal
@@ -0,0 +1,88 @@
+name:               xmms2-client
+version:            0.0.3.8
+
+author:             Oleg Belozeorov
+maintainer:         Oleg Belozeorov <upwawet@gmail.com>
+copyright:          (C) 2009-2010 Oleg Belozeorov
+license:            LGPL-3
+license-file:       COPYING
+
+category:           Sound
+synopsis:           An XMMS2 client library.
+description:
+  This package provides an interface to the X-platform Music Multiplexing
+  System 2 (http://xmms2.xmms.se) client API, thus allowing to write XMMS2
+  clients in Haskell. It contains (nearly) 1-to-1 bindings to the XMMS2
+  client API and a higher level interface.
+
+cabal-version:      >= 1.6
+build-type:         Simple
+extra-source-files: src/c/xmms2hs-client.h
+extra-tmp-files:    config.status, config.log,
+                    xmms2-client.buildinfo, C2HS.hs,
+                    hlint.out
+
+library
+  exposed-modules:  Control.Monad.ToIO,
+                    XMMS2.Client,
+                    XMMS2.Client.Types,
+                    XMMS2.Client.Types.Value,
+                    XMMS2.Client.Types.Coll,
+                    XMMS2.Client.Types.Bin,
+                    XMMS2.Client.Types.List,
+                    XMMS2.Client.Types.Dict,
+                    XMMS2.Client.Types.Property,
+                    XMMS2.Client.Types.Data,
+                    XMMS2.Client.Exception,
+                    XMMS2.Client.Connection,
+                    XMMS2.Client.Result,
+                    XMMS2.Client.Coll,
+                    XMMS2.Client.Playback,
+                    XMMS2.Client.Playlist,
+                    XMMS2.Client.Medialib,
+                    XMMS2.Client.Stats,
+                    XMMS2.Client.Bindings,
+                    XMMS2.Client.Bindings.Types,
+                    XMMS2.Client.Bindings.Types.Value,
+                    XMMS2.Client.Bindings.Types.Coll,
+                    XMMS2.Client.Bindings.Types.Bin,
+                    XMMS2.Client.Bindings.Types.List,
+                    XMMS2.Client.Bindings.Types.Dict,
+                    XMMS2.Client.Bindings.Result,
+                    XMMS2.Client.Bindings.Connection,
+                    XMMS2.Client.Bindings.Coll,
+                    XMMS2.Client.Bindings.Playback,
+                    XMMS2.Client.Bindings.Playlist,
+                    XMMS2.Client.Bindings.Medialib,
+                    XMMS2.Client.Bindings.Stats
+  other-modules:    C2HS,
+                    XMMS2.Utils
+  c-sources:		src/c/xmms2hs-client.c
+  include-dirs:		src/c
+  build-depends:	base >= 4 && < 5, haskell98, utf8-string, mtl, containers
+  build-tools:		c2hs
+  hs-source-dirs:   ., src
+  extensions:       ForeignFunctionInterface,
+                    ExistentialQuantification,
+                    TypeSynonymInstances,
+                    DeriveDataTypeable,
+                    FlexibleInstances,
+                    NoMonomorphismRestriction,
+                    MultiParamTypeClasses,
+                    FunctionalDependencies,
+                    EmptyDataDecls,
+                    FlexibleContexts,
+                    ScopedTypeVariables,
+                    OverlappingInstances
+
+
+source-repository head
+  type:             git
+  location:         git://github.com/upwawet/xmms2hs.git
+  subdir:           client
+
+source-repository this
+  type:             git
+  location:         git://github.com/upwawet/xmms2hs.git
+  subdir:           client
+  tag:              v0.0.3.8
