diff --git a/Database/Redis/Internal.hs b/Database/Redis/Internal.hs
--- a/Database/Redis/Internal.hs
+++ b/Database/Redis/Internal.hs
@@ -68,7 +68,7 @@
     show (RBulk Nothing) = "RBulk Nothing"
     show (RMulti (Just rs)) = "RMulti [" ++ join rs ++ "]"
                               where join = concat . intersperse ", " . map show
-    show (RMulti Nothing) = "[]"
+    show (RMulti Nothing) = "RMulti Nil"
 
 data (BS s) => Message s = MSubscribe s Int
                          | MUnsubscribe s Int
diff --git a/Database/Redis/Monad.hs b/Database/Redis/Monad.hs
--- a/Database/Redis/Monad.hs
+++ b/Database/Redis/Monad.hs
@@ -154,6 +154,26 @@
                                         liftIO $ Internal.sendCommand rs (Internal.CInline "EXEC")
                                         liftIO $ Internal.recv rs)
 
+watch :: (WithRedis m, BS s) => [s] -> m (R.Reply ())
+watch cs = getRedis >>= liftIO . flip R.watch cs
+
+unwatch :: WithRedis m => m (R.Reply ())
+unwatch = getRedis >>= liftIO . R.unwatch
+
+run_cas :: (MonadCatchIO m, WithRedis m, BS s1, BS s2) => [s1] -> m (R.Reply s2) -> m (R.Reply s2)
+run_cas keys cs = let keys' = map toBS keys
+                  in do r <- getRedis
+                        bracket (liftIO $ Internal.takeState r)
+                                (\_ -> liftIO $ Internal.putStateUnmodified r)
+                                (\rs -> do liftIO $ (Internal.sendCommand rs (Internal.CMBulk ("WATCH" : keys')))
+                                                      >> (Internal.recv rs :: IO (Internal.Reply ()))
+                                                      >>= R.fromROk
+                                           res <- cs
+                                           liftIO $ (Internal.sendCommand rs (Internal.CInline "UNWATCH"))
+                                                      >> (Internal.recv rs :: IO (Internal.Reply ()))
+                                                      >>= R.fromROk
+                                           return res)
+
 exists :: (WithRedis m, BS s) => s -> m (R.Reply Int)
 exists key = getRedis >>= liftIO . flip R.exists key
 
diff --git a/Database/Redis/Redis.hs b/Database/Redis/Redis.hs
--- a/Database/Redis/Redis.hs
+++ b/Database/Redis/Redis.hs
@@ -45,7 +45,8 @@
        -- * Redis commands
        -- ** Generic
        ping, auth, quit, shutdown,
-       multi, exec, discard, run_multi, exists,
+       multi, exec, discard, run_multi,
+       watch, unwatch, run_cas, exists,
        del, getType, keys, randomKey, rename,
        renameNx, dbsize, expire, expireAt,
        ttl, select, move, flushDb,
@@ -285,6 +286,45 @@
                                           sequence_ cs'
                                           sendCommand rs (CInline "EXEC")
                                           recv rs) r
+
+-- | Add keys to a watch list for Check-and-Set operation.
+--
+-- For more information see <http://code.google.com/p/redis/wiki/MultiExecCommand>
+--
+-- ROk returned
+watch :: BS s =>
+         Redis
+      -> [s]                    -- ^ keys to watch for
+      -> IO (Reply ())
+watch r keys = withState r (\rs -> sendCommand rs (CMBulk ("WATCH" : map toBS keys)) >> recv rs)
+
+-- | Force unwatch all watched keys
+--
+-- For more information see <http://code.google.com/p/redis/wiki/MultiExecCommand>
+--
+-- ROk returned
+unwatch :: Redis -> IO (Reply ())
+unwatch = withState' (\rs -> sendCommand rs (CInline "UNWATCH") >> recv rs)
+
+-- | Run actions in a CAS manner
+--
+-- You have to explicitly add multi/exec commands to an appropriate
+-- place in an action sequence. Command sequence will be explicitly
+-- terminated with /unwatch/ command even if /exec/ command was sent.
+--
+-- Result of user-defined action returned
+run_cas :: (BS s1, BS s2) =>
+           Redis
+        -> [s1]                 -- ^ keys watched
+        -> IO (Reply s2)        -- ^ action to run
+        -> IO (Reply s2)
+run_cas r keys cs = let keys' = map toBS keys
+                    in withState r (\rs -> do sendCommand rs (CMBulk ("WATCH" : keys'))
+                                              (recv rs :: IO (Reply ())) >>= fromROk
+                                              res <- cs
+                                              sendCommand rs (CInline "UNWATCH")
+                                              (recv rs :: IO (Reply ())) >>= fromROk
+                                              return res)
 
 -- | Test if the key exists
 --
diff --git a/redis.cabal b/redis.cabal
--- a/redis.cabal
+++ b/redis.cabal
@@ -1,5 +1,5 @@
 Name:                redis
-Version:             0.6
+Version:             0.7
 License:             MIT
 Maintainer:          Alexander Bogdanov <andorn@gmail.com>
 Author:              Alexander Bogdanov <andorn@gmail.com>
@@ -16,16 +16,12 @@
 	protocol. Most of the functions will work correctly with stable version
 	but not all.
 	.
-	Changes from v0.5:
-	.
-	- zunion and zinter was renamed to zunionstore and zinterstore.
-	  Important! It makes this version incompatible with older versions of Redis server.
+	Changes from v0.6:
 	.
-	- new message type for pmessages: MPMessage
+	- new commands added: watch, unwatch
 	.
-	- new reply type RParseError used for replies that was failed to convert from ByteString
+	- new batch command: run_cas
 	.
-	- new command added: setEx
 
 Stability:           beta
 Build-Type:          Simple
