diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,10 @@
+## 0.1.1.0
+
+- Export DecryptedData type.
+- Add function to unwrap DecryptedData.
+- Add two additional helper functions.
+- Improve documentation.
+
+## 0.1.0.0
+
+- Initial release.
diff --git a/rails-session.cabal b/rails-session.cabal
--- a/rails-session.cabal
+++ b/rails-session.cabal
@@ -1,5 +1,5 @@
 name:                rails-session
-version:             0.1.0.0
+version:             0.1.1.0
 synopsis:            Decrypt Ruby on Rails sessions in Haskell
 description:         Please see README.md
 homepage:            http://github.com/iconnect/rails-session#readme
@@ -11,6 +11,7 @@
 category:            Web
 build-type:          Simple
 cabal-version:       >=1.10
+extra-source-files:  CHANGELOG.md
 
 Source-repository head
   type: git
@@ -38,14 +39,12 @@
   main-is:             Spec.hs
   build-depends:       base
                      , bytestring
+                     , filepath
                      , rails-session
                      , ruby-marshal
                      , tasty
                      , tasty-hspec
+                     , transformers
                      , vector
   ghc-options:         -threaded -rtsopts -with-rtsopts=-N
   default-language:    Haskell2010
-
-source-repository head
-  type:     git
-  location: https://github.com/iconnect/haskell-oss/rails-interop
diff --git a/src/Web/Rails/Session.hs b/src/Web/Rails/Session.hs
--- a/src/Web/Rails/Session.hs
+++ b/src/Web/Rails/Session.hs
@@ -10,6 +10,8 @@
   -- * Decrypting
   , decrypt
   -- * Utilities
+  , csrfToken
+  , sessionId
   , lookupString
   , lookupFixnum
   -- * Lifting weaker types into stronger types
@@ -19,6 +21,8 @@
   , mkSalt
   , SecretKeyBase
   , mkSecretKeyBase
+  , DecryptedData
+  , unwrapDecryptedData
   ) where
 
 import              Control.Applicative ((<$>))
@@ -43,49 +47,68 @@
 
 -- TYPES
 
+-- | Wrapper around data after it has been decrypted.
 newtype DecryptedData =
   DecryptedData ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around data before it has been decrypted.
 newtype EncryptedData =
   EncryptedData ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around initialisation vector.
 newtype InitVector =
   InitVector ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around raw cookie.
 newtype Cookie =
   Cookie ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around salt.
 newtype Salt =
   Salt ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around secret.
 newtype SecretKey =
   SecretKey ByteString
   deriving (Show, Ord, Eq)
 
+-- | Wrapper around secret key base.
 newtype SecretKeyBase =
   SecretKeyBase ByteString
   deriving (Show, Ord, Eq)
 
 -- SMART CONSTRUCTORS
 
+-- | Lift a cookie into a richer type.
 mkCookie :: ByteString -> Cookie
 mkCookie = Cookie
 
+-- | Lift salt into a richer type.
 mkSalt :: ByteString -> Salt
 mkSalt = Salt
 
+-- | Lifts secret into a richer type.
 mkSecretKeyBase :: ByteString -> SecretKeyBase
 mkSecretKeyBase = SecretKeyBase
 
+-- SMART DESTRUCTORS
+
+unwrapDecryptedData :: DecryptedData -> ByteString
+unwrapDecryptedData (DecryptedData deData) =
+  deData
+
 -- EXPORTS
 
 -- | Decode a cookie encrypted by Rails.
-decode :: Maybe Salt -> SecretKeyBase -> Cookie -> Maybe RubyObject
+decode :: Maybe Salt
+       -> SecretKeyBase
+       -> Cookie
+       -> Maybe RubyObject
 decode mbSalt secretKeyBase cookie =
   either (const Nothing) Just (decodeEither mbSalt secretKeyBase cookie)
 
@@ -108,26 +131,39 @@
         -> Cookie
         -> Either String DecryptedData
 decrypt mbSalt secretKeyBase cookie =
-  let salt = fromMaybe (Salt "encrypted cookie") mbSalt
+  let salt = fromMaybe defaultSalt mbSalt
       (SecretKey secret) = generateSecret salt secretKeyBase
-      key = BS.take 32 secret
       (EncryptedData encData, InitVector initVec) = prepare cookie
   in case makeIV initVec of
        Nothing ->
          Left $! "Failed to build init. vector for: " <> show initVec
-       Just initVec' ->
+       Just initVec' -> do
+         let key = BS.take 32 secret
          case (cipherInit key :: CryptoFailable AES256) of
            CryptoFailed errorMessage ->
              Left (show errorMessage)
            CryptoPassed cipher ->
              Right . DecryptedData $! cbcDecrypt cipher initVec' encData
+  where
+    defaultSalt :: Salt
+    defaultSalt = Salt "encrypted cookie"
 
+-- UTIL
+
+-- | Helper function for looking up the csrf token in a cooie.
+csrfToken :: RubyObject -> Maybe ByteString
+csrfToken = lookupString "_csrf_token" US_ASCII
+
+-- | Helper function for looking up the session id in a cookie.
+sessionId :: RubyObject -> Maybe ByteString
+sessionId = lookupString "session_id" UTF_8
+
 -- | Lookup integer for a given key.
 lookupFixnum :: ByteString -> RubyStringEncoding -> RubyObject -> Maybe Int
-lookupFixnum k enc m =
-  case lookup (RIVar (RString k, enc)) m of
-    Just (RFixnum v) ->
-      Just v
+lookupFixnum key enc rubyObject =
+  case lookup (RIVar (RString key, enc)) rubyObject of
+    Just (RFixnum val) ->
+      Just val
     _ ->
       Nothing
 
@@ -136,14 +172,14 @@
              -> RubyStringEncoding
              -> RubyObject
              -> Maybe ByteString
-lookupString k enc m =
-  case lookup (RIVar (RString k, enc)) m of
-    Just (RIVar (RString v, _)) ->
-      Just v
+lookupString key enc rubyObject =
+  case lookup (RIVar (RString key, enc)) rubyObject of
+    Just (RIVar (RString val, _)) ->
+      Just val
     _ ->
       Nothing
 
--- UTIL
+-- PRIVATE
 
 -- | Generate secret key using same cryptographic routines as Rails.
 generateSecret :: Salt -> SecretKeyBase -> SecretKey
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -1,21 +1,28 @@
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE QuasiQuotes #-}
 
-import Data.ByteString (ByteString)
-import Data.Either (isRight)
-import Data.Ruby.Marshal hiding (decodeEither)
-import Data.Vector (fromList)
-import Test.Tasty (defaultMain, testGroup)
-import Test.Tasty.Hspec (describe, it, shouldBe, shouldSatisfy, testSpec, Spec)
-import Web.Rails.Session
+import           Data.ByteString (ByteString)
+import qualified Data.ByteString as BS
+import           Data.Either (isRight)
+import           Data.Monoid ((<>))
+import           Data.Ruby.Marshal hiding (decodeEither)
+import           Data.Vector (fromList)
+import           System.IO.Unsafe (unsafePerformIO)
+import           Test.Tasty (defaultMain, testGroup)
+import           Test.Tasty.Hspec (describe, it, shouldBe, shouldSatisfy, testSpec, Spec)
+import           Web.Rails.Session
 
+-- SPECS
+
 main :: IO ()
 main = do
-  x <- testSpec "Web.Rails.Session" specs
-  defaultMain (testGroup "All the Specs" [x])
+  rails4 <- testSpec "Web.Rails.Session: Rails4" $ specsFor Rails4
+  defaultMain (testGroup "All the Specs" [rails4])
 
-specs :: Spec
-specs = do
+specsFor :: Rails -> Spec
+specsFor rails = do
+  let cookie = unsafeReadCookie rails
+
   describe "decode" $ do
     it "should be a Right(..)" $ do
       let result = decodeEither Nothing secret cookie
@@ -32,20 +39,34 @@
       let result = decrypt Nothing secret cookie
       result `shouldSatisfy` isRight
 
+  describe "csrfToken" $ do
+    it "should look up the '_csrf_token'" $ do
+      case decodeEither Nothing secret cookie of
+        Left _ -> error "lookup failed"
+        Right result ->
+          csrfToken result `shouldBe` Just csrfTokenVal
+
+  describe "sessionId" $ do
+    it "should look up the 'session_id'" $ do
+      case decodeEither Nothing secret cookie of
+        Left _ -> error "lookup failed"
+        Right result ->
+          sessionId result `shouldBe` Just sessionIdVal
+
   describe "lookupString" $ do
     it "should look up the '_csrf_token'" $ do
       case decodeEither Nothing secret cookie of
         Left _ -> error "lookup failed"
         Right result ->
           lookupString "_csrf_token" US_ASCII result `shouldBe`
-          Just csrfToken
+          Just csrfTokenVal
 
     it "should look up the 'session_id'" $ do
       case decodeEither Nothing secret cookie of
         Left _ -> error "lookup failed"
         Right result ->
           lookupString "session_id" UTF_8 result `shouldBe`
-          Just sessionId
+          Just sessionIdVal
 
     it "should look up the 'token'" $ do
       case decodeEither Nothing secret cookie of
@@ -54,6 +75,27 @@
           lookupString "token" US_ASCII result `shouldBe`
           Just authToken
 
+-- EXAMPLES
+
+example :: FilePath -> IO (Maybe ByteString)
+example path = do
+  rawCookie <- BS.readFile path
+  let appSecret = mkSecretKeyBase "development_secret_token"
+  let cookie = mkCookie rawCookie
+  case decodeEither Nothing appSecret cookie of
+    Left _ ->
+      pure Nothing
+    Right rubyObject ->
+      pure $ sessionId rubyObject
+
+-- UTIL
+
+data Rails = Rails4 deriving (Show)
+
+unsafeReadCookie :: Rails -> Cookie
+unsafeReadCookie rails = unsafePerformIO $
+  BS.readFile ("test/" <> (show rails)) >>= pure . mkCookie
+
 -- CONFIG
 
 secret :: SecretKeyBase
@@ -64,28 +106,21 @@
 authToken :: ByteString
 authToken = "GT1EYH9X8OXYqup4HwnQIvfnh59TqNys1IvukVXpXR8="
 
-sessionId :: ByteString
-sessionId = "912a0abcf3d64e0d9d2bdb601b9e8224"
-
-csrfToken :: ByteString
-csrfToken = "c9kRzi8L7oj2MPI/QlqYpQ79WR6YfKTDob6PGl9V2pg="
-
--- SESSIONS
+sessionIdVal :: ByteString
+sessionIdVal = "912a0abcf3d64e0d9d2bdb601b9e8224"
 
-cookie :: Cookie
-cookie =
-  mkCookie $
-  "T3NpYnRsWGJsZ25qL0R4MFlZdE9wZVBrZXc3VnFHMHhYMFgvemlVUjlTekZKbERXbVd2Mkwra0xxTmNOYnZaWktBQWo3T25RV3VPRkR6RU9BQ3dub2FSWExlZmZ1RUxVWG9vZjRTbWphRzBFSW5nMVJOSklPTVRPRGxKN0tvdGxhZzVlZktLTmhxc0V1a1FCWHpwNVJGTjdON0JCbjZQWHM0R1M1SWIzeUkzalhVNWdVbnd2Z2E5RlBMSXcvR0tNSHVOZ0NiK1RBTzVxcCtMK3hJa1daYW13allNb1NyN3pOUTFBQ0tRcFNEdUVJelVMZE8rVXhwM3RhcHFONWRwby9kRStNNkRUVXNQTDNKcjF0ZWpGTUE9PS0tb3NGeEJiZ1dLeFFKcFV0WXgyUytnZz09--e996601dbf39ff5ffbf6e2f23f6ddf78c5179baa"
+csrfTokenVal :: ByteString
+csrfTokenVal = "c9kRzi8L7oj2MPI/QlqYpQ79WR6YfKTDob6PGl9V2pg="
 
 rubySession :: RubyObject
 rubySession =
   RHash
     (fromList
        [ ( RIVar (RString "session_id", UTF_8)
-         , RIVar (RString sessionId, UTF_8))
+         , RIVar (RString sessionIdVal, UTF_8))
        , ( RIVar (RString "_csrf_token", US_ASCII)
          , RIVar
-             (RString csrfToken, US_ASCII))
+             (RString csrfTokenVal, US_ASCII))
        , ( RIVar (RString "token", US_ASCII)
          , RIVar (RString authToken, UTF_8))
        ])
