diff --git a/Database/Persist/Zookeeper.hs b/Database/Persist/Zookeeper.hs
--- a/Database/Persist/Zookeeper.hs
+++ b/Database/Persist/Zookeeper.hs
@@ -1,13 +1,10 @@
-module Database.Persist.Zookeeper 
+module Database.Persist.Zookeeper
     ( module Database.Persist.Zookeeper.Config
     , module Database.Persist.Zookeeper.Store
-    , module Database.Persist.Zookeeper.Unique
     , module Database.Persist.Zookeeper.Query
-    , module Database.Persist.Zookeeper.PathPiece
     ) where
 
 import Database.Persist.Zookeeper.Config
 import Database.Persist.Zookeeper.Store
 import Database.Persist.Zookeeper.Unique()
 import Database.Persist.Zookeeper.Query
-import Database.Persist.Zookeeper.PathPiece()
diff --git a/Database/Persist/Zookeeper/Binary.hs b/Database/Persist/Zookeeper/Binary.hs
new file mode 100644
--- /dev/null
+++ b/Database/Persist/Zookeeper/Binary.hs
@@ -0,0 +1,169 @@
+{-# LANGUAGE OverloadedStrings #-}
+module Database.Persist.Zookeeper.Binary(
+  toValue
+, fromValue
+) where
+
+import Control.Arrow((***))
+import Data.Fixed
+import Data.Time
+import Data.Int (Int64)
+import Data.Word (Word8)
+import Control.Monad (liftM, liftM3)
+import Data.Binary (Binary(..), getWord8, Get)
+import qualified Data.Binary as Q
+import Data.Text (Text, unpack)
+import qualified Data.Text as T
+import Database.Persist.Types
+import qualified Data.ByteString as B
+import qualified Data.ByteString.Lazy as L
+import qualified Data.ByteString.UTF8 as U
+
+newtype BinText = BinText { unBinText :: Text }
+instance Binary BinText where
+    put = put . U.fromString . unpack . unBinText
+    get = do
+        str <- Q.get
+        return $ BinText $ (T.pack . U.toString) str
+
+newtype BinPico= BinPico { unBinPico :: Pico }
+instance Binary BinPico where
+    put = put . toRational . unBinPico
+    get = do
+        x <- Q.get :: Get Rational
+        return $ BinPico (fromRational x)
+
+newtype BinDiffTime = BinDiffTime { unBinDiffTime :: DiffTime }
+instance Binary BinDiffTime where
+    put = put . toRational . unBinDiffTime
+    get = do
+        x <- Q.get :: Get Rational
+        return $ BinDiffTime (fromRational x)
+
+newtype BinDay = BinDay { unBinDay :: Day }
+instance Binary BinDay where
+    put (BinDay (ModifiedJulianDay x)) = put x
+    get = do
+        x <- Q.get :: Get Integer
+        return $ BinDay (ModifiedJulianDay x)
+
+newtype BinTimeOfDay = BinTimeOfDay { unBinTimeOfDay :: TimeOfDay }
+instance Binary BinTimeOfDay where
+    put (BinTimeOfDay (TimeOfDay h m s)) = do
+        put h
+        put m
+        put (BinPico s)
+    get = do
+        let s = liftM unBinPico (Q.get :: Get BinPico)
+        let tod = liftM3 TimeOfDay (Q.get :: Get Int) (Q.get :: Get Int) s
+        liftM BinTimeOfDay tod
+
+{-
+newtype BinZT = BinZT { unBinZT :: ZT }
+instance Binary BinZT where
+    put (BinZT (ZT (ZonedTime (LocalTime day timeOfDay) (TimeZone mins summer name)))) = do
+        put (BinDay day)
+        put (BinTimeOfDay timeOfDay)
+        put mins
+        put summer
+        put name
+
+    get = do
+        day <- Q.get :: Get BinDay
+        timeOfDay <- Q.get :: Get BinTimeOfDay
+        mins <- Q.get :: Get Int
+        summer <- Q.get :: Get Bool
+        name <- Q.get :: Get String
+        return $ BinZT $ ZT (ZonedTime (LocalTime (unBinDay day) (unBinTimeOfDay timeOfDay)) (TimeZone mins summer name))
+-}
+
+newtype BinPersistValue = BinPersistValue { unBinPersistValue :: PersistValue }
+instance Binary BinPersistValue where
+    put (BinPersistValue (PersistText x)) = do
+        put (1 :: Word8)
+        put $ (U.fromString . unpack) x
+
+    put (BinPersistValue (PersistByteString x)) = do
+        put (2 :: Word8)
+        put x
+
+    put (BinPersistValue (PersistInt64 x)) = do
+        put (3 :: Word8)
+        put x
+
+    put (BinPersistValue (PersistDouble x)) = do
+        put (4 :: Word8)
+        put x
+
+    put (BinPersistValue (PersistBool x)) = do
+        put (5 :: Word8)
+        put x
+
+    put (BinPersistValue (PersistDay day)) = do
+        put (6 :: Word8)
+        put (BinDay day)
+
+    put (BinPersistValue (PersistTimeOfDay tod)) = do
+        put (7 :: Word8)
+        put (BinTimeOfDay tod)
+
+    put (BinPersistValue (PersistUTCTime (UTCTime day pc))) = do
+        put (8 :: Word8)
+        put (BinDay day)
+        put (BinDiffTime pc)
+
+    put (BinPersistValue PersistNull) = put (9 :: Word8)
+    put (BinPersistValue (PersistList x)) = do
+        put (10 :: Word8)
+        put (map BinPersistValue x)
+
+    put (BinPersistValue (PersistMap x)) = do
+        put (11 :: Word8)
+        put (map (BinText *** BinPersistValue) x)
+
+    put (BinPersistValue (PersistRational x)) = do
+        put (12 :: Word8)
+        put x
+
+    -- put (BinPersistValue (PersistZonedTime x)) = do
+    --     put (13 :: Word8)
+    --     put (BinZT x)
+
+    put (BinPersistValue (PersistDbSpecific _)) = undefined
+    put (BinPersistValue (PersistObjectId x)) = do
+        put (14 :: Word8)
+        put x
+
+    get = do
+        tag <- getWord8
+        let pv = case tag of
+                1 -> liftM (PersistText . unBinText) (Q.get :: Get BinText)
+                2 -> liftM PersistByteString (Q.get :: Get B.ByteString)
+                3 -> liftM PersistInt64 (Q.get :: Get Int64)
+                4 -> liftM PersistDouble (Q.get :: Get Double)
+                5 -> liftM PersistBool (Q.get :: Get Bool)
+                6 -> liftM (PersistDay . unBinDay) (Q.get :: Get BinDay)
+                7 -> liftM (PersistTimeOfDay . unBinTimeOfDay) (Q.get :: Get BinTimeOfDay)
+                8 -> do
+                    d <- Q.get :: Get BinDay
+                    dt <- Q.get :: Get BinDiffTime
+                    let utctime = UTCTime (unBinDay d) (unBinDiffTime dt)
+                    return $  PersistUTCTime utctime
+                9 -> return PersistNull
+                10-> liftM (PersistList . map unBinPersistValue) (Q.get :: Get [BinPersistValue])
+                11-> liftM (PersistMap . map (unBinText *** unBinPersistValue)) (Q.get :: Get [(BinText, BinPersistValue)])
+                12-> liftM PersistRational (Q.get :: Get Rational)
+--                13-> liftM (PersistZonedTime . unBinZT) (Q.get :: Get BinZT)
+                14-> liftM PersistObjectId (Q.get :: Get B.ByteString)
+                _ -> fail "Incorrect tag came to Binary deserialization"
+        liftM BinPersistValue pv
+
+toValue :: [PersistValue] -> B.ByteString
+toValue values = L.toStrict . Q.encode $ map BinPersistValue values
+
+fromValue' :: B.ByteString -> [BinPersistValue]
+fromValue' bin = Q.decode $ L.fromStrict bin
+
+fromValue :: B.ByteString -> [PersistValue]
+fromValue bin = map unBinPersistValue $ fromValue' bin
+
diff --git a/Database/Persist/Zookeeper/Config.hs b/Database/Persist/Zookeeper/Config.hs
--- a/Database/Persist/Zookeeper/Config.hs
+++ b/Database/Persist/Zookeeper/Config.hs
@@ -8,26 +8,32 @@
 {-# LANGUAGE ImpredicativeTypes #-}
 {-# LANGUAGE TemplateHaskell #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-module Database.Persist.Zookeeper.Config
-    where
+module Database.Persist.Zookeeper.Config(
+  ZookeeperConf(..)
+, Connection
+, Action
+, execZookeeper
+, withZookeeperPool
+, runZookeeperPool
+, defaultZookeeperConf
+, defaultZookeeperSettings
+) where
 
 import Database.Persist
 import Database.Persist.TH
 import Language.Haskell.TH
-import qualified Database.Persist.Zookeeper.ZooUtil as Z
 import qualified Database.Zookeeper as Z
 import qualified Database.Zookeeper.Pool as Z
 import Data.Pool
 import Data.Aeson
-import Control.Monad (mzero, MonadPlus(..))
-import Control.Monad.IO.Class (MonadIO (..))
-import Control.Monad.Trans.Class (MonadTrans (..))
+import Control.Monad ()
+import Control.Monad.IO.Class
 import Control.Monad.Trans.Control
-import Control.Applicative (Applicative (..))
-import Control.Monad.Reader(ReaderT(..))
-import Control.Monad.Reader.Class
+import Control.Monad.Reader
 import Data.Scientific() -- we require only RealFrac instance of Scientific
-import           Data.Time
+import Data.Time
+import Control.Exception
+import Control.Concurrent
 
 -- | Information required to connect to a Zookeeper server
 data ZookeeperConf = ZookeeperConf {
@@ -39,57 +45,65 @@
 } deriving (Show)
 
 type Connection = Pool Z.Zookeeper
+type Action = ReaderT Z.Zookeeper
 
--- | Monad reader transformer keeping Zookeeper connection through out the work
-newtype ZookeeperT m a = ZookeeperT { runZookeeperT :: ReaderT Connection m a }
-    deriving (Monad, MonadIO, MonadTrans, Functor, Applicative, MonadPlus)
+instance HasPersistBackend Z.Zookeeper Z.Zookeeper where
+  persistBackend = id
 
--- | Extracts connection from ZookeeperT monad transformer
-thisConnection :: Monad m => ZookeeperT m Connection
-thisConnection = ZookeeperT ask
+execZookeeper :: (Read a,Show a,Monad m, MonadIO m) => (Z.Zookeeper -> IO (Either Z.ZKError a)) -> Action m a
+execZookeeper action = do
+  s <- ask
+  liftIO $ waitConnectedState s
+  r <- liftIO $ action s
+  case r of
+    (Right x) -> return x
+    (Left x)  -> liftIO $ throwIO $ userError $ "Zookeeper error: code" ++ show x --fail $ show x
+  where
+    waitConnectedState zh = do
+      s <- Z.getState zh
+      case s of
+        Z.ConnectingState -> do
+          threadDelay (50*1000)
+        _ -> return ()
 
 -- | Run a connection reader function against a Zookeeper configuration
-withZookeeperConn :: (Monad m, MonadIO m) => ZookeeperConf -> (Connection -> m a) -> m a
-withZookeeperConn conf connectionReader = do
-    conn <- liftIO $ createPoolConfig conf
-    connectionReader conn
-
-runZookeeperPool :: ZookeeperT m a -> Connection -> m a
-runZookeeperPool (ZookeeperT r) = runReaderT r
+withZookeeperPool :: (Monad m, MonadIO m) => ZookeeperConf -> (Connection -> m a) -> m a
+withZookeeperPool conf connectionReader = do
+  conn <- liftIO $ createPoolConfig conf
+  connectionReader conn
 
---runZookeeper :: ZookeeperT m a -> Connection -> m a
-runZookeeper :: MonadBaseControl IO m =>
-                Connection -> ReaderT Z.Zookeeper m b -> m b
-runZookeeper pool action = withResource pool (\stat -> runReaderT action stat)
+runZookeeperPool :: MonadBaseControl IO m =>
+                    Action m b -> Connection -> m b
+runZookeeperPool action pool = withResource pool (\stat -> runReaderT action stat)
 
 defaultZookeeperConf :: ZookeeperConf
-defaultZookeeperConf = ZookeeperConf "localhost:2181" 10000 1 50 30
+defaultZookeeperConf = ZookeeperConf "localhost:2181" 300000 1 300000 30
 
 defaultZookeeperSettings :: MkPersistSettings
 defaultZookeeperSettings = (mkPersistSettings $ ConT ''Z.Zookeeper)
 
 instance PersistConfig ZookeeperConf where
-    type PersistConfigBackend ZookeeperConf = ZookeeperT
-    type PersistConfigPool ZookeeperConf = Connection
+  type PersistConfigBackend ZookeeperConf = Action
+  type PersistConfigPool ZookeeperConf = Connection
 
-    loadConfig (Object o) = do
-        coord <- o .:? "coord" .!= "localhost:2181/"
-        timeout <- o .:? "timeout" .!= 10000
-        numstripes <- o .:? "num-stripes" .!= 1
-        (idletime :: Int) <- o .:? "idletime" .!= 30
-        maxresources <- o .:? "max-resource" .!= 50
+  loadConfig (Object o) = do
+      coord <- o .:? "coord" .!= "localhost:2181/"
+      timeout <- o .:? "timeout" .!= 300000
+      numstripes <- o .:? "num-stripes" .!= 1
+      (idletime :: Int) <- o .:? "idletime" .!= 300000
+      maxresources <- o .:? "max-resource" .!= 30
 
-        return ZookeeperConf {
-            zCoord = coord
-          , zTimeout = timeout
-          , zNumStripes = numstripes
-          , zIdleTime = fromIntegral idletime
-          , zMaxResources = maxresources
-        }
+      return ZookeeperConf {
+          zCoord = coord
+        , zTimeout = timeout
+        , zNumStripes = numstripes
+        , zIdleTime = fromIntegral idletime
+        , zMaxResources = maxresources
+      }
 
-    loadConfig _ = mzero
+  loadConfig _ = mzero
 
-    createPoolConfig (ZookeeperConf h t s idle maxres ) = 
-        Z.connect h t Nothing Nothing s idle maxres
+  createPoolConfig (ZookeeperConf h t s idle maxres ) =
+      Z.connect h t Nothing Nothing s idle maxres
 
-    runPool _ = runZookeeperPool
+  runPool _ = runZookeeperPool
diff --git a/Database/Persist/Zookeeper/Internal.hs b/Database/Persist/Zookeeper/Internal.hs
--- a/Database/Persist/Zookeeper/Internal.hs
+++ b/Database/Persist/Zookeeper/Internal.hs
@@ -1,7 +1,7 @@
 {-# LANGUAGE OverloadedStrings #-}
 module Database.Persist.Zookeeper.Internal
        where
-  
+
 import Control.Monad.IO.Class (MonadIO (..))
 import Data.Monoid
 import Data.Maybe
@@ -9,25 +9,34 @@
 import qualified Data.Text as T
 import Database.Persist.Types
 import Database.Persist.Class
+import Database.Persist.Zookeeper.Binary
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as BL
 import qualified Data.ByteString.Base64.URL as B64
 import qualified Data.Map as M
 
 
-txtToKey :: (PersistEntity val) => T.Text -> Key val
-txtToKey txt = 
-  case (keyFromValues [PersistText txt]) of
+
+txtToKey :: (PersistEntity val) => String -> Key val
+txtToKey txt =
+  case (keyFromValues [PersistText (T.pack txt)]) of
     Right v -> v
-    Left v -> error $ T.unpack v
+    Left _v ->
+      case B64.decode $ B.pack txt of
+        Left v -> error $ v
+        Right v' ->
+          case A.decode $ BL.fromStrict v' of
+            Just values ->
+              case (keyFromValues values) of
+                Right v -> v
+                Left v -> error $ T.unpack v
+            Nothing -> error "failed"
 
-keyToTxt :: (PersistEntity val) => Key val -> T.Text
---keyToTxt (Key (PersistText key)) = key
-keyToTxt key = 
+keyToTxt :: (PersistEntity val) => Key val -> String
+keyToTxt key =
   case keyToValues key of
-    [PersistText txt] -> txt
-    _ -> error "keyToTxt"
---keyToTxt v = error $ "do not support "++show v
+    [PersistText txt] -> T.unpack txt
+    v -> B.unpack $ B64.encode $ BL.toStrict $ A.encode $ v
 
 dummyFromKey :: Key v -> Maybe v
 dummyFromKey _ = Nothing
@@ -41,84 +50,91 @@
 val2table :: (PersistEntity val) => val -> T.Text
 val2table = unDBName . entityDB . entityDef . Just
 
+uniqkey2key :: (PersistEntity val) => Unique val -> Key val
+uniqkey2key uniqkey = txtToKey $ (B.unpack $ B64.encode $ BL.toStrict $ A.encode $ persistUniqueToValues uniqkey)
+
 val2uniqkey :: (MonadIO m, PersistEntity val) => val -> m (Maybe (Unique val))
 val2uniqkey val = do
   case persistUniqueKeys val of
     (uniqkey:_) -> return $ Just uniqkey
     [] -> return Nothing
 
-uniqkey2key :: (PersistEntity val) => Unique val -> Key val
-uniqkey2key uniqkey =
-  let dir = entity2path $ fromJust $ dummyFromUnique uniqkey
-    in txtToKey $ T.pack $ dir <> "/" <>  (B.unpack $ B64.encode $ BL.toStrict $ A.encode $ persistUniqueToValues uniqkey)
-
 entity2bin :: (PersistEntity val) => val -> B.ByteString
-entity2bin val = BL.toStrict (A.encode (map toPersistValue (toPersistFields val)))
-
-kv2v :: [PersistValue] -> [PersistValue]
-kv2v [] = []
-kv2v ((PersistList [_k,v] ):xs) = v:kv2v xs
-kv2v (x:xs) = x:kv2v xs
+entity2bin val = toValue (map toPersistValue (toPersistFields val))
 
 bin2entity :: (PersistEntity val) => B.ByteString -> Maybe val
 bin2entity bin =
-  case A.decode (BL.fromStrict bin) :: Maybe [PersistValue]of
-    Nothing -> Nothing
-    Just v ->
-      case fromPersistValues (kv2v v) of
-        Right body  -> Just $ body
-        Left s -> error $ T.unpack s
-  
+  case fromPersistValues (fromValue bin) of
+    Right body  -> Just $ body
+    Left s -> error $ T.unpack s
 
 entity2path :: (PersistEntity val) => val -> String
 entity2path val = "/" <> (T.unpack $ val2table val)
 
--- entityAndKey2path :: (PersistEntity val) => val -> Key val -> String
--- entityAndKey2path val (Key (PersistText txt)) = entity2path val <> "/" <>  ( B.unpack $ B64.encode $ B.pack $ T.unpack txt)
--- entityAndKey2path _ _ = error "key is not persist text"
-
--- key2path :: (PersistEntity val) => Key val -> String
--- key2path key = entityAndKey2path (fromJust (dummyFromKey key)) key
-
-
+key2path :: (PersistEntity val) => Key val -> String
+key2path key = entity2path $ fromJust $ dummyFromKey key
 
-filter2path :: (PersistEntity val) => [Filter val] -> String 
+filter2path :: (PersistEntity val) => [Filter val] -> String
 filter2path filterList = entity2path $ dummyFromFList filterList
 
 getMap :: PersistEntity val => val -> M.Map T.Text PersistValue
 getMap val =  M.fromList $ getList val
+
 getList :: PersistEntity val => val -> [(T.Text,PersistValue)]
-getList val =  
+getList val =
   let fields = fmap toPersistValue (toPersistFields val)
       in zip (getFieldsName val) fields
+
 getFieldsName :: (PersistEntity val) => val -> [T.Text]
 getFieldsName val =  fmap (unDBName.fieldDB) $ entityFields $ entityDef $ Just val
-getFieldName :: (PersistEntity val,PersistField typ) => EntityField val typ -> T.Text
+
+getFieldName :: (PersistEntity val) => EntityField val typ -> T.Text
 getFieldName field =  unDBName $ fieldDB $ persistFieldDef $ field
-fieldval :: (PersistEntity val,PersistField typ) => EntityField val typ -> val -> PersistValue
-fieldval field val =  (getMap val) M.! (getFieldName field)
 
+fieldval :: (PersistEntity val) => EntityField val typ -> val -> PersistValue
+fieldval field val = (getMap val) M.! (getFieldName field)
+
 updateEntity :: PersistEntity val =>  val -> [Update val] -> Either T.Text val
-updateEntity val upds = 
+updateEntity val upds =
   fromPersistValues $ map snd $ foldl updateVals (getList val) upds
 
-
 updateVals :: PersistEntity val =>  [(T.Text,PersistValue)] -> Update val -> [(T.Text,PersistValue)]
 updateVals [] _ = []
-updateVals ((k,v):xs) u@(Update field _ _) = 
+updateVals ((k,v):xs) u@(Update field _ _) =
   if getFieldName field == k
     then (k,updateVal v u):xs
     else (k,v):updateVals xs u
-updateVals _ _ = error "not supported"
+updateVals a _ = error $"not supported vals:" ++ show a
 
 updateVal :: PersistEntity val =>  PersistValue -> Update val -> PersistValue
-updateVal _v (Update _ val upd) = 
+updateVal _org (BackendUpdate _) = error $ "BackendUpdate is not supported."
+updateVal org (Update _ val upd) =
   case upd of
-    Assign -> toPersistValue val
-    _ -> error "not support"
-    -- Add -> (+) <$> v <$> toPersistValue val 
-    -- Subtract -> v - toPersistValue val 
-    -- Multiply -> v * toPersistValue val 
-    -- Divide -> v `div` toPersistValue val 
-updateVal _v _ = error "not supported"
-
+    Assign -> pval
+    Add -> numAdd org pval
+    Subtract -> numSub org pval
+    Multiply -> numMul org pval
+    Divide -> numDiv org pval
+    BackendSpecificUpdate _ -> error $ "BackendSpecificUpdate is not supported."
+  where
+    pval = toPersistValue val
+    numAdd (PersistInt64 l) (PersistInt64 r) =  (PersistInt64 (l + r))
+    numAdd (PersistNull) (PersistInt64 r) =  (PersistInt64 r)
+    numAdd (PersistDouble l) (PersistDouble r) =  (PersistDouble (l + r))
+    numAdd (PersistNull) (PersistDouble r) =  (PersistDouble r)
+    numAdd o _  = error $ "not support : " ++ show o
+    numSub (PersistInt64 l) (PersistInt64 r) =  (PersistInt64 (l - r))
+    numSub (PersistNull) (PersistInt64 r) =  (PersistInt64 (0 - r))
+    numSub (PersistDouble l) (PersistDouble r) =  (PersistDouble (l - r))
+    numSub (PersistNull) (PersistDouble r) =  (PersistDouble (0 - r))
+    numSub _ _  = error "not support"
+    numMul (PersistInt64 l) (PersistInt64 r) =  (PersistInt64 (l * r))
+    numMul (PersistNull) (PersistInt64 r) =  (PersistInt64 (0 * r))
+    numMul (PersistDouble l) (PersistDouble r) =  (PersistDouble (l * r))
+    numMul (PersistNull) (PersistDouble r) =  (PersistDouble (0 * r))
+    numMul _ _  = error "not support"
+    numDiv (PersistInt64 l) (PersistInt64 r) =  (PersistInt64 (l `div` r))
+    numDiv (PersistNull) (PersistInt64 r) =  (PersistInt64 (0 `div` r))
+    numDiv (PersistDouble l) (PersistDouble r) =  (PersistDouble (l / r))
+    numDiv (PersistNull) (PersistDouble r) =  (PersistDouble (0 / r))
+    numDiv _ _  = error "not support"
diff --git a/Database/Persist/Zookeeper/PathPiece.hs b/Database/Persist/Zookeeper/PathPiece.hs
deleted file mode 100644
--- a/Database/Persist/Zookeeper/PathPiece.hs
+++ /dev/null
@@ -1,22 +0,0 @@
-{-# LANGUAGE FlexibleContexts, UndecidableInstances #-}
-{-# LANGUAGE TypeFamilies #-}
-{-# LANGUAGE EmptyDataDecls #-}
-{-# LANGUAGE OverloadedStrings #-}
-{-# LANGUAGE FlexibleInstances #-}
-{-# OPTIONS_GHC -fno-warn-orphans #-}
-module Database.Persist.Zookeeper.PathPiece
-    where
-
-import qualified Database.Zookeeper as Z
-import Database.Persist
-import Database.Persist.Zookeeper.Store
-import Database.Persist.Zookeeper.ZooUtil
-import Web.PathPieces (PathPiece (..))
-import Control.Applicative
-
--- | ToPathPiece is used to convert a key to/from text
-instance PathPiece (BackendKey Z.Zookeeper) where
-  fromPathPiece txt = pure $ ZooKey txt
-  toPathPiece (ZooKey txt) = txt
-
-
diff --git a/Database/Persist/Zookeeper/Query.hs b/Database/Persist/Zookeeper/Query.hs
--- a/Database/Persist/Zookeeper/Query.hs
+++ b/Database/Persist/Zookeeper/Query.hs
@@ -9,12 +9,15 @@
 
 import Database.Persist
 import Data.Monoid
+import qualified Data.List as L
+import Control.Monad
 import Control.Monad.IO.Class (MonadIO (..))
 import Control.Monad.Trans.Reader
 import qualified Data.Text as T
 import qualified Database.Zookeeper as Z
+import Database.Persist.Zookeeper.Config
 import Database.Persist.Zookeeper.Internal
-import Database.Persist.Zookeeper.Store
+import Database.Persist.Zookeeper.Store ()
 import Database.Persist.Zookeeper.ZooUtil
 import Data.Conduit
 import qualified Data.Conduit.List as CL
@@ -34,76 +37,84 @@
             loop stat
           Nothing ->
             return ()
+
   deleteWhere filterList = do
-    (str::[String]) <- execZookeeperT $ \zk -> do
-      Z.getChildren zk (filter2path filterList) Nothing
+    (str::[String]) <- execZookeeper $ \zk -> do
+      zGetChildren zk (filter2path filterList)
     loop str
     where
       loop [] = return ()
       loop (x:xs) = do
-        let key = txtToKey $ T.pack $ (filter2path filterList) <> "/" <> x
+        let key = txtToKey x
+        case filterList of
+          [] -> delete key
+          _ -> del key
+        loop xs
+      del key = do
         va <- get key
         case va of
           Nothing -> return ()
           Just v -> do
-            let (chk,_,_) = filterClause v filterList 
+            let (chk,_,_) = filterClause v filterList
             if chk
               then delete key
               else return ()
-        loop xs
-  selectSourceRes filterList [] = do
+
+  selectSourceRes filterList opt = do
     stat <- ask
-    (str::[String]) <- liftIO $ flip runReaderT stat $ execZookeeperT $ \zk -> do
-      Z.getChildren zk (filter2path filterList) Nothing
+    (str::[String]) <- liftIO $ flip runReaderT stat $ do
+      keys <- execZookeeper $ \zk -> do
+        Z.getChildren zk (filter2path filterList) Nothing
+      selectOptParser keys opt
     return $ return $ loop stat str
     where
       loop _ [] = return ()
       loop stat (x:xs) = do
-        let key = txtToKey $ T.pack $ (filter2path filterList) <> "/" <> x
+        let key = txtToKey x
         va <- liftIO $ flip runReaderT stat $ get key
         case va of
           Nothing -> return ()
           Just v -> do
-            let (chk,_,_) = filterClause v filterList 
+            let (chk,_,_) = filterClause v filterList
             if chk
               then yield $ Entity key v
               else return ()
         loop stat xs
-  selectSourceRes _ _ = error "not supported selectOpt"
-  selectFirst filterList [] =  do
-    srcRes <- selectSourceRes filterList []
+
+  selectFirst filterList opt =  do
+    srcRes <- selectSourceRes filterList opt
     liftIO $ with srcRes ( $$ CL.head)
-  selectFirst _ _ = error "not supported selectOpt"
-  selectKeysRes filterList [] = do 
+
+  selectKeysRes filterList opt = do
     stat <- ask
-    (str::[String]) <- liftIO $ flip runReaderT stat $ execZookeeperT $ \zk -> 
-      Z.getChildren zk (filter2path filterList) Nothing
+    (str::[String]) <- liftIO $ flip runReaderT stat $ do
+      keys <- execZookeeper $ \zk -> do
+        Z.getChildren zk (filter2path filterList) Nothing
+      selectOptParser keys opt
     return $ return (loop stat str)
     where
       loop _ [] = return ()
       loop stat (x:xs) = do
-        let key = txtToKey $ T.pack $ (filter2path filterList) <> "/" <> x
+        let key = txtToKey x
         va <- liftIO $ flip runReaderT stat $ get key
         case va of
           Nothing -> return ()
           Just v -> do
-            let (chk,_,_) = filterClause v filterList 
+            let (chk,_,_) = filterClause v filterList
             if chk
               then yield key
               else return ()
         loop stat xs
-  selectKeysRes  _ _ = error "not supported selectOpt"
+
   count filterList = do
     v <- selectList filterList []
     return $ length v
 
-  
 dummyFromFilts :: [Filter v] -> Maybe v
 dummyFromFilts _ = Nothing
 
 data OrNull = OrNullYes | OrNullNo
 
-
 filterClauseHelper :: PersistEntity val
              => Bool -- ^ include WHERE?
              -> OrNull
@@ -127,17 +138,16 @@
     go (BackendFilter _) = error "BackendFilter not expected"
     go (FilterAnd []) = (True,"1=1", [])
     go (FilterAnd fs) = combineAND fs
-    go (FilterOr []) = (True,"1=0", [])
+    go (FilterOr []) = (False,"1=0", [])
     go (FilterOr fs)  = combineOR fs
-    go (Filter field value pfilter) = 
-      (showSqlFilter' pfilter (fieldval field val) allVals, 
+    go (Filter field value pfilter) =
+      (showSqlFilter' pfilter (fieldval field val) allVals,
       name <> ":"
-      <> T.pack (show (fieldval field val)) <> ":" 
+      <> T.pack (show (fieldval field val)) <> ":"
       <> showSqlFilter pfilter
       <> T.pack (show (showSqlFilter' pfilter (fieldval field val) allVals))
-      <> "?5:" <> T.pack (show allVals) <> orNullSuffix, allVals) 
+      <> "?5:" <> T.pack (show allVals) <> orNullSuffix, allVals)
       where
-        
         filterValueToPersistValues :: forall a.  PersistField a => Either a [a] -> [PersistValue]
         filterValueToPersistValues v = map toPersistValue $ either return id v
 
@@ -170,9 +180,81 @@
         showSqlFilter' NotIn a (x:xs) = if a==x then False else showSqlFilter' NotIn a xs
         showSqlFilter' (BackendSpecificFilter _s) _ _ =  error "not supported"
 
-
 filterClause :: PersistEntity val
              => val
              -> [Filter val]
              -> (Bool, T.Text, [PersistValue])
-filterClause val = filterClauseHelper True OrNullNo val
+filterClause _val [] = (True,"",[])
+filterClause val filter' = filterClauseHelper True OrNullNo val filter'
+
+
+addIdx :: [[String]] -> [(String,Int)]
+addIdx keys = concat $ map (\(i,ks) -> map (\k -> (k,i)) ks) $ zip [0..] keys
+
+delIdx :: [(String,Int)] -> [[String]]
+delIdx keys = fstIdx $ L.groupBy cmp keys
+  where
+    cmp :: (String,Int) -> (String,Int) -> Bool
+    cmp (_k0,i0) (_k1,i1) = i0==i1
+
+dropIdx :: Int -> [[String]] -> [[String]]
+dropIdx num keys = delIdx $ drop num $ addIdx keys
+
+takeIdx :: Int -> [[String]] -> [[String]]
+takeIdx num keys = delIdx $ take num $ addIdx keys
+
+sortIdx' :: Ord a => Bool -> [(String,a)] -> [[(String,a)]]
+sortIdx' asc keys = L.groupBy (\(_k0,i0) (_k1,i1)-> i0==i1) $ L.sortBy (cmp' asc) keys
+  where
+    cmp' True (_k0,v0) (_k1,v1) = compare v0 v1
+    cmp' False (_k0,v0) (_k1,v1) = compare v1 v0
+
+sortIdx :: Ord a => Bool -> [[(String,a)]] -> [[(String,a)]]
+sortIdx asc keys = concat $ map (sortIdx' asc) keys
+
+fstIdx :: Ord a => [[(String,a)]] -> [[String]]
+fstIdx keys = flip map keys $ \ks -> flip map ks $ \k -> fst k
+
+selectOptParser' :: (PersistStore backend, MonadIO m, PersistEntity val, backend ~ PersistEntityBackend val)
+                 => [[String]]
+                 -> [SelectOpt val]
+                 -> ReaderT backend m [[String]]
+selectOptParser' keys [] = do
+  return keys
+selectOptParser' keys (OffsetBy i:xs) = do
+  selectOptParser' (dropIdx i keys) xs
+selectOptParser' keys (LimitTo i:xs) = do
+  selectOptParser' (takeIdx i keys) xs
+selectOptParser' keys (Asc field:xs) = do
+  keysWithVal <- forM keys $ \ks -> do
+    forM ks $ \k -> do
+      let key = txtToKey k
+      val <- get key
+      case val of
+        Nothing -> fail "can not get value"
+        Just v -> return $ (k,fieldval field v)
+  selectOptParser' (fstIdx $ sortIdx True keysWithVal) xs
+selectOptParser' keys (Desc field:xs) = do
+  keysWithVal <- forM keys $ \ks -> do
+    forM ks $ \k -> do
+      let key = txtToKey k
+      val <- get key
+      case val of
+        Nothing -> fail "can not get value"
+        Just v -> return $ (k,fieldval field v)
+  selectOptParser' (fstIdx $ sortIdx False keysWithVal) xs
+
+selectOptParser :: (PersistStore backend, MonadIO m, PersistEntity val, backend ~ PersistEntityBackend val)
+                 => [String]
+                 -> [SelectOpt val]
+                 -> ReaderT backend m [String]
+selectOptParser keys opt' = do
+  keys' <- selectOptParser' [keys] $ selectOpt opt' [] Nothing Nothing
+  return $ concat keys'
+  where
+    selectOpt (opt@(Asc _):opts) sortOpt offset limit = selectOpt opts (sortOpt++[opt]) offset limit
+    selectOpt (opt@(Desc _):opts) sortOpt offset limit = selectOpt opts (sortOpt++[opt]) offset limit
+    selectOpt (opt@(LimitTo _):opts) sortOpt offset Nothing = selectOpt opts sortOpt offset (Just opt)
+    selectOpt (opt@(OffsetBy _):opts) sortOpt Nothing limit = selectOpt opts sortOpt (Just opt) limit
+    selectOpt (_opt:opts) sortOpt offset limit = selectOpt opts sortOpt offset limit
+    selectOpt [] sortOpt offset limit = sortOpt ++ maybe [] (\v -> [v]) offset ++ maybe [] (\v -> [v]) limit
diff --git a/Database/Persist/Zookeeper/Store.hs b/Database/Persist/Zookeeper/Store.hs
--- a/Database/Persist/Zookeeper/Store.hs
+++ b/Database/Persist/Zookeeper/Store.hs
@@ -5,104 +5,102 @@
 {-# LANGUAGE FlexibleInstances #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
-module Database.Persist.Zookeeper.Store where
+module Database.Persist.Zookeeper.Store (
+  deleteRecursive
+, BackendKey(..)
+)where
 
 import Database.Persist
 import qualified Database.Persist.Sql as Sql
--- import Database.Persist.Class
--- import Database.Persist.Types
-import Control.Exception
-import Control.Applicative
-import Control.Monad.IO.Class (MonadIO (..))
 import qualified Database.Zookeeper as Z
 import Data.Monoid
 import qualified Data.Text as T
--- import qualified Data.ByteString.Char8 as B
-import Database.Persist.Zookeeper.Config (ZookeeperT(..), thisConnection)
+import Database.Persist.Zookeeper.Config
 import Database.Persist.Zookeeper.Internal
 import Database.Persist.Zookeeper.ZooUtil
-import Data.Pool
 import Control.Monad
 import Control.Monad.Reader
 import qualified Data.Aeson as A
 
---data ZookeeperBackend
-
-  
--- -- | Execute Zookeeper transaction inside ZookeeperT monad transformer
-execZookeeperT :: (Read a,Show a,Monad m, MonadIO m) => (Z.Zookeeper -> IO (Either Z.ZKError a)) -> ReaderT Z.Zookeeper m a
-execZookeeperT action = do
-    s <- ask
-    r <- liftIO $ action s
-    case r of
-      (Right x) -> return x
-      (Left x)  -> liftIO $ throwIO $ userError $ "Zookeeper error: code" ++ show x --fail $ show x
-
--- instance PersistField DB.ObjectId where
---     toPersistValue = oidToPersistValue
---     fromPersistValue oid@(PersistObjectId _) = Right $ persistObjectIdToDbOid oid
---     fromPersistValue (PersistByteString bs) = fromPersistValue (PersistObjectId bs)
---     fromPersistValue _ = Left $ T.pack "expected PersistObjectId"
+import Web.PathPieces (PathPiece (..))
 
--- instance Sql.PersistFieldSql T.Text where
---     sqlType _ = Sql.SqlOther "doesn't make much sense for MongoDB"
+-- | ToPathPiece is used to convert a key to/from text
+instance PathPiece (BackendKey Z.Zookeeper) where
+    toPathPiece key = "z" <> (unZooKey key)
+    fromPathPiece keyText =
+      case T.uncons keyText of
+        Just ('z', prefixed) -> Just $ ZooKey prefixed
+        _ -> mzero
 
 instance Sql.PersistFieldSql (BackendKey Z.Zookeeper) where
-    sqlType _ = Sql.SqlOther "doesn't make much sense for MongoDB"
+    sqlType _ = Sql.SqlOther "doesn't make much sense for Zookeeper"
 
 instance A.ToJSON (BackendKey Z.Zookeeper) where
-    toJSON (ZooKey key) = A.String key
+    toJSON (ZooKey key) = A.toJSON $ "z" <> key
 
 instance A.FromJSON (BackendKey Z.Zookeeper) where
-    parseJSON (A.String key) = pure $ ZooKey key
-    parseJSON _ = mzero
+    parseJSON = A.withText "ZooKey" $ \t ->
+      case T.uncons t of
+        Just ('z', prefixed) -> return $ ZooKey prefixed
+        _ -> (fail "Invalid json for zookey")
 
 
+deleteRecursive :: (Monad m, MonadIO m) => String -> Action m ()
+deleteRecursive dir = execZookeeper $ \zk -> zDeleteRecursive zk dir
+
+
 instance PersistStore Z.Zookeeper where
-    --type PersistMonadBackend (ZookeeperT m) = ZookeeperBackend
     newtype BackendKey Z.Zookeeper = ZooKey { unZooKey :: T.Text }
         deriving (Show, Read, Eq, Ord, PersistField)
 
     insert val = do
-      let dir = entity2path val
-      let path = dir <> "/"
-      str <- execZookeeperT $ \zk -> do
-        zCreate zk dir path (Just (entity2bin val)) [Z.Sequence]
-      return $ txtToKey $ T.pack $ str
+      mUniqVal <- val2uniqkey val
+      case mUniqVal of
+        Just uniqVal -> do
+          let key = (uniqkey2key uniqVal)
+          execZookeeper $ \zk -> do
+            let dir = entity2path val
+            r <- zCreate zk dir (keyToTxt key) (Just (entity2bin val)) []
+            case r of
+              Right _ -> return $ Right $ key
+--              Left Z.NodeExistsError -> return $ Right $ Nothing
+              Left v -> return $ Left v
+        Nothing -> do
+          let dir = entity2path val
+          str <- execZookeeper $ \zk -> do
+            zCreate zk dir "" (Just (entity2bin val)) [Z.Sequence]
+          return $ txtToKey str
 
     insertKey key val = do
-      _ <- execZookeeperT $ \zk -> do
+      _ <- execZookeeper $ \zk -> do
         let dir = entity2path val
-        zCreate zk dir (T.unpack (keyToTxt key)) (Just (entity2bin val)) []
+        zCreate zk dir (keyToTxt key) (Just (entity2bin val)) []
       return ()
 
-    insertKey _ _ = fail "Wrong key type in insertKey"
-
     repsert key val = do
-      _ <- execZookeeperT $ \zk -> do
+      _ <- execZookeeper $ \zk -> do
         let dir = entity2path val
-        zRepSert zk dir (T.unpack (keyToTxt key)) (Just (entity2bin val))
+        zRepSert zk dir (keyToTxt key) (Just (entity2bin val))
       return ()
-    repsert _ _ = fail "Wrong key type in repsert"
 
     replace key val = do
-      execZookeeperT $ \zk -> do
-        _ <- zReplace zk (T.unpack (keyToTxt key)) (Just (entity2bin val))
+      execZookeeper $ \zk -> do
+        let dir = entity2path val
+        _ <- zReplace zk dir (keyToTxt key) (Just (entity2bin val))
         return $ Right ()
       return ()
 
-    replace _ _ = fail "Wrong key type in replace"
-
     delete key = do
-      execZookeeperT $ \zk -> do
-        _ <- Z.delete zk (T.unpack (keyToTxt key)) Nothing
+      execZookeeper $ \zk -> do
+        let dir = key2path key
+        _ <- zDelete zk dir (keyToTxt key) Nothing
         return $ Right ()
       return ()
-    delete _ = fail "Wrong key type in delete"
 
     get key = do
-      r <- execZookeeperT $ \zk -> do
-        val <- Z.get zk (T.unpack (keyToTxt key)) Nothing
+      r <- execZookeeper $ \zk -> do
+        let dir = key2path key
+        val <- zGet zk dir (keyToTxt key)
         return $ Right val
       case r of
         (Left Z.NoNodeError) ->
@@ -113,14 +111,13 @@
           return (bin2entity str)
         (Right (Nothing,_stat)) -> do
           fail $ "data is nothing"
-      
-    get  _ = fail "Wrong key type in get"
+
     update key valList = do
       va <- get key
       case va of
         Nothing -> return ()
         Just v ->
           case updateEntity v valList of
-            Right v' -> 
+            Right v' ->
               replace key v'
             Left v' -> error $ show v'
diff --git a/Database/Persist/Zookeeper/Unique.hs b/Database/Persist/Zookeeper/Unique.hs
--- a/Database/Persist/Zookeeper/Unique.hs
+++ b/Database/Persist/Zookeeper/Unique.hs
@@ -8,16 +8,11 @@
        where
 
 import Database.Persist
-import Control.Applicative (Applicative)
-import Control.Monad.IO.Class (MonadIO (..))
-import Control.Monad.Trans.Control (MonadBaseControl)
-import qualified Data.Text as T
 import qualified Database.Zookeeper as Z
-import Database.Persist.Zookeeper.Config
 import Database.Persist.Zookeeper.Internal
-import Database.Persist.Zookeeper.Store
-import Database.Persist.Zookeeper.ZooUtil
+import Database.Persist.Zookeeper.Store()
 
+
 instance PersistUnique Z.Zookeeper where
     getBy uniqVal = do
       let key = uniqkey2key uniqVal
@@ -29,20 +24,3 @@
     deleteBy uniqVal = do
       let key = uniqkey2key uniqVal
       delete key
-      
-    insertUnique val = do
-      mUniqVal <- val2uniqkey val
-      case mUniqVal of
-        Just uniqVal -> do
-          let key = (uniqkey2key uniqVal)
-          let txt = keyToTxt key
-          execZookeeperT $ \zk -> do
-            let dir = entity2path val
-            r <- zCreate zk dir (T.unpack txt) (Just (entity2bin val)) []
-            case r of
-              Right _ -> return $ Right $ Just key
-              Left Z.NodeExistsError -> return $ Right $ Nothing
-              Left v -> return $ Left v
-        Nothing -> do
-          return $ Nothing
-
diff --git a/Database/Persist/Zookeeper/ZooUtil.hs b/Database/Persist/Zookeeper/ZooUtil.hs
--- a/Database/Persist/Zookeeper/ZooUtil.hs
+++ b/Database/Persist/Zookeeper/ZooUtil.hs
@@ -12,43 +12,59 @@
 
 import qualified Database.Zookeeper as Z
 import qualified Data.ByteString.Char8 as B
--- import qualified Data.ByteString.Lazy as BL
-import qualified Data.Pool as P
-import Control.Concurrent
-import Control.Concurrent.STM
-import Data.Time
-import Data.Maybe
+import Control.Monad
+import Data.Monoid
 
 deriving instance Read (Z.ZKError)
 deriving instance Read (Z.Stat)
 
+zGet :: Z.Zookeeper
+     -> String
+     -> String
+     -> IO (Either Z.ZKError (Maybe B.ByteString, Z.Stat))
+zGet zk dir key = do
+  let path = dir <> "/" <> key
+  Z.get zk path Nothing
+
+zSet :: Z.Zookeeper
+     -> String
+     -> String
+     -> Maybe B.ByteString
+     -> Maybe Z.Version
+     -> IO (Either Z.ZKError Z.Stat)
+zSet zk dir key dat ver = do
+  let path = dir <> "/" <> key
+  Z.set zk path dat ver
+
 zModify :: Z.Zookeeper
-       -> String
-       -> (Maybe B.ByteString -> IO (Maybe B.ByteString))
-       -> IO (Either Z.ZKError Z.Stat)
-zModify  zk key f = do
-  v <- Z.get zk key Nothing
+        -> String
+        -> String
+        -> (Maybe B.ByteString -> IO (Maybe B.ByteString))
+        -> IO (Either Z.ZKError Z.Stat)
+zModify  zk dir key f = do
+  v <- zGet zk dir key
   case v of
     Right (con,ver) -> do
       v'' <- f con
-      v' <- Z.set zk key v'' (Just (Z.statVersion ver))
+      v' <- zSet zk dir key v'' (Just (Z.statVersion ver))
       case v' of
         Right _ -> return v'
-        Left _ -> zModify zk key f
+        Left _ -> zModify zk dir key f
     Left e -> return $ Left e
 
 zReplace :: Z.Zookeeper
-       -> String
-       -> (Maybe B.ByteString)
-       -> IO (Either Z.ZKError Z.Stat)
-zReplace  zk key v'' = do
-  v <- Z.get zk key Nothing
+         -> String
+         -> String
+         -> (Maybe B.ByteString)
+         -> IO (Either Z.ZKError Z.Stat)
+zReplace  zk dir key v'' = do
+  v <- zGet zk dir key
   case v of
     Right (_con,ver) -> do
-      v' <- Z.set zk key v'' (Just (Z.statVersion ver))
+      v' <- zSet zk dir key v'' (Just (Z.statVersion ver))
       case v' of
         Right _ -> return v'
-        Left _ -> zReplace zk key v''
+        Left _ -> zReplace zk dir key v''
     Left e -> return $ Left e
 
 zRepSert :: Z.Zookeeper
@@ -61,7 +77,7 @@
   case v of
     Right _ -> return $ Right ()
     Left Z.NodeExistsError -> do
-      v' <- zReplace zk key v''
+      v' <- zReplace zk dir key v''
       case v' of
         Right _ -> return $ Right ()
         Left Z.NoNodeError -> do
@@ -70,19 +86,68 @@
           return $ Left s
     Left v' -> return $ Left v'
 
+
+zGetChildren :: Z.Zookeeper
+             -> String
+             -> IO (Either Z.ZKError [String])
+zGetChildren  zk dir = do
+  v <- Z.getChildren zk dir Nothing
+  case v of
+    Right _ -> return v
+    Left Z.NoNodeError -> return $ Right []
+    Left _ -> return v
+
 zCreate :: Z.Zookeeper
        -> String
        -> String
        -> Maybe B.ByteString
        -> [Z.CreateFlag]
        -> IO (Either Z.ZKError String)
-zCreate zk dir path value flag = do
+zCreate zk dir key value flag = do
+  let path = dir <> "/" <> key
   v <- Z.create zk path value Z.OpenAclUnsafe flag
   case v of
     Left Z.NoNodeError -> do
       v' <- Z.create zk dir Nothing Z.OpenAclUnsafe []
       case v' of
-        Left v'' -> return $ Left v''
-        Right _ -> zCreate zk dir path value flag
-    v' -> return v'
+        Left _ -> return $ v'
+        Right _ -> zCreate zk dir key value flag
+    Left _ -> return v
+--    See https://issues.apache.org/jira/browse/ZOOKEEPER-1027
+--    Do not use libzookeeper under 3.3.5, Z.create returns wrong node path
+--    Use libzookeeper over 3.4.*
+    Right path' -> return $ Right $ drop (length ( dir <> "/" )) path'
 
+zDelete :: Z.Zookeeper
+        -> String
+        -> String
+        -> Maybe Z.Version
+        -> IO (Either Z.ZKError ())
+zDelete zk dir key mversion = do
+  let path = dir <> "/" <> key
+  Z.delete zk path mversion
+
+zDeleteRecursive :: Z.Zookeeper
+                 -> String
+                 -> IO (Either Z.ZKError ())
+zDeleteRecursive zk dir = do
+  ls <- zGetTree zk dir
+  res <- forM (reverse ls) $ \node ->
+    Z.delete zk node Nothing
+  return $ checkRes res
+  where
+    checkRes [] = Right ()
+    checkRes (Left val:_) = Left val
+    checkRes (Right _:xs) = checkRes xs
+
+zGetTree :: Z.Zookeeper
+         -> String
+         -> IO [String]
+zGetTree zk dir = do
+  ls <- Z.getChildren zk dir Nothing
+  case ls of
+    Right dir' -> do
+      ls' <- forM dir' $ \d -> do
+        zGetTree zk (dir <> "/" <> d)
+      return $ concat ls'
+    Left err' -> error ("zGetTree's error:" ++ show err')
diff --git a/persistent-zookeeper.cabal b/persistent-zookeeper.cabal
--- a/persistent-zookeeper.cabal
+++ b/persistent-zookeeper.cabal
@@ -1,5 +1,5 @@
 name:            persistent-zookeeper
-version:         0.1.0
+version:         0.2.0
 license:         BSD3
 license-file:    LICENSE
 author:          Junji Hashimoto <junji.hashimoto@gree.net>
@@ -37,10 +37,10 @@
                    , path-pieces
                    , template-haskell
                    , base64-bytestring
-                   , stm
                    , conduit
                    , containers
                    , resourcet
+                   , binary
 
     exposed-modules: Database.Persist.Zookeeper
 
@@ -49,8 +49,8 @@
                      Database.Persist.Zookeeper.Store
                      Database.Persist.Zookeeper.Unique
                      Database.Persist.Zookeeper.Query
-                     Database.Persist.Zookeeper.PathPiece
                      Database.Persist.Zookeeper.ZooUtil
+                     Database.Persist.Zookeeper.Binary
 
     ghc-options:     -Wall
 
@@ -63,7 +63,6 @@
                    , mtl
                    , transformers
                    , transformers-base
-                   , utf8-string           >= 0.3.7    && < 0.4.0
                    , bytestring            >= 0.10.0.0 && < 0.11.0.0
                    , text                  >= 0.8
                    , aeson                 >= 0.5
@@ -80,7 +79,6 @@
                    , path-pieces
                    , base64-bytestring
                    , hspec
-                   , stm
                    , conduit
                    , containers
                    , resourcet
diff --git a/tests/basic-test.hs b/tests/basic-test.hs
--- a/tests/basic-test.hs
+++ b/tests/basic-test.hs
@@ -4,14 +4,14 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
 module Main where
 
-import qualified Database.Zookeeper as Z
+import Database.Zookeeper ()
 import Database.Persist
 import Database.Persist.Zookeeper
 import Database.Persist.Zookeeper.Internal
 import Database.Persist.TH
-import Language.Haskell.TH.Syntax
+import Language.Haskell.TH.Syntax ()
 import Data.Maybe
-import Data.Pool
+import Data.Pool ()
 import Test.Hspec
 
 let zookeeperSettings = defaultZookeeperSettings
@@ -29,37 +29,37 @@
 zookeeperConf = ZookeeperConf "localhost:2181" 10000 1 50 30
 
 main :: IO ()
-main = 
-  withZookeeperConn zookeeperConf $ \conn -> do
+main =
+  withZookeeperPool zookeeperConf $ \conn -> do
     hspec $ do
-      let key = txtToKey "/person/WyJzVGVzdC9ob2dlIl0="
+      let key = txtToKey "WyJzVGVzdC9ob2dlIl0="
       let val = Person "Test/hoge" 12 Nothing
       describe "PersistUnique test" $ do
         it "insertUnique" $ do
-          v <- runZookeeper conn $ do
+          v <- flip runZookeeperPool conn $ do
             deleteBy $ PersonU "Test/hoge"
             insertUnique val
           v `shouldBe` (Just key)
         it "getBy" $ do
-          v <- runZookeeper conn $ do
-            getBy $ PersonU "Test/hoge" 
+          v <- flip runZookeeperPool conn $ do
+            getBy $ PersonU "Test/hoge"
           (entityKey (fromJust v)) `shouldBe` key
           (entityVal (fromJust v)) `shouldBe` val
           v `shouldBe` (Just (Entity key val))
         it "deleteBy" $ do
-          v <- runZookeeper conn $ do
+          v <- flip runZookeeperPool conn $ do
             deleteBy $ PersonU "Test/hoge"
             getBy $ PersonU "Test/hoge"
           v `shouldBe` Nothing
       describe "PersistStore test" $ do
         it "StoreTest" $ do
-          key' <- runZookeeper conn $ do
+          key' <- flip runZookeeperPool conn $ do
             insert val
-          v <- runZookeeper conn $ do
+          v <- flip runZookeeperPool conn $ do
             get key'
           print $ show key'
           v `shouldBe` (Just val)
-          v' <- runZookeeper conn $ do
+          v' <- flip runZookeeperPool conn $ do
             delete key'
             get key'
           v' `shouldBe` Nothing
@@ -68,6 +68,13 @@
                                            a@(bool,_,_) -> do
                                            print $ show a
                                            bool `shouldBe` expbool
+        it "FilterTest Filter OR/AND" $ do
+          check (Person "Test/hoge" 12 Nothing) [FilterOr[]] False
+          check (Person "Test/hoge" 12 Nothing) [FilterAnd[]] True
+        it "FilterTest Nothing" $ do
+          check (Person "Test/hoge" 12 Nothing) [] True
+          check (Person "Test/hoge" 12 (Just 3)) [] True
+          check (Person "Test/hoge" 12 Nothing) [] True
         it "FilterTestEq" $ do
           check (Person "Test/hoge" 12 Nothing) [PersonName ==. ""] False
           check (Person "Test/hoge" 12 (Just 3)) [PersonHoge ==. Just 3] True
@@ -82,7 +89,7 @@
           check (Person "Test/hoge" 12 (Just 4)) [PersonHoge <=. Just 3] False
           check (Person "Test/hoge" 12 (Just 2)) [PersonHoge <=. Just 3] True
         it "StoreTest" $ do
-          va <- runZookeeper conn $ do
+          va <- flip runZookeeperPool conn $ do
             deleteWhere [PersonName !=. ""]
             _ <- insert (Person "hoge0" 1 Nothing)
             _ <- insert (Person "hoge1" 2 Nothing)
@@ -90,17 +97,17 @@
             _ <- insert (Person "hoge3" 4 Nothing)
             selectList [PersonAge ==. 2] []
           (entityVal (head va)) `shouldBe` (Person "hoge1" 2 Nothing)
-          [Entity _k v] <- runZookeeper conn $ do
+          [Entity _k v] <- flip runZookeeperPool conn $ do
             selectList [PersonName ==. "hoge2"] []
           v `shouldBe` (Person "hoge2" 3 Nothing)
-          [Entity _k v1] <- runZookeeper conn $ do
+          [Entity _k v1] <- flip runZookeeperPool conn $ do
             updateWhere [PersonName ==. "hoge2"] [PersonAge =. 10]
             selectList [PersonName ==. "hoge2"] []
           v1 `shouldBe` (Person "hoge2" 10 Nothing)
-          v2 <- runZookeeper conn $ do
+          v2 <- flip runZookeeperPool conn $ do
             selectList [PersonName !=. ""] []
           length v2 `shouldBe` 4
-          v3 <- runZookeeper conn $ do
+          v3 <- flip runZookeeperPool conn $ do
             deleteWhere [PersonName !=. ""]
             selectList [PersonName !=. ""] []
           length v3 `shouldBe` 0
