diff --git a/CHANGELOG.txt b/CHANGELOG.txt
new file mode 100644
--- /dev/null
+++ b/CHANGELOG.txt
@@ -0,0 +1,19 @@
+0.3, 2008-10-19:
+	Further performance improvements to globDir.
+	Bug fix: handle empty pattern lists correctly in globDir.
+	Added dependency: Win32, for Windows OSs.
+
+0.2, 2008-10-18:
+	Performance improvements to globDir, no functionality changes.
+	Added dependency: dlist.
+
+0.1, 2008-10-17:
+	Initial release.
+
+	Functions:
+		System.FilePath.Glob.tryCompile :: String -> Either String Pattern
+		System.FilePath.Glob.compile    :: String -> Pattern
+		System.FilePath.Glob.match      :: Pattern -> FilePath -> Bool
+		System.FilePath.Glob.globDir    :: [Pattern] -> FilePath -> IO ([[FilePath]], [FilePath])
+	
+	Dependencies: base, containers, directory, filepath, mtl.
diff --git a/Glob.cabal b/Glob.cabal
--- a/Glob.cabal
+++ b/Glob.cabal
@@ -1,7 +1,7 @@
 Cabal-Version: >= 1.2
 
 Name:        Glob
-Version:     0.2
+Version:     0.3
 Homepage:    http://iki.fi/matti.niemenmaa/glob/
 Synopsis:    Globbing library
 Category:    System
@@ -16,7 +16,8 @@
 
 Build-Type: Simple
 
-Extra-Source-Files: tests/README.txt
+Extra-Source-Files: CHANGELOG.txt
+                    tests/README.txt
                     tests/*.hs
                     tests/Tests/*.hs
 
@@ -27,6 +28,9 @@
                 , dlist      == 0.*
                 , filepath   == 1.*
                 , mtl        == 1.*
+
+   if os(windows)
+      Build-Depends: Win32 == 2.*
 
    Exposed-Modules: System.FilePath.Glob
    Other-Modules:   System.FilePath.Glob.Base
diff --git a/System/FilePath/Glob/Directory.hs b/System/FilePath/Glob/Directory.hs
--- a/System/FilePath/Glob/Directory.hs
+++ b/System/FilePath/Glob/Directory.hs
@@ -5,7 +5,7 @@
 import Control.Monad    (forM)
 import qualified Data.DList as DL
 import Data.DList       (DList)
-import Data.List        ((\\), partition)
+import Data.List        ((\\))
 import System.Directory (doesDirectoryExist, getDirectoryContents)
 import System.FilePath  ((</>))
 
@@ -41,6 +41,9 @@
 -- Any results deeper than in the given directory are enumerated lazily, using
 -- 'unsafeInterleaveIO'.
 globDir :: [Pattern] -> FilePath -> IO ([[FilePath]], [FilePath])
+globDir []   dir = do
+   c <- getRecursiveContents dir
+   return ([], DL.toList c)
 globDir pats dir = do
    results <- mapM (\p -> globDir' (separate p) dir) pats
 
@@ -53,7 +56,7 @@
           )
 
 globDir' :: [TypedPattern] -> FilePath -> IO (DList FilePath, DList FilePath)
-globDir' []   _   = return (DL.empty, DL.empty)
+globDir' []   dir = didn'tMatch dir True
 globDir' pats dir = do
    raw <- getDirectoryContents dir
 
diff --git a/System/FilePath/Glob/Utils.hs b/System/FilePath/Glob/Utils.hs
--- a/System/FilePath/Glob/Utils.hs
+++ b/System/FilePath/Glob/Utils.hs
@@ -1,3 +1,4 @@
+{-# LANGUAGE CPP #-}
 -- File created: 2008-10-10 13:40:35
 
 module System.FilePath.Glob.Utils
@@ -11,15 +12,27 @@
    , getRecursiveContents
    ) where
 
-import Control.Monad     (foldM)
-import Data.List         ((\\))
+import Control.Monad    (foldM)
+import Data.List        ((\\))
 import qualified Data.DList as DL
-import Data.DList        (DList)
+import Data.DList       (DList)
 import qualified Data.Set as Set
-import System.Directory  (doesDirectoryExist, getDirectoryContents)
-import System.FilePath   ((</>), isPathSeparator, dropDrive)
-import System.IO.Unsafe  (unsafeInterleaveIO)
+import System.Directory (getDirectoryContents)
+import System.FilePath  ((</>), isPathSeparator, dropDrive)
+import System.IO.Unsafe (unsafeInterleaveIO)
 
+#if mingw32_HOST_OS
+import Data.Bits          ((.&.))
+import System.Win32.Types (withTString)
+import System.Win32.File  (c_GetFileAttributes, fILE_ATTRIBUTE_DIRECTORY)
+#else
+import Foreign.C.String      (withCString)
+import Foreign.Marshal.Alloc (allocaBytes)
+import System.FilePath
+   (isDrive, dropTrailingPathSeparator, addTrailingPathSeparator)
+import System.Posix.Internals (sizeof_stat, lstat, s_isdir, st_mode)
+#endif
+
 inRange :: Ord a => (a,a) -> a -> Bool
 inRange (a,b) c = c >= a && c <= b
 
@@ -87,6 +100,28 @@
       if isPathSeparator x
          then xs : f xs
          else      f xs
+
+-- Significantly speedier than System.Directory.doesDirectoryExist.
+doesDirectoryExist :: FilePath -> IO Bool
+#if mingw32_HOST_OS
+-- This one allocates more memory since it has to do a UTF-16 conversion, but
+-- that can't really be helped: the below version is locale-dependent.
+doesDirectoryExist = flip withTString $ \s -> do
+   a <- c_GetFileAttributes s
+   return (a /= 0xffffffff && a.&.fILE_ATTRIBUTE_DIRECTORY /= 0)
+#else
+doesDirectoryExist s =
+   allocaBytes sizeof_stat $ \p ->
+      withCString
+         (if isDrive s
+             then addTrailingPathSeparator s
+             else dropTrailingPathSeparator s)
+         $ \c -> do
+            st <- lstat c p
+            if st == 0
+               then fmap s_isdir (st_mode p)
+               else return False
+#endif
 
 getRecursiveContents :: FilePath -> IO (DList FilePath)
 getRecursiveContents dir = do
