diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,24 @@
+#Change Log
+
+## hs-webdriver 0.2
+
+### API changes
+* FailedCommandInfo changed so that it stores a WDSession rather than just a Maybe SessionId, thus providing server host and port information as well as the session ID.
+* As a result, mkFailedcommandInfo is now String -> WD FailedCommandInfo, since it requires access to the WDSession state.
+* HTML5StorageType changed to the more accurate WebStorageType
+
+### new features
+* general documentation improvements
+* the uploadFile, uploadRawFile, and uploadZipEntry functions, which support uploading file contents to the remote server
+
+## hs-webdriver 0.1
+
+### API changes
+* getWindowSize, setWindowSize, getWindowPos, and setWindowPos have all been deprived of their WindowHandle argument. This is due to the fact that using unfocused windows with those commands causes undefined behavior. 
+
+### new features
+* the mkCookie function for convenient cookie construction
+* the focusFrame function for focusing to individual frames
+* the setPageLoadTimeout function
+* the maximize function for maximizing windows
+* support for HTML 5 web storage
diff --git a/TODO b/TODO
new file mode 100644
--- /dev/null
+++ b/TODO
@@ -0,0 +1,33 @@
+for next minor releases
+
+-- add special web-driver specific FF profile setters, either as special
+functions or via documentation
+
+-- add opera config
+
+-- improve documentation. Document errors better. Provide more
+module introductions
+  -- provide examples
+    -- basic runSession usage
+    -- intermediate usage
+    -- explicit waits usage
+    -- firefox profile usage
+    -- REPL usage
+
+
+for 1.0
+
+-- overload WD commands in typeclass
+-- add WDSettings, use WDSession as internal State type. 
+-- allow settings to automatically load drivers. add modules with driver loading
+functions
+-- allow setting to modify HTTP headers
+
+
+
+miscellaneous unsorted
+
+-- use http-conduit and attoparsec-conduit to stream JSON data. use request methods from http-types
+
+-- use ReaderT to store WDVersion for use with implicit configurations.
+
diff --git a/Test/WebDriver/Commands.hs b/Test/WebDriver/Commands.hs
--- a/Test/WebDriver/Commands.hs
+++ b/Test/WebDriver/Commands.hs
@@ -42,17 +42,22 @@
        , moveTo, moveToCenter, moveToFrom
        , clickWith, MouseButton(..)
        , mouseDown, mouseUp, withMouseDown, doubleClick
-         -- * Touch gestures
-       , touchClick, touchDown, touchUp, touchMove
-       , touchScroll, touchScrollFrom, touchDoubleClick
-       , touchLongClick, touchFlick, touchFlickFrom
          -- * Screen orientation
        , Orientation(..)
        , getOrientation, setOrientation
          -- * Geo-location
        , getLocation, setLocation
-         -- * HTML 5 web storage
+         -- * HTML 5 Web Storage
        , storageSize, getAllKeys, deleteAllKeys, getKey, setKey, deleteKey
+         -- * Uploading files to remote server
+         -- |These functions allow you to upload a file to a remote server. 
+         -- Note that this operation isn't supported by all WebDriver servers,
+         -- and the location where the file is stored is not standardized.
+       , uploadFile, uploadRawFile, uploadZipEntry
+         -- * Touch gestures
+       , touchClick, touchDown, touchUp, touchMove
+       , touchScroll, touchScrollFrom, touchDoubleClick
+       , touchLongClick, touchFlick, touchFlickFrom
          -- * IME support              
        , availableIMEEngines, activeIMEEngine, checkIMEActive
        , activateIME, deactivateIME
@@ -67,9 +72,11 @@
 import Data.Aeson
 import qualified Data.Text as T
 import Data.Text (Text, splitOn, append)
-import Data.ByteString (ByteString)
+import Data.ByteString as SBS (ByteString, concat)
 import Data.ByteString.Base64 as B64
+import Data.ByteString.Lazy as LBS (ByteString, toChunks)
 import Network.URI
+import Codec.Archive.Zip
 
 import Control.Applicative
 import Control.Monad.State.Strict
@@ -122,7 +129,7 @@
         allFields = ["type" .= ("implicit" :: String)] ++ msField
 
 -- |Sets the amount of time we wait for an asynchronous script to return a 
--- result
+-- result.
 setScriptTimeout :: Integer -> WD () 
 setScriptTimeout ms =
   doSessCommand POST "/timeouts/async_script" (object msField)
@@ -131,6 +138,7 @@
   where msField   = ["ms" .= ms]
         allFields = ["type" .= ("script" :: String)] ++ msField
 
+-- |Sets the amount of time to wait for a page to finish loading before throwing a 'Timeout' exception
 setPageLoadTimeout :: Integer -> WD ()
 setPageLoadTimeout ms = doSessCommand POST "/timeouts" params
   where params = object ["type" .= ("page load" :: String)
@@ -195,7 +203,7 @@
     timeout err = throwIO err
         
 -- |Grab a screenshot of the current page as a PNG image
-screenshot :: WD ByteString
+screenshot :: WD SBS.ByteString
 screenshot = B64.decodeLenient <$> doSessCommand GET "/screenshot" () 
 
 
@@ -509,20 +517,49 @@
                                                        "longitude",
                                                        "altitude")
 
-storageSize :: HTML5StorageType -> WD Integer
+-- |Uploads a file from the local filesystem by its file path.
+uploadFile :: FilePath -> WD ()
+uploadFile path = uploadZipEntry =<< liftIO (readEntry [] path)
+  
+-- |Uploads a raw bytestring with associated file info.
+uploadRawFile :: FilePath          -- ^File path to use with this bytestring.
+                 -> Integer        -- ^Modification time 
+                                   -- (in seconds since Unix epoch).
+                 -> LBS.ByteString -- ^ The file contents as a lazy ByteString
+                 -> WD ()
+uploadRawFile path t str = uploadZipEntry (toEntry path t str)
+
+
+-- |Lowest level interface to the file uploading mechanism.
+-- This allows you to specify the exact details of
+-- the zip entry sent across network.
+uploadZipEntry :: Entry -> WD ()
+uploadZipEntry = doSessCommand POST "/file" . single "file" 
+                 . B64.encode . SBS.concat . toChunks 
+                 . fromArchive . (`addEntryToArchive` emptyArchive)
+
+-- |Get the current number of keys in a web storage area.
+storageSize :: WebStorageType -> WD Integer
 storageSize s = doStorageCommand GET s "/size" ()
 
-getAllKeys :: HTML5StorageType -> WD [Text]
+-- |Get a list of all keys from a web storage area.
+getAllKeys :: WebStorageType -> WD [Text]
 getAllKeys s = doStorageCommand GET s "" ()
 
-deleteAllKeys :: HTML5StorageType -> WD ()
+-- |Delete all keys within a given web storage area.
+deleteAllKeys :: WebStorageType -> WD ()
 deleteAllKeys s = doStorageCommand DELETE s "" ()
 
-getKey :: HTML5StorageType -> Text ->  WD Text
+-- |Get the value associated with a key in the given web storage area.
+-- Unset keys result in empty strings, since the Web Storage spec
+-- makes no distinction between the empty string and an undefined value.
+getKey :: WebStorageType -> Text ->  WD Text
 getKey s k = doStorageCommand GET s ("/key/" `T.append` k) ()
 
-setKey :: HTML5StorageType -> Text -> Text -> WD Text
+-- |Set a key in the given web storage area.
+setKey :: WebStorageType -> Text -> Text -> WD Text
 setKey s k v = doStorageCommand POST s "" . object $ ["key"   .= k,
-                                                      "value" .= v ]            
-deleteKey :: HTML5StorageType -> Text -> WD ()
+                                                      "value" .= v ]
+-- |Delete a key in the given web storage area. 
+deleteKey :: WebStorageType -> Text -> WD ()
 deleteKey s k = doStorageCommand POST s ("/key/" `T.append` k) ()
diff --git a/Test/WebDriver/Commands/Internal.hs b/Test/WebDriver/Commands/Internal.hs
--- a/Test/WebDriver/Commands/Internal.hs
+++ b/Test/WebDriver/Commands/Internal.hs
@@ -31,7 +31,7 @@
 doWinCommand = doWinCommand' []
 
 doStorageCommand :: (ToJSON a, FromJSON b) =>
-                    RequestMethod -> HTML5StorageType -> Text -> a -> WD b
+                    RequestMethod -> WebStorageType -> Text -> a -> WD b
 doStorageCommand = doStorageCommand' []
 
 doCommand' :: (ToJSON a, FromJSON b) => 
@@ -67,7 +67,7 @@
   doSessCommand' h m (T.concat ["/element/", e, path]) a
 
 doStorageCommand' :: (ToJSON a, FromJSON b) =>
-                     [Header] -> RequestMethod -> HTML5StorageType -> Text -> a
+                     [Header] -> RequestMethod -> WebStorageType -> Text -> a
                      -> WD b
 doStorageCommand' h m s path a = doSessCommand' h m (T.concat ["/", s', path]) a
   where s' = case s of
diff --git a/Test/WebDriver/Commands/Wait.hs b/Test/WebDriver/Commands/Wait.hs
--- a/Test/WebDriver/Commands/Wait.hs
+++ b/Test/WebDriver/Commands/Wait.hs
@@ -20,10 +20,10 @@
 import Prelude hiding (catch)
 
 instance Exception ExpectFailed
--- |An exception representing a failure of an expected condition.
+-- |An exception representing the failure of an expected condition.
 data ExpectFailed = ExpectFailed deriving (Show, Eq, Typeable)
 
--- |Raises ExpectFailed.
+-- |throws 'ExpectFailed'. This is nice for writing your own abstractions.
 unexpected :: WD a
 unexpected = throwIO ExpectFailed
 
@@ -44,15 +44,21 @@
 (<||>) :: Monad m => m Bool -> m Bool -> m Bool
 (<||>) = liftM2 (||)
 
+
+-- |Apply a predicate to every element in a list, and expect that at least one
+-- succeeds.
 expectAny :: (a -> WD Bool) -> [a] -> WD ()
 expectAny p xs = expect . or =<< mapM p xs
 
+-- |Apply a predicate to every element in a list, and expect that all succeed.
 expectAll :: (a -> WD Bool) -> [a] -> WD ()
 expectAll p xs = expect . and =<< mapM p xs
 
 -- |Wait until either the given action succeeds or the timeout is reached.
 -- The action will be retried every .25 seconds until no ExpectFailed or
--- NoSuchElement exceptions occur. The timeout value is expressed in seconds.
+-- NoSuchElement exceptions occur. If the timeout is reached, then a 
+-- 'Test.WebDriver.Timeout' exception will be raised. The timeout value is 
+-- expressed in seconds.
 waitUntil :: Double -> WD a -> WD a
 waitUntil = waitUntil' 250000
 
@@ -70,12 +76,12 @@
                               
         handleExpectFailed (_ :: ExpectFailed) = retry
 
--- |Like waitWhile, but retries the action until it fails or until the timeout
+-- |Like 'waitUntil', but retries the action until it fails or until the timeout
 -- is exceeded.
 waitWhile :: Double -> WD a -> WD ()
 waitWhile = waitWhile' 250000
 
--- |Like waitWhile', but retries the action until it either fails or 
+-- |Like 'waitUntil\'', but retries the action until it either fails or 
 -- until the timeout is exceeded.
 waitWhile' :: Int -> Double -> WD a -> WD ()
 waitWhile' = wait' handler
diff --git a/Test/WebDriver/Firefox/Profile.hs b/Test/WebDriver/Firefox/Profile.hs
--- a/Test/WebDriver/Firefox/Profile.hs
+++ b/Test/WebDriver/Firefox/Profile.hs
@@ -65,7 +65,13 @@
                       }
                     deriving (Eq, Show)
 
--- |A Firefox preference. This is the subset of JSON values that excludes
+
+-- |Represents a Firefox profile that has been prepared for 
+-- network transmission. The profile cannot be modified in this form.
+newtype PreparedFirefoxProfile = PreparedFirefoxProfile ByteString
+  deriving (Eq, Show, ToJSON, FromJSON)
+
+-- |A Firefox preference value. This is the subset of JSON values that excludes
 -- arrays and objects.
 data FirefoxPref = PrefInteger !Integer
                  | PrefDouble  !Double
@@ -81,12 +87,7 @@
     PrefBool  b   -> toJSON b
 
 
--- |Represents a Firefox profile that has been prepared for 
--- network transmission. The profile cannot be modified in this form.
-newtype PreparedFirefoxProfile = PreparedFirefoxProfile ByteString
-  deriving (Eq, Show, ToJSON, FromJSON)
 
-
 instance Exception ProfileParseError
 -- |An error occured while attempting to parse a profile's prefs.js file 
 newtype ProfileParseError = ProfileParseError String
@@ -191,7 +192,6 @@
                    $ parseOnly prefsParser s
 
 -- |Prepare a FirefoxProfile for network transmission.
---
 -- Internally, this function constructs a Firefox profile within a temp 
 -- directory, archives it as a zip file, and then base64 encodes the zipped 
 -- data. The temporary directory is deleted afterwards
@@ -228,7 +228,7 @@
 
 -- |Apply a function on an automatically generated default profile, and
 -- prepare the result. The FirefoxProfile passed to the handler function is
--- the same one used by sessions when no Firefox profile is specified
+-- the default profile used by sessions when Nothing is specified
 prepareTempProfile :: MonadIO m => 
                      (FirefoxProfile -> FirefoxProfile) 
                      -> m PreparedFirefoxProfile
diff --git a/Test/WebDriver/Internal.hs b/Test/WebDriver/Internal.hs
--- a/Test/WebDriver/Internal.hs
+++ b/Test/WebDriver/Internal.hs
@@ -104,7 +104,7 @@
   sess <- get
   errInfo <- fromJSON' val
   let screen = B64.decodeLenient <$> errScreen errInfo 
-      errInfo' = errInfo { errSessId = wdSessId sess 
+      errInfo' = errInfo { errSess = sess 
                          , errScreen = screen } 
       e errType = throwIO $ FailedCommand errType errInfo'
   case status of
diff --git a/Test/WebDriver/JSON.hs b/Test/WebDriver/JSON.hs
--- a/Test/WebDriver/JSON.hs
+++ b/Test/WebDriver/JSON.hs
@@ -1,5 +1,5 @@
 {-# LANGUAGE OverloadedStrings #-}
--- |A collection of convenience functions for using and parsing JSON valus
+-- |A collection of convenience functions for using and parsing JSON values
 -- within 'WD'. All monadic parse errors are converted to asynchronous 
 -- 'BadJSON' exceptions.
 module Test.WebDriver.JSON 
diff --git a/Test/WebDriver/Types.hs b/Test/WebDriver/Types.hs
--- a/Test/WebDriver/Types.hs
+++ b/Test/WebDriver/Types.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE GeneralizedNewtypeDeriving, DeriveDataTypeable,
     TemplateHaskell, OverloadedStrings, ExistentialQuantification, 
-    MultiParamTypeClasses, TypeFamilies, NoMonoLocalBinds #-}
+    MultiParamTypeClasses, TypeFamilies, NoMonoLocalBinds 
+  #-}
 {-# OPTIONS_HADDOCK not-home #-}
 module Test.WebDriver.Types 
        ( -- * WebDriver sessions
@@ -9,7 +10,10 @@
        , Capabilities(..), defaultCaps, allCaps
        , Platform(..), ProxyType(..)
          -- ** Browser-specific configuration
-       , Browser(..), firefox, chrome, ie, opera, iPhone, iPad, android
+       , Browser(..), 
+         -- ** Default settings for browsers
+         firefox, chrome, ie, opera, iPhone, iPad, android
+       , FFLogPref
          -- * WebDriver objects and command-specific types
        , Element(..)
        , WindowHandle(..), currentWindow
@@ -19,7 +23,7 @@
        , Cookie(..), mkCookie
        , Orientation(..)
        , MouseButton(..)
-       , HTML5StorageType(..)
+       , WebStorageType(..)
          -- * Exceptions
        , InvalidURL(..), NoSessionId(..), BadJSON(..)
        , HTTPStatusUnknown(..), HTTPConnError(..)
@@ -38,7 +42,7 @@
 import Network.Stream (ConnError)
 
 
-import Data.Text as Text (toLower, toUpper)
+import Data.Text as Text (toLower, toUpper, unpack)
 import Data.Text (Text)
 import Data.ByteString (ByteString)
 
@@ -48,14 +52,16 @@
 import Control.Monad.State.Strict
 import Control.Monad.Base
 import Control.Monad.Trans.Control
+import Data.Maybe
 import Data.Word
 import Data.String
+import Text.Show
 import Data.Default
 import qualified Data.Char as C
 
 
 {- |A monadic interface to the WebDriver server. This monad is a simple, strict 
-wrapper over 'IO', threading session information between sequential commands
+layer over 'IO', threading session information between sequential commands
 -}
 newtype WD a = WD (StateT WDSession IO a)
   deriving (Functor, Monad, MonadState WDSession, MonadIO
@@ -112,11 +118,14 @@
                              wdHost   :: String
                              -- |Port number of the server
                            , wdPort   :: Word16
-                             -- |An opaque reference identifying the session.
+                             -- |An opaque reference identifying the session to
+                             -- use with 'WD' commands.
                              -- A value of Nothing indicates that a session 
-                             -- hasn't been created yet. To create new sessions,
-                             -- use the 'Test.WebDriver.Commands.createSession' 
-                             -- and 'Test.WebDriver.runSession' functions.
+                             -- hasn't been created yet.
+                             -- Sessions can be created within 'WD' via the
+                             -- 'Test.WebDriver.createSession', or created
+                             -- and closed automatically with 
+                             -- 'Test.WebDriver.runSession'
                            , wdSessId :: Maybe SessionId 
                            } deriving (Eq, Show)
 
@@ -139,7 +148,7 @@
 it's created. In this usage, fields that are set to Nothing indicate
 that we have no preference for that capability.
 
-* When returned by 'Test.WebDriver.Commands.getCaps', it's used to
+* When received from the server , it's used to
 describe the actual capabilities given to us by the WebDriver
 server. Here a value of Nothing indicates that the server doesn't
 support the capability. Thus, for Maybe Bool fields, both Nothing and
@@ -189,8 +198,8 @@
                      }
 
 -- |Default capabilities. This is the same as the 'Default' instance, but with 
--- a more specific type. By default we use Firefox of an unspecified version 
--- with default settings on whatever platform is available. 
+-- less polymorphism. By default, we use 'firefox' of an unspecified 'version' 
+-- with default system-wide proxy settings on whatever 'platform' is available.
 -- All Maybe Bool capabilities are set to Nothing (no preference).
 defaultCaps :: Capabilities
 defaultCaps = def
@@ -214,7 +223,7 @@
       
 
 -- |Browser setting and browser-specific capabilities.
-data Browser = Firefox { -- |The firefox profile to use. If Nothing, a
+data Browser = Firefox { -- |The firefox profile to use. If Nothing,
                          -- a default temporary profile is automatically created
                          -- and used.
                          ffProfile :: Maybe PreparedFirefoxProfile
@@ -224,7 +233,10 @@
                          -- system-based default.
                        , ffBinary :: Maybe FilePath
                        }
-             | Chrome { chromeDriverVersion :: Maybe String 
+             | Chrome { -- |Version of the Chrome Webdriver server server to use.
+                        -- for more information on chromedriver see
+                        -- <http://code.google.com/p/selenium/wiki/ChromeDriver>
+                        chromeDriverVersion :: Maybe String 
                         -- |Path to Chrome binary. If Nothing, use a sensible
                         -- system-based default.
                       , chromeBinary :: Maybe FilePath
@@ -237,7 +249,7 @@
              | IE { ignoreProtectedModeSettings :: Bool
                   --, useLegacyInternalServer     :: Bool
                   }
-             | Opera -- ^ Opera-specific configuration coming soon!
+             | Opera -- ^ (Opera-specific configuration coming soon!)
              | HTMLUnit
              | IPhone 
              | IPad
@@ -296,7 +308,7 @@
                deriving (Eq, Show)
 
 
--- |For Firefox sessions; indicates Firefox's log level
+-- |For 'Firefox' sessions; indicates Firefox's log level
 data FFLogPref = LogOff | LogSevere | LogWarning | LogInfo | LogConfig 
              | LogFine | LogFiner | LogFinest | LogAll
              deriving (Eq, Show, Ord, Bounded, Enum)
@@ -339,8 +351,8 @@
                       deriving (Eq, Show, Typeable)
 
 instance Exception FailedCommand
--- |This exception encapsulates many different kinds of exceptions that can
--- occur when a command fails. 
+-- |This exception encapsulates a broad variety of exceptions that can
+-- occur when a command fails.
 data FailedCommand = FailedCommand FailedCommandType FailedCommandInfo
                    deriving (Eq, Show, Typeable)
 
@@ -373,31 +385,35 @@
                        deriving (Eq, Ord, Enum, Bounded, Show)
 
 -- |Detailed information about the failed command provided by the server.
-data FailedCommandInfo = FailedCommandInfo { errMsg    :: String
-                                           , errSessId :: Maybe SessionId 
+data FailedCommandInfo = FailedCommandInfo { -- |The error message.
+                                             errMsg    :: String
+                                             -- |The session associated with 
+                                             -- the exception.
+                                           , errSess :: WDSession 
+                                             -- |A screen shot of the focused window
+                                             -- when the exception occured,
+                                             -- if provided.
                                            , errScreen :: Maybe ByteString
+                                             -- |The "class" in which the exception
+                                             -- was raised, if provided.
                                            , errClass  :: Maybe String
+                                             -- |A stack trace of the exception.
                                            , errStack  :: [StackFrame]
                                            }
                        deriving (Eq)
 
 
 -- |Constructs a FailedCommandInfo from only an error message.
-mkFailedCommandInfo :: String -> FailedCommandInfo
-mkFailedCommandInfo m = FailedCommandInfo {errMsg = m
-                                          , errSessId = Nothing
-                                          , errScreen = Nothing
-                                          , errClass  = Nothing
-                                          , errStack  = []
-                                          }
+mkFailedCommandInfo :: String -> WD FailedCommandInfo
+mkFailedCommandInfo m = do
+  sess <- get
+  return $ FailedCommandInfo {errMsg = m , errSess = sess , errScreen = Nothing
+                             , errClass  = Nothing , errStack  = [] }
 
 -- |Convenience function to throw a 'FailedCommand' locally with no server-side 
 -- info present.
 failedCommand :: FailedCommandType -> String -> WD a
-failedCommand t m = throwIO . FailedCommand t =<< getCmdInfo
-  where getCmdInfo = do
-          sessId <- wdSessId <$> get
-          return $ (mkFailedCommandInfo m) { errSessId = sessId }
+failedCommand t m = throwIO . FailedCommand t =<< mkFailedCommandInfo m
 
 -- |An individual stack frame from the stack trace provided by the server 
 -- during a FailedCommand.
@@ -406,15 +422,24 @@
                              , sfMethodName :: String
                              , sfLineNumber :: Word
                              }
-                deriving (Show, Eq)
+                deriving (Eq)
 
--- |Cookies are delicious delicacies.
+-- |Cookies are delicious delicacies. When sending cookies to the server, a value
+-- of Nothing indicates that the server should use a default value. When receiving
+-- cookies from the server, a value of Nothing indicates that the server is unable
+-- to specify the value.
 data Cookie = Cookie { cookName   :: Text
-                     , cookValue  :: Text
-                     , cookPath   :: Maybe Text
-                     , cookDomain :: Maybe Text
-                     , cookSecure :: Maybe Bool
-                     , cookExpiry :: Maybe Integer
+                     , cookValue  :: Text          -- ^ 
+                     , cookPath   :: Maybe Text    -- ^path of this cookie.
+                                                   -- if Nothing, defaults to /
+                     , cookDomain :: Maybe Text    -- ^domain of this cookie.
+                                                   -- if Nothing, the current pages
+                                                   -- domain is used
+                     , cookSecure :: Maybe Bool    -- ^Is this cookie secure?
+                     , cookExpiry :: Maybe Integer -- ^Expiry date expressed as
+                                                   -- seconds since the Unix epoch
+                                                   -- Nothing indicates that the 
+                                                   -- cookie never expires
                      } deriving (Eq, Show)              
 
 -- |Creates a Cookie with only a name and value specified. All other
@@ -429,7 +454,7 @@
 data Selector = ById Text  
               | ByName Text
               | ByClass Text -- ^ (Note: multiple classes are not  
-                             -- allowed. For more control, use ByCSS)
+                             -- allowed. For more control, use 'ByCSS')
               | ByTag Text            
               | ByLinkText Text       
               | ByPartialLinkText Text
@@ -450,22 +475,36 @@
                  deriving (Eq, Show, Ord, Bounded, Enum)
 
 
--- |A type to specify HTML 5 storage type
-data HTML5StorageType = LocalStorage | SessionStorage 
-                      deriving (Eq, Show, Ord, Bounded, Enum)
+-- |An HTML 5 storage type
+data WebStorageType = LocalStorage | SessionStorage 
+                    deriving (Eq, Show, Ord, Bounded, Enum)
 
 instance Show FailedCommandInfo where --todo: pretty print
-  show i =   showString "{errMsg = "     . shows (errMsg i) 
-           . showString ", errSessId = " . shows (errSessId i)
-           . showString ", errScreen = " . screen
-           . showString ", errClass = "  . shows (errClass i)
-           . showString ", errStack = "  . shows (errStack i) 
-           $ "}"
-    where screen = showString $ case errScreen i of 
-                                  Just _  -> "Just \"...\""
-                                  Nothing -> "Nothing"
-            
+  show i = showChar '\n' 
+           . showString "Session: " . sess 
+           . showChar '\n'
+           . showString className . showString ": " . showString (errMsg i)
+           . showChar '\n'
+           . foldl (\f s-> f . showString "  " . shows s) id (errStack i)
+           $ ""
+    where
+      className = fromMaybe "<unknown exception>" . errClass $ i
+      
+      sess = showString sessId . showString " at " 
+             . showString host . showChar ':' . shows port
+        where
+          WDSession {wdHost = host, wdPort = port, wdSessId = msid } = errSess i
+          sessId = case msid of
+            Just (SessionId sid) -> unpack sid
+            Nothing -> "<no session id>"
 
+instance Show StackFrame where
+  show f = showString (sfClassName f) . showChar '.' 
+           . showString (sfMethodName f) . showChar ' '
+           . showParen True ( showString (sfFileName f) . showChar ':'
+                              . shows (sfLineNumber f))
+           $ "\n"
+
 instance FromJSON Element where
   parseJSON (Object o) = Element <$> o .: "ELEMENT"
   parseJSON v = typeMismatch "Element" v
@@ -544,7 +583,7 @@
 instance FromJSON FailedCommandInfo where
   parseJSON (Object o) = 
     FailedCommandInfo <$> (req "message" >>= maybe (return "") return)
-                      <*> pure Nothing
+                      <*> pure undefined
                       <*> opt "screen"     Nothing
                       <*> opt "class"      Nothing
                       <*> opt "stackTrace" []
diff --git a/webdriver.cabal b/webdriver.cabal
--- a/webdriver.cabal
+++ b/webdriver.cabal
@@ -1,5 +1,5 @@
 Name: webdriver
-Version: 0.1
+Version: 0.2
 Cabal-Version: >= 1.6
 License: BSD3
 License-File: LICENSE
@@ -9,30 +9,25 @@
 Category: Web, Browser, Testing
 Synopsis: a Haskell client for the Selenium WebDriver protocol
 Build-type: Simple
-Extra-source-files: README.md
+Extra-source-files: README.md, TODO, CHANGELOG.md
 Description:
-        A Selenium WebDriver client for the Haskell
-        programming language. You can use it to automate browser
-        sessions for testing, system administration, etc.
-
+        A Selenium WebDriver client for Haskell. 
+        You can use it to automate browser sessions 
+        for testing, system administration, etc.
+        .
         For more information about Selenium itself, see
         <http://seleniumhq.org/>
-
+        .
         To find out what's been changed in this version and others,
-        see the changelog at 
+        see the change log at 
         <https://github.com/kallisti-dev/hs-webdriver/blob/master/CHANGELOG.md>
 
-
-source-repository this
-  type: git
-  location: git://github.com/kallisti-dev/hs-webdriver.git
-  tag: 0
-
 source-repository head
   type: git
   location: git://github.com/kallisti-dev/hs-webdriver.git  
 
 library
+  ghc-options: -Wall    
   build-depends:   base == 4.*
                  , aeson >= 0.4 && < 0.7
                  , HTTP >= 4000.1 && < 4000.3
@@ -67,5 +62,3 @@
 
   other-modules:   Test.WebDriver.Internal
                    Test.WebDriver.Types.Internal
-
-  ghc-options: -Wall
