diff --git a/README.markdown b/README.markdown
--- a/README.markdown
+++ b/README.markdown
@@ -7,15 +7,15 @@
 # Get involved!
 
 Please report bugs via the
-[bitbucket issue tracker](http://bitbucket.org/bos/attoparsec/filemanip).
+[github issue tracker](https://github.com/bos/filemanip/issues).
 
-Master [Mercurial repository](http://bitbucket.org/bos/filemanip):
+Master [git repository](http://github.com/bos/filemanip):
 
-* `hg clone http://bitbucket.org/bos/filemanip`
+* `git clone git://github.com/bos/filemanip.git`
 
-There's also a [git mirror](http://github.com/bos/filemanip):
+There's also a [Mercurial mirror](http://bitbucket.org/bos/filemanip):
 
-* `git clone git://github.com/bos/filemanip.git`
+* `hg clone https://bitbucket.org/bos/filemanip`
 
 (You can create and contribute changes using either Mercurial or git.)
 
diff --git a/System/FilePath/Find.hs b/System/FilePath/Find.hs
--- a/System/FilePath/Find.hs
+++ b/System/FilePath/Find.hs
@@ -1,4 +1,4 @@
-{-# LANGUAGE GeneralizedNewtypeDeriving, ScopedTypeVariables #-}
+{-# LANGUAGE CPP, GeneralizedNewtypeDeriving, ScopedTypeVariables #-}
 {-# OPTIONS_GHC -fno-warn-orphans #-}
 
 -- |
@@ -29,7 +29,7 @@
 -- Because 'FindClause' is a monad, you can use the usual monad
 -- machinery to, for example, lift pure functions into it.
 --
--- Here's a clause that will return 'False' for any file whose
+-- Here's a clause that will return 'True' for any file whose
 -- directory name contains the word @\"temp\"@.
 --
 -- @
@@ -90,6 +90,10 @@
     , filePerms
     , anyPerms
 
+    -- ** Combinators for canonical path and name
+    , canonicalPath
+    , canonicalName
+
     -- ** Combinators that operate on symbolic links
     , readLink
     , followStatus
@@ -111,19 +115,22 @@
     , (||?)
     ) where
 
-import Control.Exception
+#if !MIN_VERSION_base(4,8,0)
+import Control.Applicative (Applicative)
+#endif
+import qualified Control.Exception as E
+import Control.Exception (IOException, handle)
 import Control.Monad (foldM, forM, liftM, liftM2)
 import Control.Monad.State (State, evalState, get)
 import Data.Bits (Bits, (.&.))
 import Data.List (sort)
-import System.Directory (getDirectoryContents)
+import System.Directory (getDirectoryContents, canonicalizePath)
 import System.FilePath ((</>), takeDirectory, takeExtension, takeFileName)
 import System.FilePath.GlobPattern (GlobPattern, (~~), (/~))
 import System.IO (hPutStrLn, stderr)
 import System.IO.Unsafe (unsafeInterleaveIO, unsafePerformIO)
 import qualified System.PosixCompat.Files as F
 import qualified System.PosixCompat.Types as T
-import Prelude hiding (catch)
 
 -- | Information collected during the traversal of a directory.
 data FileInfo = FileInfo
@@ -147,7 +154,7 @@
 -- construction of combinators.  Wraps the 'State' monad, but doesn't
 -- allow 'get' or 'put'.
 newtype FindClause a = FC { runFC :: State FileInfo a }
-    deriving (Functor, Monad)
+    deriving (Functor, Applicative, Monad)
 
 -- | Run the given 'FindClause' on the given 'FileInfo' and return its
 -- result.  This can be useful if you are writing a function to pass
@@ -222,7 +229,7 @@
               then unsafeInterleaveIO (traverse path (succ depth) st)
               else filterPath path depth st []
         traverse dir depth dirSt = do
-            names <- catch (getDirContents dir) (errHandler dir)
+            names <- E.catch (getDirContents dir) (errHandler dir)
             filteredPaths <- forM names $ \name -> do
                 let path = dir </> name
                 unsafeInterleaveIO $ handle (errHandler path)
@@ -291,7 +298,7 @@
      -> IO a
 
 fold = foldWithHandler warnOnError
-    where warnOnError path a err = 
+    where warnOnError path a err =
               hPutStrLn stderr (path ++ ": " ++ show err) >> return a
 
 -- | Unconditionally return 'True'.
@@ -341,6 +348,17 @@
 directory :: FindClause FilePath
 directory = takeDirectory `liftM` filePath
 
+-- | Return the canonical path of the file being visited.
+--
+-- See `canonicalizePath` for details of what canonical path means.
+canonicalPath :: FindClause FilePath
+canonicalPath = (unsafePerformIO . canonicalizePath) `liftM` filePath
+
+-- | Return the canonical name of the file (canonical path with the
+-- directory part removed).
+canonicalName :: FindClause FilePath
+canonicalName = takeFileName `liftM` canonicalPath
+
 -- | Run the given action in the 'IO' monad (using 'unsafePerformIO')
 -- if the current file is a symlink.  Hide errors by wrapping results
 -- in the 'Maybe' monad.
@@ -408,7 +426,7 @@
 statusType _ = Unknown
 
 -- $statusFunctions
--- 
+--
 -- These are simply lifted versions of the 'F.FileStatus' accessor
 -- functions in the "System.Posix.Files" module.  The definitions all
 -- have the following form:
@@ -486,12 +504,12 @@
 liftOp f a b = a >>= \a' -> return (f a' b)
 
 -- $binaryOperators
--- 
+--
 -- These are lifted versions of the most commonly used binary
 -- operators.  They have the same fixities and associativities as
 -- their unlifted counterparts.  They are lifted using 'liftOp', like
 -- so:
--- 
+--
 -- @('==?') = 'liftOp' (==)@
 
 -- | Return 'True' if the current file's name matches the given
diff --git a/System/FilePath/GlobPattern.hs b/System/FilePath/GlobPattern.hs
--- a/System/FilePath/GlobPattern.hs
+++ b/System/FilePath/GlobPattern.hs
@@ -15,6 +15,7 @@
     ) where
 
 import Control.Arrow (second)
+import Control.Monad (msum)
 import Data.Ix (Ix, inRange)
 import Data.List (nub)
 import Data.Maybe (isJust)
@@ -117,8 +118,9 @@
 simplifyTerms (MatchGroup []:as) = simplifyTerms as
 simplifyTerms (MatchGroup gs:as) =
     case commonPrefix gs of
-    (p,[]) -> simplifyTerms (MatchLiteral p : as)
-    (p,ss) -> simplifyTerms (MatchLiteral p : MatchGroup ss : as)
+    (p ,[]) -> simplifyTerms (MatchLiteral p : as)
+    ("",ss) -> MatchGroup ss : simplifyTerms as
+    (p ,ss) -> simplifyTerms (MatchLiteral p : MatchGroup ss : as)
 simplifyTerms (a:as) = a:simplifyTerms as
 
 commonPrefix :: [String] -> (String, [String])
@@ -143,17 +145,14 @@
     where matchClass (b:bs) | (inClass && k) || not (inClass || k) = return bs
                             where inClass = b `inSRange` c
           matchClass _ = fail "no match"
-matchTerms (MatchGroup g:ts) cs = matchGroup g cs >>= matchTerms ts
-    where matchGroup g' as | any null g' = return as
-          matchGroup g' (a:as) | a `elem` map head g' =
-                                   matchGroup (map tail g') as
-          matchGroup _ _ = fail "not in group"
+matchTerms (MatchGroup g:ts) cs = msum (map matchGroup g)
+    where matchGroup g = matchTerms (MatchLiteral g : ts) cs
 matchTerms [MatchAny] _ = return ()
 matchTerms (MatchAny:ts) cs = matchAny cs >>= matchTerms ts
     where matchAny [] = fail "no match"
           matchAny cs' = case matchTerms ts cs' of
                           Nothing -> matchAny (tail cs')
-                          _ -> return cs
+                          _ -> return cs'
 matchTerms [MatchDir] cs | pathSeparator `elem` cs = fail "path separator"
                          | otherwise = return ()
 matchTerms (MatchDir:ts) cs = matchDir cs >>= matchTerms ts
diff --git a/System/FilePath/Manip.hs b/System/FilePath/Manip.hs
--- a/System/FilePath/Manip.hs
+++ b/System/FilePath/Manip.hs
@@ -21,8 +21,8 @@
 import Data.Bits ((.&.))
 import System.Directory (removeFile)
 import System.IO (Handle, IOMode(..), hClose, openFile)
-import System.Posix.Files (fileMode, getFileStatus, rename, setFileMode)
-import System.Posix.Temp (mkstemp)
+import System.PosixCompat.Files (fileMode, getFileStatus, rename, setFileMode)
+import System.PosixCompat.Temp (mkstemp)
 import qualified Data.ByteString.Char8 as B
 import qualified Data.ByteString.Lazy.Char8 as L
 import qualified System.IO as I
diff --git a/filemanip.cabal b/filemanip.cabal
--- a/filemanip.cabal
+++ b/filemanip.cabal
@@ -1,11 +1,11 @@
 Name:               filemanip
-Version:            0.3.5.2
+Version:            0.3.6.3
 License:            BSD3
 License-File:       LICENSE
 Author:             Bryan O'Sullivan <bos@serpentine.com>
 Maintainer:         Bryan O'Sullivan
-Homepage:           http://bitbucket.org/bos/filemanip
-Bug-reports:        http://bitbucket.org/bos/filemanip/issues
+Homepage:           https://github.com/bos/filemanip
+Bug-reports:        https://github.com/bos/filemanip/issues
 Synopsis:           Expressive file and directory manipulation for Haskell.
 Category:           System
 Description:        A Haskell library for working with files and directories.
@@ -18,8 +18,6 @@
 
 Library
   build-depends: base < 5, bytestring, directory, filepath, mtl, unix-compat
-  if !os(windows)
-    build-depends: unix
   if impl(ghc >= 6.10)
     build-depends:
       base >= 4
@@ -32,9 +30,9 @@
           System.FilePath.Manip
 
 source-repository head
-  type:     mercurial
-  location: http://bitbucket.org/bos/filemanip
+  type:     git
+  location: git://github.com/bos/filemanip.git
 
 source-repository head
-  type:     git
-  location: http://github.com/bos/filemanip
+  type:     mercurial
+  location: https://bitbucket.org/bos/filemanip
