diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,27 +1,43 @@
 # Change Log
 
+## hs-webdriver 0.3.2.1
+
+###bug fixes
+*Removed a bug in waitWhile' that resulted in an infinite loop
+*Fixed the incorrect representation of JSON profiles
+*Fixed relative path issues when zipping profile directories from disk
+
+## hs-webdriver 0.3.2
+
+###bug fixes
+* Changed the constraint on filesystrem-trees to avoid a broken version
+* Added the missing exports for addFile and deleteFile in Common.Profile and Firefox.Profile
+
+###new features
+* new Common.Profile functions: hasExtension, hasFile
+
 ## hs-webdriver 0.3.1 
 
 ###API changes
-*The representation of Profiles has changed, allowing it to store arbitrary files as well as extensions. The functional API for working with preferences and extensions ismostly unchanged, except for the behavior of calling addExtension consecutively with the same filepath argument.
-*The old <&&> and <||> operators in Test.WebDriver.Commands.Wait have been removed and replaced with the ones exported from Control.Conditional from the cond package.
+* The representation of Profiles has changed, allowing it to store arbitrary files as well as extensions. The functional API for working with preferences and extensions ismostly unchanged, except for the behavior of calling addExtension consecutively with the same filepath argument.
+* The old <&&> and <||> operators in Test.WebDriver.Commands.Wait have been removed and replaced with the ones exported from Control.Conditional from the cond package.
 
 ###bug fixes
-*Fixed memory leak resulting from an infinite recursion in the FromJSON instance of PreparedProfile.
-*loadProfile now properly loads an entire Firefox profile from disk, rather than just the extensions and preferences.
+* Fixed memory leak resulting from an infinite recursion in the FromJSON instance of PreparedProfile.
+* loadProfile now properly loads an entire Firefox profile from disk, rather than just the extensions and preferences.
 
 ###known issues
 *An issue involving lazy bytestring IO in the zip-archive package means that unusually large profiles might exceed the OSes open file limit.
 
 ###new features
-*several new functions for working with Firefox/Opera profiles have been added. This includes functions for loading large profiles from disk, functions for working with zipped profiles, and functions for adding arbitrary files to a profile in pure code. 
-*new helper functions were added to Test.WebDriver.Commands.Wait, exported from the cond package.
+* several new functions for working with Firefox/Opera profiles have been added. This includes functions for loading large profiles from disk, functions for working with zipped profiles, and functions for adding arbitrary files to a profile in pure code. 
+* new helper functions were added to Test.WebDriver.Commands.Wait, exported from the cond package.
 
 ## hs-webdriver 0.3.0.1
 
 ###bug fixes
-*due to a nonconformance in the spec from the Grid server, wire responses were being received that contained no sessionId key, which subsequently resulted in a parse error from our JSON parser. This has been fixed, so that an omitted sessionId defaults to Nothing.
-*major bux fixes in the Firefox profile code. Note that loadProfile is unlikely
+* due to a nonconformance in the spec from the Grid server, wire responses were being received that contained no sessionId key, which subsequently resulted in a parse error from our JSON parser. This has been fixed, so that an omitted sessionId defaults to Nothing.
+* major bux fixes in the Firefox profile code. Note that loadProfile is unlikely
 to work as expected, but prepareTempProfile should.
 
 ## hs-webdriver 0.3 
diff --git a/src/Test/WebDriver/Commands/Wait.hs b/src/Test/WebDriver/Commands/Wait.hs
--- a/src/Test/WebDriver/Commands/Wait.hs
+++ b/src/Test/WebDriver/Commands/Wait.hs
@@ -18,7 +18,7 @@
 import Control.Concurrent
 import Data.Time.Clock
 import Data.Typeable
-import Control.Conditional
+import Control.Conditional (ifM, (<||>), (<&&>), notM)
 import Prelude hiding (catch)
 
 instance Exception ExpectFailed
@@ -52,7 +52,7 @@
 -- then a 'Test.WebDriver.Timeout' exception will be raised. The timeout value 
 -- is expressed in seconds.
 waitUntil :: SessionState m => Double -> m a -> m a
-waitUntil = waitUntil' 250000
+waitUntil = waitUntil' 500000
 
 -- |Similar to 'waitUntil' but allows you to also specify the poll frequency
 -- of the 'WD' action. The frequency is expressed as an integer in microseconds.
@@ -71,7 +71,7 @@
 -- |Like 'waitUntil', but retries the action until it fails or until the timeout
 -- is exceeded.
 waitWhile :: SessionState m => Double -> m a -> m ()
-waitWhile = waitWhile' 250000
+waitWhile = waitWhile' 500000
 
 -- |Like 'waitUntil'', but retries the action until it either fails or 
 -- until the timeout is exceeded.
@@ -79,15 +79,15 @@
 waitWhile' = wait' handler
   where
     handler retry wd = do 
-      void wd `catches` [Handler handleFailedCommand
-                        ,Handler handleExpectFailed
-                        ]
-      retry
+      b <- (wd >> return True) `catches` [Handler handleFailedCommand
+                                         ,Handler handleExpectFailed
+                                         ]
+      when b retry
       where
-        handleFailedCommand (FailedCommand NoSuchElement _) = return ()
+        handleFailedCommand (FailedCommand NoSuchElement _) = return False
         handleFailedCommand err = throwIO err
                                
-        handleExpectFailed (_ :: ExpectFailed) = return ()
+        handleExpectFailed (_ :: ExpectFailed) = return False
     
 wait' :: SessionState m => 
          (m b -> m a -> m b) -> Int -> Double -> m a -> m b
@@ -99,7 +99,7 @@
               now <- liftBase getCurrentTime
               if diffUTCTime now startTime >= timeout
                 then 
-                  failedCommand Timeout "waitUntil': explicit wait timed out."
+                  failedCommand Timeout "wait': explicit wait timed out."
                 else do
                   liftBase . threadDelay $ waitAmnt
                   waitLoop startTime
diff --git a/src/Test/WebDriver/Common/Profile.hs b/src/Test/WebDriver/Common/Profile.hs
--- a/src/Test/WebDriver/Common/Profile.hs
+++ b/src/Test/WebDriver/Common/Profile.hs
@@ -32,8 +32,10 @@
 import qualified Data.ByteString.Base64 as B64
 
 import Codec.Archive.Zip
+import System.Directory
 import System.FilePath hiding (addExtension, hasExtension)
 
+
 import Data.Fixed
 import Data.Ratio
 import Data.Int
@@ -69,11 +71,10 @@
   deriving (Eq, Show)
 
 instance FromJSON (PreparedProfile s) where
-  parseJSON (Object o) = PreparedProfile <$> o .: "zip"
-  parseJSON other = typeMismatch "PreparedProfile" other
+  parseJSON v = PreparedProfile <$> parseJSON v
   
 instance ToJSON (PreparedProfile s) where
-  toJSON (PreparedProfile s) = object ["zip" .= s]
+  toJSON (PreparedProfile s) = toJSON s
 
 -- |A profile preference value. This is the subset of JSON values that excludes
 -- arrays, objects, and null.
@@ -208,9 +209,13 @@
 -- transmission.
 prepareLoadedProfile_ :: MonadBase IO m =>
                         FilePath -> m (PreparedProfile a)
-prepareLoadedProfile_ path = prepareZipArchive <$>
-                             liftBase (addFilesToArchive [OptRecursive] 
-                                       emptyArchive [path])
+prepareLoadedProfile_ path = liftBase $ do
+  oldWd <- getCurrentDirectory
+  setCurrentDirectory path
+  prepareZipArchive <$>
+    liftBase (addFilesToArchive [OptRecursive] 
+              emptyArchive ["."])
+    <* setCurrentDirectory oldWd
 
 -- |Prepare a zip file of a profile on disk for network transmission.
 -- This function is very efficient at loading large profiles from disk.
@@ -225,3 +230,4 @@
 -- |Prepare a ByteString of raw zip data for network transmission
 prepareRawZip :: LBS.ByteString -> PreparedProfile a
 prepareRawZip = PreparedProfile . B64.encode . SBS.concat . LBS.toChunks
+
diff --git a/src/Test/WebDriver/Firefox/Profile.hs b/src/Test/WebDriver/Firefox/Profile.hs
--- a/src/Test/WebDriver/Firefox/Profile.hs
+++ b/src/Test/WebDriver/Firefox/Profile.hs
@@ -37,7 +37,6 @@
 import System.Directory
 import System.IO.Temp (createTempDirectory)
 import qualified System.File.Tree as FS
-import Codec.Archive.Zip
 
 import Control.Monad
 import Control.Monad.Base
@@ -45,7 +44,6 @@
 import Control.Applicative
 import Data.List
 import Control.Exception.Lifted hiding (try)
-
 import Prelude hiding (catch)
 
 -- |Phantom type used in the parameters of 'Profile' and 'PreparedProfile'
@@ -123,10 +121,10 @@
   Profile <$> getFiles <*> getPrefs
   where
     getFiles = do
-      d <- FS.getDirectory path
+      d <- FS.getDirectory' path
       case FS.filter (not.isIgnored) [d] of
-        [t] -> return $ FS.zipWithDest (,) "" t
-        _   -> return []
+        [d'] -> return $ FS.zipWithDest (,) "" d'
+        _    -> return []
       where isIgnored p = "Cache/" `isInfixOf` p
                           || "OfflineCache/" `isInfixOf` p
                           || "lock" `isSuffixOf` p
@@ -152,13 +150,12 @@
   = liftBase $ do 
       tmpdir <- mkTemp
       mapM_ (installPath tmpdir) files
-      archive <- addUserPrefs <$> addFilesToArchive [OptRecursive] 
-                                                    emptyArchive [tmpdir]
-      removeDirectoryRecursive tmpdir
-      return . prepareZipArchive $ archive
+      installUserPrefs tmpdir
+      prepareLoadedProfile_ tmpdir
+        <* removeDirectoryRecursive tmpdir
   where
-    installPath tmp (src, d) = do
-      let dest = tmp </> d
+    installPath destDir (src, destPath) = do
+      let dest = destDir </> destPath
       isDir <- doesDirectoryExist src
       if isDir
         then createDirectoryIfMissing True dest `catch` ignoreIOException
@@ -167,14 +164,13 @@
           when (not . null $ dir) $
             createDirectoryIfMissing True dir `catch` ignoreIOException
           copyFile src dest `catch` ignoreIOException
-    
-    ignoreIOException :: IOException -> IO ()
-    ignoreIOException = print 
+      where
+        ignoreIOException :: IOException -> IO ()
+        ignoreIOException = print 
     
-    addUserPrefs = addEntryToArchive e
+    installUserPrefs d = LBS.writeFile (d </> "user" <.> "js") str
       where
-        e = toEntry ("user" <.> "js") 0
-            . LBS.concat
+        str = LBS.concat
             . map (\(k, v) -> LBS.concat [ "user_pref(", encode k, 
                                            ", ", encode v, ");\n"]) 
             . HM.toList $ prefs  
diff --git a/webdriver.cabal b/webdriver.cabal
--- a/webdriver.cabal
+++ b/webdriver.cabal
@@ -1,5 +1,5 @@
 Name: webdriver
-Version: 0.3.2
+Version: 0.3.2.1
 Cabal-Version: >= 1.6
 License: BSD3
 License-File: LICENSE
@@ -47,7 +47,7 @@
                  , transformers-base < 1.0
                  , vector >= 0.3
                  , lifted-base == 0.1.*
-                 , filesystem-trees >= 0.1 && < 0.3
+                 , filesystem-trees >= 0.1.0.2 && < 0.2
                  , data-default
                  , temporary
                  , base64-bytestring
@@ -59,8 +59,8 @@
                    Test.WebDriver.Exceptions
                    Test.WebDriver.Commands
                    Test.WebDriver.Commands.Wait
-                   Test.WebDriver.Firefox.Profile
                    Test.WebDriver.Common.Profile
+                   Test.WebDriver.Firefox.Profile
                    Test.WebDriver.Chrome.Extension
                    Test.WebDriver.Capabilities
                    Test.WebDriver.Types
