diff --git a/ChangeLog.md b/ChangeLog.md
--- a/ChangeLog.md
+++ b/ChangeLog.md
@@ -1,5 +1,11 @@
 # Changelog for passman
 
+## 0.2.1
+
+- refactoring
+- store the database where Windows can find it
+- confirm master password before creating new service
+
 ## 0.2
 
 - implemented manual saving
diff --git a/app/Main.hs b/app/Main.hs
--- a/app/Main.hs
+++ b/app/Main.hs
@@ -24,13 +24,14 @@
 
 import Control.Monad (mapM_)
 import Control.Monad.Trans.State as S
-import Data.Maybe (maybe)
-import System.Console.HCL (Request, reqFail, reqIO, runRequest)
-import System.Environment (lookupEnv)
+import System.Console.HCL (Request, reqIO, runRequest)
+import System.EasyFile
+  ( createDirectoryIfMissing
+  , getAppUserDataDirectory
+  , (</>)
+  )
 import System.Random (getStdGen)
 
-import Password
-
 import Types
 import UI
 import Util
@@ -47,24 +48,9 @@
   return $ Status g pw p db
 
 getDBPath :: Request FilePath
-getDBPath = reqIO (lookupEnv "HOME") >>= maybe
-  (do
-    reqIO $ putStrLn "ERROR: can't find home directory"
-    reqFail)
-  (\home -> case pathDelim home of
-    Nothing -> do
-      reqIO $ putStrLn "ERROR: unsupported home path"
-      reqFail
-    Just delim -> return $ home ++
-      (if last home == delim then "" else [delim]) ++
-      ".passman.json")
-
-pathDelim :: FilePath -> Maybe Char
-pathDelim = foldr
-  (\x a -> case x of
-    '/'  -> Just '/'
-    '\\' -> Just '\\'
-    _    -> a)
-  Nothing
+getDBPath = reqIO $ do
+  path <- getAppUserDataDirectory "passman"
+  createDirectoryIfMissing True path
+  return $ path </> "database.json"
 
 --jl
diff --git a/app/UI.hs b/app/UI.hs
--- a/app/UI.hs
+++ b/app/UI.hs
@@ -20,14 +20,14 @@
 
 -}
 
+{-# LANGUAGE LambdaCase #-}
+
 module UI (getMasterPass, mainMenu) where
 
-import Control.Applicative ((<|>))
 import Control.Lens (over, set, view, (^.))
 import Control.Monad (when)
 import Control.Monad.Trans.Class (lift)
 import qualified Control.Monad.Trans.State as S
-import Data.Maybe (maybe)
 import System.Console.HCL
   ( Request
   , prompt
@@ -60,8 +60,8 @@
 mainMenu :: S.StateT Status IO ()
 mainMenu =
   menu "Main Menu"
-    [ ( "add a password",         addPassword      )
-    , ( "view/edit a password",   viewEditMenu     )
+    [ ( "view/edit a password",   viewEditMenu     )
+    , ( "add a password",         addPassword      )
     , ( "change master password", changeMasterPass )
     , ( "save manually",          save >> mainMenu )
     , ( "lock session",           lockSession      )
@@ -70,6 +70,20 @@
 
 addPassword :: S.StateT Status IO ()
 addPassword = do
+  pass <- S.gets (^.masterPass)
+
+  lift (runRequest $ prompt "confirm master password: " reqPassword)
+    >>= \case
+      Nothing -> mainMenu
+      Just chkPass
+        | pass == chkPass -> addPassword'
+
+        | otherwise -> do
+          lift $ putStrLn "Incorrect master password."
+          mainMenu
+
+addPassword' :: S.StateT Status IO ()
+addPassword' = do
   svc <- req $ prompt "service name: " reqResp
   ifServExists svc
     (do
@@ -215,19 +229,20 @@
   withService x
     (lift $ putStrLn "The service could not be found in the database.") $
     \d -> do
-      pw <- S.gets $ view masterPass
-      lift $ putStrLn $ case pwGenerate pw d of
+      mp <- S.gets $ view masterPass
+      lift $ putStrLn $ case pwGenerate mp d of
         Nothing -> "The password data were not valid."
         Just pw -> "password for " ++ x ++ ": " ++ pw
 
 -- TODO: refactor this monstrosity
 editPolicy :: PWPolicy -> Request PWPolicy
-editPolicy p = do
-  p <- edit "length" (p^.pwLength) pwLength p
-  p <- edit "min upper case"  (p^.pwUpper) pwUpper p
-  p <- edit "min lower case" (p^.pwLower) pwLower p
-  p <- edit "min digits" (p^.pwDigits) pwDigits p
-  p <- special p
+editPolicy policy = do
+  p <-
+    edit "length" (policy^.pwLength) pwLength policy >>=
+    edit "min upper case"  (policy^.pwUpper) pwUpper >>=
+    edit "min lower case" (policy^.pwLower) pwLower  >>=
+    edit "min digits" (policy^.pwDigits) pwDigits    >>=
+    special
   if validatePWPolicy p
     then return p
     else do
@@ -237,9 +252,9 @@
       reqFail
   where
     edit l v t p = do
-      v <- reqDefault
+      v' <- reqDefault
         (prompt ("new " ++ l ++ " (default " ++ show v ++ "): ") reqInt) v
-      return $ set t v p
+      return $ set t v' p
     special p = do
       reqIO $ putStrLn $ "Special characters are currently " ++
         (case p^.pwSpecial of
diff --git a/app/Util.hs b/app/Util.hs
--- a/app/Util.hs
+++ b/app/Util.hs
@@ -38,14 +38,13 @@
 import Control.Monad.Trans.Class (lift)
 import qualified Control.Monad.Trans.State as S
 import Data.Aeson (decodeFileStrict, encodeFile)
-import Data.Maybe (fromJust)
+import Data.Maybe (fromJust, fromMaybe)
 import System.Console.HCL
   ( Request
   , prompt
   , reqAgree
   , reqChar
   , reqDefault
-  , reqIf
   , reqIO
   , reqMenu
   , required
@@ -79,9 +78,7 @@
   -> S.StateT Status IO a
 withService srv fb act = do
   db <- S.gets $ view database
-  case pwGetService srv db of
-    Nothing -> fb
-    Just x  -> act x
+  maybe fb act $ pwGetService srv db
 
 ifServExists
   :: String
@@ -109,9 +106,7 @@
 loadFrom :: FilePath -> Request PWDatabase
 loadFrom path = reqDefault
   (reqIO (decodeFileStrict path))
-  (Just newPWDatabase) >>= maybe
-  (return newPWDatabase)
-  return
+  (Just newPWDatabase) >>= (return . fromMaybe newPWDatabase)
 
 save :: S.StateT Status IO ()
 save = do
diff --git a/passman.cabal b/passman.cabal
--- a/passman.cabal
+++ b/passman.cabal
@@ -1,13 +1,13 @@
 cabal-version: 1.12
 
--- This file has been generated from package.yaml by hpack version 0.31.1.
+-- This file has been generated from package.yaml by hpack version 0.33.0.
 --
 -- see: https://github.com/sol/hpack
 --
--- hash: c5c331a76842a12b6c072d80df3fe0d51970f056f11188205518ee6926790491
+-- hash: 51d5ea38547ab5dc4561e0faea0947ff40e4942817ad364ff3f645b1494095ff
 
 name:           passman
-version:        0.2
+version:        0.2.1
 synopsis:       a simple password manager
 description:    Please see the README on GitHub at <https://github.com/jlamothe/passman#readme>
 category:       Security
@@ -34,6 +34,7 @@
       Paths_passman
   hs-source-dirs:
       src
+  ghc-options: -Wall
   build-depends:
       SHA
     , aeson
@@ -56,13 +57,14 @@
       Paths_passman
   hs-source-dirs:
       app
-  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       HCL >=1.7.1 && <2
     , aeson
     , base >=4.7 && <5
     , bytestring
     , containers
+    , easy-file >=0.2.2 && <0.3
     , lens
     , passman
     , random
@@ -90,7 +92,7 @@
       Paths_passman
   hs-source-dirs:
       test
-  ghc-options: -threaded -rtsopts -with-rtsopts=-N
+  ghc-options: -Wall -threaded -rtsopts -with-rtsopts=-N
   build-depends:
       HUnit
     , aeson
diff --git a/src/Password.hs b/src/Password.hs
--- a/src/Password.hs
+++ b/src/Password.hs
@@ -27,7 +27,7 @@
 
 module Password (
   -- * Data Types
-  PWDatabase, PWData(..), PWPolicy (..), PWSalt,
+  PWDatabase, PWData(..), PWPolicy (..), PWSalt (..),
   -- ** Lenses
   -- $lenses
   -- *** PWData
@@ -47,11 +47,10 @@
   pwHasService, pwSetService, pwGetService, pwRemoveService, pwSearch
   ) where
 
-import Control.Lens (makeLenses, over, set, (^.))
+import Control.Lens (makeLenses, over, set, to, (^.))
 import Data.Aeson
   ( FromJSON (parseJSON)
   , ToJSON (toJSON)
-  , Value (String)
   , object
   , withObject
   , withText
@@ -59,15 +58,15 @@
   , (.=)
   )
 import qualified Data.ByteString.Lazy as B
+import qualified Data.ByteString.Lazy.Char8 as B8
+import Data.ByteString.Builder (toLazyByteString, stringUtf8)
 import qualified Data.ByteString.Base16.Lazy as B16
 import qualified Data.ByteString.Base64.Lazy as B64
 import Data.Char (isUpper, isLower, isDigit, isAlphaNum, toLower)
 import Data.Digest.Pure.SHA
 import qualified Data.Map as M
 import Data.Maybe (fromMaybe)
-import qualified Data.Text as T'
-import qualified Data.Text.Lazy as T
-import Data.Text.Lazy.Encoding (decodeUtf8, encodeUtf8)
+import qualified Data.Text as T
 import System.Random (RandomGen, randoms, split)
 
 -- | a mapping of service names to password data
@@ -97,7 +96,8 @@
   } deriving (Eq, Show)
 
 -- | the "salt" used to generate a password
-type PWSalt = B.ByteString
+newtype PWSalt = PWSalt { runPWSalt :: B.ByteString }
+  deriving (Eq, Show)
 
 -- $lenses The following functions are automatically generated by
 -- @makeLenses@. See the
@@ -120,11 +120,11 @@
     <*> v .: "min_digits"
     <*> v .: "min_special"
 
-instance FromJSON B.ByteString where
-  parseJSON = withText "ByteString" $ \v ->
-    case B64.decode $ encodeUtf8 $ T.pack $ T'.unpack v of
+instance FromJSON PWSalt where
+  parseJSON = withText "PWSalt" $ \v ->
+    case B64.decode $ toUTF8 $ T.unpack v of
       Left x  -> fail x
-      Right x -> return x
+      Right x -> return $ PWSalt x
 
 instance ToJSON PWData where
   toJSON d = object
@@ -141,8 +141,8 @@
     , "min_special" .= (p^.pwSpecial)
     ]
 
-instance ToJSON B.ByteString where
-  toJSON = toJSON . toB64
+instance ToJSON PWSalt where
+  toJSON = toJSON . toB64 . runPWSalt
 
 -- | default (empty) password database
 newPWDatabase :: PWDatabase
@@ -171,7 +171,7 @@
   -> (PWSalt, g)
   -- ^ the result and new random generator
 newPWSalt g = (result, g2) where
-  result = B.pack $ take 32 $ randoms g1
+  result = PWSalt $ B.pack $ take 32 $ randoms g1
   (g1, g2) = split g
 
 -- | validates a password database
@@ -190,7 +190,7 @@
   -- ^ @"True"@ if valid; @"False"@ otherwise
 validatePWData x =
   validatePWPolicy (x^.pwPolicy) &&
-  B.length (x^.pwSalt) > 0
+  B.length (x^.pwSalt.to runPWSalt) > 0
 
 -- | validates a password policy
 validatePWPolicy
@@ -336,11 +336,11 @@
   raw x = let x' = mkHash x in
     x' `B.append` raw x'
 
-mkSeed :: String -> PWData -> B.ByteString
-mkSeed pw d = toUTF8 pw `B.append` (d^.pwSalt)
+mkSeed :: String -> PWData ->B.ByteString
+mkSeed pw d = toUTF8 pw `B.append` (d^.pwSalt.to runPWSalt)
 
 mkHash :: B.ByteString -> B.ByteString
-mkHash = fst . B16.decode . encodeUtf8 . T.pack . show . sha256
+mkHash = fst . B16.decode . toUTF8 . show . sha256
 
 nextPolicy :: Char -> PWPolicy -> PWPolicy
 nextPolicy x p = over pwLength pred $
@@ -357,15 +357,15 @@
     dec l = over l (max 0 . pred) p
 
 toUTF8 :: String -> B.ByteString
-toUTF8 = encodeUtf8 . T.pack
+toUTF8 = toLazyByteString . stringUtf8
 
 toB64 :: B.ByteString -> String
-toB64 = T.unpack . decodeUtf8 . B64.encode
+toB64 = B8.unpack . B64.encode
 
 contains :: String -> String -> Bool
 _ `contains` "" = True
 "" `contains` _ = False
-xs@(x:xs') `contains` ys
+xs@(_:xs') `contains` ys
   | xs `startsWith` ys = True
   | otherwise = xs' `contains` ys
 
diff --git a/test/Spec.hs b/test/Spec.hs
--- a/test/Spec.hs
+++ b/test/Spec.hs
@@ -41,11 +41,13 @@
 import qualified Spec.ValidatePWDatabase as ValidatePWDatabase
 import qualified Spec.ValidatePWPolicy as ValidatePWPolicy
 
+main :: IO ()
 main = do
   counts <- runTestTT tests
   when (failures counts > 0 || errors counts > 0)
     exitFailure
 
+tests :: Test
 tests = TestList
   [ NewPWDatabase.tests
   , NewPWData.tests
diff --git a/test/Spec/JSON.hs b/test/Spec/JSON.hs
--- a/test/Spec/JSON.hs
+++ b/test/Spec/JSON.hs
@@ -25,31 +25,41 @@
 import Data.Aeson (eitherDecode, encode, decode)
 import qualified Data.ByteString.Lazy as B
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "JSON" $ TestList [success, failure]
 
+success :: Test
 success = TestLabel "succeasful encoding/decoding" $
   eitherDecode (encode db) ~?= Right db
 
+failure :: Test
 failure = TestLabel "decoding failure" $
   (decode B.empty :: Maybe PWDatabase) ~?= Nothing
 
+db :: M.Map String PWData
 db = M.fromList
   [ ( "foo", foo )
   , ( "bar", bar )
   , ( "baz", baz )
   ]
 
+foo :: PWData
+g'  :: StdGen
 (foo, g') = newPWData g
 
+bar :: PWData
+g'' :: StdGen
 (bar, g'') = newPWData g'
 
+baz :: PWData
 (baz, _) = newPWData g''
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/NewPWData.hs b/test/Spec/NewPWData.hs
--- a/test/Spec/NewPWData.hs
+++ b/test/Spec/NewPWData.hs
@@ -23,23 +23,27 @@
 module Spec.NewPWData (tests) where
 
 import Control.Lens ((^.))
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test  (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "newPData" $ TestList
   [ testSalt x
   , testPolicy x
   ] where (x, _) = newPWData g
 
+testSalt :: PWData -> Test
 testSalt x = TestLabel "pwSalt" $
   x^.pwSalt ~?= salt where
     (salt, _) = newPWSalt g
 
+testPolicy :: PWData -> Test
 testPolicy x = TestLabel "pwPolicy" $
   x^.pwPolicy ~?= newPWPolicy
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/NewPWDatabase.hs b/test/Spec/NewPWDatabase.hs
--- a/test/Spec/NewPWDatabase.hs
+++ b/test/Spec/NewPWDatabase.hs
@@ -26,6 +26,7 @@
 
 import Password
 
+tests :: Test
 tests = TestLabel "newPWDatabase" $
   length newPWDatabase ~?= 0
 
diff --git a/test/Spec/NewPWPolicy.hs b/test/Spec/NewPWPolicy.hs
--- a/test/Spec/NewPWPolicy.hs
+++ b/test/Spec/NewPWPolicy.hs
@@ -27,6 +27,7 @@
 
 import Password
 
+tests :: Test
 tests = TestLabel "PWPolicy" $ TestList $ map test'
   [ ( "pwLength",  newPWPolicy^.pwLength  ~?= 16     )
   , ( "pwUpper",   newPWPolicy^.pwUpper   ~?= 0      )
@@ -35,6 +36,7 @@
   , ( "pwSpecial", newPWPolicy^.pwSpecial ~?= Just 0 )
   ]
 
+test' :: (String, Test) -> Test
 test' (label, x) = TestLabel label x
 
 --jl
diff --git a/test/Spec/NewPWSalt.hs b/test/Spec/NewPWSalt.hs
--- a/test/Spec/NewPWSalt.hs
+++ b/test/Spec/NewPWSalt.hs
@@ -28,6 +28,7 @@
 
 import Password
 
+tests :: Test
 tests = TestLabel "newPWSalt" $ TestList
   [ testLength salt
   , testDiff salt salt'
@@ -36,9 +37,12 @@
     (salt', _) = newPWSalt g'
     g = mkStdGen 1
 
-testLength x = TestLabel "salt length" $ B.length x ~?= 32
+testLength :: PWSalt -> Test
+testLength x = TestLabel "salt length" $
+  B.length (runPWSalt x) ~?= 32
 
-testDiff x y = TestLabel "different generators" $ TestCase $
+testDiff :: PWSalt -> PWSalt -> Test
+testDiff x y = TestLabel "different salts" $ TestCase $
   assertBool "salts match" $ x /= y
 
 --jl
diff --git a/test/Spec/PWGenerate.hs b/test/Spec/PWGenerate.hs
--- a/test/Spec/PWGenerate.hs
+++ b/test/Spec/PWGenerate.hs
@@ -24,7 +24,7 @@
 
 import Control.Lens (set, (^.))
 import Data.Maybe (fromJust)
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit
   (Test (..)
   , assertBool
@@ -35,6 +35,7 @@
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwGenerate" $ TestList
   [ defaultData
   , invalidPolicy
@@ -43,15 +44,18 @@
   , differentMaster
   ]
 
+defaultData :: Test
 defaultData = TestLabel "default data" $ TestCase $
   case pwGenerate "foo" validData of
     Nothing -> assertFailure "no password generated"
     Just x  -> assertEqual "incorrect password length"
       (validData^.pwPolicy.pwLength) (length x)
 
+invalidPolicy :: Test
 invalidPolicy = TestLabel "invalid policy" $
   pwGenerate "foo" invalidPolicy' ~?= Nothing
 
+constraints :: Test
 constraints = TestLabel "strict constraints" $ TestCase $
   case pwGenerate "foo" constraints' of
     Nothing -> assertFailure "no password generated"
@@ -67,6 +71,7 @@
       assertEqual "incorrect number of special characters"
         (fromJust $ constraints'^.pwPolicy.pwSpecial) (pwCountSpecial x)
 
+noSpecial :: Test
 noSpecial = TestLabel "no special chars" $ TestCase $
   case pwGenerate "foo" noSpecial' of
     Nothing -> assertFailure "no password generated"
@@ -75,25 +80,31 @@
         (noSpecial'^.pwPolicy.pwLength) (length x)
       assertEqual "special characters found" 0 $ pwCountSpecial x
 
+differentMaster :: Test
 differentMaster = TestLabel "different master passwords" $ TestCase $
   assertBool "passwords match" $
   fromJust (pwGenerate "foo" validData) /=
   fromJust (pwGenerate "bar" validData)
 
+validData :: PWData
 (validData, _) = newPWData g
 
+invalidPolicy' :: PWData
 invalidPolicy' = set (pwPolicy.pwLength) (-1) validData
 
+constraints' :: PWData
 constraints' = set (pwPolicy.pwUpper) 4 $
   set (pwPolicy.pwLower) 4 $
   set (pwPolicy.pwDigits) 4 $
   set (pwPolicy.pwSpecial) (Just 4)
   validData
 
+noSpecial' :: PWData
 noSpecial' = set (pwPolicy.pwLength) 256 $
   set (pwPolicy.pwSpecial) Nothing
   validData
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/PWGetService.hs b/test/Spec/PWGetService.hs
--- a/test/Spec/PWGetService.hs
+++ b/test/Spec/PWGetService.hs
@@ -23,35 +23,46 @@
 module Spec.PWGetService (tests) where
 
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwGetService" $ TestList
   [ empty, found, notFound ]
 
+empty :: Test
 empty = TestLabel "empty database" $
   pwGetService "foo" newPWDatabase ~?= Nothing
 
+found :: Test
 found = TestLabel "service found" $
   pwGetService "foo" db ~?= Just foo
 
+notFound :: Test
 notFound = TestLabel "service not found" $
   pwGetService "quux" db ~?= Nothing
 
+db :: M.Map String PWData
 db = M.fromList
   [ ( "foo", foo )
   , ( "bar", bar )
   , ( "baz", baz )
   ]
 
+foo :: PWData
+g'  :: StdGen
 (foo, g') = newPWData g
 
+bar :: PWData
+g'' :: StdGen
 (bar, g'') = newPWData g'
 
+baz :: PWData
 (baz, _) = newPWData g''
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/PWHasService.hs b/test/Spec/PWHasService.hs
--- a/test/Spec/PWHasService.hs
+++ b/test/Spec/PWHasService.hs
@@ -23,32 +23,41 @@
 module Spec.PWHasService (tests) where
 
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwHasService" $ TestList $ map test'
   [ ( "empty database", "foo",  newPWDatabase, False )
-  , ( "in database",    "foo",  db,            True  )
-  , ( "not found",      "quux", db,            False )
+  , ( "in database",    "foo",  database,      True  )
+  , ( "not found",      "quux", database,      False )
   ]
 
+test' :: (String, String, PWDatabase, Bool) -> Test
 test' (label, x, db, expect) = TestLabel label $
   pwHasService x db ~?= expect
 
-db = M.fromList
+database :: M.Map String PWData
+database = M.fromList
   [ ( "foo", foo )
   , ( "bar", bar )
   , ( "baz", baz )
   ]
 
+foo :: PWData
+g'  :: StdGen
 (foo, g') = newPWData g
 
+bar :: PWData
+g'' :: StdGen
 (bar, g'') = newPWData g'
 
+baz :: PWData
 (baz, _) = newPWData g''
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/PWRemoveService.hs b/test/Spec/PWRemoveService.hs
--- a/test/Spec/PWRemoveService.hs
+++ b/test/Spec/PWRemoveService.hs
@@ -23,26 +23,31 @@
 module Spec.PWRemoveService (tests) where
 
 import qualified Data.Map.Lazy as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), assertBool, (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwRemoveService" $ TestList
   [ emptyDB
   , existingService
   , missingService
   ]
 
+emptyDB :: Test
 emptyDB = TestLabel "empty database" $
   pwRemoveService "foo" newPWDatabase ~?= newPWDatabase
 
+existingService :: Test
 existingService = TestLabel "existing service" $
   test' "foo" ["bar", "baz"]
 
+missingService :: Test
 missingService = TestLabel "missing service" $
   test' "quux" ["foo", "bar", "baz"]
 
+test' :: String -> [String] -> Test
 test' serv keys = let db' = pwRemoveService serv db in
   TestList $
   TestLabel "key count" (length keys ~?= length (M.keys db')) :
@@ -50,18 +55,25 @@
   (\x -> TestLabel x $ TestCase $ assertBool "service missing" $ pwHasService x db')
   keys
 
+db :: M.Map String PWData
 db = M.fromList
   [ ( "foo", foo )
   , ( "bar", bar )
   , ( "baz", baz )
   ]
 
+foo :: PWData
+g'  ::StdGen
 (foo, g') = newPWData g
 
+bar :: PWData
+g'' :: StdGen
 (bar, g'') = newPWData g'
 
+baz :: PWData
 (baz, _) = newPWData g''
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/PWSearch.hs b/test/Spec/PWSearch.hs
--- a/test/Spec/PWSearch.hs
+++ b/test/Spec/PWSearch.hs
@@ -23,35 +23,44 @@
 module Spec.PWSearch (tests) where
 
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), assertBool, (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwSearch" $ TestList $ map test'
   [ ( "no results",   "quux", []                    )
   , ( "some results", "A",    ["bar", "baz"]        )
   , ( "all results",  "",     ["foo", "bar", "baz"] )
   ]
 
+test' :: (String, String, [String]) -> Test
 test' (label, str, expect) = TestLabel label $ TestList $
   TestLabel "length" (length result ~?= length expect) :
   map (\x -> TestLabel ("has " ++ x) $ TestCase $
     assertBool "not found" $ elem x expect) result
   where result = pwSearch str db
 
+db :: M.Map String PWData
 db = M.fromList
   [ ( "foo", foo )
   , ( "bar", bar )
   , ( "baz", baz )
   ]
 
+foo :: PWData
+g'  :: StdGen
 (foo, g') = newPWData g
 
+bar :: PWData
+g'' :: StdGen
 (bar, g'') = newPWData g'
 
+baz :: PWData
 (baz, _) = newPWData g''
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/PWSetService.hs b/test/Spec/PWSetService.hs
--- a/test/Spec/PWSetService.hs
+++ b/test/Spec/PWSetService.hs
@@ -23,51 +23,68 @@
 module Spec.PWSetService (tests) where
 
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "pwSetService" $ TestList
   [ addToEmpty, addToNonEmpty, addToExisting ]
 
+addToEmpty :: Test
 addToEmpty = tests' "empty database" newPWDatabase 1
 
+addToNonEmpty :: Test
 addToNonEmpty = tests' "non-empty database" nonEmpty 3
 
+addToExisting :: Test
 addToExisting = tests' "existing database" existing 3
 
+tests' :: String -> PWDatabase -> Int -> Test
 tests' label db size = TestLabel label $ TestList
   [ dbSize result size
   , find result
   ] where
     result = pwSetService "foo" foo db
 
+dbSize :: M.Map String PWData -> Int -> Test
 dbSize db expect = TestLabel "database size" $
   length db ~?= expect
 
+find :: M.Map String PWData -> Test
 find db = TestLabel "record" $
   M.lookup "foo" db ~?= Just foo
 
+nonEmpty :: M.Map String PWData
 nonEmpty = M.fromList
   [ ( "bar", bar )
   , ( "baz", baz )
   ]
 
+existing :: M.Map String PWData
 existing = M.fromList
   [ ( "foo", foo' )
   , ( "bar", bar  )
   , ( "baz", baz  )
   ]
 
+foo :: PWData
+g1  :: StdGen
 (foo, g1) = newPWData g
 
+foo' :: PWData
+g2   :: StdGen
 (foo', g2) = newPWData g1
 
+bar :: PWData
+g3  :: StdGen
 (bar, g3) = newPWData g2
 
+baz :: PWData
 (baz, _) = newPWData g3
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/ValidatePWData.hs b/test/Spec/ValidatePWData.hs
--- a/test/Spec/ValidatePWData.hs
+++ b/test/Spec/ValidatePWData.hs
@@ -24,26 +24,32 @@
 
 import Control.Lens (set)
 import qualified Data.ByteString.Lazy as B
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "validatePWData" $ TestList $ map test'
   [ ( "valid",          new,           True  )
   , ( "invalid policy", invalidPolicy, False )
   , ( "invalid salt",   invalidSalt,   False )
   ]
 
+test' :: (String, PWData, Bool) -> Test
 test' (label, x, expect) = TestLabel label $
   validatePWData x ~?= expect
 
+new :: PWData
 (new, _) = newPWData g
 
+invalidPolicy :: PWData
 invalidPolicy = set (pwPolicy.pwLength) (-1) new
 
-invalidSalt = set pwSalt B.empty new
+invalidSalt :: PWData
+invalidSalt = set pwSalt (PWSalt B.empty) new
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/ValidatePWDatabase.hs b/test/Spec/ValidatePWDatabase.hs
--- a/test/Spec/ValidatePWDatabase.hs
+++ b/test/Spec/ValidatePWDatabase.hs
@@ -24,11 +24,12 @@
 
 import Control.Lens (set)
 import qualified Data.Map as M
-import System.Random (mkStdGen)
+import System.Random (mkStdGen, StdGen)
 import Test.HUnit (Test (..), (~?=))
 
 import Password
 
+tests :: Test
 tests = TestLabel "validatePWDatabase" $ TestList $ map test'
   [ ( "empty",       newPWDatabase, True  )
   , ( "valid",       validDB,       True  )
@@ -36,19 +37,26 @@
   , ( "bar invalid", barInvalid,    False )
   ]
 
+test' :: (String, PWDatabase, Bool) -> Test
 test' (label, x, expect) = TestLabel label $
   validatePWDatabase x ~?= expect
 
+validDB :: M.Map String PWData
 validDB = M.fromList [("foo", validData), ("bar", validData)]
 
+fooInvalid :: M.Map String PWData
 fooInvalid = M.insert "foo" invalidData validDB
 
+barInvalid :: M.Map String PWData
 barInvalid = M.insert "bar" invalidData validDB
 
+validData :: PWData
 (validData, _) = newPWData g
 
+invalidData :: PWData
 invalidData = set (pwPolicy.pwLength) (-1) validData
 
+g :: StdGen
 g = mkStdGen 1
 
 --jl
diff --git a/test/Spec/ValidatePWPolicy.hs b/test/Spec/ValidatePWPolicy.hs
--- a/test/Spec/ValidatePWPolicy.hs
+++ b/test/Spec/ValidatePWPolicy.hs
@@ -27,6 +27,7 @@
 
 import Password
 
+tests :: Test
 tests = TestLabel "validatePWPolicy" $ TestList $ map test'
   [ ( "default",          id,                        True  )
   , ( "no special chars", set pwSpecial Nothing,     True  )
@@ -45,18 +46,24 @@
   , ( "negative special", set pwSpecial (Just (-1)), False )
   ]
 
+test' :: (String, PWPolicy -> PWPolicy, Bool) -> Test
 test' (label, f, expect) = TestLabel label $
   validatePWPolicy x ~?= expect where
   x = f newPWPolicy
 
+validMins :: PWPolicy -> PWPolicy
 validMins = setAll 1
 
+excessive :: PWPolicy -> PWPolicy
 excessive = setAll 5
 
+shortValid :: PWPolicy -> PWPolicy
 shortValid = set pwLength 8 . setAll 2
 
+shortInvalid :: PWPolicy -> PWPolicy
 shortInvalid = set pwLength 8 . set pwUpper 9
 
+setAll :: Int -> PWPolicy -> PWPolicy
 setAll x = set pwUpper x .
   set pwLower x .
   set pwDigits x .
