diff --git a/CHANGES b/CHANGES
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,10 @@
+0.1.0
+
+ - Added increment/decrement commands
+ - Added add and replace commands
+ - Added 'update' operation which allows an atomic
+   operation on a cached value
+
 0.0.1
 
  - Initial release
diff --git a/Network/Starling.hs b/Network/Starling.hs
--- a/Network/Starling.hs
+++ b/Network/Starling.hs
@@ -39,14 +39,16 @@
     , Key
     , Value
     , Result
+    , ResultM
     , ResponseStatus(..)
     , set
     , get
     , delete
-    -- , add
-    -- , replace
-    -- , increment
-    -- , decrement
+    , add
+    , replace
+    , update
+    , increment
+    , decrement
     , flush
     , stats
     -- , oneStat -- doesn't seem to work for me
@@ -71,13 +73,32 @@
 
 import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString.Lazy as BS
+import qualified Data.Binary.Get as B
 
-type Result a = IO (Either (ResponseStatus, ByteString) a)
+import Data.Word
 
+import Control.Monad.Trans (liftIO, MonadIO)
+
+type Result a = ResultM IO a
+
+-- | If an operation fails the result will return in 'Left'
+-- with the failure code and a text description of the failure
+type ResultM m a = m (Either (ResponseStatus, ByteString) a)
+
 -- | Set a value in the cache
 set :: Connection -> Key -> Value -> Result ()
 set con key value = simpleRequest con (Core.set key value) (const ())
 
+-- | Set a vlue in the cache. Fails if a value is already defined
+-- for the indicated key.
+add :: Connection -> Key -> Value -> Result ()
+add con key value = simpleRequest con (Core.add key value) (const ())
+
+-- | Set a value in the cache. Fails if a value is not already defined
+-- for the indicated key.
+replace :: Connection -> Key -> Value -> Result ()
+replace con key value = simpleRequest con (Core.replace key value) (const ())
+
 -- | Retrive a value from the cache
 get :: Connection -> Key -> Result ByteString
 get con key = simpleRequest con (Core.get key) rsBody
@@ -86,6 +107,49 @@
 delete :: Connection -> Key -> Result ()
 delete con key = simpleRequest con (Core.delete key) (const ())
 
+-- | Update a value in the cache. This operation requires two round trips.
+-- This operation can fail if the key is not present in the cache, or if
+-- the value changes in the cache between the two calls.
+-- So watch out! Even if the value exists the operation might
+-- not go through in the face of concurrent access.
+--
+-- Testing indicates that if we fail because we could not gaurantee
+-- atomicity the failure code will be 'KeyExists'.
+update :: MonadIO m =>
+          Connection -> Key -> (Value -> m (Maybe Value)) -> ResultM m ()
+update con key f
+    = do
+  response <- liftIO $ synchRequest con (Core.get key)
+  case rsStatus response of
+    NoError -> do
+        let oldVal = rsBody response
+            cas = rsCas response
+        res <- f oldVal
+        let baseRequest = case res of
+                            Nothing -> Core.delete key
+                            Just newVal -> Core.replace key newVal
+            request = addCAS cas $ baseRequest
+        liftIO $ simpleRequest con request (const ())
+    _ -> return . errorResult $ response
+
+-- | Increment a value in the cache. The first 'Word64' argument is the
+-- amount by which to increment and the second is the intial value to
+-- use of the key does not yet have a value.
+-- The return value is the updated value in the cache.
+increment :: Connection -> Key -> Word64 -> Word64 -> Result Word64
+increment con key amount init
+    = simpleRequest con (Core.increment key amount init) $ \response ->
+      B.runGet B.getWord64be (rsBody response)
+
+-- | Decrement a value in the cache. The first 'Word64' argument is the
+-- amount by which to decrement and the second is the intial value to
+-- use of the key does not yet have a value.
+-- The return value is the updated value in the cache.
+decrement :: Connection -> Key -> Word64 -> Word64 -> Result Word64
+decrement con key amount init
+    = simpleRequest con (Core.decrement key amount init) $ \response ->
+      B.runGet B.getWord64be (rsBody response)
+
 -- | Delete all entries in the cache
 flush :: Connection -> Result ()
 flush con = simpleRequest con Core.flush (const ())
@@ -111,8 +175,12 @@
      if rsStatus resp == NoError
       then return . Right . unpackStats $ resps
       else return $ errorResult resp
- where unpackStats = filter (\(x,y) -> not (BS.null x && BS.null y)) .
-                     map (\response -> (rsKey response, rsBody response))
+
+ where
+
+   unpackStats
+       = filter (\(x,y) -> not (BS.null x && BS.null y)) .
+         map (\response -> (rsKey response, rsBody response))
 
 -- | Returns a single stat. Example: 'stat con "pid"' will return
 -- the 
diff --git a/Network/Starling/Core.hs b/Network/Starling/Core.hs
--- a/Network/Starling/Core.hs
+++ b/Network/Starling/Core.hs
@@ -32,7 +32,6 @@
     , Response(..)
     , getResponse
     , StarlingReadError(..)
-    , StarlingReadError
     , Serialize(..)
     , Deserialize(..)
     , Opaque
@@ -54,8 +53,6 @@
 
 import Data.ByteString.Lazy (ByteString)
 import qualified Data.ByteString.Lazy as BS
-
-import Data.ByteString.Lazy.Char8()
 
 import qualified Data.Binary.Builder as B
 import qualified Data.Binary.Get as B
diff --git a/starling.cabal b/starling.cabal
--- a/starling.cabal
+++ b/starling.cabal
@@ -1,5 +1,5 @@
 name:            starling
-version:         0.0.2
+version:         0.1.0
 stability:       Alpha
 
 synopsis:        A memcached client
@@ -20,7 +20,7 @@
 
 cabal-version:   >= 1.6
 
-build-depends:   base==4.*, binary, bytestring
+build-depends:   base == 4.*, binary, bytestring, transformers == 0.1.*
 build-type:      Simple
 
 extra-source-files: CHANGES
