diff --git a/System/Libnotify.hs b/System/Libnotify.hs
--- a/System/Libnotify.hs
+++ b/System/Libnotify.hs
@@ -1,150 +1,130 @@
-{-# LANGUAGE FlexibleInstances, FlexibleContexts #-}
+{-# LANGUAGE GeneralizedNewtypeDeriving  #-}
 -- | System.Libnotify module deals with notification session processing.
 {-# OPTIONS_HADDOCK prune #-}
 module System.Libnotify
-  ( oneShot, withNotifications
+  ( Notify, NotifyState, NotifyError (..)
+  , oneShot, withNotifications
   , new, continue, update, render, close
   , setTimeout, setCategory, setUrgency
-  , Hint(..), GeneralHint, removeHints
+  , addHint, removeHints
   , addAction, removeActions
-  , notifyErrorHandler
+  , setIconFromPixbuf, setImageFromPixbuf
+  , module System.Libnotify.Types
   ) where
 
-import Control.Exception (throw)
-import Control.Monad.Reader (MonadIO, MonadReader, ReaderT, liftIO, runReaderT, ask)
-import Data.Int (Int32)
+import Control.Applicative ((<$>))
+import Control.Monad.Reader (ReaderT, ask, runReaderT)
+import Control.Monad.State (StateT, execStateT, get, put)
+import Control.Monad.Trans (MonadIO, liftIO)
 import Data.Maybe (fromMaybe)
-import Data.Word (Word8)
-import qualified Data.ByteString as BS
-import System.IO (stderr, hPutStrLn)
+import Graphics.UI.Gtk.Gdk.Pixbuf (Pixbuf)
 
+import System.Libnotify.Internal (Notification)
 import qualified System.Libnotify.Internal as N
 import System.Libnotify.Types
 
--- | Notification session. Saves notification initial state.
-data Session = Session
-                 { notification :: N.Notification
-                 , title :: Title
-                 , body :: Body
-                 , icon :: Icon
-                 }
+-- | Notification state. Contains next rendered notification data.
+data NotifyState = NotifyState Title Body Icon
 
+-- | Libnotify errors.
+data NotifyError
+  = NotifyInitHasFailed  -- ^ notify_init() has failed.
+  | NewCalledBeforeInit  -- ^ 'new' has called before notify_init().
+  deriving Show
+
+-- | Notification monad. Saves notification context.
+newtype Notify a = Notify { runNotify :: StateT NotifyState (ReaderT Notification IO) a } deriving (Functor, Monad, MonadIO)
+
 {-|
   Initializes and uninitializes libnotify API.
   Any notifications API calls should be wrapped into @withNotifications@, i.e.
 
   > main = withNotifications (Just "api-name") $ do { ... here are notification API calls ... }
 -}
-withNotifications :: Maybe String -> IO a -> IO ()
+withNotifications :: Maybe String -> IO a -> IO (Either NotifyError ())
 withNotifications a x = (N.initNotify . fromMaybe " ") a >>= \initted ->
                         if initted
-                          then x >> N.uninitNotify
-                          else throw NotifyInitHasFailed
+                          then Right <$> (x >> N.uninitNotify)
+                          else return $ Left NotifyInitHasFailed
 
 -- | Function for one-time notification with hints perhaps. Should be enough for a vast majority of applications.
-oneShot :: Hint a => Title -> Body -> Icon -> [a] -> IO ()
-oneShot t b i hs = withNotifications Nothing $
-                     new t b i $
-                       mapM_ addHint hs >> render
+oneShot :: Title -> Body -> Icon -> Maybe [Hint] -> IO (Either NotifyError ())
+oneShot t b i hs = withNotifications Nothing . new t b i $ mapM_ addHint (fromMaybe [] hs) >> render
 
 -- | Creates new notification session. Inside 'new' call one can manage current notification via 'update' or 'render' calls.
 -- Returns notification pointer. This could be useful if one wants to 'update' or 'close' the same notification after some time (see 'continue').
-new :: Title -> Body -> Icon -> ReaderT Session IO t -> IO Session
+new :: Title -> Body -> Icon -> Notify t -> IO (Either NotifyError (Notification, NotifyState))
 new t b i f = N.isInitted >>= \initted ->
               if initted
-                then do n <- N.newNotify t (listToMaybeAll b) (listToMaybeAll i)
-                        continue (Session n t b i) f
-                        return (Session n t b i)
-                else throw NewCalledBeforeInit
+                then do n <- N.newNotify t (listToMaybe b) (listToMaybe i)
+                        s <- continue (n, NotifyState t b i) f
+                        return $ Right (n, s)
+                else return $ Left NewCalledBeforeInit
 
 -- | Continues old notification session.
-continue :: Session -> ReaderT Session IO a -> IO ()
-continue s f = runReaderT f s >> return ()
+continue :: (Notification, NotifyState) -> Notify a -> IO NotifyState
+continue (n, s) f = runReaderT (execStateT (runNotify f) s) n
 
 -- | Updates notification 'Title', 'Body' and 'Icon'.
 -- User can update notification partially, passing Nothing to arguments that should not changed.
-update :: (MonadIO m, MonadReader Session m) => Maybe Title -> Maybe Body -> Maybe Icon -> m Bool
-update nt nb ni = ask >>= \(Session n t b i) ->
-                    liftIO $ N.updateNotify n
-                               (fromMaybe t nt)
-                               (listToMaybeAll (fromMaybe b nb))
-                               (listToMaybeAll (fromMaybe i ni))
+update :: Maybe Title -> Maybe Body -> Maybe Icon -> Notify Bool
+update mt mb mi = Notify $
+  do n <- ask
+     NotifyState t b i <- get
+     let nt = fromMaybe t mt
+         nb = fromMaybe b mb
+         ni = fromMaybe i mi
+     put (NotifyState nt nb ni)
+     liftIO $ N.updateNotify n nt (listToMaybe nb) (listToMaybe ni)
 
 -- | Shows notification to user.
-render :: (MonadIO m, MonadReader Session m) => m Bool
-render = ask >>= liftIO . N.showNotify . notification
+render :: Notify Bool
+render = Notify $ ask >>= liftIO . N.showNotify
 
 -- | Closes notification.
-close :: (MonadIO m, MonadReader Session m) => m Bool
-close = ask >>= liftIO . N.closeNotify . notification
+close :: Notify Bool
+close = Notify $ ask >>= liftIO . N.closeNotify
 
 -- | Sets notification 'Timeout'.
-setTimeout :: (MonadIO m, MonadReader Session m) => Timeout -> m ()
-setTimeout t = ask >>= liftIO . N.setTimeout t . notification
+setTimeout :: Timeout -> Notify ()
+setTimeout t = Notify $ ask >>= liftIO . N.setTimeout t
 
 -- | Sets notification 'Category'.
-setCategory :: (MonadIO m, MonadReader Session m) => Category -> m ()
-setCategory c = ask >>= liftIO . N.setCategory c . notification
+setCategory :: Category -> Notify ()
+setCategory c = Notify $ ask >>= liftIO . N.setCategory c
 
 -- | Sets notification 'Urgency'.
-setUrgency :: (MonadIO m, MonadReader Session m) => Urgency -> m ()
-setUrgency u = ask >>= liftIO . N.setUrgency u . notification
-
--- | Instance of 'Hint' class. Useful for 'oneShot' calls with empty hint list.
-data GeneralHint = HintInt String Int32 | HintDouble String Double | HintString String String | HintByte String Word8 | HintArray String BS.ByteString
-
--- | Hint is some setting (server-dependent) which comes with notification.
-class Hint a where
-  -- | Adds 'Hint' to notification.
-  addHint :: a -> (MonadIO m, MonadReader Session m) => m ()
-  -- | Generalizes 'Hint' to some type. Could be useful if one wants to pass list of distinct hints types.
-  generalize :: a -> GeneralHint
-
-instance Hint GeneralHint where
-  addHint (HintInt k v) = addHint (k,v)
-  addHint (HintDouble k v) = addHint (k,v)
-  addHint (HintString k v) = addHint (k,v)
-  addHint (HintByte k v) = addHint (k,v)
-  addHint (HintArray k v) = addHint (k,v)
-  generalize = id
-
-instance Hint (Key,Int32) where
-  addHint (k,v) = ask >>= \s -> liftIO $ N.setHintInt32 (notification s) k v
-  generalize (k,v) = HintInt k v
-
-instance Hint (Key,Double) where
-  addHint (k,v) = ask >>= \s -> liftIO $ N.setHintDouble (notification s) k v
-  generalize (k,v) = HintDouble k v
+setUrgency :: Urgency -> Notify ()
+setUrgency u = Notify $ ask >>= liftIO . N.setUrgency u
 
-instance Hint (Key,String) where
-  addHint (k,v) = ask >>= \s -> liftIO $ N.setHintString (notification s) k v
-  generalize (k,v) = HintString k v
+-- | Sets notification icon from pixbuf
+setIconFromPixbuf :: Pixbuf -> Notify ()
+setIconFromPixbuf p = Notify $ ask >>= liftIO . N.setIconFromPixbuf p
 
-instance Hint (Key,Word8) where
-  addHint (k,v) = ask >>= \s -> liftIO $ N.setHintByte (notification s) k v
-  generalize (k,v) = HintByte k v
+-- | Sets notification image from pixbuf
+setImageFromPixbuf :: Pixbuf -> Notify ()
+setImageFromPixbuf p = Notify $ ask >>= liftIO . N.setImageFromPixbuf p
 
-instance Hint (Key,BS.ByteString) where
-  addHint (k,v) = ask >>= \s -> liftIO $ N.setHintByteArray (notification s) k v
-  generalize (k,v) = HintArray k v
+-- | Adds 'Hint' to notification.
+addHint :: Hint -> Notify ()
+addHint (HintInt k v) =  Notify $ ask >>= liftIO . N.setHintInt32 k v
+addHint (HintDouble k v) = Notify $ ask >>= liftIO . N.setHintDouble k v
+addHint (HintString k v) = Notify $ ask >>= liftIO . N.setHintString k v
+addHint (HintByte k v) = Notify $ ask >>= liftIO . N.setHintByte k v
+addHint (HintArray k v) = Notify $ ask >>= liftIO . N.setHintByteArray k v
 
 -- | Removes hints from notification.
-removeHints :: (MonadIO m, MonadReader Session m) => m ()
-removeHints = ask >>= liftIO . N.clearHints . notification
+removeHints :: Notify ()
+removeHints = Notify $ ask >>= liftIO . N.clearHints
 
 -- | Adds action to notification.
-addAction :: (MonadIO m, MonadReader Session m) => String -> String -> (N.Notification -> String -> IO ()) -> m ()
-addAction a l c = ask >>= \s -> liftIO $ N.addAction (notification s) a l c
+addAction :: String -> String -> (Notification -> String -> IO ()) -> Notify ()
+addAction a l c = Notify $ ask >>= liftIO . N.addAction a l c
 
 -- | Removes actions from notification.
-removeActions :: (MonadIO m, MonadReader Session m) => m ()
-removeActions = ask >>= liftIO . N.clearActions . notification
-
--- | Libnotify error handler
-notifyErrorHandler :: NotifyError -> IO ()
-notifyErrorHandler NotifyInitHasFailed = hPutStrLn stderr "withNotifications: init has failed."
-notifyErrorHandler NewCalledBeforeInit = hPutStrLn stderr "new: Libnotify is not initialized properly."
+removeActions :: Notify ()
+removeActions = Notify $ ask >>= liftIO . N.clearActions
 
-listToMaybeAll :: [a] -> Maybe [a]
-listToMaybeAll [] = Nothing
-listToMaybeAll xs = Just xs
+listToMaybe :: [a] -> Maybe [a]
+listToMaybe [] = Nothing
+listToMaybe xs = Just xs
diff --git a/System/Libnotify/Internal.hsc b/System/Libnotify/Internal.hsc
--- a/System/Libnotify/Internal.hsc
+++ b/System/Libnotify/Internal.hsc
@@ -15,11 +15,11 @@
   , addAction, clearActions, closeNotify
   ) where
 
+import Control.Exception (throw)
 import Foreign
 import Foreign.C
 import Graphics.UI.Gtk.Gdk.Pixbuf
-import System.Glib.GError
-import System.Glib.GList
+import System.Glib.GError (GError)
 import Unsafe.Coerce
 import qualified Data.ByteString as BS
 
@@ -85,9 +85,9 @@
   p_error <- peek pp_error
   if p_error == nullPtr
     then return result
-    else do error <- peek p_error
+    else do gerror <- peek p_error
             g_error_free p_error
-            throwGError error
+            throw gerror
 
 foreign import ccall unsafe "libnotify/notify.h notify_notification_show"
   notify_notification_show :: Notification -> Ptr (Ptr GError) -> IO Bool
@@ -125,8 +125,8 @@
 foreign import ccall unsafe "libnotify/notify.h notify_notification_set_urgency"
   notify_notification_set_urgency :: Notification -> CInt -> IO ()
 
-setIconFromPixbuf :: Notification -> Pixbuf -> IO ()
-setIconFromPixbuf notify pixbuf =
+setIconFromPixbuf :: Pixbuf -> Notification -> IO ()
+setIconFromPixbuf pixbuf notify =
   withForeignPtr (unsafeCoerce pixbuf) $ \p_pixbuf ->
   notify_notification_set_icon_from_pixbuf notify p_pixbuf
 
@@ -135,8 +135,8 @@
                                            -> Ptr Pixbuf
                                            -> IO ()
 
-setImageFromPixbuf :: Notification -> Pixbuf -> IO ()
-setImageFromPixbuf notify pixbuf =
+setImageFromPixbuf :: Pixbuf -> Notification -> IO ()
+setImageFromPixbuf pixbuf notify =
   withForeignPtr (unsafeCoerce pixbuf) $ \p_pixbuf ->
   notify_notification_set_image_from_pixbuf notify p_pixbuf
 
@@ -145,8 +145,8 @@
                                             -> Ptr Pixbuf
                                             -> IO ()
 
-setHintInt32 :: Notification -> String -> Int32 -> IO ()
-setHintInt32 notify key value =
+setHintInt32 :: String -> Int32 -> Notification -> IO ()
+setHintInt32 key value notify =
   withCString key $ \p_key ->
   notify_notification_set_hint_int32 notify p_key (fromIntegral value)
 
@@ -156,8 +156,8 @@
                                      -> CInt
                                      -> IO ()
 
-setHintDouble :: Notification -> String -> Double -> IO ()
-setHintDouble notify key value =
+setHintDouble :: String -> Double -> Notification -> IO ()
+setHintDouble key value notify =
   withCString key $ \p_key ->
   notify_notification_set_hint_double notify p_key (realToFrac value)
 
@@ -167,8 +167,8 @@
                                       -> CDouble
                                       -> IO ()
 
-setHintString :: Notification -> String -> String -> IO ()
-setHintString notify key value =
+setHintString :: String -> String -> Notification -> IO ()
+setHintString key value notify =
   withCString key   $ \p_key ->
   withCString value $ \p_value ->
   notify_notification_set_hint_string notify p_key p_value
@@ -179,8 +179,8 @@
                                       -> CString
                                       -> IO ()
 
-setHintByte :: Notification -> String -> Word8 -> IO ()
-setHintByte notify key value =
+setHintByte :: String -> Word8 -> Notification -> IO ()
+setHintByte key value notify =
   withCString key $ \p_key ->
   notify_notification_set_hint_byte notify p_key (fromIntegral value)
 
@@ -190,8 +190,8 @@
                                     -> CUChar
                                     -> IO ()
 
-setHintByteArray :: Notification -> String -> BS.ByteString -> IO ()
-setHintByteArray notify key value =
+setHintByteArray :: String -> BS.ByteString -> Notification -> IO ()
+setHintByteArray key value notify =
   withCString key $ \p_key ->
   withArrayLen (BS.foldr' step [] value) $ \len p_bs ->
   notify_notification_set_hint_byte_array notify p_key p_bs (fromIntegral len)
@@ -212,12 +212,12 @@
   notify_notification_clear_hints :: Notification -> IO ()
 
 addAction
-  :: Notification
-  -> String
+  :: String
   -> String
   -> (Notification -> String -> IO ())
+  -> Notification
   -> IO ()
-addAction notify action label callback =
+addAction action label callback notify =
   withCString action $ \p_action ->
   withCString label  $ \p_label -> do
     p_callback <- wrapActionCallback $ makeCallback callback
@@ -261,9 +261,9 @@
   p_error <- peek pp_error
   if p_error == nullPtr
     then return result
-    else do error <- peek p_error
+    else do gerror <- peek p_error
             g_error_free p_error
-            throwGError error
+            throw gerror
 
 foreign import ccall unsafe "libnotify/notify.h notify_notification_close"
   notify_notification_close :: Notification -> Ptr (Ptr GError) -> IO Bool
diff --git a/System/Libnotify/Types.hs b/System/Libnotify/Types.hs
new file mode 100644
--- /dev/null
+++ b/System/Libnotify/Types.hs
@@ -0,0 +1,53 @@
+-- | System.Libnotify.Types module is a collection of types is used in other modules.
+-- This is reexported with System.Libnotify module. Perhaps it'll never be needed to import explicitly.
+{-# OPTIONS_HADDOCK prune #-}
+
+module System.Libnotify.Types
+  ( Timeout(..), Urgency(..), Category
+  , Title, Body, Icon
+  , ServerInfo(..)
+  , Hint(..)
+  ) where
+
+import qualified Data.ByteString as BS
+import Data.Int (Int32)
+import Data.Word (Word8)
+
+-- | Urgency can be used by the notification server to prioritize notifications.
+-- Although urgency does not work with notify-osd.
+data Urgency
+       = Low -- ^ Low priority notification.
+       | Normal -- ^ Default notification urgency.
+       | Critical -- ^ Critical notification that requires immediate attention.
+
+-- | Timeout in seconds after which notification is closed.
+-- Although timeout does not work with notify-osd.
+data Timeout
+       = Default -- ^ Default server timeout.
+       | Custom Int -- ^ User defined timeout (in milliseconds).
+       | Infinite -- ^ Notification will not expire until user pays attention to it.
+
+-- | Category can be used by the notification server to filter or display the data in a certain way.
+type Category = String
+
+-- | Type synonim for notification title.
+type Title = String
+-- | Type synonim for notification body.
+type Body = String
+-- | Type synonim for notification icon.
+type Icon = String
+
+-- | Server information.
+data ServerInfo = ServerInfo
+  { serverName  :: String
+  , serverVendor :: String
+  , serverVersion :: String
+  , serverSpecVersion :: String
+  } deriving Show
+
+-- | Hint is some setting (server-dependent) which comes with notification.
+data Hint = HintInt String Int32
+          | HintDouble String Double
+          | HintString String String
+          | HintByte String Word8
+          | HintArray String BS.ByteString
diff --git a/System/Libnotify/Types.hsc b/System/Libnotify/Types.hsc
deleted file mode 100644
--- a/System/Libnotify/Types.hsc
+++ /dev/null
@@ -1,55 +0,0 @@
-{-# LANGUAGE ForeignFunctionInterface, DeriveDataTypeable #-}
--- | System.Libnotify.Types module is a collection of types is used in other modules.
--- This is reexported with System.Libnotify module. Perhaps it'll never be needed to import explicitly.
-{-# OPTIONS_HADDOCK prune #-}
-
-#include <libnotify/notify.h>
-
-module System.Libnotify.Types
-  ( Timeout(..), Urgency(..), Category
-  , Title, Body, Icon
-  , Key
-  , ServerInfo(..)
-  , NotifyError(..)
-  ) where
-
-import Control.Exception (Exception)
-import Data.Typeable (Typeable)
-import Foreign.C
-
--- | Urgency can be used by the notification server to prioritize notifications.
--- Although urgency does not work with notify-osd.
-data Urgency = Low | Normal | Critical
-
--- | Timeout in seconds after which notification is closed.
--- Although timeout does not work with notify-osd.
-data Timeout = Default | Custom Int | Infinite
-
--- | Category can be used by the notification server to filter or display the data in a certain way.
-type Category = String
-
--- | Type synonim for notification title.
-type Title = String
--- | Type synonim for notification body.
-type Body = String
--- | Type synonim for notification icon.
-type Icon = String
-
--- | Type synonym for 'Hint' key type.
-type Key = String
-
--- | Server information.
-data ServerInfo = ServerInfo
-  { serverName  :: String
-  , serverVendor :: String
-  , serverVersion :: String
-  , serverSpecVersion :: String
-  } deriving Show
-
--- | Libnotify errors.
-data NotifyError
-  = NotifyInitHasFailed  -- ^ notify_init() has failed.
-  | NewCalledBeforeInit  -- ^ 'new' has called before notify_init().
-  deriving (Show, Typeable)
-
-instance Exception NotifyError
diff --git a/libnotify.cabal b/libnotify.cabal
--- a/libnotify.cabal
+++ b/libnotify.cabal
@@ -1,20 +1,20 @@
-Name:		libnotify
-Version:	0.0.1.2
-Description:	Usable binding to libnotify library.
-License:	MIT
-License-file:	LICENSE
-Author:		Emon Tsukimiya, Matvey Aksenov
-Maintainer:	Matvey Aksenov <matvey.aksenov@gmail.com>
-Category:	System, Desktop
-Synopsis:	Haskell binding for Libnotify
-Cabal-Version:	>= 1.6
-Build-Type:	Simple
+Name: libnotify
+Version: 0.0.2.0
+Description: Usable binding to libnotify library.
+License: MIT
+License-file: LICENSE
+Author: Emon Tsukimiya, Matvey Aksenov
+Maintainer: Matvey Aksenov <matvey.aksenov@gmail.com>
+Category: System, Desktop
+Synopsis: Haskell binding for Libnotify
+Cabal-Version: >= 1.6
+Build-Type: Simple
 
 Library
-  Build-Depends:	base >= 3 && < 5, bytestring, glib, gtk, mtl
-  Exposed-Modules:	System.Libnotify, System.Libnotify.Internal, System.Libnotify.Server, System.Libnotify.Types
-  Pkgconfig-Depends:	libnotify
-  Extensions:		DeriveDataTypeable, FlexibleInstances, FlexibleContexts
+  Build-Depends: base >= 3 && < 5, bytestring, glib, gtk, mtl
+  Exposed-Modules: System.Libnotify, System.Libnotify.Internal, System.Libnotify.Server, System.Libnotify.Types
+  Pkgconfig-Depends: libnotify
+  GHC-options: -Wall
 
 source-repository head
   type:     git
@@ -23,4 +23,4 @@
 source-repository this
   type:     git
   location: https://github.com/supki/haskell-libnotify
-  tag:      v0.0.1.2
+  tag:      v0.0.2.0
